mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 22:26:13 +00:00
perf(dashboard): seed the mood chart's series from the snapshot
The dashboard snapshot carries the mood tile's series from the same engine `/api/mood/analytics` answers from, and the snapshot already seeds the widget layout, but nothing seeded the mood analytics cell the mood chart reads, so every dashboard open with the mood chart asked for the series again. Both seed points, the server render and the client snapshot read, now fill that cell too, under the same rule as the layout: only an empty cell, and only when the tile has readings, the one case where its summary is the route's.
This commit is contained in:
1 parent
ea6e94adcf
commit
b970ea7468
3 files changed
+68
No files matched your search
@@ -102,6 +102,19 @@ export default async function DashboardPage() {
|
||||
const queryClient = new QueryClient();
|
||||
queryClient.setQueryData(queryKeys.dashboardSnapshot(locale), wireBody);
|
||||
queryClient.setQueryData(queryKeys.dashboardWidgets(), wireBody.layout);
|
||||
// The mood chart's series rides the mood tile (same engine as
|
||||
// `/api/mood/analytics`); seeded with readings only, where the tile's
|
||||
// summary is the route's.
|
||||
const mood = (
|
||||
wireBody.tiles as
|
||||
{ mood?: { entries: unknown[]; summary: unknown } } | undefined
|
||||
)?.mood;
|
||||
if (mood?.summary && mood.entries.length > 0) {
|
||||
queryClient.setQueryData(queryKeys.moodAnalytics(), {
|
||||
entries: mood.entries,
|
||||
summary: mood.summary,
|
||||
});
|
||||
}
|
||||
|
||||
// Above-the-fold prefetch runs ONLY in snapshot mode: legacy mode derives
|
||||
// its chart-type list from analytics queries the RSC did not run, so there
|
||||
|
||||
@@ -143,6 +143,46 @@ describe("useDashboardSnapshot — auto-refresh on an open page", () => {
|
||||
await (opts.queryFn as () => Promise<unknown>)();
|
||||
expect(setQueryDataMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("seeds the mood chart's series from the mood tile, so the chart asks for nothing", async () => {
|
||||
const entries = [{ date: "2026-11-10", score: 4, samples: 1 }];
|
||||
const summary = { count: 1, latest: 4 };
|
||||
vi.stubGlobal(
|
||||
"fetch",
|
||||
vi.fn().mockResolvedValue(
|
||||
envelopeResponse({
|
||||
layout: { widgets: [] },
|
||||
tiles: { mood: { entries, summary } },
|
||||
}),
|
||||
),
|
||||
);
|
||||
getQueryDataMock.mockReturnValue(undefined);
|
||||
useDashboardSnapshot();
|
||||
await (lastOpts().queryFn as () => Promise<unknown>)();
|
||||
expect(setQueryDataMock).toHaveBeenCalledWith(queryKeys.moodAnalytics(), {
|
||||
entries,
|
||||
summary,
|
||||
});
|
||||
});
|
||||
|
||||
it("leaves the mood chart to its own read when the tile has no readings", async () => {
|
||||
vi.stubGlobal(
|
||||
"fetch",
|
||||
vi.fn().mockResolvedValue(
|
||||
envelopeResponse({
|
||||
layout: { widgets: [] },
|
||||
tiles: { mood: { entries: [], summary: null } },
|
||||
}),
|
||||
),
|
||||
);
|
||||
getQueryDataMock.mockReturnValue(undefined);
|
||||
useDashboardSnapshot();
|
||||
await (lastOpts().queryFn as () => Promise<unknown>)();
|
||||
expect(setQueryDataMock).not.toHaveBeenCalledWith(
|
||||
queryKeys.moodAnalytics(),
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("prefetchDashboardSnapshot — hydration-safe promise handoff", () => {
|
||||
|
||||
@@ -194,6 +194,21 @@ function makeSnapshotQueryFn(queryClient: QueryClient) {
|
||||
if (!queryClient.getQueryData(queryKeys.dashboardWidgets())) {
|
||||
queryClient.setQueryData(queryKeys.dashboardWidgets(), snap.layout);
|
||||
}
|
||||
// The mood tile carries the series `/api/mood/analytics` answers (one
|
||||
// engine, `buildMoodDailySeries`), which is what the mood chart reads.
|
||||
// Same seed-when-empty rule, and only with readings, the one case where
|
||||
// the tile's summary is the route's.
|
||||
const mood = snap.tiles?.mood;
|
||||
if (
|
||||
mood?.summary &&
|
||||
mood.entries.length > 0 &&
|
||||
!queryClient.getQueryData(queryKeys.moodAnalytics())
|
||||
) {
|
||||
queryClient.setQueryData(queryKeys.moodAnalytics(), {
|
||||
entries: mood.entries,
|
||||
summary: mood.summary,
|
||||
});
|
||||
}
|
||||
return snap;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user