mirror of
https://gitlab.dit.htwk-leipzig.de/htwk-software/htwkalender-pwa.git
synced 2025-07-16 09:38:51 +02:00
fix:#3 refactored functions
This commit is contained in:
@ -16,26 +16,7 @@
|
||||
|
||||
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 { addMonths } from "date-fns";
|
||||
import { formatYearMonthDay } from "@/helpers/dates";
|
||||
|
||||
const END_OF_SUMMER_SEMESTER = "0930";
|
||||
@ -88,15 +69,15 @@ export async function fetchRoomOccupancy(
|
||||
to_date?: string,
|
||||
): Promise<RoomOccupancyList> {
|
||||
if (from_date == undefined) {
|
||||
let new_from_date = getSemesterStart(new Date());
|
||||
const 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));
|
||||
const new_to_date = getSemesterStart(addMonths(new Date(), 6));
|
||||
to_date = new_to_date.toISOString();
|
||||
}
|
||||
|
||||
var roomOccupancyList: RoomOccupancyList = new RoomOccupancyList(
|
||||
let roomOccupancyList: RoomOccupancyList = new RoomOccupancyList(
|
||||
new Date(),
|
||||
0,
|
||||
0,
|
||||
|
@ -21,17 +21,16 @@ import FullCalendar from "@fullcalendar/vue3";
|
||||
import dayGridPlugin from "@fullcalendar/daygrid";
|
||||
import interactionPlugin from "@fullcalendar/interaction";
|
||||
import timeGridPlugin from "@fullcalendar/timegrid";
|
||||
import { computed, ComputedRef, inject, ref, Ref } from "vue";
|
||||
import { CalendarOptions, DatesSetArg, EventInput } from "@fullcalendar/core";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import {computed, ComputedRef, inject, ref, Ref, watch} from "vue";
|
||||
import {CalendarOptions, DatesSetArg, EventInput} from "@fullcalendar/core";
|
||||
import {useI18n} from "vue-i18n";
|
||||
import allLocales from "@fullcalendar/core/locales-all";
|
||||
import router from "@/router";
|
||||
import { formatYearMonthDay } from "@/helpers/dates";
|
||||
import { useQuery } from "@tanstack/vue-query";
|
||||
import { watch } from "vue";
|
||||
import { fetchRoomOccupancy } from "@/api/fetchRoomOccupancy";
|
||||
import { isValid } from "date-fns";
|
||||
import { RoomOccupancyList } from "@/model/roomOccupancyList";
|
||||
import {formatYearMonthDay} from "@/helpers/dates";
|
||||
import {useQuery} from "@tanstack/vue-query";
|
||||
import {fetchRoomOccupancy} from "@/api/fetchRoomOccupancy";
|
||||
import {isValid} from "date-fns";
|
||||
import {RoomOccupancyList} from "@/model/roomOccupancyList";
|
||||
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
|
||||
@ -78,7 +77,7 @@ const selectedRoom = computed(() => props.room);
|
||||
* @returns Anonymized occupancy events
|
||||
*/
|
||||
function transformData(data: RoomOccupancyList) {
|
||||
const events = data
|
||||
return data
|
||||
.decodeOccupancy(
|
||||
selectedRoom.value,
|
||||
new Date(currentDateFrom.value),
|
||||
@ -88,7 +87,6 @@ function transformData(data: RoomOccupancyList) {
|
||||
id: index,
|
||||
event: event,
|
||||
}));
|
||||
return events;
|
||||
}
|
||||
|
||||
const { data: occupancy } = useQuery({
|
||||
|
@ -14,7 +14,7 @@
|
||||
//You should have received a copy of the GNU Affero General Public License
|
||||
//along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import { Binary } from "bson";
|
||||
import {Binary, Document} from "bson";
|
||||
import { AnonymizedOccupancy } from "./event";
|
||||
import {
|
||||
Duration,
|
||||
@ -93,7 +93,7 @@ export class RoomOccupancyList {
|
||||
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(
|
||||
const decodeInterval = interval(
|
||||
clamp(from, this.getOccupancyInterval()),
|
||||
clamp(to, this.getOccupancyInterval()),
|
||||
);
|
||||
@ -108,7 +108,7 @@ export class RoomOccupancyList {
|
||||
|
||||
const occupancyList = [];
|
||||
|
||||
let { decodeSliceStart, decodeSlice } = this.sliceOccupancy(
|
||||
const { decodeSliceStart, decodeSlice } = this.sliceOccupancy(
|
||||
decodeInterval,
|
||||
roomOccupancy.occupancy.buffer,
|
||||
);
|
||||
@ -145,10 +145,10 @@ export class RoomOccupancyList {
|
||||
|
||||
/**
|
||||
* Slice the important parts of the occupancy list for a given time range.
|
||||
* @param from the start of the time range.
|
||||
* @param to the end of the time range.
|
||||
* @returns a new occupancy byte array with the starting time of the first byte
|
||||
* @throws an error, if the selected time range is outside of the occupancy list.
|
||||
* @param decodeInterval
|
||||
* @param occupancy
|
||||
*/
|
||||
private sliceOccupancy(
|
||||
decodeInterval: NormalizedInterval,
|
||||
@ -156,14 +156,14 @@ export class RoomOccupancyList {
|
||||
): { decodeSliceStart: Date; decodeSlice: Uint8Array } {
|
||||
// Calculate the slice of bytes, that are needed to decode the requested time range
|
||||
// Note: differenceInMinutes calculates (left - right)
|
||||
let minutesFromStart = differenceInMinutes(
|
||||
const minutesFromStart = differenceInMinutes(
|
||||
decodeInterval.start,
|
||||
this.start,
|
||||
);
|
||||
let minutesToEnd = differenceInMinutes(decodeInterval.end, this.start);
|
||||
const minutesToEnd = differenceInMinutes(decodeInterval.end, this.start);
|
||||
|
||||
let firstByte = Math.floor(minutesFromStart / this.granularity / 8);
|
||||
let lastByte = Math.ceil(minutesToEnd / this.granularity / 8);
|
||||
const firstByte = Math.floor(minutesFromStart / this.granularity / 8);
|
||||
const lastByte = Math.ceil(minutesToEnd / this.granularity / 8);
|
||||
|
||||
// check if firstByte and lastByte are within the bounds of the occupancy array and throw an error if not
|
||||
if (
|
||||
@ -175,11 +175,11 @@ export class RoomOccupancyList {
|
||||
throw new Error("Requested time range is outside of the occupancy list.");
|
||||
}
|
||||
|
||||
let decodeSliceStart = addMinutes(
|
||||
const decodeSliceStart = addMinutes(
|
||||
this.start,
|
||||
firstByte * 8 * this.granularity,
|
||||
);
|
||||
let decodeSlice = occupancy.buffer.slice(firstByte, lastByte);
|
||||
const decodeSlice = occupancy.buffer.slice(firstByte, lastByte);
|
||||
|
||||
return { decodeSliceStart, decodeSlice: new Uint8Array(decodeSlice) };
|
||||
}
|
||||
@ -209,23 +209,25 @@ export class RoomOccupancyList {
|
||||
granularity: number,
|
||||
room: string,
|
||||
): AnonymizedOccupancy[] {
|
||||
let occupancyList = [];
|
||||
const occupancyList = [];
|
||||
let firstOccupancyBit: number | null = null;
|
||||
|
||||
// Iterate over all bytes that are in the array
|
||||
for (let byte_i = 0; byte_i < occupancy.length; byte_i++) {
|
||||
let byte = occupancy[byte_i];
|
||||
|
||||
const byte = occupancy[byte_i];
|
||||
// Iterate over all bits in the current byte
|
||||
for (let bit_i = 0; bit_i < 8; bit_i++) {
|
||||
let isOccupied = (byte & (1 << (7 - bit_i))) !== 0;
|
||||
|
||||
if (firstOccupancyBit === null && isOccupied) {
|
||||
firstOccupancyBit = byte_i * 8 + bit_i;
|
||||
} else if (firstOccupancyBit !== null && !isOccupied) {
|
||||
let startTime = addMinutes(start, firstOccupancyBit * granularity);
|
||||
let endTime = addMinutes(start, (byte_i * 8 + bit_i) * granularity);
|
||||
const isOccupied = (byte & (1 << (7 - bit_i))) !== 0;
|
||||
const calculateOccupancyBitIndex = (byte_i: number, bit_i: number) => byte_i * 8 + bit_i;
|
||||
|
||||
if(firstOccupancyBit === null){
|
||||
if (isOccupied) {
|
||||
firstOccupancyBit = calculateOccupancyBitIndex(byte_i, bit_i);
|
||||
}
|
||||
} else {
|
||||
if (!isOccupied) {
|
||||
const startTime = addMinutes(start, firstOccupancyBit * granularity);
|
||||
const endTime = addMinutes(start, calculateOccupancyBitIndex(byte_i, bit_i) * granularity);
|
||||
// add event between start and end of a block of boolean true values
|
||||
occupancyList.push(
|
||||
new AnonymizedOccupancy(
|
||||
@ -236,16 +238,15 @@ export class RoomOccupancyList {
|
||||
false,
|
||||
),
|
||||
);
|
||||
|
||||
firstOccupancyBit = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// add last event if it is still ongoing
|
||||
if (firstOccupancyBit !== null) {
|
||||
let startTime = addMinutes(start, firstOccupancyBit * granularity);
|
||||
let endTime = addMinutes(start, occupancy.length * 8 * granularity);
|
||||
const startTime = addMinutes(start, firstOccupancyBit * granularity);
|
||||
const endTime = addMinutes(start, occupancy.length * 8 * granularity);
|
||||
|
||||
occupancyList.push(
|
||||
new AnonymizedOccupancy(
|
||||
@ -265,6 +266,7 @@ export class RoomOccupancyList {
|
||||
* Generate a list of AnonymizedOccupancy objects for a given time range.
|
||||
* The generated events are always lying within the time range [START_OF_DAY, END_OF_DAY].
|
||||
*
|
||||
* @param rooms
|
||||
* @param from The start time within the specified start day.
|
||||
* @param to The end time within the specified end day.
|
||||
* @returns a list of AnonymizedEventDTO objects, from start to end.
|
||||
@ -282,11 +284,11 @@ export class RoomOccupancyList {
|
||||
}
|
||||
|
||||
return eachDayOfInterval({ start: from, end: to }).map((day) => {
|
||||
let startTime = max([
|
||||
const startTime = max([
|
||||
from,
|
||||
RoomOccupancyList.setTimeOfDay(day, START_OF_WORKDAY),
|
||||
]);
|
||||
let endTime = min([
|
||||
const endTime = min([
|
||||
to,
|
||||
RoomOccupancyList.setTimeOfDay(day, END_OF_WORKDAY),
|
||||
]);
|
||||
@ -307,13 +309,13 @@ export class RoomOccupancyList {
|
||||
* @param json the JS object to read from.
|
||||
* @returns a RoomOccupancyList object.
|
||||
*/
|
||||
public static fromJSON(json: any): RoomOccupancyList {
|
||||
public static fromJSON(json: Document): RoomOccupancyList {
|
||||
return new RoomOccupancyList(
|
||||
json.start,
|
||||
json.granularity,
|
||||
json.blocks,
|
||||
json.rooms.map(
|
||||
(room: any) => new RoomOccupancy(room.name, room.occupancy),
|
||||
(room: { name: string, occupancy: Binary }) => new RoomOccupancy(room.name, room.occupancy),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user