|
1 | | -import { z } from "zod"; |
2 | 1 | import { $transaction, prisma } from "~/db.server"; |
3 | 2 | import { logger } from "./logger.server"; |
4 | 3 | import { type UserFromSession } from "./session.server"; |
5 | | - |
6 | | -const FavoritePage = z.object({ |
7 | | - /** Stable id, generated client-side when the page is favorited. */ |
8 | | - id: z.string(), |
9 | | - /** App-relative URL including any search params (filters, tabs). */ |
10 | | - url: z.string(), |
11 | | - /** Display label shown in the side menu; user-renamable. */ |
12 | | - label: z.string(), |
13 | | - /** Key into the favorite page icon registry. */ |
14 | | - icon: z.string().optional(), |
15 | | -}); |
16 | | - |
17 | | -export type FavoritePage = z.infer<typeof FavoritePage>; |
18 | | - |
19 | | -const SideMenuPreferences = z.object({ |
20 | | - isCollapsed: z.boolean().default(false), |
21 | | - /** Expanded side menu width in px, set by the resize handle. */ |
22 | | - width: z.number().optional(), |
23 | | - // Map for section collapsed states - keys are section identifiers |
24 | | - collapsedSections: z.record(z.string(), z.boolean()).optional(), |
25 | | - /** Organization-specific settings */ |
26 | | - organizations: z |
27 | | - .record( |
28 | | - z.string(), |
29 | | - z.object({ |
30 | | - orderedItems: z.record(z.string(), z.array(z.string())), |
31 | | - }) |
32 | | - ) |
33 | | - .optional(), |
34 | | - /** Pages the user favorited, in display order. */ |
35 | | - favorites: z.array(FavoritePage).optional(), |
36 | | - /** Custom top-to-bottom order of side menu sections (section ids). */ |
37 | | - sectionOrder: z.array(z.string()).optional(), |
38 | | - /** Per-item visibility overrides (item id -> hidden). Items absent fall back to their default. */ |
39 | | - hiddenItems: z.record(z.string(), z.boolean()).optional(), |
40 | | - /** Custom item order within a section (section id -> item ids). */ |
41 | | - sectionItemOrder: z.record(z.string(), z.array(z.string())).optional(), |
42 | | -}); |
43 | | - |
44 | | -export type SideMenuPreferences = z.infer<typeof SideMenuPreferences>; |
| 4 | +import { |
| 5 | + type DashboardPreferences, |
| 6 | + type FavoritePage, |
| 7 | + parseDashboardPreferences, |
| 8 | + SideMenuPreferences, |
| 9 | +} from "~/utils/dashboardPreferences"; |
| 10 | + |
| 11 | +export type { |
| 12 | + DashboardPreferences, |
| 13 | + FavoritePage, |
| 14 | + SideMenuPreferences, |
| 15 | +} from "~/utils/dashboardPreferences"; |
45 | 16 |
|
46 | 17 | import { type SideMenuSectionId } from "~/components/navigation/sideMenuTypes"; |
47 | 18 | export type { SideMenuSectionId }; |
48 | 19 |
|
49 | | -import { ThemePreference } from "~/utils/themePreference"; |
| 20 | +import { type ThemePreference } from "~/utils/themePreference"; |
50 | 21 | export { normalizeThemePreference, type ThemePreference } from "~/utils/themePreference"; |
51 | 22 |
|
52 | | -const DashboardPreferences = z.object({ |
53 | | - version: z.literal("1"), |
54 | | - theme: ThemePreference.optional(), |
55 | | - /** Interface contrast for the System themes, 0-100. */ |
56 | | - contrast: z.number().int().min(0).max(100).optional(), |
57 | | - currentProjectId: z.string().optional(), |
58 | | - projects: z.record( |
59 | | - z.string(), |
60 | | - z.object({ |
61 | | - currentEnvironment: z.object({ id: z.string() }), |
62 | | - }) |
63 | | - ), |
64 | | - sideMenu: SideMenuPreferences.optional(), |
65 | | -}); |
66 | | - |
67 | | -export type DashboardPreferences = z.infer<typeof DashboardPreferences>; |
68 | | - |
69 | 23 | export function getDashboardPreferences(data?: any | null): DashboardPreferences { |
70 | | - if (!data) { |
71 | | - return { |
72 | | - version: "1", |
73 | | - projects: {}, |
74 | | - }; |
75 | | - } |
76 | | - |
77 | | - const result = DashboardPreferences.safeParse(data); |
78 | | - if (!result.success) { |
79 | | - logger.error("Failed to parse DashboardPreferences", { data, error: result.error }); |
80 | | - return { |
81 | | - version: "1", |
82 | | - projects: {}, |
83 | | - }; |
84 | | - } |
85 | | - |
86 | | - return result.data; |
| 24 | + return parseDashboardPreferences(data, (error) => { |
| 25 | + logger.error("Failed to parse DashboardPreferences", { data, error }); |
| 26 | + }); |
87 | 27 | } |
88 | 28 |
|
89 | 29 | /** |
|
0 commit comments