@perses-dev/tracing-gantt-chart-plugin 0.8.0 → 0.9.1

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 (137) hide show
  1. package/__mf/css/async/263.6c6463ea.css +1 -0
  2. package/__mf/js/TracingGanttChart.3a1782e8.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.20959198.js +1 -0
  34. package/__mf/js/async/lib-router.ab6beae3.js +2 -0
  35. package/__mf/js/main.4e6f9520.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 +15 -3
  41. package/lib/TracingGanttChart/DetailPane/Attributes.d.ts.map +1 -1
  42. package/lib/TracingGanttChart/DetailPane/Attributes.js +51 -18
  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 +17 -3
  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/TracingGanttChart.d.ts +2 -3
  76. package/lib/TracingGanttChart/TracingGanttChart.d.ts.map +1 -1
  77. package/lib/TracingGanttChart/TracingGanttChart.js +4 -3
  78. package/lib/TracingGanttChart/TracingGanttChart.js.map +1 -1
  79. package/lib/TracingGanttChart/trace.d.ts +7 -0
  80. package/lib/TracingGanttChart/trace.d.ts.map +1 -1
  81. package/lib/TracingGanttChart/trace.js +13 -4
  82. package/lib/TracingGanttChart/trace.js.map +1 -1
  83. package/lib/TracingGanttChart.d.ts.map +1 -1
  84. package/lib/TracingGanttChart.js +7 -1
  85. package/lib/TracingGanttChart.js.map +1 -1
  86. package/lib/TracingGanttChartPanel.d.ts +1 -11
  87. package/lib/TracingGanttChartPanel.d.ts.map +1 -1
  88. package/lib/TracingGanttChartPanel.js +10 -2
  89. package/lib/TracingGanttChartPanel.js.map +1 -1
  90. package/lib/cjs/PanelActions.js +88 -0
  91. package/lib/cjs/TracingGanttChart/DetailPane/Attributes.js +56 -17
  92. package/lib/cjs/TracingGanttChart/DetailPane/DetailPane.js +17 -3
  93. package/lib/cjs/TracingGanttChart/DetailPane/SpanEvents.js +66 -20
  94. package/lib/cjs/TracingGanttChart/DetailPane/SpanLinks.js +72 -0
  95. package/lib/cjs/TracingGanttChart/GanttTable/GanttTable.js +15 -1
  96. package/lib/cjs/TracingGanttChart/GanttTable/GanttTableRow.js +2 -1
  97. package/lib/cjs/TracingGanttChart/GanttTable/SpanLinksButton.js +108 -0
  98. package/lib/cjs/TracingGanttChart/GanttTable/SpanName.js +12 -1
  99. package/lib/cjs/TracingGanttChart/MiniGanttChart/draw.js +1 -8
  100. package/lib/cjs/TracingGanttChart/TracingGanttChart.js +4 -3
  101. package/lib/cjs/TracingGanttChart/trace.js +13 -4
  102. package/lib/cjs/TracingGanttChart.js +7 -1
  103. package/lib/cjs/TracingGanttChartPanel.js +10 -2
  104. package/lib/cjs/gantt-chart-model.js +1 -1
  105. package/lib/gantt-chart-model.d.ts +31 -0
  106. package/lib/gantt-chart-model.d.ts.map +1 -1
  107. package/lib/gantt-chart-model.js +1 -1
  108. package/lib/gantt-chart-model.js.map +1 -1
  109. package/mf-manifest.json +86 -66
  110. package/mf-stats.json +100 -74
  111. package/package.json +7 -5
  112. package/__mf/js/788.5684e3ab.js +0 -5
  113. package/__mf/js/TracingGanttChart.77b94eb3.js +0 -5
  114. package/__mf/js/async/156.5a401ecb.js +0 -1
  115. package/__mf/js/async/173.6314a363.js +0 -2
  116. package/__mf/js/async/193.12ce9ab1.js +0 -44
  117. package/__mf/js/async/193.12ce9ab1.js.LICENSE.txt +0 -68
  118. package/__mf/js/async/377.59c252c4.js +0 -2
  119. package/__mf/js/async/511.b81ea373.js +0 -1
  120. package/__mf/js/async/620.1d1ce390.js +0 -2
  121. package/__mf/js/async/651.3ea371e5.js +0 -1
  122. package/__mf/js/async/694.4580ad20.js +0 -1
  123. package/__mf/js/async/740.babbb403.js +0 -1
  124. package/__mf/js/async/75.d81e6bbf.js +0 -1
  125. package/__mf/js/async/783.3c2c57f6.js +0 -110
  126. package/__mf/js/async/960.478a8f11.js +0 -2
  127. package/__mf/js/async/964.a98cab40.js +0 -2
  128. package/__mf/js/async/981.bc5132f8.js +0 -2
  129. package/__mf/js/async/__federation_expose_TracingGanttChart.7b5aeb33.js +0 -1
  130. package/__mf/js/main.9fe8ed9b.js +0 -1
  131. /package/__mf/js/async/{173.6314a363.js.LICENSE.txt → 173.66fc423e.js.LICENSE.txt} +0 -0
  132. /package/__mf/js/async/{783.3c2c57f6.js.LICENSE.txt → 533.f20b93c0.js.LICENSE.txt} +0 -0
  133. /package/__mf/js/async/{620.1d1ce390.js.LICENSE.txt → 863.0e6501cd.js.LICENSE.txt} +0 -0
  134. /package/__mf/js/async/{960.478a8f11.js.LICENSE.txt → 960.89291786.js.LICENSE.txt} +0 -0
  135. /package/__mf/js/async/{964.a98cab40.js.LICENSE.txt → 964.3f12c3f5.js.LICENSE.txt} +0 -0
  136. /package/__mf/js/async/{981.bc5132f8.js.LICENSE.txt → 981.1c640ffc.js.LICENSE.txt} +0 -0
  137. /package/__mf/js/async/{377.59c252c4.js.LICENSE.txt → lib-router.ab6beae3.js.LICENSE.txt} +0 -0
@@ -13,10 +13,10 @@
13
13
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
14
14
  import { useMemo } from 'react';
15
15
  import { Divider, Link, List, ListItem, ListItemText } from '@mui/material';
16
- import { Link as RouterLink } from 'react-router-dom';
16
+ import { replaceVariablesInString, useAllVariableValues, useRouterContext } from '@perses-dev/plugin-system';
17
17
  import { formatDuration } from '../utils';
