fix(web): select tree nodes by index path instead of GUID

Cards in a deck share the deck's GUID, so GUID-based selection highlighted
every card with that GUID and rendered the first match. Key selection by the
node's unique index path instead.
This commit is contained in:
2026-08-08 17:42:16 +08:00
parent 835250abdd
commit 55e0351c1d
2 changed files with 28 additions and 24 deletions
+14 -11
View File
@@ -5,11 +5,11 @@ import { iconsForObject } from './objectIcons';
interface Props {
nodes: ObjectTreeNode[];
selectedGuid: string | null;
onSelect: (guid: string) => void;
selectedPath: string | null;
onSelect: (path: string) => void;
}
export default function ObjectTree({ nodes, selectedGuid, onSelect }: Props) {
export default function ObjectTree({ nodes, selectedPath, onSelect }: Props) {
return (
<ul className="space-y-0.5">
{nodes.map((node, index) => (
@@ -18,7 +18,7 @@ export default function ObjectTree({ nodes, selectedGuid, onSelect }: Props) {
node={node}
depth={0}
path={`${index}`}
selectedGuid={selectedGuid}
selectedPath={selectedPath}
onSelect={onSelect}
/>
))}
@@ -30,17 +30,20 @@ function TreeNode({
node,
depth,
path,
selectedGuid,
selectedPath,
onSelect,
}: {
node: ObjectTreeNode;
depth: number;
/** Index path from the root, used as a stable unique key. */
/** Index path from the root, used as a stable unique key and selection id. */
path: string;
selectedGuid: string | null;
onSelect: (guid: string) => void;
selectedPath: string | null;
onSelect: (path: string) => void;
}) {
const selected = node.object.GUID === selectedGuid;
// Selection is keyed by the node's unique index path, not its GUID: cards in
// a deck frequently share a GUID (the deck's), so GUID-based selection would
// highlight and render the wrong card.
const selected = path === selectedPath;
const hasChildren = node.children.length > 0;
const [expanded, setExpanded] = useState(false);
return (
@@ -69,7 +72,7 @@ function TreeNode({
<span className="h-6 w-6 shrink-0" />
)}
<button
onClick={() => onSelect(node.object.GUID)}
onClick={() => onSelect(path)}
className="block min-w-0 flex-1 truncate py-1 text-left text-sm"
>
<span
@@ -91,7 +94,7 @@ function TreeNode({
node={child}
depth={depth + 1}
path={`${path}-${index}`}
selectedGuid={selectedGuid}
selectedPath={selectedPath}
onSelect={onSelect}
/>
))}