[schedule] Improved calendar view
* Load events on next and prev * Resize if display is not wide enough * Fixed permissions
This commit is contained in:
parent
1316c47706
commit
575090552f
|
@ -47,14 +47,15 @@
|
||||||
<q-calendar-agenda
|
<q-calendar-agenda
|
||||||
ref="calendar"
|
ref="calendar"
|
||||||
v-model="selectedDate"
|
v-model="selectedDate"
|
||||||
:view="calendarView"
|
:view="calendarRealView"
|
||||||
|
:max-days="calendarDays"
|
||||||
:weekdays="[1, 2, 3, 4, 5, 6, 0]"
|
:weekdays="[1, 2, 3, 4, 5, 6, 0]"
|
||||||
locale="de-de"
|
locale="de-de"
|
||||||
style="height: 100%; min-height: 400px"
|
style="height: 100%; min-height: 400px"
|
||||||
>
|
>
|
||||||
<template #day="{ scope: { timestamp } }" style="min-height: 200px">
|
<template #day="{ scope: { timestamp } }" style="min-height: 200px">
|
||||||
<template v-if="!getAgenda(timestamp)" style="min-height: 200px"> </template>
|
<template v-if="!events[timestamp.weekday]" style="min-height: 200px"> </template>
|
||||||
<template v-for="agenda in getAgenda(timestamp)" :key="agenda.id">
|
<template v-for="agenda in events[timestamp.weekday]" :key="agenda.id">
|
||||||
<eventslot :event="agenda" />
|
<eventslot :event="agenda" />
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
@ -65,10 +66,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onBeforeMount, ref } from 'vue';
|
import { computed, defineComponent, onBeforeMount, ref } from 'vue';
|
||||||
import { useScheduleStore } from '../../store';
|
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';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'AgendaView',
|
name: 'AgendaView',
|
||||||
|
@ -76,10 +78,16 @@ export default defineComponent({
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const store = useScheduleStore();
|
const store = useScheduleStore();
|
||||||
|
const windowWidth = ref(window.innerWidth);
|
||||||
const selectedDate = ref(date.formatDate(new Date(), 'YYYY-MM-DD'));
|
const selectedDate = ref(date.formatDate(new Date(), 'YYYY-MM-DD'));
|
||||||
const proxyDate = ref('');
|
const proxyDate = ref('');
|
||||||
const calendar = ref<QCalendar.QCalendar>();
|
const calendar = ref<QCalendar.QCalendar>();
|
||||||
const calendarView = 'week';
|
const calendarView = ref('week');
|
||||||
|
|
||||||
|
const calendarRealView = computed(() => (calendarDays.value != 7 ? 'day' : 'week'));
|
||||||
|
const calendarDays = computed(() =>
|
||||||
|
calendarView.value == 'day' ? 1 : windowWidth.value < 1000 ? 3 : 7
|
||||||
|
);
|
||||||
const events = ref<Agendas>({});
|
const events = ref<Agendas>({});
|
||||||
|
|
||||||
interface Agendas {
|
interface Agendas {
|
||||||
|
@ -87,35 +95,40 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
let agenda: Agendas = {};
|
window.addEventListener('resize', () => {
|
||||||
console.log('Hier Passiert was');
|
windowWidth.value = window.innerWidth;
|
||||||
const list = await store.getEvents({ from: new Date(selectedDate.value) });
|
});
|
||||||
if (list)
|
|
||||||
|
await loadAgendas();
|
||||||
|
});
|
||||||
|
|
||||||
|
async function loadAgendas() {
|
||||||
|
const selected = new Date(selectedDate.value);
|
||||||
|
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) => {
|
list.forEach((event) => {
|
||||||
let day = event.start.getDay();
|
const day = event.start.getDay();
|
||||||
|
|
||||||
if (!agenda[day]) {
|
if (!events.value[day]) {
|
||||||
agenda[day] = [];
|
events.value[day] = [];
|
||||||
}
|
}
|
||||||
agenda[day].push(event);
|
events.value[day].push(event);
|
||||||
});
|
});
|
||||||
console.log('finish agenda:', agenda);
|
|
||||||
events.value = agenda;
|
|
||||||
});
|
|
||||||
|
|
||||||
function getAgenda(day: { weekday: string }) {
|
|
||||||
return events.value[parseInt(day.weekday, 10)];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function calendarNext() {
|
function calendarNext() {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call
|
calendar.value?.next();
|
||||||
return calendar.value?.next();
|
void loadAgendas();
|
||||||
}
|
}
|
||||||
|
|
||||||
function calendarPrev() {
|
function calendarPrev() {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call
|
calendar.value?.prev();
|
||||||
return calendar.value?.prev();
|
void loadAgendas();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateProxy() {
|
function updateProxy() {
|
||||||
proxyDate.value = selectedDate.value;
|
proxyDate.value = selectedDate.value;
|
||||||
}
|
}
|
||||||
|
@ -155,13 +168,14 @@ export default defineComponent({
|
||||||
calendar,
|
calendar,
|
||||||
selectedDate,
|
selectedDate,
|
||||||
events,
|
events,
|
||||||
getAgenda,
|
|
||||||
calendarNext,
|
calendarNext,
|
||||||
calendarPrev,
|
calendarPrev,
|
||||||
updateProxy,
|
updateProxy,
|
||||||
saveNewSelectedDate,
|
saveNewSelectedDate,
|
||||||
proxyDate,
|
proxyDate,
|
||||||
|
calendarDays,
|
||||||
calendarView,
|
calendarView,
|
||||||
|
calendarRealView,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
<Eventtypes />
|
<Eventtypes />
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
<q-tab-panel name="jobtypes">
|
<q-tab-panel name="jobtypes">
|
||||||
<JobTypes v-if="canEditRoles" />
|
<JobTypes v-if="canEditJobTypes" />
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
</q-tab-panels>
|
</q-tab-panels>
|
||||||
</q-page>
|
</q-page>
|
||||||
|
@ -58,7 +58,7 @@ export default defineComponent({
|
||||||
name: 'EventManagement',
|
name: 'EventManagement',
|
||||||
components: { CreateEvent, Eventtypes, JobTypes },
|
components: { CreateEvent, Eventtypes, JobTypes },
|
||||||
setup() {
|
setup() {
|
||||||
const canEditRoles = computed(() => hasPermission(PERMISSIONS.ROLES_EDIT));
|
const canEditJobTypes = computed(() => hasPermission(PERMISSIONS.JOB_TYPE));
|
||||||
|
|
||||||
interface Tab {
|
interface Tab {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -85,7 +85,7 @@ export default defineComponent({
|
||||||
const tab = ref<string>('create');
|
const tab = ref<string>('create');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
canEditRoles,
|
canEditJobTypes,
|
||||||
showDrawer,
|
showDrawer,
|
||||||
tab,
|
tab,
|
||||||
tabs,
|
tabs,
|
||||||
|
|
|
@ -37,9 +37,6 @@
|
||||||
<q-tab-panel name="eventtypes">
|
<q-tab-panel name="eventtypes">
|
||||||
<Eventtypes />
|
<Eventtypes />
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
<q-tab-panel name="jobtypes">
|
|
||||||
<JobTypes v-if="canEditRoles" />
|
|
||||||
</q-tab-panel>
|
|
||||||
</q-tab-panels>
|
</q-tab-panels>
|
||||||
</q-page>
|
</q-page>
|
||||||
</div>
|
</div>
|
||||||
|
@ -48,26 +45,21 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, ref } from 'vue';
|
import { computed, defineComponent, ref } from 'vue';
|
||||||
import Eventtypes from '../components/management/Eventtypes.vue';
|
import Eventtypes from '../components/management/Eventtypes.vue';
|
||||||
import JobTypes from '../components/management/JobTypes.vue';
|
|
||||||
//import CreateEvent from '../components/management/CreateEvent.vue';
|
//import CreateEvent from '../components/management/CreateEvent.vue';
|
||||||
import AgendaView from '../components/overview/AgendaView.vue';
|
import AgendaView from '../components/overview/AgendaView.vue';
|
||||||
import { hasPermission } from 'src/utils/permission';
|
|
||||||
import { PERMISSIONS } from '../permissions';
|
|
||||||
import { Screen } from 'quasar';
|
import { Screen } from 'quasar';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'EventOverview',
|
name: 'EventOverview',
|
||||||
components: { AgendaView, Eventtypes, JobTypes },
|
components: { AgendaView, Eventtypes },
|
||||||
setup() {
|
setup() {
|
||||||
const canEditRoles = computed(() => hasPermission(PERMISSIONS.ROLES_EDIT));
|
|
||||||
|
|
||||||
interface Tab {
|
interface Tab {
|
||||||
name: string;
|
name: string;
|
||||||
label: string;
|
label: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tabs: Tab[] = [
|
const tabs: Tab[] = [
|
||||||
{ name: 'agendaView', label: 'Kalendar' }
|
{ name: 'agendaView', label: 'Kalendar' },
|
||||||
// { name: 'eventtypes', label: 'Veranstaltungsarten' },
|
// { name: 'eventtypes', label: 'Veranstaltungsarten' },
|
||||||
// { name: 'jobtypes', label: 'Dienstarten' }
|
// { name: 'jobtypes', label: 'Dienstarten' }
|
||||||
];
|
];
|
||||||
|
@ -80,17 +72,16 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
set: (val: boolean) => {
|
set: (val: boolean) => {
|
||||||
drawer.value = val;
|
drawer.value = val;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const tab = ref<string>('agendaView');
|
const tab = ref<string>('agendaView');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
canEditRoles,
|
|
||||||
showDrawer,
|
showDrawer,
|
||||||
tab,
|
tab,
|
||||||
tabs
|
tabs,
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
export const PERMISSIONS = {
|
export const PERMISSIONS = {
|
||||||
// Kann andere Nutzer bearbeiten
|
// Can create events
|
||||||
EDIT_OTHER: 'users_edit_other',
|
CREATE: 'schedule_create',
|
||||||
// Kann Rollen von Nutzern setzen
|
// Can edit events
|
||||||
SET_ROLES: 'users_set_roles',
|
EDIT: 'schedule_edit',
|
||||||
// Kann Nutzer löschen
|
// Can delete events
|
||||||
DELETE: 'users_delete_other',
|
DELETE: 'schedule_delete',
|
||||||
// Kann neue Nutzer hinzufügen
|
// Can create and edit EventTypes
|
||||||
REGISTER: 'users_register',
|
EVENT_TYPE: 'schedule_event_type',
|
||||||
// Kann Rollen löschen oder bearbeiten, z.b. Rechte hinzufügen etc
|
// Can create and edit JobTypes
|
||||||
ROLES_EDIT: 'roles_edit',
|
JOB_TYPE: 'schedule_job_type',
|
||||||
|
// Can self assign to jobs
|
||||||
|
ASSIGN: 'schedule_assign',
|
||||||
|
// Can assign other users to jobs
|
||||||
|
ASSIGN_OTHER: 'schedule_assign_other',
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { FG_Plugin } from 'src/plugins';
|
import { FG_Plugin } from 'src/plugins';
|
||||||
|
import { PERMISSIONS } from '../permissions';
|
||||||
|
|
||||||
const mainRoutes: FG_Plugin.PluginRouteConfig[] = [
|
const mainRoutes: FG_Plugin.PluginRouteConfig[] = [
|
||||||
{
|
{
|
||||||
|
@ -14,9 +15,7 @@ const mainRoutes: FG_Plugin.PluginRouteConfig[] = [
|
||||||
{
|
{
|
||||||
title: 'Dienstübersicht',
|
title: 'Dienstübersicht',
|
||||||
icon: 'mdi-account-group',
|
icon: 'mdi-account-group',
|
||||||
|
|
||||||
shortcut: true,
|
shortcut: true,
|
||||||
permissions: [],
|
|
||||||
route: {
|
route: {
|
||||||
path: 'schedule-overview',
|
path: 'schedule-overview',
|
||||||
name: 'schedule-overview',
|
name: 'schedule-overview',
|
||||||
|
@ -27,6 +26,7 @@ const mainRoutes: FG_Plugin.PluginRouteConfig[] = [
|
||||||
title: 'Dienstverwaltung',
|
title: 'Dienstverwaltung',
|
||||||
icon: 'mdi-account-details',
|
icon: 'mdi-account-details',
|
||||||
shortcut: false,
|
shortcut: false,
|
||||||
|
permissions: [PERMISSIONS.CREATE],
|
||||||
route: {
|
route: {
|
||||||
path: 'schedule-management',
|
path: 'schedule-management',
|
||||||
name: 'schedule-management',
|
name: 'schedule-management',
|
||||||
|
|
|
@ -20,3 +20,11 @@ export function formatDateTime(
|
||||||
export function asHour(date?: Date) {
|
export function asHour(date?: Date) {
|
||||||
if (date) return formatDateTime(date, false, true);
|
if (date) return formatDateTime(date, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function startOfWeek(date: Date, startMonday = true) {
|
||||||
|
const start = new Date(date);
|
||||||
|
const day = date.getDay() || 7;
|
||||||
|
if (startMonday && day !== 1) start.setHours(-24 * (day - 1));
|
||||||
|
else if (!startMonday && day !== 7) start.setHours(-24 * day);
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue