Skip to content
Snippets Groups Projects

Resolve "Calendar unusable with many full-day appointments"

Merged Hangzhi Yu requested to merge 1116-calendar-unusable-with-many-full-day-appointments into master
3 files
+ 90
2
Compare changes
  • Side-by-side
  • Inline
Files
3
@@ -40,6 +40,44 @@
:calendar-type="internalCalendarType"
/>
</template>
<template
v-if="Object.keys(daysWithHiddenEvents).length"
#interval-header
>
<div
v-if="
!internalCalendarType === 'day' ||
Object.keys(daysWithHiddenEvents).includes(internalCalendarFocus)
"
class="d-flex justify-center align-end"
:style="{ height: '100%' }"
>
<v-btn
icon
class="ma-2"
@click="showAllAllDayEvents = !showAllAllDayEvents"
>
<v-icon>{{ showAllAllDayEventsButtonIcon }}</v-icon>
</v-btn>
</div>
</template>
<template #day-header="{ date }">
<template
v-if="
Object.keys(daysWithHiddenEvents).includes(date) &&
!showAllAllDayEvents
"
>
<v-spacer />
<div
class="v-event-more ml-1"
v-ripple
@click="showAllAllDayEvents = true"
>
{{ $tc("calendar.more_events", daysWithHiddenEvents[date]) }}
</div>
</template>
</template>
</v-calendar>
<component
v-if="selectedEvent"
@@ -65,6 +103,8 @@ import {
import { gqlCalendar, calendarDaysPreference } from "./calendar.graphql";
import { Interval } from "luxon";
export default {
name: "Calendar",
props: {
@@ -104,6 +144,11 @@ export default {
required: false,
default: "current",
},
maxAllDayEvents: {
type: Number,
required: false,
default: 5,
},
},
data() {
return {
@@ -139,6 +184,9 @@ export default {
daysOfWeek: [1, 2, 3, 4, 5, 6, 0],
},
},
showAllAllDayEvents: false,
daysWithHiddenEvents: {},
};
},
emits: ["changeCalendarType", "changeCalendarFocus", "selectEvent"],
@@ -164,7 +212,7 @@ export default {
};
},
events() {
return this.calendar.calendarFeeds
let events = this.calendar.calendarFeeds
.filter((c) => this.calendarFeeds.map((cf) => cf.name).includes(c.name))
.flatMap((cf) =>
cf.events.map((event) => {
@@ -184,6 +232,34 @@ export default {
};
}),
);
if (this.internalCalendarType === "month" || this.showAllAllDayEvents) {
return events;
}
let dateFullEventCount = {};
this.clearDaysWithHiddenEvents();
return events.filter((event) => {
if (!event.allDay) {
return true;
}
const start = event.startDateTime;
dateFullEventCount[start] = (dateFullEventCount[start] || 0) + 1;
const show = dateFullEventCount[start] <= this.maxAllDayEvents;
if (!show) {
const dateInterval = Interval.fromDateTimes(
start,
event.endDateTime.endOf("day"),
)
.splitBy({ day: 1 })
.map((date) => date.start.toISODate());
for (const date of dateInterval) {
this.daysWithHiddenEvents[date] =
(this.daysWithHiddenEvents[date] || 0) + 1;
}
}
return show;
});
},
paramsForSend() {
if (this.params !== null) {
@@ -251,6 +327,9 @@ export default {
return this.personByIdOrMe.preferences.daysOfWeek;
},
showAllAllDayEventsButtonIcon() {
return this.showAllAllDayEvents ? "mdi-chevron-up" : "mdi-chevron-down";
},
},
watch: {
params(newParams) {
@@ -526,6 +605,9 @@ export default {
// TODO: is this destroyed when unloading?
setInterval(() => this.cal.updateTimes(), 60 * 1000);
},
clearDaysWithHiddenEvents() {
this.daysWithHiddenEvents = {};
},
},
mounted() {
this.ready = true;
Loading