Merge pull request #1038 from SuanmoSuanyangTechnology/fix/history_zy
fix(web): history undo/redo
This commit is contained in:
@@ -355,14 +355,13 @@ const CaseList: FC<CaseListProps> = ({
|
|||||||
// Update node ports based on case count changes (add/remove cases)
|
// Update node ports based on case count changes (add/remove cases)
|
||||||
const updateNodePorts = (caseCount: number, removedCaseIndex?: number) => {
|
const updateNodePorts = (caseCount: number, removedCaseIndex?: number) => {
|
||||||
if (!selectedNode || !graphRef?.current) return;
|
if (!selectedNode || !graphRef?.current) return;
|
||||||
|
const graph = graphRef.current;
|
||||||
// Get current port count to determine if it's an add or remove operation
|
|
||||||
const currentPorts = selectedNode.getPorts().filter((port: any) => port.group === 'right');
|
const currentRightPorts = selectedNode.getPorts().filter((port: any) => port.group === 'right');
|
||||||
const currentCaseCount = currentPorts.length - 1; // Exclude ELSE port
|
const currentCaseCount = currentRightPorts.length - 1;
|
||||||
const isAddingCase = removedCaseIndex === undefined && caseCount > currentCaseCount;
|
const isAddingCase = removedCaseIndex === undefined && caseCount > currentCaseCount;
|
||||||
|
|
||||||
// Save existing edge connections (including left-side port connections)
|
const existingEdges = graph.getEdges().filter((edge: any) =>
|
||||||
const existingEdges = graphRef.current.getEdges().filter((edge: any) =>
|
|
||||||
edge.getSourceCellId() === selectedNode.id || edge.getTargetCellId() === selectedNode.id
|
edge.getSourceCellId() === selectedNode.id || edge.getTargetCellId() === selectedNode.id
|
||||||
);
|
);
|
||||||
const edgeConnections = existingEdges.map((edge: any) => ({
|
const edgeConnections = existingEdges.map((edge: any) => ({
|
||||||
@@ -371,113 +370,70 @@ const CaseList: FC<CaseListProps> = ({
|
|||||||
targetCellId: edge.getTargetCellId(),
|
targetCellId: edge.getTargetCellId(),
|
||||||
targetPortId: edge.getTargetPortId(),
|
targetPortId: edge.getTargetPortId(),
|
||||||
sourceCellId: edge.getSourceCellId(),
|
sourceCellId: edge.getSourceCellId(),
|
||||||
isIncoming: edge.getTargetCellId() === selectedNode.id
|
isIncoming: edge.getTargetCellId() === selectedNode.id,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Remove all existing right-side ports
|
const cases = form.getFieldValue(name) || [];
|
||||||
const existingPorts = selectedNode.getPorts();
|
const leftPorts = selectedNode.getPorts().filter((p: any) => p.group !== 'right');
|
||||||
existingPorts.forEach((port: any) => {
|
const newRightPorts = Array.from({ length: caseCount + 1 }, (_, i) => ({
|
||||||
if (port.group === 'right') {
|
id: `CASE${i + 1}`,
|
||||||
selectedNode.removePort(port.id);
|
group: 'right',
|
||||||
|
args: { x: nodeWidth, y: getConditionNodeCasePortY(cases, i) },
|
||||||
|
}));
|
||||||
|
|
||||||
|
graph.startBatch('update-ports');
|
||||||
|
|
||||||
|
existingEdges.forEach((edge: any) => graph.removeCell(edge));
|
||||||
|
// Replace all ports in one prop call — produces a single cell:change:ports command
|
||||||
|
selectedNode.prop('ports/items', [...leftPorts, ...newRightPorts], { rewrite: true });
|
||||||
|
selectedNode.prop('size', { width: nodeWidth, height: calcConditionNodeTotalHeight(cases) });
|
||||||
|
|
||||||
|
edgeConnections.forEach(({sourcePortId, targetCellId, targetPortId, sourceCellId, isIncoming }: any) => {
|
||||||
|
if (isIncoming) {
|
||||||
|
const sourceCell = graph.getCellById(sourceCellId);
|
||||||
|
if (sourceCell) {
|
||||||
|
graph.addEdge({
|
||||||
|
source: { cell: sourceCellId, port: sourcePortId },
|
||||||
|
target: { cell: selectedNode.id, port: targetPortId },
|
||||||
|
...edgeAttrs
|
||||||
|
});
|
||||||
|
sourceCell.toFront();
|
||||||
|
bringLoopChildrenToFront(sourceCell);
|
||||||
|
selectedNode.toFront();
|
||||||
|
bringLoopChildrenToFront(selectedNode);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const originalCaseNumber = parseInt(sourcePortId.match(/CASE(\d+)/)?.[1] || '0');
|
||||||
|
if (removedCaseIndex !== undefined && originalCaseNumber === removedCaseIndex + 1) return;
|
||||||
|
let newPortId = sourcePortId;
|
||||||
|
|
||||||
|
if (removedCaseIndex !== undefined) {
|
||||||
|
if (originalCaseNumber > removedCaseIndex + 1) {
|
||||||
|
newPortId = `CASE${originalCaseNumber - 1}`;
|
||||||
|
} else if (originalCaseNumber === currentCaseCount + 1) {
|
||||||
|
newPortId = `CASE${caseCount + 1}`;
|
||||||
|
}
|
||||||
|
} else if (isAddingCase && originalCaseNumber === currentCaseCount + 1) {
|
||||||
|
newPortId = `CASE${caseCount + 1}`;
|
||||||
|
}
|
||||||
|
if (newRightPorts.find((p) => p.id === newPortId)) {
|
||||||
|
const targetCell = graph.getCellById(targetCellId);
|
||||||
|
if (targetCell) {
|
||||||
|
graph.addEdge({
|
||||||
|
source: { cell: selectedNode.id, port: newPortId },
|
||||||
|
target: { cell: targetCellId, port: targetPortId },
|
||||||
|
...edgeAttrs
|
||||||
|
});
|
||||||
|
selectedNode.toFront();
|
||||||
|
bringLoopChildrenToFront(selectedNode);
|
||||||
|
targetCell.toFront();
|
||||||
|
bringLoopChildrenToFront(targetCell);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const cases = form.getFieldValue(name) || [];
|
graph.stopBatch('update-ports');
|
||||||
selectedNode.prop('size', { width: nodeWidth, height: calcConditionNodeTotalHeight(cases) });
|
|
||||||
|
|
||||||
// Add ELIF ports
|
|
||||||
for (let i = 0; i < caseCount; i++) {
|
|
||||||
selectedNode.addPort({
|
|
||||||
id: `CASE${i + 1}`,
|
|
||||||
group: 'right',
|
|
||||||
args: {
|
|
||||||
x: nodeWidth,
|
|
||||||
y: getConditionNodeCasePortY(cases, i),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add ELSE port
|
|
||||||
selectedNode.addPort({
|
|
||||||
id: `CASE${caseCount + 1}`,
|
|
||||||
group: 'right',
|
|
||||||
args: {
|
|
||||||
x: nodeWidth,
|
|
||||||
y: getConditionNodeCasePortY(cases, caseCount),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Restore edge connections
|
|
||||||
setTimeout(() => {
|
|
||||||
edgeConnections.forEach(({ edge, sourcePortId, targetCellId, targetPortId, sourceCellId, isIncoming }: any) => {
|
|
||||||
// If it's an incoming connection (left-side port), restore directly
|
|
||||||
if (isIncoming) {
|
|
||||||
const sourceCell = graphRef.current?.getCellById(sourceCellId);
|
|
||||||
if (sourceCell) {
|
|
||||||
graphRef.current?.addEdge({
|
|
||||||
source: { cell: sourceCellId, port: sourcePortId },
|
|
||||||
target: { cell: selectedNode.id, port: targetPortId },
|
|
||||||
...edgeAttrs,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
sourceCell.toFront()
|
|
||||||
selectedNode.toFront()
|
|
||||||
bringLoopChildrenToFront(sourceCell)
|
|
||||||
bringLoopChildrenToFront(selectedNode)
|
|
||||||
graphRef.current?.removeCell(edge);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle right-side port connections
|
|
||||||
const originalCaseNumber = parseInt(sourcePortId.match(/CASE(\d+)/)?.[1] || '0');
|
|
||||||
|
|
||||||
// If it's a remove operation and the port is being removed, delete the connection
|
|
||||||
if (removedCaseIndex !== undefined && originalCaseNumber === removedCaseIndex + 1) {
|
|
||||||
graphRef.current?.removeCell(edge);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let newPortId = sourcePortId;
|
|
||||||
|
|
||||||
// If it's a remove operation, remap port IDs
|
|
||||||
if (removedCaseIndex !== undefined) {
|
|
||||||
if (originalCaseNumber > removedCaseIndex + 1) {
|
|
||||||
// Ports after the removed port, shift numbering forward
|
|
||||||
newPortId = `CASE${originalCaseNumber - 1}`;
|
|
||||||
}
|
|
||||||
// ELSE port always maps to the new ELSE port position
|
|
||||||
else if (originalCaseNumber === currentCaseCount + 1) {
|
|
||||||
newPortId = `CASE${caseCount + 1}`;
|
|
||||||
}
|
|
||||||
} else if (isAddingCase) {
|
|
||||||
// If it's an add operation, ELSE port needs to be remapped
|
|
||||||
if (originalCaseNumber === currentCaseCount + 1) {
|
|
||||||
newPortId = `CASE${caseCount + 1}`; // New ELSE port
|
|
||||||
}
|
|
||||||
// Newly added ports don't restore any connections
|
|
||||||
}
|
|
||||||
|
|
||||||
const newPorts = selectedNode.getPorts();
|
|
||||||
const matchingPort = newPorts.find((port: any) => port.id === newPortId);
|
|
||||||
|
|
||||||
if (matchingPort) {
|
|
||||||
const targetCell = graphRef.current?.getCellById(targetCellId);
|
|
||||||
if (targetCell) {
|
|
||||||
graphRef.current?.addEdge({
|
|
||||||
source: { cell: selectedNode.id, port: newPortId },
|
|
||||||
target: { cell: targetCellId, port: targetPortId },
|
|
||||||
...edgeAttrs
|
|
||||||
});
|
|
||||||
selectedNode.toFront()
|
|
||||||
bringLoopChildrenToFront(selectedNode)
|
|
||||||
targetCell.toFront()
|
|
||||||
bringLoopChildrenToFront(targetCell)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
graphRef.current?.removeCell(edge);
|
|
||||||
});
|
|
||||||
}, 50);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleChangeLogicalOperator = (index: number) => {
|
const handleChangeLogicalOperator = (index: number) => {
|
||||||
|
|||||||
@@ -42,109 +42,73 @@ const CategoryList: FC<CategoryListProps> = ({ parentName, selectedNode, graphRe
|
|||||||
// Update node ports based on category count changes (add/remove categories)
|
// Update node ports based on category count changes (add/remove categories)
|
||||||
const updateNodePorts = (caseCount: number, removedCaseIndex?: number) => {
|
const updateNodePorts = (caseCount: number, removedCaseIndex?: number) => {
|
||||||
if (!selectedNode || !graphRef?.current) return;
|
if (!selectedNode || !graphRef?.current) return;
|
||||||
|
const graph = graphRef.current;
|
||||||
|
|
||||||
// Save existing edge connections (including left-side port connections)
|
const existingEdges = graph.getEdges().filter((edge: any) =>
|
||||||
const existingEdges = graphRef.current.getEdges().filter((edge: any) =>
|
|
||||||
edge.getSourceCellId() === selectedNode.id || edge.getTargetCellId() === selectedNode.id
|
edge.getSourceCellId() === selectedNode.id || edge.getTargetCellId() === selectedNode.id
|
||||||
);
|
);
|
||||||
const edgeConnections = existingEdges.map((edge: any) => ({
|
const edgeConnections = existingEdges.map((edge: any) => ({
|
||||||
edge,
|
|
||||||
sourcePortId: edge.getSourcePortId(),
|
sourcePortId: edge.getSourcePortId(),
|
||||||
targetCellId: edge.getTargetCellId(),
|
targetCellId: edge.getTargetCellId(),
|
||||||
targetPortId: edge.getTargetPortId(),
|
targetPortId: edge.getTargetPortId(),
|
||||||
sourceCellId: edge.getSourceCellId(),
|
sourceCellId: edge.getSourceCellId(),
|
||||||
isIncoming: edge.getTargetCellId() === selectedNode.id
|
isIncoming: edge.getTargetCellId() === selectedNode.id,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Remove all existing right-side ports
|
graph.startBatch('update-ports');
|
||||||
const existingPorts = selectedNode.getPorts();
|
|
||||||
existingPorts.forEach((port: any) => {
|
existingEdges.forEach((edge: any) => graph.removeCell(edge));
|
||||||
if (port.group === 'right') {
|
// Replace all ports in one prop call — produces a single cell:change:ports command
|
||||||
selectedNode.removePort(port.id);
|
const leftPorts = selectedNode.getPorts().filter((p: any) => p.group !== 'right');
|
||||||
}
|
const newRightPorts = Array.from({ length: caseCount }, (_, i) => ({
|
||||||
});
|
id: `CASE${i + 1}`,
|
||||||
|
group: 'right',
|
||||||
|
args: { x: nodeWidth, y: portItemArgsY * i + conditionNodePortItemArgsY },
|
||||||
|
}));
|
||||||
|
selectedNode.prop('ports/items', [...leftPorts, ...newRightPorts], { rewrite: true });
|
||||||
|
|
||||||
// Calculate new node height: base height 88px + 30px for each additional port
|
|
||||||
const newHeight = conditionNodeHeight + (caseCount - 2) * conditionNodeItemHeight;
|
const newHeight = conditionNodeHeight + (caseCount - 2) * conditionNodeItemHeight;
|
||||||
|
selectedNode.prop('size', { width: nodeWidth, height: newHeight < conditionNodeHeight ? conditionNodeHeight : newHeight });
|
||||||
|
|
||||||
selectedNode.prop('size', { width: nodeWidth, height: newHeight < conditionNodeHeight ? conditionNodeHeight : newHeight })
|
edgeConnections.forEach(({ sourcePortId, targetCellId, targetPortId, sourceCellId, isIncoming }: any) => {
|
||||||
|
if (isIncoming) {
|
||||||
// Update right port x position
|
const sourceCell = graph.getCellById(sourceCellId);
|
||||||
const currentPorts = selectedNode.getPorts();
|
if (sourceCell) {
|
||||||
currentPorts.forEach(port => {
|
graph.addEdge({
|
||||||
if (port.group === 'right' && port.args) {
|
source: { cell: sourceCellId, port: sourcePortId },
|
||||||
selectedNode.portProp(port.id!, 'args/x', nodeWidth);
|
target: { cell: selectedNode.id, port: targetPortId },
|
||||||
|
...edgeAttrs
|
||||||
|
});
|
||||||
|
sourceCell.toFront();
|
||||||
|
bringLoopChildrenToFront(sourceCell);
|
||||||
|
selectedNode.toFront();
|
||||||
|
bringLoopChildrenToFront(selectedNode);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const originalCaseNumber = parseInt(sourcePortId.match(/CASE(\d+)/)?.[1] || '0');
|
||||||
|
if (removedCaseIndex !== undefined && originalCaseNumber === removedCaseIndex + 1) return;
|
||||||
|
let newPortId = sourcePortId;
|
||||||
|
if (removedCaseIndex !== undefined && originalCaseNumber > removedCaseIndex + 1) {
|
||||||
|
newPortId = `CASE${originalCaseNumber - 1}`;
|
||||||
|
}
|
||||||
|
if (newRightPorts.find((p) => p.id === newPortId)) {
|
||||||
|
const targetCell = graph.getCellById(targetCellId);
|
||||||
|
if (targetCell) {
|
||||||
|
graph.addEdge({
|
||||||
|
source: { cell: selectedNode.id, port: newPortId },
|
||||||
|
target: { cell: targetCellId, port: targetPortId },
|
||||||
|
...edgeAttrs
|
||||||
|
});
|
||||||
|
selectedNode.toFront();
|
||||||
|
bringLoopChildrenToFront(selectedNode);
|
||||||
|
targetCell.toFront();
|
||||||
|
bringLoopChildrenToFront(targetCell);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add category ports
|
graph.stopBatch('update-ports');
|
||||||
for (let i = 0; i < caseCount; i++) {
|
|
||||||
selectedNode.addPort({
|
|
||||||
id: `CASE${i + 1}`,
|
|
||||||
group: 'right',
|
|
||||||
args: {
|
|
||||||
x: nodeWidth,
|
|
||||||
y: portItemArgsY * i + conditionNodePortItemArgsY,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Restore edge connections
|
|
||||||
setTimeout(() => {
|
|
||||||
edgeConnections.forEach(({ edge, sourcePortId, targetCellId, targetPortId, sourceCellId, isIncoming }: any) => {
|
|
||||||
graphRef.current?.removeCell(edge);
|
|
||||||
|
|
||||||
// If it's an incoming connection (left-side port), restore directly
|
|
||||||
if (isIncoming) {
|
|
||||||
const sourceCell = graphRef.current?.getCellById(sourceCellId);
|
|
||||||
if (sourceCell) {
|
|
||||||
graphRef.current?.addEdge({
|
|
||||||
source: { cell: sourceCellId, port: sourcePortId },
|
|
||||||
target: { cell: selectedNode.id, port: targetPortId },
|
|
||||||
...edgeAttrs
|
|
||||||
});
|
|
||||||
sourceCell.toFront()
|
|
||||||
bringLoopChildrenToFront(sourceCell)
|
|
||||||
selectedNode.toFront()
|
|
||||||
bringLoopChildrenToFront(selectedNode)
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle right-side port connections
|
|
||||||
const originalCaseNumber = parseInt(sourcePortId.match(/CASE(\d+)/)?.[1] || '0');
|
|
||||||
|
|
||||||
// If it's a removed port, don't recreate the connection
|
|
||||||
if (removedCaseIndex !== undefined && originalCaseNumber === removedCaseIndex + 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let newPortId = sourcePortId;
|
|
||||||
|
|
||||||
// If a port was removed, remap subsequent port IDs
|
|
||||||
if (removedCaseIndex !== undefined && originalCaseNumber > removedCaseIndex + 1) {
|
|
||||||
newPortId = `CASE${originalCaseNumber - 1}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the new port exists
|
|
||||||
const newPorts = selectedNode.getPorts();
|
|
||||||
const matchingPort = newPorts.find((port: any) => port.id === newPortId);
|
|
||||||
|
|
||||||
if (matchingPort) {
|
|
||||||
const targetCell = graphRef.current?.getCellById(targetCellId);
|
|
||||||
if (targetCell) {
|
|
||||||
graphRef.current?.addEdge({
|
|
||||||
source: { cell: selectedNode.id, port: newPortId },
|
|
||||||
target: { cell: targetCellId, port: targetPortId },
|
|
||||||
...edgeAttrs
|
|
||||||
});
|
|
||||||
selectedNode.toFront()
|
|
||||||
bringLoopChildrenToFront(selectedNode)
|
|
||||||
targetCell.toFront()
|
|
||||||
bringLoopChildrenToFront(targetCell)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 50);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAddCategory = (addFunc: Function) => {
|
const handleAddCategory = (addFunc: Function) => {
|
||||||
|
|||||||
@@ -124,9 +124,7 @@ export const useWorkflowGraph = ({
|
|||||||
const [canRedo, setCanRedo] = useState(false)
|
const [canRedo, setCanRedo] = useState(false)
|
||||||
const [historyRecords, setHistoryRecords] = useState<HistoryRecord[]>([])
|
const [historyRecords, setHistoryRecords] = useState<HistoryRecord[]>([])
|
||||||
const lastHistoryRef = useRef<{ cellIds: string[]; timestamp: number; type: string } | null>(null)
|
const lastHistoryRef = useRef<{ cellIds: string[]; timestamp: number; type: string } | null>(null)
|
||||||
const undoRef = useRef<() => void>(() => {})
|
const syncChildRelationshipsRef = useRef<() => void>(() => { })
|
||||||
const redoRef = useRef<() => void>(() => {})
|
|
||||||
const syncChildRelationshipsRef = useRef<() => void>(() => {})
|
|
||||||
const isSyncingRef = useRef(false)
|
const isSyncingRef = useRef(false)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!graphRef.current) return
|
if (!graphRef.current) return
|
||||||
@@ -532,24 +530,82 @@ export const useWorkflowGraph = ({
|
|||||||
const graph = graphRef.current
|
const graph = graphRef.current
|
||||||
graph.disableHistory()
|
graph.disableHistory()
|
||||||
graph.getNodes().forEach(node => {
|
graph.getNodes().forEach(node => {
|
||||||
const cycleId = node.getData()?.cycle
|
const nodeData = node.getData()
|
||||||
if (!cycleId) return
|
|
||||||
const parentNode = graph.getCellById(cycleId) as Node | null
|
|
||||||
if (!parentNode) return
|
|
||||||
if (!parentNode.getChildren()?.some(c => c.id === node.id)) {
|
|
||||||
parentNode.addChild(node, { silent: true })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
graph.getNodes().forEach(node => {
|
|
||||||
const children = node.getChildren()
|
const children = node.getChildren()
|
||||||
if (!children?.length) return
|
|
||||||
children.forEach(child => {
|
const cycleId = nodeData?.cycle
|
||||||
if (!child.isNode()) return
|
|
||||||
const childCycleId = (child as Node).getData?.()?.cycle
|
if (cycleId) {
|
||||||
if (childCycleId !== node.id && childCycleId !== node.getData?.()?.id) {
|
const parentNode = graph.getCellById(cycleId) as Node | null
|
||||||
node.removeChild(child, { silent: true })
|
if (!parentNode) return
|
||||||
|
if (!parentNode.getChildren()?.some(c => c.id === node.id)) {
|
||||||
|
parentNode.addChild(node, { silent: true })
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
|
if (nodeData.type === 'if-else') {
|
||||||
|
const rightPorts = node.getPorts().filter(p => p.group === 'right')
|
||||||
|
const caseCount = rightPorts.length - 1 // last port is ELSE
|
||||||
|
const currentCases: any[] = nodeData.config?.cases?.defaultValue ?? []
|
||||||
|
const newCases = caseCount !== currentCases.length
|
||||||
|
? Array.from({ length: caseCount }, (_, i) => currentCases[i] ?? { logical_operator: 'and', expressions: [] })
|
||||||
|
: currentCases
|
||||||
|
if (caseCount !== currentCases.length) {
|
||||||
|
node.setData({
|
||||||
|
...nodeData,
|
||||||
|
config: { ...nodeData.config, cases: { ...nodeData.config.cases, defaultValue: newCases } }
|
||||||
|
}, { deep: false, silent: true })
|
||||||
|
}
|
||||||
|
// Sync node height and port Y positions
|
||||||
|
node.prop('size', { width: nodeWidth, height: calcConditionNodeTotalHeight(newCases) })
|
||||||
|
newCases.forEach((_c: any, i: number) => {
|
||||||
|
node.portProp(`CASE${i + 1}`, 'args/y', getConditionNodeCasePortY(newCases, i))
|
||||||
|
})
|
||||||
|
node.portProp(`CASE${newCases.length + 1}`, 'args/y', getConditionNodeCasePortY(newCases, newCases.length))
|
||||||
|
node.toFront()
|
||||||
|
graph.getEdges().filter(e => e.getSourceCellId() === node.id).forEach(e => {
|
||||||
|
const tgt = graph.getCellById(e.getTargetCellId())
|
||||||
|
tgt?.toFront()
|
||||||
|
})
|
||||||
|
} else if (nodeData.type === 'question-classifier') {
|
||||||
|
const rightPorts = node.getPorts().filter(p => p.group === 'right')
|
||||||
|
const currentCategories: any[] = nodeData.config?.categories?.defaultValue ?? []
|
||||||
|
const categoryCount = rightPorts.length
|
||||||
|
const newCategories = categoryCount !== currentCategories.length
|
||||||
|
? rightPorts.map((port, i) => {
|
||||||
|
if (currentCategories[i]) return currentCategories[i]
|
||||||
|
const edge = graph.getEdges().find(e => e.getSourceCellId() === node.id && e.getSourcePortId() === port.id)
|
||||||
|
return edge ? { name: '' } : {}
|
||||||
|
})
|
||||||
|
: currentCategories
|
||||||
|
if (categoryCount !== currentCategories.length) {
|
||||||
|
node.setData({
|
||||||
|
...nodeData,
|
||||||
|
config: { ...nodeData.config, categories: { ...nodeData.config.categories, defaultValue: [...newCategories] } }
|
||||||
|
}, { deep: false, silent: true })
|
||||||
|
}
|
||||||
|
// Sync node height and port Y positions
|
||||||
|
const newHeight = conditionNodeHeight + (categoryCount - 2) * conditionNodeItemHeight
|
||||||
|
node.prop('size', { width: nodeWidth, height: Math.max(newHeight, conditionNodeHeight) })
|
||||||
|
rightPorts.forEach((_p, i) => {
|
||||||
|
node.portProp(`CASE${i + 1}`, 'args/y', portItemArgsY * i + conditionNodePortItemArgsY)
|
||||||
|
})
|
||||||
|
node.toFront()
|
||||||
|
graph.getEdges().filter(e => e.getSourceCellId() === node.id).forEach(e => {
|
||||||
|
const tgt = graph.getCellById(e.getTargetCellId())
|
||||||
|
tgt?.toFront()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (children?.length) {
|
||||||
|
children.forEach(child => {
|
||||||
|
if (!child.isNode()) return
|
||||||
|
const childCycleId = (child as Node).getData?.()?.cycle
|
||||||
|
if (childCycleId !== node.id && childCycleId !== node.getData?.()?.id) {
|
||||||
|
node.removeChild(child, { silent: true })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
resizeGroupNodes(graph)
|
resizeGroupNodes(graph)
|
||||||
graph.getEdges().forEach(edge => {
|
graph.getEdges().forEach(edge => {
|
||||||
|
|||||||
Reference in New Issue
Block a user