@perses-dev/tracing-gantt-chart-plugin 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/__mf/css/async/263.6c6463ea.css +1 -0
  2. package/__mf/js/TracingGanttChart.6861c573.js +5 -0
  3. package/__mf/js/async/109.1225b97d.js +73 -0
  4. package/__mf/js/async/109.1225b97d.js.LICENSE.txt +35 -0
  5. package/__mf/js/async/118.c1138755.js +1 -0
  6. package/__mf/js/async/173.66fc423e.js +2 -0
  7. package/__mf/js/async/214.8bf3e03e.js +1 -0
  8. package/__mf/js/async/224.670da1e3.js +1 -0
  9. package/__mf/js/async/238.5c460cb2.js +1 -0
  10. package/__mf/js/async/292.4821b1b1.js +1 -0
  11. package/__mf/js/async/387.23da505f.js +1 -0
  12. package/__mf/js/async/409.12b6365d.js +1 -0
  13. package/__mf/js/async/488.2d364feb.js +1 -0
  14. package/__mf/js/async/533.f20b93c0.js +110 -0
  15. package/__mf/js/async/558.3b93d5ec.js +39 -0
  16. package/__mf/js/async/558.3b93d5ec.js.LICENSE.txt +21 -0
  17. package/__mf/js/async/62.1a6f8c05.js +1 -0
  18. package/__mf/js/async/651.bcb43163.js +1 -0
  19. package/__mf/js/async/{770.5431adef.js → 694.fe491393.js} +1 -1
  20. package/__mf/js/async/738.7d9e5092.js +1 -0
  21. package/__mf/js/async/740.fa3debdf.js +1 -0
  22. package/__mf/js/async/75.a3a29681.js +1 -0
  23. package/__mf/js/async/770.65ae427e.js +1 -0
  24. package/__mf/js/async/814.c33b5f31.js +2 -0
  25. package/__mf/js/async/814.c33b5f31.js.LICENSE.txt +24 -0
  26. package/__mf/js/async/832.0e397220.js +7 -0
  27. package/__mf/js/async/832.0e397220.js.LICENSE.txt +21 -0
  28. package/__mf/js/async/863.0e6501cd.js +2 -0
  29. package/__mf/js/async/897.f1628ec5.js +1 -0
  30. package/__mf/js/async/960.89291786.js +2 -0
  31. package/__mf/js/async/964.3f12c3f5.js +2 -0
  32. package/__mf/js/async/981.1c640ffc.js +2 -0
  33. package/__mf/js/async/__federation_expose_TracingGanttChart.3c44e08a.js +1 -0
  34. package/__mf/js/async/lib-router.ab6beae3.js +2 -0
  35. package/__mf/js/main.fb8fb582.js +5 -0
  36. package/lib/PanelActions.d.ts +9 -0
  37. package/lib/PanelActions.d.ts.map +1 -0
  38. package/lib/PanelActions.js +70 -0
  39. package/lib/PanelActions.js.map +1 -0
  40. package/lib/TracingGanttChart/DetailPane/Attributes.d.ts +21 -2
  41. package/lib/TracingGanttChart/DetailPane/Attributes.d.ts.map +1 -1
  42. package/lib/TracingGanttChart/DetailPane/Attributes.js +103 -31
  43. package/lib/TracingGanttChart/DetailPane/Attributes.js.map +1 -1
  44. package/lib/TracingGanttChart/DetailPane/DetailPane.d.ts +2 -2
  45. package/lib/TracingGanttChart/DetailPane/DetailPane.d.ts.map +1 -1
  46. package/lib/TracingGanttChart/DetailPane/DetailPane.js +22 -16
  47. package/lib/TracingGanttChart/DetailPane/DetailPane.js.map +1 -1
  48. package/lib/TracingGanttChart/DetailPane/SpanEvents.d.ts +2 -0
  49. package/lib/TracingGanttChart/DetailPane/SpanEvents.d.ts.map +1 -1
  50. package/lib/TracingGanttChart/DetailPane/SpanEvents.js +69 -23
  51. package/lib/TracingGanttChart/DetailPane/SpanEvents.js.map +1 -1
  52. package/lib/TracingGanttChart/DetailPane/SpanLinks.d.ts +9 -0
  53. package/lib/TracingGanttChart/DetailPane/SpanLinks.d.ts.map +1 -0
  54. package/lib/TracingGanttChart/DetailPane/SpanLinks.js +64 -0
  55. package/lib/TracingGanttChart/DetailPane/SpanLinks.js.map +1 -0
  56. package/lib/TracingGanttChart/GanttTable/GanttTable.d.ts +2 -1
  57. package/lib/TracingGanttChart/GanttTable/GanttTable.d.ts.map +1 -1
  58. package/lib/TracingGanttChart/GanttTable/GanttTable.js +15 -1
  59. package/lib/TracingGanttChart/GanttTable/GanttTable.js.map +1 -1
  60. package/lib/TracingGanttChart/GanttTable/GanttTableRow.d.ts +2 -1
  61. package/lib/TracingGanttChart/GanttTable/GanttTableRow.d.ts.map +1 -1
  62. package/lib/TracingGanttChart/GanttTable/GanttTableRow.js +2 -1
  63. package/lib/TracingGanttChart/GanttTable/GanttTableRow.js.map +1 -1
  64. package/lib/TracingGanttChart/GanttTable/SpanLinksButton.d.ts +8 -0
  65. package/lib/TracingGanttChart/GanttTable/SpanLinksButton.d.ts.map +1 -0
  66. package/lib/TracingGanttChart/GanttTable/SpanLinksButton.js +95 -0
  67. package/lib/TracingGanttChart/GanttTable/SpanLinksButton.js.map +1 -0
  68. package/lib/TracingGanttChart/GanttTable/SpanName.d.ts +2 -0
  69. package/lib/TracingGanttChart/GanttTable/SpanName.d.ts.map +1 -1
  70. package/lib/TracingGanttChart/GanttTable/SpanName.js +12 -1
  71. package/lib/TracingGanttChart/GanttTable/SpanName.js.map +1 -1
  72. package/lib/TracingGanttChart/MiniGanttChart/draw.d.ts.map +1 -1
  73. package/lib/TracingGanttChart/MiniGanttChart/draw.js +1 -8
  74. package/lib/TracingGanttChart/MiniGanttChart/draw.js.map +1 -1
  75. package/lib/TracingGanttChart/TraceDetails.d.ts +7 -0
  76. package/lib/TracingGanttChart/TraceDetails.d.ts.map +1 -0
  77. package/lib/TracingGanttChart/TraceDetails.js +90 -0
  78. package/lib/TracingGanttChart/TraceDetails.js.map +1 -0
  79. package/lib/TracingGanttChart/TracingGanttChart.d.ts +2 -3
  80. package/lib/TracingGanttChart/TracingGanttChart.d.ts.map +1 -1
  81. package/lib/TracingGanttChart/TracingGanttChart.js +8 -3
  82. package/lib/TracingGanttChart/TracingGanttChart.js.map +1 -1
  83. package/lib/TracingGanttChart/trace.d.ts +7 -0
  84. package/lib/TracingGanttChart/trace.d.ts.map +1 -1
  85. package/lib/TracingGanttChart/trace.js +13 -4
  86. package/lib/TracingGanttChart/trace.js.map +1 -1
  87. package/lib/TracingGanttChart.d.ts.map +1 -1
  88. package/lib/TracingGanttChart.js +7 -1
  89. package/lib/TracingGanttChart.js.map +1 -1
  90. package/lib/TracingGanttChartPanel.d.ts +1 -11
  91. package/lib/TracingGanttChartPanel.d.ts.map +1 -1
  92. package/lib/TracingGanttChartPanel.js +10 -2
  93. package/lib/TracingGanttChartPanel.js.map +1 -1
  94. package/lib/cjs/PanelActions.js +88 -0
  95. package/lib/cjs/TracingGanttChart/DetailPane/Attributes.js +117 -31
  96. package/lib/cjs/TracingGanttChart/DetailPane/DetailPane.js +19 -13
  97. package/lib/cjs/TracingGanttChart/DetailPane/SpanEvents.js +66 -20
  98. package/lib/cjs/TracingGanttChart/DetailPane/SpanLinks.js +72 -0
  99. package/lib/cjs/TracingGanttChart/GanttTable/GanttTable.js +15 -1
  100. package/lib/cjs/TracingGanttChart/GanttTable/GanttTableRow.js +2 -1
  101. package/lib/cjs/TracingGanttChart/GanttTable/SpanLinksButton.js +108 -0
  102. package/lib/cjs/TracingGanttChart/GanttTable/SpanName.js +12 -1
  103. package/lib/cjs/TracingGanttChart/MiniGanttChart/draw.js +1 -8
  104. package/lib/cjs/TracingGanttChart/TraceDetails.js +98 -0
  105. package/lib/cjs/TracingGanttChart/TracingGanttChart.js +8 -3
  106. package/lib/cjs/TracingGanttChart/trace.js +13 -4
  107. package/lib/cjs/TracingGanttChart.js +7 -1
  108. package/lib/cjs/TracingGanttChartPanel.js +10 -2
  109. package/lib/cjs/gantt-chart-model.js +1 -1
  110. package/lib/gantt-chart-model.d.ts +31 -0
  111. package/lib/gantt-chart-model.d.ts.map +1 -1
  112. package/lib/gantt-chart-model.js +1 -1
  113. package/lib/gantt-chart-model.js.map +1 -1
  114. package/mf-manifest.json +86 -66
  115. package/mf-stats.json +100 -74
  116. package/package.json +15 -5
  117. package/__mf/js/788.d9986a69.js +0 -5
  118. package/__mf/js/TracingGanttChart.906bee00.js +0 -5
  119. package/__mf/js/async/156.5a401ecb.js +0 -1
  120. package/__mf/js/async/173.6314a363.js +0 -2
  121. package/__mf/js/async/193.12ce9ab1.js +0 -44
  122. package/__mf/js/async/193.12ce9ab1.js.LICENSE.txt +0 -68
  123. package/__mf/js/async/377.59c252c4.js +0 -2
  124. package/__mf/js/async/511.b81ea373.js +0 -1
  125. package/__mf/js/async/620.1d1ce390.js +0 -2
  126. package/__mf/js/async/651.3ea371e5.js +0 -1
  127. package/__mf/js/async/694.4580ad20.js +0 -1
  128. package/__mf/js/async/740.babbb403.js +0 -1
  129. package/__mf/js/async/75.d81e6bbf.js +0 -1
  130. package/__mf/js/async/783.3c2c57f6.js +0 -110
  131. package/__mf/js/async/960.478a8f11.js +0 -2
  132. package/__mf/js/async/964.a98cab40.js +0 -2
  133. package/__mf/js/async/981.bc5132f8.js +0 -2
  134. package/__mf/js/async/__federation_expose_TracingGanttChart.cfa547a5.js +0 -1
  135. package/__mf/js/main.2f3ef69f.js +0 -1
  136. /package/__mf/js/async/{173.6314a363.js.LICENSE.txt → 173.66fc423e.js.LICENSE.txt} +0 -0
  137. /package/__mf/js/async/{783.3c2c57f6.js.LICENSE.txt → 533.f20b93c0.js.LICENSE.txt} +0 -0
  138. /package/__mf/js/async/{620.1d1ce390.js.LICENSE.txt → 863.0e6501cd.js.LICENSE.txt} +0 -0
  139. /package/__mf/js/async/{960.478a8f11.js.LICENSE.txt → 960.89291786.js.LICENSE.txt} +0 -0
  140. /package/__mf/js/async/{964.a98cab40.js.LICENSE.txt → 964.3f12c3f5.js.LICENSE.txt} +0 -0
  141. /package/__mf/js/async/{981.bc5132f8.js.LICENSE.txt → 981.1c640ffc.js.LICENSE.txt} +0 -0
  142. /package/__mf/js/async/{377.59c252c4.js.LICENSE.txt → lib-router.ab6beae3.js.LICENSE.txt} +0 -0
@@ -19,7 +19,7 @@ import { GanttTableRow } from './GanttTableRow';
19
19
  import { GanttTableHeader } from './GanttTableHeader';
20
20
  import { ResizableDivider } from './ResizableDivider';
