From 7861c9b64217a81708e14a305f7cf1694b058d1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sat, 27 Jun 2026 13:02:48 +0200 Subject: [PATCH] Show the steps pill for layouts that predate its tile id resolveInsightsLayout merged any default tile a saved layout did not enumerate as hidden, so a late-added tile such as steps (introduced in v1.12) was force-hidden on every read of an existing or iOS-synced layout and its nav pill never appeared, even with step data present. Appended tiles now inherit the default visibility instead, matching the fresh-account default; the per-tile data floor still keeps an empty metric out of the nav. --- src/lib/__tests__/insights-layout.test.ts | 8 ++++++++ src/lib/insights-layout.ts | 10 ++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/lib/__tests__/insights-layout.test.ts b/src/lib/__tests__/insights-layout.test.ts index c68033ce7..b637a385f 100644 --- a/src/lib/__tests__/insights-layout.test.ts +++ b/src/lib/__tests__/insights-layout.test.ts @@ -76,6 +76,14 @@ describe("resolveInsightsLayout — v1 → v2 forward upgrade", () => { visible: false, order: 1, }); + + // v1.22 — a late-added default tile the saved blob never enumerated + // (e.g. `steps`, which entered the set in v1.12) merges in + // default-VISIBLE, matching the fresh-account default. The old + // force-hidden merge silently dropped its nav pill on every read of an + // existing or iOS-synced layout. + const steps = resolved.tiles.find((t) => t.id === "steps"); + expect(steps?.visible).toBe(true); }); it("returns the full default layout for garbage input", () => { diff --git a/src/lib/insights-layout.ts b/src/lib/insights-layout.ts index 44cba5e6f..7b2d3367a 100644 --- a/src/lib/insights-layout.ts +++ b/src/lib/insights-layout.ts @@ -215,7 +215,14 @@ export function resolveInsightsLayout(raw: unknown): InsightsLayout { }); // Merge with defaults so new tiles introduced in later versions show - // up automatically (invisible by default, the user opts in). + // up automatically. v1.22 — appended tiles inherit the default's + // visibility (`visible: true` for every default tile) instead of being + // force-hidden. The old default-invisible override silently dropped the + // pill for any late-added tile id (e.g. `steps`, which entered the set in + // v1.12) on every read of an existing or iOS-synced layout that didn't + // enumerate it, so it never matched the fresh-account default. The + // per-tile data floor (`summaries[...].count > 0` at the call site) still + // keeps an empty metric from bloating the nav. const savedIds = new Set(filtered.map((t) => t.id)); const missing = DEFAULT_INSIGHTS_LAYOUT.tiles.filter( (t) => !savedIds.has(t.id), @@ -223,7 +230,6 @@ export function resolveInsightsLayout(raw: unknown): InsightsLayout { const maxOrder = Math.max(0, ...filtered.map((t) => t.order)); const appended = missing.map((t, i) => ({ ...t, - visible: false, // default-invisible on auto-upgrade order: maxOrder + 1 + i, }));