Поправил логику проверки удаления узлов
This commit is contained in:
+20
-11
@@ -259,17 +259,25 @@ function DiagramCanvas({ initialValue, onChange }: DiagramEditorProps) {
|
||||
setSelectedEdgeId(null);
|
||||
}, []);
|
||||
|
||||
const onNodesChange = useCallback(
|
||||
(changes: NodeChange[]) => {
|
||||
const withChildren = new Set(nodes.filter((n) => n.parentId).map((n) => n.parentId!));
|
||||
const filteredChanges = changes.filter((change) => {
|
||||
if (change.type !== 'remove' || !withChildren.has(change.id)) return true;
|
||||
// Runs before React Flow computes any removal changes at all (for both
|
||||
// nodes and their connected edges), so blocking here — unlike filtering
|
||||
// inside onNodesChange — stops the connected edges from being deleted too.
|
||||
const onBeforeDelete = useCallback(
|
||||
async ({ nodes: nodesToDelete }: { nodes: Node[]; edges: Edge[] }) => {
|
||||
const hasContainerNode = nodesToDelete.some((node) => nodes.some((n) => n.parentId === node.id));
|
||||
if (hasContainerNode) {
|
||||
window.alert('Сначала удалите вложенные узлы — у этого узла есть под-процесс.');
|
||||
return false;
|
||||
});
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[nodes],
|
||||
);
|
||||
|
||||
const positionChanges = filteredChanges.filter((c) => c.type === 'position' && c.position);
|
||||
let adjustedChanges = filteredChanges;
|
||||
const onNodesChange = useCallback(
|
||||
(changes: NodeChange[]) => {
|
||||
const positionChanges = changes.filter((c) => c.type === 'position' && c.position);
|
||||
let adjustedChanges = changes;
|
||||
if (positionChanges.length === 1) {
|
||||
const change = positionChanges[0];
|
||||
const draggedNode = change.type === 'position' ? nodes.find((n) => n.id === change.id) : undefined;
|
||||
@@ -286,7 +294,7 @@ function DiagramCanvas({ initialValue, onChange }: DiagramEditorProps) {
|
||||
};
|
||||
const snapped = computeSnapAndGuides(dragged, others);
|
||||
setAlignmentGuides(change.dragging === false ? [] : snapped.guides);
|
||||
adjustedChanges = filteredChanges.map((c) =>
|
||||
adjustedChanges = changes.map((c) =>
|
||||
c === change ? { ...c, position: { x: snapped.x, y: snapped.y } } : c,
|
||||
);
|
||||
}
|
||||
@@ -294,7 +302,7 @@ function DiagramCanvas({ initialValue, onChange }: DiagramEditorProps) {
|
||||
setAlignmentGuides([]);
|
||||
}
|
||||
|
||||
const isHistoryWorthy = filteredChanges.some(
|
||||
const isHistoryWorthy = changes.some(
|
||||
(change) =>
|
||||
change.type === 'remove' ||
|
||||
(change.type === 'position' && change.dragging === false) ||
|
||||
@@ -308,7 +316,7 @@ function DiagramCanvas({ initialValue, onChange }: DiagramEditorProps) {
|
||||
// emitChange — filtering edges here too (redundantly with onEdgesChange)
|
||||
// guarantees a removed node never leaves a dangling edge behind.
|
||||
const removedIds = new Set(
|
||||
filteredChanges.filter((change) => change.type === 'remove').map((change) => change.id),
|
||||
changes.filter((change) => change.type === 'remove').map((change) => change.id),
|
||||
);
|
||||
const nextEdges = removedIds.size
|
||||
? edges.filter((edge) => !removedIds.has(edge.source) && !removedIds.has(edge.target))
|
||||
@@ -574,6 +582,7 @@ function DiagramCanvas({ initialValue, onChange }: DiagramEditorProps) {
|
||||
onEdgesChange={onEdgesChange}
|
||||
onConnect={onConnect}
|
||||
onReconnect={onReconnect}
|
||||
onBeforeDelete={onBeforeDelete}
|
||||
edgesReconnectable={mode === 'edit'}
|
||||
onNodeClick={onNodeClick}
|
||||
onEdgeClick={onEdgeClick}
|
||||
|
||||
Reference in New Issue
Block a user