fix(web): use structured dashboard tile match keys

This commit is contained in:
vince 2026-06-20 15:16:51 +02:00
parent de87464ef1
commit a7d0a4c3b2
2 changed files with 21 additions and 3 deletions

View file

@ -4,6 +4,7 @@ import { genericDashboardFixture } from "@dimensionlab/dashboard-model/fixtures"
import { dimensionLabDashboardFixture } from "$lib/dashboard-seed/dimensionlab"; import { dimensionLabDashboardFixture } from "$lib/dashboard-seed/dimensionlab";
import { import {
AppStateView, AppStateView,
dashboardTileMatchKey,
dashboardHydrationTiles, dashboardHydrationTiles,
restoreDashboardTileSnapshots, restoreDashboardTileSnapshots,
} from "./App"; } from "./App";
@ -159,4 +160,17 @@ describe("React app dashboard state view", () => {
severity: "stale", severity: "stale",
}); });
}); });
test("uses structured tile match keys for delimiter-bearing ids", () => {
expect(
dashboardTileMatchKey({ kind: "service", groupId: "a:b", id: "c" }),
).not.toBe(
dashboardTileMatchKey({ kind: "service", groupId: "a", id: "b:c" }),
);
expect(
dashboardTileMatchKey({ kind: "status", stripId: "a:b", id: "c" }),
).not.toBe(
dashboardTileMatchKey({ kind: "status", stripId: "a", id: "b:c" }),
);
});
}); });

View file

@ -385,7 +385,7 @@ export default function App() {
const responsesByKey = new Map( const responsesByKey = new Map(
batchResponse.tiles.map((tileResponse) => [ batchResponse.tiles.map((tileResponse) => [
dashboardTileKey(tileResponse.tile), dashboardTileMatchKey(tileResponse.tile),
tileResponse, tileResponse,
]), ]),
); );
@ -397,7 +397,7 @@ export default function App() {
tile, tile,
result: applyDashboardTileHydrationResponse( result: applyDashboardTileHydrationResponse(
tile, tile,
responsesByKey.get(key), responsesByKey.get(dashboardTileMatchKey(tile)),
run, run,
signal, signal,
snapshotContext, snapshotContext,
@ -474,7 +474,7 @@ export default function App() {
signal.aborted || signal.aborted ||
run !== hydrationRun || run !== hydrationRun ||
!tileResponse || !tileResponse ||
dashboardTileKey(tileResponse.tile) !== dashboardTileKey(tile) || dashboardTileMatchKey(tileResponse.tile) !== dashboardTileMatchKey(tile) ||
tileResponse.state !== "ready" tileResponse.state !== "ready"
) { ) {
return signal.aborted || cancelled || run !== hydrationRun return signal.aborted || cancelled || run !== hydrationRun
@ -749,6 +749,10 @@ function dashboardTileKey(tile: DashboardTileReference): string {
return `${tile.kind}:${tile.id}`; return `${tile.kind}:${tile.id}`;
} }
export function dashboardTileMatchKey(tile: DashboardTileReference): string {
return JSON.stringify(tile);
}
function dashboardTileModelId(tile: DashboardTileReference): string { function dashboardTileModelId(tile: DashboardTileReference): string {
if (tile.kind === "status") return `${tile.stripId}:${tile.id}`; if (tile.kind === "status") return `${tile.stripId}:${tile.id}`;
return tile.id; return tile.id;