@perses-dev/table-plugin 0.13.0-beta.0 → 0.13.0-beta.2

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 (100) hide show
  1. package/__mf/js/Table.24e2a11a.js +7 -0
  2. package/__mf/js/async/1432.4e515509.js +1 -0
  3. package/__mf/js/async/1589.124ce93d.js +2 -0
  4. package/__mf/js/async/1616.4828085d.js +1 -0
  5. package/__mf/js/async/2043.1f09864b.js +2 -0
  6. package/__mf/js/async/2082.231e8397.js +1 -0
  7. package/__mf/js/async/2842.cd8ee26c.js +1 -0
  8. package/__mf/js/async/392.b6035b41.js +2 -0
  9. package/__mf/js/async/4121.e7df36d6.js +2 -0
  10. package/__mf/js/async/4320.a5c90448.js +1 -0
  11. package/__mf/js/async/5002.3eb39a8c.js +1 -0
  12. package/__mf/js/async/5071.839a8f1a.js +1 -0
  13. package/__mf/js/async/5587.a8a428db.js +1 -0
  14. package/__mf/js/async/6274.8edae86d.js +2 -0
  15. package/__mf/js/async/629.8cff215d.js +1 -0
  16. package/__mf/js/async/6593.daabbc06.js +3 -0
  17. package/__mf/js/async/{6811.6a011de7.js → 6811.9d4b123a.js} +1 -1
  18. package/__mf/js/async/7177.e0e5ba2f.js +1 -0
  19. package/__mf/js/async/7192.692181c8.js +1 -0
  20. package/__mf/js/async/7413.c9310b8a.js +1 -0
  21. package/__mf/js/async/7862.4f5027fd.js +2 -0
  22. package/__mf/js/async/7968.3a9a982e.js +1 -0
  23. package/__mf/js/async/7978.116e4d81.js +1 -0
  24. package/__mf/js/async/7984.b099dc73.js +22 -0
  25. package/__mf/js/async/8356.152d5686.js +1 -0
  26. package/__mf/js/async/8470.b9762117.js +2 -0
  27. package/__mf/js/async/{868.a08b9f5f.js → 868.507e984c.js} +2 -2
  28. package/__mf/js/async/873.264fedc9.js +1 -0
  29. package/__mf/js/async/8969.24f980e6.js +7 -0
  30. package/__mf/js/async/9051.c4deebd7.js +1 -0
  31. package/__mf/js/async/9235.c67cdb1d.js +1 -0
  32. package/__mf/js/async/941.cc458a98.js +2 -0
  33. package/__mf/js/async/9588.d23e2ed3.js +1 -0
  34. package/__mf/js/async/9701.9c4cea02.js +1 -0
  35. package/__mf/js/async/__federation_expose_Table.4785e503.js +1 -0
  36. package/__mf/js/async/lib-router.3493bbf9.js +2 -0
  37. package/__mf/js/async/{lib-router.96861d20.js.LICENSE.txt → lib-router.3493bbf9.js.LICENSE.txt} +3 -3
  38. package/__mf/js/main.a243624b.js +7 -0
  39. package/lib/cjs/components/TablePanel.js +74 -39
  40. package/lib/cjs/test/mock-query-results.js +107 -0
  41. package/lib/components/TablePanel.d.ts.map +1 -1
  42. package/lib/components/TablePanel.js +74 -39
  43. package/lib/components/TablePanel.js.map +1 -1
  44. package/lib/test/mock-query-results.d.ts +4 -0
  45. package/lib/test/mock-query-results.d.ts.map +1 -1
  46. package/lib/test/mock-query-results.js +101 -0
  47. package/lib/test/mock-query-results.js.map +1 -1
  48. package/mf-manifest.json +49 -52
  49. package/mf-stats.json +49 -52
  50. package/package.json +6 -5
  51. package/__mf/js/Table.5ec41996.js +0 -7
  52. package/__mf/js/async/1432.47ca9bc7.js +0 -1
  53. package/__mf/js/async/1519.446ee3b5.js +0 -1
  54. package/__mf/js/async/1616.29b0085e.js +0 -1
  55. package/__mf/js/async/1805.b4a1e768.js +0 -1
  56. package/__mf/js/async/2043.0b0ffaef.js +0 -2
  57. package/__mf/js/async/2082.c0b3db38.js +0 -1
  58. package/__mf/js/async/256.7929d7f5.js +0 -1
  59. package/__mf/js/async/2842.cee1ed42.js +0 -1
  60. package/__mf/js/async/392.eef36bcd.js +0 -2
  61. package/__mf/js/async/4121.403fdade.js +0 -2
  62. package/__mf/js/async/4320.5cbfbd1c.js +0 -1
  63. package/__mf/js/async/5002.fd6ad994.js +0 -1
  64. package/__mf/js/async/5071.1684b9fd.js +0 -1
  65. package/__mf/js/async/5183.acc536f9.js +0 -22
  66. package/__mf/js/async/5286.1b3a5a62.js +0 -7
  67. package/__mf/js/async/5587.966d92d2.js +0 -1
  68. package/__mf/js/async/6274.71776a1d.js +0 -2
  69. package/__mf/js/async/6753.5632301a.js +0 -1
  70. package/__mf/js/async/7177.f0c1cf85.js +0 -1
  71. package/__mf/js/async/7192.f9d57dbb.js +0 -1
  72. package/__mf/js/async/7413.a78d135c.js +0 -1
  73. package/__mf/js/async/7862.de8ef786.js +0 -2
  74. package/__mf/js/async/7968.545aab42.js +0 -1
  75. package/__mf/js/async/7978.61f7fc2d.js +0 -1
  76. package/__mf/js/async/8356.7a060c2c.js +0 -1
  77. package/__mf/js/async/8470.dac32d6a.js +0 -2
  78. package/__mf/js/async/873.bb80627c.js +0 -1
  79. package/__mf/js/async/8750.8dc0b93d.js +0 -3
  80. package/__mf/js/async/9051.2db4f8e5.js +0 -1
  81. package/__mf/js/async/9235.35b8884a.js +0 -1
  82. package/__mf/js/async/941.97799379.js +0 -2
  83. package/__mf/js/async/9546.f3c1cf02.js +0 -2
  84. package/__mf/js/async/9588.178c0b3f.js +0 -1
  85. package/__mf/js/async/9701.4ae63d2f.js +0 -1
  86. package/__mf/js/async/__federation_expose_Table.7060f62e.js +0 -1
  87. package/__mf/js/async/lib-router.96861d20.js +0 -2
  88. package/__mf/js/main.8677f3d2.js +0 -7
  89. /package/__mf/css/async/{5286.85c2cbf6.css → 8969.85c2cbf6.css} +0 -0
  90. /package/__mf/js/async/{9546.f3c1cf02.js.LICENSE.txt → 1589.124ce93d.js.LICENSE.txt} +0 -0
  91. /package/__mf/js/async/{2043.0b0ffaef.js.LICENSE.txt → 2043.1f09864b.js.LICENSE.txt} +0 -0
  92. /package/__mf/js/async/{392.eef36bcd.js.LICENSE.txt → 392.b6035b41.js.LICENSE.txt} +0 -0
  93. /package/__mf/js/async/{4121.403fdade.js.LICENSE.txt → 4121.e7df36d6.js.LICENSE.txt} +0 -0
  94. /package/__mf/js/async/{6274.71776a1d.js.LICENSE.txt → 6274.8edae86d.js.LICENSE.txt} +0 -0
  95. /package/__mf/js/async/{7862.de8ef786.js.LICENSE.txt → 7862.4f5027fd.js.LICENSE.txt} +0 -0
  96. /package/__mf/js/async/{5183.acc536f9.js.LICENSE.txt → 7984.b099dc73.js.LICENSE.txt} +0 -0
  97. /package/__mf/js/async/{8470.dac32d6a.js.LICENSE.txt → 8470.b9762117.js.LICENSE.txt} +0 -0
  98. /package/__mf/js/async/{868.a08b9f5f.js.LICENSE.txt → 868.507e984c.js.LICENSE.txt} +0 -0
  99. /package/__mf/js/async/{5286.1b3a5a62.js.LICENSE.txt → 8969.24f980e6.js.LICENSE.txt} +0 -0
  100. /package/__mf/js/async/{941.97799379.js.LICENSE.txt → 941.cc458a98.js.LICENSE.txt} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"TablePanel.d.ts","sourceRoot":"","sources":["../../../src/components/TablePanel.tsx"],"names":[],"mappings":"AAuBA,OAAO,EAIL,UAAU,EAIX,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,YAAY,EAAqD,MAAM,OAAO,CAAC;AACxF,OAAO,EAAiB,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAA+D,YAAY,EAAE,MAAM,WAAW,CAAC;AAmVtG,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,YAAY,GAAG;IAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;CAAE,CAK3F;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;AAElE,wBAAgB,UAAU,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI,CA4brG"}
1
+ {"version":3,"file":"TablePanel.d.ts","sourceRoot":"","sources":["../../../src/components/TablePanel.tsx"],"names":[],"mappings":"AAwBA,OAAO,EAIL,UAAU,EAIX,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,YAAY,EAAqD,MAAM,OAAO,CAAC;AACxF,OAAO,EAAiB,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAA+D,YAAY,EAAE,MAAM,WAAW,CAAC;AAqVtG,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,YAAY,GAAG;IAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;CAAE,CAK3F;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;AAElE,wBAAgB,UAAU,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI,CAgerG"}
@@ -262,7 +262,7 @@ function ColumnFilterDropdown({ allValues, selectedValues, onFilterChange, theme
262
262
  /*#__PURE__*/ _jsx("input", {
263
263
  type: "checkbox",
264
264
  checked: selectedValues.length === values.length && values.length > 0,
265
- onChange: (e)=>onFilterChange(e.target.checked ? values : []),
265
+ onChange: (e)=>onFilterChange(e.target.checked ? values.map((v)=>v.original) : []),
266
266
  style: {
267
267
  marginRight: 8
268
268
  }
@@ -308,15 +308,15 @@ function ColumnFilterDropdown({ allValues, selectedValues, onFilterChange, theme
308
308
  children: [
309
309
  /*#__PURE__*/ _jsx("input", {
310
310
  type: "checkbox",
311
- checked: selectedValues.includes(value),
311
+ checked: selectedValues.includes(value.original),
312
312
  onChange: (e)=>{
313
313
  if (e.target.checked) {
314
314
  onFilterChange([
315
315
  ...selectedValues,
316
- value
316
+ value.original
317
317
  ]);
318
318
  } else {
319
- onFilterChange(selectedValues.filter((v)=>v !== value));
319
+ onFilterChange(selectedValues.filter((v)=>v !== value.original));
320
320
  }
321
321
  },
322
322
  style: {
@@ -328,7 +328,7 @@ function ColumnFilterDropdown({ allValues, selectedValues, onFilterChange, theme
328
328
  fontSize: 14,
329
329
  color: theme.palette.text.primary
330
330
  },
331
- children: value === null || value === undefined || value === '' ? '(empty)' : String(value)
331
+ children: value === null || value === undefined || value.formatted === '' ? '(empty)' : String(value.formatted)
332
332
  })
333
333
  ]
334
334
  })
@@ -440,21 +440,61 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
440
440
  }
441
441
  }
442
442
  }
443
+ // Include column names from columnSettings so that columns with no data
444
+ // are still extended with undefined for cellSettings evaluation (e.g. N/A for null)
445
+ for (const col of spec.columnSettings ?? []){
446
+ if (!result.includes(col.name)) {
447
+ result.push(col.name);
448
+ }
449
+ }
443
450
  return result;
444
451
  }, [
445
- data
452
+ data,
453
+ spec.columnSettings
454
+ ]);
455
+ const columnsFormat = useMemo(()=>{
456
+ const columnsFormat = {};
457
+ const settings = spec?.columnSettings;
458
+ if (settings) {
459
+ for(let i = 0; i < settings.length; i++){
460
+ const { name, format } = settings[i] || {};
461
+ if (name && format) {
462
+ columnsFormat[name] = format;
463
+ }
464
+ }
465
+ }
466
+ return columnsFormat;
467
+ }, [
468
+ spec
446
469
  ]);
447
- // fetch unique values for each column of filtering
448
470
  const columnUniqueValues = useMemo(()=>{
449
471
  const uniqueValues = {};
450
- keys.forEach((key)=>{
451
- const values = data.map((row)=>row[key]).filter((val)=>val !== null && val !== undefined && val !== '');
452
- uniqueValues[key] = Array.from(new Set(values));
453
- });
472
+ for (const key of keys){
473
+ const formatOption = columnsFormat?.[key];
474
+ uniqueValues[key] = [];
475
+ const usedValues = new Map();
476
+ for (const row of data){
477
+ const val = row[key];
478
+ if (val === '' || val === null || val === undefined) {
479
+ continue;
480
+ }
481
+ if (usedValues.get(String(val))) {
482
+ continue;
483
+ }
484
+ if (typeof val === 'string' || typeof val === 'number') {
485
+ uniqueValues[key].push({
486
+ original: val,
487
+ formatted: formatOption && typeof val === 'number' ? formatValue(val, formatOption) : val
488
+ });
489
+ usedValues.set(String(val), true);
490
+ }
491
+ }
492
+ }
454
493
  return uniqueValues;
455
494
  }, [
456
495
  data,
457
- keys
496
+ keys,
497
+ columnsFormat
458
498
  ]);
459
499
  const gaugeRangeByColumn = useMemo(()=>{
460
500
  const result = {};
@@ -514,6 +554,26 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
514
554
  gaugeRangeByColumn,
515
555
  spec.cellSettings
516
556
  ]);
557
+ // Filtering state — declared before cellConfigs so filteredData is available for cell config evaluation
558
+ const [columnFilters, setColumnFilters] = useState([]);
559
+ // filter data based on the current filters
560
+ const filteredData = useMemo(()=>{
561
+ if (!spec.enableFiltering || columnFilters.length === 0) {
562
+ return data;
563
+ }
564
+ return data.filter((row)=>{
565
+ return columnFilters.every((filter)=>{
566
+ const value = row[filter.id];
567
+ const filterValues = filter.value;
568
+ if (!filterValues || filterValues.length === 0) return true;
569
+ return filterValues.includes(value);
570
+ });
571
+ });
572
+ }, [
573
+ data,
574
+ columnFilters,
575
+ spec.enableFiltering
576
+ ]);
517
577
  // Generate cell settings that will be used by the table to render cells (text color, background color, ...)
518
578
  const cellConfigs = useMemo(()=>{
519
579
  // If there are no cell settings globally or per column, return an empty object
@@ -522,7 +582,7 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
522
582
  }
523
583
  const result = {};
524
584
  let index = 0;
525
- for (const row of data){
585
+ for (const row of filteredData){
526
586
  // Transforming key to object to extend the row with undefined values if the key is not present
527
587
  // for checking the cell config "Misc" condition with "null"
528
588
  const keysAsObj = keys.reduce((acc, key)=>{
@@ -554,7 +614,7 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
554
614
  }
555
615
  return result;
556
616
  }, [
557
- data,
617
+ filteredData,
558
618
  keys,
559
619
  spec.cellSettings,
560
620
  spec.columnSettings
@@ -568,8 +628,6 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
568
628
  }) ?? [];
569
629
  }
570
630
  const [sorting, setSorting] = useState(generateDefaultSortingState());
571
- // Filtering state
572
- const [columnFilters, setColumnFilters] = useState([]);
573
631
  const [filterAnchorEl, setFilterAnchorEl] = useState({});
574
632
  const [openFilterColumn, setOpenFilterColumn] = useState(null);
575
633
  // get selected values for a column
@@ -621,29 +679,6 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
621
679
  }, [
622
680
  openFilterColumn
623
681
  ]);
