<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-card> <div style="max-width: 1800px; width: 100%"> <q-toolbar class="bg-primary text-white q-my-md shadow-2 items-center row justify-center"> <div class="row justify-center items-center"> <q-btn flat dense label="Prev" @click="calendarPrev" /> <q-separator vertical /> <q-btn flat dense >{{ asMonth(selectedDate) }} {{ asYear(selectedDate) }} <q-popup-proxy transition-show="scale" transition-hide="scale" @before-show="updateProxy" > <q-date v-model="proxyDate"> <div class="row items-center justify-end q-gutter-sm"> <q-btn v-close-popup label="Cancel" color="primary" flat /> <q-btn v-close-popup label="OK" color="primary" flat @click="saveNewSelectedDate(proxyDate)" /> </div> </q-date> </q-popup-proxy> </q-btn> <q-separator vertical /> <q-btn flat dense label="Next" @click="calendarNext" /> </div> <!-- <q-space /> --> <q-btn-toggle v-model="calendarView" class="row absolute-right" flat stretch toggle-color="" :options="[ { label: 'Tag', value: 'day' }, { label: 'Woche', value: 'week' }, ]" /> </q-toolbar> <q-calendar-agenda v-model="selectedDate" :view="calendarRealView" :max-days="calendarDays" :weekdays="[1, 2, 3, 4, 5, 6, 0]" locale="de-de" style="height: 100%; min-height: 400px" > <template #day="{ scope: { timestamp } }"> <div itemref="" class="q-pb-sm" style="min-height: 200px"> <eventslot v-for="(agenda, index) in events[timestamp.weekday]" :key="index" v-model="events[timestamp.weekday][index]" @removeEvent="remove" @editEvent="edit" /> </div> </template> </q-calendar-agenda> </div> </q-card> </q-page> </template> <script lang="ts"> import { ComponentPublicInstance, computed, defineComponent, onBeforeMount, ref } from 'vue'; import { useScheduleStore } from '../../store'; import Eventslot from './slots/EventSlot.vue'; import { date } from 'quasar'; import { startOfWeek } from '@flaschengeist/api'; import EditEvent from '../management/EditEvent.vue'; import { QCalendarAgenda } from '@quasar/quasar-ui-qcalendar' export default defineComponent({ name: 'AgendaView', components: { Eventslot, EditEvent, QCalendarAgenda: <ComponentPublicInstance>QCalendarAgenda }, setup() { const store = useScheduleStore(); const windowWidth = ref(window.innerWidth); const selectedDate = ref(date.formatDate(new Date(), 'YYYY-MM-DD')); const proxyDate = ref(''); const calendarView = ref('week'); const calendarRealView = computed(() => (calendarDays.value != 7 ? 'day' : 'week')); const calendarDays = computed(() => // <= 1023 is the breakpoint for sm to md calendarView.value == 'day' ? 1 : windowWidth.value <= 1023 ? 3 : 7 ); const events = ref<Agendas>({}); const editor = ref<FG.Event | undefined>(undefined); interface Agendas { [index: number]: FG.Event[]; } onBeforeMount(async () => { window.addEventListener('resize', () => { windowWidth.value = window.innerWidth; }); 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) { if (await store.removeEvent(id)) { // Successfull removed for (const idx in events.value) { const i = events.value[idx].findIndex((event) => event.id === id); if (i !== -1) { events.value[idx].splice(i, 1); break; } } } else { // Not found, this means our eventa are outdated await loadAgendas(); } } async function loadAgendas() { const selected = new Date(selectedDate.value); console.log(selected); const start = calendarRealView.value === 'day' ? selected : startOfWeek(selected); const end = date.addToDate(start, { days: calendarDays.value }); events.value = {}; const list = await store.getEvents({ from: start, to: end }); list.forEach((event) => { const day = event.start.getDay(); if (!events.value[day]) { events.value[day] = []; } events.value[day].push(event); }); } function calendarNext() { selectedDate.value = date.formatDate( date.addToDate(selectedDate.value, { days: calendarDays.value }), 'YYYY-MM-DD' ); void loadAgendas(); } function calendarPrev() { selectedDate.value = date.formatDate( date.subtractFromDate(selectedDate.value, { days: calendarDays.value }), 'YYYY-MM-DD' ); void loadAgendas(); } function updateProxy() { proxyDate.value = selectedDate.value; } function saveNewSelectedDate() { proxyDate.value = date.formatDate(proxyDate.value, 'YYYY-MM-DD'); selectedDate.value = proxyDate.value; } function asMonth(value: string) { if (value) { return date.formatDate(new Date(value), 'MMMM', { months: [ 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember', ], }); } } function asYear(value: string) { if (value) { return date.formatDate(new Date(value), 'YYYY'); } } return { asYear, asMonth, selectedDate, edit, editor, editDone, events, calendarNext, calendarPrev, updateProxy, saveNewSelectedDate, proxyDate, remove, calendarDays, calendarView, calendarRealView, }; }, }); </script> <style></style>