Fix: Cut and Paste functionality #9
@@ -62,6 +62,7 @@ export default function NodeContextMenu({
|
||||
const graphsById = useGraphsStore((s) => (s as { graphsById: Map<string, GraphModel> }).graphsById);
|
||||
const addTreeNode = useGraphLayersTreeStore(store => store.add);
|
||||
const removeTreeNode = useGraphLayersTreeStore(store => store.remove);
|
||||
const moveTreeNode = useGraphLayersTreeStore(store => store.move);
|
||||
const setCut = useCutStore(store => store.setCut);
|
||||
const clearCut = useCutStore(store => store.clearCut);
|
||||
|
||||
@@ -165,6 +166,22 @@ export default function NodeContextMenu({
|
||||
}
|
||||
}
|
||||
|
||||
// Update navigation tree: reparent tree nodes from source graph to target graph.
|
||||
// A tree node belongs to the source graph when its tree parent matches sourceGraphId
|
||||
// (or is a root node when sourceGraphId is 'main').
|
||||
const treeState = useGraphLayersTreeStore.getState();
|
||||
const effectiveSourceParent = cutState.sourceGraphId === 'main' ? undefined : cutState.sourceGraphId ?? undefined;
|
||||
const newTreeParent = graphContextValue.graphId === 'main' ? undefined : graphContextValue.graphId;
|
||||
|
||||
for (const nodeId of cutState.cutNodeIds) {
|
||||
if (treeState.nodesFlatById.has(nodeId)) {
|
||||
const nodeTreeParent = treeState.parentIdByChildId.get(nodeId);
|
||||
if (nodeTreeParent === effectiveSourceParent) {
|
||||
moveTreeNode(nodeId, newTreeParent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clearCut();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ export interface TreeStore {
|
||||
tree: TreeDataNode[];
|
||||
add: (childNode: NodeContext, parentNodeId: string | undefined) => void;
|
||||
remove: (nodeId: string) => void;
|
||||
move: (nodeId: string, newParentId: string | undefined) => void;
|
||||
reset: () => void;
|
||||
}
|
||||
|
||||
@@ -90,6 +91,44 @@ export const useGraphLayersTreeStore = create<TreeStore>()((set) => ({
|
||||
tree: createTree([...state.rootNodes], nodesFlatById)
|
||||
}
|
||||
}),
|
||||
move: (nodeId, newParentId) => set((state) => {
|
||||
const node = state.nodesFlatById.get(nodeId);
|
||||
if (!node) return state;
|
||||
|
||||
const nodesFlatById = new Map(state.nodesFlatById);
|
||||
const parentIdByChildId = new Map(state.parentIdByChildId);
|
||||
let rootNodes = [...state.rootNodes];
|
||||
|
||||
// Remove from old parent
|
||||
const oldParentId = state.parentIdByChildId.get(nodeId);
|
||||
if (oldParentId !== undefined) {
|
||||
const oldParent = nodesFlatById.get(oldParentId);
|
||||
if (oldParent) {
|
||||
oldParent.children = oldParent.children?.filter(n => n.key !== nodeId) ?? [];
|
||||
}
|
||||
parentIdByChildId.delete(nodeId);
|
||||
} else {
|
||||
rootNodes = rootNodes.filter(n => n.key !== nodeId);
|
||||
}
|
||||
|
||||
// Add to new parent
|
||||
if (newParentId !== undefined) {
|
||||
const newParent = nodesFlatById.get(newParentId);
|
||||
if (newParent) {
|
||||
newParent.children = newParent.children ? [...newParent.children, node] : [node];
|
||||
parentIdByChildId.set(nodeId, newParentId);
|
||||
}
|
||||
} else {
|
||||
rootNodes = [...rootNodes, node];
|
||||
}
|
||||
|
||||
return {
|
||||
nodesFlatById,
|
||||
parentIdByChildId,
|
||||
rootNodes,
|
||||
tree: createTree(rootNodes, nodesFlatById),
|
||||
};
|
||||
}),
|
||||
reset: () => set({
|
||||
nodesFlatById: new Map<React.Key, TreeDataNode>(),
|
||||
parentIdByChildId: new Map<React.Key, string>(),
|
||||
|
||||
Reference in New Issue
Block a user