624
- // filter data based on the current filters
625
- const filteredData = useMemo(()=>{
626
- let filtered = [
627
- ...data
628
- ];
629
- // apply column filters if enabled
630
- if (spec.enableFiltering && columnFilters.length > 0) {
631
- filtered = filtered.filter((row)=>{
632
- return columnFilters.every((filter)=>{
633
- const value = row[filter.id];
634
- const filterValues = filter.value;
635
- if (!filterValues || filterValues.length === 0) return true; // No filter values means no filtering
636
- // Check if the row value is in the selected filter values
637
- return filterValues.includes(value);
638
- });
639
- });
640
- }
641
- return filtered;
642
- }, [
643
- data,
644
- columnFilters,
645
- spec.enableFiltering
646
- ]);
647
682
  // Keep ref in sync with filtered data for use in selection handler
648
683
  filteredDataRef.current = filteredData;
649
684
  const [pagination, setPagination] = useState(spec.pagination ? {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/TablePanel.tsx"],"sourcesContent":["// Copyright 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, Theme, Typography, useTheme } from '@mui/material';\nimport {\n formatValue,\n Table,\n TableCellConfigs,\n TableColumnConfig,\n transformData,\n useSelection,\n} from '@perses-dev/components';\nimport { useSelectionItemActions } from '@perses-dev/dashboards';\nimport {\n ActionOptions,\n CalculationsMap,\n PanelData,\n PanelProps,\n replaceVariablesInString,\n useAllVariableValues,\n VariableStateMap,\n} from '@perses-dev/plugin-system';\nimport { ColumnFiltersState, PaginationState, RowSelectionState, SortingState } from '@tanstack/react-table';\nimport { ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { QueryDataType, TimeSeriesData } from '@perses-dev/spec';\nimport { CellSettings, ColumnSettings, evaluateConditionalFormatting, TableOptions } from '../models';\nimport { buildRawTableData, getTablePanelQueryMode } from '../table-data-utils';\nimport { EmbeddedPanel } from './EmbeddedPanel';\n\nfunction parseNumericCellValue(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === 'string') {\n const parsed = Number(value);\n if (Number.isFinite(parsed)) {\n return parsed;\n }\n }\n return undefined;\n}\n\nfunction isPanelData(value: unknown): value is PanelData<QueryDataType> {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n const candidate = value as { definition?: unknown; data?: unknown };\n return candidate.definition !== undefined && candidate.data !== undefined;\n}\n\nfunction createSyntheticPanelData(value: unknown, columnName: string): PanelData<TimeSeriesData> | undefined {\n const numericValue = parseNumericCellValue(value);\n if (numericValue === undefined) {\n return undefined;\n }\n\n const now = Date.now();\n return {\n definition: {\n kind: 'TimeSeriesQuery',\n spec: { plugin: { kind: 'PrometheusTimeSeriesQuery', spec: { query: '' } } },\n },\n data: {\n timeRange: { start: new Date(now), end: new Date(now) },\n stepMs: 1,\n series: [{ name: columnName, values: [[now, numericValue]], labels: {} }],\n },\n };\n}\n\nfunction getGaugeNumericValue(value: unknown): number | undefined {\n if (isPanelData(value)) {\n const series = (value.data as TimeSeriesData)?.series;\n const firstSeries = series?.[0];\n if (!firstSeries?.values?.length) {\n return undefined;\n }\n const calc = CalculationsMap['last-number'];\n if (typeof calc !== 'function') {\n return undefined;\n }\n const calculatedValue = calc(firstSeries.values);\n return typeof calculatedValue === 'number' ? calculatedValue : undefined;\n }\n\n return parseNumericCellValue(value);\n}\n\ninterface GaugeRange {\n min: number;\n max: number;\n}\n\nfunction InlineGaugeCellWithRange({\n value,\n range,\n fillColor,\n format,\n}: {\n value?: number;\n range?: GaugeRange;\n fillColor?: string;\n format?: ColumnSettings['format'];\n}): ReactElement {\n if (value === undefined) {\n return <></>;\n }\n\n let percent = 0;\n if (range !== undefined) {\n if (range.max === range.min) {\n percent = 100;\n } else {\n percent = ((value - range.min) / (range.max - range.min)) * 100;\n }\n }\n percent = Math.max(0, Math.min(100, percent));\n\n const trackColor = 'rgba(127,127,127,0.20)';\n\n return (\n <Box sx={{ display: 'flex', alignItems: 'center', width: '100%', gap: 1 }}>\n <Box sx={{ flexGrow: 1, borderRadius: 1, backgroundColor: trackColor, height: 24, overflow: 'hidden' }}>\n <Box\n sx={{\n width: `${percent}%`,\n height: '100%',\n backgroundColor: fillColor ?? 'success.main',\n borderRadius: 1,\n }}\n />\n </Box>\n <Typography variant=\"body2\" sx={{ minWidth: 52, textAlign: 'right' }}>\n {format ? formatValue(value, format) : value.toFixed(2)}\n </Typography>\n </Box>\n );\n}\n\nfunction resolveGaugeFillColor(\n value: unknown,\n globalCellSettings: CellSettings[],\n columnCellSettings: CellSettings[] | undefined\n): string | undefined {\n let cellConfig = evaluateConditionalFormatting(value, globalCellSettings);\n if (columnCellSettings?.length) {\n const columnCellConfig = evaluateConditionalFormatting(value, columnCellSettings);\n if (columnCellConfig) {\n cellConfig = columnCellConfig;\n }\n }\n return cellConfig?.backgroundColor ?? cellConfig?.textColor;\n}\n\nfunction generateCellContentConfig(\n column: ColumnSettings,\n gaugeRange?: GaugeRange,\n globalCellSettings: CellSettings[] = []\n): Pick<TableColumnConfig<unknown>, 'cellDescription' | 'cell'> {\n const plugin = column.plugin;\n if (plugin !== undefined) {\n return {\n cell: (ctx): ReactElement => {\n const cellValue = ctx.getValue();\n if (plugin.kind === 'GaugeChart') {\n const gaugeValue = getGaugeNumericValue(cellValue);\n const gaugeFillColor = resolveGaugeFillColor(gaugeValue, globalCellSettings, column.cellSettings);\n return (\n <InlineGaugeCellWithRange\n value={gaugeValue}\n range={gaugeRange}\n fillColor={gaugeFillColor}\n format={plugin.spec?.format ?? column.format}\n />\n );\n }\n const panelData = isPanelData(cellValue) ? cellValue : createSyntheticPanelData(cellValue, column.name);\n if (!panelData) return <></>;\n return <EmbeddedPanel kind={plugin.kind} spec={plugin.spec} queryResults={[panelData]} />;\n },\n cellDescription: column.cellDescription ? (): string => `${column.cellDescription}` : (): string => '', // disable hover text\n };\n }\n\n return {\n cell: (ctx): ReactElement | string => {\n const cellValue = ctx.getValue();\n return typeof cellValue === 'number' && column.format ? formatValue(cellValue, column.format) : cellValue;\n },\n cellDescription: column.cellDescription ? (): string => `${column.cellDescription}` : undefined, // TODO: variable rendering + cell value\n };\n}\n\ninterface ColumnFilterDropdownProps {\n allValues: Array<string | number>;\n selectedValues: Array<string | number>;\n onFilterChange: (values: Array<string | number>) => void;\n theme: Theme;\n}\n\nfunction ColumnFilterDropdown({\n allValues,\n selectedValues,\n onFilterChange,\n theme,\n}: ColumnFilterDropdownProps): ReactElement {\n const [searchTerm, setSearchTerm] = useState('');\n const values = [...new Set(allValues)].filter((v) => v !== null).sort();\n const filteredValues = searchTerm\n ? values.filter((v) => String(v).toLowerCase().includes(searchTerm.toLowerCase()))\n : values;\n if (values.length === 0) {\n return (\n <div\n data-filter-dropdown\n style={{\n width: 200,\n padding: 10,\n backgroundColor: theme.palette.background.paper,\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: 4,\n boxShadow: theme.shadows[4],\n }}\n >\n <div style={{ color: theme.palette.text.secondary, fontSize: 14 }}>No values found</div>\n </div>\n );\n }\n\n return (\n <div\n data-filter-dropdown\n style={{\n width: 200,\n padding: 10,\n backgroundColor: theme.palette.background.paper,\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: 4,\n boxShadow: theme.shadows[4],\n maxHeight: 250,\n overflowY: 'auto',\n }}\n >\n <input\n type=\"text\"\n placeholder=\"Search...\"\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n style={{\n width: '100%',\n padding: '6px 8px',\n marginBottom: 8,\n fontSize: 13,\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: 4,\n backgroundColor: theme.palette.background.default,\n color: theme.palette.text.primary,\n boxSizing: 'border-box',\n }}\n />\n <div style={{ marginBottom: 8, fontSize: 14, fontWeight: 'bold' }}>\n <label style={{ display: 'flex', alignItems: 'center', cursor: 'pointer' }}>\n <input\n type=\"checkbox\"\n checked={selectedValues.length === values.length && values.length > 0}\n onChange={(e) => onFilterChange(e.target.checked ? values : [])}\n style={{ marginRight: 8 }}\n />\n <span style={{ color: theme.palette.text.primary }}>Select All ({values.length})</span>\n </label>\n </div>\n <hr\n style={{\n margin: '8px 0',\n border: 'none',\n borderTop: `1px solid ${theme.palette.divider}`,\n }}\n />\n {filteredValues.map((value, index) => (\n <div key={`value-${index}`} style={{ marginBottom: 4 }}>\n <label\n style={{\n display: 'flex',\n alignItems: 'center',\n cursor: 'pointer',\n padding: '2px 0',\n borderRadius: 2,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = theme.palette.action.hover;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent';\n }}\n >\n <input\n type=\"checkbox\"\n checked={selectedValues.includes(value)}\n onChange={(e) => {\n if (e.target.checked) {\n onFilterChange([...selectedValues, value]);\n } else {\n onFilterChange(selectedValues.filter((v) => v !== value));\n }\n }}\n style={{ marginRight: 8 }}\n />\n <span\n style={{\n fontSize: 14,\n color: theme.palette.text.primary,\n }}\n >\n {value === null || value === undefined || value === '' ? '(empty)' : String(value)}\n </span>\n </label>\n </div>\n ))}\n </div>\n );\n}\n\n/*\n * Generate column config from column definitions, if a column has multiple definitions, the first one will be used.\n * If column is hidden, return undefined.\n * If column do not have a definition, return a default column config.\n */\nfunction generateColumnConfig(\n name: string,\n columnSettings: ColumnSettings[],\n allVariables: VariableStateMap,\n gaugeRangeByColumn: Record<string, GaugeRange>,\n globalCellSettings: CellSettings[] = []\n): TableColumnConfig<unknown> | undefined {\n for (const column of columnSettings) {\n if (column.name === name) {\n if (column.hide) {\n return undefined;\n }\n\n const { name, header, headerDescription, enableSorting, width, align, dataLink } = column;\n const modifiedDataLink = dataLink\n ? { ...dataLink, url: replaceVariablesInString(dataLink.url, allVariables) }\n : undefined;\n\n return {\n accessorKey: name,\n header: header ?? name,\n headerDescription,\n enableSorting,\n width,\n align,\n dataLink: modifiedDataLink,\n ...generateCellContentConfig(column, gaugeRangeByColumn[name], globalCellSettings),\n };\n }\n }\n\n return {\n accessorKey: name,\n header: name,\n };\n}\n\nexport function getTablePanelQueryOptions(spec: TableOptions): { mode: 'instant' | 'range' } {\n // if any cell renders a panel plugin, perform a range query instead of an instant query\n return {\n mode: getTablePanelQueryMode(spec),\n };\n}\n\nexport type TableProps = PanelProps<TableOptions, TimeSeriesData>;\n\nexport function TablePanel({ contentDimensions, spec, queryResults }: TableProps): ReactElement | null {\n const theme = useTheme();\n const allVariables = useAllVariableValues();\n\n const selectionEnabled = spec.selection?.enabled ?? false;\n const { selectionMap, setSelection, clearSelection } = useSelection<Record<string, unknown>, string>();\n\n const itemActionsConfig = spec.actions ? (spec.actions as ActionOptions) : undefined;\n const itemActionsListConfig =\n itemActionsConfig?.enabled && itemActionsConfig.displayWithItem ? itemActionsConfig.actionsList : [];\n\n const { getItemActionButtons, confirmDialog, actionButtons } = useSelectionItemActions({\n actions: itemActionsListConfig,\n variableState: allVariables,\n });\n\n const filteredDataRef = useRef<Array<Record<string, unknown>>>([]);\n\n // Convert selectionMap to TanStack's RowSelectionState format\n const rowSelection = useMemo((): RowSelectionState => {\n const result: RowSelectionState = {};\n selectionMap.forEach((_, id) => {\n result[id] = true;\n });\n return result;\n }, [selectionMap]);\n\n const handleRowSelectionChange = useCallback(\n (newRowSelection: RowSelectionState) => {\n const newSelection: Array<{ id: string; item: Record<string, unknown> }> = [];\n for (const [id, isSelected] of Object.entries(newRowSelection)) {\n if (isSelected) {\n const index = parseInt(id, 10);\n if (filteredDataRef.current[index] !== undefined) {\n newSelection.push({ id, item: filteredDataRef.current[index] });\n }\n }\n }\n\n if (newSelection.length === 0) {\n clearSelection();\n } else {\n setSelection(newSelection);\n }\n },\n [setSelection, clearSelection]\n );\n\n // TODO: handle other query types\n const rawData: Array<Record<string, unknown>> = useMemo(() => {\n // Transform query results to a tabular format using shared utility\n return buildRawTableData(queryResults, spec);\n }, [queryResults, spec]);\n\n // Transform will be applied by their orders on the original data\n const data = useMemo(() => transformData(rawData, spec.transforms ?? []), [rawData, spec.transforms]);\n\n const keys: string[] = useMemo(() => {\n const result: string[] = [];\n\n for (const entry of data) {\n for (const key of Object.keys(entry)) {\n if (!result.includes(key)) {\n result.push(key);\n }\n }\n }\n\n return result;\n }, [data]);\n\n // fetch unique values for each column of filtering\n const columnUniqueValues = useMemo(() => {\n const uniqueValues: Record<string, Array<string | number>> = {};\n\n keys.forEach((key) => {\n const values = data.map((row) => row[key]).filter((val) => val !== null && val !== undefined && val !== '');\n uniqueValues[key] = Array.from(new Set(values as Array<string | number>));\n });\n\n return uniqueValues;\n }, [data, keys]);\n\n const gaugeRangeByColumn = useMemo(() => {\n const result: Record<string, GaugeRange> = {};\n\n for (const key of keys) {\n let min = Number.POSITIVE_INFINITY;\n let max = Number.NEGATIVE_INFINITY;\n\n for (const row of data) {\n const numericValue = getGaugeNumericValue(row[key]);\n if (numericValue === undefined) {\n continue;\n }\n min = Math.min(min, numericValue);\n max = Math.max(max, numericValue);\n }\n\n if (min !== Number.POSITIVE_INFINITY && max !== Number.NEGATIVE_INFINITY) {\n result[key] = { min, max };\n }\n }\n\n return result;\n }, [data, keys]);\n\n // Generate columns and map each column accessor to its settings index and data key\n const columns: Array<TableColumnConfig<unknown>> = useMemo(() => {\n const columns: Array<TableColumnConfig<unknown>> = [];\n const customizedColumns = new Set<string>();\n\n // Process columnSettings if they exist\n for (const columnSetting of spec.columnSettings ?? []) {\n if (customizedColumns.has(columnSetting.name)) continue; // Skip duplicates\n\n const columnConfig = generateColumnConfig(\n columnSetting.name,\n spec.columnSettings ?? [],\n allVariables,\n gaugeRangeByColumn,\n spec.cellSettings ?? []\n );\n if (columnConfig !== undefined) {\n columns.push(columnConfig);\n customizedColumns.add(columnSetting.name);\n }\n }\n\n // Add remaining columns if defaultColumnHidden is false\n if (!spec.defaultColumnHidden) {\n for (const key of keys) {\n if (!customizedColumns.has(key)) {\n const columnConfig = generateColumnConfig(\n key,\n spec.columnSettings ?? [],\n allVariables,\n gaugeRangeByColumn,\n spec.cellSettings ?? []\n );\n if (columnConfig !== undefined) {\n columns.push(columnConfig);\n }\n }\n }\n }\n\n return columns;\n }, [keys, spec.columnSettings, spec.defaultColumnHidden, allVariables, gaugeRangeByColumn, spec.cellSettings]);\n\n // Generate cell settings that will be used by the table to render cells (text color, background color, ...)\n const cellConfigs: TableCellConfigs = useMemo(() => {\n // If there are no cell settings globally or per column, return an empty object\n if (spec.cellSettings === undefined && !spec.columnSettings?.some((col) => col.cellSettings !== undefined)) {\n return {};\n }\n\n const result: TableCellConfigs = {};\n\n let index = 0;\n for (const row of data) {\n // Transforming key to object to extend the row with undefined values if the key is not present\n // for checking the cell config \"Misc\" condition with \"null\"\n const keysAsObj = keys.reduce(\n (acc, key) => {\n acc[key] = undefined;\n return acc;\n },\n {} as Record<string, undefined>\n );\n\n const extendRow = {\n ...keysAsObj,\n ...row,\n };\n\n // Generate cellConfigs for each column (including duplicates with different headers)\n for (const [key, value] of Object.entries(extendRow)) {\n // First, try to get cell config from global cell settings\n let cellConfig = evaluateConditionalFormatting(value, spec.cellSettings ?? []);\n\n // Then, try to get cell config from column-specific cell settings\n const columnSetting = spec.columnSettings?.find((col) => col.name === key);\n if (columnSetting?.cellSettings?.length) {\n const columnCellConfig = evaluateConditionalFormatting(value, columnSetting.cellSettings);\n // Column-specific settings take precedence over global settings\n if (columnCellConfig) {\n cellConfig = columnCellConfig;\n }\n }\n\n if (cellConfig) {\n result[`${index}_${key}`] = cellConfig;\n }\n }\n index++;\n }\n\n return result;\n }, [data, keys, spec.cellSettings, spec.columnSettings]);\n\n function generateDefaultSortingState(): SortingState {\n return (\n spec.columnSettings\n ?.filter((column) => column.sort !== undefined)\n .map((column) => {\n return {\n id: column.name,\n desc: column.sort === 'desc',\n };\n }) ?? []\n );\n }\n\n const [sorting, setSorting] = useState<SortingState>(generateDefaultSortingState());\n\n // Filtering state\n const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);\n const [filterAnchorEl, setFilterAnchorEl] = useState<{ [key: string]: HTMLElement | null }>({});\n const [openFilterColumn, setOpenFilterColumn] = useState<string | null>(null);\n\n // get selected values for a column\n const getSelectedFilterValues = (columnId: string): Array<string | number> => {\n const filter = columnFilters.find((f) => f.id === columnId);\n return filter ? (filter.value as Array<string | number>) : [];\n };\n\n // update column filter\n const updateColumnFilter = (columnId: string, values: Array<string | number>): void => {\n const newFilters = columnFilters.filter((f) => f.id !== columnId);\n if (values.length > 0) {\n newFilters.push({ id: columnId, value: values });\n }\n setColumnFilters(newFilters);\n };\n\n // Handle filter clicks\n const handleFilterClick = (event: React.MouseEvent<HTMLButtonElement>, columnId: string): void => {\n event.preventDefault();\n event.stopPropagation();\n setFilterAnchorEl({ ...filterAnchorEl, [columnId]: event.currentTarget });\n setOpenFilterColumn(columnId);\n };\n\n const handleFilterClose = (): void => {\n setFilterAnchorEl({});\n setOpenFilterColumn(null);\n };\n\n // Close filter when clicking outside\n useEffect(() => {\n if (!openFilterColumn) return;\n\n const handleClick = (e: MouseEvent): void => {\n const target = e.target as Element;\n if (!target.closest('[data-filter-dropdown]') && !target.closest('button')) {\n handleFilterClose();\n }\n };\n\n const timer = setTimeout(() => {\n document.addEventListener('click', handleClick);\n }, 100);\n\n return (): void => {\n clearTimeout(timer);\n document.removeEventListener('click', handleClick);\n };\n }, [openFilterColumn]);\n\n // filter data based on the current filters\n const filteredData = useMemo(() => {\n let filtered = [...data];\n\n // apply column filters if enabled\n if (spec.enableFiltering && columnFilters.length > 0) {\n filtered = filtered.filter((row) => {\n return columnFilters.every((filter) => {\n const value = row[filter.id];\n const filterValues = filter.value as Array<string | number>;\n\n if (!filterValues || filterValues.length === 0) return true; // No filter values means no filtering\n\n // Check if the row value is in the selected filter values\n return filterValues.includes(value as string | number);\n });\n });\n }\n\n return filtered;\n }, [data, columnFilters, spec.enableFiltering]);\n\n // Keep ref in sync with filtered data for use in selection handler\n filteredDataRef.current = filteredData;\n\n const [pagination, setPagination] = useState<PaginationState | undefined>(\n spec.pagination ? { pageIndex: 0, pageSize: 10 } : undefined\n );\n\n useEffect(() => {\n // If the pagination setting changes from no pagination to pagination, but the pagination state is undefined, update the pagination state\n if (spec.pagination && !pagination) {\n setPagination({ pageIndex: 0, pageSize: 10 });\n } else if (!spec.pagination && pagination) {\n setPagination(undefined);\n }\n }, [spec.pagination, pagination]);\n\n if (contentDimensions === undefined) {\n return null;\n }\n\n if (!data?.length) {\n return (\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n height: '100%',\n }}\n >\n <Typography>No data</Typography>\n </Box>\n );\n }\n\n return (\n <>\n {confirmDialog}\n {spec.enableFiltering && (\n <div\n style={{\n display: 'flex',\n background: theme.palette.background.default,\n borderBottom: `1px solid ${theme.palette.divider}`,\n width: contentDimensions.width,\n boxSizing: 'border-box',\n }}\n >\n {columns.map((column, idx) => {\n const filters = getSelectedFilterValues(column.accessorKey as string);\n const columnWidth = column.width || spec.defaultColumnWidth;\n return (\n <div\n key={`filter-${idx}`}\n style={{\n padding: '8px',\n borderRight: idx < columns.length - 1 ? `1px solid ${theme.palette.divider}` : 'none',\n width: columnWidth,\n minWidth: columnWidth,\n maxWidth: columnWidth,\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n boxSizing: 'border-box',\n flex: typeof columnWidth === 'number' ? 'none' : '1 1 auto',\n }}\n >\n <span\n style={{\n marginRight: 8,\n fontSize: '12px',\n color: theme.palette.text.secondary,\n flex: 1,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {filters.length ? `${filters.length} items` : 'All'}\n </span>\n <button\n onClick={(e) => {\n handleFilterClick(e, column.accessorKey as string);\n }}\n style={{\n border: `1px solid ${theme.palette.divider}`,\n background: theme.palette.background.paper,\n cursor: 'pointer',\n fontSize: '12px',\n color: filters.length ? theme.palette.primary.main : theme.palette.text.secondary,\n padding: '4px 8px',\n borderRadius: '4px',\n minWidth: '20px',\n height: '24px',\n flexShrink: 0,\n transition: 'all 0.2s ease',\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background = theme.palette.action.hover;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = theme.palette.background.paper;\n }}\n type=\"button\"\n >\n ▼\n </button>\n\n {openFilterColumn === column.accessorKey && (\n <div\n style={{\n position: 'absolute',\n top: '100%',\n left: 0,\n zIndex: 1000,\n marginTop: 4,\n }}\n >\n <ColumnFilterDropdown\n allValues={columnUniqueValues[column.accessorKey as string] || []}\n selectedValues={filters}\n onFilterChange={(values) => updateColumnFilter(column.accessorKey as string, values)}\n theme={theme}\n />\n </div>\n )}\n </div>\n );\n })}\n </div>\n )}\n <Table\n data={filteredData}\n columns={columns}\n cellConfigs={cellConfigs}\n height={spec.enableFiltering ? contentDimensions.height - 40 : contentDimensions.height}\n width={contentDimensions.width}\n density={spec.density}\n defaultColumnWidth={spec.defaultColumnWidth}\n defaultColumnHeight={spec.defaultColumnHeight}\n sorting={sorting}\n onSortingChange={setSorting}\n pagination={pagination}\n onPaginationChange={setPagination}\n checkboxSelection={selectionEnabled}\n rowSelection={rowSelection}\n onRowSelectionChange={handleRowSelectionChange}\n getItemActions={({ id, data }) => getItemActionButtons({ id, data: data as Record<string, unknown> })}\n hasItemActions={actionButtons && actionButtons.length > 0}\n />\n </>\n );\n}\n"],"names":["Box","Typography","useTheme","formatValue","Table","transformData","useSelection","useSelectionItemActions","CalculationsMap","replaceVariablesInString","useAllVariableValues","useCallback","useEffect","useMemo","useRef","useState","evaluateConditionalFormatting","buildRawTableData","getTablePanelQueryMode","EmbeddedPanel","parseNumericCellValue","value","Number","isFinite","parsed","undefined","isPanelData","candidate","definition","data","createSyntheticPanelData","columnName","numericValue","now","Date","kind","spec","plugin","query","timeRange","start","end","stepMs","series","name","values","labels","getGaugeNumericValue","firstSeries","length","calc","calculatedValue","InlineGaugeCellWithRange","range","fillColor","format","percent","max","min","Math","trackColor","sx","display","alignItems","width","gap","flexGrow","borderRadius","backgroundColor","height","overflow","variant","minWidth","textAlign","toFixed","resolveGaugeFillColor","globalCellSettings","columnCellSettings","cellConfig","columnCellConfig","textColor","generateCellContentConfig","column","gaugeRange","cell","ctx","cellValue","getValue","gaugeValue","gaugeFillColor","cellSettings","panelData","queryResults","cellDescription","ColumnFilterDropdown","allValues","selectedValues","onFilterChange","theme","searchTerm","setSearchTerm","Set","filter","v","sort","filteredValues","String","toLowerCase","includes","div","data-filter-dropdown","style","padding","palette","background","paper","border","divider","boxShadow","shadows","color","text","secondary","fontSize","maxHeight","overflowY","input","type","placeholder","onChange","e","target","marginBottom","default","primary","boxSizing","fontWeight","label","cursor","checked","marginRight","span","hr","margin","borderTop","map","index","onMouseEnter","currentTarget","action","hover","onMouseLeave","generateColumnConfig","columnSettings","allVariables","gaugeRangeByColumn","hide","header","headerDescription","enableSorting","align","dataLink","modifiedDataLink","url","accessorKey","getTablePanelQueryOptions","mode","TablePanel","contentDimensions","selectionEnabled","selection","enabled","selectionMap","setSelection","clearSelection","itemActionsConfig","actions","itemActionsListConfig","displayWithItem","actionsList","getItemActionButtons","confirmDialog","actionButtons","variableState","filteredDataRef","rowSelection","result","forEach","_","id","handleRowSelectionChange","newRowSelection","newSelection","isSelected","Object","entries","parseInt","current","push","item","rawData","transforms","keys","entry","key","columnUniqueValues","uniqueValues","row","val","Array","from","POSITIVE_INFINITY","NEGATIVE_INFINITY","columns","customizedColumns","columnSetting","has","columnConfig","add","defaultColumnHidden","cellConfigs","some","col","keysAsObj","reduce","acc","extendRow","find","generateDefaultSortingState","desc","sorting","setSorting","columnFilters","setColumnFilters","filterAnchorEl","setFilterAnchorEl","openFilterColumn","setOpenFilterColumn","getSelectedFilterValues","columnId","f","updateColumnFilter","newFilters","handleFilterClick","event","preventDefault","stopPropagation","handleFilterClose","handleClick","closest","timer","setTimeout","document","addEventListener","clearTimeout","removeEventListener","filteredData","filtered","enableFiltering","every","filterValues","pagination","setPagination","pageIndex","pageSize","justifyContent","borderBottom","idx","filters","columnWidth","defaultColumnWidth","borderRight","maxWidth","position","flex","textOverflow","whiteSpace","button","onClick","main","flexShrink","transition","top","left","zIndex","marginTop","density","defaultColumnHeight","onSortingChange","onPaginationChange","checkboxSelection","onRowSelectionChange","getItemActions","hasItemActions"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/TablePanel.tsx"],"sourcesContent":["// Copyright 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, Theme, Typography, useTheme } from '@mui/material';\nimport {\n FormatOptions,\n formatValue,\n Table,\n TableCellConfigs,\n TableColumnConfig,\n transformData,\n useSelection,\n} from '@perses-dev/components';\nimport { useSelectionItemActions } from '@perses-dev/dashboards';\nimport {\n ActionOptions,\n CalculationsMap,\n PanelData,\n PanelProps,\n replaceVariablesInString,\n useAllVariableValues,\n VariableStateMap,\n} from '@perses-dev/plugin-system';\nimport { ColumnFiltersState, PaginationState, RowSelectionState, SortingState } from '@tanstack/react-table';\nimport { ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { QueryDataType, TimeSeriesData } from '@perses-dev/spec';\nimport { CellSettings, ColumnSettings, evaluateConditionalFormatting, TableOptions } from '../models';\nimport { buildRawTableData, getTablePanelQueryMode } from '../table-data-utils';\nimport { EmbeddedPanel } from './EmbeddedPanel';\n\ntype FilterValuesType<T> = Array<{ original: T; formatted: T }>;\n\nfunction parseNumericCellValue(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === 'string') {\n const parsed = Number(value);\n if (Number.isFinite(parsed)) {\n return parsed;\n }\n }\n return undefined;\n}\n\nfunction isPanelData(value: unknown): value is PanelData<QueryDataType> {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n const candidate = value as { definition?: unknown; data?: unknown };\n return candidate.definition !== undefined && candidate.data !== undefined;\n}\n\nfunction createSyntheticPanelData(value: unknown, columnName: string): PanelData<TimeSeriesData> | undefined {\n const numericValue = parseNumericCellValue(value);\n if (numericValue === undefined) {\n return undefined;\n }\n\n const now = Date.now();\n return {\n definition: {\n kind: 'TimeSeriesQuery',\n spec: { plugin: { kind: 'PrometheusTimeSeriesQuery', spec: { query: '' } } },\n },\n data: {\n timeRange: { start: new Date(now), end: new Date(now) },\n stepMs: 1,\n series: [{ name: columnName, values: [[now, numericValue]], labels: {} }],\n },\n };\n}\n\nfunction getGaugeNumericValue(value: unknown): number | undefined {\n if (isPanelData(value)) {\n const series = (value.data as TimeSeriesData)?.series;\n const firstSeries = series?.[0];\n if (!firstSeries?.values?.length) {\n return undefined;\n }\n const calc = CalculationsMap['last-number'];\n if (typeof calc !== 'function') {\n return undefined;\n }\n const calculatedValue = calc(firstSeries.values);\n return typeof calculatedValue === 'number' ? calculatedValue : undefined;\n }\n\n return parseNumericCellValue(value);\n}\n\ninterface GaugeRange {\n min: number;\n max: number;\n}\n\nfunction InlineGaugeCellWithRange({\n value,\n range,\n fillColor,\n format,\n}: {\n value?: number;\n range?: GaugeRange;\n fillColor?: string;\n format?: ColumnSettings['format'];\n}): ReactElement {\n if (value === undefined) {\n return <></>;\n }\n\n let percent = 0;\n if (range !== undefined) {\n if (range.max === range.min) {\n percent = 100;\n } else {\n percent = ((value - range.min) / (range.max - range.min)) * 100;\n }\n }\n percent = Math.max(0, Math.min(100, percent));\n\n const trackColor = 'rgba(127,127,127,0.20)';\n\n return (\n <Box sx={{ display: 'flex', alignItems: 'center', width: '100%', gap: 1 }}>\n <Box sx={{ flexGrow: 1, borderRadius: 1, backgroundColor: trackColor, height: 24, overflow: 'hidden' }}>\n <Box\n sx={{\n width: `${percent}%`,\n height: '100%',\n backgroundColor: fillColor ?? 'success.main',\n borderRadius: 1,\n }}\n />\n </Box>\n <Typography variant=\"body2\" sx={{ minWidth: 52, textAlign: 'right' }}>\n {format ? formatValue(value, format) : value.toFixed(2)}\n </Typography>\n </Box>\n );\n}\n\nfunction resolveGaugeFillColor(\n value: unknown,\n globalCellSettings: CellSettings[],\n columnCellSettings: CellSettings[] | undefined\n): string | undefined {\n let cellConfig = evaluateConditionalFormatting(value, globalCellSettings);\n if (columnCellSettings?.length) {\n const columnCellConfig = evaluateConditionalFormatting(value, columnCellSettings);\n if (columnCellConfig) {\n cellConfig = columnCellConfig;\n }\n }\n return cellConfig?.backgroundColor ?? cellConfig?.textColor;\n}\n\nfunction generateCellContentConfig(\n column: ColumnSettings,\n gaugeRange?: GaugeRange,\n globalCellSettings: CellSettings[] = []\n): Pick<TableColumnConfig<unknown>, 'cellDescription' | 'cell'> {\n const plugin = column.plugin;\n if (plugin !== undefined) {\n return {\n cell: (ctx): ReactElement => {\n const cellValue = ctx.getValue();\n if (plugin.kind === 'GaugeChart') {\n const gaugeValue = getGaugeNumericValue(cellValue);\n const gaugeFillColor = resolveGaugeFillColor(gaugeValue, globalCellSettings, column.cellSettings);\n return (\n <InlineGaugeCellWithRange\n value={gaugeValue}\n range={gaugeRange}\n fillColor={gaugeFillColor}\n format={plugin.spec?.format ?? column.format}\n />\n );\n }\n const panelData = isPanelData(cellValue) ? cellValue : createSyntheticPanelData(cellValue, column.name);\n if (!panelData) return <></>;\n return <EmbeddedPanel kind={plugin.kind} spec={plugin.spec} queryResults={[panelData]} />;\n },\n cellDescription: column.cellDescription ? (): string => `${column.cellDescription}` : (): string => '', // disable hover text\n };\n }\n\n return {\n cell: (ctx): ReactElement | string => {\n const cellValue = ctx.getValue();\n return typeof cellValue === 'number' && column.format ? formatValue(cellValue, column.format) : cellValue;\n },\n cellDescription: column.cellDescription ? (): string => `${column.cellDescription}` : undefined, // TODO: variable rendering + cell value\n };\n}\n\ninterface ColumnFilterDropdownProps {\n allValues: FilterValuesType<string | number>;\n selectedValues: Array<string | number>;\n onFilterChange: (values: Array<string | number>) => void;\n theme: Theme;\n}\n\nfunction ColumnFilterDropdown({\n allValues,\n selectedValues,\n onFilterChange,\n theme,\n}: ColumnFilterDropdownProps): ReactElement {\n const [searchTerm, setSearchTerm] = useState('');\n const values = [...new Set(allValues)].filter((v) => v !== null).sort();\n const filteredValues = searchTerm\n ? values.filter((v) => String(v).toLowerCase().includes(searchTerm.toLowerCase()))\n : values;\n if (values.length === 0) {\n return (\n <div\n data-filter-dropdown\n style={{\n width: 200,\n padding: 10,\n backgroundColor: theme.palette.background.paper,\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: 4,\n boxShadow: theme.shadows[4],\n }}\n >\n <div style={{ color: theme.palette.text.secondary, fontSize: 14 }}>No values found</div>\n </div>\n );\n }\n\n return (\n <div\n data-filter-dropdown\n style={{\n width: 200,\n padding: 10,\n backgroundColor: theme.palette.background.paper,\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: 4,\n boxShadow: theme.shadows[4],\n maxHeight: 250,\n overflowY: 'auto',\n }}\n >\n <input\n type=\"text\"\n placeholder=\"Search...\"\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n style={{\n width: '100%',\n padding: '6px 8px',\n marginBottom: 8,\n fontSize: 13,\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: 4,\n backgroundColor: theme.palette.background.default,\n color: theme.palette.text.primary,\n boxSizing: 'border-box',\n }}\n />\n <div style={{ marginBottom: 8, fontSize: 14, fontWeight: 'bold' }}>\n <label style={{ display: 'flex', alignItems: 'center', cursor: 'pointer' }}>\n <input\n type=\"checkbox\"\n checked={selectedValues.length === values.length && values.length > 0}\n onChange={(e) => onFilterChange(e.target.checked ? values.map((v) => v.original) : [])}\n style={{ marginRight: 8 }}\n />\n <span style={{ color: theme.palette.text.primary }}>Select All ({values.length})</span>\n </label>\n </div>\n <hr\n style={{\n margin: '8px 0',\n border: 'none',\n borderTop: `1px solid ${theme.palette.divider}`,\n }}\n />\n {filteredValues.map((value, index) => (\n <div key={`value-${index}`} style={{ marginBottom: 4 }}>\n <label\n style={{\n display: 'flex',\n alignItems: 'center',\n cursor: 'pointer',\n padding: '2px 0',\n borderRadius: 2,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = theme.palette.action.hover;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent';\n }}\n >\n <input\n type=\"checkbox\"\n checked={selectedValues.includes(value.original)}\n onChange={(e) => {\n if (e.target.checked) {\n onFilterChange([...selectedValues, value.original]);\n } else {\n onFilterChange(selectedValues.filter((v) => v !== value.original));\n }\n }}\n style={{ marginRight: 8 }}\n />\n <span\n style={{\n fontSize: 14,\n color: theme.palette.text.primary,\n }}\n >\n {value === null || value === undefined || value.formatted === '' ? '(empty)' : String(value.formatted)}\n </span>\n </label>\n </div>\n ))}\n </div>\n );\n}\n\n/*\n * Generate column config from column definitions, if a column has multiple definitions, the first one will be used.\n * If column is hidden, return undefined.\n * If column do not have a definition, return a default column config.\n */\nfunction generateColumnConfig(\n name: string,\n columnSettings: ColumnSettings[],\n allVariables: VariableStateMap,\n gaugeRangeByColumn: Record<string, GaugeRange>,\n globalCellSettings: CellSettings[] = []\n): TableColumnConfig<unknown> | undefined {\n for (const column of columnSettings) {\n if (column.name === name) {\n if (column.hide) {\n return undefined;\n }\n\n const { name, header, headerDescription, enableSorting, width, align, dataLink } = column;\n const modifiedDataLink = dataLink\n ? { ...dataLink, url: replaceVariablesInString(dataLink.url, allVariables) }\n : undefined;\n\n return {\n accessorKey: name,\n header: header ?? name,\n headerDescription,\n enableSorting,\n width,\n align,\n dataLink: modifiedDataLink,\n ...generateCellContentConfig(column, gaugeRangeByColumn[name], globalCellSettings),\n };\n }\n }\n\n return {\n accessorKey: name,\n header: name,\n };\n}\n\nexport function getTablePanelQueryOptions(spec: TableOptions): { mode: 'instant' | 'range' } {\n // if any cell renders a panel plugin, perform a range query instead of an instant query\n return {\n mode: getTablePanelQueryMode(spec),\n };\n}\n\nexport type TableProps = PanelProps<TableOptions, TimeSeriesData>;\n\nexport function TablePanel({ contentDimensions, spec, queryResults }: TableProps): ReactElement | null {\n const theme = useTheme();\n const allVariables = useAllVariableValues();\n\n const selectionEnabled = spec.selection?.enabled ?? false;\n const { selectionMap, setSelection, clearSelection } = useSelection<Record<string, unknown>, string>();\n\n const itemActionsConfig = spec.actions ? (spec.actions as ActionOptions) : undefined;\n const itemActionsListConfig =\n itemActionsConfig?.enabled && itemActionsConfig.displayWithItem ? itemActionsConfig.actionsList : [];\n\n const { getItemActionButtons, confirmDialog, actionButtons } = useSelectionItemActions({\n actions: itemActionsListConfig,\n variableState: allVariables,\n });\n\n const filteredDataRef = useRef<Array<Record<string, unknown>>>([]);\n\n // Convert selectionMap to TanStack's RowSelectionState format\n const rowSelection = useMemo((): RowSelectionState => {\n const result: RowSelectionState = {};\n selectionMap.forEach((_, id) => {\n result[id] = true;\n });\n return result;\n }, [selectionMap]);\n\n const handleRowSelectionChange = useCallback(\n (newRowSelection: RowSelectionState) => {\n const newSelection: Array<{ id: string; item: Record<string, unknown> }> = [];\n for (const [id, isSelected] of Object.entries(newRowSelection)) {\n if (isSelected) {\n const index = parseInt(id, 10);\n if (filteredDataRef.current[index] !== undefined) {\n newSelection.push({ id, item: filteredDataRef.current[index] });\n }\n }\n }\n\n if (newSelection.length === 0) {\n clearSelection();\n } else {\n setSelection(newSelection);\n }\n },\n [setSelection, clearSelection]\n );\n\n // TODO: handle other query types\n const rawData: Array<Record<string, unknown>> = useMemo(() => {\n // Transform query results to a tabular format using shared utility\n return buildRawTableData(queryResults, spec);\n }, [queryResults, spec]);\n\n // Transform will be applied by their orders on the original data\n const data = useMemo(() => transformData(rawData, spec.transforms ?? []), [rawData, spec.transforms]);\n\n const keys: string[] = useMemo(() => {\n const result: string[] = [];\n\n for (const entry of data) {\n for (const key of Object.keys(entry)) {\n if (!result.includes(key)) {\n result.push(key);\n }\n }\n }\n\n // Include column names from columnSettings so that columns with no data\n // are still extended with undefined for cellSettings evaluation (e.g. N/A for null)\n for (const col of spec.columnSettings ?? []) {\n if (!result.includes(col.name)) {\n result.push(col.name);\n }\n }\n\n return result;\n }, [data, spec.columnSettings]);\n\n const columnsFormat = useMemo(() => {\n const columnsFormat: Record<string, FormatOptions> = {};\n const settings = spec?.columnSettings;\n if (settings) {\n for (let i = 0; i < settings.length; i++) {\n const { name, format } = settings[i] || {};\n if (name && format) {\n columnsFormat[name] = format;\n }\n }\n }\n\n return columnsFormat;\n }, [spec]);\n\n const columnUniqueValues = useMemo(() => {\n const uniqueValues: Record<string, FilterValuesType<string | number>> = {};\n\n for (const key of keys) {\n const formatOption = columnsFormat?.[key];\n uniqueValues[key] = [];\n const usedValues: Map<string, true> = new Map();\n for (const row of data) {\n const val = row[key];\n if (val === '' || val === null || val === undefined) {\n continue;\n }\n if (usedValues.get(String(val))) {\n continue;\n }\n\n if (typeof val === 'string' || typeof val === 'number') {\n uniqueValues[key].push({\n original: val,\n formatted: formatOption && typeof val === 'number' ? formatValue(val, formatOption) : val,\n });\n usedValues.set(String(val), true);\n }\n }\n }\n return uniqueValues;\n }, [data, keys, columnsFormat]);\n\n const gaugeRangeByColumn = useMemo(() => {\n const result: Record<string, GaugeRange> = {};\n\n for (const key of keys) {\n let min = Number.POSITIVE_INFINITY;\n let max = Number.NEGATIVE_INFINITY;\n\n for (const row of data) {\n const numericValue = getGaugeNumericValue(row[key]);\n if (numericValue === undefined) {\n continue;\n }\n min = Math.min(min, numericValue);\n max = Math.max(max, numericValue);\n }\n\n if (min !== Number.POSITIVE_INFINITY && max !== Number.NEGATIVE_INFINITY) {\n result[key] = { min, max };\n }\n }\n\n return result;\n }, [data, keys]);\n\n // Generate columns and map each column accessor to its settings index and data key\n const columns: Array<TableColumnConfig<unknown>> = useMemo(() => {\n const columns: Array<TableColumnConfig<unknown>> = [];\n const customizedColumns = new Set<string>();\n\n // Process columnSettings if they exist\n for (const columnSetting of spec.columnSettings ?? []) {\n if (customizedColumns.has(columnSetting.name)) continue; // Skip duplicates\n\n const columnConfig = generateColumnConfig(\n columnSetting.name,\n spec.columnSettings ?? [],\n allVariables,\n gaugeRangeByColumn,\n spec.cellSettings ?? []\n );\n if (columnConfig !== undefined) {\n columns.push(columnConfig);\n customizedColumns.add(columnSetting.name);\n }\n }\n\n // Add remaining columns if defaultColumnHidden is false\n if (!spec.defaultColumnHidden) {\n for (const key of keys) {\n if (!customizedColumns.has(key)) {\n const columnConfig = generateColumnConfig(\n key,\n spec.columnSettings ?? [],\n allVariables,\n gaugeRangeByColumn,\n spec.cellSettings ?? []\n );\n if (columnConfig !== undefined) {\n columns.push(columnConfig);\n }\n }\n }\n }\n\n return columns;\n }, [keys, spec.columnSettings, spec.defaultColumnHidden, allVariables, gaugeRangeByColumn, spec.cellSettings]);\n\n // Filtering state — declared before cellConfigs so filteredData is available for cell config evaluation\n const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);\n\n // filter data based on the current filters\n const filteredData = useMemo(() => {\n if (!spec.enableFiltering || columnFilters.length === 0) {\n return data;\n }\n\n return data.filter((row) => {\n return columnFilters.every((filter) => {\n const value = row[filter.id];\n const filterValues = filter.value as Array<string | number>;\n\n if (!filterValues || filterValues.length === 0) return true;\n\n return filterValues.includes(value as string | number);\n });\n });\n }, [data, columnFilters, spec.enableFiltering]);\n\n // Generate cell settings that will be used by the table to render cells (text color, background color, ...)\n const cellConfigs: TableCellConfigs = useMemo(() => {\n // If there are no cell settings globally or per column, return an empty object\n if (spec.cellSettings === undefined && !spec.columnSettings?.some((col) => col.cellSettings !== undefined)) {\n return {};\n }\n\n const result: TableCellConfigs = {};\n\n let index = 0;\n for (const row of filteredData) {\n // Transforming key to object to extend the row with undefined values if the key is not present\n // for checking the cell config \"Misc\" condition with \"null\"\n const keysAsObj = keys.reduce(\n (acc, key) => {\n acc[key] = undefined;\n return acc;\n },\n {} as Record<string, undefined>\n );\n\n const extendRow = {\n ...keysAsObj,\n ...row,\n };\n\n // Generate cellConfigs for each column (including duplicates with different headers)\n for (const [key, value] of Object.entries(extendRow)) {\n // First, try to get cell config from global cell settings\n let cellConfig = evaluateConditionalFormatting(value, spec.cellSettings ?? []);\n\n // Then, try to get cell config from column-specific cell settings\n const columnSetting = spec.columnSettings?.find((col) => col.name === key);\n if (columnSetting?.cellSettings?.length) {\n const columnCellConfig = evaluateConditionalFormatting(value, columnSetting.cellSettings);\n // Column-specific settings take precedence over global settings\n if (columnCellConfig) {\n cellConfig = columnCellConfig;\n }\n }\n\n if (cellConfig) {\n result[`${index}_${key}`] = cellConfig;\n }\n }\n index++;\n }\n\n return result;\n }, [filteredData, keys, spec.cellSettings, spec.columnSettings]);\n\n function generateDefaultSortingState(): SortingState {\n return (\n spec.columnSettings\n ?.filter((column) => column.sort !== undefined)\n .map((column) => {\n return {\n id: column.name,\n desc: column.sort === 'desc',\n };\n }) ?? []\n );\n }\n\n const [sorting, setSorting] = useState<SortingState>(generateDefaultSortingState());\n\n const [filterAnchorEl, setFilterAnchorEl] = useState<{ [key: string]: HTMLElement | null }>({});\n const [openFilterColumn, setOpenFilterColumn] = useState<string | null>(null);\n\n // get selected values for a column\n const getSelectedFilterValues = (columnId: string): Array<string | number> => {\n const filter = columnFilters.find((f) => f.id === columnId);\n return filter ? (filter.value as Array<string | number>) : [];\n };\n\n // update column filter\n const updateColumnFilter = (columnId: string, values: Array<string | number>): void => {\n const newFilters = columnFilters.filter((f) => f.id !== columnId);\n if (values.length > 0) {\n newFilters.push({ id: columnId, value: values });\n }\n setColumnFilters(newFilters);\n };\n\n // Handle filter clicks\n const handleFilterClick = (event: React.MouseEvent<HTMLButtonElement>, columnId: string): void => {\n event.preventDefault();\n event.stopPropagation();\n setFilterAnchorEl({ ...filterAnchorEl, [columnId]: event.currentTarget });\n setOpenFilterColumn(columnId);\n };\n\n const handleFilterClose = (): void => {\n setFilterAnchorEl({});\n setOpenFilterColumn(null);\n };\n\n // Close filter when clicking outside\n useEffect(() => {\n if (!openFilterColumn) return;\n\n const handleClick = (e: MouseEvent): void => {\n const target = e.target as Element;\n if (!target.closest('[data-filter-dropdown]') && !target.closest('button')) {\n handleFilterClose();\n }\n };\n\n const timer = setTimeout(() => {\n document.addEventListener('click', handleClick);\n }, 100);\n\n return (): void => {\n clearTimeout(timer);\n document.removeEventListener('click', handleClick);\n };\n }, [openFilterColumn]);\n\n // Keep ref in sync with filtered data for use in selection handler\n filteredDataRef.current = filteredData;\n\n const [pagination, setPagination] = useState<PaginationState | undefined>(\n spec.pagination ? { pageIndex: 0, pageSize: 10 } : undefined\n );\n\n useEffect(() => {\n // If the pagination setting changes from no pagination to pagination, but the pagination state is undefined, update the pagination state\n if (spec.pagination && !pagination) {\n setPagination({ pageIndex: 0, pageSize: 10 });\n } else if (!spec.pagination && pagination) {\n setPagination(undefined);\n }\n }, [spec.pagination, pagination]);\n\n if (contentDimensions === undefined) {\n return null;\n }\n\n if (!data?.length) {\n return (\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n height: '100%',\n }}\n >\n <Typography>No data</Typography>\n </Box>\n );\n }\n\n return (\n <>\n {confirmDialog}\n {spec.enableFiltering && (\n <div\n style={{\n display: 'flex',\n background: theme.palette.background.default,\n borderBottom: `1px solid ${theme.palette.divider}`,\n width: contentDimensions.width,\n boxSizing: 'border-box',\n }}\n >\n {columns.map((column, idx) => {\n const filters = getSelectedFilterValues(column.accessorKey as string);\n const columnWidth = column.width || spec.defaultColumnWidth;\n return (\n <div\n key={`filter-${idx}`}\n style={{\n padding: '8px',\n borderRight: idx < columns.length - 1 ? `1px solid ${theme.palette.divider}` : 'none',\n width: columnWidth,\n minWidth: columnWidth,\n maxWidth: columnWidth,\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n boxSizing: 'border-box',\n flex: typeof columnWidth === 'number' ? 'none' : '1 1 auto',\n }}\n >\n <span\n style={{\n marginRight: 8,\n fontSize: '12px',\n color: theme.palette.text.secondary,\n flex: 1,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {filters.length ? `${filters.length} items` : 'All'}\n </span>\n <button\n onClick={(e) => {\n handleFilterClick(e, column.accessorKey as string);\n }}\n style={{\n border: `1px solid ${theme.palette.divider}`,\n background: theme.palette.background.paper,\n cursor: 'pointer',\n fontSize: '12px',\n color: filters.length ? theme.palette.primary.main : theme.palette.text.secondary,\n padding: '4px 8px',\n borderRadius: '4px',\n minWidth: '20px',\n height: '24px',\n flexShrink: 0,\n transition: 'all 0.2s ease',\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background = theme.palette.action.hover;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = theme.palette.background.paper;\n }}\n type=\"button\"\n >\n ▼\n </button>\n\n {openFilterColumn === column.accessorKey && (\n <div\n style={{\n position: 'absolute',\n top: '100%',\n left: 0,\n zIndex: 1000,\n marginTop: 4,\n }}\n >\n <ColumnFilterDropdown\n allValues={columnUniqueValues[column.accessorKey as string] || []}\n selectedValues={filters}\n onFilterChange={(values) => updateColumnFilter(column.accessorKey as string, values)}\n theme={theme}\n />\n </div>\n )}\n </div>\n );\n })}\n </div>\n )}\n <Table\n data={filteredData}\n columns={columns}\n cellConfigs={cellConfigs}\n height={spec.enableFiltering ? contentDimensions.height - 40 : contentDimensions.height}\n width={contentDimensions.width}\n density={spec.density}\n defaultColumnWidth={spec.defaultColumnWidth}\n defaultColumnHeight={spec.defaultColumnHeight}\n sorting={sorting}\n onSortingChange={setSorting}\n pagination={pagination}\n onPaginationChange={setPagination}\n checkboxSelection={selectionEnabled}\n rowSelection={rowSelection}\n onRowSelectionChange={handleRowSelectionChange}\n getItemActions={({ id, data }) => getItemActionButtons({ id, data: data as Record<string, unknown> })}\n hasItemActions={actionButtons && actionButtons.length > 0}\n />\n </>\n );\n}\n"],"names":["Box","Typography","useTheme","formatValue","Table","transformData","useSelection","useSelectionItemActions","CalculationsMap","replaceVariablesInString","useAllVariableValues","useCallback","useEffect","useMemo","useRef","useState","evaluateConditionalFormatting","buildRawTableData","getTablePanelQueryMode","EmbeddedPanel","parseNumericCellValue","value","Number","isFinite","parsed","undefined","isPanelData","candidate","definition","data","createSyntheticPanelData","columnName","numericValue","now","Date","kind","spec","plugin","query","timeRange","start","end","stepMs","series","name","values","labels","getGaugeNumericValue","firstSeries","length","calc","calculatedValue","InlineGaugeCellWithRange","range","fillColor","format","percent","max","min","Math","trackColor","sx","display","alignItems","width","gap","flexGrow","borderRadius","backgroundColor","height","overflow","variant","minWidth","textAlign","toFixed","resolveGaugeFillColor","globalCellSettings","columnCellSettings","cellConfig","columnCellConfig","textColor","generateCellContentConfig","column","gaugeRange","cell","ctx","cellValue","getValue","gaugeValue","gaugeFillColor","cellSettings","panelData","queryResults","cellDescription","ColumnFilterDropdown","allValues","selectedValues","onFilterChange","theme","searchTerm","setSearchTerm","Set","filter","v","sort","filteredValues","String","toLowerCase","includes","div","data-filter-dropdown","style","padding","palette","background","paper","border","divider","boxShadow","shadows","color","text","secondary","fontSize","maxHeight","overflowY","input","type","placeholder","onChange","e","target","marginBottom","default","primary","boxSizing","fontWeight","label","cursor","checked","map","original","marginRight","span","hr","margin","borderTop","index","onMouseEnter","currentTarget","action","hover","onMouseLeave","formatted","generateColumnConfig","columnSettings","allVariables","gaugeRangeByColumn","hide","header","headerDescription","enableSorting","align","dataLink","modifiedDataLink","url","accessorKey","getTablePanelQueryOptions","mode","TablePanel","contentDimensions","selectionEnabled","selection","enabled","selectionMap","setSelection","clearSelection","itemActionsConfig","actions","itemActionsListConfig","displayWithItem","actionsList","getItemActionButtons","confirmDialog","actionButtons","variableState","filteredDataRef","rowSelection","result","forEach","_","id","handleRowSelectionChange","newRowSelection","newSelection","isSelected","Object","entries","parseInt","current","push","item","rawData","transforms","keys","entry","key","col","columnsFormat","settings","i","columnUniqueValues","uniqueValues","formatOption","usedValues","Map","row","val","get","set","POSITIVE_INFINITY","NEGATIVE_INFINITY","columns","customizedColumns","columnSetting","has","columnConfig","add","defaultColumnHidden","columnFilters","setColumnFilters","filteredData","enableFiltering","every","filterValues","cellConfigs","some","keysAsObj","reduce","acc","extendRow","find","generateDefaultSortingState","desc","sorting","setSorting","filterAnchorEl","setFilterAnchorEl","openFilterColumn","setOpenFilterColumn","getSelectedFilterValues","columnId","f","updateColumnFilter","newFilters","handleFilterClick","event","preventDefault","stopPropagation","handleFilterClose","handleClick","closest","timer","setTimeout","document","addEventListener","clearTimeout","removeEventListener","pagination","setPagination","pageIndex","pageSize","justifyContent","borderBottom","idx","filters","columnWidth","defaultColumnWidth","borderRight","maxWidth","position","flex","textOverflow","whiteSpace","button","onClick","main","flexShrink","transition","top","left","zIndex","marginTop","density","defaultColumnHeight","onSortingChange","onPaginationChange","checkboxSelection","onRowSelectionChange","getItemActions","hasItemActions"],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,GAAG,EAASC,UAAU,EAAEC,QAAQ,QAAQ,gBAAgB;AACjE,SAEEC,WAAW,EACXC,KAAK,EAGLC,aAAa,EACbC,YAAY,QACP,yBAAyB;AAChC,SAASC,uBAAuB,QAAQ,yBAAyB;AACjE,SAEEC,eAAe,EAGfC,wBAAwB,EACxBC,oBAAoB,QAEf,4BAA4B;AAEnC,SAAuBC,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AAExF,SAAuCC,6BAA6B,QAAsB,YAAY;AACtG,SAASC,iBAAiB,EAAEC,sBAAsB,QAAQ,sBAAsB;AAChF,SAASC,aAAa,QAAQ,kBAAkB;AAIhD,SAASC,sBAAsBC,KAAc;IAC3C,IAAI,OAAOA,UAAU,YAAYC,OAAOC,QAAQ,CAACF,QAAQ;QACvD,OAAOA;IACT;IACA,IAAI,OAAOA,UAAU,UAAU;QAC7B,MAAMG,SAASF,OAAOD;QACtB,IAAIC,OAAOC,QAAQ,CAACC,SAAS;YAC3B,OAAOA;QACT;IACF;IACA,OAAOC;AACT;AAEA,SAASC,YAAYL,KAAc;IACjC,IAAI,OAAOA,UAAU,YAAYA,UAAU,MAAM;QAC/C,OAAO;IACT;IACA,MAAMM,YAAYN;IAClB,OAAOM,UAAUC,UAAU,KAAKH,aAAaE,UAAUE,IAAI,KAAKJ;AAClE;AAEA,SAASK,yBAAyBT,KAAc,EAAEU,UAAkB;IAClE,MAAMC,eAAeZ,sBAAsBC;IAC3C,IAAIW,iBAAiBP,WAAW;QAC9B,OAAOA;IACT;IAEA,MAAMQ,MAAMC,KAAKD,GAAG;IACpB,OAAO;QACLL,YAAY;YACVO,MAAM;YACNC,MAAM;gBAAEC,QAAQ;oBAAEF,MAAM;oBAA6BC,MAAM;wBAAEE,OAAO;oBAAG;gBAAE;YAAE;QAC7E;QACAT,MAAM;YACJU,WAAW;gBAAEC,OAAO,IAAIN,KAAKD;gBAAMQ,KAAK,IAAIP,KAAKD;YAAK;YACtDS,QAAQ;YACRC,QAAQ;gBAAC;oBAAEC,MAAMb;oBAAYc,QAAQ;wBAAC;4BAACZ;4BAAKD;yBAAa;qBAAC;oBAAEc,QAAQ,CAAC;gBAAE;aAAE;QAC3E;IACF;AACF;AAEA,SAASC,qBAAqB1B,KAAc;IAC1C,IAAIK,YAAYL,QAAQ;QACtB,MAAMsB,SAAUtB,MAAMQ,IAAI,EAAqBc;QAC/C,MAAMK,cAAcL,QAAQ,CAAC,EAAE;QAC/B,IAAI,CAACK,aAAaH,QAAQI,QAAQ;YAChC,OAAOxB;QACT;QACA,MAAMyB,OAAO1C,eAAe,CAAC,cAAc;QAC3C,IAAI,OAAO0C,SAAS,YAAY;YAC9B,OAAOzB;QACT;QACA,MAAM0B,kBAAkBD,KAAKF,YAAYH,MAAM;QAC/C,OAAO,OAAOM,oBAAoB,WAAWA,kBAAkB1B;IACjE;IAEA,OAAOL,sBAAsBC;AAC/B;AAOA,SAAS+B,yBAAyB,EAChC/B,KAAK,EACLgC,KAAK,EACLC,SAAS,EACTC,MAAM,EAMP;IACC,IAAIlC,UAAUI,WAAW;QACvB,qBAAO;IACT;IAEA,IAAI+B,UAAU;IACd,IAAIH,UAAU5B,WAAW;QACvB,IAAI4B,MAAMI,GAAG,KAAKJ,MAAMK,GAAG,EAAE;YAC3BF,UAAU;QACZ,OAAO;YACLA,UAAU,AAAEnC,CAAAA,QAAQgC,MAAMK,GAAG,AAAD,IAAML,CAAAA,MAAMI,GAAG,GAAGJ,MAAMK,GAAG,AAAD,IAAM;QAC9D;IACF;IACAF,UAAUG,KAAKF,GAAG,CAAC,GAAGE,KAAKD,GAAG,CAAC,KAAKF;IAEpC,MAAMI,aAAa;IAEnB,qBACE,MAAC5D;QAAI6D,IAAI;YAAEC,SAAS;YAAQC,YAAY;YAAUC,OAAO;YAAQC,KAAK;QAAE;;0BACtE,KAACjE;gBAAI6D,IAAI;oBAAEK,UAAU;oBAAGC,cAAc;oBAAGC,iBAAiBR;oBAAYS,QAAQ;oBAAIC,UAAU;gBAAS;0BACnG,cAAA,KAACtE;oBACC6D,IAAI;wBACFG,OAAO,GAAGR,QAAQ,CAAC,CAAC;wBACpBa,QAAQ;wBACRD,iBAAiBd,aAAa;wBAC9Ba,cAAc;oBAChB;;;0BAGJ,KAAClE;gBAAWsE,SAAQ;gBAAQV,IAAI;oBAAEW,UAAU;oBAAIC,WAAW;gBAAQ;0BAChElB,SAASpD,YAAYkB,OAAOkC,UAAUlC,MAAMqD,OAAO,CAAC;;;;AAI7D;AAEA,SAASC,sBACPtD,KAAc,EACduD,kBAAkC,EAClCC,kBAA8C;IAE9C,IAAIC,aAAa9D,8BAA8BK,OAAOuD;IACtD,IAAIC,oBAAoB5B,QAAQ;QAC9B,MAAM8B,mBAAmB/D,8BAA8BK,OAAOwD;QAC9D,IAAIE,kBAAkB;YACpBD,aAAaC;QACf;IACF;IACA,OAAOD,YAAYV,mBAAmBU,YAAYE;AACpD;AAEA,SAASC,0BACPC,MAAsB,EACtBC,UAAuB,EACvBP,qBAAqC,EAAE;IAEvC,MAAMvC,SAAS6C,OAAO7C,MAAM;IAC5B,IAAIA,WAAWZ,WAAW;QACxB,OAAO;YACL2D,MAAM,CAACC;gBACL,MAAMC,YAAYD,IAAIE,QAAQ;gBAC9B,IAAIlD,OAAOF,IAAI,KAAK,cAAc;oBAChC,MAAMqD,aAAazC,qBAAqBuC;oBACxC,MAAMG,iBAAiBd,sBAAsBa,YAAYZ,oBAAoBM,OAAOQ,YAAY;oBAChG,qBACE,KAACtC;wBACC/B,OAAOmE;wBACPnC,OAAO8B;wBACP7B,WAAWmC;wBACXlC,QAAQlB,OAAOD,IAAI,EAAEmB,UAAU2B,OAAO3B,MAAM;;gBAGlD;gBACA,MAAMoC,YAAYjE,YAAY4D,aAAaA,YAAYxD,yBAAyBwD,WAAWJ,OAAOtC,IAAI;gBACtG,IAAI,CAAC+C,WAAW,qBAAO;gBACvB,qBAAO,KAACxE;oBAAcgB,MAAME,OAAOF,IAAI;oBAAEC,MAAMC,OAAOD,IAAI;oBAAEwD,cAAc;wBAACD;qBAAU;;YACvF;YACAE,iBAAiBX,OAAOW,eAAe,GAAG,IAAc,GAAGX,OAAOW,eAAe,EAAE,GAAG,IAAc;QACtG;IACF;IAEA,OAAO;QACLT,MAAM,CAACC;YACL,MAAMC,YAAYD,IAAIE,QAAQ;YAC9B,OAAO,OAAOD,cAAc,YAAYJ,OAAO3B,MAAM,GAAGpD,YAAYmF,WAAWJ,OAAO3B,MAAM,IAAI+B;QAClG;QACAO,iBAAiBX,OAAOW,eAAe,GAAG,IAAc,GAAGX,OAAOW,eAAe,EAAE,GAAGpE;IACxF;AACF;AASA,SAASqE,qBAAqB,EAC5BC,SAAS,EACTC,cAAc,EACdC,cAAc,EACdC,KAAK,EACqB;IAC1B,MAAM,CAACC,YAAYC,cAAc,GAAGrF,SAAS;IAC7C,MAAM8B,SAAS;WAAI,IAAIwD,IAAIN;KAAW,CAACO,MAAM,CAAC,CAACC,IAAMA,MAAM,MAAMC,IAAI;IACrE,MAAMC,iBAAiBN,aACnBtD,OAAOyD,MAAM,CAAC,CAACC,IAAMG,OAAOH,GAAGI,WAAW,GAAGC,QAAQ,CAACT,WAAWQ,WAAW,OAC5E9D;IACJ,IAAIA,OAAOI,MAAM,KAAK,GAAG;QACvB,qBACE,KAAC4D;YACCC,sBAAoB;YACpBC,OAAO;gBACL/C,OAAO;gBACPgD,SAAS;gBACT5C,iBAAiB8B,MAAMe,OAAO,CAACC,UAAU,CAACC,KAAK;gBAC/CC,QAAQ,CAAC,UAAU,EAAElB,MAAMe,OAAO,CAACI,OAAO,EAAE;gBAC5ClD,cAAc;gBACdmD,WAAWpB,MAAMqB,OAAO,CAAC,EAAE;YAC7B;sBAEA,cAAA,KAACV;gBAAIE,OAAO;oBAAES,OAAOtB,MAAMe,OAAO,CAACQ,IAAI,CAACC,SAAS;oBAAEC,UAAU;gBAAG;0BAAG;;;IAGzE;IAEA,qBACE,MAACd;QACCC,sBAAoB;QACpBC,OAAO;YACL/C,OAAO;YACPgD,SAAS;YACT5C,iBAAiB8B,MAAMe,OAAO,CAACC,UAAU,CAACC,KAAK;YAC/CC,QAAQ,CAAC,UAAU,EAAElB,MAAMe,OAAO,CAACI,OAAO,EAAE;YAC5ClD,cAAc;YACdmD,WAAWpB,MAAMqB,OAAO,CAAC,EAAE;YAC3BK,WAAW;YACXC,WAAW;QACb;;0BAEA,KAACC;gBACCC,MAAK;gBACLC,aAAY;gBACZ3G,OAAO8E;gBACP8B,UAAU,CAACC,IAAM9B,cAAc8B,EAAEC,MAAM,CAAC9G,KAAK;gBAC7C0F,OAAO;oBACL/C,OAAO;oBACPgD,SAAS;oBACToB,cAAc;oBACdT,UAAU;oBACVP,QAAQ,CAAC,UAAU,EAAElB,MAAMe,OAAO,CAACI,OAAO,EAAE;oBAC5ClD,cAAc;oBACdC,iBAAiB8B,MAAMe,OAAO,CAACC,UAAU,CAACmB,OAAO;oBACjDb,OAAOtB,MAAMe,OAAO,CAACQ,IAAI,CAACa,OAAO;oBACjCC,WAAW;gBACb;;0BAEF,KAAC1B;gBAAIE,OAAO;oBAAEqB,cAAc;oBAAGT,UAAU;oBAAIa,YAAY;gBAAO;0BAC9D,cAAA,MAACC;oBAAM1B,OAAO;wBAAEjD,SAAS;wBAAQC,YAAY;wBAAU2E,QAAQ;oBAAU;;sCACvE,KAACZ;4BACCC,MAAK;4BACLY,SAAS3C,eAAe/C,MAAM,KAAKJ,OAAOI,MAAM,IAAIJ,OAAOI,MAAM,GAAG;4BACpEgF,UAAU,CAACC,IAAMjC,eAAeiC,EAAEC,MAAM,CAACQ,OAAO,GAAG9F,OAAO+F,GAAG,CAAC,CAACrC,IAAMA,EAAEsC,QAAQ,IAAI,EAAE;4BACrF9B,OAAO;gCAAE+B,aAAa;4BAAE;;sCAE1B,MAACC;4BAAKhC,OAAO;gCAAES,OAAOtB,MAAMe,OAAO,CAACQ,IAAI,CAACa,OAAO;4BAAC;;gCAAG;gCAAazF,OAAOI,MAAM;gCAAC;;;;;;0BAGnF,KAAC+F;gBACCjC,OAAO;oBACLkC,QAAQ;oBACR7B,QAAQ;oBACR8B,WAAW,CAAC,UAAU,EAAEhD,MAAMe,OAAO,CAACI,OAAO,EAAE;gBACjD;;YAEDZ,eAAemC,GAAG,CAAC,CAACvH,OAAO8H,sBAC1B,KAACtC;oBAA2BE,OAAO;wBAAEqB,cAAc;oBAAE;8BACnD,cAAA,MAACK;wBACC1B,OAAO;4BACLjD,SAAS;4BACTC,YAAY;4BACZ2E,QAAQ;4BACR1B,SAAS;4BACT7C,cAAc;wBAChB;wBACAiF,cAAc,CAAClB;4BACbA,EAAEmB,aAAa,CAACtC,KAAK,CAAC3C,eAAe,GAAG8B,MAAMe,OAAO,CAACqC,MAAM,CAACC,KAAK;wBACpE;wBACAC,cAAc,CAACtB;4BACbA,EAAEmB,aAAa,CAACtC,KAAK,CAAC3C,eAAe,GAAG;wBAC1C;;0CAEA,KAAC0D;gCACCC,MAAK;gCACLY,SAAS3C,eAAeY,QAAQ,CAACvF,MAAMwH,QAAQ;gCAC/CZ,UAAU,CAACC;oCACT,IAAIA,EAAEC,MAAM,CAACQ,OAAO,EAAE;wCACpB1C,eAAe;+CAAID;4CAAgB3E,MAAMwH,QAAQ;yCAAC;oCACpD,OAAO;wCACL5C,eAAeD,eAAeM,MAAM,CAAC,CAACC,IAAMA,MAAMlF,MAAMwH,QAAQ;oCAClE;gCACF;gCACA9B,OAAO;oCAAE+B,aAAa;gCAAE;;0CAE1B,KAACC;gCACChC,OAAO;oCACLY,UAAU;oCACVH,OAAOtB,MAAMe,OAAO,CAACQ,IAAI,CAACa,OAAO;gCACnC;0CAECjH,UAAU,QAAQA,UAAUI,aAAaJ,MAAMoI,SAAS,KAAK,KAAK,YAAY/C,OAAOrF,MAAMoI,SAAS;;;;mBAlCjG,CAAC,MAAM,EAAEN,OAAO;;;AAyClC;AAEA;;;;CAIC,GACD,SAASO,qBACP9G,IAAY,EACZ+G,cAAgC,EAChCC,YAA8B,EAC9BC,kBAA8C,EAC9CjF,qBAAqC,EAAE;IAEvC,KAAK,MAAMM,UAAUyE,eAAgB;QACnC,IAAIzE,OAAOtC,IAAI,KAAKA,MAAM;YACxB,IAAIsC,OAAO4E,IAAI,EAAE;gBACf,OAAOrI;YACT;YAEA,MAAM,EAAEmB,IAAI,EAAEmH,MAAM,EAAEC,iBAAiB,EAAEC,aAAa,EAAEjG,KAAK,EAAEkG,KAAK,EAAEC,QAAQ,EAAE,GAAGjF;YACnF,MAAMkF,mBAAmBD,WACrB;gBAAE,GAAGA,QAAQ;gBAAEE,KAAK5J,yBAAyB0J,SAASE,GAAG,EAAET;YAAc,IACzEnI;YAEJ,OAAO;gBACL6I,aAAa1H;gBACbmH,QAAQA,UAAUnH;gBAClBoH;gBACAC;gBACAjG;gBACAkG;gBACAC,UAAUC;gBACV,GAAGnF,0BAA0BC,QAAQ2E,kBAAkB,CAACjH,KAAK,EAAEgC,mBAAmB;YACpF;QACF;IACF;IAEA,OAAO;QACL0F,aAAa1H;QACbmH,QAAQnH;IACV;AACF;AAEA,OAAO,SAAS2H,0BAA0BnI,IAAkB;IAC1D,wFAAwF;IACxF,OAAO;QACLoI,MAAMtJ,uBAAuBkB;IAC/B;AACF;AAIA,OAAO,SAASqI,WAAW,EAAEC,iBAAiB,EAAEtI,IAAI,EAAEwD,YAAY,EAAc;IAC9E,MAAMM,QAAQhG;IACd,MAAM0J,eAAelJ;IAErB,MAAMiK,mBAAmBvI,KAAKwI,SAAS,EAAEC,WAAW;IACpD,MAAM,EAAEC,YAAY,EAAEC,YAAY,EAAEC,cAAc,EAAE,GAAG1K;IAEvD,MAAM2K,oBAAoB7I,KAAK8I,OAAO,GAAI9I,KAAK8I,OAAO,GAAqBzJ;IAC3E,MAAM0J,wBACJF,mBAAmBJ,WAAWI,kBAAkBG,eAAe,GAAGH,kBAAkBI,WAAW,GAAG,EAAE;IAEtG,MAAM,EAAEC,oBAAoB,EAAEC,aAAa,EAAEC,aAAa,EAAE,GAAGjL,wBAAwB;QACrF2K,SAASC;QACTM,eAAe7B;IACjB;IAEA,MAAM8B,kBAAkB5K,OAAuC,EAAE;IAEjE,8DAA8D;IAC9D,MAAM6K,eAAe9K,QAAQ;QAC3B,MAAM+K,SAA4B,CAAC;QACnCd,aAAae,OAAO,CAAC,CAACC,GAAGC;YACvBH,MAAM,CAACG,GAAG,GAAG;QACf;QACA,OAAOH;IACT,GAAG;QAACd;KAAa;IAEjB,MAAMkB,2BAA2BrL,YAC/B,CAACsL;QACC,MAAMC,eAAqE,EAAE;QAC7E,KAAK,MAAM,CAACH,IAAII,WAAW,IAAIC,OAAOC,OAAO,CAACJ,iBAAkB;YAC9D,IAAIE,YAAY;gBACd,MAAMhD,QAAQmD,SAASP,IAAI;gBAC3B,IAAIL,gBAAgBa,OAAO,CAACpD,MAAM,KAAK1H,WAAW;oBAChDyK,aAAaM,IAAI,CAAC;wBAAET;wBAAIU,MAAMf,gBAAgBa,OAAO,CAACpD,MAAM;oBAAC;gBAC/D;YACF;QACF;QAEA,IAAI+C,aAAajJ,MAAM,KAAK,GAAG;YAC7B+H;QACF,OAAO;YACLD,aAAamB;QACf;IACF,GACA;QAACnB;QAAcC;KAAe;IAGhC,iCAAiC;IACjC,MAAM0B,UAA0C7L,QAAQ;QACtD,mEAAmE;QACnE,OAAOI,kBAAkB2E,cAAcxD;IACzC,GAAG;QAACwD;QAAcxD;KAAK;IAEvB,iEAAiE;IACjE,MAAMP,OAAOhB,QAAQ,IAAMR,cAAcqM,SAAStK,KAAKuK,UAAU,IAAI,EAAE,GAAG;QAACD;QAAStK,KAAKuK,UAAU;KAAC;IAEpG,MAAMC,OAAiB/L,QAAQ;QAC7B,MAAM+K,SAAmB,EAAE;QAE3B,KAAK,MAAMiB,SAAShL,KAAM;YACxB,KAAK,MAAMiL,OAAOV,OAAOQ,IAAI,CAACC,OAAQ;gBACpC,IAAI,CAACjB,OAAOhF,QAAQ,CAACkG,MAAM;oBACzBlB,OAAOY,IAAI,CAACM;gBACd;YACF;QACF;QAEA,wEAAwE;QACxE,oFAAoF;QACpF,KAAK,MAAMC,OAAO3K,KAAKuH,cAAc,IAAI,EAAE,CAAE;YAC3C,IAAI,CAACiC,OAAOhF,QAAQ,CAACmG,IAAInK,IAAI,GAAG;gBAC9BgJ,OAAOY,IAAI,CAACO,IAAInK,IAAI;YACtB;QACF;QAEA,OAAOgJ;IACT,GAAG;QAAC/J;QAAMO,KAAKuH,cAAc;KAAC;IAE9B,MAAMqD,gBAAgBnM,QAAQ;QAC5B,MAAMmM,gBAA+C,CAAC;QACtD,MAAMC,WAAW7K,MAAMuH;QACvB,IAAIsD,UAAU;YACZ,IAAK,IAAIC,IAAI,GAAGA,IAAID,SAAShK,MAAM,EAAEiK,IAAK;gBACxC,MAAM,EAAEtK,IAAI,EAAEW,MAAM,EAAE,GAAG0J,QAAQ,CAACC,EAAE,IAAI,CAAC;gBACzC,IAAItK,QAAQW,QAAQ;oBAClByJ,aAAa,CAACpK,KAAK,GAAGW;gBACxB;YACF;QACF;QAEA,OAAOyJ;IACT,GAAG;QAAC5K;KAAK;IAET,MAAM+K,qBAAqBtM,QAAQ;QACjC,MAAMuM,eAAkE,CAAC;QAEzE,KAAK,MAAMN,OAAOF,KAAM;YACtB,MAAMS,eAAeL,eAAe,CAACF,IAAI;YACzCM,YAAY,CAACN,IAAI,GAAG,EAAE;YACtB,MAAMQ,aAAgC,IAAIC;YAC1C,KAAK,MAAMC,OAAO3L,KAAM;gBACtB,MAAM4L,MAAMD,GAAG,CAACV,IAAI;gBACpB,IAAIW,QAAQ,MAAMA,QAAQ,QAAQA,QAAQhM,WAAW;oBACnD;gBACF;gBACA,IAAI6L,WAAWI,GAAG,CAAChH,OAAO+G,OAAO;oBAC/B;gBACF;gBAEA,IAAI,OAAOA,QAAQ,YAAY,OAAOA,QAAQ,UAAU;oBACtDL,YAAY,CAACN,IAAI,CAACN,IAAI,CAAC;wBACrB3D,UAAU4E;wBACVhE,WAAW4D,gBAAgB,OAAOI,QAAQ,WAAWtN,YAAYsN,KAAKJ,gBAAgBI;oBACxF;oBACAH,WAAWK,GAAG,CAACjH,OAAO+G,MAAM;gBAC9B;YACF;QACF;QACA,OAAOL;IACT,GAAG;QAACvL;QAAM+K;QAAMI;KAAc;IAE9B,MAAMnD,qBAAqBhJ,QAAQ;QACjC,MAAM+K,SAAqC,CAAC;QAE5C,KAAK,MAAMkB,OAAOF,KAAM;YACtB,IAAIlJ,MAAMpC,OAAOsM,iBAAiB;YAClC,IAAInK,MAAMnC,OAAOuM,iBAAiB;YAElC,KAAK,MAAML,OAAO3L,KAAM;gBACtB,MAAMG,eAAee,qBAAqByK,GAAG,CAACV,IAAI;gBAClD,IAAI9K,iBAAiBP,WAAW;oBAC9B;gBACF;gBACAiC,MAAMC,KAAKD,GAAG,CAACA,KAAK1B;gBACpByB,MAAME,KAAKF,GAAG,CAACA,KAAKzB;YACtB;YAEA,IAAI0B,QAAQpC,OAAOsM,iBAAiB,IAAInK,QAAQnC,OAAOuM,iBAAiB,EAAE;gBACxEjC,MAAM,CAACkB,IAAI,GAAG;oBAAEpJ;oBAAKD;gBAAI;YAC3B;QACF;QAEA,OAAOmI;IACT,GAAG;QAAC/J;QAAM+K;KAAK;IAEf,mFAAmF;IACnF,MAAMkB,UAA6CjN,QAAQ;QACzD,MAAMiN,UAA6C,EAAE;QACrD,MAAMC,oBAAoB,IAAI1H;QAE9B,uCAAuC;QACvC,KAAK,MAAM2H,iBAAiB5L,KAAKuH,cAAc,IAAI,EAAE,CAAE;YACrD,IAAIoE,kBAAkBE,GAAG,CAACD,cAAcpL,IAAI,GAAG,UAAU,kBAAkB;YAE3E,MAAMsL,eAAexE,qBACnBsE,cAAcpL,IAAI,EAClBR,KAAKuH,cAAc,IAAI,EAAE,EACzBC,cACAC,oBACAzH,KAAKsD,YAAY,IAAI,EAAE;YAEzB,IAAIwI,iBAAiBzM,WAAW;gBAC9BqM,QAAQtB,IAAI,CAAC0B;gBACbH,kBAAkBI,GAAG,CAACH,cAAcpL,IAAI;YAC1C;QACF;QAEA,wDAAwD;QACxD,IAAI,CAACR,KAAKgM,mBAAmB,EAAE;YAC7B,KAAK,MAAMtB,OAAOF,KAAM;gBACtB,IAAI,CAACmB,kBAAkBE,GAAG,CAACnB,MAAM;oBAC/B,MAAMoB,eAAexE,qBACnBoD,KACA1K,KAAKuH,cAAc,IAAI,EAAE,EACzBC,cACAC,oBACAzH,KAAKsD,YAAY,IAAI,EAAE;oBAEzB,IAAIwI,iBAAiBzM,WAAW;wBAC9BqM,QAAQtB,IAAI,CAAC0B;oBACf;gBACF;YACF;QACF;QAEA,OAAOJ;IACT,GAAG;QAAClB;QAAMxK,KAAKuH,cAAc;QAAEvH,KAAKgM,mBAAmB;QAAExE;QAAcC;QAAoBzH,KAAKsD,YAAY;KAAC;IAE7G,wGAAwG;IACxG,MAAM,CAAC2I,eAAeC,iBAAiB,GAAGvN,SAA6B,EAAE;IAEzE,2CAA2C;IAC3C,MAAMwN,eAAe1N,QAAQ;QAC3B,IAAI,CAACuB,KAAKoM,eAAe,IAAIH,cAAcpL,MAAM,KAAK,GAAG;YACvD,OAAOpB;QACT;QAEA,OAAOA,KAAKyE,MAAM,CAAC,CAACkH;YAClB,OAAOa,cAAcI,KAAK,CAAC,CAACnI;gBAC1B,MAAMjF,QAAQmM,GAAG,CAAClH,OAAOyF,EAAE,CAAC;gBAC5B,MAAM2C,eAAepI,OAAOjF,KAAK;gBAEjC,IAAI,CAACqN,gBAAgBA,aAAazL,MAAM,KAAK,GAAG,OAAO;gBAEvD,OAAOyL,aAAa9H,QAAQ,CAACvF;YAC/B;QACF;IACF,GAAG;QAACQ;QAAMwM;QAAejM,KAAKoM,eAAe;KAAC;IAE9C,4GAA4G;IAC5G,MAAMG,cAAgC9N,QAAQ;QAC5C,+EAA+E;QAC/E,IAAIuB,KAAKsD,YAAY,KAAKjE,aAAa,CAACW,KAAKuH,cAAc,EAAEiF,KAAK,CAAC7B,MAAQA,IAAIrH,YAAY,KAAKjE,YAAY;YAC1G,OAAO,CAAC;QACV;QAEA,MAAMmK,SAA2B,CAAC;QAElC,IAAIzC,QAAQ;QACZ,KAAK,MAAMqE,OAAOe,aAAc;YAC9B,+FAA+F;YAC/F,4DAA4D;YAC5D,MAAMM,YAAYjC,KAAKkC,MAAM,CAC3B,CAACC,KAAKjC;gBACJiC,GAAG,CAACjC,IAAI,GAAGrL;gBACX,OAAOsN;YACT,GACA,CAAC;YAGH,MAAMC,YAAY;gBAChB,GAAGH,SAAS;gBACZ,GAAGrB,GAAG;YACR;YAEA,qFAAqF;YACrF,KAAK,MAAM,CAACV,KAAKzL,MAAM,IAAI+K,OAAOC,OAAO,CAAC2C,WAAY;gBACpD,0DAA0D;gBAC1D,IAAIlK,aAAa9D,8BAA8BK,OAAOe,KAAKsD,YAAY,IAAI,EAAE;gBAE7E,kEAAkE;gBAClE,MAAMsI,gBAAgB5L,KAAKuH,cAAc,EAAEsF,KAAK,CAAClC,MAAQA,IAAInK,IAAI,KAAKkK;gBACtE,IAAIkB,eAAetI,cAAczC,QAAQ;oBACvC,MAAM8B,mBAAmB/D,8BAA8BK,OAAO2M,cAActI,YAAY;oBACxF,gEAAgE;oBAChE,IAAIX,kBAAkB;wBACpBD,aAAaC;oBACf;gBACF;gBAEA,IAAID,YAAY;oBACd8G,MAAM,CAAC,GAAGzC,MAAM,CAAC,EAAE2D,KAAK,CAAC,GAAGhI;gBAC9B;YACF;YACAqE;QACF;QAEA,OAAOyC;IACT,GAAG;QAAC2C;QAAc3B;QAAMxK,KAAKsD,YAAY;QAAEtD,KAAKuH,cAAc;KAAC;IAE/D,SAASuF;QACP,OACE9M,KAAKuH,cAAc,EACfrD,OAAO,CAACpB,SAAWA,OAAOsB,IAAI,KAAK/E,WACpCmH,IAAI,CAAC1D;YACJ,OAAO;gBACL6G,IAAI7G,OAAOtC,IAAI;gBACfuM,MAAMjK,OAAOsB,IAAI,KAAK;YACxB;QACF,MAAM,EAAE;IAEd;IAEA,MAAM,CAAC4I,SAASC,WAAW,GAAGtO,SAAuBmO;IAErD,MAAM,CAACI,gBAAgBC,kBAAkB,GAAGxO,SAAgD,CAAC;IAC7F,MAAM,CAACyO,kBAAkBC,oBAAoB,GAAG1O,SAAwB;IAExE,mCAAmC;IACnC,MAAM2O,0BAA0B,CAACC;QAC/B,MAAMrJ,SAAS+H,cAAcY,IAAI,CAAC,CAACW,IAAMA,EAAE7D,EAAE,KAAK4D;QAClD,OAAOrJ,SAAUA,OAAOjF,KAAK,GAA8B,EAAE;IAC/D;IAEA,uBAAuB;IACvB,MAAMwO,qBAAqB,CAACF,UAAkB9M;QAC5C,MAAMiN,aAAazB,cAAc/H,MAAM,CAAC,CAACsJ,IAAMA,EAAE7D,EAAE,KAAK4D;QACxD,IAAI9M,OAAOI,MAAM,GAAG,GAAG;YACrB6M,WAAWtD,IAAI,CAAC;gBAAET,IAAI4D;gBAAUtO,OAAOwB;YAAO;QAChD;QACAyL,iBAAiBwB;IACnB;IAEA,uBAAuB;IACvB,MAAMC,oBAAoB,CAACC,OAA4CL;QACrEK,MAAMC,cAAc;QACpBD,MAAME,eAAe;QACrBX,kBAAkB;YAAE,GAAGD,cAAc;YAAE,CAACK,SAAS,EAAEK,MAAM3G,aAAa;QAAC;QACvEoG,oBAAoBE;IACtB;IAEA,MAAMQ,oBAAoB;QACxBZ,kBAAkB,CAAC;QACnBE,oBAAoB;IACtB;IAEA,qCAAqC;IACrC7O,UAAU;QACR,IAAI,CAAC4O,kBAAkB;QAEvB,MAAMY,cAAc,CAAClI;YACnB,MAAMC,SAASD,EAAEC,MAAM;YACvB,IAAI,CAACA,OAAOkI,OAAO,CAAC,6BAA6B,CAAClI,OAAOkI,OAAO,CAAC,WAAW;gBAC1EF;YACF;QACF;QAEA,MAAMG,QAAQC,WAAW;YACvBC,SAASC,gBAAgB,CAAC,SAASL;QACrC,GAAG;QAEH,OAAO;YACLM,aAAaJ;YACbE,SAASG,mBAAmB,CAAC,SAASP;QACxC;IACF,GAAG;QAACZ;KAAiB;IAErB,mEAAmE;IACnE9D,gBAAgBa,OAAO,GAAGgC;IAE1B,MAAM,CAACqC,YAAYC,cAAc,GAAG9P,SAClCqB,KAAKwO,UAAU,GAAG;QAAEE,WAAW;QAAGC,UAAU;IAAG,IAAItP;IAGrDb,UAAU;QACR,yIAAyI;QACzI,IAAIwB,KAAKwO,UAAU,IAAI,CAACA,YAAY;YAClCC,cAAc;gBAAEC,WAAW;gBAAGC,UAAU;YAAG;QAC7C,OAAO,IAAI,CAAC3O,KAAKwO,UAAU,IAAIA,YAAY;YACzCC,cAAcpP;QAChB;IACF,GAAG;QAACW,KAAKwO,UAAU;QAAEA;KAAW;IAEhC,IAAIlG,sBAAsBjJ,WAAW;QACnC,OAAO;IACT;IAEA,IAAI,CAACI,MAAMoB,QAAQ;QACjB,qBACE,KAACjD;YACC6D,IAAI;gBACFC,SAAS;gBACTkN,gBAAgB;gBAChBjN,YAAY;gBACZM,QAAQ;YACV;sBAEA,cAAA,KAACpE;0BAAW;;;IAGlB;IAEA,qBACE;;YACGsL;YACAnJ,KAAKoM,eAAe,kBACnB,KAAC3H;gBACCE,OAAO;oBACLjD,SAAS;oBACToD,YAAYhB,MAAMe,OAAO,CAACC,UAAU,CAACmB,OAAO;oBAC5C4I,cAAc,CAAC,UAAU,EAAE/K,MAAMe,OAAO,CAACI,OAAO,EAAE;oBAClDrD,OAAO0G,kBAAkB1G,KAAK;oBAC9BuE,WAAW;gBACb;0BAECuF,QAAQlF,GAAG,CAAC,CAAC1D,QAAQgM;oBACpB,MAAMC,UAAUzB,wBAAwBxK,OAAOoF,WAAW;oBAC1D,MAAM8G,cAAclM,OAAOlB,KAAK,IAAI5B,KAAKiP,kBAAkB;oBAC3D,qBACE,MAACxK;wBAECE,OAAO;4BACLC,SAAS;4BACTsK,aAAaJ,MAAMpD,QAAQ7K,MAAM,GAAG,IAAI,CAAC,UAAU,EAAEiD,MAAMe,OAAO,CAACI,OAAO,EAAE,GAAG;4BAC/ErD,OAAOoN;4BACP5M,UAAU4M;4BACVG,UAAUH;4BACVtN,SAAS;4BACTC,YAAY;4BACZyN,UAAU;4BACVjJ,WAAW;4BACXkJ,MAAM,OAAOL,gBAAgB,WAAW,SAAS;wBACnD;;0CAEA,KAACrI;gCACChC,OAAO;oCACL+B,aAAa;oCACbnB,UAAU;oCACVH,OAAOtB,MAAMe,OAAO,CAACQ,IAAI,CAACC,SAAS;oCACnC+J,MAAM;oCACNnN,UAAU;oCACVoN,cAAc;oCACdC,YAAY;gCACd;0CAECR,QAAQlO,MAAM,GAAG,GAAGkO,QAAQlO,MAAM,CAAC,MAAM,CAAC,GAAG;;0CAEhD,KAAC2O;gCACCC,SAAS,CAAC3J;oCACR6H,kBAAkB7H,GAAGhD,OAAOoF,WAAW;gCACzC;gCACAvD,OAAO;oCACLK,QAAQ,CAAC,UAAU,EAAElB,MAAMe,OAAO,CAACI,OAAO,EAAE;oCAC5CH,YAAYhB,MAAMe,OAAO,CAACC,UAAU,CAACC,KAAK;oCAC1CuB,QAAQ;oCACRf,UAAU;oCACVH,OAAO2J,QAAQlO,MAAM,GAAGiD,MAAMe,OAAO,CAACqB,OAAO,CAACwJ,IAAI,GAAG5L,MAAMe,OAAO,CAACQ,IAAI,CAACC,SAAS;oCACjFV,SAAS;oCACT7C,cAAc;oCACdK,UAAU;oCACVH,QAAQ;oCACR0N,YAAY;oCACZC,YAAY;gCACd;gCACA5I,cAAc,CAAClB;oCACbA,EAAEmB,aAAa,CAACtC,KAAK,CAACG,UAAU,GAAGhB,MAAMe,OAAO,CAACqC,MAAM,CAACC,KAAK;gCAC/D;gCACAC,cAAc,CAACtB;oCACbA,EAAEmB,aAAa,CAACtC,KAAK,CAACG,UAAU,GAAGhB,MAAMe,OAAO,CAACC,UAAU,CAACC,KAAK;gCACnE;gCACAY,MAAK;0CACN;;4BAIAyH,qBAAqBtK,OAAOoF,WAAW,kBACtC,KAACzD;gCACCE,OAAO;oCACLyK,UAAU;oCACVS,KAAK;oCACLC,MAAM;oCACNC,QAAQ;oCACRC,WAAW;gCACb;0CAEA,cAAA,KAACtM;oCACCC,WAAWoH,kBAAkB,CAACjI,OAAOoF,WAAW,CAAW,IAAI,EAAE;oCACjEtE,gBAAgBmL;oCAChBlL,gBAAgB,CAACpD,SAAWgN,mBAAmB3K,OAAOoF,WAAW,EAAYzH;oCAC7EqD,OAAOA;;;;uBArER,CAAC,OAAO,EAAEgL,KAAK;gBA2E1B;;0BAGJ,KAAC9Q;gBACCyB,MAAM0M;gBACNT,SAASA;gBACTa,aAAaA;gBACbtK,QAAQjC,KAAKoM,eAAe,GAAG9D,kBAAkBrG,MAAM,GAAG,KAAKqG,kBAAkBrG,MAAM;gBACvFL,OAAO0G,kBAAkB1G,KAAK;gBAC9BqO,SAASjQ,KAAKiQ,OAAO;gBACrBhB,oBAAoBjP,KAAKiP,kBAAkB;gBAC3CiB,qBAAqBlQ,KAAKkQ,mBAAmB;gBAC7ClD,SAASA;gBACTmD,iBAAiBlD;gBACjBuB,YAAYA;gBACZ4B,oBAAoB3B;gBACpB4B,mBAAmB9H;gBACnBgB,cAAcA;gBACd+G,sBAAsB1G;gBACtB2G,gBAAgB,CAAC,EAAE5G,EAAE,EAAElK,IAAI,EAAE,GAAKyJ,qBAAqB;wBAAES;wBAAIlK,MAAMA;oBAAgC;gBACnG+Q,gBAAgBpH,iBAAiBA,cAAcvI,MAAM,GAAG;;;;AAIhE"}
@@ -122,6 +122,10 @@ export declare const MOCK_NULL_QUERY_RESULT: {
122
122
  isRefetchError: boolean;
123
123
  isStale: boolean;
124
124
  }[];
125
+ export declare const MOCK_MULTI_QUERY_DATA_Q1: TimeSeriesData;
126
+ export declare const MOCK_MULTI_QUERY_DATA_Q2: TimeSeriesData;
127
+ export declare const MOCK_MULTI_QUERY_DATA_WITH_ZERO: TimeSeriesData;
128
+ export declare const MOCK_MULTI_QUERY_DATA_EMPTY: TimeSeriesData;
125
129
  export declare const MOCK_TIME_SERIES_QUERY_DEFINITION: {
126
130
  kind: string;
127
131
  spec: {
@@ -1 +1 @@
1
- {"version":3,"file":"mock-query-results.d.ts","sourceRoot":"","sources":["../../../src/test/mock-query-results.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,eAAO,MAAM,wCAAwC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DpD,CAAC;AAEF,eAAO,MAAM,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDrD,CAAC;AAEF,eAAO,MAAM,gCAAgC,EAAE,cAsC9C,CAAC;AAEF,eAAO,MAAM,iCAAiC,EAAE,cAgC/C,CAAC;AAEF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgElC,CAAC;AAEF,eAAO,MAAM,iCAAiC;;;;;;;;;;CAU7C,CAAC"}
1
+ {"version":3,"file":"mock-query-results.d.ts","sourceRoot":"","sources":["../../../src/test/mock-query-results.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,eAAO,MAAM,wCAAwC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DpD,CAAC;AAEF,eAAO,MAAM,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDrD,CAAC;AAEF,eAAO,MAAM,gCAAgC,EAAE,cAsC9C,CAAC;AAEF,eAAO,MAAM,iCAAiC,EAAE,cAgC/C,CAAC;AAEF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgElC,CAAC;AAIF,eAAO,MAAM,wBAAwB,EAAE,cAetC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,cAWtC,CAAC;AAIF,eAAO,MAAM,+BAA+B,EAAE,cAe7C,CAAC;AAIF,eAAO,MAAM,2BAA2B,EAAE,cAIzC,CAAC;AAEF,eAAO,MAAM,iCAAiC;;;;;;;;;;CAU7C,CAAC"}
@@ -374,6 +374,107 @@ export const MOCK_NULL_QUERY_RESULT = [
374
374
  isStale: true
375
375
  }
376
376
  ];
377
+ // Two queries where Query 1 covers both namespaces but Query 2 only covers one.
378
+ // After MergeSeries + JoinByColumnValue, ns-b will have null for value #2.
379
+ export const MOCK_MULTI_QUERY_DATA_Q1 = {
380
+ timeRange: {
381
+ start: new Date(1666625535000),
382
+ end: new Date(1666625535000)
383
+ },
384
+ stepMs: 24379,
385
+ series: [
386
+ {
387
+ name: 'namespace="ns-a"',
388
+ values: [
389
+ [
390
+ 1666479357903,
391
+ 100
392
+ ]
393
+ ],
394
+ labels: {
395
+ namespace: 'ns-a'
396
+ }
397
+ },
398
+ {
399
+ name: 'namespace="ns-b"',
400
+ values: [
401
+ [
402
+ 1666479357903,
403
+ 200
404
+ ]
405
+ ],
406
+ labels: {
407
+ namespace: 'ns-b'
408
+ }
409
+ }
410
+ ]
411
+ };
412
+ export const MOCK_MULTI_QUERY_DATA_Q2 = {
413
+ timeRange: {
414
+ start: new Date(1666625535000),
415
+ end: new Date(1666625535000)
416
+ },
417
+ stepMs: 24379,
418
+ series: [
419
+ {
420
+ name: 'namespace="ns-a"',
421
+ values: [
422
+ [
423
+ 1666479357903,
424
+ 50
425
+ ]
426
+ ],
427
+ labels: {
428
+ namespace: 'ns-a'
429
+ }
430
+ }
431
+ ]
432
+ };
433
+ // Query where a namespace has genuine zero value (not null).
434
+ // Used to verify 0 is rendered as 0, not as N/A.
435
+ export const MOCK_MULTI_QUERY_DATA_WITH_ZERO = {
436
+ timeRange: {
437
+ start: new Date(1666625535000),
438
+ end: new Date(1666625535000)
439
+ },
440
+ stepMs: 24379,
441
+ series: [
442
+ {
443
+ name: 'namespace="ns-a"',
444
+ values: [
445
+ [
446
+ 1666479357903,
447
+ 50
448
+ ]
449
+ ],
450
+ labels: {
451
+ namespace: 'ns-a'
452
+ }
453
+ },
454
+ {
455
+ name: 'namespace="ns-b"',
456
+ values: [
457
+ [
458
+ 1666479357903,
459
+ 0
460
+ ]
461
+ ],
462
+ labels: {
463
+ namespace: 'ns-b'
464
+ }
465
+ }
466
+ ]
467
+ };
468
+ // Query that returns no data at all — simulates a metric like cpu_request_hard
469
+ // when no ResourceQuotas exist on the cluster.
470
+ export const MOCK_MULTI_QUERY_DATA_EMPTY = {
471
+ timeRange: {
472
+ start: new Date(1666625535000),
473
+ end: new Date(1666625535000)
474
+ },
475
+ stepMs: 24379,
476
+ series: []
477
+ };
377
478
  export const MOCK_TIME_SERIES_QUERY_DEFINITION = {
378
479
  kind: 'TimeSeriesQuery',
379
480
  spec: {