mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-22 23:16:46 +00:00
refactor(collab): keep the phone notes tab loading without a trip id guard
The shared notes hook skipped loading and listening without a trip id, which only the desktop panel did. That guard is now a desktop option, so the phone tab loads and listens as before.
This commit is contained in:
@@ -43,7 +43,13 @@ function useCollabNotes({ tripId, currentUser }: CollabNotesProps) {
|
||||
const can = useCanDo()
|
||||
const trip = useTripStore((s) => s.trip)
|
||||
const canEdit = can('collab_edit', trip)
|
||||
const { notes, setNotes, loading, uploadNoteFiles } = useCollabNotesData<CollabNote>({ tripId, t, toast, resetOnLoadError: true })
|
||||
const { notes, setNotes, loading, uploadNoteFiles } = useCollabNotesData<CollabNote>({
|
||||
tripId,
|
||||
t,
|
||||
toast,
|
||||
resetOnLoadError: true,
|
||||
waitForTripId: true,
|
||||
})
|
||||
const [showNewModal, setShowNewModal] = useState(false)
|
||||
const [editingNote, setEditingNote] = useState(null)
|
||||
const [viewingNote, setViewingNote] = useState<CollabNote | null>(null)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// FE-COLLAB-NOTESDATA-001 to FE-COLLAB-NOTESDATA-008: the note list behind the desktop
|
||||
// Collab panel (empties on a failed load) and the phone's notes tab (keeps the list), with
|
||||
// Collab panel (empties on a failed load, waits for a trip id) and the phone's notes tab
|
||||
// (keeps the list, always loads), with
|
||||
// the live note events and the attachment upload both run after saving a note.
|
||||
import { act, renderHook, waitFor } from '@testing-library/react';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
@@ -79,11 +80,16 @@ describe('useCollabNotesData', () => {
|
||||
expect(empty.result.current.notes).toEqual([]);
|
||||
});
|
||||
|
||||
it('FE-COLLAB-NOTESDATA-002: without a trip nothing loads or listens', () => {
|
||||
const { result } = setup({ tripId: 0 });
|
||||
it('FE-COLLAB-NOTESDATA-002: without a trip the desktop list waits, the phone list still loads', async () => {
|
||||
const desktop = setup({ tripId: 0, waitForTripId: true });
|
||||
expect(collabApi.getNotes).not.toHaveBeenCalled();
|
||||
expect(addListener).not.toHaveBeenCalled();
|
||||
expect(result.current.loading).toBe(true);
|
||||
expect(desktop.result.current.loading).toBe(true);
|
||||
|
||||
const phone = await loaded({ tripId: 0 });
|
||||
expect(collabApi.getNotes).toHaveBeenCalledWith(0);
|
||||
expect(addListener).toHaveBeenCalledTimes(1);
|
||||
expect(phone.result.current.notes.map((n) => n.id)).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
it('FE-COLLAB-NOTESDATA-003: a failed reload empties the desktop list and keeps the phone list', async () => {
|
||||
|
||||
@@ -12,6 +12,8 @@ export interface CollabNotesDataOptions {
|
||||
toast: ReturnType<typeof useToast>;
|
||||
/** The desktop panel outlives a trip change, so a failed load there empties the list. */
|
||||
resetOnLoadError?: boolean;
|
||||
/** The desktop panel loads and listens only once it has a trip id; the phone tab always does. */
|
||||
waitForTripId?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -26,12 +28,13 @@ export function useCollabNotesData<N extends { id: number } = CollabNoteData>({
|
||||
t,
|
||||
toast,
|
||||
resetOnLoadError = false,
|
||||
waitForTripId = false,
|
||||
}: CollabNotesDataOptions) {
|
||||
const [notes, setNotes] = useState<N[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (!tripId) return;
|
||||
if (waitForTripId && !tripId) return;
|
||||
let cancelled = false;
|
||||
setLoading(true);
|
||||
collabApi
|
||||
@@ -48,10 +51,10 @@ export function useCollabNotesData<N extends { id: number } = CollabNoteData>({
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [tripId, resetOnLoadError]);
|
||||
}, [tripId, resetOnLoadError, waitForTripId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!tripId) return;
|
||||
if (waitForTripId && !tripId) return;
|
||||
const handler = (msg: Record<string, unknown>) => {
|
||||
// An event still in flight from a trip just left must not land in this list.
|
||||
if (String(msg?.tripId) !== String(tripId)) return;
|
||||
@@ -69,7 +72,7 @@ export function useCollabNotesData<N extends { id: number } = CollabNoteData>({
|
||||
};
|
||||
addListener(handler);
|
||||
return () => removeListener(handler);
|
||||
}, [tripId]);
|
||||
}, [tripId, waitForTripId]);
|
||||
|
||||
/**
|
||||
* Uploads a saved note's attachments one by one; a file the server refuses is toasted
|
||||
|
||||
Reference in New Issue
Block a user