fix: reactivity bug with ListReservationsPage
All checks were successful
Build BAB Application Deployment Artifact / build (push) Successful in 2m32s

This commit is contained in:
2024-06-21 23:44:34 -04:00
parent ff8e54449a
commit a11b2a0568
5 changed files with 36 additions and 64 deletions

View File

@@ -184,7 +184,7 @@ function getEvents(scope: ResourceIntervalScope) {
scope.resource.$id
);
return resourceEvents.map((event) => {
return resourceEvents.value.map((event) => {
return {
left: scope.timeStartPosX(parsed(event.start)),
width: scope.timeDurationWidth(

View File

@@ -207,7 +207,7 @@ function selectBlock(event: MouseEvent, scope: DayBodyScope, block: Interval) {
const boatReservations = computed((): Record<string, Reservation[]> => {
return reservationStore
.getReservationsByDate(selectedDate.value)
.reduce((result, reservation) => {
.value.reduce((result, reservation) => {
if (!result[reservation.resource]) result[reservation.resource] = [];
result[reservation.resource].push(reservation);
return result;

View File

@@ -134,16 +134,16 @@ const createReservationFromInterval = (interval: Interval | Reservation) => {
function handleSwipe({ ...event }) {
event.direction === 'right' ? calendar.value?.prev() : calendar.value?.next();
}
function boatReservationEvents(
const boatReservationEvents = (
timestamp: Timestamp,
resource: Boat | undefined
) {
if (!resource) return [];
): Reservation[] => {
if (!resource) return [] as Reservation[];
return reservationStore.getReservationsByDate(
getDate(timestamp),
(resource as Boat).$id
);
}
).value;
};
function onToday() {
calendar.value.moveToToday();
}

View File

@@ -22,7 +22,7 @@
class="q-pa-none">
<q-card
clas="q-ma-md"
v-if="!futureUserReservations.length">
v-if="!reservationStore.futureUserReservations.length">
<q-card-section>
<div class="text-h6">You don't have any upcoming bookings!</div>
<div class="text-h8">Why don't you go make one?</div>
@@ -41,7 +41,7 @@
</q-card>
<div v-else>
<div
v-for="reservation in futureUserReservations"
v-for="reservation in reservationStore.futureUserReservations"
:key="reservation.$id">
<ReservationCardComponent :modelValue="reservation" />
</div>
@@ -51,7 +51,7 @@
name="past"
class="q-pa-none">
<div
v-for="reservation in pastUserReservations"
v-for="reservation in reservationStore.pastUserReservations"
:key="reservation.$id">
<ReservationCardComponent :modelValue="reservation" />
</div>
@@ -63,7 +63,7 @@ import { useReservationStore } from 'src/stores/reservation';
import ReservationCardComponent from 'src/components/scheduling/ReservationCardComponent.vue';
import { onMounted, ref } from 'vue';
const { futureUserReservations, pastUserReservations } = useReservationStore();
const reservationStore = useReservationStore();
onMounted(() => useReservationStore().fetchUserReservations());

View File

@@ -1,6 +1,6 @@
import { defineStore } from 'pinia';
import type { Reservation } from './schedule.types';
import { computed, ref, watch } from 'vue';
import { ComputedRef, computed, reactive } from 'vue';
import { AppwriteIds, databases } from 'src/boot/appwrite';
import { ID, Query } from 'appwrite';
import { date, useQuasar } from 'quasar';
@@ -11,10 +11,10 @@ import { isPast } from 'src/utils/schedule';
import { useRealtimeStore } from './realtime';
export const useReservationStore = defineStore('reservation', () => {
const reservations = ref<Map<string, Reservation>>(new Map());
const datesLoaded = ref<Record<string, LoadingTypes>>({});
const userReservations = ref<Map<string, Reservation>>(new Map());
// TODO: Come up with a better way of storing reservations by date & reservations for user
const reservations = reactive<Map<string, Reservation>>(new Map());
const datesLoaded = reactive<Record<string, LoadingTypes>>({});
const userReservations = reactive<Map<string, Reservation>>(new Map());
const authStore = useAuthStore();
const $q = useQuasar();
const realtimeStore = useRealtimeStore();
@@ -29,12 +29,12 @@ export const useReservationStore = defineStore('reservation', () => {
'databases.*.collections.*.documents.*.delete'
)
) {
reservations.value.delete(payload.$id);
userReservations.value.delete(payload.$id);
reservations.delete(payload.$id);
userReservations.delete(payload.$id);
} else {
reservations.value.set(payload.$id, payload);
reservations.set(payload.$id, payload);
if (payload.user === authStore.currentUser?.$id)
userReservations.value.set(payload.$id, payload);
userReservations.set(payload.$id, payload);
}
}
}
@@ -62,7 +62,7 @@ export const useReservationStore = defineStore('reservation', () => {
);
response.documents.forEach((d) =>
reservations.value.set(d.$id, d as Reservation)
reservations.set(d.$id, d as Reservation)
);
setDateLoaded(startDate, endDate, 'loaded');
} catch (error) {
@@ -103,8 +103,8 @@ export const useReservationStore = defineStore('reservation', () => {
reservation
);
}
reservations.value.set(response.$id, response as Reservation);
userReservations.value.set(response.$id, response as Reservation);
reservations.set(response.$id, response as Reservation);
userReservations.set(response.$id, response as Reservation);
console.info('Reservation booked: ', response);
return response as Reservation;
} catch (e) {
@@ -117,14 +117,8 @@ export const useReservationStore = defineStore('reservation', () => {
reservation: string | Reservation | null | undefined
) => {
if (!reservation) return false;
let id;
if (typeof reservation === 'string') {
id = reservation;
} else if ('$id' in reservation && typeof reservation.$id === 'string') {
id = reservation.$id;
} else {
return false;
}
const id = typeof reservation === 'string' ? reservation : reservation.$id;
if (!id) return false;
const status = $q.notify({
color: 'secondary',
@@ -142,8 +136,8 @@ export const useReservationStore = defineStore('reservation', () => {
AppwriteIds.collection.reservation,
id
);
reservations.value.delete(id);
userReservations.value.delete(id);
reservations.delete(id);
userReservations.delete(id);
console.info(`Deleted reservation: ${id}`);
status({
color: 'warning',
@@ -168,7 +162,7 @@ export const useReservationStore = defineStore('reservation', () => {
if (start > end) return [];
let curDate = start;
while (curDate < end) {
datesLoaded.value[(parseDate(curDate) as Timestamp).date] = state;
datesLoaded[(parseDate(curDate) as Timestamp).date] = state;
curDate = date.addToDate(curDate, { days: 1 });
}
};
@@ -179,8 +173,7 @@ export const useReservationStore = defineStore('reservation', () => {
const unloaded = [];
while (curDate < end) {
const parsedDate = (parseDate(curDate) as Timestamp).date;
if (datesLoaded.value[parsedDate] === undefined)
unloaded.push(parsedDate);
if (datesLoaded[parsedDate] === undefined) unloaded.push(parsedDate);
curDate = date.addToDate(curDate, { days: 1 });
}
return unloaded;
@@ -190,15 +183,15 @@ export const useReservationStore = defineStore('reservation', () => {
const getReservationsByDate = (
searchDate: string,
boat?: string
): Reservation[] => {
if (!datesLoaded.value[searchDate]) {
): ComputedRef<Reservation[]> => {
if (!datesLoaded[searchDate]) {
fetchReservationsForDateRange(searchDate);
}
const dayStart = new Date(searchDate + 'T00:00');
const dayEnd = new Date(searchDate + 'T23:59');
return computed(() => {
return Array.from(reservations.value.values()).filter((reservation) => {
return Array.from(reservations.values()).filter((reservation) => {
const reservationStart = new Date(reservation.start);
const reservationEnd = new Date(reservation.end);
@@ -207,7 +200,7 @@ export const useReservationStore = defineStore('reservation', () => {
const matchesBoat = boat ? boat === reservation.resource : true;
return isWithinDay && matchesBoat;
});
}).value;
});
};
// Get conflicting reservations for a resource within a time range
@@ -216,7 +209,7 @@ export const useReservationStore = defineStore('reservation', () => {
start: Date,
end: Date
): Reservation[] => {
return Array.from(reservations.value.values()).filter(
return Array.from(reservations.values()).filter(
(entry) =>
entry.resource === resource &&
new Date(entry.start) < end &&
@@ -251,7 +244,7 @@ export const useReservationStore = defineStore('reservation', () => {
[Query.equal('user', authStore.currentUser.$id)]
);
response.documents.forEach((d) =>
userReservations.value.set(d.$id, d as Reservation)
userReservations.set(d.$id, d as Reservation)
);
} catch (error) {
console.error('Failed to fetch reservations for user: ', error);
@@ -259,7 +252,7 @@ export const useReservationStore = defineStore('reservation', () => {
};
const sortedUserReservations = computed((): Reservation[] =>
[...userReservations.value?.values()].sort(
[...userReservations.values()].sort(
(a, b) => new Date(b.start).getTime() - new Date(a.start).getTime()
)
);
@@ -274,27 +267,6 @@ export const useReservationStore = defineStore('reservation', () => {
return sortedUserReservations.value?.filter((b) => isPast(b.end));
});
// Ensure reactivity for computed properties when Map is modified
watch(
reservations,
() => {
sortedUserReservations.value;
futureUserReservations.value;
pastUserReservations.value;
},
{ deep: true }
);
watch(
userReservations,
() => {
sortedUserReservations.value;
futureUserReservations.value;
pastUserReservations.value;
},
{ deep: true }
);
return {
getReservationsByDate,
getReservationById,