Remember the calendar state in ICSAgenda component when navigating back

This commit is contained in:
summersamara 2023-12-19 22:12:42 +01:00
parent 1e0db0d8c9
commit f3051d5f11
2 changed files with 69 additions and 22 deletions

View file

@ -1,5 +1,9 @@
<template>
<FullCalendar :options="calendarOptions" class="agenda-view" />
<FullCalendar
ref="calendarRef"
:options="calendarOptions"
class="agenda-view"
/>
<div v-if="listOfEventsByDate.date" class="my-4">
<b v-text="formatDateString(listOfEventsByDate.date)" />
@ -48,7 +52,11 @@ import { EventSegment } from "@fullcalendar/core";
import dayGridPlugin from "@fullcalendar/daygrid";
import iCalendarPlugin from "@fullcalendar/icalendar";
import interactionPlugin from "@fullcalendar/interaction";
import { formatDateString, formatTimeString } from "@/filters/datetime";
import {
formatDateISOStringWithoutTime,
formatDateString,
formatTimeString,
} from "@/filters/datetime";
const props = defineProps<{
icsFeedUrl: string;
@ -56,15 +64,26 @@ const props = defineProps<{
const { t } = useI18n({ useScope: "global" });
const calendarRef = ref();
const lastSelectedDate = ref<string | undefined>(undefined);
const listOfEventsByDate = ref<{ events: EventSegment[]; date?: string }>({
events: [],
date: undefined,
});
if (window.location.hash.length) {
lastSelectedDate.value = formatDateISOStringWithoutTime(
window.location.hash.replace("#_", "")
);
}
const calendarOptions = computed((): object => {
return {
plugins: [dayGridPlugin, iCalendarPlugin, interactionPlugin],
initialView: "dayGridMonth",
initialDate: lastSelectedDate.value,
events: {
url: props.icsFeedUrl,
format: "ics",
@ -75,25 +94,6 @@ const calendarOptions = computed((): object => {
moreLinkContent: (arg: { num: number; text: string }) => {
return "+" + arg.num.toString();
},
moreLinkClick: (info: {
date: Date;
allSegs: EventSegment[];
hiddenSegs: EventSegment[];
jsEvent: object;
}) => {
listOfEventsByDate.value = {
events: info.allSegs,
date: info.date.toISOString(),
};
return "none";
},
dateClick: (info: { dateStr: string }) => {
const moreLinkElement = document.querySelectorAll(
`td[data-date='${info.dateStr}'] a.fc-more-link`
)[0] as undefined | HTMLElement;
moreLinkElement?.click();
},
contentHeight: "auto",
eventClassNames: "line-clamp-3 bg-mbz-yellow dark:bg-mbz-purple",
headerToolbar: {
@ -110,6 +110,44 @@ const calendarOptions = computed((): object => {
day: t("Day"),
list: t("List"),
},
dateClick: (info: { dateStr: string }) => {
calendarRef.value.getApi().select(info.dateStr);
},
select: (info: { startStr: string }) => {
const startDateStr = formatDateISOStringWithoutTime(info.startStr);
const moreLinkElement = document.querySelectorAll(
`td[data-date='${startDateStr}'] a.fc-more-link`
)[0] as undefined | HTMLElement;
moreLinkElement?.click();
},
moreLinkClick: (info: {
date: Date;
allSegs: EventSegment[];
hiddenSegs: EventSegment[];
jsEvent: object;
}) => {
listOfEventsByDate.value = {
events: info.allSegs,
date: info.date.toISOString(),
};
if (info.allSegs.length) {
window.location.hash =
"_" + formatDateISOStringWithoutTime(info.date.toISOString());
}
return "none";
},
moreLinkDidMount: (arg: { el: Element }) => {
if (
lastSelectedDate.value &&
arg.el.closest(`td[data-date='${lastSelectedDate.value}']`)
) {
calendarRef.value.getApi().select(lastSelectedDate.value);
lastSelectedDate.value = undefined;
}
},
};
});
</script>

View file

@ -4,6 +4,10 @@ function parseDateTime(value: string): Date {
return new Date(value);
}
function formatDateISOStringWithoutTime(value: string): string {
return parseDateTime(value).toISOString().split("T")[0];
}
function formatDateString(value: string): string {
return parseDateTime(value).toLocaleString(locale(), {
weekday: "long",
@ -76,4 +80,9 @@ function formatDateTimeString(
const locale = () => i18n.global.locale.replace("_", "-");
export { formatDateString, formatTimeString, formatDateTimeString };
export {
formatDateISOStringWithoutTime,
formatDateString,
formatTimeString,
formatDateTimeString,
};