diff --git a/frontend/src/api/fetchRoomOccupancy.ts b/frontend/src/api/fetchRoomOccupancy.ts index bc9f6e1..e3cbf35 100644 --- a/frontend/src/api/fetchRoomOccupancy.ts +++ b/frontend/src/api/fetchRoomOccupancy.ts @@ -16,11 +16,67 @@ import { BSON } from "bson"; import { RoomOccupancyList } from "@/model/roomOccupancyList.ts"; +import { Duration, NormalizedInterval, add, addDays, addMinutes, addMonths, clamp, differenceInMinutes, eachDayOfInterval, endOfDay, interval, isAfter, isBefore, isEqual, max, min, startOfDay, subDays } from "date-fns"; +import { formatYearMonthDay } from "@/helpers/dates"; + +const END_OF_SUMMER_SEMESTER = "0930"; +const END_OF_WINTER_SEMESTER = "0331"; + +/** + * check if date is in winter semester before summer semester + * @param date - The date to check + * @returns boolean - true if date is in winter semester + */ +export function isBeforeSummer(date: Date): boolean { + const formattedDate = formatYearMonthDay(date).slice(4); + return formattedDate <= END_OF_WINTER_SEMESTER; +} + +/** + * check if date is in winter semester after summer semester + * @param date - The date to check + * @returns boolean - true if date is in winter semester + */ +export function isAfterSummer(date: Date): boolean { + const formattedDate = formatYearMonthDay(date).slice(4); + return formattedDate > END_OF_SUMMER_SEMESTER; +} + +/** + * Gets the start date of the current semester + * @param date - The date to check + * @returns Date - The start date of the current semester + */ +export function getSemesterStart(date: Date): Date { + if (isBeforeSummer(date)) { + return new Date(date.getFullYear()-1, 9, 1); + } else if (isAfterSummer(date)) { + return new Date(date.getFullYear(), 9, 1); + } else { + return new Date(date.getFullYear(), 3, 1); + } +} + +/** + * Fetches the room occupancy for a given date range. + * @param from_date the start date of the date range + * @param to_date the end date of the date range + * @returns RoomOccupancyList - the room occupancy list + */ export async function fetchRoomOccupancy( - from_date: string, - to_date: string, + from_date?: string, + to_date?: string ): Promise { + if (from_date == undefined) { + let new_from_date = getSemesterStart(new Date()); + from_date = new_from_date.toISOString(); + } + if (to_date == undefined) { + let new_to_date = getSemesterStart(addMonths(new Date(), 6)); + to_date = new_to_date.toISOString(); + } + var roomOccupancyList: RoomOccupancyList = new RoomOccupancyList( new Date(), 0, 0, [] ); diff --git a/frontend/src/components/RoomOccupation.vue b/frontend/src/components/RoomOccupation.vue index 9bf4e2e..c35fe04 100644 --- a/frontend/src/components/RoomOccupation.vue +++ b/frontend/src/components/RoomOccupation.vue @@ -86,7 +86,7 @@ const { data: occupations } = useQuery({ showFree: event.free, })), enabled: () => selectedRoom.value !== "" && currentDateFrom.value !== "", - staleTime: 5000000, // 500 seconds + staleTime: 5000000, // 5000 seconds }); watch(occupations, () => fullCalendar.value?.getApi().refetchEvents()); diff --git a/frontend/src/components/RoomOccupationOffline.vue b/frontend/src/components/RoomOccupationOffline.vue index 1e8b817..1321f69 100644 --- a/frontend/src/components/RoomOccupationOffline.vue +++ b/frontend/src/components/RoomOccupationOffline.vue @@ -87,16 +87,16 @@ function transformData(data: RoomOccupancyList) { return events; } -const { data: occupations } = useQuery({ - queryKey: ["roomOccupation", selectedRoom, currentDateFrom, currentDateTo], +const { data: occupancy } = useQuery({ + queryKey: ["roomOccupancy"],//, selectedRoom, currentDateFrom, currentDateTo], queryFn: () => - fetchRoomOccupancy( - new Date(currentDateFrom.value).toISOString(), - new Date(currentDateTo.value).toISOString() - ), - select: (data) => transformData(data), - enabled: () => selectedRoom.value !== "" && currentDateFrom.value !== "", - staleTime: 5000000, // 500 seconds + fetchRoomOccupancy(), + staleTime: 12 * 3600000, // 12 hours +}); + +const occupations = computed(() => { + if (!occupancy.value) return; + return transformData(occupancy.value); }); watch(occupations, () => fullCalendar.value?.getApi().refetchEvents()); diff --git a/frontend/src/model/roomOccupancyList.ts b/frontend/src/model/roomOccupancyList.ts index c18f629..eab3413 100644 --- a/frontend/src/model/roomOccupancyList.ts +++ b/frontend/src/model/roomOccupancyList.ts @@ -69,16 +69,17 @@ export class RoomOccupancyList { */ public decodeOccupancy(room : string, from : Date, to : Date) : AnonymizedOccupancy[] { const roomOccupancy = this.rooms.find((r) => r.name === room); + + // Get start and end of decoded time range (within encoded list and requested range) + let decodeInterval = interval(clamp(from, this.getOccupancyInterval()), clamp(to, this.getOccupancyInterval())); - if (roomOccupancy === undefined) { + // if the room is not in the list or the time range is empty, return stub events + if (roomOccupancy === undefined || isEqual(decodeInterval.start, decodeInterval.end)) { return RoomOccupancyList.generateStubEvents(room, from, to); } const occupancyList = []; - // Get start and end of decoded time range (within encoded list and requested range) - let decodeInterval = interval(clamp(from, this.getOccupancyInterval()), clamp(to, this.getOccupancyInterval())); - let {decodeSliceStart, decodeSlice} = this.sliceOccupancy( decodeInterval, roomOccupancy.occupancy.buffer