From 76978e888379d522e74ed0e76c0b115bad5bccd8 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Wed, 10 Feb 2021 17:37:43 +0100 Subject: [PATCH] [Pinia] Use pinia for schedule --- .../components/management/CreateEvent.vue | 23 +- .../components/management/Eventtypes.vue | 48 ++-- .../schedule/components/management/Job.vue | 14 +- .../components/management/JobTypes.vue | 38 ++- .../components/overview/AgendaView.vue | 50 ++-- .../components/overview/slots/EventSlot.vue | 93 ++++--- src/plugins/schedule/pages/MainPage.vue | 9 +- src/plugins/schedule/plugin.ts | 4 - src/plugins/schedule/store.ts | 125 +++++++++ src/plugins/schedule/store/schedule.ts | 245 ------------------ 10 files changed, 248 insertions(+), 401 deletions(-) create mode 100644 src/plugins/schedule/store.ts delete mode 100644 src/plugins/schedule/store/schedule.ts diff --git a/src/plugins/schedule/components/management/CreateEvent.vue b/src/plugins/schedule/components/management/CreateEvent.vue index 7d1f9d8..99ac748 100644 --- a/src/plugins/schedule/components/management/CreateEvent.vue +++ b/src/plugins/schedule/components/management/CreateEvent.vue @@ -67,17 +67,15 @@ import { defineComponent, ref, onBeforeMount, computed } from 'vue'; import IsoDateInput from 'src/components/utils/IsoDateInput.vue'; import Job from './Job.vue'; -import { mapGetters, useStore } from 'vuex'; -import { StateInterface } from 'src/store'; import { date } from 'quasar'; +import { useScheduleStore } from '../../store'; export default defineComponent({ name: 'CreateEvent', components: { IsoDateInput, Job }, setup() { - const store = useStore(); - const scheduleGetters = mapGetters('schedule', ['eventTypes']); - const eventtypes = computed(() => scheduleGetters.eventTypes()); + const store = useScheduleStore(); + const eventtypes = computed(() => store.eventTypes); const jobDeleteDisabled = computed(() => event.value.jobs.length < 2); const newJob = ref(({ @@ -97,8 +95,8 @@ export default defineComponent({ } as FG.Event); onBeforeMount(() => { - void store.dispatch('schedule/getEventTypes'); - void store.dispatch('schedule/getJobTypes'); + void store.getEventTypes(); + void store.getJobTypes(); }); function setStart(data: { job: FG.Job; value: Date }) { @@ -137,11 +135,14 @@ export default defineComponent({ event.value.jobs.splice(index, 1); } - function save() { + async function save() { console.log('Event:', event); - store.dispatch('schedule/addEvent', event.value).catch((error) => { - console.warn(error); - }); + try { + await store.addEvent(event.value); + reset(); + } catch (error) { + console.error(error); + } } function reset() { diff --git a/src/plugins/schedule/components/management/Eventtypes.vue b/src/plugins/schedule/components/management/Eventtypes.vue index 950e428..d258ff1 100644 --- a/src/plugins/schedule/components/management/Eventtypes.vue +++ b/src/plugins/schedule/components/management/Eventtypes.vue @@ -46,30 +46,22 @@ diff --git a/src/plugins/schedule/components/overview/slots/EventSlot.vue b/src/plugins/schedule/components/overview/slots/EventSlot.vue index b21671a..c42c59c 100644 --- a/src/plugins/schedule/components/overview/slots/EventSlot.vue +++ b/src/plugins/schedule/components/overview/slots/EventSlot.vue @@ -68,10 +68,11 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { defineComponent, ref, onBeforeMount, PropType } from 'vue'; import { useRouter } from 'vue-router'; -import { useStore } from 'vuex'; -import { StateInterface } from 'src/store'; -import { date } from 'quasar'; -import { asHour } from '../../../../../utils/datetime'; +import { date, Notify } from 'quasar'; +import { asHour } from 'src/utils/datetime'; +import { useUserStore } from 'src/plugins/user/store'; +import { useMainStore } from 'src/store'; +import { useScheduleStore } from 'src/plugins/schedule/store'; export default defineComponent({ name: 'Eventslot', @@ -91,72 +92,72 @@ export default defineComponent({ }, setup(props) { - const store = useStore(); - const state = store.state.users; + const store = useScheduleStore(); + const mainStore = useMainStore(); + const userStore = useUserStore(); const router = useRouter(); const availableUsers = null; const refreshKey = ref(0); - const users = ref(state.users); + onBeforeMount(async () => userStore.getUsers()); + function refresh() { router.go(0); refreshKey.value += 1; } - onBeforeMount(() => { - store.dispatch('user/getUsers').catch((error) => { - console.warn(error); - }); - }); function isUserEnrolled(job: FG.Job) { return ( - job.services.filter((service) => service.userid == state.currentUser?.userid).length >= 1 + job.services.findIndex((service) => service.userid == mainStore.currentUser.userid) >= 0 ); } + function jobFull(job: FG.Job) { console.log('jobFull', job.services.length >= job.required_services); return job.services.length >= job.required_services; } + function userDisplay(userid: string) { - return state.users.find((user) => (user.userid = userid))?.display_name; + return userStore.users.find((user) => (user.userid = userid))?.display_name; } - function enrollForJob(job: FG.Job) { - console.log(job.services); - if (state.currentUser) { - const newService: FG.Service = { - userid: state.currentUser?.userid, - value: 1, - }; - - const newUserService = { user: newService }; - const UpdateInformation = { - eventId: props.event.id, - JobId: job.id, - service: newUserService, - }; - void store.dispatch('schedule/updateEvent', UpdateInformation).catch((error) => { - console.warn(error); + async function enrollForJob(job: FG.Job) { + const newService: FG.Service = { + userid: mainStore.currentUser.userid, + value: 1, + }; + try { + await store.updateEvent(props.event.id, job.id, { user: newService }); + } catch (error) { + console.warn(error); + Notify.create({ + group: false, + type: 'negative', + message: 'Fehler beim Eintragen als Dienst', + timeout: 10000, + progress: true, + actions: [{ icon: 'mdi-close', color: 'white' }], }); } refresh(); } - function signOutFromJob(job: FG.Job) { - console.log(job.services); - if (state.currentUser) { - const newService: FG.Service = { - userid: state.currentUser?.userid, - value: -1, - }; + async function signOutFromJob(job: FG.Job) { + const newService: FG.Service = { + userid: mainStore.currentUser.userid, + value: -1, + }; - const newUserService = { user: newService }; - const UpdateInformation = { - eventId: props.event.id, - JobId: job.id, - service: newUserService, - }; - void store.dispatch('schedule/updateEvent', UpdateInformation).catch((error) => { - console.warn(error); + try { + await store.updateEvent(props.event.id, job.id, { user: newService }); + } catch (error) { + console.warn(error); + Notify.create({ + group: false, + type: 'negative', + message: 'Fehler beim Austragen als Dienst', + timeout: 10000, + progress: true, + actions: [{ icon: 'mdi-close', color: 'white' }], }); } refresh(); @@ -166,8 +167,6 @@ export default defineComponent({ refreshKey, availableUsers, enrollForJob, - state, - users, isUserEnrolled, signOutFromJob, jobFull, diff --git a/src/plugins/schedule/pages/MainPage.vue b/src/plugins/schedule/pages/MainPage.vue index c5fc1cc..939c072 100644 --- a/src/plugins/schedule/pages/MainPage.vue +++ b/src/plugins/schedule/pages/MainPage.vue @@ -24,24 +24,17 @@ import { computed, defineComponent } from 'vue'; import EssentialLink from 'src/components/navigation/EssentialLink.vue'; import mainRoutes from 'src/plugins/schedule/routes'; -import { mapGetters } from 'vuex'; -import setLoadingBar from 'src/utils/loading'; import { useRoute } from 'vue-router'; + export default defineComponent({ // name: 'PageName' components: { EssentialLink }, setup() { - const balanceGetters = mapGetters('balance', ['loading']); const route = useRoute(); - const loading = computed(() => { - return balanceGetters.loading() > 0; - }); const checkMain = computed(() => { return route.matched.length == 2; }); - setLoadingBar(loading); - return { checkMain, mainRoutes }; }, }); diff --git a/src/plugins/schedule/plugin.ts b/src/plugins/schedule/plugin.ts index c8364c1..21741da 100644 --- a/src/plugins/schedule/plugin.ts +++ b/src/plugins/schedule/plugin.ts @@ -1,9 +1,6 @@ -import { Module } from 'vuex'; import { defineAsyncComponent } from 'vue'; import mainRoutes from './routes'; import { FG_Plugin } from 'src/plugins'; -import { StateInterface } from 'src/store'; -import store, { ScheduleInterface } from './store/schedule'; const plugin: FG_Plugin.Plugin = { name: 'Schedule', @@ -11,7 +8,6 @@ const plugin: FG_Plugin.Plugin = { requiredModules: ['User'], requiredBackendModules: ['schedule'], version: '0.0.1', - store: new Map>([['schedule', store]]), widgets: [ { priority: 0, diff --git a/src/plugins/schedule/store.ts b/src/plugins/schedule/store.ts new file mode 100644 index 0000000..f56bcd4 --- /dev/null +++ b/src/plugins/schedule/store.ts @@ -0,0 +1,125 @@ +import { api } from 'src/boot/axios'; +import { AxiosError } from 'axios'; +import { defineStore } from 'pinia'; + +interface UserService { + user: FG.Service; +} + +function fixEvent(event: FG.Event) { + event.start = new Date(event.start); + event.end = new Date(event.end); +} + +export const useScheduleStore = defineStore({ + id: 'schedule', + + state: () => ({ + jobTypes: [] as FG.JobType[], + eventTypes: [] as FG.EventType[], + }), + + getters: {}, + + actions: { + async getJobTypes() { + try { + const { data } = await api.get('/schedule/job-types'); + this.jobTypes = data; + return this.jobTypes; + } catch (error) { + throw error; + } + }, + + async addJobType(name: string) { + await api.post('/schedule/job-types', { name: name }); + //TODO: HAndle new JT + }, + + async removeJobType(id: number) { + await api.delete(`/schedule/job-types/${id}`); + //Todo Handle delete JT + }, + + async renameJobType(id: number, newName: string) { + await api.put(`/schedule/job-types/${id}`, { name: newName }); + // TODO handle rename + }, + + async getEventTypes() { + try { + const { data } = await api.get('/schedule/event-types'); + this.eventTypes = data; + } catch (error) { + throw error; + } + }, + + /** Add new EventType + * + * @param name Name of new EventType + * @returns EventType object or null if name already exists + * @throws Exception if requests fails because of an other reason + */ + async addEventType(name: string) { + try { + const { data } = await api.post('/schedule/event-types', { name: name }); + return data; + } catch (error) { + if ('response' in error) { + const ae = error; + if (ae.response && ae.response.status == 409 /* CONFLICT */) return null; + } + throw error; + } + }, + + async removeEventType(id: number) { + await api.delete(`/schedule/event-types/${id}`); + // TODO handle delete + }, + + async renameEventType(id: number, newName: string) { + try { + await api.put(`/schedule/event-types/${id}`, { name: newName }); + // TODO handle rename + return true; + } catch (error) { + if ('response' in error) { + const ae = error; + if (ae.response && ae.response.status == 409 /* CONFLICT */) return false; + } + throw error; + } + }, + + async getEvents(filter: { from?: Date; to?: Date } | undefined = undefined) { + try { + const { data } = await api.get('/schedule/events', { params: filter }); + data.forEach((element) => fixEvent(element)); + return data; + } catch (error) { + throw error; + } + }, + async updateEvent(eventId: number, jobId: number, service: FG.Service | UserService) { + try { + const { data } = await api.put( + `/schedule/events/${eventId}/jobs/${jobId}`, + service + ); + fixEvent(data); + return data; + } catch (error) { + throw error; + } + }, + + async addEvent(event: FG.Event) { + const { data } = await api.post('/schedule/events', event); + return data; + //TODO: Handle add event} + }, + }, +}); diff --git a/src/plugins/schedule/store/schedule.ts b/src/plugins/schedule/store/schedule.ts deleted file mode 100644 index 260ea8b..0000000 --- a/src/plugins/schedule/store/schedule.ts +++ /dev/null @@ -1,245 +0,0 @@ -import { Module, MutationTree, ActionTree, GetterTree } from 'vuex'; -import { StateInterface } from 'src/store'; -import { axios } from 'src/boot/axios'; -import { AxiosResponse } from 'axios'; - -export interface JobType { - id: number; - name: string; -} - -export interface EventType { - id: number; - name: string; -} - -export interface ScheduleInterface { - jobTypes: JobType[]; - eventTypes: EventType[]; - events: FG.Event[]; -} - -const state: ScheduleInterface = { - jobTypes: [], - eventTypes: [], - events: [], -}; - -interface Event { - start: Date; - end?: Date; - description: string; - type: EventType; - jobs: Job[]; -} - -interface Job { - id: number; - start: Date | null; - end?: Date | null; - comment: string; - type: FG.JobType | null; - services: Array; - required_services: number; -} - -const mutations: MutationTree = { - setJobTypes(state, jobTypes: JobType[]) { - state.jobTypes = jobTypes; - }, - addJobType(state, jobType: JobType) { - state.jobTypes.unshift(jobType); - }, - removeJobType(state, id: number) { - const index = state.jobTypes.findIndex((item) => item.id == id); - state.jobTypes.splice(index, 1); - }, - setJobType(state, jobType: JobType) { - const _jobtype = state.jobTypes.find((item) => item.id == jobType.id); - if (_jobtype) { - _jobtype.name = jobType.name; - } - }, - setEventTypes(state, eventTypes: EventType[]) { - state.eventTypes = eventTypes; - }, - addEventType(state, eventType: EventType) { - state.eventTypes.unshift(eventType); - }, - removeEventType(state, id: number) { - const index = state.eventTypes.findIndex((item) => item.id == id); - state.eventTypes.splice(index, 1); - }, - setEventType(state, eventType: EventType) { - const _eventtype = state.eventTypes.find((item) => item.id == eventType.id); - if (_eventtype) { - _eventtype.name = eventType.name; - } - }, - addEvent(state, event: FG.Event) { - state.events.unshift(event); - }, - setEvents(state, events: FG.Event[]) { - state.events = events; - }, - updateEvent(state, event: FG.Event) { - /*let eventToChange = state.events.find(ev => ev.id == event.id); - eventToChange = event; */ - const index = state.events.findIndex((ev) => ev.id == event.id); - if (index > -1) { - state.events[index] = event; - } - }, -}; - -const actions: ActionTree = { - getJobTypes({ commit }) { - axios - .get('/schedule/job-types') - .then((response: AxiosResponse) => { - console.log('action:', response.data); - commit('setJobTypes', response.data); - }) - .catch((err) => { - console.warn(err); - }); - }, - - addJobType({ commit }, data) { - axios - .post('/schedule/job-types', data) - .then((response: AxiosResponse) => { - commit('addJobType', response.data); - }) - .catch((err) => { - console.warn(err); - }); - }, - - removeJobType({ commit }, data: number) { - axios - .delete(`/schedule/job-types/${data}`) - .then(() => { - commit('removeJobType', data); - }) - .catch((err) => { - console.warn(err); - }); - }, - - changeJobTypeName({ commit }, jobtype: JobType) { - axios - .put(`/schedule/job-types/${jobtype.id}`, jobtype) - .then(() => { - commit('setJobType', jobtype); - }) - .catch((err) => { - console.warn(err); - }); - }, - - getEventTypes({ commit }) { - axios - .get('/schedule/event-types') - .then((response: AxiosResponse) => { - console.log('action:', response.data); - commit('setEventTypes', response.data); - }) - .catch((err) => { - console.warn(err); - }); - }, - - addEventType({ commit }, data) { - console.log(data); - axios - .post('/schedule/event-types', data) - .then((response: AxiosResponse) => { - commit('addEventType', response.data); - }) - .catch((err) => { - console.warn(err); - }); - }, - removeEventType({ commit }, data: number) { - axios - .delete(`/schedule/event-types/${data}`) - .then(() => { - commit('removeEventType', data); - }) - .catch((err) => { - console.warn(err); - }); - }, - changeEventTypeName({ commit }, eventtype: { id: number; name: string; oldname: string }) { - axios - .put(`/schedule/event-types/${eventtype.id}`, eventtype) - .then(() => { - commit('setEventType', eventtype); - }) - .catch((err) => { - console.warn(err); - }); - }, - - addEvent({ commit }, event: Event) { - axios - .post('/schedule/events', event) - .then((response: AxiosResponse) => { - commit('addEvent', response.data); - }) - .catch((err) => { - console.warn(err); - }); - console.log('Events: ', state.events); - }, - updateEvent( - { commit }, - updateInformation: { eventId: number; JobId: number; service: FG.Service } - ) { - axios - .put( - `/schedule/events/${updateInformation.eventId}/jobs/${updateInformation.JobId}`, - updateInformation.service - ) - .then((response: AxiosResponse) => { - response.data.start = new Date(response.data.start); - commit('updateEvent', response.data); - }) - .catch((err) => { - console.warn(err); - }); - }, - getEvents({ commit }) { - axios - .get('/schedule/events') - .then((response: AxiosResponse) => { - console.log('action:', response.data); - response.data.forEach((event) => { - event.start = new Date(event.start); - }); - commit('setEvents', response.data); - }) - .catch((err) => { - console.warn(err); - }); - }, -}; -const getters: GetterTree = { - jobTypes(state) { - return state.jobTypes; - }, - events(state) { - return state.events; - }, -}; - -const schedule: Module = { - namespaced: true, - state, - mutations, - actions, - getters, -}; - -export default schedule;