Add versioned project settings modal
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const projectStateSnapshotSchemaVersion = 1 as const;
|
||||
export const legacyProjectStateSnapshotSchemaVersion = 1 as const;
|
||||
export const projectStateSnapshotSchemaVersion = 2 as const;
|
||||
|
||||
const idSchema = z.string().trim().min(1);
|
||||
const nullableStringSchema = z.string().nullable();
|
||||
const finiteNumberSchema = z.number().finite();
|
||||
|
||||
const projectSchema = z
|
||||
const legacyProjectSchema = z
|
||||
.object({
|
||||
id: idSchema,
|
||||
name: z.string().trim().min(1),
|
||||
@@ -15,6 +16,13 @@ const projectSchema = z
|
||||
})
|
||||
.strict();
|
||||
|
||||
const projectSchema = legacyProjectSchema.extend({
|
||||
internalProjectNumber: z.string().trim().min(1).max(100).nullable(),
|
||||
externalProjectNumber: z.string().trim().min(1).max(100).nullable(),
|
||||
buildingOwner: z.string().trim().min(1).max(200).nullable(),
|
||||
description: z.string().trim().min(1).max(2000).nullable(),
|
||||
});
|
||||
|
||||
const distributionBoardSchema = z
|
||||
.object({
|
||||
id: idSchema,
|
||||
@@ -132,17 +140,29 @@ const roomSchema = z
|
||||
})
|
||||
.strict();
|
||||
|
||||
const projectStateSnapshotContents = {
|
||||
distributionBoards: z.array(distributionBoardSchema),
|
||||
circuitLists: z.array(circuitListSchema),
|
||||
circuitSections: z.array(circuitSectionSchema),
|
||||
circuits: z.array(circuitSchema),
|
||||
projectDevices: z.array(projectDeviceSchema),
|
||||
floors: z.array(floorSchema),
|
||||
rooms: z.array(roomSchema),
|
||||
};
|
||||
|
||||
const legacyProjectStateSnapshotSchema = z
|
||||
.object({
|
||||
schemaVersion: z.literal(legacyProjectStateSnapshotSchemaVersion),
|
||||
project: legacyProjectSchema,
|
||||
...projectStateSnapshotContents,
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const projectStateSnapshotSchema = z
|
||||
.object({
|
||||
schemaVersion: z.literal(projectStateSnapshotSchemaVersion),
|
||||
project: projectSchema,
|
||||
distributionBoards: z.array(distributionBoardSchema),
|
||||
circuitLists: z.array(circuitListSchema),
|
||||
circuitSections: z.array(circuitSectionSchema),
|
||||
circuits: z.array(circuitSchema),
|
||||
projectDevices: z.array(projectDeviceSchema),
|
||||
floors: z.array(floorSchema),
|
||||
rooms: z.array(roomSchema),
|
||||
...projectStateSnapshotContents,
|
||||
})
|
||||
.strict();
|
||||
|
||||
@@ -153,11 +173,37 @@ export type ProjectStateSnapshot = z.infer<
|
||||
export function parseProjectStateSnapshot(
|
||||
value: unknown
|
||||
): ProjectStateSnapshot {
|
||||
const snapshot = projectStateSnapshotSchema.parse(value);
|
||||
const version = isPlainObject(value) ? value.schemaVersion : undefined;
|
||||
const snapshot =
|
||||
version === legacyProjectStateSnapshotSchemaVersion
|
||||
? upgradeLegacyProjectStateSnapshot(
|
||||
legacyProjectStateSnapshotSchema.parse(value)
|
||||
)
|
||||
: projectStateSnapshotSchema.parse(value);
|
||||
assertProjectStateSnapshotRelations(snapshot);
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
function upgradeLegacyProjectStateSnapshot(
|
||||
snapshot: z.infer<typeof legacyProjectStateSnapshotSchema>
|
||||
): ProjectStateSnapshot {
|
||||
return {
|
||||
...snapshot,
|
||||
schemaVersion: projectStateSnapshotSchemaVersion,
|
||||
project: {
|
||||
...snapshot.project,
|
||||
internalProjectNumber: null,
|
||||
externalProjectNumber: null,
|
||||
buildingOwner: null,
|
||||
description: null,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
||||
return value !== null && typeof value === "object" && !Array.isArray(value);
|
||||
}
|
||||
|
||||
export function serializeProjectStateSnapshot(
|
||||
snapshot: ProjectStateSnapshot
|
||||
): string {
|
||||
|
||||
Reference in New Issue
Block a user