79 lines
2.8 KiB
TypeScript
79 lines
2.8 KiB
TypeScript
import type { WorkflowConfig, WorkflowDefinition } from '../../api/workflows'
|
|
import type { WorkflowGraphFamily, WorkflowNodeDefinitionMap } from './workflowNodeLibrary'
|
|
import { getNodeFamily } from './workflowNodeLibrary'
|
|
|
|
export const BLUEPRINT_LABELS: Record<string, string> = {
|
|
cad_intake: 'Reference Blueprint',
|
|
order_rendering: 'Reference Blueprint',
|
|
still_graph_reference: 'Graph Reference',
|
|
starter_cad_intake: 'Starter',
|
|
starter_order_rendering: 'Starter',
|
|
}
|
|
|
|
export const BLUEPRINT_DESCRIPTION: Record<string, string> = {
|
|
cad_intake: 'Canonical CAD-file workflow for intake, preview generation, and material discovery.',
|
|
order_rendering: 'Canonical order-line workflow for production rendering, exports, and notifications.',
|
|
still_graph_reference: 'Reference still-render graph that stays parallel to the legacy workflow while native nodes reach parity.',
|
|
starter_cad_intake: 'Minimal CAD-file starter graph.',
|
|
starter_order_rendering: 'Minimal order-line starter graph.',
|
|
}
|
|
|
|
export function inferWorkflowFamily(
|
|
config: WorkflowConfig,
|
|
nodeDefinitionsByStep?: WorkflowNodeDefinitionMap,
|
|
): WorkflowGraphFamily {
|
|
const nodes = Array.isArray(config.nodes) ? config.nodes : []
|
|
if (nodes.length > 0) {
|
|
const families = new Set(nodes.map(node => getNodeFamily(node.step, nodeDefinitionsByStep)))
|
|
if (families.size === 1) {
|
|
return Array.from(families)[0]
|
|
}
|
|
return 'mixed'
|
|
}
|
|
|
|
const presetType = config.ui?.preset ?? 'custom'
|
|
if (presetType === 'custom') {
|
|
return 'mixed'
|
|
}
|
|
|
|
return 'order_line'
|
|
}
|
|
|
|
export function getWorkflowBlueprint(config: WorkflowConfig): string | null {
|
|
const blueprint = config.ui?.blueprint
|
|
return typeof blueprint === 'string' && blueprint.trim().length > 0 ? blueprint : null
|
|
}
|
|
|
|
export function isReferenceBlueprint(config: WorkflowConfig): boolean {
|
|
const blueprint = getWorkflowBlueprint(config)
|
|
return blueprint === 'cad_intake' || blueprint === 'order_rendering' || blueprint === 'still_graph_reference'
|
|
}
|
|
|
|
export function cloneWorkflowConfig(config: WorkflowConfig, options?: { stripBlueprint?: boolean }): WorkflowConfig {
|
|
const nextUi = { ...(config.ui ?? {}) }
|
|
if (options?.stripBlueprint) {
|
|
delete nextUi.blueprint
|
|
}
|
|
|
|
return {
|
|
version: config.version,
|
|
nodes: config.nodes.map(node => ({
|
|
...node,
|
|
params: { ...(node.params ?? {}) },
|
|
ui: node.ui ? { ...node.ui } : undefined,
|
|
})),
|
|
edges: config.edges.map(edge => ({ ...edge })),
|
|
ui: nextUi,
|
|
}
|
|
}
|
|
|
|
export function compareWorkflows(a: WorkflowDefinition, b: WorkflowDefinition): number {
|
|
const blueprintRank = Number(isReferenceBlueprint(b.config)) - Number(isReferenceBlueprint(a.config))
|
|
if (blueprintRank !== 0) return blueprintRank
|
|
|
|
const activeRank = Number(b.is_active) - Number(a.is_active)
|
|
if (activeRank !== 0) return activeRank
|
|
|
|
return a.name.localeCompare(b.name)
|
|
}
|