release v2.0.0 #4

Merged
crimsen merged 481 commits from develop into master 2024-01-18 15:15:08 +00:00
3 changed files with 145 additions and 100 deletions
Showing only changes of commit 8c6036c686 - Show all commits

View File

@ -1,100 +1,102 @@
<template> <template>
<q-page padding> <q-card>
<q-card> <q-form @submit="save()" @reset="reset">
<q-form @submit="save()" @reset="reset"> <q-card-section class="fit row justify-start content-center items-center">
<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">
<div class="text-h6 col-xs-12 col-sm-6 q-pa-sm"> Veranstaltung <template v-if="modelValue">bearbeiten</template
Veranstaltung <template v-if="modelValue">bearbeiten</template ><template v-else>erstellen</template>
><template v-else>erstellen</template> </div>
</div> <q-select
<q-select :model-value="template"
:model-value="template" filled
filled label="Vorlage"
label="Vorlage" class="col-xs-12 col-sm-6 q-pa-sm"
class="col-xs-12 col-sm-6 q-pa-sm" :options="templates"
:options="templates" option-label="name"
option-label="name" map-options
map-options clearable
clearable :disable="templates.length == 0"
:disable="templates.length == 0" @update:modelValue="fromTemplate"
@update:modelValue="fromTemplate" @clear="reset()"
@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>
<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-input </q-card>
v-model="event.name" </q-card-section>
class="col-xs-12 col-sm-6 q-pa-sm" <q-card-actions align="around">
label="Name" <q-card-actions align="left">
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>
<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 v-if="!template" color="secondary" label="Neue Vorlage" @click="save(true)" /> <q-btn v-if="!template" color="secondary" label="Neue Vorlage" @click="save(true)" />
<q-btn v-else color="negative" label="Vorlage löschen" @click="removeTemplate" /> <q-btn v-else color="negative" label="Vorlage löschen" @click="removeTemplate" />
<q-btn color="primary" type="submit" label="Erstellen" />
</q-card-actions> </q-card-actions>
</q-form> <q-card-actions align="right">
</q-card> <q-btn label="Zurücksetzen" type="reset" />
</q-page> <q-btn color="primary" type="submit" label="Speichern" />
</q-card-actions>
</q-card-actions>
</q-form>
</q-card>
</template> </template>
<script lang="ts"> <script lang="ts">
@ -116,7 +118,10 @@ export default defineComponent({
type: Object as PropType<FG.Event | undefined>, type: Object as PropType<FG.Event | undefined>,
}, },
}, },
setup(props) { emits: {
done: (val: boolean) => typeof val === 'boolean',
},
setup(props, { emit }) {
const store = useScheduleStore(); const store = useScheduleStore();
const emptyJob = { const emptyJob = {
@ -199,6 +204,7 @@ export default defineComponent({
} }
} }
reset(); reset();
emit('done', true);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
} }

View File

@ -1,4 +1,21 @@
<template> <template>
<q-dialog
:model-value="editor !== undefined"
persistent
transition-show="scale"
transition-hide="scale"
>
<q-card>
<div class="column">
<div class="col" align="right" style="position: sticky; top: 0; z-index: 999">
<q-btn round color="negative" icon="close" dense rounded @click="editDone(false)" />
</div>
<div class="col" style="margin: 0; padding: 0; margin-top: -2.4em">
<edit-event v-model="editor" @done="editDone" />
</div>
</div>
</q-card>
</q-dialog>
<q-page padding> <q-page padding>
<q-card> <q-card>
<div style="max-width: 1800px; width: 100%"> <div style="max-width: 1800px; width: 100%">
@ -59,6 +76,7 @@
:key="index" :key="index"
v-model="events[timestamp.weekday][index]" v-model="events[timestamp.weekday][index]"
@removeEvent="remove" @removeEvent="remove"
@editEvent="edit"
/> />
</div> </div>
</template> </template>
@ -74,10 +92,11 @@ import { useScheduleStore } from '../../store';
import Eventslot from './slots/EventSlot.vue'; import Eventslot from './slots/EventSlot.vue';
import { date } from 'quasar'; import { date } from 'quasar';
import { startOfWeek } from 'src/utils/datetime'; import { startOfWeek } from 'src/utils/datetime';
import EditEvent from '../management/EditEvent.vue';
export default defineComponent({ export default defineComponent({
name: 'AgendaView', name: 'AgendaView',
components: { Eventslot }, components: { Eventslot, EditEvent },
setup() { setup() {
const store = useScheduleStore(); const store = useScheduleStore();
@ -92,6 +111,7 @@ export default defineComponent({
calendarView.value == 'day' ? 1 : windowWidth.value <= 1023 ? 3 : 7 calendarView.value == 'day' ? 1 : windowWidth.value <= 1023 ? 3 : 7
); );
const events = ref<Agendas>({}); const events = ref<Agendas>({});
const editor = ref<FG.Event | undefined>(undefined);
interface Agendas { interface Agendas {
[index: number]: FG.Event[]; [index: number]: FG.Event[];
@ -105,6 +125,14 @@ export default defineComponent({
await loadAgendas(); await loadAgendas();
}); });
async function edit(id: number) {
editor.value = await store.getEvent(id);
}
function editDone(changed: boolean) {
if (changed) void loadAgendas();
editor.value = undefined;
}
async function remove(id: number) { async function remove(id: number) {
if (await store.removeEvent(id)) { if (await store.removeEvent(id)) {
// Successfull removed // Successfull removed
@ -192,6 +220,9 @@ export default defineComponent({
asYear, asYear,
asMonth, asMonth,
selectedDate, selectedDate,
edit,
editor,
editDone,
events, events,
calendarNext, calendarNext,
calendarPrev, calendarPrev,

View File

@ -26,11 +26,14 @@
/> />
</q-card-section> </q-card-section>
<q-card-actions v-if="canEdit || canDelete" vertical align="center"> <q-card-actions v-if="canEdit || canDelete" vertical align="center">
<router-link v-if="canEdit" :to="{ name: 'events-edit', params: { id: event.id } }"> <q-btn
<template #default> v-if="canEdit"
<q-btn color="secondary" flat label="Bearbeiten" style="min-width: 95%" /> color="secondary"
</template> flat
</router-link> label="Bearbeiten"
style="min-width: 95%"
@click="edit"
/>
<q-btn <q-btn
v-if="canDelete" v-if="canDelete"
color="negative" color="negative"
@ -61,6 +64,7 @@ export default defineComponent({
emits: { emits: {
'update:modelValue': (val: FG.Event) => !!val, 'update:modelValue': (val: FG.Event) => !!val,
removeEvent: (val: number) => typeof val === 'number', removeEvent: (val: number) => typeof val === 'number',
editEvent: (val: number) => !!val,
}, },
setup(props, { emit }) { setup(props, { emit }) {
const canDelete = computed(() => hasPermission(PERMISSIONS.DELETE)); const canDelete = computed(() => hasPermission(PERMISSIONS.DELETE));
@ -77,12 +81,16 @@ export default defineComponent({
function remove() { function remove() {
emit('removeEvent', props.modelValue.id); emit('removeEvent', props.modelValue.id);
} }
function edit() {
emit('editEvent', props.modelValue.id);
}
return { return {
canDelete, canDelete,
canEdit, canEdit,
remove, edit,
event, event,
remove,
}; };
}, },
}); });