fix(timeline): close the life event sheet before the timeline refetch

The life event hooks returned the timeline and day refresh from
onSuccess, which a mutation waits for, so saving or removing an event
kept the sheet spinning until the whole timeline had reloaded. The
refresh is now started and not returned, like the other record sheets.
This commit is contained in:
Marc-André Bombeck committed 2026-11-11 21:40:02 +01:00
1 parent e68041a3af
commit b5c97062b8
2 files changed
+45 -1

No files matched your search

@@ -0,0 +1,42 @@
/**
* A life event save settles once the server stored it.
*
* The hooks returned the timeline refresh from `onSuccess`, which a mutation
* waits for, so the sheet kept its spinner until the timeline had refetched.
*/
import { describe, expect, it, vi } from "vitest";
const client = vi.hoisted(() => ({
// A refetch that never answers, as on a slow connection.
invalidateQueries: vi.fn(() => new Promise(() => {})),
getQueryCache: () => ({ findAll: () => [] }),
}));
vi.mock("react", async (importOriginal) => ({
...(await importOriginal<typeof import("react")>()),
useRef: <T>(initial: T) => ({ current: initial }),
}));
vi.mock("@tanstack/react-query", () => ({
useQuery: (options: unknown) => options,
// The hook's options are what is under test; return them as they are.
useMutation: (options: unknown) => options,
useQueryClient: () => client,
}));
import { useLifeEventMutations } from "../use-timeline";
describe("life event saves", () => {
it.each(["create", "update", "remove"] as const)(
"%s starts the refresh and does not wait for it",
(name) => {
client.invalidateQueries.mockClear();
const options = useLifeEventMutations()[name] as unknown as {
onSuccess: () => unknown;
};
expect(options.onSuccess()).toBeUndefined();
expect(client.invalidateQueries).toHaveBeenCalled();
},
);
});
+3 -1
View File
@@ -73,8 +73,10 @@ export function useLifeEvents(enabled = true) {
export function useLifeEventMutations() {
const qc = useQueryClient();
// Not returned, so the sheet closes without waiting for the timeline to
// refetch.
const invalidate = () =>
invalidateKeys(qc, [queryKeys.timelineRoot(), queryKeys.dayRoot()]);
void invalidateKeys(qc, [queryKeys.timelineRoot(), queryKeys.dayRoot()]);
// One key until a save lands, so a retry after a timeout is not a second
// event.