improvements
This commit is contained in:
@@ -5,6 +5,8 @@ export type FlowContextValue = {
|
||||
setNodes: (updater: any) => void
|
||||
edges: any[]
|
||||
setEdges: (updater: any) => void
|
||||
renamingNodeId: string | null
|
||||
setRenamingNodeId: (id: string | null) => void
|
||||
}
|
||||
|
||||
const FlowContext = React.createContext<FlowContextValue | null>(null)
|
||||
|
||||
@@ -1,5 +1,50 @@
|
||||
/** Generate short unique node id */
|
||||
export const genId = () => `node_${Math.random().toString(36).slice(2, 9)}`
|
||||
export const PREFIX_BY_TYPE: Record<string, string> = {
|
||||
config: 'cfg_',
|
||||
render: 'rnd_',
|
||||
variable: 'var_',
|
||||
function: 'fn_',
|
||||
}
|
||||
|
||||
/** Next node id for type: prefix + 3-digit increasing number (001, 002, …) */
|
||||
export function getNextNodeId(type: string, existingIds: string[]): string {
|
||||
const prefix = PREFIX_BY_TYPE[type] ?? 'node_'
|
||||
const re = new RegExp(`^${prefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(\\d+)$`)
|
||||
let max = 0
|
||||
for (const id of existingIds) {
|
||||
const m = id.match(re)
|
||||
if (m) max = Math.max(max, parseInt(m[1], 10))
|
||||
}
|
||||
return `${prefix}${String(max + 1).padStart(3, '0')}`
|
||||
}
|
||||
|
||||
/** Recursively replace oldId with newId in string values (for rename propagation) */
|
||||
function replaceInData(value: unknown, oldId: string, newId: string): unknown {
|
||||
if (typeof value === 'string') return value.split(oldId).join(newId)
|
||||
if (value === null || typeof value !== 'object') return value
|
||||
if (Array.isArray(value)) return value.map((v) => replaceInData(v, oldId, newId))
|
||||
const out: Record<string, unknown> = {}
|
||||
for (const [k, v] of Object.entries(value)) out[k] = replaceInData(v, oldId, newId)
|
||||
return out
|
||||
}
|
||||
|
||||
/** Update graph after renaming a node: change node id and all references in data and edges */
|
||||
export function replaceNodeIdInGraph(
|
||||
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: typeof nodes; edges: typeof edges } {
|
||||
const newNodes = nodes.map((n) =>
|
||||
n.id === oldId ? { ...n, id: newId } : { ...n, data: replaceInData(n.data, oldId, newId) as any }
|
||||
)
|
||||
const newEdges = edges.map((e) => ({
|
||||
...e,
|
||||
id: e.id.includes(oldId) ? e.id.split(oldId).join(newId) : e.id,
|
||||
source: e.source === oldId ? newId : e.source,
|
||||
target: e.target === oldId ? newId : e.target,
|
||||
}))
|
||||
return { nodes: newNodes, edges: newEdges }
|
||||
}
|
||||
|
||||
export const DEFAULT_NODE_STYLE: Record<string, { width: number; height: number }> = {
|
||||
config: { width: 320, height: 320 },
|
||||
@@ -20,3 +65,14 @@ export function getDefaultDataForType(type: string, newId?: string): any {
|
||||
if (type === 'config' && newId) base.title = `config-${newId}`
|
||||
return base
|
||||
}
|
||||
|
||||
/** Data for Reset action: clears code completely for config/function; same as default for others */
|
||||
export function getResetDataForType(type: string, nodeId?: string): any {
|
||||
if (type === 'config') {
|
||||
return { plantuml: '@startuml\n\n@enduml\n', title: nodeId ? `config-${nodeId}` : '' }
|
||||
}
|
||||
if (type === 'function') {
|
||||
return { body: '' }
|
||||
}
|
||||
return getDefaultDataForType(type, nodeId)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user