fix: Improve reactivity in intervals
This commit is contained in:
@@ -38,7 +38,7 @@
|
|||||||
v-for="block in getAvailableIntervals(
|
v-for="block in getAvailableIntervals(
|
||||||
scope.timestamp,
|
scope.timestamp,
|
||||||
boats[scope.columnIndex]
|
boats[scope.columnIndex]
|
||||||
)"
|
).value"
|
||||||
:key="block.$id">
|
:key="block.$id">
|
||||||
<div
|
<div
|
||||||
class="timeblock"
|
class="timeblock"
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ const currentUser = useAuthStore().currentUser;
|
|||||||
|
|
||||||
const getSortedIntervals = (timestamp: Timestamp, boat?: Boat): Interval[] => {
|
const getSortedIntervals = (timestamp: Timestamp, boat?: Boat): Interval[] => {
|
||||||
return getAvailableIntervals(timestamp, boat)
|
return getAvailableIntervals(timestamp, boat)
|
||||||
.concat(boatReservationEvents(timestamp, boat))
|
.value.concat(boatReservationEvents(timestamp, boat))
|
||||||
.sort((a, b) => Date.parse(a.start) - Date.parse(b.start));
|
.sort((a, b) => Date.parse(a.start) - Date.parse(b.start));
|
||||||
};
|
};
|
||||||
// Method declarations
|
// Method declarations
|
||||||
|
|||||||
@@ -26,7 +26,9 @@
|
|||||||
cell-width="150px">
|
cell-width="150px">
|
||||||
<template #day="{ scope }">
|
<template #day="{ scope }">
|
||||||
<div
|
<div
|
||||||
v-if="filteredIntervals(scope.timestamp, scope.resource).length"
|
v-if="
|
||||||
|
filteredIntervals(scope.timestamp, scope.resource).value.length
|
||||||
|
"
|
||||||
style="
|
style="
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@@ -35,10 +37,8 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
">
|
">
|
||||||
<template
|
<template
|
||||||
v-for="block in sortedIntervals(
|
v-for="block in sortedIntervals(scope.timestamp, scope.resource)
|
||||||
scope.timestamp,
|
.value"
|
||||||
scope.resource
|
|
||||||
)"
|
|
||||||
:key="block.id">
|
:key="block.id">
|
||||||
<q-chip class="cursor-pointer">
|
<q-chip class="cursor-pointer">
|
||||||
{{ date.formatDate(block.start, 'HH:mm') }} -
|
{{ date.formatDate(block.start, 'HH:mm') }} -
|
||||||
@@ -163,7 +163,7 @@ import {
|
|||||||
} from '@quasar/quasar-ui-qcalendar';
|
} from '@quasar/quasar-ui-qcalendar';
|
||||||
import { Boat, useBoatStore } from 'src/stores/boat';
|
import { Boat, useBoatStore } from 'src/stores/boat';
|
||||||
import { useIntervalStore } from 'src/stores/interval';
|
import { useIntervalStore } from 'src/stores/interval';
|
||||||
import { onMounted, ref } from 'vue';
|
import { computed, onMounted, ref } from 'vue';
|
||||||
import type {
|
import type {
|
||||||
Interval,
|
Interval,
|
||||||
IntervalTemplate,
|
IntervalTemplate,
|
||||||
@@ -208,8 +208,10 @@ const filteredIntervals = (date: Timestamp, boat: Boat) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const sortedIntervals = (date: Timestamp, boat: Boat) => {
|
const sortedIntervals = (date: Timestamp, boat: Boat) => {
|
||||||
return filteredIntervals(date, boat).sort(
|
return computed(() =>
|
||||||
|
filteredIntervals(date, boat).value.sort(
|
||||||
(a, b) => Date.parse(a.start) - Date.parse(b.start)
|
(a, b) => Date.parse(a.start) - Date.parse(b.start)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -293,7 +295,7 @@ function onDrop(
|
|||||||
overlapped.value = boatsToApply
|
overlapped.value = boatsToApply
|
||||||
.map((boat) =>
|
.map((boat) =>
|
||||||
intervalsOverlapped(
|
intervalsOverlapped(
|
||||||
existingIntervals.concat(
|
existingIntervals.value.concat(
|
||||||
intervalsFromTemplate(boat, templateId, date)
|
intervalsFromTemplate(boat, templateId, date)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,25 +2,26 @@ import { defineStore } from 'pinia';
|
|||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { Boat } from './boat';
|
import { Boat } from './boat';
|
||||||
import { Timestamp, today } from '@quasar/quasar-ui-qcalendar';
|
import { Timestamp, today } from '@quasar/quasar-ui-qcalendar';
|
||||||
|
import { Interval } from './schedule.types';
|
||||||
import { Interval, IntervalRecord } from './schedule.types';
|
|
||||||
import { AppwriteIds, databases } from 'src/boot/appwrite';
|
import { AppwriteIds, databases } from 'src/boot/appwrite';
|
||||||
import { ID, Query } from 'appwrite';
|
import { ID, Query } from 'appwrite';
|
||||||
import { useReservationStore } from './reservation';
|
import { useReservationStore } from './reservation';
|
||||||
|
import { LoadingTypes } from 'src/utils/misc';
|
||||||
|
|
||||||
export const useIntervalStore = defineStore('interval', () => {
|
export const useIntervalStore = defineStore('interval', () => {
|
||||||
// TODO: Implement functions to dynamically pull this data.
|
const intervals = ref(new Map<string, Interval>()); // Intervals by DocID
|
||||||
const intervals = ref<Map<string, Interval>>(new Map());
|
const dateStatus = ref(new Map<string, LoadingTypes>()); // State of load by date
|
||||||
const intervalDates = ref<IntervalRecord>({});
|
|
||||||
const reservationStore = useReservationStore();
|
|
||||||
const selectedDate = ref<string>(today());
|
const selectedDate = ref<string>(today());
|
||||||
|
|
||||||
const getIntervals = (date: Timestamp | string, boat?: Boat): Interval[] => {
|
const reservationStore = useReservationStore();
|
||||||
|
|
||||||
|
const getIntervals = (date: Timestamp | string, boat?: Boat) => {
|
||||||
const searchDate = typeof date === 'string' ? date : date.date;
|
const searchDate = typeof date === 'string' ? date : date.date;
|
||||||
const dayStart = new Date(searchDate + 'T00:00');
|
const dayStart = new Date(searchDate + 'T00:00');
|
||||||
const dayEnd = new Date(searchDate + 'T23:59');
|
const dayEnd = new Date(searchDate + 'T23:59');
|
||||||
if (!intervalDates.value[searchDate]) {
|
if (dateStatus.value.get(searchDate) === undefined) {
|
||||||
intervalDates.value[searchDate] = 'pending';
|
dateStatus.value.set(searchDate, 'pending');
|
||||||
fetchIntervals(searchDate);
|
fetchIntervals(searchDate);
|
||||||
}
|
}
|
||||||
return computed(() => {
|
return computed(() => {
|
||||||
@@ -32,22 +33,19 @@ export const useIntervalStore = defineStore('interval', () => {
|
|||||||
const matchesBoat = boat ? boat.$id === interval.resource : true;
|
const matchesBoat = boat ? boat.$id === interval.resource : true;
|
||||||
return isWithinDay && matchesBoat;
|
return isWithinDay && matchesBoat;
|
||||||
});
|
});
|
||||||
}).value;
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAvailableIntervals = (
|
const getAvailableIntervals = (date: Timestamp | string, boat?: Boat) => {
|
||||||
date: Timestamp | string,
|
return computed(() =>
|
||||||
boat?: Boat
|
getIntervals(date, boat).value.filter((interval) => {
|
||||||
): Interval[] => {
|
|
||||||
return computed(() => {
|
|
||||||
return getIntervals(date, boat).filter((interval) => {
|
|
||||||
return !reservationStore.isResourceTimeOverlapped(
|
return !reservationStore.isResourceTimeOverlapped(
|
||||||
interval.resource,
|
interval.resource,
|
||||||
new Date(interval.start),
|
new Date(interval.start),
|
||||||
new Date(interval.end)
|
new Date(interval.end)
|
||||||
);
|
);
|
||||||
});
|
})
|
||||||
}).value;
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
async function fetchInterval(id: string): Promise<Interval> {
|
async function fetchInterval(id: string): Promise<Interval> {
|
||||||
@@ -78,11 +76,11 @@ export const useIntervalStore = defineStore('interval', () => {
|
|||||||
response.documents.forEach((d) =>
|
response.documents.forEach((d) =>
|
||||||
intervals.value.set(d.$id, d as Interval)
|
intervals.value.set(d.$id, d as Interval)
|
||||||
);
|
);
|
||||||
intervalDates.value[dateString] = 'loaded';
|
dateStatus.value.set(dateString, 'loaded');
|
||||||
console.info(`Loaded ${response.documents.length} intervals from server`);
|
console.info(`Loaded ${response.documents.length} intervals from server`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to fetch intervals', error);
|
console.error('Failed to fetch intervals', error);
|
||||||
intervalDates.value[dateString] = 'error';
|
dateStatus.value.set(dateString, 'error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Models } from 'appwrite';
|
import { Models } from 'appwrite';
|
||||||
import { LoadingTypes } from 'src/utils/misc';
|
|
||||||
|
|
||||||
export type StatusTypes = 'tentative' | 'confirmed' | 'pending' | undefined;
|
export type StatusTypes = 'tentative' | 'confirmed' | 'pending' | undefined;
|
||||||
export type Reservation = Interval & {
|
export type Reservation = Interval & {
|
||||||
@@ -29,7 +28,3 @@ export type IntervalTemplate = Partial<Models.Document> & {
|
|||||||
name: string;
|
name: string;
|
||||||
timeTuples: TimeTuple[];
|
timeTuples: TimeTuple[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface IntervalRecord {
|
|
||||||
[key: string]: LoadingTypes;
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user