/** * Reusable property-schema fragments for nodes and edges. Each symbol composes * a base (Identity + Presentation) with its own Physics group. */ import type { PropertyGroup, PropertySchema, PropertyDef } from './properties' const yesNo: PropertyDef['options'] = [ { value: 'yes', label: 'Show' }, { value: 'no', label: 'Hide' } ] export function identityGroup(defaultTitle: string): PropertyGroup { return { id: 'identity', label: 'Identity', defs: [ { key: 'title', label: 'Title', type: 'string', group: 'identity', default: defaultTitle }, { key: 'tag', label: 'Tag / ID', type: 'string', group: 'identity', default: '' }, { key: 'notes', label: 'Notes', type: 'string', group: 'identity', default: '' } ] } } export function nodePresentationGroup(color: string): PropertyGroup { return { id: 'presentation', label: 'Presentation', defs: [ { key: 'color', label: 'Accent color', type: 'color', group: 'presentation', default: color }, { key: 'rotation', label: 'Rotation', type: 'int', group: 'presentation', unit: '°', min: 0, max: 270, step: 90, default: 0 }, { key: 'width', label: 'Width', type: 'int', group: 'presentation', unit: 'px', min: 24, max: 240, default: 72 }, { key: 'height', label: 'Height', type: 'int', group: 'presentation', unit: 'px', min: 24, max: 240, default: 72 }, { key: 'showLabel', label: 'Label', type: 'enum', group: 'presentation', options: yesNo, default: 'yes' } ] } } export function physicsGroup(defs: PropertyDef[]): PropertyGroup { return { id: 'physics', label: 'Physics', defs: defs.map((d) => ({ ...d, group: 'physics' })) } } /** Build a node schema from a physics-group definition list. */ export function nodeSchema( defaultTitle: string, color: string, physics: PropertyDef[] ): PropertySchema { return [identityGroup(defaultTitle), nodePresentationGroup(color), physicsGroup(physics)] } // ---- Edge schema ---------------------------------------------------------- export const MARKER_OPTIONS: PropertyDef['options'] = [ { value: 'none', label: 'None' }, { value: 'arrow', label: 'Arrow' }, { value: 'openArrow', label: 'Open arrow' }, { value: 'circle', label: 'Circle' }, { value: 'diamond', label: 'Diamond' }, { value: 'bar', label: 'Bar' } ] export const LINE_STYLE_OPTIONS: PropertyDef['options'] = [ { value: 'solid', label: 'Solid' }, { value: 'dashed', label: 'Dashed' }, { value: 'dotted', label: 'Dotted' } ] export function edgeSchema(): PropertySchema { return [ { id: 'identity', label: 'Identity', defs: [ { key: 'title', label: 'Title', type: 'string', group: 'identity', default: '' }, { key: 'tag', label: 'Tag / ID', type: 'string', group: 'identity', default: '' } ] }, { id: 'presentation', label: 'Presentation', defs: [ { key: 'color', label: 'Line color', type: 'color', group: 'presentation', default: '#2f7fe0' }, { key: 'lineStyle', label: 'Line style', type: 'enum', group: 'presentation', options: LINE_STYLE_OPTIONS, default: 'solid' }, { key: 'strokeWidth', label: 'Width', type: 'int', group: 'presentation', unit: 'px', min: 1, max: 12, default: 3 }, { key: 'tailMarker', label: 'Tail marker', type: 'enum', group: 'presentation', options: MARKER_OPTIONS, default: 'none' }, { key: 'headMarker', label: 'Head marker', type: 'enum', group: 'presentation', options: MARKER_OPTIONS, default: 'arrow' } ] }, { id: 'physics', label: 'Physics', defs: [ { key: 'length', label: 'Length', type: 'float', group: 'physics', unit: 'm', min: 0, step: 0.1, default: 10 }, { key: 'diameter', label: 'Diameter', type: 'float', group: 'physics', unit: 'mm', min: 1, step: 1, default: 100 }, { key: 'material', label: 'Material', type: 'catalogueItem', group: 'physics', catalogue: 'pipeMaterial', default: 'steel' }, { key: 'roughness', label: 'Roughness', type: 'float', group: 'physics', unit: 'mm', min: 0, step: 0.001, default: 0.045 }, { key: 'flowType', label: 'Flow type', type: 'enum', group: 'physics', options: [ { value: 'auto', label: 'Auto' }, { value: 'laminar', label: 'Laminar' }, { value: 'turbulent', label: 'Turbulent' } ], default: 'auto' }, { key: 'designFlow', label: 'Design flow', type: 'float', group: 'physics', unit: 'm³/h', min: 0, step: 0.1, default: 0 }, { key: 'tags', label: 'Zone tags', type: 'listOfValues', group: 'physics', itemType: 'string', default: [] } ] } ] }