2021-01-23 13:40:35 +00:00
|
|
|
<template>
|
2021-03-25 13:11:54 +00:00
|
|
|
<q-card>
|
2021-03-28 01:38:26 +00:00
|
|
|
<q-form ref="form" @submit="save()" @reset="reset">
|
2021-03-25 13:11:54 +00:00
|
|
|
<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">
|
2021-03-28 19:21:04 +00:00
|
|
|
Veranstaltung <template v-if="modelValue.id">bearbeiten</template
|
2021-03-25 13:11:54 +00:00
|
|
|
><template v-else>erstellen</template>
|
|
|
|
</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 && modelValue === 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>
|
2021-03-28 01:38:26 +00:00
|
|
|
<q-card-section class="row justify-around" align="around">
|
|
|
|
<div class="text-h6 text-center col-6">Schichten</div>
|
|
|
|
<div class="col-6 text-center">
|
|
|
|
<q-btn color="primary" label="Schicht hinzufügen" @click="addJob()" />
|
|
|
|
</div>
|
|
|
|
</q-card-section>
|
|
|
|
<template v-for="(job, index) in event.jobs" :key="index">
|
2021-03-25 13:11:54 +00:00
|
|
|
<job
|
|
|
|
v-model="event.jobs[index]"
|
2021-03-28 01:38:26 +00:00
|
|
|
:can-delete="jobDeleteDisabled"
|
2021-03-25 13:11:54 +00:00
|
|
|
@remove-job="removeJob(index)"
|
2021-03-20 23:58:31 +00:00
|
|
|
/>
|
2021-03-28 01:38:26 +00:00
|
|
|
</template>
|
2021-03-25 13:11:54 +00:00
|
|
|
</q-card-section>
|
|
|
|
<q-card-actions align="around">
|
|
|
|
<q-card-actions align="left">
|
2021-03-28 19:21:04 +00:00
|
|
|
<q-btn v-if="template" color="negative" label="Vorlage löschen" @click="removeTemplate" />
|
|
|
|
<q-btn color="secondary" label="Vorlage speichern" @click="save(true)" />
|
2021-01-23 13:40:35 +00:00
|
|
|
</q-card-actions>
|
2021-03-25 13:11:54 +00:00
|
|
|
<q-card-actions align="right">
|
|
|
|
<q-btn label="Zurücksetzen" type="reset" />
|
|
|
|
<q-btn color="primary" type="submit" label="Speichern" />
|
|
|
|
</q-card-actions>
|
|
|
|
</q-card-actions>
|
|
|
|
</q-form>
|
|
|
|
</q-card>
|
2021-01-23 13:40:35 +00:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts">
|
2021-03-24 19:49:35 +00:00
|
|
|
import { computed, defineComponent, PropType, ref, onBeforeMount } from 'vue';
|
2021-03-28 19:21:04 +00:00
|
|
|
import { ModifyDateOptions, QForm, date as qdate } from 'quasar';
|
2021-02-10 16:37:43 +00:00
|
|
|
import { useScheduleStore } from '../../store';
|
2021-03-28 01:38:26 +00:00
|
|
|
import { EditableEvent, emptyEvent, emptyJob } from '../../store/models';
|
2021-03-20 23:58:31 +00:00
|
|
|
import { notEmpty } from 'src/utils/validators';
|
2021-03-24 19:49:35 +00:00
|
|
|
import IsoDateInput from 'src/components/utils/IsoDateInput.vue';
|
|
|
|
import Job from './Job.vue';
|
|
|
|
import RecurrenceRule from './RecurrenceRule.vue';
|
2021-02-05 23:07:58 +00:00
|
|
|
|
2021-01-23 13:40:35 +00:00
|
|
|
export default defineComponent({
|
2021-03-24 19:49:35 +00:00
|
|
|
name: 'EditEvent',
|
2021-03-20 23:58:31 +00:00
|
|
|
components: { IsoDateInput, Job, RecurrenceRule },
|
2021-03-24 19:49:35 +00:00
|
|
|
props: {
|
|
|
|
modelValue: {
|
2021-03-28 19:21:04 +00:00
|
|
|
default: () => emptyEvent,
|
|
|
|
type: Object as PropType<EditableEvent>,
|
|
|
|
},
|
|
|
|
date: {
|
2021-03-24 19:49:35 +00:00
|
|
|
required: false,
|
2021-03-28 19:21:04 +00:00
|
|
|
default: () => new Date(),
|
|
|
|
type: [Object, String, Number] as PropType<Date | string | number>,
|
2021-03-24 19:49:35 +00:00
|
|
|
},
|
|
|
|
},
|
2021-03-25 13:11:54 +00:00
|
|
|
emits: {
|
|
|
|
done: (val: boolean) => typeof val === 'boolean',
|
|
|
|
},
|
|
|
|
setup(props, { emit }) {
|
2021-02-10 16:37:43 +00:00
|
|
|
const store = useScheduleStore();
|
2021-01-27 21:37:12 +00:00
|
|
|
|
2021-03-28 19:21:04 +00:00
|
|
|
const date = computed(() => new Date(props.date));
|
|
|
|
const event = ref<EditableEvent>(
|
|
|
|
props.modelValue.id
|
|
|
|
? props.modelValue
|
|
|
|
: Object.assign({}, props.modelValue, { start: date.value })
|
|
|
|
);
|
2021-03-20 23:58:31 +00:00
|
|
|
const eventtypes = computed(() => store.eventTypes);
|
2021-03-28 01:38:26 +00:00
|
|
|
const form = ref<QForm>();
|
2021-03-20 23:58:31 +00:00
|
|
|
const jobDeleteDisabled = computed(() => event.value.jobs.length < 2);
|
|
|
|
const recurrent = ref(false);
|
|
|
|
const recurrenceRule = ref<FG.RecurrenceRule>({ frequency: 'daily', interval: 1 });
|
2021-03-28 01:38:26 +00:00
|
|
|
const templates = computed(() => store.templates);
|
|
|
|
const template = ref<FG.Event>();
|
2021-01-26 19:38:46 +00:00
|
|
|
|
|
|
|
onBeforeMount(() => {
|
2021-02-10 16:37:43 +00:00
|
|
|
void store.getEventTypes();
|
|
|
|
void store.getJobTypes();
|
2021-03-20 23:58:31 +00:00
|
|
|
void store.getTemplates();
|
2021-01-26 19:38:46 +00:00
|
|
|
});
|
2021-01-27 21:37:12 +00:00
|
|
|
|
2021-01-26 19:38:46 +00:00
|
|
|
function addJob() {
|
2021-03-20 23:58:31 +00:00
|
|
|
event.value.jobs.push(Object.assign({}, emptyJob));
|
2021-01-26 19:38:46 +00:00
|
|
|
}
|
|
|
|
|
2021-01-27 23:55:17 +00:00
|
|
|
function removeJob(index: number) {
|
|
|
|
event.value.jobs.splice(index, 1);
|
2021-01-26 19:38:46 +00:00
|
|
|
}
|
2021-01-27 23:55:17 +00:00
|
|
|
|
2021-03-20 23:58:31 +00:00
|
|
|
function fromTemplate(tpl: FG.Event) {
|
|
|
|
template.value = tpl;
|
|
|
|
event.value = Object.assign({}, tpl);
|
2021-03-28 19:21:04 +00:00
|
|
|
event.value.start = new Date(
|
|
|
|
date.value.getUTCFullYear(),
|
|
|
|
date.value.getUTCMonth(),
|
|
|
|
date.value.getUTCDate()
|
|
|
|
);
|
2021-03-28 01:38:26 +00:00
|
|
|
const diff = event.value.start.getTime() - tpl.start.getTime();
|
|
|
|
console.log(event.value);
|
|
|
|
console.log(diff);
|
|
|
|
if (event.value.end) event.value.end = new Date(event.value.end.getTime() + diff);
|
|
|
|
|
|
|
|
event.value.jobs.forEach((job) => {
|
|
|
|
job.start.setTime(job.start.getTime() + diff);
|
|
|
|
if (job.end) job.end.setTime(job.end.getTime() + diff);
|
|
|
|
});
|
2021-03-20 23:58:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async function save(template = false) {
|
2021-03-28 01:38:26 +00:00
|
|
|
if (!(await form.value?.validate())) return;
|
2021-03-20 23:58:31 +00:00
|
|
|
event.value.is_template = template;
|
2021-02-10 16:37:43 +00:00
|
|
|
try {
|
2021-03-28 01:38:26 +00:00
|
|
|
// Casting is save as .validate() ensures that type property is set!
|
2021-03-28 19:21:04 +00:00
|
|
|
await store.saveEvent(<FG.Event>event.value);
|
2021-03-24 19:49:35 +00:00
|
|
|
if (props.modelValue === undefined && recurrent.value && !event.value.is_template) {
|
2021-03-20 23:58:31 +00:00
|
|
|
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) {
|
2021-03-28 19:21:04 +00:00
|
|
|
event.value.start = qdate.addToDate(event.value.start, options);
|
|
|
|
if (event.value.end) event.value.end = qdate.addToDate(event.value.end, options);
|
2021-03-20 23:58:31 +00:00
|
|
|
event.value.jobs.forEach((job) => {
|
2021-03-28 19:21:04 +00:00
|
|
|
job.start = qdate.addToDate(job.start, options);
|
|
|
|
if (job.end) job.end = qdate.addToDate(job.end, options);
|
2021-03-20 23:58:31 +00:00
|
|
|
});
|
|
|
|
count++;
|
|
|
|
if (
|
|
|
|
count <= 120 &&
|
|
|
|
(!recurrenceRule.value.count || count <= recurrenceRule.value.count) &&
|
|
|
|
(!recurrenceRule.value.until || event.value.start < recurrenceRule.value.until)
|
|
|
|
)
|
2021-03-28 19:21:04 +00:00
|
|
|
void store.saveEvent(<FG.Event>event.value);
|
2021-03-20 23:58:31 +00:00
|
|
|
else break;
|
|
|
|
}
|
|
|
|
}
|
2021-02-10 16:37:43 +00:00
|
|
|
reset();
|
2021-03-25 13:11:54 +00:00
|
|
|
emit('done', true);
|
2021-02-10 16:37:43 +00:00
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
}
|
2021-01-23 13:40:35 +00:00
|
|
|
}
|
2021-01-26 19:38:46 +00:00
|
|
|
|
2021-03-24 19:49:35 +00:00
|
|
|
async function removeTemplate() {
|
|
|
|
if (template.value !== undefined) {
|
|
|
|
await store.removeEvent(template.value.id);
|
|
|
|
template.value = undefined;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-26 19:38:46 +00:00
|
|
|
function reset() {
|
2021-03-24 19:49:35 +00:00
|
|
|
event.value = Object.assign({}, props.modelValue || emptyEvent);
|
2021-03-20 23:58:31 +00:00
|
|
|
template.value = undefined;
|
2021-01-26 19:38:46 +00:00
|
|
|
}
|
2021-01-27 21:37:12 +00:00
|
|
|
|
2021-01-26 19:38:46 +00:00
|
|
|
return {
|
2021-01-27 21:37:12 +00:00
|
|
|
jobDeleteDisabled,
|
2021-01-26 19:38:46 +00:00
|
|
|
addJob,
|
|
|
|
eventtypes,
|
2021-03-20 23:58:31 +00:00
|
|
|
templates,
|
2021-01-26 19:38:46 +00:00
|
|
|
removeJob,
|
|
|
|
notEmpty,
|
|
|
|
save,
|
|
|
|
reset,
|
2021-03-28 01:38:26 +00:00
|
|
|
form,
|
2021-03-20 23:58:31 +00:00
|
|
|
recurrent,
|
|
|
|
fromTemplate,
|
2021-03-24 19:49:35 +00:00
|
|
|
removeTemplate,
|
2021-03-20 23:58:31 +00:00
|
|
|
template,
|
|
|
|
recurrenceRule,
|
2021-01-27 21:37:12 +00:00
|
|
|
event,
|
2021-01-26 19:38:46 +00:00
|
|
|
};
|
2021-03-18 16:23:57 +00:00
|
|
|
},
|
2021-01-23 13:40:35 +00:00
|
|
|
});
|
|
|
|
</script>
|
|
|
|
|
2021-02-05 23:07:58 +00:00
|
|
|
<style></style>
|