18
18
  export function TraceAttributes(props) {
19
- const { trace, span, attributeLinks } = props;
19
+ const { customLinks, trace, span } = props;
20
20
  return /*#__PURE__*/ _jsxs(_Fragment, {
21
21
  children: [
22
22
  /*#__PURE__*/ _jsxs(List, {
@@ -39,44 +39,77 @@ export function TraceAttributes(props) {
39
39
  span.attributes.length > 0 && /*#__PURE__*/ _jsxs(_Fragment, {
40
40
  children: [
41
41
  /*#__PURE__*/ _jsx(AttributeList, {
42
- attributeLinks: attributeLinks,
43
- attributes: span.attributes
42
+ customLinks: customLinks,
43
+ attributes: span.attributes.toSorted((a, b)=>a.key.localeCompare(b.key))
44
44
  }),
45
45
  /*#__PURE__*/ _jsx(Divider, {})
46
46
  ]
47
47
  }),
48
48
  /*#__PURE__*/ _jsx(AttributeList, {
49
- attributeLinks: attributeLinks,
50
- attributes: span.resource.attributes
49
+ customLinks: customLinks,
50
+ attributes: span.resource.attributes.toSorted((a, b)=>a.key.localeCompare(b.key))
51
51
  })
52
52
  ]
53
53
  });
54
54
  }
55
55
  export function AttributeList(props) {
56
- const { attributeLinks, attributes } = props;
57
- const attributesMap = useMemo(()=>Object.fromEntries(attributes.map((attr)=>[
58
- attr.key,
59
- attr.value
60
- ])), [
56
+ const { customLinks, attributes } = props;
57
+ return /*#__PURE__*/ _jsx(List, {
58
+ children: /*#__PURE__*/ _jsx(AttributeItems, {
59
+ customLinks: customLinks,
60
+ attributes: attributes
61
+ })
62
+ });
63
+ }
64
+ export function AttributeItems(props) {
65
+ const { customLinks, attributes } = props;
66
+ const variableValues = useAllVariableValues();
67
+ // turn array into map for fast access
68
+ const attributeLinks = useMemo(()=>{
69
+ const attrs = (customLinks?.links.attributes ?? []).map((a)=>[
70
+ a.name,
71
+ a.link
72
+ ]);
73
+ return Object.fromEntries(attrs);
74
+ }, [
75
+ customLinks
76
+ ]);
77
+ // some links require access to other attributes, for example a pod link "/namespace/${k8s_namespace_name}/pod/${k8s_pod_name}"
78
+ const extraVariables = useMemo(()=>{
79
+ // replace dot with underscore in attribute name, because dot is not allowed in variable names
80
+ const stringAttrs = attributes.map((attr)=>[
81
+ attr.key.replaceAll('.', '_'),
82
+ renderAttributeValue(attr.value)
83
+ ]);
84
+ return {
85
+ ...customLinks?.variables,
86
+ ...Object.fromEntries(stringAttrs)
87
+ };
88
+ }, [
89
+ customLinks,
61
90
  attributes
62
91
  ]);
63
- return /*#__PURE__*/ _jsx(List, {
64
- children: attributes.sort((a, b)=>a.key.localeCompare(b.key)).map((attribute, i)=>/*#__PURE__*/ _jsx(AttributeItem, {
92
+ return /*#__PURE__*/ _jsx(_Fragment, {
93
+ children: attributes.map((attribute, i)=>/*#__PURE__*/ _jsx(AttributeItem, {
65
94
  name: attribute.key,
66
95
  value: renderAttributeValue(attribute.value),
67
- link: attributeLinks?.[attribute.key]?.(attributesMap)
96
+ link: attributeLinks[attribute.key] ? replaceVariablesInString(attributeLinks[attribute.key], variableValues, extraVariables) : undefined
68
97
  }, i))
69
98
  });
70
99
  }
71
- function AttributeItem(props) {
100
+ export function AttributeItem(props) {
72
101
  const { name, value, link } = props;
73
- const valueComponent = link ? /*#__PURE__*/ _jsx(Link, {
74
- component: RouterLink,
102
+ const { RouterComponent } = useRouterContext();
103
+ const valueComponent = RouterComponent && link ? /*#__PURE__*/ _jsx(Link, {
104
+ component: RouterComponent,
75
105
  to: link,
76
106
  children: value
77
107
  }) : value;
78
108
  return /*#__PURE__*/ _jsx(ListItem, {
79
- disablePadding: true,
109
+ sx: {
110
+ px: 1,
111
+ py: 0
112
+ },
80
113
  children: /*#__PURE__*/ _jsx(ListItemText, {
81
114
  primary: name,
82
115
  secondary: valueComponent,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/TracingGanttChart/DetailPane/Attributes.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 } from 'react';\nimport { Divider, Link, List, ListItem, ListItemText } from '@mui/material';\nimport { Link as RouterLink } from 'react-router-dom';\nimport { otlpcommonv1 } from '@perses-dev/core';\nimport { Span, Trace } from '../trace';\nimport { formatDuration } from '../utils';\n\nexport type AttributeLinks = Record<string, (attributes: Record<string, otlpcommonv1.AnyValue>) => string>;\n\nexport interface TraceAttributesProps {\n trace: Trace;\n span: Span;\n attributeLinks?: AttributeLinks;\n}\n\nexport function TraceAttributes(props: TraceAttributesProps) {\n const { trace, span, attributeLinks } = props;\n\n return (\n <>\n <List>\n <AttributeItem name=\"span ID\" value={span.spanId} />\n <AttributeItem name=\"start\" value={formatDuration(span.startTimeUnixMs - trace.startTimeUnixMs)} />\n <AttributeItem name=\"duration\" value={formatDuration(span.endTimeUnixMs - span.startTimeUnixMs)} />\n </List>\n <Divider />\n {span.attributes.length > 0 && (\n <>\n <AttributeList attributeLinks={attributeLinks} attributes={span.attributes} />\n <Divider />\n </>\n )}\n <AttributeList attributeLinks={attributeLinks} attributes={span.resource.attributes} />\n </>\n );\n}\n\nexport interface AttributeListProps {\n attributeLinks?: AttributeLinks;\n attributes: otlpcommonv1.KeyValue[];\n}\n\nexport function AttributeList(props: AttributeListProps): ReactElement {\n const { attributeLinks, attributes } = props;\n const attributesMap = useMemo(\n () => Object.fromEntries(attributes.map((attr) => [attr.key, attr.value])),\n [attributes]\n );\n\n return (\n <List>\n {attributes\n .sort((a, b) => a.key.localeCompare(b.key))\n .map((attribute, i) => (\n <AttributeItem\n key={i}\n name={attribute.key}\n value={renderAttributeValue(attribute.value)}\n link={attributeLinks?.[attribute.key]?.(attributesMap)}\n />\n ))}\n </List>\n );\n}\n\ninterface AttributeItemProps {\n name: string;\n value: string;\n link?: string;\n}\n\nfunction AttributeItem(props: AttributeItemProps): ReactElement {\n const { name, value, link } = props;\n\n const valueComponent = link ? (\n <Link component={RouterLink} to={link}>\n {value}\n </Link>\n ) : (\n value\n );\n\n return (\n <ListItem disablePadding>\n <ListItemText\n primary={name}\n secondary={valueComponent}\n slotProps={{\n primary: { variant: 'h5' },\n secondary: { variant: 'body1', sx: { wordBreak: 'break-word' } },\n }}\n />\n </ListItem>\n );\n}\n\nfunction renderAttributeValue(value: otlpcommonv1.AnyValue): string {\n if ('stringValue' in value) return value.stringValue.length > 0 ? value.stringValue : '<empty string>';\n if ('intValue' in value) return value.intValue;\n if ('boolValue' in value) return value.boolValue.toString();\n if ('arrayValue' in value) return value.arrayValue.values.map(renderAttributeValue).join(', ');\n return 'unknown';\n}\n"],"names":["useMemo","Divider","Link","List","ListItem","ListItemText","RouterLink","formatDuration","TraceAttributes","props","trace","span","attributeLinks","AttributeItem","name","value","spanId","startTimeUnixMs","endTimeUnixMs","attributes","length","AttributeList","resource","attributesMap","Object","fromEntries","map","attr","key","sort","a","b","localeCompare","attribute","i","renderAttributeValue","link","valueComponent","component","to","disablePadding","primary","secondary","slotProps","variant","sx","wordBreak","stringValue","intValue","boolValue","toString","arrayValue","values","join"],"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,QAAQ,QAAQ;AAC9C,SAASC,OAAO,EAAEC,IAAI,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,YAAY,QAAQ,gBAAgB;AAC5E,SAASH,QAAQI,UAAU,QAAQ,mBAAmB;AAGtD,SAASC,cAAc,QAAQ,WAAW;AAU1C,OAAO,SAASC,gBAAgBC,KAA2B;IACzD,MAAM,EAAEC,KAAK,EAAEC,IAAI,EAAEC,cAAc,EAAE,GAAGH;IAExC,qBACE;;0BACE,MAACN;;kCACC,KAACU;wBAAcC,MAAK;wBAAUC,OAAOJ,KAAKK,MAAM;;kCAChD,KAACH;wBAAcC,MAAK;wBAAQC,OAAOR,eAAeI,KAAKM,eAAe,GAAGP,MAAMO,eAAe;;kCAC9F,KAACJ;wBAAcC,MAAK;wBAAWC,OAAOR,eAAeI,KAAKO,aAAa,GAAGP,KAAKM,eAAe;;;;0BAEhG,KAAChB;YACAU,KAAKQ,UAAU,CAACC,MAAM,GAAG,mBACxB;;kCACE,KAACC;wBAAcT,gBAAgBA;wBAAgBO,YAAYR,KAAKQ,UAAU;;kCAC1E,KAAClB;;;0BAGL,KAACoB;gBAAcT,gBAAgBA;gBAAgBO,YAAYR,KAAKW,QAAQ,CAACH,UAAU;;;;AAGzF;AAOA,OAAO,SAASE,cAAcZ,KAAyB;IACrD,MAAM,EAAEG,cAAc,EAAEO,UAAU,EAAE,GAAGV;IACvC,MAAMc,gBAAgBvB,QACpB,IAAMwB,OAAOC,WAAW,CAACN,WAAWO,GAAG,CAAC,CAACC,OAAS;gBAACA,KAAKC,GAAG;gBAAED,KAAKZ,KAAK;aAAC,IACxE;QAACI;KAAW;IAGd,qBACE,KAAChB;kBACEgB,WACEU,IAAI,CAAC,CAACC,GAAGC,IAAMD,EAAEF,GAAG,CAACI,aAAa,CAACD,EAAEH,GAAG,GACxCF,GAAG,CAAC,CAACO,WAAWC,kBACf,KAACrB;gBAECC,MAAMmB,UAAUL,GAAG;gBACnBb,OAAOoB,qBAAqBF,UAAUlB,KAAK;gBAC3CqB,MAAMxB,gBAAgB,CAACqB,UAAUL,GAAG,CAAC,GAAGL;eAHnCW;;AAQjB;AAQA,SAASrB,cAAcJ,KAAyB;IAC9C,MAAM,EAAEK,IAAI,EAAEC,KAAK,EAAEqB,IAAI,EAAE,GAAG3B;IAE9B,MAAM4B,iBAAiBD,qBACrB,KAAClC;QAAKoC,WAAWhC;QAAYiC,IAAIH;kBAC9BrB;SAGHA;IAGF,qBACE,KAACX;QAASoC,cAAc;kBACtB,cAAA,KAACnC;YACCoC,SAAS3B;YACT4B,WAAWL;YACXM,WAAW;gBACTF,SAAS;oBAAEG,SAAS;gBAAK;gBACzBF,WAAW;oBAAEE,SAAS;oBAASC,IAAI;wBAAEC,WAAW;oBAAa;gBAAE;YACjE;;;AAIR;AAEA,SAASX,qBAAqBpB,KAA4B;IACxD,IAAI,iBAAiBA,OAAO,OAAOA,MAAMgC,WAAW,CAAC3B,MAAM,GAAG,IAAIL,MAAMgC,WAAW,GAAG;IACtF,IAAI,cAAchC,OAAO,OAAOA,MAAMiC,QAAQ;IAC9C,IAAI,eAAejC,OAAO,OAAOA,MAAMkC,SAAS,CAACC,QAAQ;IACzD,IAAI,gBAAgBnC,OAAO,OAAOA,MAAMoC,UAAU,CAACC,MAAM,CAAC1B,GAAG,CAACS,sBAAsBkB,IAAI,CAAC;IACzF,OAAO;AACT"}
1
+ {"version":3,"sources":["../../../../src/TracingGanttChart/DetailPane/Attributes.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 } from 'react';\nimport { Divider, Link, List, ListItem, ListItemText } from '@mui/material';\nimport { otlpcommonv1 } from '@perses-dev/core';\nimport { replaceVariablesInString, useAllVariableValues, useRouterContext } from '@perses-dev/plugin-system';\nimport { Span, Trace } from '../trace';\nimport { formatDuration } from '../utils';\nimport { CustomLinks } from '../../gantt-chart-model';\n\nexport interface TraceAttributesProps {\n customLinks?: CustomLinks;\n trace: Trace;\n span: Span;\n}\n\nexport function TraceAttributes(props: TraceAttributesProps) {\n const { customLinks, trace, span } = props;\n\n return (\n <>\n <List>\n <AttributeItem name=\"span ID\" value={span.spanId} />\n <AttributeItem name=\"start\" value={formatDuration(span.startTimeUnixMs - trace.startTimeUnixMs)} />\n <AttributeItem name=\"duration\" value={formatDuration(span.endTimeUnixMs - span.startTimeUnixMs)} />\n </List>\n <Divider />\n {span.attributes.length > 0 && (\n <>\n <AttributeList\n customLinks={customLinks}\n attributes={span.attributes.toSorted((a, b) => a.key.localeCompare(b.key))}\n />\n <Divider />\n </>\n )}\n <AttributeList\n customLinks={customLinks}\n attributes={span.resource.attributes.toSorted((a, b) => a.key.localeCompare(b.key))}\n />\n </>\n );\n}\n\nexport interface AttributeListProps {\n customLinks?: CustomLinks;\n attributes: otlpcommonv1.KeyValue[];\n}\n\nexport function AttributeList(props: AttributeListProps): ReactElement {\n const { customLinks, attributes } = props;\n\n return (\n <List>\n <AttributeItems customLinks={customLinks} attributes={attributes} />\n </List>\n );\n}\n\ninterface AttributeItemsProps {\n customLinks?: CustomLinks;\n attributes: otlpcommonv1.KeyValue[];\n}\n\nexport function AttributeItems(props: AttributeItemsProps): ReactElement {\n const { customLinks, attributes } = props;\n const variableValues = useAllVariableValues();\n\n // turn array into map for fast access\n const attributeLinks = useMemo(() => {\n const attrs = (customLinks?.links.attributes ?? []).map((a) => [a.name, a.link]);\n return Object.fromEntries(attrs);\n }, [customLinks]);\n\n // some links require access to other attributes, for example a pod link \"/namespace/${k8s_namespace_name}/pod/${k8s_pod_name}\"\n const extraVariables = useMemo(() => {\n // replace dot with underscore in attribute name, because dot is not allowed in variable names\n const stringAttrs = attributes.map((attr) => [attr.key.replaceAll('.', '_'), renderAttributeValue(attr.value)]);\n\n return {\n ...customLinks?.variables,\n ...Object.fromEntries(stringAttrs),\n };\n }, [customLinks, attributes]);\n\n return (\n <>\n {attributes.map((attribute, i) => (\n <AttributeItem\n key={i}\n name={attribute.key}\n value={renderAttributeValue(attribute.value)}\n link={\n attributeLinks[attribute.key]\n ? replaceVariablesInString(attributeLinks[attribute.key], variableValues, extraVariables)\n : undefined\n }\n />\n ))}\n </>\n );\n}\n\ninterface AttributeItemProps {\n name: string;\n value: string;\n link?: string;\n}\n\nexport function AttributeItem(props: AttributeItemProps): ReactElement {\n const { name, value, link } = props;\n const { RouterComponent } = useRouterContext();\n\n const valueComponent =\n RouterComponent && link ? (\n <Link component={RouterComponent} to={link}>\n {value}\n </Link>\n ) : (\n value\n );\n\n return (\n <ListItem sx={{ px: 1, py: 0 }}>\n <ListItemText\n primary={name}\n secondary={valueComponent}\n slotProps={{\n primary: { variant: 'h5' },\n secondary: { variant: 'body1', sx: { wordBreak: 'break-word' } },\n }}\n />\n </ListItem>\n );\n}\n\nfunction renderAttributeValue(value: otlpcommonv1.AnyValue): string {\n if ('stringValue' in value) return value.stringValue.length > 0 ? value.stringValue : '<empty string>';\n if ('intValue' in value) return value.intValue;\n if ('boolValue' in value) return value.boolValue.toString();\n if ('arrayValue' in value) return value.arrayValue.values.map(renderAttributeValue).join(', ');\n return 'unknown';\n}\n"],"names":["useMemo","Divider","Link","List","ListItem","ListItemText","replaceVariablesInString","useAllVariableValues","useRouterContext","formatDuration","TraceAttributes","props","customLinks","trace","span","AttributeItem","name","value","spanId","startTimeUnixMs","endTimeUnixMs","attributes","length","AttributeList","toSorted","a","b","key","localeCompare","resource","AttributeItems","variableValues","attributeLinks","attrs","links","map","link","Object","fromEntries","extraVariables","stringAttrs","attr","replaceAll","renderAttributeValue","variables","attribute","i","undefined","RouterComponent","valueComponent","component","to","sx","px","py","primary","secondary","slotProps","variant","wordBreak","stringValue","intValue","boolValue","toString","arrayValue","values","join"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { ReactElement } from 'react';
2
2
  import { Span, Trace } from '../trace';
3
- import { AttributeLinks } from './Attributes';
3
+ import { CustomLinks } from '../../gantt-chart-model';
4
4
  export interface DetailPaneProps {
5
- attributeLinks?: AttributeLinks;
5
+ customLinks?: CustomLinks;
6
6
  trace: Trace;
7
7
  span: Span;
8
8
  onCloseBtnClick: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"DetailPane.d.ts","sourceRoot":"","sources":["../../../../src/TracingGanttChart/DetailPane/DetailPane.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAE,YAAY,EAAY,MAAM,OAAO,CAAC;AAE/C,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,cAAc,EAAmB,MAAM,cAAc,CAAC;AAG/D,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;IACX,eAAe,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,CA6B/D"}
1
+ {"version":3,"file":"DetailPane.d.ts","sourceRoot":"","sources":["../../../../src/TracingGanttChart/DetailPane/DetailPane.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAE,YAAY,EAAY,MAAM,OAAO,CAAC;AAE/C,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAKtD,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;IACX,eAAe,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,CAmC/D"}
@@ -16,16 +16,21 @@ import { useState } from 'react';
16
16
  import CloseIcon from 'mdi-material-ui/Close';
17
17
  import { TraceAttributes } from './Attributes';
18
18
  import { SpanEventList } from './SpanEvents';
19
+ import { SpanLinkList } from './SpanLinks';
19
20
  /**
20
21
  * DetailPane renders a sidebar showing the span attributes etc.
21
22
  */ export function DetailPane(props) {
22
- const { attributeLinks, trace, span, onCloseBtnClick } = props;
23
+ const { customLinks, trace, span, onCloseBtnClick } = props;
23
24
  const [tab, setTab] = useState('attributes');
24
25
  // if the events tab is selected, and then a span without events is clicked,
25
26
  // we need to switch the current selected tab back to the attributes tab.
26
27
  if (tab === 'events' && span.events.length === 0) {
27
28
  setTab('attributes');
28
29
  }
30
+ // same as above, but for span links
31
+ if (tab === 'links' && span.links.length === 0) {
32
+ setTab('attributes');
33
+ }
29
34
  return /*#__PURE__*/ _jsxs(Box, {
30
35
  children: [
31
36
  /*#__PURE__*/ _jsx(IconButton, {
@@ -67,18 +72,27 @@ import { SpanEventList } from './SpanEvents';
67
72
  span.events.length > 0 && /*#__PURE__*/ _jsx(Tab, {
68
73
  value: "events",
69
74
  label: "Events"
75
+ }),
76
+ span.links.length > 0 && /*#__PURE__*/ _jsx(Tab, {
77
+ value: "links",
78
+ label: "Links"
70
79
  })
71
80
  ]
72
81
  })
73
82
  }),
74
83
  tab === 'attributes' && /*#__PURE__*/ _jsx(TraceAttributes, {
84
+ customLinks: customLinks,
75
85
  trace: trace,
76
- span: span,
77
- attributeLinks: attributeLinks
86
+ span: span
78
87
  }),
79
88
  tab === 'events' && /*#__PURE__*/ _jsx(SpanEventList, {
89
+ customLinks: customLinks,
80
90
  trace: trace,
81
91
  span: span
92
+ }),
93
+ tab === 'links' && /*#__PURE__*/ _jsx(SpanLinkList, {
94
+ customLinks: customLinks,
95
+ span: span
82
96
  })
83
97
  ]
84
98
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/TracingGanttChart/DetailPane/DetailPane.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, IconButton, Tab, Tabs, Typography } from '@mui/material';\nimport { ReactElement, useState } from 'react';\nimport CloseIcon from 'mdi-material-ui/Close';\nimport { Span, Trace } from '../trace';\nimport { AttributeLinks, TraceAttributes } from './Attributes';\nimport { SpanEventList } from './SpanEvents';\n\nexport interface DetailPaneProps {\n attributeLinks?: AttributeLinks;\n trace: Trace;\n span: Span;\n onCloseBtnClick: () => void;\n}\n\n/**\n * DetailPane renders a sidebar showing the span attributes etc.\n */\nexport function DetailPane(props: DetailPaneProps): ReactElement {\n const { attributeLinks, trace, span, onCloseBtnClick } = props;\n const [tab, setTab] = useState<'attributes' | 'events'>('attributes');\n\n // if the events tab is selected, and then a span without events is clicked,\n // we need to switch the current selected tab back to the attributes tab.\n if (tab === 'events' && span.events.length === 0) {\n setTab('attributes');\n }\n\n return (\n <Box>\n <IconButton sx={{ float: 'right' }} onClick={onCloseBtnClick}>\n <CloseIcon />\n </IconButton>\n <Typography sx={{ wordBreak: 'break-word' }}>{span.resource.serviceName}</Typography>\n <Typography variant=\"h2\" sx={{ wordBreak: 'break-word' }}>\n {span.name}\n </Typography>\n <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>\n <Tabs value={tab} onChange={(_, tab) => setTab(tab)}>\n <Tab sx={{ p: 0 }} value=\"attributes\" label=\"Attributes\" />\n {span.events.length > 0 && <Tab value=\"events\" label=\"Events\" />}\n </Tabs>\n </Box>\n {tab === 'attributes' && <TraceAttributes trace={trace} span={span} attributeLinks={attributeLinks} />}\n {tab === 'events' && <SpanEventList trace={trace} span={span} />}\n </Box>\n );\n}\n"],"names":["Box","IconButton","Tab","Tabs","Typography","useState","CloseIcon","TraceAttributes","SpanEventList","DetailPane","props","attributeLinks","trace","span","onCloseBtnClick","tab","setTab","events","length","sx","float","onClick","wordBreak","resource","serviceName","variant","name","borderBottom","borderColor","value","onChange","_","p","label"],"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,UAAU,EAAEC,GAAG,EAAEC,IAAI,EAAEC,UAAU,QAAQ,gBAAgB;AACvE,SAAuBC,QAAQ,QAAQ,QAAQ;AAC/C,OAAOC,eAAe,wBAAwB;AAE9C,SAAyBC,eAAe,QAAQ,eAAe;AAC/D,SAASC,aAAa,QAAQ,eAAe;AAS7C;;CAEC,GACD,OAAO,SAASC,WAAWC,KAAsB;IAC/C,MAAM,EAAEC,cAAc,EAAEC,KAAK,EAAEC,IAAI,EAAEC,eAAe,EAAE,GAAGJ;IACzD,MAAM,CAACK,KAAKC,OAAO,GAAGX,SAAkC;IAExD,4EAA4E;IAC5E,yEAAyE;IACzE,IAAIU,QAAQ,YAAYF,KAAKI,MAAM,CAACC,MAAM,KAAK,GAAG;QAChDF,OAAO;IACT;IAEA,qBACE,MAAChB;;0BACC,KAACC;gBAAWkB,IAAI;oBAAEC,OAAO;gBAAQ;gBAAGC,SAASP;0BAC3C,cAAA,KAACR;;0BAEH,KAACF;gBAAWe,IAAI;oBAAEG,WAAW;gBAAa;0BAAIT,KAAKU,QAAQ,CAACC,WAAW;;0BACvE,KAACpB;gBAAWqB,SAAQ;gBAAKN,IAAI;oBAAEG,WAAW;gBAAa;0BACpDT,KAAKa,IAAI;;0BAEZ,KAAC1B;gBAAImB,IAAI;oBAAEQ,cAAc;oBAAGC,aAAa;gBAAU;0BACjD,cAAA,MAACzB;oBAAK0B,OAAOd;oBAAKe,UAAU,CAACC,GAAGhB,MAAQC,OAAOD;;sCAC7C,KAACb;4BAAIiB,IAAI;gCAAEa,GAAG;4BAAE;4BAAGH,OAAM;4BAAaI,OAAM;;wBAC3CpB,KAAKI,MAAM,CAACC,MAAM,GAAG,mBAAK,KAAChB;4BAAI2B,OAAM;4BAASI,OAAM;;;;;YAGxDlB,QAAQ,8BAAgB,KAACR;gBAAgBK,OAAOA;gBAAOC,MAAMA;gBAAMF,gBAAgBA;;YACnFI,QAAQ,0BAAY,KAACP;gBAAcI,OAAOA;gBAAOC,MAAMA;;;;AAG9D"}
1
+ {"version":3,"sources":["../../../../src/TracingGanttChart/DetailPane/DetailPane.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, IconButton, Tab, Tabs, Typography } from '@mui/material';\nimport { ReactElement, useState } from 'react';\nimport CloseIcon from 'mdi-material-ui/Close';\nimport { Span, Trace } from '../trace';\nimport { CustomLinks } from '../../gantt-chart-model';\nimport { TraceAttributes } from './Attributes';\nimport { SpanEventList } from './SpanEvents';\nimport { SpanLinkList } from './SpanLinks';\n\nexport interface DetailPaneProps {\n customLinks?: CustomLinks;\n trace: Trace;\n span: Span;\n onCloseBtnClick: () => void;\n}\n\n/**\n * DetailPane renders a sidebar showing the span attributes etc.\n */\nexport function DetailPane(props: DetailPaneProps): ReactElement {\n const { customLinks, trace, span, onCloseBtnClick } = props;\n const [tab, setTab] = useState<'attributes' | 'events' | 'links'>('attributes');\n\n // if the events tab is selected, and then a span without events is clicked,\n // we need to switch the current selected tab back to the attributes tab.\n if (tab === 'events' && span.events.length === 0) {\n setTab('attributes');\n }\n // same as above, but for span links\n if (tab === 'links' && span.links.length === 0) {\n setTab('attributes');\n }\n\n return (\n <Box>\n <IconButton sx={{ float: 'right' }} onClick={onCloseBtnClick}>\n <CloseIcon />\n </IconButton>\n <Typography sx={{ wordBreak: 'break-word' }}>{span.resource.serviceName}</Typography>\n <Typography variant=\"h2\" sx={{ wordBreak: 'break-word' }}>\n {span.name}\n </Typography>\n <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>\n <Tabs value={tab} onChange={(_, tab) => setTab(tab)}>\n <Tab sx={{ p: 0 }} value=\"attributes\" label=\"Attributes\" />\n {span.events.length > 0 && <Tab value=\"events\" label=\"Events\" />}\n {span.links.length > 0 && <Tab value=\"links\" label=\"Links\" />}\n </Tabs>\n </Box>\n {tab === 'attributes' && <TraceAttributes customLinks={customLinks} trace={trace} span={span} />}\n {tab === 'events' && <SpanEventList customLinks={customLinks} trace={trace} span={span} />}\n {tab === 'links' && <SpanLinkList customLinks={customLinks} span={span} />}\n </Box>\n );\n}\n"],"names":["Box","IconButton","Tab","Tabs","Typography","useState","CloseIcon","TraceAttributes","SpanEventList","SpanLinkList","DetailPane","props","customLinks","trace","span","onCloseBtnClick","tab","setTab","events","length","links","sx","float","onClick","wordBreak","resource","serviceName","variant","name","borderBottom","borderColor","value","onChange","_","p","label"],"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,UAAU,EAAEC,GAAG,EAAEC,IAAI,EAAEC,UAAU,QAAQ,gBAAgB;AACvE,SAAuBC,QAAQ,QAAQ,QAAQ;AAC/C,OAAOC,eAAe,wBAAwB;AAG9C,SAASC,eAAe,QAAQ,eAAe;AAC/C,SAASC,aAAa,QAAQ,eAAe;AAC7C,SAASC,YAAY,QAAQ,cAAc;AAS3C;;CAEC,GACD,OAAO,SAASC,WAAWC,KAAsB;IAC/C,MAAM,EAAEC,WAAW,EAAEC,KAAK,EAAEC,IAAI,EAAEC,eAAe,EAAE,GAAGJ;IACtD,MAAM,CAACK,KAAKC,OAAO,GAAGZ,SAA4C;IAElE,4EAA4E;IAC5E,yEAAyE;IACzE,IAAIW,QAAQ,YAAYF,KAAKI,MAAM,CAACC,MAAM,KAAK,GAAG;QAChDF,OAAO;IACT;IACA,oCAAoC;IACpC,IAAID,QAAQ,WAAWF,KAAKM,KAAK,CAACD,MAAM,KAAK,GAAG;QAC9CF,OAAO;IACT;IAEA,qBACE,MAACjB;;0BACC,KAACC;gBAAWoB,IAAI;oBAAEC,OAAO;gBAAQ;gBAAGC,SAASR;0BAC3C,cAAA,KAACT;;0BAEH,KAACF;gBAAWiB,IAAI;oBAAEG,WAAW;gBAAa;0BAAIV,KAAKW,QAAQ,CAACC,WAAW;;0BACvE,KAACtB;gBAAWuB,SAAQ;gBAAKN,IAAI;oBAAEG,WAAW;gBAAa;0BACpDV,KAAKc,IAAI;;0BAEZ,KAAC5B;gBAAIqB,IAAI;oBAAEQ,cAAc;oBAAGC,aAAa;gBAAU;0BACjD,cAAA,MAAC3B;oBAAK4B,OAAOf;oBAAKgB,UAAU,CAACC,GAAGjB,MAAQC,OAAOD;;sCAC7C,KAACd;4BAAImB,IAAI;gCAAEa,GAAG;4BAAE;4BAAGH,OAAM;4BAAaI,OAAM;;wBAC3CrB,KAAKI,MAAM,CAACC,MAAM,GAAG,mBAAK,KAACjB;4BAAI6B,OAAM;4BAASI,OAAM;;wBACpDrB,KAAKM,KAAK,CAACD,MAAM,GAAG,mBAAK,KAACjB;4BAAI6B,OAAM;4BAAQI,OAAM;;;;;YAGtDnB,QAAQ,8BAAgB,KAACT;gBAAgBK,aAAaA;gBAAaC,OAAOA;gBAAOC,MAAMA;;YACvFE,QAAQ,0BAAY,KAACR;gBAAcI,aAAaA;gBAAaC,OAAOA;gBAAOC,MAAMA;;YACjFE,QAAQ,yBAAW,KAACP;gBAAaG,aAAaA;gBAAaE,MAAMA;;;;AAGxE"}
@@ -1,6 +1,8 @@
1
1
  import { ReactElement } from 'react';
2
2
  import { Trace, Span } from '../trace';
3
+ import { CustomLinks } from '../../gantt-chart-model';
3
4
  export interface SpanEventListProps {
5
+ customLinks?: CustomLinks;
4
6
  trace: Trace;
5
7
  span: Span;
6
8
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SpanEvents.d.ts","sourceRoot":"","sources":["../../../../src/TracingGanttChart/DetailPane/SpanEvents.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAErC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAS,MAAM,UAAU,CAAC;AAG9C,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,YAAY,CAYrE"}
1
+ {"version":3,"file":"SpanEvents.d.ts","sourceRoot":"","sources":["../../../../src/TracingGanttChart/DetailPane/SpanEvents.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAY,YAAY,EAAY,MAAM,OAAO,CAAC;AAIzD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAS,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGtD,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,YAAY,CAerE"}
@@ -11,41 +11,87 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
14
- import { Accordion, AccordionDetails, AccordionSummary, Typography } from '@mui/material';
15
- import ExpandMoreIcon from 'mdi-material-ui/ChevronDown';
14
+ import { Collapse, Divider, List, ListItemButton, ListItemText } from '@mui/material';
15
+ import { Fragment, useState } from 'react';
16
+ import ChevronUp from 'mdi-material-ui/ChevronUp';
17
+ import ChevronDown from 'mdi-material-ui/ChevronDown';
16
18
  import { formatDuration } from '../utils';
17
- import { AttributeList } from './Attributes';
19
+ import { AttributeItems, AttributeItem } from './Attributes';
18
20
  export function SpanEventList(props) {
19
- const { trace, span } = props;
21
+ const { customLinks, trace, span } = props;
20
22
  return /*#__PURE__*/ _jsx(_Fragment, {
21
- children: span.events.sort((a, b)=>a.timeUnixMs - b.timeUnixMs).map((event, i)=>/*#__PURE__*/ _jsx(SpanEventItem, {
22
- trace: trace,
23
- event: event
23
+ children: span.events.sort((a, b)=>a.timeUnixMs - b.timeUnixMs).map((event, i)=>/*#__PURE__*/ _jsxs(Fragment, {
24
+ children: [
25
+ i > 0 && /*#__PURE__*/ _jsx(Divider, {}),
26
+ /*#__PURE__*/ _jsx(SpanEventItem, {
27
+ customLinks: customLinks,
28
+ trace: trace,
29
+ event: event
30
+ })
31
+ ]
24
32
  }, i))
25
33
  });
26
34
  }
27
35
  function SpanEventItem(props) {
28
- const { trace, event } = props;
36
+ const { customLinks, trace, event } = props;
29
37
  const relativeTime = event.timeUnixMs - trace.startTimeUnixMs;
30
- return /*#__PURE__*/ _jsxs(Accordion, {
31
- disableGutters: true,
38
+ const [open, setOpen] = useState(false);
39
+ const handleClick = ()=>{
40
+ setOpen(!open);
41
+ };
42
+ return /*#__PURE__*/ _jsxs(List, {
32
43
  children: [
33
- /*#__PURE__*/ _jsx(AccordionSummary, {
34
- expandIcon: /*#__PURE__*/ _jsx(ExpandMoreIcon, {}),
35
- children: /*#__PURE__*/ _jsx(Typography, {
36
- children: formatDuration(relativeTime)
37
- })
38
- }),
39
- /*#__PURE__*/ _jsxs(AccordionDetails, {
44
+ /*#__PURE__*/ _jsxs(ListItemButton, {
45
+ onClick: handleClick,
46
+ sx: {
47
+ px: 1
48
+ },
40
49
  children: [
41
- /*#__PURE__*/ _jsx(Typography, {
42
- variant: "subtitle1",
43
- children: event.name
50
+ /*#__PURE__*/ _jsx(ListItemText, {
51
+ primary: /*#__PURE__*/ _jsxs(_Fragment, {
52
+ children: [
53
+ /*#__PURE__*/ _jsxs("strong", {
54
+ children: [
55
+ formatDuration(relativeTime),
56
+ ":"
57
+ ]
58
+ }),
59
+ " ",
60
+ event.name
61
+ ]
62
+ }),
63
+ slotProps: {
64
+ primary: {
65
+ noWrap: true
66
+ }
67
+ }
44
68
  }),
45
- /*#__PURE__*/ _jsx(AttributeList, {
46
- attributes: event.attributes
47
- })
69
+ open ? /*#__PURE__*/ _jsx(ChevronUp, {}) : /*#__PURE__*/ _jsx(ChevronDown, {})
48
70
  ]
71
+ }),
72
+ /*#__PURE__*/ _jsx(Collapse, {
73
+ in: open,
74
+ timeout: "auto",
75
+ unmountOnExit: true,
76
+ children: /*#__PURE__*/ _jsxs(List, {
77
+ sx: {
78
+ px: 1
79
+ },
80
+ children: [
81
+ /*#__PURE__*/ _jsx(AttributeItem, {
82
+ name: "name",
83
+ value: event.name
84
+ }),
85
+ /*#__PURE__*/ _jsx(AttributeItem, {
86
+ name: "time",
87
+ value: formatDuration(relativeTime)
88
+ }),
89
+ /*#__PURE__*/ _jsx(AttributeItems, {
90
+ customLinks: customLinks,
91
+ attributes: event.attributes
92
+ })
93
+ ]
94
+ })
49
95
  })
50
96
  ]
51
97
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/TracingGanttChart/DetailPane/SpanEvents.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 { Accordion, AccordionDetails, AccordionSummary, Typography } from '@mui/material';\nimport ExpandMoreIcon from 'mdi-material-ui/ChevronDown';\nimport { ReactElement } from 'react';\nimport { formatDuration } from '../utils';\nimport { Trace, Span, Event } from '../trace';\nimport { AttributeList } from './Attributes';\n\nexport interface SpanEventListProps {\n trace: Trace;\n span: Span;\n}\n\nexport function SpanEventList(props: SpanEventListProps): ReactElement {\n const { trace, span } = props;\n\n return (\n <>\n {span.events\n .sort((a, b) => a.timeUnixMs - b.timeUnixMs)\n .map((event, i) => (\n <SpanEventItem key={i} trace={trace} event={event} />\n ))}\n </>\n );\n}\n\ninterface SpanEventItemProps {\n trace: Trace;\n event: Event;\n}\n\nfunction SpanEventItem(props: SpanEventItemProps): ReactElement {\n const { trace, event } = props;\n const relativeTime = event.timeUnixMs - trace.startTimeUnixMs;\n\n return (\n <Accordion disableGutters>\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n <Typography>{formatDuration(relativeTime)}</Typography>\n </AccordionSummary>\n <AccordionDetails>\n <Typography variant=\"subtitle1\">{event.name}</Typography>\n <AttributeList attributes={event.attributes} />\n </AccordionDetails>\n </Accordion>\n );\n}\n"],"names":["Accordion","AccordionDetails","AccordionSummary","Typography","ExpandMoreIcon","formatDuration","AttributeList","SpanEventList","props","trace","span","events","sort","a","b","timeUnixMs","map","event","i","SpanEventItem","relativeTime","startTimeUnixMs","disableGutters","expandIcon","variant","name","attributes"],"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,SAAS,EAAEC,gBAAgB,EAAEC,gBAAgB,EAAEC,UAAU,QAAQ,gBAAgB;AAC1F,OAAOC,oBAAoB,8BAA8B;AAEzD,SAASC,cAAc,QAAQ,WAAW;AAE1C,SAASC,aAAa,QAAQ,eAAe;AAO7C,OAAO,SAASC,cAAcC,KAAyB;IACrD,MAAM,EAAEC,KAAK,EAAEC,IAAI,EAAE,GAAGF;IAExB,qBACE;kBACGE,KAAKC,MAAM,CACTC,IAAI,CAAC,CAACC,GAAGC,IAAMD,EAAEE,UAAU,GAAGD,EAAEC,UAAU,EAC1CC,GAAG,CAAC,CAACC,OAAOC,kBACX,KAACC;gBAAsBV,OAAOA;gBAAOQ,OAAOA;eAAxBC;;AAI9B;AAOA,SAASC,cAAcX,KAAyB;IAC9C,MAAM,EAAEC,KAAK,EAAEQ,KAAK,EAAE,GAAGT;IACzB,MAAMY,eAAeH,MAAMF,UAAU,GAAGN,MAAMY,eAAe;IAE7D,qBACE,MAACrB;QAAUsB,cAAc;;0BACvB,KAACpB;gBAAiBqB,0BAAY,KAACnB;0BAC7B,cAAA,KAACD;8BAAYE,eAAee;;;0BAE9B,MAACnB;;kCACC,KAACE;wBAAWqB,SAAQ;kCAAaP,MAAMQ,IAAI;;kCAC3C,KAACnB;wBAAcoB,YAAYT,MAAMS,UAAU;;;;;;AAInD"}
1
+ {"version":3,"sources":["../../../../src/TracingGanttChart/DetailPane/SpanEvents.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 { Collapse, Divider, List, ListItemButton, ListItemText } from '@mui/material';\nimport { Fragment, ReactElement, useState } from 'react';\nimport ChevronUp from 'mdi-material-ui/ChevronUp';\nimport ChevronDown from 'mdi-material-ui/ChevronDown';\nimport { formatDuration } from '../utils';\nimport { Trace, Span, Event } from '../trace';\nimport { CustomLinks } from '../../gantt-chart-model';\nimport { AttributeItems, AttributeItem } from './Attributes';\n\nexport interface SpanEventListProps {\n customLinks?: CustomLinks;\n trace: Trace;\n span: Span;\n}\n\nexport function SpanEventList(props: SpanEventListProps): ReactElement {\n const { customLinks, trace, span } = props;\n\n return (\n <>\n {span.events\n .sort((a, b) => a.timeUnixMs - b.timeUnixMs)\n .map((event, i) => (\n <Fragment key={i}>\n {i > 0 && <Divider />}\n <SpanEventItem customLinks={customLinks} trace={trace} event={event} />\n </Fragment>\n ))}\n </>\n );\n}\n\ninterface SpanEventItemProps {\n customLinks?: CustomLinks;\n trace: Trace;\n event: Event;\n}\n\nfunction SpanEventItem(props: SpanEventItemProps): ReactElement {\n const { customLinks, trace, event } = props;\n const relativeTime = event.timeUnixMs - trace.startTimeUnixMs;\n\n const [open, setOpen] = useState(false);\n const handleClick = () => {\n setOpen(!open);\n };\n\n return (\n <List>\n <ListItemButton onClick={handleClick} sx={{ px: 1 }}>\n <ListItemText\n primary={\n <>\n <strong>{formatDuration(relativeTime)}:</strong> {event.name}\n </>\n }\n slotProps={{ primary: { noWrap: true } }}\n />\n {open ? <ChevronUp /> : <ChevronDown />}\n </ListItemButton>\n <Collapse in={open} timeout=\"auto\" unmountOnExit>\n <List sx={{ px: 1 }}>\n <AttributeItem name=\"name\" value={event.name} />\n <AttributeItem name=\"time\" value={formatDuration(relativeTime)} />\n <AttributeItems customLinks={customLinks} attributes={event.attributes} />\n </List>\n </Collapse>\n </List>\n );\n}\n"],"names":["Collapse","Divider","List","ListItemButton","ListItemText","Fragment","useState","ChevronUp","ChevronDown","formatDuration","AttributeItems","AttributeItem","SpanEventList","props","customLinks","trace","span","events","sort","a","b","timeUnixMs","map","event","i","SpanEventItem","relativeTime","startTimeUnixMs","open","setOpen","handleClick","onClick","sx","px","primary","strong","name","slotProps","noWrap","in","timeout","unmountOnExit","value","attributes"],"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,EAAEC,OAAO,EAAEC,IAAI,EAAEC,cAAc,EAAEC,YAAY,QAAQ,gBAAgB;AACtF,SAASC,QAAQ,EAAgBC,QAAQ,QAAQ,QAAQ;AACzD,OAAOC,eAAe,4BAA4B;AAClD,OAAOC,iBAAiB,8BAA8B;AACtD,SAASC,cAAc,QAAQ,WAAW;AAG1C,SAASC,cAAc,EAAEC,aAAa,QAAQ,eAAe;AAQ7D,OAAO,SAASC,cAAcC,KAAyB;IACrD,MAAM,EAAEC,WAAW,EAAEC,KAAK,EAAEC,IAAI,EAAE,GAAGH;IAErC,qBACE;kBACGG,KAAKC,MAAM,CACTC,IAAI,CAAC,CAACC,GAAGC,IAAMD,EAAEE,UAAU,GAAGD,EAAEC,UAAU,EAC1CC,GAAG,CAAC,CAACC,OAAOC,kBACX,MAACnB;;oBACEmB,IAAI,mBAAK,KAACvB;kCACX,KAACwB;wBAAcX,aAAaA;wBAAaC,OAAOA;wBAAOQ,OAAOA;;;eAFjDC;;AAOzB;AAQA,SAASC,cAAcZ,KAAyB;IAC9C,MAAM,EAAEC,WAAW,EAAEC,KAAK,EAAEQ,KAAK,EAAE,GAAGV;IACtC,MAAMa,eAAeH,MAAMF,UAAU,GAAGN,MAAMY,eAAe;IAE7D,MAAM,CAACC,MAAMC,QAAQ,GAAGvB,SAAS;IACjC,MAAMwB,cAAc;QAClBD,QAAQ,CAACD;IACX;IAEA,qBACE,MAAC1B;;0BACC,MAACC;gBAAe4B,SAASD;gBAAaE,IAAI;oBAAEC,IAAI;gBAAE;;kCAChD,KAAC7B;wBACC8B,uBACE;;8CACE,MAACC;;wCAAQ1B,eAAeiB;wCAAc;;;gCAAU;gCAAEH,MAAMa,IAAI;;;wBAGhEC,WAAW;4BAAEH,SAAS;gCAAEI,QAAQ;4BAAK;wBAAE;;oBAExCV,qBAAO,KAACrB,+BAAe,KAACC;;;0BAE3B,KAACR;gBAASuC,IAAIX;gBAAMY,SAAQ;gBAAOC,aAAa;0BAC9C,cAAA,MAACvC;oBAAK8B,IAAI;wBAAEC,IAAI;oBAAE;;sCAChB,KAACtB;4BAAcyB,MAAK;4BAAOM,OAAOnB,MAAMa,IAAI;;sCAC5C,KAACzB;4BAAcyB,MAAK;4BAAOM,OAAOjC,eAAeiB;;sCACjD,KAAChB;4BAAeI,aAAaA;4BAAa6B,YAAYpB,MAAMoB,UAAU;;;;;;;AAKhF"}
@@ -0,0 +1,9 @@
1
+ import { ReactElement } from 'react';
2
+ import { Span } from '../trace';
3
+ import { CustomLinks } from '../../gantt-chart-model';
4
+ export interface SpanLinkListProps {
5
+ customLinks?: CustomLinks;
6
+ span: Span;
7
+ }
8
+ export declare function SpanLinkList(props: SpanLinkListProps): ReactElement;
9
+ //# sourceMappingURL=SpanLinks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpanLinks.d.ts","sourceRoot":"","sources":["../../../../src/TracingGanttChart/DetailPane/SpanLinks.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAY,YAAY,EAAE,MAAM,OAAO,CAAC;AAE/C,OAAO,EAAE,IAAI,EAAQ,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGtD,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAanE"}
@@ -0,0 +1,64 @@
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 { Divider, List } from '@mui/material';
15
+ import { Fragment } from 'react';
16
+ import { replaceVariablesInString, useAllVariableValues } from '@perses-dev/plugin-system';
17
+ import { AttributeItem, AttributeItems } from './Attributes';
18
+ export function SpanLinkList(props) {
19
+ const { customLinks, span } = props;
20
+ return /*#__PURE__*/ _jsx(_Fragment, {
21
+ children: span.links.map((link, i)=>/*#__PURE__*/ _jsxs(Fragment, {
22
+ children: [
23
+ i > 0 && /*#__PURE__*/ _jsx(Divider, {}),
24
+ /*#__PURE__*/ _jsx(SpanLinkItem, {
25
+ link: link,
26
+ customLinks: customLinks
27
+ })
28
+ ]
29
+ }, i))
30
+ });
31
+ }
32
+ function SpanLinkItem(props) {
33
+ const { customLinks, link } = props;
34
+ const variableValues = useAllVariableValues();
35
+ const traceLink = customLinks?.links.trace ? replaceVariablesInString(customLinks.links.trace, variableValues, {
36
+ ...customLinks?.variables,
37
+ traceId: link.traceId
38
+ }) : undefined;
39
+ const spanLink = customLinks?.links.span ? replaceVariablesInString(customLinks.links.span, variableValues, {
40
+ ...customLinks?.variables,
41
+ traceId: link.traceId,
42
+ spanId: link.spanId
43
+ }) : undefined;
44
+ return /*#__PURE__*/ _jsxs(List, {
45
+ children: [
46
+ /*#__PURE__*/ _jsx(AttributeItem, {
47
+ name: "trace ID",
48
+ value: link.traceId,
49
+ link: traceLink
50
+ }),
51
+ /*#__PURE__*/ _jsx(AttributeItem, {
52
+ name: "span ID",
53
+ value: link.spanId,
54
+ link: spanLink
55
+ }),
56
+ /*#__PURE__*/ _jsx(AttributeItems, {
57
+ customLinks: customLinks,
58
+ attributes: link.attributes
59
+ })
60
+ ]
61
+ });
62
+ }
63
+
64
+ //# sourceMappingURL=SpanLinks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/TracingGanttChart/DetailPane/SpanLinks.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 { Divider, List } from '@mui/material';\nimport { Fragment, ReactElement } from 'react';\nimport { replaceVariablesInString, useAllVariableValues } from '@perses-dev/plugin-system';\nimport { Span, Link } from '../trace';\nimport { CustomLinks } from '../../gantt-chart-model';\nimport { AttributeItem, AttributeItems } from './Attributes';\n\nexport interface SpanLinkListProps {\n customLinks?: CustomLinks;\n span: Span;\n}\n\nexport function SpanLinkList(props: SpanLinkListProps): ReactElement {\n const { customLinks, span } = props;\n\n return (\n <>\n {span.links.map((link, i) => (\n <Fragment key={i}>\n {i > 0 && <Divider />}\n <SpanLinkItem link={link} customLinks={customLinks} />\n </Fragment>\n ))}\n </>\n );\n}\n\ninterface SpanLinkItemProps {\n customLinks?: CustomLinks;\n link: Link;\n}\n\nfunction SpanLinkItem(props: SpanLinkItemProps): ReactElement {\n const { customLinks, link } = props;\n const variableValues = useAllVariableValues();\n const traceLink = customLinks?.links.trace\n ? replaceVariablesInString(customLinks.links.trace, variableValues, {\n ...customLinks?.variables,\n traceId: link.traceId,\n })\n : undefined;\n const spanLink = customLinks?.links.span\n ? replaceVariablesInString(customLinks.links.span, variableValues, {\n ...customLinks?.variables,\n traceId: link.traceId,\n spanId: link.spanId,\n })\n : undefined;\n\n return (\n <List>\n <AttributeItem name=\"trace ID\" value={link.traceId} link={traceLink} />\n <AttributeItem name=\"span ID\" value={link.spanId} link={spanLink} />\n <AttributeItems customLinks={customLinks} attributes={link.attributes} />\n </List>\n );\n}\n"],"names":["Divider","List","Fragment","replaceVariablesInString","useAllVariableValues","AttributeItem","AttributeItems","SpanLinkList","props","customLinks","span","links","map","link","i","SpanLinkItem","variableValues","traceLink","trace","variables","traceId","undefined","spanLink","spanId","name","value","attributes"],"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,OAAO,EAAEC,IAAI,QAAQ,gBAAgB;AAC9C,SAASC,QAAQ,QAAsB,QAAQ;AAC/C,SAASC,wBAAwB,EAAEC,oBAAoB,QAAQ,4BAA4B;AAG3F,SAASC,aAAa,EAAEC,cAAc,QAAQ,eAAe;AAO7D,OAAO,SAASC,aAAaC,KAAwB;IACnD,MAAM,EAAEC,WAAW,EAAEC,IAAI,EAAE,GAAGF;IAE9B,qBACE;kBACGE,KAAKC,KAAK,CAACC,GAAG,CAAC,CAACC,MAAMC,kBACrB,MAACZ;;oBACEY,IAAI,mBAAK,KAACd;kCACX,KAACe;wBAAaF,MAAMA;wBAAMJ,aAAaA;;;eAF1BK;;AAOvB;AAOA,SAASC,aAAaP,KAAwB;IAC5C,MAAM,EAAEC,WAAW,EAAEI,IAAI,EAAE,GAAGL;IAC9B,MAAMQ,iBAAiBZ;IACvB,MAAMa,YAAYR,aAAaE,MAAMO,QACjCf,yBAAyBM,YAAYE,KAAK,CAACO,KAAK,EAAEF,gBAAgB;QAChE,GAAGP,aAAaU,SAAS;QACzBC,SAASP,KAAKO,OAAO;IACvB,KACAC;IACJ,MAAMC,WAAWb,aAAaE,MAAMD,OAChCP,yBAAyBM,YAAYE,KAAK,CAACD,IAAI,EAAEM,gBAAgB;QAC/D,GAAGP,aAAaU,SAAS;QACzBC,SAASP,KAAKO,OAAO;QACrBG,QAAQV,KAAKU,MAAM;IACrB,KACAF;IAEJ,qBACE,MAACpB;;0BACC,KAACI;gBAAcmB,MAAK;gBAAWC,OAAOZ,KAAKO,OAAO;gBAAEP,MAAMI;;0BAC1D,KAACZ;gBAAcmB,MAAK;gBAAUC,OAAOZ,KAAKU,MAAM;gBAAEV,MAAMS;;0BACxD,KAAChB;gBAAeG,aAAaA;gBAAaiB,YAAYb,KAAKa,UAAU;;;;AAG3E"}
@@ -1,9 +1,10 @@
1
1
  import { ReactElement } from 'react';
2
2
  import { Viewport } from '../utils';
3
- import { TracingGanttChartOptions } from '../../gantt-chart-model';
3
+ import { CustomLinks, TracingGanttChartOptions } from '../../gantt-chart-model';
4
4
  import { Span, Trace } from '../trace';
5
5
  export interface GanttTableProps {
6
6
  options: TracingGanttChartOptions;
7
+ customLinks?: CustomLinks;
7
8
  trace: Trace;
8
9
  viewport: Viewport;
9
10
  selectedSpan?: Span;
@@ -1 +1 @@
1
- {"version":3,"file":"GanttTable.d.ts","sourceRoot":"","sources":["../../../../src/TracingGanttChart/GanttTable/GanttTable.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAE,YAAY,EAA6B,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAMvC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,wBAAwB,CAAC;IAClC,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,WAAW,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CACnC;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,CAuD/D"}
1
+ {"version":3,"file":"GanttTable.d.ts","sourceRoot":"","sources":["../../../../src/TracingGanttChart/GanttTable/GanttTable.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAE,YAAY,EAA6B,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAMvC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,wBAAwB,CAAC;IAClC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,WAAW,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CACnC;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,CAoE/D"}
@@ -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":"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"}
@@ -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;