Many changes to try to improve reliability

This commit is contained in:
2024-05-17 18:17:25 -04:00
parent dd631b71bb
commit b506ab7ca9
11 changed files with 218 additions and 134 deletions

View File

@@ -44,12 +44,16 @@ export const useAuthStore = defineStore('auth', () => {
'/userinfo/' + id,
ExecutionMethod.GET
)
.then(
(res) => (userNames.value[id] = JSON.parse(res.responseBody).name)
);
.then((res) => {
if (res.responseBody) {
userNames.value[id] = JSON.parse(res.responseBody).name;
} else {
console.error(res, id);
}
});
}
} catch (e) {
console.log('Failed to get username. Error: ' + e);
console.error('Failed to get username. Error: ' + e);
}
return userNames.value[id];
}

View File

@@ -2,17 +2,20 @@ import { defineStore } from 'pinia';
import type { Reservation } from './schedule.types';
import { ref } from 'vue';
import { AppwriteIds, databases } from 'src/boot/appwrite';
import { Timestamp, parsed } from '@quasar/quasar-ui-qcalendar';
import { Query } from 'appwrite';
import { date } from 'quasar';
import { Timestamp, parseDate } from '@quasar/quasar-ui-qcalendar';
export const useReservationStore = defineStore('reservation', () => {
const reservations = ref<Reservation[]>([]);
const reservations = ref<Map<string, Reservation>>(new Map());
const datesLoaded = ref<Record<string, boolean>>({});
const getConflictingReservations = (
resource: string,
start: Date,
end: Date
): Reservation[] => {
const overlapped = reservations.value.filter(
const overlapped = Array.from(reservations.value.values()).filter(
(entry: Reservation) =>
entry.resource == resource &&
new Date(entry.start) < end &&
@@ -37,46 +40,75 @@ export const useReservationStore = defineStore('reservation', () => {
);
};
const addOrCreateReservation = (reservation: Reservation) => {
const index = reservations.value.findIndex(
(res) => res.id == reservation.id
);
index != -1
? (reservations.value[index] = reservation)
: reservations.value.push(reservation);
};
async function fetchReservations() {
function setDateLoaded(start: Date, end: Date, state: boolean) {
let curDate = start;
while (curDate < end) {
datesLoaded.value[(parseDate(curDate) as Timestamp).date] = state;
curDate = date.addToDate(curDate, { days: 1 });
}
}
async function fetchReservationsForDateRange(start: string, end?: string) {
const startDate = new Date(start + 'T00:00');
const endDate = new Date(end || start + 'T23:59');
datesLoaded.value[start] = false;
if (end) {
setDateLoaded(startDate, endDate, false);
}
try {
const response = await databases.listDocuments(
AppwriteIds.databaseId,
AppwriteIds.collection.reservation
);
reservations.value = response.documents as Reservation[];
databases
.listDocuments(
AppwriteIds.databaseId,
AppwriteIds.collection.reservation,
[
Query.and([
Query.greaterThanEqual('end', startDate.toISOString()),
Query.lessThanEqual('start', endDate.toISOString()),
]),
]
)
.then((response) => {
response.documents.forEach((d) =>
reservations.value.set(d.$id, d as Reservation)
);
setDateLoaded(startDate, endDate, true);
});
} catch (error) {
console.error('Failed to fetch timeblocks', error);
console.error('Failed to fetch reservations', error);
}
}
const getBoatReservations = (
searchDate: Timestamp,
async function fetchReservations() {
return;
// fetchReservationsForDateRange(
// today(),
// date.addToDate(today(), { days: 7 }).toLocaleDateString()
// );
}
const getReservationsByDate = (
searchDate: string,
boat?: string
): Reservation[] => {
const result = reservations.value.filter((x) => {
return (
((parsed(x.start)?.date == searchDate.date ||
parsed(x.end)?.date == searchDate.date) && // Part of reservation falls on day
x.resource != undefined && // A boat is defined
!boat) ||
x.resource == boat // A specific boat has been passed, and matches
);
if (!datesLoaded.value[searchDate]) {
fetchReservationsForDateRange(searchDate);
}
const result = Array.from(reservations.value.values()).filter((x) => {
return new Date(x.start) < new Date(searchDate + 'T' + '23:59') &&
new Date(x.end) > new Date(searchDate + 'T' + '00:00') && // Part of reservation falls on day
boat
? boat === x.boat
: true; // A specific boat has been passed, and matches
});
console.log(result);
return result;
};
return {
getBoatReservations,
getReservationsByDate,
fetchReservations,
addOrCreateReservation,
isReservationOverlapped,
isResourceTimeOverlapped,
getConflictingReservations,

View File

@@ -1,5 +1,5 @@
import { defineStore } from 'pinia';
import { ref } from 'vue';
import { ComputedRef, computed, ref } from 'vue';
import { Boat } from './boat';
import {
Timestamp,
@@ -11,7 +11,6 @@ import {
import { IntervalTemplate, TimeTuple, Interval } from './schedule.types';
import { AppwriteIds, databases } from 'src/boot/appwrite';
import { ID, Models } from 'appwrite';
import { buildISODate } from 'src/utils/misc';
export function arrayToTimeTuples(arr: string[]) {
const timeTuples: TimeTuple[] = [];
@@ -70,28 +69,34 @@ export function buildInterval(
as a UTC time and date-time forms are interpreted as local time. */
const result = {
boatId: resource.$id,
start: buildISODate(blockDate, time[0]),
end: buildISODate(blockDate, time[1]),
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.
const timeblocks = ref<Interval[]>([]);
const timeblockTemplates = ref<IntervalTemplate[]>([]);
const intervals = ref<Interval[]>([]);
const intervalTemplates = ref<IntervalTemplate[]>([]);
const getIntervals = (date: Timestamp, boat: Boat): Interval[] => {
return timeblocks.value.filter((block) => {
return (
compareDate(parseDate(new Date(block.start)) as Timestamp, date) &&
block.boatId === boat.$id
);
});
const getIntervals = (
date: Timestamp,
boat: Boat
): ComputedRef<Interval[]> => {
return computed(() =>
intervals.value.filter((block) => {
return (
compareDate(parseDate(new Date(block.start)) as Timestamp, date) &&
block.boatId === boat.$id
);
})
);
};
const getIntervalsForDate = (date: string): Interval[] => {
// TODO: This needs to actually make sure we have the dates we need, stay in sync, etc.
return timeblocks.value.filter((b) => {
return intervals.value.filter((b) => {
return compareDate(
parseDate(new Date(b.start)) as Timestamp,
parsed(date) as Timestamp
@@ -105,7 +110,7 @@ export const useScheduleStore = defineStore('schedule', () => {
AppwriteIds.databaseId,
AppwriteIds.collection.timeBlock
);
timeblocks.value = response.documents as Interval[];
intervals.value = response.documents as Interval[];
} catch (error) {
console.error('Failed to fetch timeblocks', error);
}
@@ -117,7 +122,7 @@ export const useScheduleStore = defineStore('schedule', () => {
AppwriteIds.databaseId,
AppwriteIds.collection.timeBlockTemplate
);
timeblockTemplates.value = response.documents.map(
intervalTemplates.value = response.documents.map(
(d: Models.Document): IntervalTemplate => {
return {
...d,
@@ -153,7 +158,7 @@ export const useScheduleStore = defineStore('schedule', () => {
ID.unique(),
interval
);
timeblocks.value.push(response as Interval);
intervals.value.push(response as Interval);
} catch (e) {
console.error('Error creating Interval: ' + e);
}
@@ -167,7 +172,8 @@ export const useScheduleStore = defineStore('schedule', () => {
interval.$id,
{ ...interval, $id: undefined }
);
timeblocks.value.push(response as Interval);
intervals.value.push(response as Interval);
console.log(`Saved Interval: ${interval.$id}`);
} else {
console.error('Update interval called without an ID');
}
@@ -182,7 +188,7 @@ export const useScheduleStore = defineStore('schedule', () => {
AppwriteIds.collection.timeBlock,
id
);
timeblocks.value = timeblocks.value.filter((block) => block.$id !== id);
intervals.value = intervals.value.filter((block) => block.$id !== id);
} catch (e) {
console.error('Error deleting Interval: ' + e);
}
@@ -195,7 +201,7 @@ export const useScheduleStore = defineStore('schedule', () => {
ID.unique(),
{ name: template.name, timeTuple: template.timeTuples.flat(2) }
);
timeblockTemplates.value.push(response as IntervalTemplate);
intervalTemplates.value.push(response as IntervalTemplate);
} catch (e) {
console.error('Error updating IntervalTemplate: ' + e);
}
@@ -207,7 +213,7 @@ export const useScheduleStore = defineStore('schedule', () => {
AppwriteIds.collection.timeBlockTemplate,
id
);
timeblockTemplates.value = timeblockTemplates.value.filter(
intervalTemplates.value = intervalTemplates.value.filter(
(template) => template.$id !== id
);
} catch (e) {
@@ -228,7 +234,7 @@ export const useScheduleStore = defineStore('schedule', () => {
timeTuple: template.timeTuples.flat(2),
}
);
timeblockTemplates.value = timeblockTemplates.value.map((b) =>
intervalTemplates.value = intervalTemplates.value.map((b) =>
b.$id !== id
? b
: ({
@@ -242,8 +248,8 @@ export const useScheduleStore = defineStore('schedule', () => {
};
return {
timeblocks,
timeblockTemplates,
timeblocks: intervals,
timeblockTemplates: intervalTemplates,
getIntervalsForDate,
getIntervals,
fetchIntervals,

View File

@@ -3,8 +3,8 @@ import { Models } from 'appwrite';
export type StatusTypes = 'tentative' | 'confirmed' | 'pending' | undefined;
export type Reservation = Partial<Models.Document> & {
user: string;
start: string; // ISODate
end: string; //ISODate
start: string;
end: string;
resource: string; // Boat ID
status?: StatusTypes;
};

View File

@@ -151,7 +151,6 @@ export const useTaskStore = defineStore('tasks', {
const result = state.tasks.filter((task) =>
task.title.toLowerCase().includes(searchQuery.toLowerCase())
);
console.log(result);
return result;
},
},