21
21
  export function GanttTable(props) {
22
- const { options, trace, viewport, selectedSpan, onSpanClick } = props;
22
+ const { options, customLinks, trace, viewport, selectedSpan, onSpanClick } = props;
23
23
  const { collapsedSpans, setVisibleSpans } = useGanttTableContext();
24
24
  const [nameColumnWidth, setNameColumnWidth] = useState(0.25);
25
25
  const tableRef = useRef(null);
@@ -34,6 +34,18 @@ export function GanttTable(props) {
34
34
  trace.rootSpans,
35
35
  collapsedSpans
36
36
  ]);
37
+ const selectedSpanIndex = useMemo(()=>{
38
+ if (!selectedSpan) return undefined;
39
+ for(let i = 0; i < rows.length; i++){
40
+ if (rows[i]?.spanId === selectedSpan.spanId) {
41
+ return i;
42
+ }
43
+ }
44
+ return undefined;
45
+ }, [
46
+ rows,
47
+ selectedSpan
48
+ ]);
37
49
  const divider = /*#__PURE__*/ _jsx(ResizableDivider, {
38
50
  parentRef: tableRef,
39
51
  onMove: setNameColumnWidth
@@ -64,8 +76,10 @@ export function GanttTable(props) {
64
76
  }),
65
77
  /*#__PURE__*/ _jsx(Virtuoso, {
66
78
  data: rows,
79
+ initialTopMostItemIndex: selectedSpanIndex ?? 0,
67
80
  itemContent: (_, span)=>/*#__PURE__*/ _jsx(GanttTableRow, {
68
81
  options: options,
82
+ customLinks: customLinks,
69
83
  span: span,
70
84
  viewport: viewport,
71
85
  selected: span === selectedSpan,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/TracingGanttChart/GanttTable/GanttTable.tsx"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Virtuoso, ListRange } from 'react-virtuoso';\nimport { ReactElement, useMemo, useRef, useState } from 'react';\nimport { Box, useTheme } from '@mui/material';\nimport { Viewport } from '../utils';\nimport { TracingGanttChartOptions } from '../../gantt-chart-model';\nimport { Span, Trace } from '../trace';\nimport { useGanttTableContext } from './GanttTableProvider';\nimport { GanttTableRow } from './GanttTableRow';\nimport { GanttTableHeader } from './GanttTableHeader';\nimport { ResizableDivider } from './ResizableDivider';\n\nexport interface GanttTableProps {\n options: TracingGanttChartOptions;\n trace: Trace;\n viewport: Viewport;\n selectedSpan?: Span;\n onSpanClick: (span: Span) => void;\n}\n\nexport function GanttTable(props: GanttTableProps): ReactElement {\n const { options, trace, viewport, selectedSpan, onSpanClick } = props;\n const { collapsedSpans, setVisibleSpans } = useGanttTableContext();\n const [nameColumnWidth, setNameColumnWidth] = useState<number>(0.25);\n const tableRef = useRef<HTMLDivElement>(null);\n const theme = useTheme();\n\n const rows = useMemo(() => {\n const rows: Span[] = [];\n for (const rootSpan of trace.rootSpans) {\n treeToRows(rows, rootSpan, collapsedSpans);\n }\n return rows;\n }, [trace.rootSpans, collapsedSpans]);\n\n const divider = <ResizableDivider parentRef={tableRef} onMove={setNameColumnWidth} />;\n\n // update currently visible spans\n function handleRangeChange({ startIndex, endIndex }: ListRange): void {\n const visibleSpans: string[] = [];\n for (let i = startIndex; i <= endIndex; i++) {\n visibleSpans.push(rows[i]!.spanId);\n }\n setVisibleSpans(visibleSpans);\n }\n\n return (\n <Box\n ref={tableRef}\n sx={{\n display: 'flex',\n flexDirection: 'column',\n flexGrow: 1,\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: `${theme.shape.borderRadius}px`,\n }}\n >\n <GanttTableHeader trace={trace} viewport={viewport} nameColumnWidth={nameColumnWidth} divider={divider} />\n <Virtuoso\n data={rows}\n itemContent={(_, span) => (\n <GanttTableRow\n options={options}\n span={span}\n viewport={viewport}\n selected={span === selectedSpan}\n nameColumnWidth={nameColumnWidth}\n divider={divider}\n onClick={onSpanClick}\n />\n )}\n rangeChanged={handleRangeChange}\n />\n </Box>\n );\n}\n\n/**\n * treeToRows recursively transforms the span tree to a list of rows and\n * hides collapsed child spans.\n */\nfunction treeToRows(rows: Span[], span: Span, collapsedSpans: string[]): void {\n rows.push(span);\n if (!collapsedSpans.includes(span.spanId)) {\n for (const child of span.childSpans) {\n treeToRows(rows, child, collapsedSpans);\n }\n }\n}\n"],"names":["Virtuoso","useMemo","useRef","useState","Box","useTheme","useGanttTableContext","GanttTableRow","GanttTableHeader","ResizableDivider","GanttTable","props","options","trace","viewport","selectedSpan","onSpanClick","collapsedSpans","setVisibleSpans","nameColumnWidth","setNameColumnWidth","tableRef","theme","rows","rootSpan","rootSpans","treeToRows","divider","parentRef","onMove","handleRangeChange","startIndex","endIndex","visibleSpans","i","push","spanId","ref","sx","display","flexDirection","flexGrow","border","palette","borderRadius","shape","data","itemContent","_","span","selected","onClick","rangeChanged","includes","child","childSpans"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,QAAQ,QAAmB,iBAAiB;AACrD,SAAuBC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AAChE,SAASC,GAAG,EAAEC,QAAQ,QAAQ,gBAAgB;AAI9C,SAASC,oBAAoB,QAAQ,uBAAuB;AAC5D,SAASC,aAAa,QAAQ,kBAAkB;AAChD,SAASC,gBAAgB,QAAQ,qBAAqB;AACtD,SAASC,gBAAgB,QAAQ,qBAAqB;AAUtD,OAAO,SAASC,WAAWC,KAAsB;IAC/C,MAAM,EAAEC,OAAO,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,YAAY,EAAEC,WAAW,EAAE,GAAGL;IAChE,MAAM,EAAEM,cAAc,EAAEC,eAAe,EAAE,GAAGZ;IAC5C,MAAM,CAACa,iBAAiBC,mBAAmB,GAAGjB,SAAiB;IAC/D,MAAMkB,WAAWnB,OAAuB;IACxC,MAAMoB,QAAQjB;IAEd,MAAMkB,OAAOtB,QAAQ;QACnB,MAAMsB,OAAe,EAAE;QACvB,KAAK,MAAMC,YAAYX,MAAMY,SAAS,CAAE;YACtCC,WAAWH,MAAMC,UAAUP;QAC7B;QACA,OAAOM;IACT,GAAG;QAACV,MAAMY,SAAS;QAAER;KAAe;IAEpC,MAAMU,wBAAU,KAAClB;QAAiBmB,WAAWP;QAAUQ,QAAQT;;IAE/D,iCAAiC;IACjC,SAASU,kBAAkB,EAAEC,UAAU,EAAEC,QAAQ,EAAa;QAC5D,MAAMC,eAAyB,EAAE;QACjC,IAAK,IAAIC,IAAIH,YAAYG,KAAKF,UAAUE,IAAK;YAC3CD,aAAaE,IAAI,CAACZ,IAAI,CAACW,EAAE,CAAEE,MAAM;QACnC;QACAlB,gBAAgBe;IAClB;IAEA,qBACE,MAAC7B;QACCiC,KAAKhB;QACLiB,IAAI;YACFC,SAAS;YACTC,eAAe;YACfC,UAAU;YACVC,QAAQ,CAAC,UAAU,EAAEpB,MAAMqB,OAAO,CAAChB,OAAO,EAAE;YAC5CiB,cAAc,GAAGtB,MAAMuB,KAAK,CAACD,YAAY,CAAC,EAAE,CAAC;QAC/C;;0BAEA,KAACpC;gBAAiBK,OAAOA;gBAAOC,UAAUA;gBAAUK,iBAAiBA;gBAAiBQ,SAASA;;0BAC/F,KAAC3B;gBACC8C,MAAMvB;gBACNwB,aAAa,CAACC,GAAGC,qBACf,KAAC1C;wBACCK,SAASA;wBACTqC,MAAMA;wBACNnC,UAAUA;wBACVoC,UAAUD,SAASlC;wBACnBI,iBAAiBA;wBACjBQ,SAASA;wBACTwB,SAASnC;;gBAGboC,cAActB;;;;AAItB;AAEA;;;CAGC,GACD,SAASJ,WAAWH,IAAY,EAAE0B,IAAU,EAAEhC,cAAwB;IACpEM,KAAKY,IAAI,CAACc;IACV,IAAI,CAAChC,eAAeoC,QAAQ,CAACJ,KAAKb,MAAM,GAAG;QACzC,KAAK,MAAMkB,SAASL,KAAKM,UAAU,CAAE;YACnC7B,WAAWH,MAAM+B,OAAOrC;QAC1B;IACF;AACF"}
1
+ {"version":3,"sources":["../../../../src/TracingGanttChart/GanttTable/GanttTable.tsx"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Virtuoso, ListRange } from 'react-virtuoso';\nimport { ReactElement, useMemo, useRef, useState } from 'react';\nimport { Box, useTheme } from '@mui/material';\nimport { Viewport } from '../utils';\nimport { CustomLinks, TracingGanttChartOptions } from '../../gantt-chart-model';\nimport { Span, Trace } from '../trace';\nimport { useGanttTableContext } from './GanttTableProvider';\nimport { GanttTableRow } from './GanttTableRow';\nimport { GanttTableHeader } from './GanttTableHeader';\nimport { ResizableDivider } from './ResizableDivider';\n\nexport interface GanttTableProps {\n options: TracingGanttChartOptions;\n customLinks?: CustomLinks;\n trace: Trace;\n viewport: Viewport;\n selectedSpan?: Span;\n onSpanClick: (span: Span) => void;\n}\n\nexport function GanttTable(props: GanttTableProps): ReactElement {\n const { options, customLinks, trace, viewport, selectedSpan, onSpanClick } = props;\n const { collapsedSpans, setVisibleSpans } = useGanttTableContext();\n const [nameColumnWidth, setNameColumnWidth] = useState<number>(0.25);\n const tableRef = useRef<HTMLDivElement>(null);\n const theme = useTheme();\n\n const rows = useMemo(() => {\n const rows: Span[] = [];\n for (const rootSpan of trace.rootSpans) {\n treeToRows(rows, rootSpan, collapsedSpans);\n }\n return rows;\n }, [trace.rootSpans, collapsedSpans]);\n\n const selectedSpanIndex = useMemo(() => {\n if (!selectedSpan) return undefined;\n\n for (let i = 0; i < rows.length; i++) {\n if (rows[i]?.spanId === selectedSpan.spanId) {\n return i;\n }\n }\n return undefined;\n }, [rows, selectedSpan]);\n\n const divider = <ResizableDivider parentRef={tableRef} onMove={setNameColumnWidth} />;\n\n // update currently visible spans\n function handleRangeChange({ startIndex, endIndex }: ListRange): void {\n const visibleSpans: string[] = [];\n for (let i = startIndex; i <= endIndex; i++) {\n visibleSpans.push(rows[i]!.spanId);\n }\n setVisibleSpans(visibleSpans);\n }\n\n return (\n <Box\n ref={tableRef}\n sx={{\n display: 'flex',\n flexDirection: 'column',\n flexGrow: 1,\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: `${theme.shape.borderRadius}px`,\n }}\n >\n <GanttTableHeader trace={trace} viewport={viewport} nameColumnWidth={nameColumnWidth} divider={divider} />\n <Virtuoso\n data={rows}\n initialTopMostItemIndex={selectedSpanIndex ?? 0}\n itemContent={(_, span) => (\n <GanttTableRow\n options={options}\n customLinks={customLinks}\n span={span}\n viewport={viewport}\n selected={span === selectedSpan}\n nameColumnWidth={nameColumnWidth}\n divider={divider}\n onClick={onSpanClick}\n />\n )}\n rangeChanged={handleRangeChange}\n />\n </Box>\n );\n}\n\n/**\n * treeToRows recursively transforms the span tree to a list of rows and\n * hides collapsed child spans.\n */\nfunction treeToRows(rows: Span[], span: Span, collapsedSpans: string[]): void {\n rows.push(span);\n if (!collapsedSpans.includes(span.spanId)) {\n for (const child of span.childSpans) {\n treeToRows(rows, child, collapsedSpans);\n }\n }\n}\n"],"names":["Virtuoso","useMemo","useRef","useState","Box","useTheme","useGanttTableContext","GanttTableRow","GanttTableHeader","ResizableDivider","GanttTable","props","options","customLinks","trace","viewport","selectedSpan","onSpanClick","collapsedSpans","setVisibleSpans","nameColumnWidth","setNameColumnWidth","tableRef","theme","rows","rootSpan","rootSpans","treeToRows","selectedSpanIndex","undefined","i","length","spanId","divider","parentRef","onMove","handleRangeChange","startIndex","endIndex","visibleSpans","push","ref","sx","display","flexDirection","flexGrow","border","palette","borderRadius","shape","data","initialTopMostItemIndex","itemContent","_","span","selected","onClick","rangeChanged","includes","child","childSpans"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,QAAQ,QAAmB,iBAAiB;AACrD,SAAuBC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AAChE,SAASC,GAAG,EAAEC,QAAQ,QAAQ,gBAAgB;AAI9C,SAASC,oBAAoB,QAAQ,uBAAuB;AAC5D,SAASC,aAAa,QAAQ,kBAAkB;AAChD,SAASC,gBAAgB,QAAQ,qBAAqB;AACtD,SAASC,gBAAgB,QAAQ,qBAAqB;AAWtD,OAAO,SAASC,WAAWC,KAAsB;IAC/C,MAAM,EAAEC,OAAO,EAAEC,WAAW,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,YAAY,EAAEC,WAAW,EAAE,GAAGN;IAC7E,MAAM,EAAEO,cAAc,EAAEC,eAAe,EAAE,GAAGb;IAC5C,MAAM,CAACc,iBAAiBC,mBAAmB,GAAGlB,SAAiB;IAC/D,MAAMmB,WAAWpB,OAAuB;IACxC,MAAMqB,QAAQlB;IAEd,MAAMmB,OAAOvB,QAAQ;QACnB,MAAMuB,OAAe,EAAE;QACvB,KAAK,MAAMC,YAAYX,MAAMY,SAAS,CAAE;YACtCC,WAAWH,MAAMC,UAAUP;QAC7B;QACA,OAAOM;IACT,GAAG;QAACV,MAAMY,SAAS;QAAER;KAAe;IAEpC,MAAMU,oBAAoB3B,QAAQ;QAChC,IAAI,CAACe,cAAc,OAAOa;QAE1B,IAAK,IAAIC,IAAI,GAAGA,IAAIN,KAAKO,MAAM,EAAED,IAAK;YACpC,IAAIN,IAAI,CAACM,EAAE,EAAEE,WAAWhB,aAAagB,MAAM,EAAE;gBAC3C,OAAOF;YACT;QACF;QACA,OAAOD;IACT,GAAG;QAACL;QAAMR;KAAa;IAEvB,MAAMiB,wBAAU,KAACxB;QAAiByB,WAAWZ;QAAUa,QAAQd;;IAE/D,iCAAiC;IACjC,SAASe,kBAAkB,EAAEC,UAAU,EAAEC,QAAQ,EAAa;QAC5D,MAAMC,eAAyB,EAAE;QACjC,IAAK,IAAIT,IAAIO,YAAYP,KAAKQ,UAAUR,IAAK;YAC3CS,aAAaC,IAAI,CAAChB,IAAI,CAACM,EAAE,CAAEE,MAAM;QACnC;QACAb,gBAAgBoB;IAClB;IAEA,qBACE,MAACnC;QACCqC,KAAKnB;QACLoB,IAAI;YACFC,SAAS;YACTC,eAAe;YACfC,UAAU;YACVC,QAAQ,CAAC,UAAU,EAAEvB,MAAMwB,OAAO,CAACd,OAAO,EAAE;YAC5Ce,cAAc,GAAGzB,MAAM0B,KAAK,CAACD,YAAY,CAAC,EAAE,CAAC;QAC/C;;0BAEA,KAACxC;gBAAiBM,OAAOA;gBAAOC,UAAUA;gBAAUK,iBAAiBA;gBAAiBa,SAASA;;0BAC/F,KAACjC;gBACCkD,MAAM1B;gBACN2B,yBAAyBvB,qBAAqB;gBAC9CwB,aAAa,CAACC,GAAGC,qBACf,KAAC/C;wBACCK,SAASA;wBACTC,aAAaA;wBACbyC,MAAMA;wBACNvC,UAAUA;wBACVwC,UAAUD,SAAStC;wBACnBI,iBAAiBA;wBACjBa,SAASA;wBACTuB,SAASvC;;gBAGbwC,cAAcrB;;;;AAItB;AAEA;;;CAGC,GACD,SAAST,WAAWH,IAAY,EAAE8B,IAAU,EAAEpC,cAAwB;IACpEM,KAAKgB,IAAI,CAACc;IACV,IAAI,CAACpC,eAAewC,QAAQ,CAACJ,KAAKtB,MAAM,GAAG;QACzC,KAAK,MAAM2B,SAASL,KAAKM,UAAU,CAAE;YACnCjC,WAAWH,MAAMmC,OAAOzC;QAC1B;IACF;AACF"}
@@ -1,8 +1,9 @@
1
1
  import { Viewport } from '../utils';
2
- import { TracingGanttChartOptions } from '../../gantt-chart-model';
2
+ import { CustomLinks, TracingGanttChartOptions } from '../../gantt-chart-model';
3
3
  import { Span } from '../trace';
4
4
  interface GanttTableRowProps {
5
5
  options: TracingGanttChartOptions;
6
+ customLinks?: CustomLinks;
6
7
  span: Span;
7
8
  viewport: Viewport;
8
9
  selected?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"GanttTableRow.d.ts","sourceRoot":"","sources":["../../../../src/TracingGanttChart/GanttTable/GanttTableRow.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAE,QAAQ,EAAa,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAIhC,UAAU,kBAAkB;IAC1B,OAAO,EAAE,wBAAwB,CAAC;IAClC,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CAC/B;AAED,eAAO,MAAM,aAAa,0DAsBxB,CAAC"}
1
+ {"version":3,"file":"GanttTableRow.d.ts","sourceRoot":"","sources":["../../../../src/TracingGanttChart/GanttTable/GanttTableRow.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAE,QAAQ,EAAa,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAIhC,UAAU,kBAAkB;IAC1B,OAAO,EAAE,wBAAwB,CAAC;IAClC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CAC/B;AAED,eAAO,MAAM,aAAa,0DAsBxB,CAAC"}
@@ -17,7 +17,7 @@ import { rowHeight } from '../utils';
17
17
  import { SpanName } from './SpanName';
18
18
  import { SpanDuration } from './SpanDuration';
19
19
  export const GanttTableRow = /*#__PURE__*/ memo(function GanttTableRow(props) {
20
- const { options, span, viewport, selected, nameColumnWidth, divider, onClick } = props;
20
+ const { options, customLinks, span, viewport, selected, nameColumnWidth, divider, onClick } = props;
21
21
  const theme = useTheme();
22
22
  const handleOnClick = ()=>{
23
23
  // ignore event if triggered by selecting text
@@ -32,6 +32,7 @@ export const GanttTableRow = /*#__PURE__*/ memo(function GanttTableRow(props) {
32
32
  onClick: handleOnClick,
33
33
  children: [
34
34
  /*#__PURE__*/ _jsx(SpanName, {
35
+ customLinks: customLinks,
35
36
  span: span,
36
37
  nameColumnWidth: nameColumnWidth
37
38
  }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/TracingGanttChart/GanttTable/GanttTableRow.tsx"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Stack, styled, useTheme } from '@mui/material';\nimport { memo } from 'react';\nimport { Viewport, rowHeight } from '../utils';\nimport { TracingGanttChartOptions } from '../../gantt-chart-model';\nimport { Span } from '../trace';\nimport { SpanName } from './SpanName';\nimport { SpanDuration } from './SpanDuration';\n\ninterface GanttTableRowProps {\n options: TracingGanttChartOptions;\n span: Span;\n viewport: Viewport;\n selected?: boolean;\n nameColumnWidth: number;\n divider: React.ReactNode;\n onClick: (span: Span) => void;\n}\n\nexport const GanttTableRow = memo(function GanttTableRow(props: GanttTableRowProps) {\n const { options, span, viewport, selected, nameColumnWidth, divider, onClick } = props;\n const theme = useTheme();\n\n const handleOnClick = (): void => {\n // ignore event if triggered by selecting text\n if (document.getSelection()?.type === 'Range') return;\n\n onClick(span);\n };\n\n return (\n <RowContainer\n sx={{ backgroundColor: selected ? theme.palette.action.selected : 'inherit' }}\n direction=\"row\"\n onClick={handleOnClick}\n >\n <SpanName span={span} nameColumnWidth={nameColumnWidth} />\n {divider}\n <SpanDuration options={options} span={span} viewport={viewport} />\n </RowContainer>\n );\n});\n\nconst RowContainer = styled(Stack)(({ theme }) => ({\n height: rowHeight,\n '&:hover': {\n backgroundColor: theme.palette.action.hover,\n borderTop: `1px solid ${theme.palette.divider}`,\n borderBottom: `1px solid ${theme.palette.divider}`,\n },\n}));\n"],"names":["Stack","styled","useTheme","memo","rowHeight","SpanName","SpanDuration","GanttTableRow","props","options","span","viewport","selected","nameColumnWidth","divider","onClick","theme","handleOnClick","document","getSelection","type","RowContainer","sx","backgroundColor","palette","action","direction","height","hover","borderTop","borderBottom"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,KAAK,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,gBAAgB;AACxD,SAASC,IAAI,QAAQ,QAAQ;AAC7B,SAAmBC,SAAS,QAAQ,WAAW;AAG/C,SAASC,QAAQ,QAAQ,aAAa;AACtC,SAASC,YAAY,QAAQ,iBAAiB;AAY9C,OAAO,MAAMC,8BAAgBJ,KAAK,SAASI,cAAcC,KAAyB;IAChF,MAAM,EAAEC,OAAO,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,eAAe,EAAEC,OAAO,EAAEC,OAAO,EAAE,GAAGP;IACjF,MAAMQ,QAAQd;IAEd,MAAMe,gBAAgB;QACpB,8CAA8C;QAC9C,IAAIC,SAASC,YAAY,IAAIC,SAAS,SAAS;QAE/CL,QAAQL;IACV;IAEA,qBACE,MAACW;QACCC,IAAI;YAAEC,iBAAiBX,WAAWI,MAAMQ,OAAO,CAACC,MAAM,CAACb,QAAQ,GAAG;QAAU;QAC5Ec,WAAU;QACVX,SAASE;;0BAET,KAACZ;gBAASK,MAAMA;gBAAMG,iBAAiBA;;YACtCC;0BACD,KAACR;gBAAaG,SAASA;gBAASC,MAAMA;gBAAMC,UAAUA;;;;AAG5D,GAAG;AAEH,MAAMU,eAAepB,OAAOD,OAAO,CAAC,EAAEgB,KAAK,EAAE,GAAM,CAAA;QACjDW,QAAQvB;QACR,WAAW;YACTmB,iBAAiBP,MAAMQ,OAAO,CAACC,MAAM,CAACG,KAAK;YAC3CC,WAAW,CAAC,UAAU,EAAEb,MAAMQ,OAAO,CAACV,OAAO,EAAE;YAC/CgB,cAAc,CAAC,UAAU,EAAEd,MAAMQ,OAAO,CAACV,OAAO,EAAE;QACpD;IACF,CAAA"}
1
+ {"version":3,"sources":["../../../../src/TracingGanttChart/GanttTable/GanttTableRow.tsx"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Stack, styled, useTheme } from '@mui/material';\nimport { memo } from 'react';\nimport { Viewport, rowHeight } from '../utils';\nimport { CustomLinks, TracingGanttChartOptions } from '../../gantt-chart-model';\nimport { Span } from '../trace';\nimport { SpanName } from './SpanName';\nimport { SpanDuration } from './SpanDuration';\n\ninterface GanttTableRowProps {\n options: TracingGanttChartOptions;\n customLinks?: CustomLinks;\n span: Span;\n viewport: Viewport;\n selected?: boolean;\n nameColumnWidth: number;\n divider: React.ReactNode;\n onClick: (span: Span) => void;\n}\n\nexport const GanttTableRow = memo(function GanttTableRow(props: GanttTableRowProps) {\n const { options, customLinks, span, viewport, selected, nameColumnWidth, divider, onClick } = props;\n const theme = useTheme();\n\n const handleOnClick = (): void => {\n // ignore event if triggered by selecting text\n if (document.getSelection()?.type === 'Range') return;\n\n onClick(span);\n };\n\n return (\n <RowContainer\n sx={{ backgroundColor: selected ? theme.palette.action.selected : 'inherit' }}\n direction=\"row\"\n onClick={handleOnClick}\n >\n <SpanName customLinks={customLinks} span={span} nameColumnWidth={nameColumnWidth} />\n {divider}\n <SpanDuration options={options} span={span} viewport={viewport} />\n </RowContainer>\n );\n});\n\nconst RowContainer = styled(Stack)(({ theme }) => ({\n height: rowHeight,\n '&:hover': {\n backgroundColor: theme.palette.action.hover,\n borderTop: `1px solid ${theme.palette.divider}`,\n borderBottom: `1px solid ${theme.palette.divider}`,\n },\n}));\n"],"names":["Stack","styled","useTheme","memo","rowHeight","SpanName","SpanDuration","GanttTableRow","props","options","customLinks","span","viewport","selected","nameColumnWidth","divider","onClick","theme","handleOnClick","document","getSelection","type","RowContainer","sx","backgroundColor","palette","action","direction","height","hover","borderTop","borderBottom"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,KAAK,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,gBAAgB;AACxD,SAASC,IAAI,QAAQ,QAAQ;AAC7B,SAAmBC,SAAS,QAAQ,WAAW;AAG/C,SAASC,QAAQ,QAAQ,aAAa;AACtC,SAASC,YAAY,QAAQ,iBAAiB;AAa9C,OAAO,MAAMC,8BAAgBJ,KAAK,SAASI,cAAcC,KAAyB;IAChF,MAAM,EAAEC,OAAO,EAAEC,WAAW,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,eAAe,EAAEC,OAAO,EAAEC,OAAO,EAAE,GAAGR;IAC9F,MAAMS,QAAQf;IAEd,MAAMgB,gBAAgB;QACpB,8CAA8C;QAC9C,IAAIC,SAASC,YAAY,IAAIC,SAAS,SAAS;QAE/CL,QAAQL;IACV;IAEA,qBACE,MAACW;QACCC,IAAI;YAAEC,iBAAiBX,WAAWI,MAAMQ,OAAO,CAACC,MAAM,CAACb,QAAQ,GAAG;QAAU;QAC5Ec,WAAU;QACVX,SAASE;;0BAET,KAACb;gBAASK,aAAaA;gBAAaC,MAAMA;gBAAMG,iBAAiBA;;YAChEC;0BACD,KAACT;gBAAaG,SAASA;gBAASE,MAAMA;gBAAMC,UAAUA;;;;AAG5D,GAAG;AAEH,MAAMU,eAAerB,OAAOD,OAAO,CAAC,EAAEiB,KAAK,EAAE,GAAM,CAAA;QACjDW,QAAQxB;QACR,WAAW;YACToB,iBAAiBP,MAAMQ,OAAO,CAACC,MAAM,CAACG,KAAK;YAC3CC,WAAW,CAAC,UAAU,EAAEb,MAAMQ,OAAO,CAACV,OAAO,EAAE;YAC/CgB,cAAc,CAAC,UAAU,EAAEd,MAAMQ,OAAO,CAACV,OAAO,EAAE;QACpD;IACF,CAAA"}
@@ -0,0 +1,8 @@
1
+ import { Span } from '../trace';
2
+ import { CustomLinks } from '../../gantt-chart-model';
3
+ export interface SpanLinksButtonProps {
4
+ customLinks: CustomLinks;
5
+ span: Span;
6
+ }
7
+ export declare function SpanLinksButton(props: SpanLinksButtonProps): import("react/jsx-runtime").JSX.Element | undefined;
8
+ //# sourceMappingURL=SpanLinksButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpanLinksButton.d.ts","sourceRoot":"","sources":["../../../../src/TracingGanttChart/GanttTable/SpanLinksButton.tsx"],"names":[],"mappings":"AAkBA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,WAAW,CAAC;IACzB,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,uDA6E1D"}
@@ -0,0 +1,95 @@
1
+ // Copyright 2025 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
14
+ import { IconButton, Menu, MenuItem } from '@mui/material';
15
+ import { useState } from 'react';
16
+ import LaunchIcon from 'mdi-material-ui/Launch';
17
+ import { InfoTooltip } from '@perses-dev/components';
18
+ import { replaceVariablesInString, useAllVariableValues, useRouterContext } from '@perses-dev/plugin-system';
19
+ export function SpanLinksButton(props) {
20
+ const { customLinks, span } = props;
21
+ const variableValues = useAllVariableValues();
22
+ const { RouterComponent } = useRouterContext();
23
+ const [anchorEl, setAnchorEl] = useState(null);
24
+ const isOpen = Boolean(anchorEl);
25
+ if (!RouterComponent || !customLinks.links.span) {
26
+ return;
27
+ }
28
+ // if there is a single span link, render the button directly without a menu
29
+ if (span.links.length == 1 && span.links[0]) {
30
+ const link = span.links[0];
31
+ return /*#__PURE__*/ _jsx(InfoTooltip, {
32
+ description: "open linked span",
33
+ children: /*#__PURE__*/ _jsx(IconButton, {
34
+ size: "small",
35
+ component: RouterComponent,
36
+ to: replaceVariablesInString(customLinks.links.span, variableValues, {
37
+ ...customLinks.variables,
38
+ traceId: link.traceId,
39
+ spanId: link.spanId
40
+ }),
41
+ children: /*#__PURE__*/ _jsx(LaunchIcon, {
42
+ fontSize: "inherit"
43
+ })
44
+ })
45
+ });
46
+ }
47
+ const handleOpenMenu = (event)=>{
48
+ // do not propagate onClick event to the table row (otherwise, the detail pane would open)
49
+ event.stopPropagation();
50
+ setAnchorEl(event.currentTarget);
51
+ };
52
+ const handleClose = (event)=>{
53
+ // Closing the menu, i.e. clicking on the fullscreen transparent MUI backdrop element, does trigger a click on the table row (which opens the detail pane).
54
+ // Therefore, stop propagating this event
55
+ event.stopPropagation();
56
+ setAnchorEl(null);
57
+ };
58
+ return /*#__PURE__*/ _jsxs(_Fragment, {
59
+ children: [
60
+ /*#__PURE__*/ _jsx(InfoTooltip, {
61
+ description: `${span.links.length} linked spans`,
62
+ children: /*#__PURE__*/ _jsx(IconButton, {
63
+ "aria-label": "span links",
64
+ "aria-haspopup": "true",
65
+ "aria-expanded": isOpen ? 'true' : undefined,
66
+ size: "small",
67
+ onClick: handleOpenMenu,
68
+ children: /*#__PURE__*/ _jsx(LaunchIcon, {
69
+ fontSize: "inherit"
70
+ })
71
+ })
72
+ }),
73
+ /*#__PURE__*/ _jsx(Menu, {
74
+ anchorEl: anchorEl,
75
+ open: isOpen,
76
+ onClose: handleClose,
77
+ children: span.links.map((link)=>/*#__PURE__*/ _jsxs(MenuItem, {
78
+ component: RouterComponent,
79
+ onClick: handleClose,
80
+ to: replaceVariablesInString(customLinks.links.span, variableValues, {
81
+ ...customLinks.variables,
82
+ traceId: link.traceId,
83
+ spanId: link.spanId
84
+ }),
85
+ children: [
86
+ "Open linked span ",
87
+ link.spanId
88
+ ]
89
+ }, link.spanId))
90
+ })
91
+ ]
92
+ });
93
+ }
94
+
95
+ //# sourceMappingURL=SpanLinksButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/TracingGanttChart/GanttTable/SpanLinksButton.tsx"],"sourcesContent":["// Copyright 2025 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { IconButton, Menu, MenuItem } from '@mui/material';\nimport { MouseEvent, useState } from 'react';\nimport LaunchIcon from 'mdi-material-ui/Launch';\nimport { InfoTooltip } from '@perses-dev/components';\nimport { replaceVariablesInString, useAllVariableValues, useRouterContext } from '@perses-dev/plugin-system';\nimport { Span } from '../trace';\nimport { CustomLinks } from '../../gantt-chart-model';\n\nexport interface SpanLinksButtonProps {\n customLinks: CustomLinks;\n span: Span;\n}\n\nexport function SpanLinksButton(props: SpanLinksButtonProps) {\n const { customLinks, span } = props;\n const variableValues = useAllVariableValues();\n const { RouterComponent } = useRouterContext();\n const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);\n const isOpen = Boolean(anchorEl);\n\n if (!RouterComponent || !customLinks.links.span) {\n return;\n }\n\n // if there is a single span link, render the button directly without a menu\n if (span.links.length == 1 && span.links[0]) {\n const link = span.links[0];\n return (\n <InfoTooltip description=\"open linked span\">\n <IconButton\n size=\"small\"\n component={RouterComponent}\n to={replaceVariablesInString(customLinks.links.span, variableValues, {\n ...customLinks.variables,\n traceId: link.traceId,\n spanId: link.spanId,\n })}\n >\n <LaunchIcon fontSize=\"inherit\" />\n </IconButton>\n </InfoTooltip>\n );\n }\n\n const handleOpenMenu = (event: MouseEvent<HTMLButtonElement>) => {\n // do not propagate onClick event to the table row (otherwise, the detail pane would open)\n event.stopPropagation();\n\n setAnchorEl(event.currentTarget);\n };\n\n const handleClose = (event: MouseEvent) => {\n // Closing the menu, i.e. clicking on the fullscreen transparent MUI backdrop element, does trigger a click on the table row (which opens the detail pane).\n // Therefore, stop propagating this event\n event.stopPropagation();\n\n setAnchorEl(null);\n };\n\n return (\n <>\n <InfoTooltip description={`${span.links.length} linked spans`}>\n <IconButton\n aria-label=\"span links\"\n aria-haspopup=\"true\"\n aria-expanded={isOpen ? 'true' : undefined}\n size=\"small\"\n onClick={handleOpenMenu}\n >\n <LaunchIcon fontSize=\"inherit\" />\n </IconButton>\n </InfoTooltip>\n <Menu anchorEl={anchorEl} open={isOpen} onClose={handleClose}>\n {span.links.map((link) => (\n <MenuItem\n key={link.spanId}\n component={RouterComponent}\n onClick={handleClose}\n to={replaceVariablesInString(customLinks.links.span!, variableValues, {\n ...customLinks.variables,\n traceId: link.traceId,\n spanId: link.spanId,\n })}\n >\n Open linked span {link.spanId}\n </MenuItem>\n ))}\n </Menu>\n </>\n );\n}\n"],"names":["IconButton","Menu","MenuItem","useState","LaunchIcon","InfoTooltip","replaceVariablesInString","useAllVariableValues","useRouterContext","SpanLinksButton","props","customLinks","span","variableValues","RouterComponent","anchorEl","setAnchorEl","isOpen","Boolean","links","length","link","description","size","component","to","variables","traceId","spanId","fontSize","handleOpenMenu","event","stopPropagation","currentTarget","handleClose","aria-label","aria-haspopup","aria-expanded","undefined","onClick","open","onClose","map"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,UAAU,EAAEC,IAAI,EAAEC,QAAQ,QAAQ,gBAAgB;AAC3D,SAAqBC,QAAQ,QAAQ,QAAQ;AAC7C,OAAOC,gBAAgB,yBAAyB;AAChD,SAASC,WAAW,QAAQ,yBAAyB;AACrD,SAASC,wBAAwB,EAAEC,oBAAoB,EAAEC,gBAAgB,QAAQ,4BAA4B;AAS7G,OAAO,SAASC,gBAAgBC,KAA2B;IACzD,MAAM,EAAEC,WAAW,EAAEC,IAAI,EAAE,GAAGF;IAC9B,MAAMG,iBAAiBN;IACvB,MAAM,EAAEO,eAAe,EAAE,GAAGN;IAC5B,MAAM,CAACO,UAAUC,YAAY,GAAGb,SAA6B;IAC7D,MAAMc,SAASC,QAAQH;IAEvB,IAAI,CAACD,mBAAmB,CAACH,YAAYQ,KAAK,CAACP,IAAI,EAAE;QAC/C;IACF;IAEA,4EAA4E;IAC5E,IAAIA,KAAKO,KAAK,CAACC,MAAM,IAAI,KAAKR,KAAKO,KAAK,CAAC,EAAE,EAAE;QAC3C,MAAME,OAAOT,KAAKO,KAAK,CAAC,EAAE;QAC1B,qBACE,KAACd;YAAYiB,aAAY;sBACvB,cAAA,KAACtB;gBACCuB,MAAK;gBACLC,WAAWV;gBACXW,IAAInB,yBAAyBK,YAAYQ,KAAK,CAACP,IAAI,EAAEC,gBAAgB;oBACnE,GAAGF,YAAYe,SAAS;oBACxBC,SAASN,KAAKM,OAAO;oBACrBC,QAAQP,KAAKO,MAAM;gBACrB;0BAEA,cAAA,KAACxB;oBAAWyB,UAAS;;;;IAI7B;IAEA,MAAMC,iBAAiB,CAACC;QACtB,0FAA0F;QAC1FA,MAAMC,eAAe;QAErBhB,YAAYe,MAAME,aAAa;IACjC;IAEA,MAAMC,cAAc,CAACH;QACnB,2JAA2J;QAC3J,yCAAyC;QACzCA,MAAMC,eAAe;QAErBhB,YAAY;IACd;IAEA,qBACE;;0BACE,KAACX;gBAAYiB,aAAa,GAAGV,KAAKO,KAAK,CAACC,MAAM,CAAC,aAAa,CAAC;0BAC3D,cAAA,KAACpB;oBACCmC,cAAW;oBACXC,iBAAc;oBACdC,iBAAepB,SAAS,SAASqB;oBACjCf,MAAK;oBACLgB,SAAST;8BAET,cAAA,KAAC1B;wBAAWyB,UAAS;;;;0BAGzB,KAAC5B;gBAAKc,UAAUA;gBAAUyB,MAAMvB;gBAAQwB,SAASP;0BAC9CtB,KAAKO,KAAK,CAACuB,GAAG,CAAC,CAACrB,qBACf,MAACnB;wBAECsB,WAAWV;wBACXyB,SAASL;wBACTT,IAAInB,yBAAyBK,YAAYQ,KAAK,CAACP,IAAI,EAAGC,gBAAgB;4BACpE,GAAGF,YAAYe,SAAS;4BACxBC,SAASN,KAAKM,OAAO;4BACrBC,QAAQP,KAAKO,MAAM;wBACrB;;4BACD;4BACmBP,KAAKO,MAAM;;uBATxBP,KAAKO,MAAM;;;;AAe5B"}
@@ -1,6 +1,8 @@
1
1
  import { ReactElement } from 'react';
2
2
  import { Span } from '../trace';
3
+ import { CustomLinks } from '../../gantt-chart-model';
3
4
  export interface SpanNameProps {
5
+ customLinks?: CustomLinks;
4
6
  span: Span;
5
7
  nameColumnWidth: number;
6
8
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SpanName.d.ts","sourceRoot":"","sources":["../../../../src/TracingGanttChart/GanttTable/SpanName.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAErC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGhC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,IAAI,CAAC;IACX,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,YAAY,CAY3D"}
1
+ {"version":3,"file":"SpanName.d.ts","sourceRoot":"","sources":["../../../../src/TracingGanttChart/GanttTable/SpanName.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAErC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAItD,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,EAAE,IAAI,CAAC;IACX,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,YAAY,CAiB3D"}
@@ -15,10 +15,11 @@ import { Box, Stack } from '@mui/material';
15
15
  import AlertIcon from 'mdi-material-ui/AlertCircleOutline';
16
16
  import { spanHasError } from '../utils';
17
17
  import { SpanIndents } from './SpanIndents';
18
+ import { SpanLinksButton } from './SpanLinksButton';
18
19
  /**
19
20
  * SpanName renders the entire left column of a SpanRow, i.e. the hierarchy and the service and span name
20
21
  */ export function SpanName(props) {
21
- const { span, nameColumnWidth } = props;
22
+ const { customLinks, span, nameColumnWidth } = props;
22
23
  return /*#__PURE__*/ _jsxs(Stack, {
23
24
  direction: "row",
24
25
  sx: {
@@ -53,6 +54,16 @@ import { SpanIndents } from './SpanIndents';
53
54
  " ",
54
55
  span.name
55
56
  ]
57
+ }),
58
+ customLinks && customLinks.links.span && span.links.length > 0 && /*#__PURE__*/ _jsx(Box, {
59
+ sx: {
60
+ marginLeft: 'auto',
61
+ px: 1
62
+ },
63
+ children: /*#__PURE__*/ _jsx(SpanLinksButton, {
64
+ customLinks: customLinks,
65
+ span: span
66
+ })
56
67
  })
57
68
  ]
58
69
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/TracingGanttChart/GanttTable/SpanName.tsx"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, Stack } from '@mui/material';\nimport AlertIcon from 'mdi-material-ui/AlertCircleOutline';\nimport { ReactElement } from 'react';\nimport { spanHasError } from '../utils';\nimport { Span } from '../trace';\nimport { SpanIndents } from './SpanIndents';\n\nexport interface SpanNameProps {\n span: Span;\n nameColumnWidth: number;\n}\n\n/**\n * SpanName renders the entire left column of a SpanRow, i.e. the hierarchy and the service and span name\n */\nexport function SpanName(props: SpanNameProps): ReactElement {\n const { span, nameColumnWidth } = props;\n\n return (\n <Stack direction=\"row\" sx={{ alignItems: 'center' }} style={{ width: `${nameColumnWidth * 100}%` }}>\n <SpanIndents span={span} />\n {spanHasError(span) && <AlertIcon titleAccess=\"error\" color=\"error\" sx={{ marginRight: '5px' }} />}\n <Box sx={{ whiteSpace: 'nowrap', overflow: 'hidden' }}>\n <strong>{span.resource.serviceName}:</strong> {span.name}\n </Box>\n </Stack>\n );\n}\n"],"names":["Box","Stack","AlertIcon","spanHasError","SpanIndents","SpanName","props","span","nameColumnWidth","direction","sx","alignItems","style","width","titleAccess","color","marginRight","whiteSpace","overflow","strong","resource","serviceName","name"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,GAAG,EAAEC,KAAK,QAAQ,gBAAgB;AAC3C,OAAOC,eAAe,qCAAqC;AAE3D,SAASC,YAAY,QAAQ,WAAW;AAExC,SAASC,WAAW,QAAQ,gBAAgB;AAO5C;;CAEC,GACD,OAAO,SAASC,SAASC,KAAoB;IAC3C,MAAM,EAAEC,IAAI,EAAEC,eAAe,EAAE,GAAGF;IAElC,qBACE,MAACL;QAAMQ,WAAU;QAAMC,IAAI;YAAEC,YAAY;QAAS;QAAGC,OAAO;YAAEC,OAAO,GAAGL,kBAAkB,IAAI,CAAC,CAAC;QAAC;;0BAC/F,KAACJ;gBAAYG,MAAMA;;YAClBJ,aAAaI,uBAAS,KAACL;gBAAUY,aAAY;gBAAQC,OAAM;gBAAQL,IAAI;oBAAEM,aAAa;gBAAM;;0BAC7F,MAAChB;gBAAIU,IAAI;oBAAEO,YAAY;oBAAUC,UAAU;gBAAS;;kCAClD,MAACC;;4BAAQZ,KAAKa,QAAQ,CAACC,WAAW;4BAAC;;;oBAAU;oBAAEd,KAAKe,IAAI;;;;;AAIhE"}
1
+ {"version":3,"sources":["../../../../src/TracingGanttChart/GanttTable/SpanName.tsx"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, Stack } from '@mui/material';\nimport AlertIcon from 'mdi-material-ui/AlertCircleOutline';\nimport { ReactElement } from 'react';\nimport { spanHasError } from '../utils';\nimport { Span } from '../trace';\nimport { CustomLinks } from '../../gantt-chart-model';\nimport { SpanIndents } from './SpanIndents';\nimport { SpanLinksButton } from './SpanLinksButton';\n\nexport interface SpanNameProps {\n customLinks?: CustomLinks;\n span: Span;\n nameColumnWidth: number;\n}\n\n/**\n * SpanName renders the entire left column of a SpanRow, i.e. the hierarchy and the service and span name\n */\nexport function SpanName(props: SpanNameProps): ReactElement {\n const { customLinks, span, nameColumnWidth } = props;\n\n return (\n <Stack direction=\"row\" sx={{ alignItems: 'center' }} style={{ width: `${nameColumnWidth * 100}%` }}>\n <SpanIndents span={span} />\n {spanHasError(span) && <AlertIcon titleAccess=\"error\" color=\"error\" sx={{ marginRight: '5px' }} />}\n <Box sx={{ whiteSpace: 'nowrap', overflow: 'hidden' }}>\n <strong>{span.resource.serviceName}:</strong> {span.name}\n </Box>\n {customLinks && customLinks.links.span && span.links.length > 0 && (\n <Box sx={{ marginLeft: 'auto', px: 1 }}>\n <SpanLinksButton customLinks={customLinks} span={span} />\n </Box>\n )}\n </Stack>\n );\n}\n"],"names":["Box","Stack","AlertIcon","spanHasError","SpanIndents","SpanLinksButton","SpanName","props","customLinks","span","nameColumnWidth","direction","sx","alignItems","style","width","titleAccess","color","marginRight","whiteSpace","overflow","strong","resource","serviceName","name","links","length","marginLeft","px"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,GAAG,EAAEC,KAAK,QAAQ,gBAAgB;AAC3C,OAAOC,eAAe,qCAAqC;AAE3D,SAASC,YAAY,QAAQ,WAAW;AAGxC,SAASC,WAAW,QAAQ,gBAAgB;AAC5C,SAASC,eAAe,QAAQ,oBAAoB;AAQpD;;CAEC,GACD,OAAO,SAASC,SAASC,KAAoB;IAC3C,MAAM,EAAEC,WAAW,EAAEC,IAAI,EAAEC,eAAe,EAAE,GAAGH;IAE/C,qBACE,MAACN;QAAMU,WAAU;QAAMC,IAAI;YAAEC,YAAY;QAAS;QAAGC,OAAO;YAAEC,OAAO,GAAGL,kBAAkB,IAAI,CAAC,CAAC;QAAC;;0BAC/F,KAACN;gBAAYK,MAAMA;;YAClBN,aAAaM,uBAAS,KAACP;gBAAUc,aAAY;gBAAQC,OAAM;gBAAQL,IAAI;oBAAEM,aAAa;gBAAM;;0BAC7F,MAAClB;gBAAIY,IAAI;oBAAEO,YAAY;oBAAUC,UAAU;gBAAS;;kCAClD,MAACC;;4BAAQZ,KAAKa,QAAQ,CAACC,WAAW;4BAAC;;;oBAAU;oBAAEd,KAAKe,IAAI;;;YAEzDhB,eAAeA,YAAYiB,KAAK,CAAChB,IAAI,IAAIA,KAAKgB,KAAK,CAACC,MAAM,GAAG,mBAC5D,KAAC1B;gBAAIY,IAAI;oBAAEe,YAAY;oBAAQC,IAAI;gBAAE;0BACnC,cAAA,KAACvB;oBAAgBG,aAAaA;oBAAaC,MAAMA;;;;;AAK3D"}
@@ -1 +1 @@
1
- {"version":3,"file":"draw.d.ts","sourceRoot":"","sources":["../../../../src/TracingGanttChart/MiniGanttChart/draw.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAcvC,wBAAgB,SAAS,CACvB,GAAG,EAAE,wBAAwB,EAC7B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EACZ,kBAAkB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,GACzC,IAAI,CAiCN"}
1
+ {"version":3,"file":"draw.d.ts","sourceRoot":"","sources":["../../../../src/TracingGanttChart/MiniGanttChart/draw.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAMvC,wBAAgB,SAAS,CACvB,GAAG,EAAE,wBAAwB,EAC7B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EACZ,kBAAkB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,GACzC,IAAI,CAiCN"}
@@ -13,16 +13,9 @@
13
13
  import { minSpanWidthPx } from '../utils';
14
14
  const MIN_BAR_HEIGHT = 1;
15
15
  const MAX_BAR_HEIGHT = 7;
16
- function countSpans(span) {
17
- let n = 1;
18
- for (const childSpan of span.childSpans){
19
- n += countSpans(childSpan);
20
- }
21
- return n;
22
- }
23
16
  export function drawSpans(ctx, width, height, trace, spanColorGenerator) {
24
17
  // calculate optimal height, enforce min and max bar height and finally round to an integer
25
- const numSpans = trace.rootSpans.map(countSpans).reduce((acc, n)=>acc + n, 0);
18
+ const numSpans = trace.spanById.size;
26
19
  const barHeight = Math.round(Math.min(Math.max(height / numSpans, MIN_BAR_HEIGHT), MAX_BAR_HEIGHT));
27
20
  const traceDuration = trace.endTimeUnixMs - trace.startTimeUnixMs;
28
21
  const yChange = height / numSpans;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/TracingGanttChart/MiniGanttChart/draw.ts"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Span, Trace } from '../trace';\nimport { minSpanWidthPx } from '../utils';\n\nconst MIN_BAR_HEIGHT = 1;\nconst MAX_BAR_HEIGHT = 7;\n\nfunction countSpans(span: Span): number {\n let n = 1;\n for (const childSpan of span.childSpans) {\n n += countSpans(childSpan);\n }\n return n;\n}\n\nexport function drawSpans(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n trace: Trace,\n spanColorGenerator: (span: Span) => string\n): void {\n // calculate optimal height, enforce min and max bar height and finally round to an integer\n const numSpans = trace.rootSpans.map(countSpans).reduce((acc, n) => acc + n, 0);\n const barHeight = Math.round(Math.min(Math.max(height / numSpans, MIN_BAR_HEIGHT), MAX_BAR_HEIGHT));\n\n const traceDuration = trace.endTimeUnixMs - trace.startTimeUnixMs;\n const yChange = height / numSpans;\n let y = 0;\n\n const drawSpan = (span: Span): void => {\n const spanDuration = span.endTimeUnixMs - span.startTimeUnixMs;\n const relativeDuration = spanDuration / traceDuration;\n const relativeStart = (span.startTimeUnixMs - trace.startTimeUnixMs) / traceDuration;\n\n ctx.fillStyle = spanColorGenerator(span);\n ctx.beginPath();\n ctx.rect(\n Math.round(relativeStart * width),\n Math.round(y),\n Math.max(minSpanWidthPx, Math.round(relativeDuration * width)),\n barHeight\n );\n ctx.fill();\n y += yChange;\n\n for (const childSpan of span.childSpans) {\n drawSpan(childSpan);\n }\n };\n\n for (const rootSpan of trace.rootSpans) {\n drawSpan(rootSpan);\n }\n}\n"],"names":["minSpanWidthPx","MIN_BAR_HEIGHT","MAX_BAR_HEIGHT","countSpans","span","n","childSpan","childSpans","drawSpans","ctx","width","height","trace","spanColorGenerator","numSpans","rootSpans","map","reduce","acc","barHeight","Math","round","min","max","traceDuration","endTimeUnixMs","startTimeUnixMs","yChange","y","drawSpan","spanDuration","relativeDuration","relativeStart","fillStyle","beginPath","rect","fill","rootSpan"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAGjC,SAASA,cAAc,QAAQ,WAAW;AAE1C,MAAMC,iBAAiB;AACvB,MAAMC,iBAAiB;AAEvB,SAASC,WAAWC,IAAU;IAC5B,IAAIC,IAAI;IACR,KAAK,MAAMC,aAAaF,KAAKG,UAAU,CAAE;QACvCF,KAAKF,WAAWG;IAClB;IACA,OAAOD;AACT;AAEA,OAAO,SAASG,UACdC,GAA6B,EAC7BC,KAAa,EACbC,MAAc,EACdC,KAAY,EACZC,kBAA0C;IAE1C,2FAA2F;IAC3F,MAAMC,WAAWF,MAAMG,SAAS,CAACC,GAAG,CAACb,YAAYc,MAAM,CAAC,CAACC,KAAKb,IAAMa,MAAMb,GAAG;IAC7E,MAAMc,YAAYC,KAAKC,KAAK,CAACD,KAAKE,GAAG,CAACF,KAAKG,GAAG,CAACZ,SAASG,UAAUb,iBAAiBC;IAEnF,MAAMsB,gBAAgBZ,MAAMa,aAAa,GAAGb,MAAMc,eAAe;IACjE,MAAMC,UAAUhB,SAASG;IACzB,IAAIc,IAAI;IAER,MAAMC,WAAW,CAACzB;QAChB,MAAM0B,eAAe1B,KAAKqB,aAAa,GAAGrB,KAAKsB,eAAe;QAC9D,MAAMK,mBAAmBD,eAAeN;QACxC,MAAMQ,gBAAgB,AAAC5B,CAAAA,KAAKsB,eAAe,GAAGd,MAAMc,eAAe,AAAD,IAAKF;QAEvEf,IAAIwB,SAAS,GAAGpB,mBAAmBT;QACnCK,IAAIyB,SAAS;QACbzB,IAAI0B,IAAI,CACNf,KAAKC,KAAK,CAACW,gBAAgBtB,QAC3BU,KAAKC,KAAK,CAACO,IACXR,KAAKG,GAAG,CAACvB,gBAAgBoB,KAAKC,KAAK,CAACU,mBAAmBrB,SACvDS;QAEFV,IAAI2B,IAAI;QACRR,KAAKD;QAEL,KAAK,MAAMrB,aAAaF,KAAKG,UAAU,CAAE;YACvCsB,SAASvB;QACX;IACF;IAEA,KAAK,MAAM+B,YAAYzB,MAAMG,SAAS,CAAE;QACtCc,SAASQ;IACX;AACF"}
1
+ {"version":3,"sources":["../../../../src/TracingGanttChart/MiniGanttChart/draw.ts"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Span, Trace } from '../trace';\nimport { minSpanWidthPx } from '../utils';\n\nconst MIN_BAR_HEIGHT = 1;\nconst MAX_BAR_HEIGHT = 7;\n\nexport function drawSpans(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n trace: Trace,\n spanColorGenerator: (span: Span) => string\n): void {\n // calculate optimal height, enforce min and max bar height and finally round to an integer\n const numSpans = trace.spanById.size;\n const barHeight = Math.round(Math.min(Math.max(height / numSpans, MIN_BAR_HEIGHT), MAX_BAR_HEIGHT));\n\n const traceDuration = trace.endTimeUnixMs - trace.startTimeUnixMs;\n const yChange = height / numSpans;\n let y = 0;\n\n const drawSpan = (span: Span): void => {\n const spanDuration = span.endTimeUnixMs - span.startTimeUnixMs;\n const relativeDuration = spanDuration / traceDuration;\n const relativeStart = (span.startTimeUnixMs - trace.startTimeUnixMs) / traceDuration;\n\n ctx.fillStyle = spanColorGenerator(span);\n ctx.beginPath();\n ctx.rect(\n Math.round(relativeStart * width),\n Math.round(y),\n Math.max(minSpanWidthPx, Math.round(relativeDuration * width)),\n barHeight\n );\n ctx.fill();\n y += yChange;\n\n for (const childSpan of span.childSpans) {\n drawSpan(childSpan);\n }\n };\n\n for (const rootSpan of trace.rootSpans) {\n drawSpan(rootSpan);\n }\n}\n"],"names":["minSpanWidthPx","MIN_BAR_HEIGHT","MAX_BAR_HEIGHT","drawSpans","ctx","width","height","trace","spanColorGenerator","numSpans","spanById","size","barHeight","Math","round","min","max","traceDuration","endTimeUnixMs","startTimeUnixMs","yChange","y","drawSpan","span","spanDuration","relativeDuration","relativeStart","fillStyle","beginPath","rect","fill","childSpan","childSpans","rootSpan","rootSpans"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAGjC,SAASA,cAAc,QAAQ,WAAW;AAE1C,MAAMC,iBAAiB;AACvB,MAAMC,iBAAiB;AAEvB,OAAO,SAASC,UACdC,GAA6B,EAC7BC,KAAa,EACbC,MAAc,EACdC,KAAY,EACZC,kBAA0C;IAE1C,2FAA2F;IAC3F,MAAMC,WAAWF,MAAMG,QAAQ,CAACC,IAAI;IACpC,MAAMC,YAAYC,KAAKC,KAAK,CAACD,KAAKE,GAAG,CAACF,KAAKG,GAAG,CAACV,SAASG,UAAUR,iBAAiBC;IAEnF,MAAMe,gBAAgBV,MAAMW,aAAa,GAAGX,MAAMY,eAAe;IACjE,MAAMC,UAAUd,SAASG;IACzB,IAAIY,IAAI;IAER,MAAMC,WAAW,CAACC;QAChB,MAAMC,eAAeD,KAAKL,aAAa,GAAGK,KAAKJ,eAAe;QAC9D,MAAMM,mBAAmBD,eAAeP;QACxC,MAAMS,gBAAgB,AAACH,CAAAA,KAAKJ,eAAe,GAAGZ,MAAMY,eAAe,AAAD,IAAKF;QAEvEb,IAAIuB,SAAS,GAAGnB,mBAAmBe;QACnCnB,IAAIwB,SAAS;QACbxB,IAAIyB,IAAI,CACNhB,KAAKC,KAAK,CAACY,gBAAgBrB,QAC3BQ,KAAKC,KAAK,CAACO,IACXR,KAAKG,GAAG,CAAChB,gBAAgBa,KAAKC,KAAK,CAACW,mBAAmBpB,SACvDO;QAEFR,IAAI0B,IAAI;QACRT,KAAKD;QAEL,KAAK,MAAMW,aAAaR,KAAKS,UAAU,CAAE;YACvCV,SAASS;QACX;IACF;IAEA,KAAK,MAAME,YAAY1B,MAAM2B,SAAS,CAAE;QACtCZ,SAASW;IACX;AACF"}
@@ -0,0 +1,7 @@
1
+ import { ReactElement } from 'react';
2
+ import { Trace } from './trace';
3
+ export interface TraceDetailsProps {
4
+ trace: Trace;
5
+ }
6
+ export declare function TraceDetails(props: TraceDetailsProps): ReactElement;
7
+ //# sourceMappingURL=TraceDetails.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TraceDetails.d.ts","sourceRoot":"","sources":["../../../src/TracingGanttChart/TraceDetails.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAGrC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAahC,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,KAAK,CAAC;CACd;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CA2BnE"}
@@ -0,0 +1,90 @@
1
+ // Copyright 2025 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
+ import { Stack, Typography } from '@mui/material';
15
+ import { useTimeZone } from '@perses-dev/components';
16
+ import { formatDuration } from './utils';
17
+ const DATE_FORMAT_OPTIONS = {
18
+ year: 'numeric',
19
+ month: 'long',
20
+ day: 'numeric',
21
+ hour: 'numeric',
22
+ minute: 'numeric',
23
+ second: 'numeric',
24
+ fractionalSecondDigits: 3,
25
+ timeZoneName: 'short'
26
+ };
27
+ export function TraceDetails(props) {
28
+ const { trace } = props;
29
+ const { dateFormatOptionsWithUserTimeZone } = useTimeZone();
30
+ const dateFormatOptions = dateFormatOptionsWithUserTimeZone(DATE_FORMAT_OPTIONS);
31
+ const dateFormatter = new Intl.DateTimeFormat(undefined, dateFormatOptions);
32
+ const rootSpan = trace.rootSpans[0];
33
+ if (!rootSpan) {
34
+ return /*#__PURE__*/ _jsx(Typography, {
35
+ children: "Trace contains no spans."
36
+ });
37
+ }
38
+ return /*#__PURE__*/ _jsxs(Stack, {
39
+ direction: "row",
40
+ sx: {
41
+ justifyContent: 'space-between'
42
+ },
43
+ children: [
44
+ /*#__PURE__*/ _jsxs(Typography, {
45
+ variant: "h3",
46
+ children: [
47
+ rootSpan.resource.serviceName,
48
+ ": ",
49
+ rootSpan.name,
50
+ " (",
51
+ formatDuration(trace.endTimeUnixMs - trace.startTimeUnixMs),
52
+ ")"
53
+ ]
54
+ }),
55
+ /*#__PURE__*/ _jsxs(Typography, {
56
+ variant: "h4",
57
+ children: [
58
+ /*#__PURE__*/ _jsxs(Typography, {
59
+ component: "span",
60
+ sx: {
61
+ px: 1
62
+ },
63
+ children: [
64
+ /*#__PURE__*/ _jsx("strong", {
65
+ children: "Start:"
66
+ }),
67
+ " ",
68
+ dateFormatter.format(trace.startTimeUnixMs)
69
+ ]
70
+ }),
71
+ /*#__PURE__*/ _jsxs(Typography, {
72
+ component: "span",
73
+ sx: {
74
+ px: 1
75
+ },
76
+ children: [
77
+ /*#__PURE__*/ _jsx("strong", {
78
+ children: "Trace ID:"
79
+ }),
80
+ " ",
81
+ rootSpan.traceId
82
+ ]
83
+ })
84
+ ]
85
+ })
86
+ ]
87
+ });
88
+ }
89
+
90
+ //# sourceMappingURL=TraceDetails.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/TracingGanttChart/TraceDetails.tsx"],"sourcesContent":["// Copyright 2025 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Stack, Typography } from '@mui/material';\nimport { ReactElement } from 'react';\nimport { useTimeZone } from '@perses-dev/components';\nimport { formatDuration } from './utils';\nimport { Trace } from './trace';\n\nconst DATE_FORMAT_OPTIONS: Intl.DateTimeFormatOptions = {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n second: 'numeric',\n fractionalSecondDigits: 3,\n timeZoneName: 'short',\n};\n\nexport interface TraceDetailsProps {\n trace: Trace;\n}\n\nexport function TraceDetails(props: TraceDetailsProps): ReactElement {\n const { trace } = props;\n\n const { dateFormatOptionsWithUserTimeZone } = useTimeZone();\n const dateFormatOptions = dateFormatOptionsWithUserTimeZone(DATE_FORMAT_OPTIONS);\n const dateFormatter = new Intl.DateTimeFormat(undefined, dateFormatOptions);\n\n const rootSpan = trace.rootSpans[0];\n if (!rootSpan) {\n return <Typography>Trace contains no spans.</Typography>;\n }\n\n return (\n <Stack direction=\"row\" sx={{ justifyContent: 'space-between' }}>\n <Typography variant=\"h3\">\n {rootSpan.resource.serviceName}: {rootSpan.name} ({formatDuration(trace.endTimeUnixMs - trace.startTimeUnixMs)})\n </Typography>\n <Typography variant=\"h4\">\n <Typography component=\"span\" sx={{ px: 1 }}>\n <strong>Start:</strong> {dateFormatter.format(trace.startTimeUnixMs)}\n </Typography>\n <Typography component=\"span\" sx={{ px: 1 }}>\n <strong>Trace ID:</strong> {rootSpan.traceId}\n </Typography>\n </Typography>\n </Stack>\n );\n}\n"],"names":["Stack","Typography","useTimeZone","formatDuration","DATE_FORMAT_OPTIONS","year","month","day","hour","minute","second","fractionalSecondDigits","timeZoneName","TraceDetails","props","trace","dateFormatOptionsWithUserTimeZone","dateFormatOptions","dateFormatter","Intl","DateTimeFormat","undefined","rootSpan","rootSpans","direction","sx","justifyContent","variant","resource","serviceName","name","endTimeUnixMs","startTimeUnixMs","component","px","strong","format","traceId"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,KAAK,EAAEC,UAAU,QAAQ,gBAAgB;AAElD,SAASC,WAAW,QAAQ,yBAAyB;AACrD,SAASC,cAAc,QAAQ,UAAU;AAGzC,MAAMC,sBAAkD;IACtDC,MAAM;IACNC,OAAO;IACPC,KAAK;IACLC,MAAM;IACNC,QAAQ;IACRC,QAAQ;IACRC,wBAAwB;IACxBC,cAAc;AAChB;AAMA,OAAO,SAASC,aAAaC,KAAwB;IACnD,MAAM,EAAEC,KAAK,EAAE,GAAGD;IAElB,MAAM,EAAEE,iCAAiC,EAAE,GAAGd;IAC9C,MAAMe,oBAAoBD,kCAAkCZ;IAC5D,MAAMc,gBAAgB,IAAIC,KAAKC,cAAc,CAACC,WAAWJ;IAEzD,MAAMK,WAAWP,MAAMQ,SAAS,CAAC,EAAE;IACnC,IAAI,CAACD,UAAU;QACb,qBAAO,KAACrB;sBAAW;;IACrB;IAEA,qBACE,MAACD;QAAMwB,WAAU;QAAMC,IAAI;YAAEC,gBAAgB;QAAgB;;0BAC3D,MAACzB;gBAAW0B,SAAQ;;oBACjBL,SAASM,QAAQ,CAACC,WAAW;oBAAC;oBAAGP,SAASQ,IAAI;oBAAC;oBAAG3B,eAAeY,MAAMgB,aAAa,GAAGhB,MAAMiB,eAAe;oBAAE;;;0BAEjH,MAAC/B;gBAAW0B,SAAQ;;kCAClB,MAAC1B;wBAAWgC,WAAU;wBAAOR,IAAI;4BAAES,IAAI;wBAAE;;0CACvC,KAACC;0CAAO;;4BAAe;4BAAEjB,cAAckB,MAAM,CAACrB,MAAMiB,eAAe;;;kCAErE,MAAC/B;wBAAWgC,WAAU;wBAAOR,IAAI;4BAAES,IAAI;wBAAE;;0CACvC,KAACC;0CAAO;;4BAAkB;4BAAEb,SAASe,OAAO;;;;;;;AAKtD"}
@@ -1,10 +1,9 @@
1
1
  import { ReactElement } from 'react';
2
2
  import { otlptracev1 } from '@perses-dev/core';
3
- import { TracingGanttChartOptions } from '../gantt-chart-model';
4
- import { AttributeLinks } from './DetailPane/Attributes';
3
+ import { CustomLinks, TracingGanttChartOptions } from '../gantt-chart-model';
5
4
  export interface TracingGanttChartProps {
6
5
  options: TracingGanttChartOptions;
7
- attributeLinks?: AttributeLinks;
6
+ customLinks?: CustomLinks;
8
7
  trace: otlptracev1.TracesData;
9
8
  }
10
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"TracingGanttChart.d.ts","sourceRoot":"","sources":["../../../src/TracingGanttChart/TracingGanttChart.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAA6B,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAOhE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGzD,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,wBAAwB,CAAC;IAClC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,KAAK,EAAE,WAAW,CAAC,UAAU,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,YAAY,CAoD7E"}
1
+ {"version":3,"file":"TracingGanttChart.d.ts","sourceRoot":"","sources":["../../../src/TracingGanttChart/TracingGanttChart.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAA6B,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAU7E,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,wBAAwB,CAAC;IAClC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,EAAE,WAAW,CAAC,UAAU,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,YAAY,CAwD7E"}
@@ -19,13 +19,14 @@ import { GanttTable } from './GanttTable/GanttTable';
19
19
  import { GanttTableProvider } from './GanttTable/GanttTableProvider';
20
20
  import { ResizableDivider } from './GanttTable/ResizableDivider';
21
21
  import { getTraceModel } from './trace';
22
+ import { TraceDetails } from './TraceDetails';
22
23
  /**
23
24
  * The core GanttChart panel for Perses.
24
25
  *
25
26
  * The UI/UX of this panel is based on Jaeger UI, licensed under Apache License, Version 2.0.
26
27
  * https://github.com/jaegertracing/jaeger-ui
27
28
  */ export function TracingGanttChart(props) {
28
- const { options, attributeLinks, trace: otlpTrace } = props;
29
+ const { options, customLinks, trace: otlpTrace } = props;
29
30
  const theme = useTheme();
30
31
  const trace = useMemo(()=>{
31
32
  try {
@@ -40,7 +41,7 @@ import { getTraceModel } from './trace';
40
41
  startTimeUnixMs: trace.startTimeUnixMs,
41
42
  endTimeUnixMs: trace.endTimeUnixMs
42
43
  });
43
- const [selectedSpan, setSelectedSpan] = useState(undefined);
44
+ const [selectedSpan, setSelectedSpan] = useState(()=>options.selectedSpanId ? trace.spanById.get(options.selectedSpanId) : undefined);
44
45
  const ganttChart = useRef(null);
45
46
  // tableWidth only comes to effect if the detail pane is visible.
46
47
  // setTableWidth() is only called by <ResizableDivider />
@@ -61,6 +62,9 @@ import { getTraceModel } from './trace';
61
62
  gap
62
63
  },
63
64
  children: [
65
+ /*#__PURE__*/ _jsx(TraceDetails, {
66
+ trace: trace
67
+ }),
64
68
  /*#__PURE__*/ _jsx(MiniGanttChart, {
65
69
  options: options,
66
70
  trace: trace,
@@ -70,6 +74,7 @@ import { getTraceModel } from './trace';
70
74
  /*#__PURE__*/ _jsx(GanttTableProvider, {
71
75
  children: /*#__PURE__*/ _jsx(GanttTable, {
72
76
  options: options,
77
+ customLinks: customLinks,
73
78
  trace: trace,
74
79
  viewport: viewport,
75
80
  selectedSpan: selectedSpan,
@@ -91,7 +96,7 @@ import { getTraceModel } from './trace';
91
96
  overflow: 'auto'
92
97
  },
93
98
  children: /*#__PURE__*/ _jsx(DetailPane, {
94
- attributeLinks: attributeLinks,
99
+ customLinks: customLinks,
95
100
  trace: trace,
96
101
  span: selectedSpan,
97
102
  onCloseBtnClick: ()=>setSelectedSpan(undefined)
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/TracingGanttChart/TracingGanttChart.tsx"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ReactElement, useMemo, useRef, useState } from 'react';\nimport { Box, Stack, useTheme } from '@mui/material';\nimport { otlptracev1 } from '@perses-dev/core';\nimport { TracingGanttChartOptions } from '../gantt-chart-model';\nimport { MiniGanttChart } from './MiniGanttChart/MiniGanttChart';\nimport { DetailPane } from './DetailPane/DetailPane';\nimport { Viewport } from './utils';\nimport { GanttTable } from './GanttTable/GanttTable';\nimport { GanttTableProvider } from './GanttTable/GanttTableProvider';\nimport { ResizableDivider } from './GanttTable/ResizableDivider';\nimport { AttributeLinks } from './DetailPane/Attributes';\nimport { getTraceModel, Span } from './trace';\n\nexport interface TracingGanttChartProps {\n options: TracingGanttChartOptions;\n attributeLinks?: AttributeLinks;\n trace: otlptracev1.TracesData;\n}\n\n/**\n * The core GanttChart panel for Perses.\n *\n * The UI/UX of this panel is based on Jaeger UI, licensed under Apache License, Version 2.0.\n * https://github.com/jaegertracing/jaeger-ui\n */\nexport function TracingGanttChart(props: TracingGanttChartProps): ReactElement {\n const { options, attributeLinks, trace: otlpTrace } = props;\n\n const theme = useTheme();\n const trace = useMemo(() => {\n try {\n return getTraceModel(otlpTrace);\n } catch (e) {\n throw new Error(`Error: unable to parse trace: ${e}`);\n }\n }, [otlpTrace]);\n const [viewport, setViewport] = useState<Viewport>({\n startTimeUnixMs: trace.startTimeUnixMs,\n endTimeUnixMs: trace.endTimeUnixMs,\n });\n const [selectedSpan, setSelectedSpan] = useState<Span | undefined>(undefined);\n\n const ganttChart = useRef<HTMLDivElement>(null);\n // tableWidth only comes to effect if the detail pane is visible.\n // setTableWidth() is only called by <ResizableDivider />\n const [tableWidth, setTableWidth] = useState<number>(0.82);\n const gap = 2;\n\n return (\n <Stack ref={ganttChart} direction=\"row\" sx={{ height: '100%', minHeight: '240px', gap }}>\n <Stack sx={{ flexGrow: 1, gap }}>\n <MiniGanttChart options={options} trace={trace} viewport={viewport} setViewport={setViewport} />\n <GanttTableProvider>\n <GanttTable\n options={options}\n trace={trace}\n viewport={viewport}\n selectedSpan={selectedSpan}\n onSpanClick={setSelectedSpan}\n />\n </GanttTableProvider>\n </Stack>\n {selectedSpan && (\n <>\n <ResizableDivider parentRef={ganttChart} spacing={parseInt(theme.spacing(gap))} onMove={setTableWidth} />\n <Box sx={{ width: `${(1 - tableWidth) * 100}%`, overflow: 'auto' }}>\n <DetailPane\n attributeLinks={attributeLinks}\n trace={trace}\n span={selectedSpan}\n onCloseBtnClick={() => setSelectedSpan(undefined)}\n />\n </Box>\n </>\n )}\n </Stack>\n );\n}\n"],"names":["useMemo","useRef","useState","Box","Stack","useTheme","MiniGanttChart","DetailPane","GanttTable","GanttTableProvider","ResizableDivider","getTraceModel","TracingGanttChart","props","options","attributeLinks","trace","otlpTrace","theme","e","Error","viewport","setViewport","startTimeUnixMs","endTimeUnixMs","selectedSpan","setSelectedSpan","undefined","ganttChart","tableWidth","setTableWidth","gap","ref","direction","sx","height","minHeight","flexGrow","onSpanClick","parentRef","spacing","parseInt","onMove","width","overflow","span","onCloseBtnClick"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAAuBA,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AAChE,SAASC,GAAG,EAAEC,KAAK,EAAEC,QAAQ,QAAQ,gBAAgB;AAGrD,SAASC,cAAc,QAAQ,kCAAkC;AACjE,SAASC,UAAU,QAAQ,0BAA0B;AAErD,SAASC,UAAU,QAAQ,0BAA0B;AACrD,SAASC,kBAAkB,QAAQ,kCAAkC;AACrE,SAASC,gBAAgB,QAAQ,gCAAgC;AAEjE,SAASC,aAAa,QAAc,UAAU;AAQ9C;;;;;CAKC,GACD,OAAO,SAASC,kBAAkBC,KAA6B;IAC7D,MAAM,EAAEC,OAAO,EAAEC,cAAc,EAAEC,OAAOC,SAAS,EAAE,GAAGJ;IAEtD,MAAMK,QAAQb;IACd,MAAMW,QAAQhB,QAAQ;QACpB,IAAI;YACF,OAAOW,cAAcM;QACvB,EAAE,OAAOE,GAAG;YACV,MAAM,IAAIC,MAAM,CAAC,8BAA8B,EAAED,GAAG;QACtD;IACF,GAAG;QAACF;KAAU;IACd,MAAM,CAACI,UAAUC,YAAY,GAAGpB,SAAmB;QACjDqB,iBAAiBP,MAAMO,eAAe;QACtCC,eAAeR,MAAMQ,aAAa;IACpC;IACA,MAAM,CAACC,cAAcC,gBAAgB,GAAGxB,SAA2ByB;IAEnE,MAAMC,aAAa3B,OAAuB;IAC1C,iEAAiE;IACjE,yDAAyD;IACzD,MAAM,CAAC4B,YAAYC,cAAc,GAAG5B,SAAiB;IACrD,MAAM6B,MAAM;IAEZ,qBACE,MAAC3B;QAAM4B,KAAKJ;QAAYK,WAAU;QAAMC,IAAI;YAAEC,QAAQ;YAAQC,WAAW;YAASL;QAAI;;0BACpF,MAAC3B;gBAAM8B,IAAI;oBAAEG,UAAU;oBAAGN;gBAAI;;kCAC5B,KAACzB;wBAAeQ,SAASA;wBAASE,OAAOA;wBAAOK,UAAUA;wBAAUC,aAAaA;;kCACjF,KAACb;kCACC,cAAA,KAACD;4BACCM,SAASA;4BACTE,OAAOA;4BACPK,UAAUA;4BACVI,cAAcA;4BACda,aAAaZ;;;;;YAIlBD,8BACC;;kCACE,KAACf;wBAAiB6B,WAAWX;wBAAYY,SAASC,SAASvB,MAAMsB,OAAO,CAACT;wBAAOW,QAAQZ;;kCACxF,KAAC3B;wBAAI+B,IAAI;4BAAES,OAAO,GAAG,AAAC,CAAA,IAAId,UAAS,IAAK,IAAI,CAAC,CAAC;4BAAEe,UAAU;wBAAO;kCAC/D,cAAA,KAACrC;4BACCQ,gBAAgBA;4BAChBC,OAAOA;4BACP6B,MAAMpB;4BACNqB,iBAAiB,IAAMpB,gBAAgBC;;;;;;;AAOrD"}
1
+ {"version":3,"sources":["../../../src/TracingGanttChart/TracingGanttChart.tsx"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ReactElement, useMemo, useRef, useState } from 'react';\nimport { Box, Stack, useTheme } from '@mui/material';\nimport { otlptracev1 } from '@perses-dev/core';\nimport { CustomLinks, TracingGanttChartOptions } from '../gantt-chart-model';\nimport { MiniGanttChart } from './MiniGanttChart/MiniGanttChart';\nimport { DetailPane } from './DetailPane/DetailPane';\nimport { Viewport } from './utils';\nimport { GanttTable } from './GanttTable/GanttTable';\nimport { GanttTableProvider } from './GanttTable/GanttTableProvider';\nimport { ResizableDivider } from './GanttTable/ResizableDivider';\nimport { getTraceModel, Span } from './trace';\nimport { TraceDetails } from './TraceDetails';\n\nexport interface TracingGanttChartProps {\n options: TracingGanttChartOptions;\n customLinks?: CustomLinks;\n trace: otlptracev1.TracesData;\n}\n\n/**\n * The core GanttChart panel for Perses.\n *\n * The UI/UX of this panel is based on Jaeger UI, licensed under Apache License, Version 2.0.\n * https://github.com/jaegertracing/jaeger-ui\n */\nexport function TracingGanttChart(props: TracingGanttChartProps): ReactElement {\n const { options, customLinks, trace: otlpTrace } = props;\n\n const theme = useTheme();\n const trace = useMemo(() => {\n try {\n return getTraceModel(otlpTrace);\n } catch (e) {\n throw new Error(`Error: unable to parse trace: ${e}`);\n }\n }, [otlpTrace]);\n const [viewport, setViewport] = useState<Viewport>({\n startTimeUnixMs: trace.startTimeUnixMs,\n endTimeUnixMs: trace.endTimeUnixMs,\n });\n const [selectedSpan, setSelectedSpan] = useState<Span | undefined>(() =>\n options.selectedSpanId ? trace.spanById.get(options.selectedSpanId) : undefined\n );\n\n const ganttChart = useRef<HTMLDivElement>(null);\n // tableWidth only comes to effect if the detail pane is visible.\n // setTableWidth() is only called by <ResizableDivider />\n const [tableWidth, setTableWidth] = useState<number>(0.82);\n const gap = 2;\n\n return (\n <Stack ref={ganttChart} direction=\"row\" sx={{ height: '100%', minHeight: '240px', gap }}>\n <Stack sx={{ flexGrow: 1, gap }}>\n <TraceDetails trace={trace} />\n <MiniGanttChart options={options} trace={trace} viewport={viewport} setViewport={setViewport} />\n <GanttTableProvider>\n <GanttTable\n options={options}\n customLinks={customLinks}\n trace={trace}\n viewport={viewport}\n selectedSpan={selectedSpan}\n onSpanClick={setSelectedSpan}\n />\n </GanttTableProvider>\n </Stack>\n {selectedSpan && (\n <>\n <ResizableDivider parentRef={ganttChart} spacing={parseInt(theme.spacing(gap))} onMove={setTableWidth} />\n <Box sx={{ width: `${(1 - tableWidth) * 100}%`, overflow: 'auto' }}>\n <DetailPane\n customLinks={customLinks}\n trace={trace}\n span={selectedSpan}\n onCloseBtnClick={() => setSelectedSpan(undefined)}\n />\n </Box>\n </>\n )}\n </Stack>\n );\n}\n"],"names":["useMemo","useRef","useState","Box","Stack","useTheme","MiniGanttChart","DetailPane","GanttTable","GanttTableProvider","ResizableDivider","getTraceModel","TraceDetails","TracingGanttChart","props","options","customLinks","trace","otlpTrace","theme","e","Error","viewport","setViewport","startTimeUnixMs","endTimeUnixMs","selectedSpan","setSelectedSpan","selectedSpanId","spanById","get","undefined","ganttChart","tableWidth","setTableWidth","gap","ref","direction","sx","height","minHeight","flexGrow","onSpanClick","parentRef","spacing","parseInt","onMove","width","overflow","span","onCloseBtnClick"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAAuBA,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AAChE,SAASC,GAAG,EAAEC,KAAK,EAAEC,QAAQ,QAAQ,gBAAgB;AAGrD,SAASC,cAAc,QAAQ,kCAAkC;AACjE,SAASC,UAAU,QAAQ,0BAA0B;AAErD,SAASC,UAAU,QAAQ,0BAA0B;AACrD,SAASC,kBAAkB,QAAQ,kCAAkC;AACrE,SAASC,gBAAgB,QAAQ,gCAAgC;AACjE,SAASC,aAAa,QAAc,UAAU;AAC9C,SAASC,YAAY,QAAQ,iBAAiB;AAQ9C;;;;;CAKC,GACD,OAAO,SAASC,kBAAkBC,KAA6B;IAC7D,MAAM,EAAEC,OAAO,EAAEC,WAAW,EAAEC,OAAOC,SAAS,EAAE,GAAGJ;IAEnD,MAAMK,QAAQd;IACd,MAAMY,QAAQjB,QAAQ;QACpB,IAAI;YACF,OAAOW,cAAcO;QACvB,EAAE,OAAOE,GAAG;YACV,MAAM,IAAIC,MAAM,CAAC,8BAA8B,EAAED,GAAG;QACtD;IACF,GAAG;QAACF;KAAU;IACd,MAAM,CAACI,UAAUC,YAAY,GAAGrB,SAAmB;QACjDsB,iBAAiBP,MAAMO,eAAe;QACtCC,eAAeR,MAAMQ,aAAa;IACpC;IACA,MAAM,CAACC,cAAcC,gBAAgB,GAAGzB,SAA2B,IACjEa,QAAQa,cAAc,GAAGX,MAAMY,QAAQ,CAACC,GAAG,CAACf,QAAQa,cAAc,IAAIG;IAGxE,MAAMC,aAAa/B,OAAuB;IAC1C,iEAAiE;IACjE,yDAAyD;IACzD,MAAM,CAACgC,YAAYC,cAAc,GAAGhC,SAAiB;IACrD,MAAMiC,MAAM;IAEZ,qBACE,MAAC/B;QAAMgC,KAAKJ;QAAYK,WAAU;QAAMC,IAAI;YAAEC,QAAQ;YAAQC,WAAW;YAASL;QAAI;;0BACpF,MAAC/B;gBAAMkC,IAAI;oBAAEG,UAAU;oBAAGN;gBAAI;;kCAC5B,KAACvB;wBAAaK,OAAOA;;kCACrB,KAACX;wBAAeS,SAASA;wBAASE,OAAOA;wBAAOK,UAAUA;wBAAUC,aAAaA;;kCACjF,KAACd;kCACC,cAAA,KAACD;4BACCO,SAASA;4BACTC,aAAaA;4BACbC,OAAOA;4BACPK,UAAUA;4BACVI,cAAcA;4BACdgB,aAAaf;;;;;YAIlBD,8BACC;;kCACE,KAAChB;wBAAiBiC,WAAWX;wBAAYY,SAASC,SAAS1B,MAAMyB,OAAO,CAACT;wBAAOW,QAAQZ;;kCACxF,KAAC/B;wBAAImC,IAAI;4BAAES,OAAO,GAAG,AAAC,CAAA,IAAId,UAAS,IAAK,IAAI,CAAC,CAAC;4BAAEe,UAAU;wBAAO;kCAC/D,cAAA,KAACzC;4BACCS,aAAaA;4BACbC,OAAOA;4BACPgC,MAAMvB;4BACNwB,iBAAiB,IAAMvB,gBAAgBI;;;;;;;AAOrD"}