import { api, isAxiosError } from '@flaschengeist/api'; import { defineStore } from 'pinia'; import { EditableEvent } from './models'; import { Notify } from 'quasar'; /** * Convert JSON decoded Job to real job (fix Date object) */ function fixJob(job: FG.Job) { job.start = new Date(job.start); if (job.end) job.end = new Date(job.end); return job; } /** * Convert JSON decoded Event to real Event object (fix Date object) */ function fixEvent(event: FG.Event) { event.start = new Date(event.start); if (event.end) event.end = new Date(event.end); event.jobs.forEach((job) => fixJob(job)); } export const useEventStore = defineStore({ id: 'events', state: () => ({ jobTypes: [] as FG.JobType[], eventTypes: [] as FG.EventType[], templates: [] as FG.Event[], invitations: [] as FG.Invitation[], }), getters: {}, actions: { async getJobTypes(force = false) { if (force || this.jobTypes.length == 0) try { const { data } = await api.get('/events/job-types'); this.jobTypes = data; } catch (error) { throw error; } return this.jobTypes; }, addJobType(name: string) { return api .post('/events/job-types', { name: name }) .then(({ data }) => this.jobTypes.push(data)); }, removeJobType(id: number) { return api .delete(`/events/job-types/${id}`) .then(() => (this.jobTypes = this.jobTypes.filter((v) => v.id !== id))); }, renameJobType(id: number, newName: string) { return api.put(`/events/job-types/${id}`, { name: newName }).then(() => { const idx = this.jobTypes.findIndex((v) => v.id === id); if (idx >= 0) this.jobTypes[idx].name = newName; }); }, async getEventTypes(force = false) { if (force || this.eventTypes.length == 0) try { const { data } = await api.get('/events/event-types'); this.eventTypes = data; } catch (error) { throw error; } return this.eventTypes; }, /** Add new EventType * * @param name Name of new EventType */ addEventType(name: string) { return api .post('/events/event-types', { name: name }) .then(({ data }) => this.eventTypes.push(data)); }, removeEventType(id: number) { return api .delete(`/events/event-types/${id}`) .then(() => (this.eventTypes = this.eventTypes.filter((v) => v.id !== id))); }, renameEventType(id: number, newName: string) { return api.put(`/events/event-types/${id}`, { name: newName }).then(() => { const idx = this.eventTypes.findIndex((v) => v.id === id); if (idx >= 0) this.eventTypes[idx].name = newName; }); }, async getTemplates(force = false) { if (force || this.templates.length == 0) { const { data } = await api.get('/events/templates'); data.forEach((element) => fixEvent(element)); this.templates = data; } return this.templates; }, async getEvents( filter?: FG.PaginationFilter & { user?: string; } ) { try { const { data } = await api.get>('/events', { params: filter, }); data.result.forEach((element) => fixEvent(element)); return data; } catch (error) { throw error; } }, async getEvent(id: number) { try { const { data } = await api.get(`/events/${id}`); fixEvent(data); return data; } catch (error) { throw error; } }, async removeEvent(id: number) { try { await api.delete(`/events/${id}`); const idx = this.templates.findIndex((v) => v.id === id); if (idx !== -1) this.templates.splice(idx, 1); } catch (e) { if (isAxiosError(e, 404)) return false; throw e; } return true; }, async addEvent(event: EditableEvent) { if (event?.id === undefined) { const { data } = await api.post('/events', event); if (data.is_template) this.templates.push(data); fixEvent(data); return data; } else { if (typeof event.type === 'object') event.type = event.type.id; const { data } = await api.put(`/events/${event.id}`, event); if (data.is_template) this.templates.push(data); fixEvent(data); return data; } }, async assignToJob(jobId: number, service: FG.Service) { return api .post(`/events/jobs/${jobId}/assign`, service) .then(({ data }) => fixJob(data)); }, async getJob(id: number) { return api.get(`/events/jobs/${id}`).then(({ data }) => fixJob(data)); }, async getJobs(filter?: FG.PaginationFilter) { return api .get>('/events/jobs', { params: filter }) .then(({ data }) => { data.result.forEach((j) => fixJob(j)); return data; }); }, /** * Send invite to job or transfer to other user * @param job Job to invite to * @param invitees Users to invite * @param isTransfer set to True to transfer service instead of invite */ async invite(job: FG.Job, invitees: FG.User[], transferee: FG.User | undefined = undefined) { return api.post('/events/invitations', { job: job.id, invitees: invitees.map((v) => v.userid), transferee: transferee?.userid, }); }, async getInvitations(force = false) { if (this.invitations.length == 0 || force) { const { data } = await api.get('/events/invitations'); this.invitations = data; } return this.invitations; }, async rejectInvitation(invite: FG.Invitation | number) { try { await api.delete(`/events/invitations/${typeof invite === 'number' ? invite : invite.id}`); const idx = this.invitations.findIndex((v) => v.id === (invite.id || invite)); if (idx >= 0) this.invitations.splice(idx, 1); notify_success('Einladung für erfolgreich abgelehnt'); } catch (e) { notify_failure(); } }, async acceptInvitation(invite: FG.Invitation | number) { try { await api.put(`/events/invitations/${typeof invite === 'number' ? invite : invite.id}`, { accept: true, }); const idx = this.invitations.findIndex((v) => v.id === (invite.id || invite)); if (idx >= 0) this.invitations.splice(idx, 1); notify_success('Einladung für erfolgreich angenommen'); } catch (e) { notify_failure(); } }, }, }); function notify_failure() { Notify.create({ message: 'Es ist ein Fehler aufgetreten.', color: 'negative', group: false, timeout: 10000, actions: [{ icon: 'mdi-close', color: 'white' }], }); } function notify_success(msg: string) { Notify.create({ message: msg, color: 'positive', group: false, timeout: 5000, actions: [{ icon: 'mdi-close', color: 'white' }], }); }