mirror of
https://gitlab.dit.htwk-leipzig.de/htwk-software/htwkalender-pwa.git
synced 2026-01-17 16:52:26 +01:00
feat:#3 frontend room occupancy decoder
This commit is contained in:
108
frontend/src/view/RoomFinderOffline.vue
Normal file
108
frontend/src/view/RoomFinderOffline.vue
Normal file
@@ -0,0 +1,108 @@
|
||||
<!--
|
||||
Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
|
||||
Copyright (C) 2024 HTWKalender support@htwkalender.de
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
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/>.
|
||||
-->
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Ref, computed, ref, watch } from "vue";
|
||||
import { fetchRoom } from "../api/fetchRoom.ts";
|
||||
import DynamicPage from "./DynamicPage.vue";
|
||||
import RoomOccupationOffline from "../components/RoomOccupationOffline.vue";
|
||||
import { computedAsync } from "@vueuse/core";
|
||||
import router from "@/router";
|
||||
|
||||
type Room = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
const selectedRoom: Ref<Room> = ref({ name: "" });
|
||||
|
||||
// Watch for changes in URL parameter
|
||||
router.afterEach(async (to) => {
|
||||
const room = to.query.room;
|
||||
if (room && typeof room === "string") {
|
||||
setRoomFromList(room, rooms.value);
|
||||
}
|
||||
});
|
||||
|
||||
const rooms = computedAsync<Set<string>>(async () => {
|
||||
let rooms: Set<string> = new Set();
|
||||
return await fetchRoom()
|
||||
.then((data) => {
|
||||
rooms = new Set(data);
|
||||
return rooms;
|
||||
})
|
||||
.finally(() => {
|
||||
const room = router.currentRoute.value.query.room;
|
||||
if (room && typeof room === "string") {
|
||||
// check if room is available in roomsList
|
||||
setRoomFromList(room, rooms);
|
||||
}
|
||||
});
|
||||
}, new Set());
|
||||
|
||||
const roomsList = computed(() => {
|
||||
return Array.from(rooms.value).map((room) => {
|
||||
return { name: room } as Room;
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Set the room from the list of rooms
|
||||
* @param room Name of the room
|
||||
* @param rooms List of available rooms
|
||||
*/
|
||||
function setRoomFromList(room: string, rooms: Set<string>) {
|
||||
// wait for the roomsList to be available
|
||||
const roomInList: boolean = rooms.has(room);
|
||||
if (roomInList) {
|
||||
selectedRoom.value.name = room;
|
||||
}
|
||||
}
|
||||
|
||||
watch(selectedRoom, (newRoom: Room) => {
|
||||
if (newRoom.name !== "") {
|
||||
router.push({
|
||||
query: { ...router.currentRoute.value.query, room: newRoom.name },
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DynamicPage
|
||||
:hide-content="selectedRoom.name === ''"
|
||||
:headline="$t('roomFinderPage.headline') + ' – Offline'"
|
||||
:sub-title="$t('roomFinderPage.detail')"
|
||||
icon="pi pi-search"
|
||||
>
|
||||
<template #selection>
|
||||
<Dropdown
|
||||
v-model="selectedRoom"
|
||||
:options="roomsList"
|
||||
class="flex-1 m-0"
|
||||
filter
|
||||
option-label="name"
|
||||
:placeholder="$t('roomFinderPage.dropDownSelect')"
|
||||
:empty-message="$t('roomFinderPage.noRoomsAvailable')"
|
||||
:auto-filter-focus="true"
|
||||
/>
|
||||
</template>
|
||||
<template #content>
|
||||
<RoomOccupationOffline :room="selectedRoom.name" />
|
||||
</template>
|
||||
</DynamicPage>
|
||||
</template>
|
||||
Reference in New Issue
Block a user