diff --git a/.server-changes/run-trace-tree-interactions.md b/.server-changes/run-trace-tree-interactions.md new file mode 100644 index 00000000000..eb94cf06712 --- /dev/null +++ b/.server-changes/run-trace-tree-interactions.md @@ -0,0 +1,6 @@ +--- +area: webapp +type: fix +--- + +Run trace rows now respond consistently to mouse and keyboard selection, including Alt-click expansion controls. diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx index 53ba28b800b..be4b2b4a816 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx @@ -968,6 +968,11 @@ function TasksTreeView({ }, }); + const getInteractiveNodeProps = (id: string) => ({ + ...getNodeProps(id), + onClick: () => selectNode(id), + }); + return (
@@ -1047,7 +1052,7 @@ function TasksTreeView({ autoFocus tree={events} nodes={nodes} - getNodeProps={getNodeProps} + getNodeProps={getInteractiveNodeProps} getTreeProps={getTreeProps} parentClassName="pl-3" renderNode={({ node, state, index }) => ( @@ -1058,9 +1063,6 @@ function TasksTreeView({ ? "bg-grid-dimmed hover:bg-grid-bright" : "bg-transparent hover:bg-grid-dimmed" )} - onClick={() => { - selectNode(node.id); - }} >
{Array.from({ length: node.level }).map((_, index) => ( @@ -1070,9 +1072,18 @@ function TasksTreeView({ isSelected={state.selected} /> ))} -
{ @@ -1083,10 +1094,13 @@ function TasksTreeView({ } else { expandAllBelowDepth(node.level); } - } else { + } else if (node.hasChildren) { toggleExpandNode(node.id); + } else { + selectNode(node.id, false); } scrollToNode(node.id); + parentRef.current?.focus({ preventScroll: true }); }} > {node.hasChildren ? ( @@ -1098,7 +1112,7 @@ function TasksTreeView({ ) : (
)} -
+
diff --git a/apps/webapp/app/routes/storybook.tree-view/route.tsx b/apps/webapp/app/routes/storybook.tree-view/route.tsx index ac58d71b185..bc7c8cc26ef 100644 --- a/apps/webapp/app/routes/storybook.tree-view/route.tsx +++ b/apps/webapp/app/routes/storybook.tree-view/route.tsx @@ -177,6 +177,11 @@ function TreeViewParent({ }, }); + const getInteractiveNodeProps = (id: string) => ({ + ...getNodeProps(id), + onClick: () => toggleNodeSelection(id), + }); + return (
@@ -203,7 +208,7 @@ function TreeViewParent({ autoFocus tree={tree} nodes={nodes} - getNodeProps={getNodeProps} + getNodeProps={getInteractiveNodeProps} getTreeProps={getTreeProps} parentClassName="h-96 bg-background-deep" renderNode={({ node, state, index, virtualizer, virtualItem }) => ( @@ -215,19 +220,23 @@ function TreeViewParent({ "flex cursor-pointer items-center gap-2 py-1 hover:bg-blue-500/10", state.selected && "bg-blue-500/20 hover:bg-blue-500/30" )} - onClick={() => { - toggleNodeSelection(node.id); - }} > -
{ e.stopPropagation(); toggleExpandNode(node.id); selectNode(node.id, true); - }} - onKeyDown={(e) => { - console.log(e.key); + parentRef.current?.focus(); }} > {node.hasChildren ? ( @@ -239,7 +248,7 @@ function TreeViewParent({ ) : ( )} -
+
{node.data.title}
)}