Compare commits

..

5 Commits

Author SHA1 Message Date
Claude Bot
04387d66a9 fix: sync tree node title on graph node rename (closes #10) 2026-03-31 07:26:09 +00:00
471bff1a8c feature: Modify readme' (#5) from claude/issue-4 into master
Reviewed-on: #5
2026-03-23 14:58:39 +00:00
Claude Bot
9aa28a9fa3 docs: rewrite README to describe ConceptSketch project (closes #4) 2026-03-23 14:55:43 +00:00
4733916523 Merge pull request 'Fix: Breadcrumb disappearing' (#3) from claude/issue-2 into master
Reviewed-on: #3
2026-03-23 14:41:42 +00:00
Claude Bot
eb3a23ab03 fix: resolve stale closure causing breadcrumbs to disappear on back-navigation (closes #2)
The onClick handler in createPathSegment closed over the graphsPath variable
from the render when the segment was created. By the time a breadcrumb was
clicked (after further navigation), that closure was stale, so findIndex
returned -1 and splice(0) wiped the entire breadcrumb array.

Fix: use the functional updater form of setGraphsPath so findIndex runs
against the current state rather than a stale snapshot.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 22:57:48 +00:00
3 changed files with 20 additions and 7 deletions

View File

@@ -264,12 +264,7 @@ const Graph = forwardRef<GraphHandle, { setGraphPath: React.Dispatch<React.SetSt
title: selectedNodeName, title: selectedNodeName,
key: pathSegmentId, key: pathSegmentId,
onClick: () => { onClick: () => {
const index = graphsPath.findIndex(p => p.key === pathSegmentId); setGraphsPath(prev => prev.slice(0, prev.findIndex(p => p.key === pathSegmentId) + 1));
setGraphsPath(prev => {
prev.splice(index + 1);
return [...prev];
});
selectGraphId(pathSegmentId); selectGraphId(pathSegmentId);
} }
} as BreadcrumbItemType; } as BreadcrumbItemType;

View File

@@ -1,6 +1,7 @@
import { Input, Modal } from "antd"; import { Input, Modal } from "antd";
import { graphContext, type NodeContext } from "./Graph"; import { graphContext, type NodeContext } from "./Graph";
import { useContext, useState } from "react"; import { useContext, useState } from "react";
import { useGraphLayersTreeStore } from "../stores/TreeStore";
export default function NodeRenameModal({ export default function NodeRenameModal({
nodeContext, nodeContext,
@@ -15,7 +16,8 @@ export default function NodeRenameModal({
return; return;
} }
const [nodeName, setSelectedNodeName] = useState(nodeContext.nodeName); const [nodeName, setSelectedNodeName] = useState(nodeContext.nodeName);
const graphContextValue = useContext(graphContext)!; const graphContextValue = useContext(graphContext)!;
const renameTreeNode = useGraphLayersTreeStore(state => state.rename);
function renameNode() { function renameNode() {
const node = graphContextValue.graph.nodes.find(n => n.id === nodeContext.nodeId); const node = graphContextValue.graph.nodes.find(n => n.id === nodeContext.nodeId);
@@ -24,6 +26,7 @@ export default function NodeRenameModal({
} }
node.label = nodeName; node.label = nodeName;
graphContextValue.setGraph(prev => ({ ...prev, nodes: graphContextValue.graph.nodes })); graphContextValue.setGraph(prev => ({ ...prev, nodes: graphContextValue.graph.nodes }));
renameTreeNode(nodeContext.nodeId, nodeName);
openRenameModal(false); openRenameModal(false);
} }

View File

@@ -10,6 +10,7 @@ export interface TreeStore {
tree: TreeDataNode[]; tree: TreeDataNode[];
add: (childNode: NodeContext, parentNodeId: string | undefined) => void; add: (childNode: NodeContext, parentNodeId: string | undefined) => void;
remove: (nodeId: string) => void; remove: (nodeId: string) => void;
rename: (nodeId: string, newName: string) => void;
reset: () => void; reset: () => void;
} }
@@ -90,6 +91,20 @@ export const useGraphLayersTreeStore = create<TreeStore>()((set) => ({
tree: createTree([...state.rootNodes], nodesFlatById) tree: createTree([...state.rootNodes], nodesFlatById)
} }
}), }),
rename: (nodeId, newName) => set((state) => {
const node = state.nodesFlatById.get(nodeId);
if (!node) {
return state;
}
const nodesFlatById = new Map(state.nodesFlatById);
nodesFlatById.set(nodeId, { ...node, title: newName });
return {
...state,
nodesFlatById,
rootNodes: [...state.rootNodes],
tree: createTree([...state.rootNodes], nodesFlatById),
};
}),
reset: () => set({ reset: () => set({
nodesFlatById: new Map<React.Key, TreeDataNode>(), nodesFlatById: new Map<React.Key, TreeDataNode>(),
parentIdByChildId: new Map<React.Key, string>(), parentIdByChildId: new Map<React.Key, string>(),