iprov
This commit is contained in:
@@ -1,52 +0,0 @@
|
||||
import { describe, it, expect, beforeAll } from 'vitest'
|
||||
import { getNextNodeId, replaceNodeIdInGraph, DEFAULT_NODE_STYLE } from './flowUtils'
|
||||
import { registerBuiltinNodes } from './registerBuiltinNodes'
|
||||
|
||||
beforeAll(() => {
|
||||
registerBuiltinNodes()
|
||||
})
|
||||
|
||||
describe('getNextNodeId', () => {
|
||||
it('returns prefix + 001 when no existing ids', () => {
|
||||
expect(getNextNodeId('config', [])).toBe('cfg_001')
|
||||
expect(getNextNodeId('render', [])).toBe('rnd_001')
|
||||
expect(getNextNodeId('variable', [])).toBe('var_001')
|
||||
expect(getNextNodeId('function', [])).toBe('fn_001')
|
||||
})
|
||||
|
||||
it('increments after existing ids', () => {
|
||||
expect(getNextNodeId('config', ['cfg_001'])).toBe('cfg_002')
|
||||
expect(getNextNodeId('config', ['cfg_001', 'cfg_002', 'cfg_003'])).toBe('cfg_004')
|
||||
})
|
||||
|
||||
it('ignores ids of other types', () => {
|
||||
expect(getNextNodeId('config', ['rnd_001', 'var_001'])).toBe('cfg_001')
|
||||
expect(getNextNodeId('config', ['cfg_002'])).toBe('cfg_003')
|
||||
})
|
||||
})
|
||||
|
||||
describe('replaceNodeIdInGraph', () => {
|
||||
it('renames node and updates edges and references in data', () => {
|
||||
const nodes = [
|
||||
{ id: 'cfg_001', data: { title: 'cfg_001', plantuml: 'x' }, type: 'config', position: { x: 0, y: 0 } },
|
||||
{ id: 'rnd_001', data: {}, type: 'render', position: { x: 100, y: 0 } },
|
||||
]
|
||||
const edges = [
|
||||
{ id: 'e-cfg_001-rnd_001', source: 'cfg_001', target: 'rnd_001' },
|
||||
]
|
||||
const result = replaceNodeIdInGraph(nodes, edges, 'cfg_001', 'cfg_002')
|
||||
expect(result.nodes[0].id).toBe('cfg_002')
|
||||
expect(result.nodes[0].data).toEqual(expect.objectContaining({ title: 'cfg_002' }))
|
||||
expect(result.edges[0].source).toBe('cfg_002')
|
||||
expect(result.edges[0].id).toBe('e-cfg_002-rnd_001')
|
||||
})
|
||||
})
|
||||
|
||||
describe('DEFAULT_NODE_STYLE', () => {
|
||||
it('has styles for config, render, variable, function', () => {
|
||||
expect(DEFAULT_NODE_STYLE.config).toEqual({ width: 320, height: 320 })
|
||||
expect(DEFAULT_NODE_STYLE.render).toEqual({ width: 384, height: 320 })
|
||||
expect(DEFAULT_NODE_STYLE.variable).toEqual({ width: 224, height: 180 })
|
||||
expect(DEFAULT_NODE_STYLE.function).toEqual({ width: 288, height: 260 })
|
||||
})
|
||||
})
|
||||
@@ -11,11 +11,7 @@ import {
|
||||
getDefaultStyle,
|
||||
} from './nodeRegistry'
|
||||
|
||||
/** Minimal node/edge shape for replaceNodeIdInGraph (avoids circular dependency on nodeTypes). */
|
||||
type GraphNode = { id: string; data?: unknown; [k: string]: unknown }
|
||||
type GraphEdge = { id: string; source: string; target: string; [k: string]: unknown }
|
||||
|
||||
export function nodePropsAreEqual<P extends { id?: string; data?: unknown; width?: number; height?: number; selected?: boolean }>(
|
||||
export function nodePropsAreEqual<P extends { id?: string; data?: any; width?: number; height?: number; selected?: boolean }>(
|
||||
prev: P,
|
||||
next: P
|
||||
): boolean {
|
||||
@@ -60,15 +56,13 @@ function replaceInData(value: unknown, oldId: string, newId: string): unknown {
|
||||
|
||||
/** Update graph after renaming a node: change node id and all references in data and edges */
|
||||
export function replaceNodeIdInGraph(
|
||||
nodes: GraphNode[],
|
||||
edges: GraphEdge[],
|
||||
nodes: Array<{ id: string; data?: any; [k: string]: any }>,
|
||||
edges: Array<{ id: string; source: string; target: string; [k: string]: any }>,
|
||||
oldId: string,
|
||||
newId: string
|
||||
): { nodes: GraphNode[]; edges: GraphEdge[] } {
|
||||
): { nodes: typeof nodes; edges: typeof edges } {
|
||||
const newNodes = nodes.map((n) =>
|
||||
n.id === oldId
|
||||
? { ...n, id: newId, data: replaceInData(n.data, oldId, newId) }
|
||||
: { ...n, data: replaceInData(n.data, oldId, newId) }
|
||||
n.id === oldId ? { ...n, id: newId } : { ...n, data: replaceInData(n.data, oldId, newId) as any }
|
||||
)
|
||||
const newEdges = edges.map((e) => ({
|
||||
...e,
|
||||
@@ -88,12 +82,12 @@ export const DEFAULT_NODE_STYLE: Record<string, { width: number; height: number
|
||||
}
|
||||
|
||||
/** Default data for a new node. Uses nodeRegistry when type is registered. */
|
||||
export function getDefaultDataForType(type: string, newId?: string): Record<string, unknown> {
|
||||
export function getDefaultDataForType(type: string, newId?: string): any {
|
||||
return getDefaultDataFromRegistry(type, newId)
|
||||
}
|
||||
|
||||
/** Data for Reset action. Uses nodeRegistry when type is registered. */
|
||||
export function getResetDataForType(type: string, nodeId?: string): Record<string, unknown> {
|
||||
export function getResetDataForType(type: string, nodeId?: string): any {
|
||||
return getResetDataFromRegistry(type, nodeId)
|
||||
}
|
||||
|
||||
|
||||
@@ -12,18 +12,9 @@ export type NodeHelpEntry = {
|
||||
content: React.ReactNode
|
||||
}
|
||||
|
||||
/** Props passed to registered node components: id, data, and optional dimensions/selection. */
|
||||
export type NodeComponentProps = {
|
||||
id: string
|
||||
data?: Record<string, unknown>
|
||||
width?: number
|
||||
height?: number
|
||||
selected?: boolean
|
||||
}
|
||||
|
||||
export type NodeTypeDescriptor = {
|
||||
id: string
|
||||
component: React.ComponentType<NodeComponentProps>
|
||||
component: React.ComponentType<any>
|
||||
defaultStyle: { width: number; height: number }
|
||||
defaultData: Record<string, unknown>
|
||||
idPrefix: string
|
||||
@@ -70,8 +61,8 @@ export function getDefaultDataForType(type: string, newId?: string): Record<stri
|
||||
const desc = registry.get(type)
|
||||
if (!desc) return {}
|
||||
if (desc.getDefaultData) return { ...desc.getDefaultData(newId) }
|
||||
const base: Record<string, unknown> = { ...desc.defaultData }
|
||||
if (type === 'config' && newId) base.title = `${newId}`
|
||||
const base = { ...desc.defaultData }
|
||||
if (type === 'config' && newId) (base as any).title = `${newId}`
|
||||
return base
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user