feat: synchronize backend and frontend custom field handling
This commit is contained in:
64
src/common/constants/component-includes.ts
Normal file
64
src/common/constants/component-includes.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { Prisma } from '@prisma/client';
|
||||
|
||||
const CUSTOM_FIELD_SELECT = {
|
||||
id: true,
|
||||
name: true,
|
||||
type: true,
|
||||
required: true,
|
||||
options: true,
|
||||
} as const;
|
||||
|
||||
export const COMPONENT_WITH_RELATIONS_INCLUDE = {
|
||||
machine: true,
|
||||
parentComposant: true,
|
||||
typeComposant: {
|
||||
include: {
|
||||
customFields: true,
|
||||
},
|
||||
},
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: {
|
||||
include: {
|
||||
customFields: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
customFieldValues: {
|
||||
include: {
|
||||
customField: { select: CUSTOM_FIELD_SELECT },
|
||||
},
|
||||
},
|
||||
pieces: {
|
||||
include: {
|
||||
customFieldValues: {
|
||||
include: {
|
||||
customField: { select: CUSTOM_FIELD_SELECT },
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: {
|
||||
include: {
|
||||
customFields: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
documents: true,
|
||||
},
|
||||
},
|
||||
documents: true,
|
||||
} satisfies Prisma.ComposantInclude;
|
||||
|
||||
export interface ComposantWithRelations
|
||||
extends Prisma.ComposantGetPayload<{
|
||||
include: typeof COMPONENT_WITH_RELATIONS_INCLUDE;
|
||||
}> {
|
||||
sousComposants?: ComposantWithRelations[];
|
||||
}
|
||||
51
src/common/utils/component-tree.util.ts
Normal file
51
src/common/utils/component-tree.util.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
export interface HierarchicalComponent<T = any> {
|
||||
id: string;
|
||||
parentComposantId?: string | null;
|
||||
sousComposants?: T[];
|
||||
}
|
||||
|
||||
export function buildComponentHierarchy<T extends HierarchicalComponent<T>>(
|
||||
components: readonly T[],
|
||||
): T[] {
|
||||
if (!Array.isArray(components) || components.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const byParent = new Map<string | null, T[]>();
|
||||
|
||||
components.forEach((raw) => {
|
||||
const component = raw as HierarchicalComponent<T>;
|
||||
const parentId = component.parentComposantId ?? null;
|
||||
if (!byParent.has(parentId)) {
|
||||
byParent.set(parentId, [] as T[]);
|
||||
}
|
||||
component.sousComposants = [] as T[];
|
||||
byParent.get(parentId)!.push(component as T);
|
||||
});
|
||||
|
||||
const attach = (component: T): T => {
|
||||
const children = byParent.get(component.id) ?? [];
|
||||
component.sousComposants = children.map(attach);
|
||||
return component;
|
||||
};
|
||||
|
||||
const roots = byParent.get(null) ?? [];
|
||||
return roots.map(attach);
|
||||
}
|
||||
|
||||
export function buildComponentSubtree<T extends HierarchicalComponent<T>>(
|
||||
components: T[],
|
||||
rootId: string,
|
||||
): T | null {
|
||||
if (!Array.isArray(components) || components.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const map = new Map<string, T>();
|
||||
components.forEach((component) => {
|
||||
map.set(component.id, component);
|
||||
});
|
||||
|
||||
buildComponentHierarchy(components);
|
||||
return map.get(rootId) ?? null;
|
||||
}
|
||||
Reference in New Issue
Block a user