diff --git a/static/app/views/performance/newTraceDetails/traceModels/__snapshots__/traceTree.spec.tsx.snap b/static/app/views/performance/newTraceDetails/traceModels/__snapshots__/traceTree.spec.tsx.snap index f068d5d11a6ec1..29de4bdcb242f5 100644 --- a/static/app/views/performance/newTraceDetails/traceModels/__snapshots__/traceTree.spec.tsx.snap +++ b/static/app/views/performance/newTraceDetails/traceModels/__snapshots__/traceTree.spec.tsx.snap @@ -98,8 +98,8 @@ exports[`TraceTree eap trace correctly renders eap-transactions toggle state 1`] " eap trace root span.op - span.description (eap-transaction) + span.op - span.description (eap-transaction) span.op - span.description (eap-transaction) - span.op - span.description (eap-transaction) " `; @@ -109,7 +109,7 @@ eap trace root span.op - span.description (eap-transaction) span.op - span.description span.op - span.description (eap-transaction) - span.op - span.description (eap-transaction) + span.op - span.description (eap-transaction) " `; @@ -117,8 +117,8 @@ exports[`TraceTree eap trace correctly renders eap-transactions toggle state 3`] " eap trace root span.op - span.description (eap-transaction) + span.op - span.description (eap-transaction) span.op - span.description (eap-transaction) - span.op - span.description (eap-transaction) " `; diff --git a/static/app/views/performance/newTraceDetails/traceModels/traceTree.spec.tsx b/static/app/views/performance/newTraceDetails/traceModels/traceTree.spec.tsx index 73d488bb6b9568..e9bdb3b2f8c05d 100644 --- a/static/app/views/performance/newTraceDetails/traceModels/traceTree.spec.tsx +++ b/static/app/views/performance/newTraceDetails/traceModels/traceTree.spec.tsx @@ -844,6 +844,16 @@ describe('TraceTree', () => { childTransactionA, childTransactionB, ]); + expect(TraceTree.VisibleParent(childTransactionA)).toBe(rootTransaction); + expect(TraceTree.VisibleParent(childTransactionB)).toBe(rootTransaction); + expect(TraceTree.Depth(childTransactionA)).toBe( + TraceTree.Depth(rootTransaction) + 1 + ); + expect(TraceTree.Depth(childTransactionB)).toBe( + TraceTree.Depth(rootTransaction) + 1 + ); + expect(TraceTree.IsLastVisibleChild(childTransactionA)).toBe(false); + expect(TraceTree.IsLastVisibleChild(childTransactionB)).toBe(true); const rootTransactionIndex = tree.list.indexOf(rootTransaction); expect(tree.list.slice(rootTransactionIndex, rootTransactionIndex + 3)).toEqual([ rootTransaction, @@ -855,6 +865,10 @@ describe('TraceTree', () => { expect(childTransactionA.parent).toBe(spanA); expect(childTransactionB.parent).toBe(spanB); + expect(TraceTree.VisibleParent(childTransactionA)).toBe(spanA); + expect(TraceTree.VisibleParent(childTransactionB)).toBe(spanB); + expect(TraceTree.Depth(childTransactionA)).toBe(TraceTree.Depth(spanA) + 1); + expect(TraceTree.Depth(childTransactionB)).toBe(TraceTree.Depth(spanB) + 1); expect(tree.list.slice(rootTransactionIndex, rootTransactionIndex + 5)).toEqual([ rootTransaction, spanA, @@ -2064,6 +2078,17 @@ describe('TraceTree', () => { }); }); + describe('IsLastVisibleChild', () => { + it('treats the trace root row as the last visible child', () => { + const tree = TraceTree.FromTrace(trace, traceOptions); + const traceRoot = tree.root.children[0]!; + + expect(TraceTree.VisibleParent(traceRoot)).toBeNull(); + expect(TraceTree.IsLastVisibleChild(traceRoot)).toBe(true); + expect(TraceTree.ConnectorsTo(traceRoot)).toEqual([]); + }); + }); + describe('Invalidate', () => { it('invalidates node', () => { const tree = TraceTree.FromTrace(trace, traceOptions); diff --git a/static/app/views/performance/newTraceDetails/traceModels/traceTree.tsx b/static/app/views/performance/newTraceDetails/traceModels/traceTree.tsx index 3e9bbc9c364b99..7f090cb077d57c 100644 --- a/static/app/views/performance/newTraceDetails/traceModels/traceTree.tsx +++ b/static/app/views/performance/newTraceDetails/traceModels/traceTree.tsx @@ -1212,16 +1212,43 @@ export class TraceTree extends TraceTreeEventDispatcher { return node.depth; } - let depth = -2; - let start: BaseNode | null = node; + const visibleParent = TraceTree.VisibleParent(node); + node.depth = visibleParent ? TraceTree.Depth(visibleParent) + 1 : 0; + return node.depth; + } + + static VisibleParent(node: BaseNode): BaseNode | null { + if (node.visibleParent !== undefined) { + return node.visibleParent; + } + + let start = node.parent; while (start) { - depth++; + if ( + start.directVisibleChildren.includes(node) && + (start.isRootNodeChild() || TraceTree.VisibleParent(start) !== null) + ) { + node.visibleParent = start; + return node.visibleParent; + } + start = start.parent; } - node.depth = depth; - return depth; + node.visibleParent = null; + return node.visibleParent; + } + + static IsLastVisibleChild(node: BaseNode): boolean { + const visibleParent = TraceTree.VisibleParent(node); + + if (!visibleParent) { + return node.isLastChild(); + } + + const visibleChildren = visibleParent.directVisibleChildren; + return visibleChildren[visibleChildren.length - 1] === node; } static ConnectorsTo(node: BaseNode): number[] { @@ -1230,31 +1257,36 @@ export class TraceTree extends TraceTreeEventDispatcher { } const connectors: number[] = []; - let start = node.parent; + let start = TraceTree.VisibleParent(node); - if (start?.isRootNodeChild() && !node.isLastChild()) { + if (start?.isRootNodeChild() && !TraceTree.IsLastVisibleChild(node)) { node.connectors = [-TraceTree.Depth(node)]; return node.connectors; } - if (!node.isLastChild()) { + if (!TraceTree.IsLastVisibleChild(node)) { connectors.push(TraceTree.Depth(node)); } while (start) { - if (!start.value || !start.parent) { + if (!start.value) { break; } - if (start.isLastChild()) { - start = start.parent; + const visibleParent = TraceTree.VisibleParent(start); + if (!visibleParent) { + break; + } + + if (TraceTree.IsLastVisibleChild(start)) { + start = visibleParent; continue; } connectors.push( - start.parent.isRootNodeChild() ? -TraceTree.Depth(start) : TraceTree.Depth(start) + visibleParent.isRootNodeChild() ? -TraceTree.Depth(start) : TraceTree.Depth(start) ); - start = start.parent; + start = visibleParent; } node.connectors = connectors; diff --git a/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/baseNode.tsx b/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/baseNode.tsx index f127b561fa2fb1..ee0a29324303c9 100644 --- a/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/baseNode.tsx +++ b/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/baseNode.tsx @@ -114,6 +114,11 @@ export abstract class BaseNode : null} - {props.node.isLastChild() ? ( + {TraceTree.IsLastVisibleChild(props.node) ? ( ) : null}