<template> <q-page padding> <q-card> <q-form @submit="save()" @reset="reset"> <q-card-section class="fit row justify-start content-center items-center"> <div class="text-h6 col-xs-12 col-sm-6 q-pa-sm">Veranstaltung erstellen</div> <q-select :model-value="template" filled label="Vorlage" class="col-xs-12 col-sm-6 q-pa-sm" :options="templates" option-label="name" map-options clearable :disable="templates.length == 0" @update:modelValue="fromTemplate" @clear="reset()" /> <q-input v-model="event.name" class="col-xs-12 col-sm-6 q-pa-sm" label="Name" type="text" filled /> <q-select v-model="event.type" filled use-input label="Veranstaltungstyp" input-debounce="0" class="col-xs-12 col-sm-6 q-pa-sm" :options="eventtypes" option-label="name" option-value="id" emit-value map-options clearable :rules="[notEmpty]" /> <IsoDateInput v-model="event.start" class="col-xs-12 col-sm-6 q-pa-sm" label="Veranstaltungsbeginn" :rules="[notEmpty]" /> <IsoDateInput v-model="event.end" class="col-xs-12 col-sm-6 q-pa-sm" label="Veranstaltungsende" /> <q-input v-model="event.description" class="col-12 q-pa-sm" label="Beschreibung" type="textarea" filled /> </q-card-section> <q-card-section v-if="event.template_id === undefined"> <q-btn-toggle v-model="recurrent" spread no-caps :options="[ { label: 'Einmalig', value: false }, { label: 'Wiederkehrend', value: true }, ]" /> <RecurrenceRule v-if="!!recurrent" v-model="recurrenceRule" /> </q-card-section> <q-separator /> <q-card-section> <q-btn color="primary" label="Schicht hinzufügen" @click="addJob()" /> </q-card-section> <q-card-section v-for="(job, index) in event.jobs" :key="index"> <q-card class="q-my-auto"> <job v-model="event.jobs[index]" :job-can-delete="jobDeleteDisabled" @remove-job="removeJob(index)" /> </q-card> </q-card-section> <q-card-actions align="right"> <q-btn label="Reset" type="reset" /> <q-btn color="secondary" label="Neue Vorlage" @click="save(true)" /> <q-btn color="primary" type="submit" label="Erstellen" /> </q-card-actions> </q-form> </q-card> </q-page> </template> <script lang="ts"> import { defineComponent, ref, onBeforeMount, computed } from 'vue'; import IsoDateInput from 'src/components/utils/IsoDateInput.vue'; import Job from './Job.vue'; import RecurrenceRule from './RecurrenceRule.vue'; import { date, ModifyDateOptions } from 'quasar'; import { useScheduleStore } from '../../store'; import { notEmpty } from 'src/utils/validators'; export default defineComponent({ name: 'CreateEvent', components: { IsoDateInput, Job, RecurrenceRule }, setup() { const store = useScheduleStore(); const emptyJob = { id: NaN, start: new Date(), end: date.addToDate(new Date(), { hours: 1 }), services: [], required_services: 2, type: store.jobTypes[0], }; const emptyEvent = { id: NaN, start: new Date(), jobs: [Object.assign({}, emptyJob)], type: store.eventTypes[0], is_template: false, }; const templates = computed(() => store.templates); const template = ref<FG.Event | undefined>(undefined); const event = ref<FG.Event>(Object.assign({}, emptyEvent)); const eventtypes = computed(() => store.eventTypes); const jobDeleteDisabled = computed(() => event.value.jobs.length < 2); const recurrent = ref(false); const recurrenceRule = ref<FG.RecurrenceRule>({ frequency: 'daily', interval: 1 }); onBeforeMount(() => { void store.getEventTypes(); void store.getJobTypes(); void store.getTemplates(); }); function addJob() { event.value.jobs.push(Object.assign({}, emptyJob)); } function removeJob(index: number) { event.value.jobs.splice(index, 1); } function fromTemplate(tpl: FG.Event) { template.value = tpl; event.value = Object.assign({}, tpl); } async function save(template = false) { console.log(template); event.value.is_template = template; try { await store.addEvent(event.value); if (recurrent.value && !event.value.is_template) { let count = 0; const options: ModifyDateOptions = {}; switch (recurrenceRule.value.frequency) { case 'daily': options['days'] = 1 * recurrenceRule.value.interval; break; case 'weekly': options['days'] = 7 * recurrenceRule.value.interval; break; case 'monthly': options['months'] = 1 * recurrenceRule.value.interval; break; } while (true) { event.value.start = date.addToDate(event.value.start, options); if (event.value.end) event.value.end = date.addToDate(event.value.end, options); event.value.jobs.forEach((job) => { job.start = date.addToDate(job.start, options); if (job.end) job.end = date.addToDate(job.end, options); }); count++; if ( count <= 120 && (!recurrenceRule.value.count || count <= recurrenceRule.value.count) && (!recurrenceRule.value.until || event.value.start < recurrenceRule.value.until) ) await store.addEvent(event.value); else break; } } reset(); } catch (error) { console.error(error); } } function reset() { event.value = Object.assign({}, emptyEvent); template.value = undefined; } return { jobDeleteDisabled, addJob, eventtypes, templates, removeJob, notEmpty, save, reset, recurrent, fromTemplate, template, recurrenceRule, event, }; }, }); </script> <style></style>