fix:#5 added room table and changed sql query

This commit is contained in:
Elmar Kresse
2024-01-25 00:34:42 +01:00
parent 1b536dd008
commit fe8e22da5a
4 changed files with 119 additions and 19 deletions

View File

@ -2,6 +2,7 @@ package db
import (
"fmt"
"github.com/pocketbase/pocketbase/tools/types"
"htwkalender/model"
"log/slog"
"time"
@ -265,3 +266,36 @@ func GetEventsInTimeRange(app *pocketbase.PocketBase, from time.Time, to time.Ti
return events, nil
}
// GetEventsThatCollideWithTimeRange returns all events that collide with the given time range
// events that collide are events that start before the given time range and end after the given time range
// or events that start before the given time range and end in the given time range
// or events that start in the given time range and end after the given time range
// or events that start in the given time range and end in the given time range
func GetEventsThatCollideWithTimeRange(app *pocketbase.PocketBase, from time.Time, to time.Time) (model.Events, error) {
var events model.Events
var fromTypeTime, _ = types.ParseDateTime(from)
var toTypeTime, _ = types.ParseDateTime(to)
//TODO check if this query is correct returns null or events on complete other days
err := app.Dao().DB().Select("*").From("events").Where(
dbx.And(
dbx.NewExp("(Start <= {:startDate1}", dbx.Params{"startDate1": fromTypeTime}),
dbx.NewExp("AND End >= {:endDate1})", dbx.Params{"endDate1": toTypeTime}))).OrWhere(
dbx.And(
dbx.NewExp("(Start >= {:startDate2}", dbx.Params{"startDate2": fromTypeTime}),
dbx.NewExp("AND End <= {:endDate2})", dbx.Params{"endDate2": toTypeTime}))).OrWhere(
dbx.And(
dbx.NewExp("(Start <= {:startDate3}", dbx.Params{"startDate3": fromTypeTime}),
dbx.NewExp("AND End <= {:endDate3})", dbx.Params{"endDate3": toTypeTime}))).OrWhere(
dbx.And(
dbx.NewExp("(Start >= {:startDate4}", dbx.Params{"startDate4": fromTypeTime}),
dbx.NewExp("AND End >= {:endDate4})", dbx.Params{"endDate4": toTypeTime}))).All(&events)
if err != nil {
return nil, err
}
return events, nil
}

View File

@ -50,7 +50,7 @@ func GetFreeRooms(app *pocketbase.PocketBase, from time.Time, to time.Time) ([]s
return nil, err
}
var events model.Events
events, err = db.GetEventsInTimeRange(app, from, to)
events, err = db.GetEventsThatCollideWithTimeRange(app, from, to)
if err != nil {
return nil, err
}

View File

@ -0,0 +1,16 @@
// load free rooms as a list of strings form the backend
export async function requestFreeRooms(from: string, to: string): Promise<string[]> {
console.debug("requestFreeRooms: from=" + from + ", to=" + to)
const rooms: string[] = [];
await fetch("/api/rooms/free?from=" + from + "&to=" + to)
.then((response) => {
return response.json();
})
.then((roomsResponse: [] | null) => {
roomsResponse?.forEach((room: string) => rooms.push(room));
});
return rooms;
}

View File

@ -1,35 +1,85 @@
<script setup lang="ts">
import { Ref, ref } from "vue";
import { computed, Ref, ref } from "vue";
import DynamicPage from "@/view/DynamicPage.vue";
import { requestFreeRooms } from "@/api/requestFreeRooms.ts";
const selected: Ref<{ name: string }> = ref({ name: "" });
const date: Ref<Date> = ref(new Date(Date.now()));
const start: Ref<Date> = ref(new Date(Date.now()));
const end: Ref<Date> = ref(new Date(Date.now() + 3600000));
async function loadFreeRooms(): Promise<void> {
availableRooms.value = [];
const startDate = new Date(date.value.getTime());
startDate.setHours(start.value.getHours());
startDate.setMinutes(start.value.getMinutes());
const endDate = new Date(date.value.getTime());
endDate.setHours(end.value.getHours());
endDate.setMinutes(end.value.getMinutes());
await requestFreeRooms(startDate.toISOString(), endDate.toISOString()).then((data) => {
availableRooms.value = data.map((room, index) => {
return { id: index, room: room };
});
});
}
const isLater = computed(() => {
return start.value > end.value;
});
const availableRooms: Ref<{id: number, room: string}[]> = ref([]);
const dates = ref();
</script>
<template>
<DynamicPage
:hide-content="selected.name === ''"
:hide-content="availableRooms.length === 0"
:headline="$t('freeRooms.freeRooms')"
:sub-title="$t('freeRooms.detail')"
icon="pi pi-search"
:button="{
label: 'Search',
icon: 'pi pi-search',
disabled: isLater,
onClick: loadFreeRooms,
}"
>
<template #selection>
<Calendar
v-model="dates"
class="flex-1 m-0"
:placeholder="$t('roomFinderPage.dropDownSelect')"
:empty-message="$t('roomFinderPage.noRoomsAvailable')"
:auto-filter-focus="true"
selection-mode="range"
:manual-input="false"
:show-time="true"
:show-seconds="true"
/>
<Button icon="pi pi-search" />
<template #selection="{ flexSpecs }">
<Calendar
v-model="date"
:class="flexSpecs"
:placeholder="$t('roomFinderPage.dropDownSelect')"
:empty-message="$t('roomFinderPage.noRoomsAvailable')"
:auto-filter-focus="true"
date-format="dd.mm.yy"
/>
<div class="break"/>
<Calendar
v-model="start"
placeholder="start"
time-only
date-format="HH:mm"
:class="[{'p-invalid':isLater}, flexSpecs]"
/>
<Calendar
v-model="end"
time-only
placeholder="end"
date-format="HH:mm"
:class="[{'p-invalid':isLater}, flexSpecs]"
/>
</template>
<template #content>
<Button>Button</Button>
<DataTable :value="availableRooms">
<Column field="id" header="ID"></Column>
<Column field="room" header="Room"></Column>
</DataTable>
</template>
</DynamicPage>
</template>
<style scoped>
.break {
flex-basis: 100%;
height: 0;
}
</style>