feat(dashboard): manage account layout drafts and recovery
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
export type WidgetSize = 'standard' | 'full';
|
||||
|
||||
export const WIDGETS = [
|
||||
{ id: 'cards', titleKey: 'dashboardSummaryCards', defaultSize: 'full', sizes: ['full'] },
|
||||
{ id: 'attention', titleKey: 'dashboardTodayTitle', defaultSize: 'standard', sizes: ['standard', 'full'] },
|
||||
{ id: 'funnel', titleKey: 'dashboardCurrentPipeline', defaultSize: 'standard', sizes: ['standard', 'full'] },
|
||||
{ id: 'activity', titleKey: 'dashboardApplicationActivity', defaultSize: 'full', sizes: ['standard', 'full'] },
|
||||
{ id: 'stageAge', titleKey: 'dashboardStageAge', defaultSize: 'standard', sizes: ['standard', 'full'] },
|
||||
{ id: 'sources', titleKey: 'dashboardResponseSources', defaultSize: 'standard', sizes: ['standard', 'full'] },
|
||||
{ id: 'salary', titleKey: 'dashboardSalaryInsights', defaultSize: 'full', sizes: ['standard', 'full'] },
|
||||
{ id: 'companies', titleKey: 'dashboardTopCompaniesByActivity', defaultSize: 'standard', sizes: ['standard', 'full'] },
|
||||
{ id: 'skills', titleKey: 'dashboardJobTags', defaultSize: 'standard', sizes: ['standard', 'full'] },
|
||||
] as const;
|
||||
|
||||
export type WidgetId = typeof WIDGETS[number]['id'];
|
||||
export type DashboardWidget = { id: WidgetId; visible: boolean; size: WidgetSize };
|
||||
export type DashboardLayout = { version: 1; revision: number; widgets: DashboardWidget[] };
|
||||
|
||||
export function defaultDashboardLayout(): DashboardLayout {
|
||||
return { version: 1, revision: 0, widgets: WIDGETS.map(w => ({ id: w.id, visible: true, size: w.defaultSize })) };
|
||||
}
|
||||
|
||||
export function normalizeDashboardLayout(input: unknown): DashboardLayout {
|
||||
if (!input || typeof input !== 'object') return defaultDashboardLayout();
|
||||
const value = input as Record<string, unknown>;
|
||||
if (value.version !== 1 || !Number.isSafeInteger(value.revision) || (value.revision as number) < 0 || !Array.isArray(value.widgets)) return defaultDashboardLayout();
|
||||
const revision = value.revision as number;
|
||||
const widgets: DashboardWidget[] = [];
|
||||
const seen = new Set<WidgetId>();
|
||||
for (const item of value.widgets) {
|
||||
if (!item || typeof item !== 'object') continue;
|
||||
const definition = WIDGETS.find(w => w.id === item.id);
|
||||
if (!definition || seen.has(definition.id)) continue;
|
||||
seen.add(definition.id);
|
||||
widgets.push({ id: definition.id, visible: typeof item.visible === 'boolean' ? item.visible : revision === 0,
|
||||
size: (definition.sizes as readonly string[]).includes(item.size) ? item.size : definition.defaultSize });
|
||||
}
|
||||
for (const definition of WIDGETS) {
|
||||
if (!seen.has(definition.id)) widgets.push({ id: definition.id, visible: revision === 0, size: definition.defaultSize });
|
||||
}
|
||||
return { version: 1, revision, widgets };
|
||||
}
|
||||
Reference in New Issue
Block a user