diff --git a/src/api.d.ts b/src/api.d.ts index bf406f8..fc76ce3 100644 --- a/src/api.d.ts +++ b/src/api.d.ts @@ -13,11 +13,13 @@ declare namespace FG { id: number; name: string; } - interface Invite { + interface Invitation { id: number; job_id: number; invitee_id: string; - sender_id: string; + inviter_id: string; + transferee_id?: string; + transferee: User; } interface Job { id: number; @@ -25,9 +27,9 @@ declare namespace FG { end?: Date; type: JobType | number; comment?: string; + locked: boolean; services: Array; required_services: number; - locked: boolean; } interface JobType { id: number; diff --git a/src/components/overview/slots/JobSlot.vue b/src/components/overview/slots/JobSlot.vue index b8cea89..9631b6e 100644 --- a/src/components/overview/slots/JobSlot.vue +++ b/src/components/overview/slots/JobSlot.vue @@ -32,7 +32,7 @@ flat color="primary" label="Eintragen" - @click="enrollForJob" + @click="assignJob()" /> @@ -44,7 +44,7 @@ Tauschen - + Austragen @@ -115,46 +115,21 @@ export default defineComponent({ ) ); - async function enrollForJob() { + async function assignJob(assign = true) { const newService: FG.Service = { userid: mainStore.currentUser.userid, is_backup: false, - value: 1, + value: assign ? 1 : -1, }; try { - await store.assignToJob(props.modelValue.id, newService); - const job = Object.assign({}, props.modelValue) - job.services.push(newService) + const job = await store.assignToJob(props.modelValue.id, newService); emit('update:modelValue', job); } catch (error) { console.warn(error); quasar.notify({ group: false, type: 'negative', - message: 'Fehler beim Eintragen als Dienst', - timeout: 10000, - progress: true, - actions: [{ icon: 'mdi-close', color: 'white' }], - }); - } - } - async function signOutFromJob() { - const newService: FG.Service = { - userid: mainStore.currentUser.userid, - is_backup: false, - value: -1, - }; - try { - await store.assignToJob(props.modelValue.id, newService); - const job = Object.assign({}, props.modelValue) - job.services.push(newService) - emit('update:modelValue', job); - } catch (error) { - console.warn(error); - quasar.notify({ - group: false, - type: 'negative', - message: 'Fehler beim Austragen als Dienst', + message: 'Fehler beim Ein- oder Austragen als Dienst', timeout: 10000, progress: true, actions: [{ icon: 'mdi-close', color: 'white' }], @@ -166,19 +141,18 @@ export default defineComponent({ quasar.dialog({ component: TransferInviteDialog, componentProps: { - invite: isInvite, + isInvite: isInvite, job: props.modelValue, }, }); } return { + assignJob, canInvite, - enrollForJob, isEnrolled, isFull, invite: () => invite(true), - signOutFromJob, transfer: () => invite(false), typeName, userDisplay, diff --git a/src/components/overview/slots/TransferInviteDialog.vue b/src/components/overview/slots/TransferInviteDialog.vue index d0f6b1b..d95ee5d 100644 --- a/src/components/overview/slots/TransferInviteDialog.vue +++ b/src/components/overview/slots/TransferInviteDialog.vue @@ -65,10 +65,9 @@ export default defineComponent({ ); function invite() { - store - .sendInvite(props.job, invitees.value, !props.isInvite) - .then(() => onDialogOK()) - .catch(() => onDialogCancel()); + void store + .invite(props.job, invitees.value, !props.isInvite ? mainStore.currentUser : undefined) + .then(() => onDialogOK()); } return { diff --git a/src/events.d.ts b/src/events.d.ts index ec9d101..bbb6f0e 100644 --- a/src/events.d.ts +++ b/src/events.d.ts @@ -1,9 +1,25 @@ -declare namespace FG { - export interface RecurrenceRule { - frequency: string; - interval: number; - count?: number; - until?: Date; - weekdays?: Array; - } +import { FG_Plugin } from "@flaschengeist/types"; + +export interface RecurrenceRule { + frequency: string; + interval: number; + count?: number; + until?: Date; + weekdays?: Array; +} + +interface InvitationData { + invitation: number; +} + +interface InvitationResponseData { + event: number, + job: number, + invitee: string +} + +export interface EventNotification extends FG_Plugin.Notification { + data: { + type: number + } & (InvitationData | InvitationResponseData); } diff --git a/src/index.ts b/src/index.ts index 8f0ef84..30353b3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,39 @@ import { innerRoutes, privateRoutes } from './routes'; import { FG_Plugin } from '@flaschengeist/types'; import { defineAsyncComponent } from 'vue'; +import { EventNotification, InvitationData, InvitationResponseData } from './events'; +import { useEventStore } from './store'; + +const EventTypes = { + _mask_: 0xf0, + invitation: 0x00, + invite: 0x01, + transfer: 0x02, + invitation_response: 0x10, + invitation_accepted: 0x10, + invitation_rejected: 0x11, +}; + +function transpile(msg: FG_Plugin.Notification) { + const message = msg as EventNotification; + message.icon = 'mdi-calendar'; + if ((message.data.type & EventTypes._mask_) === EventTypes.invitation) { + message.accept = () => { + const store = useEventStore(); + return store.acceptInvitation((message.data).invitation); + }; + + message.reject = () => { + const store = useEventStore(); + return store.rejectInvitation((message.data).invitation); + }; + + message.link = { name: 'events-requests' }; + } else if ((message.data.type & EventTypes._mask_) === EventTypes.invitation_response) { + message.link = {name: 'events-single-view', params: {id: (message.data).event}} + } + return message; +} const plugin: FG_Plugin.Plugin = { id: 'dev.flaschengeist.events', @@ -9,6 +42,7 @@ const plugin: FG_Plugin.Plugin = { internalRoutes: privateRoutes, requiredModules: [['events']], version: '0.0.1', + notification: transpile, widgets: [ { priority: 0, diff --git a/src/pages/EventPage.vue b/src/pages/EventPage.vue index d97cf1f..2e77c78 100644 --- a/src/pages/EventPage.vue +++ b/src/pages/EventPage.vue @@ -1,25 +1,37 @@