[events] First work on job transfer and job invite

This commit is contained in:
Ferdinand Thiessen 2021-04-01 03:16:25 +02:00
parent 1f71abcd4b
commit 43dcd0579e
1 changed files with 132 additions and 31 deletions

View File

@ -1,5 +1,46 @@
<template> <template>
<q-card bordered> <q-card bordered>
<q-dialog :model-value="dialog">
<q-card style="min-width: 320px">
<q-card-section class="row items-center q-pb-none">
<div class="text-h6">
{{ userDisplay(service.userid) }} {{ asDate(modelValue.start) }}
</div>
<q-space />
<q-btn icon="close" flat round dense @click="dialog = false" />
</q-card-section>
<q-card-section>
{{ modelValue.type.name }} {{ asHour(modelValue.start)
}}{{ modelValue.end ? ` - ${asHour(modelValue.end)}` : '' }}
Uhr
</q-card-section>
<q-card-actions align="around">
<q-btn style="width: 47.5%" color="primary" label="Eintragen" @click="enroll" />
<q-toggle
v-model="service.is_backup"
style="width: 47.5%"
color="primary"
label="Als Backup"
/>
</q-card-actions>
<q-card-actions v-if="!enrolled(service.userid)" align="around">
<q-btn
v-if="isEnrolled"
style="width: 47.5%"
color="negative"
label="Übertragen"
@click="transfer"
/>
<q-btn
v-if="!iam(service.userid)"
style="width: 47.5%"
color="secondary"
label="Einladen"
@click="invite"
/>
</q-card-actions>
</q-card>
</q-dialog>
<div class="text-weight-medium q-px-xs"> <div class="text-weight-medium q-px-xs">
{{ asHour(modelValue.start) }} {{ asHour(modelValue.start) }}
<template v-if="modelValue.end">- {{ asHour(modelValue.end) }}</template> <template v-if="modelValue.end">- {{ asHour(modelValue.end) }}</template>
@ -13,34 +54,51 @@
<div> <div>
<q-select <q-select
:model-value="modelValue.services" :model-value="modelValue.services"
:options="options"
:option-label="(v) => userDisplay(v.userid)"
filled filled
:option-label="(opt) => userDisplay(opt)"
multiple multiple
disable
use-chips
stack-label stack-label
label="Dienste" label="Dienste"
class="col-auto q-px-xs" class="col-auto q-px-xs"
style="font-size: 6px" style="font-size: 6px"
counter counter
:max-values="modelValue.required_services" :max-values="modelValue.required_services"
@add="enrollDialog"
> >
<template #selected-item="scope">
<q-chip
:removable="canEdit(scope.opt.userid)"
dense
:tabindex="scope.tabindex"
color="white"
:text-color="scope.opt.is_backup ? 'primary' : 'secondary'"
class="q-ma-none"
@remove="remove(scope.opt.userid, scope.removeAtIndex, scope.index)"
>
<q-avatar :color="scope.opt.is_backup ? 'primary' : 'secondary'" text-color="white">
<img
:src="userAvatar(scope.opt.userid)"
onerror="this.src=' data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==';"
/>
</q-avatar>
{{ userDisplay(scope.opt.userid) }}
</q-chip>
</template>
</q-select> </q-select>
<div class="row col-12 justify-end">
<q-btn v-if="canEnroll" flat color="primary" label="Eintragen" @click="enrollForJob" />
<q-btn v-if="isEnrolled" flat color="negative" label="Austragen" @click="signOutFromJob" />
</div>
</div> </div>
</q-card> </q-card>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, onBeforeMount, computed, PropType } from 'vue'; import { defineComponent, onBeforeMount, computed, ref, PropType } from 'vue';
import { Notify } from 'quasar'; import { Notify } from 'quasar';
import { asHour } from 'src/utils/datetime'; import { asHour, asDate } from 'src/utils/datetime';
import { useUserStore } from 'src/plugins/user/store'; import { useUserStore } from 'src/plugins/user/store';
import { useMainStore } from 'src/stores'; import { useMainStore } from 'src/stores';
import { useScheduleStore } from 'src/plugins/events/store'; import { useScheduleStore } from 'src/plugins/events/store';
import { PERMISSIONS } from 'src/plugins/events/permissions';
import { hasPermission } from 'src/utils/permission';
export default defineComponent({ export default defineComponent({
name: 'JobSlot', name: 'JobSlot',
@ -60,35 +118,35 @@ export default defineComponent({
const mainStore = useMainStore(); const mainStore = useMainStore();
const userStore = useUserStore(); const userStore = useUserStore();
const availableUsers = null; const availableUsers = null;
const dialog = ref(false);
const service = ref<FG.Service>();
onBeforeMount(async () => userStore.getUsers()); onBeforeMount(async () => userStore.getUsers());
function userDisplay(service: FG.Service) { function userDisplay(uid: string) {
return userStore.findUser(service.userid)?.display_name || service.userid; return userStore.findUser(uid)?.display_name || uid;
} }
const isEnrolled = computed( function userAvatar(uid: string) {
() => return userStore.findUser(uid)?.avatar_url;
props.modelValue.services.findIndex( }
(service) => service.userid == mainStore.currentUser.userid
) !== -1
);
const canEnroll = computed(() => { function enrollDialog(details: { index: number; value: FG.User }) {
const is = isEnrolled.value; service.value = {
let sum = 0; userid: details.value.userid,
props.modelValue.services.forEach((s) => (sum += s.value));
return sum < props.modelValue.required_services && !is;
});
async function enrollForJob() {
const newService: FG.Service = {
userid: mainStore.currentUser.userid,
is_backup: false, is_backup: false,
value: 1, value: 0.5,
}; };
dialog.value = true;
}
function iam(uid: string) {
return uid === mainStore.currentUser.userid;
}
async function enroll() {
try { try {
const job = await store.updateJob(props.eventId, props.modelValue.id, { user: newService }); const job = await store.updateJob(props.eventId, props.modelValue.id, {
user: <FG.Service>service.value,
});
emit('update:modelValue', job); emit('update:modelValue', job);
} catch (error) { } catch (error) {
console.warn(error); console.warn(error);
@ -102,6 +160,39 @@ export default defineComponent({
}); });
} }
} }
async function remove(userid: string, rem: (i: number) => void, index: number) {
if (userid === mainStore.currentUser.userid || hasPermission(PERMISSIONS.ASSIGN_OTHER)) {
console.log('YES REM');
rem(index);
await signOutFromJob();
}
}
const options = computed(() =>
hasPermission(PERMISSIONS.ASSIGN_OTHER)
? userStore.users.filter((v) => !enrolled(v.userid))
: !isEnrolled.value
? [mainStore.currentUser]
: []
);
function canEdit(uid: string) {
return uid === mainStore.currentUser.userid || hasPermission(PERMISSIONS.ASSIGN_OTHER);
}
function enrolled(userid: string) {
return props.modelValue.services.findIndex((service) => service.userid == userid) !== -1;
}
const isEnrolled = computed(() => enrolled(mainStore.currentUser.userid));
const canEnroll = computed(() => {
const is = isEnrolled.value;
let sum = 0;
props.modelValue.services.forEach((s) => (sum += s.value));
return sum < props.modelValue.required_services && !is;
});
async function signOutFromJob() { async function signOutFromJob() {
const newService: FG.Service = { const newService: FG.Service = {
userid: mainStore.currentUser.userid, userid: mainStore.currentUser.userid,
@ -127,13 +218,23 @@ export default defineComponent({
} }
return { return {
enroll,
availableUsers, availableUsers,
enrollForJob, canEdit,
isEnrolled, isEnrolled,
enrolled,
signOutFromJob, signOutFromJob,
enrollDialog,
canEnroll, canEnroll,
remove,
userAvatar,
userDisplay, userDisplay,
options,
iam,
dialog,
service,
asHour, asHour,
asDate,
}; };
}, },
}); });