Skip to content

Commit 8e6a56e

Browse files
committed
fix(webapp): an unknown saved theme no longer erases the whole preferences blob
theme and contrast degrade to undefined on their own instead of failing the blob's validation, which reset favorites, side-menu layout and current project - permanently after the next preference write.
1 parent fa56e38 commit 8e6a56e

2 files changed

Lines changed: 16 additions & 4 deletions

File tree

apps/webapp/app/utils/dashboardPreferences.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ export type SideMenuPreferences = z.infer<typeof SideMenuPreferences>;
4747

4848
const DashboardPreferences = z.object({
4949
version: z.literal("1"),
50-
theme: ThemePreference.optional(),
50+
/* An unknown value (e.g. written by a newer deploy) degrades to undefined
51+
instead of failing the whole blob and erasing every other setting */
52+
theme: ThemePreference.optional().catch(undefined),
5153
/** Interface contrast for the System themes, 0-100. */
52-
contrast: z.number().int().min(0).max(100).optional(),
54+
contrast: z.number().int().min(0).max(100).optional().catch(undefined),
5355
currentProjectId: z.string().optional(),
5456
projects: z.record(
5557
z.string(),

apps/webapp/test/themePreference.test.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,18 @@ describe("DashboardPreferences theme schema", () => {
3636
expect(result.theme).toBeUndefined();
3737
});
3838

39-
it("rejects an invalid theme by falling back to defaults", () => {
40-
const result = parseDashboardPreferences({ version: "1", projects: {}, theme: "neon" });
39+
it("drops an invalid theme without erasing the rest of the preferences", () => {
40+
const result = parseDashboardPreferences({
41+
version: "1",
42+
projects: {},
43+
theme: "neon",
44+
contrast: 999,
45+
currentProjectId: "proj_123",
46+
sideMenu: { isCollapsed: true },
47+
});
4148
expect(result.theme).toBeUndefined();
49+
expect(result.contrast).toBeUndefined();
50+
expect(result.currentProjectId).toBe("proj_123");
51+
expect(result.sideMenu?.isCollapsed).toBe(true);
4252
});
4353
});

0 commit comments

Comments
 (0)