From 274d0193f79b82428f48f292b766349654d4c17d Mon Sep 17 00:00:00 2001 From: Patrick Toal Date: Wed, 8 May 2024 13:32:10 -0400 Subject: [PATCH] Some timeblock stuff working --- src/App.vue | 12 +- .../boat/BoatScheduleTableComponent.vue | 8 +- src/pages/schedule/ManageCalendar.vue | 187 ++++++++++++++++-- src/stores/sampledata/schedule.ts | 4 +- src/stores/schedule.ts | 65 +++++- src/stores/schedule.types.ts | 2 +- 6 files changed, 239 insertions(+), 39 deletions(-) diff --git a/src/App.vue b/src/App.vue index 4c18434..e16cd59 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,9 +3,19 @@ diff --git a/src/components/scheduling/boat/BoatScheduleTableComponent.vue b/src/components/scheduling/boat/BoatScheduleTableComponent.vue index 839c6dc..adc1ca9 100644 --- a/src/components/scheduling/boat/BoatScheduleTableComponent.vue +++ b/src/components/scheduling/boat/BoatScheduleTableComponent.vue @@ -73,7 +73,7 @@ import { } from '@quasar/quasar-ui-qcalendar'; import CalendarHeaderComponent from './CalendarHeaderComponent.vue'; -import { ref, computed, onMounted } from 'vue'; +import { ref, computed } from 'vue'; import { useBoatStore } from 'src/stores/boat'; import { useScheduleStore } from 'src/stores/schedule'; import { Timeblock } from 'src/stores/schedule.types'; @@ -86,12 +86,6 @@ const selectedDate = ref(today()); const calendar = ref(null); -onMounted(async () => { - await boatStore.fetchBoats(); - await scheduleStore.fetchTimeBlocks(); - // useScheduleStore().fetchReservations() -}); // TODO: Probably need this to be more sophisticated. - function handleSwipe({ ...event }) { event.direction === 'right' ? calendar.value?.prev() : calendar.value?.next(); } diff --git a/src/pages/schedule/ManageCalendar.vue b/src/pages/schedule/ManageCalendar.vue index 2a899c8..09a2596 100644 --- a/src/pages/schedule/ManageCalendar.vue +++ b/src/pages/schedule/ManageCalendar.vue @@ -6,14 +6,49 @@ ref="calendar" v-model="selectedDate" v-model:model-resources="resources" + resource-key="$id" + resource-label="name" view="week" :weekdays="[1, 2, 3, 4, 5, 6, 0]" hoverable animated bordered + :drag-enter-func="onDragEnter" + :drag-over-func="onDragOver" + :drag-leave-func="onDragLeave" + :drop-func="onDrop" :day-min-height="50" :day-height="0" - > + > + +
@@ -37,33 +72,149 @@ :label="template.name" style="font-size: 0.8em" draggable="true" + @dragstart="onDragStart($event, template)" > - - {{ item[0] }} - {{ item[1] }} - + + + + + - - +
+ + +
+
- diff --git a/src/stores/sampledata/schedule.ts b/src/stores/sampledata/schedule.ts index cdb79a5..1cecd8b 100644 --- a/src/stores/sampledata/schedule.ts +++ b/src/stores/sampledata/schedule.ts @@ -18,7 +18,7 @@ import type { export const templateA: TimeBlockTemplate = { id: '1', name: 'WeekdayBlocks', - timeTuple: [ + timeTuples: [ ['08:00', '12:00'], ['12:00', '16:00'], ['17:00', '21:00'], @@ -28,7 +28,7 @@ export const templateA: TimeBlockTemplate = { export const templateB: TimeBlockTemplate = { id: '2', name: 'WeekendBlocks', - timeTuple: [ + timeTuples: [ ['07:00', '10:00'], ['10:00', '13:00'], ['13:00', '16:00'], diff --git a/src/stores/schedule.ts b/src/stores/schedule.ts index 0fb54b0..37a5c91 100644 --- a/src/stores/schedule.ts +++ b/src/stores/schedule.ts @@ -15,6 +15,30 @@ import { Timeblock, } from './schedule.types'; import { AppwriteIds, databases } from 'src/boot/appwrite'; +import { ID, Models } from 'appwrite'; + +export function arrayToTimeTuples(arr: string[]) { + const timeTuples: TimeTuple[] = []; + for (let i = 0; i < arr.length; i += 2) { + timeTuples.push([arr[i], arr[i + 1]]); + } + return timeTuples; +} + +export function buildTimeBlock( + resource: Boat, + time: TimeTuple, + blockDate: string +): Timeblock { + /* When the time zone offset is absent, date-only forms are interpreted + as a UTC time and date-time forms are interpreted as local time. */ + const result = { + boatId: resource.$id, + start: new Date(blockDate + 'T' + time[0]).toISOString(), + end: new Date(blockDate + 'T' + time[1]).toISOString(), + }; + return result; +} export const useScheduleStore = defineStore('schedule', () => { // TODO: Implement functions to dynamically pull this data. @@ -22,11 +46,16 @@ export const useScheduleStore = defineStore('schedule', () => { const timeblocks = ref([]); const timeblockTemplates = ref([]); + const getTimeblocks = (date: Timestamp, boat: Boat): Timeblock[] => { + return timeblocks.value.filter((block) => { + return ( + compareDate(parseDate(new Date(block.start)) as Timestamp, date) && + block.boatId === boat.$id + ); + }); + }; const getTimeblocksForDate = (date: string): Timeblock[] => { // TODO: This needs to actually make sure we have the dates we need, stay in sync, etc. - if (!timeblocks.value) { - fetchTimeBlocks(); - } return timeblocks.value.filter((b) => { return compareDate( parseDate(new Date(b.start)) as Timestamp, @@ -68,14 +97,14 @@ export const useScheduleStore = defineStore('schedule', () => { AppwriteIds.databaseId, AppwriteIds.collection.timeBlockTemplate ); - const res = response.documents.map((d) => { - const timeTuples: TimeTuple[] = []; - for (let i = 0; i < d.timeTuple.length; i += 2) { - timeTuples.push([d.timeTuple[i], d.timeTuple[i + 1]]); + timeblockTemplates.value = response.documents.map( + (d: Models.Document): TimeBlockTemplate => { + return { + ...d, + timeTuples: arrayToTimeTuples(d.timeTuple), + } as TimeBlockTemplate; } - return { ...d, timeTuple: timeTuples }; - }) as TimeBlockTemplate[]; - timeblockTemplates.value = res; + ); } catch (error) { console.error('Failed to fetch timeblock templates', error); } @@ -139,6 +168,20 @@ export const useScheduleStore = defineStore('schedule', () => { : reservations.value.push(reservation); }; + const createTimeblock = async (block: Timeblock) => { + try { + const response = await databases.createDocument( + AppwriteIds.databaseId, + AppwriteIds.collection.timeBlock, + ID.unique(), + block + ); + timeblocks.value.push(response as Timeblock); + } catch (e) { + console.log('Error creating Timeblock: ' + e); + } + }; + return { reservations, timeblocks, @@ -146,10 +189,12 @@ export const useScheduleStore = defineStore('schedule', () => { getBoatReservations, getConflictingReservations, getTimeblocksForDate, + getTimeblocks, fetchTimeBlocks, fetchTimeBlockTemplates, getNewId, addOrCreateReservation, + createTimeblock, isReservationOverlapped, isResourceTimeOverlapped, }; diff --git a/src/stores/schedule.types.ts b/src/stores/schedule.types.ts index f9a0d20..8498eef 100644 --- a/src/stores/schedule.types.ts +++ b/src/stores/schedule.types.ts @@ -27,5 +27,5 @@ export type Timeblock = Partial & { export type TimeBlockTemplate = Partial & { name: string; - timeTuple: TimeTuple[]; + timeTuples: TimeTuple[]; };