feat(phase3): import/export, sparklines, user theme overrides
- JSON import/export with conflict resolution (skip/overwrite) + admin UI - Ping history sparklines on AppWidget and AppCard (24h, 288 points) - Hourly cleanup job for old AppStatus records - User theme preferences (hue, saturation, mode, background, locale) - Settings page with ThemeCustomizer (sliders, toggles, live preview) - Prisma migration for user preference fields - i18n translations for all new strings (EN/RU)
This commit is contained in:
@@ -181,6 +181,71 @@ export const createPermissionSchema = z.object({
|
||||
level: z.enum([PermissionLevel.VIEW, PermissionLevel.EDIT, PermissionLevel.ADMIN])
|
||||
});
|
||||
|
||||
// --- Import/Export ---
|
||||
|
||||
const importAppSchema = z.object({
|
||||
name: z.string().min(1).max(200),
|
||||
url: z.string().url(),
|
||||
icon: z.string().max(500).nullable(),
|
||||
iconType: z.string().max(50),
|
||||
description: z.string().max(1000).nullable(),
|
||||
category: z.string().max(100).nullable(),
|
||||
tags: z.string().max(500),
|
||||
healthcheckEnabled: z.boolean(),
|
||||
healthcheckInterval: z.number().int().min(30).max(86400),
|
||||
healthcheckMethod: z.string(),
|
||||
healthcheckExpectedStatus: z.number().int().min(100).max(599),
|
||||
healthcheckTimeout: z.number().int().min(1000).max(30000)
|
||||
});
|
||||
|
||||
const importWidgetSchema = z.object({
|
||||
type: z.string().min(1),
|
||||
order: z.number().int().min(0),
|
||||
config: z.string(),
|
||||
appName: z.string().nullable()
|
||||
});
|
||||
|
||||
const importSectionSchema = z.object({
|
||||
title: z.string().min(1).max(200),
|
||||
icon: z.string().max(500).nullable(),
|
||||
order: z.number().int().min(0),
|
||||
isExpandedByDefault: z.boolean(),
|
||||
widgets: z.array(importWidgetSchema)
|
||||
});
|
||||
|
||||
const importBoardSchema = z.object({
|
||||
name: z.string().min(1).max(200),
|
||||
icon: z.string().max(500).nullable(),
|
||||
description: z.string().max(1000).nullable(),
|
||||
isDefault: z.boolean(),
|
||||
isGuestAccessible: z.boolean(),
|
||||
backgroundConfig: z.string().nullable(),
|
||||
sections: z.array(importSectionSchema)
|
||||
});
|
||||
|
||||
const importGroupSchema = z.object({
|
||||
name: z.string().min(1).max(100),
|
||||
description: z.string().max(500).nullable(),
|
||||
isDefault: z.boolean()
|
||||
});
|
||||
|
||||
const importSettingsSchema = z.object({
|
||||
authMode: z.string().optional(),
|
||||
registrationEnabled: z.boolean().optional(),
|
||||
defaultTheme: z.string().optional(),
|
||||
defaultPrimaryColor: z.string().optional(),
|
||||
healthcheckDefaults: z.string().optional()
|
||||
});
|
||||
|
||||
export const importDataSchema = z.object({
|
||||
version: z.string(),
|
||||
exportedAt: z.string(),
|
||||
apps: z.array(importAppSchema),
|
||||
boards: z.array(importBoardSchema),
|
||||
groups: z.array(importGroupSchema),
|
||||
settings: importSettingsSchema
|
||||
});
|
||||
|
||||
// --- System Settings ---
|
||||
|
||||
export const updateSystemSettingsSchema = z.object({
|
||||
|
||||
Reference in New Issue
Block a user