@perses-dev/table-plugin 0.14.0-rc.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__mf/js/{Table.a3908f66.js → Table.ebbb2ee7.js} +7 -7
- package/__mf/js/async/1186.c3ecd87e.js +2 -0
- package/__mf/js/async/1616.25e2199d.js +1 -0
- package/__mf/js/async/2035.8c5e1b3d.js +1 -0
- package/__mf/js/async/2043.8461503c.js +2 -0
- package/__mf/js/async/{2062.db498990.js → 2062.73e78253.js} +2 -2
- package/__mf/js/async/2465.9316e1cb.js +1 -0
- package/__mf/js/async/{3632.a80fa015.js → 3632.84ef6cd5.js} +1 -1
- package/__mf/js/async/392.51a9627f.js +2 -0
- package/__mf/js/async/3923.c6b1145c.js +1 -0
- package/__mf/js/async/4077.6f37cf93.js +1 -0
- package/__mf/js/async/4121.a6ca4bac.js +2 -0
- package/__mf/js/async/4122.0a04e6f7.js +37 -0
- package/__mf/js/async/4496.4877c6e5.js +1 -0
- package/__mf/js/async/5002.0e743a8d.js +1 -0
- package/__mf/js/async/5054.1c50fb8f.js +1 -0
- package/__mf/js/async/5071.f8c5a819.js +1 -0
- package/__mf/js/async/5153.7d0d7795.js +1 -0
- package/__mf/js/async/5587.6d6a3639.js +1 -0
- package/__mf/js/async/{5741.675e49c8.js → 5741.5f6a7a5a.js} +2 -2
- package/__mf/js/async/6274.43b1d3bc.js +2 -0
- package/__mf/js/async/7192.dd906218.js +1 -0
- package/__mf/js/async/7534.f7d12a3b.js +1 -0
- package/__mf/js/async/7862.5452c56f.js +2 -0
- package/__mf/js/async/{7893.377f2764.js → 7893.c43cf786.js} +4 -4
- package/__mf/js/async/7968.7e226d7f.js +1 -0
- package/__mf/js/async/7978.615f9fe5.js +1 -0
- package/__mf/js/async/8356.a755a055.js +1 -0
- package/__mf/js/async/8470.9d08d819.js +2 -0
- package/__mf/js/async/873.e2f78af4.js +1 -0
- package/__mf/js/async/9207.fcade851.js +1 -0
- package/__mf/js/async/9235.b5f3e126.js +1 -0
- package/__mf/js/async/9321.1fda940e.js +1 -0
- package/__mf/js/async/941.b9f95391.js +2 -0
- package/__mf/js/async/9588.f644ab7e.js +1 -0
- package/__mf/js/async/9996.043596d6.js +3 -0
- package/__mf/js/async/__federation_expose_Table.ff254b34.js +1 -0
- package/__mf/js/async/lib-router.96610317.js +2 -0
- package/__mf/js/{main.7b8cd485.js → main.a12bf036.js} +2 -2
- package/lib/components/TablePanel.d.ts.map +1 -1
- package/lib/components/TablePanel.js +3 -3
- package/lib/components/TablePanel.js.map +1 -1
- package/lib/models/table-model.d.ts +2 -2
- package/lib/models/table-model.d.ts.map +1 -1
- package/lib/models/table-model.js +6 -4
- package/lib/models/table-model.js.map +1 -1
- package/mf-manifest.json +46 -46
- package/mf-stats.json +46 -46
- package/package.json +5 -5
- package/__mf/js/async/1186.c1b14e64.js +0 -2
- package/__mf/js/async/1616.58269394.js +0 -1
- package/__mf/js/async/2035.9b7993d8.js +0 -1
- package/__mf/js/async/2043.231e3e9c.js +0 -2
- package/__mf/js/async/2465.a95673ec.js +0 -1
- package/__mf/js/async/392.16b8c016.js +0 -2
- package/__mf/js/async/3923.1a5a1a34.js +0 -1
- package/__mf/js/async/4077.4d399855.js +0 -1
- package/__mf/js/async/4121.28d73fa4.js +0 -2
- package/__mf/js/async/4122.c44aa0dd.js +0 -37
- package/__mf/js/async/4496.1555a936.js +0 -1
- package/__mf/js/async/5002.da5c7909.js +0 -1
- package/__mf/js/async/5054.ceb0de94.js +0 -1
- package/__mf/js/async/5071.25ee2344.js +0 -1
- package/__mf/js/async/5153.d0a5188e.js +0 -1
- package/__mf/js/async/5587.ae5b65d8.js +0 -1
- package/__mf/js/async/6274.a022b53a.js +0 -2
- package/__mf/js/async/7192.13903b23.js +0 -1
- package/__mf/js/async/7534.cc00b47e.js +0 -1
- package/__mf/js/async/7862.86d45646.js +0 -2
- package/__mf/js/async/7968.6d77e809.js +0 -1
- package/__mf/js/async/7978.e4341773.js +0 -1
- package/__mf/js/async/8356.6fc36a50.js +0 -1
- package/__mf/js/async/8470.a7afb117.js +0 -2
- package/__mf/js/async/873.cf58d4f4.js +0 -1
- package/__mf/js/async/9207.1bb95977.js +0 -1
- package/__mf/js/async/9235.d62a73ea.js +0 -1
- package/__mf/js/async/9321.d6e366f3.js +0 -1
- package/__mf/js/async/941.99874609.js +0 -2
- package/__mf/js/async/9588.29a8dbd5.js +0 -1
- package/__mf/js/async/9996.438ee6a0.js +0 -3
- package/__mf/js/async/__federation_expose_Table.98b8d4f5.js +0 -1
- package/__mf/js/async/lib-router.b83965b4.js +0 -2
- /package/__mf/js/async/{2043.231e3e9c.js.LICENSE.txt → 2043.8461503c.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{2062.db498990.js.LICENSE.txt → 2062.73e78253.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{392.16b8c016.js.LICENSE.txt → 392.51a9627f.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{4121.28d73fa4.js.LICENSE.txt → 4121.a6ca4bac.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{5741.675e49c8.js.LICENSE.txt → 5741.5f6a7a5a.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{6274.a022b53a.js.LICENSE.txt → 6274.43b1d3bc.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{7862.86d45646.js.LICENSE.txt → 7862.5452c56f.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{7893.377f2764.js.LICENSE.txt → 7893.c43cf786.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{8470.a7afb117.js.LICENSE.txt → 8470.9d08d819.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{941.99874609.js.LICENSE.txt → 941.b9f95391.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{lib-router.b83965b4.js.LICENSE.txt → lib-router.96610317.js.LICENSE.txt} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TablePanel.d.ts","sourceRoot":"","sources":["../../../src/components/TablePanel.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAA4B,UAAU,EAAoB,MAAM,2BAA2B,CAAC;AAExG,OAAO,KAAK,EAAE,QAAQ,EAAiB,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C,OAAO,KAAK,EAAgC,YAAY,EAAE,MAAM,WAAW,CAAC;AAwV5E,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,GAAG,QAAQ,CAAC,CAAC;AAE7E,wBAAgB,UAAU,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"TablePanel.d.ts","sourceRoot":"","sources":["../../../src/components/TablePanel.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAA4B,UAAU,EAAoB,MAAM,2BAA2B,CAAC;AAExG,OAAO,KAAK,EAAE,QAAQ,EAAiB,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C,OAAO,KAAK,EAAgC,YAAY,EAAE,MAAM,WAAW,CAAC;AAwV5E,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,GAAG,QAAQ,CAAC,CAAC;AAE7E,wBAAgB,UAAU,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI,CA6lBrG"}
|
|
@@ -600,12 +600,12 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
|
|
|
600
600
|
};
|
|
601
601
|
// Generate cellConfigs for each column (including duplicates with different headers)
|
|
602
602
|
for (const [key, value] of Object.entries(extendRow)){
|
|
603
|
+
const columnSetting = spec.columnSettings?.find((col)=>col.name === key);
|
|
603
604
|
// First, try to get cell config from global cell settings
|
|
604
|
-
let cellConfig = evaluateConditionalFormatting(value, spec.cellSettings ?? []);
|
|
605
|
+
let cellConfig = evaluateConditionalFormatting(value, spec.cellSettings ?? [], columnSetting);
|
|
605
606
|
// Then, try to get cell config from column-specific cell settings
|
|
606
|
-
const columnSetting = spec.columnSettings?.find((col)=>col.name === key);
|
|
607
607
|
if (columnSetting?.cellSettings?.length) {
|
|
608
|
-
const columnCellConfig = evaluateConditionalFormatting(value, columnSetting.cellSettings);
|
|
608
|
+
const columnCellConfig = evaluateConditionalFormatting(value, columnSetting.cellSettings, columnSetting);
|
|
609
609
|
// Column-specific settings take precedence over global settings
|
|
610
610
|
if (columnCellConfig) {
|
|
611
611
|
cellConfig = columnCellConfig;
|
|
@@ -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 type { Theme } from '@mui/material';\nimport { Box, Typography, useTheme } from '@mui/material';\nimport type { FormatOptions, TableCellConfigs, TableColumnConfig } from '@perses-dev/components';\nimport { formatValue, Table, transformData, useSelection } from '@perses-dev/components';\nimport { useSelectionItemActions } from '@perses-dev/dashboards';\nimport type { ActionOptions, PanelData, PanelProps, VariableStateMap } from '@perses-dev/plugin-system';\nimport { CalculationsMap, replaceVariablesInString, useAllVariableValues } from '@perses-dev/plugin-system';\nimport type { JsonData, QueryDataType, TimeSeriesData } from '@perses-dev/spec';\nimport type { ColumnFiltersState, PaginationState, RowSelectionState, SortingState } from '@tanstack/react-table';\nimport type { ReactElement } from 'react';\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport type { CellSettings, ColumnSettings, TableOptions } from '../models';\nimport { evaluateConditionalFormatting } 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<ReactElement | string | number>();\n return typeof cellValue === 'number' && column.format\n ? formatValue(cellValue, column.format)\n : (cellValue as ReactElement | string);\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).toSorted();\n const filteredValues = searchTerm\n ? values.filter((v) => String(v.formatted).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 <Box\n component=\"label\"\n sx={{\n display: 'flex',\n alignItems: 'center',\n cursor: 'pointer',\n padding: '2px 0',\n borderRadius: '2px',\n '&:hover': {\n backgroundColor: theme.palette.action.hover,\n },\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 </Box>\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 defaultEnableSorting = false,\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: enableSorting ?? defaultEnableSorting,\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 enableSorting: defaultEnableSorting,\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 | JsonData>;\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 // Refs used to keep the filter row in sync with the table's horizontal\n const [panelContainer, setPanelContainer] = useState<HTMLDivElement | null>(null);\n const filterRowInnerRef = useRef<HTMLDivElement>(null);\n const filterCellRefs = useRef<Array<HTMLDivElement | null>>([]);\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 spec.enableSorting ?? false,\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 spec.enableSorting ?? false,\n );\n if (columnConfig !== undefined) {\n columns.push(columnConfig);\n }\n }\n }\n }\n\n return columns;\n }, [\n keys,\n spec.columnSettings,\n spec.defaultColumnHidden,\n spec.enableSorting,\n allVariables,\n gaugeRangeByColumn,\n spec.cellSettings,\n ]);\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\n if (openFilterColumn === columnId) {\n handleFilterClose();\n return;\n }\n\n setFilterAnchorEl({ ...filterAnchorEl, [columnId]: event.currentTarget });\n setOpenFilterColumn(columnId);\n };\n\n const handleFilterClose = useCallback((): 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, handleFilterClose]);\n\n // Keep ref in sync with filtered data for use in selection handler\n useLayoutEffect(() => {\n filteredDataRef.current = filteredData;\n }, [filteredData]);\n\n const [pagination, setPagination] = useState<PaginationState | undefined>(\n spec.pagination ? { pageIndex: 0, pageSize: 10 } : undefined,\n );\n\n if (spec.pagination && !pagination) {\n setPagination({ pageIndex: 0, pageSize: 10 });\n } else if (!spec.pagination && pagination) {\n setPagination(undefined);\n }\n\n // Sync the filter row's horizontal position with the table scroll.\n useEffect(() => {\n if (!spec.enableFiltering) {\n return;\n }\n\n const scrollContainer = panelContainer?.querySelector<HTMLElement>('.MuiTableContainer-root');\n const filterRowInner = filterRowInnerRef.current;\n\n if (!scrollContainer || !filterRowInner) {\n return;\n }\n\n const syncFilterRowScroll = (): void => {\n filterRowInner.style.transform = `translateX(-${scrollContainer.scrollLeft}px)`;\n\n setOpenFilterColumn((current) => (current === null ? current : null));\n setFilterAnchorEl((current) => (Object.keys(current).length === 0 ? current : {}));\n };\n\n filterRowInner.style.transform = `translateX(-${scrollContainer.scrollLeft}px)`;\n\n scrollContainer.addEventListener('scroll', syncFilterRowScroll, { passive: true });\n return (): void => {\n scrollContainer.removeEventListener('scroll', syncFilterRowScroll);\n };\n }, [panelContainer, spec.enableFiltering]);\n\n // Sync filter cell widths with the actual rendered table column widths to keep them aligned.\n useEffect(() => {\n if (!spec.enableFiltering) {\n return;\n }\n\n const scrollContainer = panelContainer?.querySelector<HTMLElement>('.MuiTableContainer-root');\n if (!scrollContainer) {\n return;\n }\n\n const syncColumnWidths = (): void => {\n const headerCells = scrollContainer.querySelectorAll<HTMLElement>('thead tr th');\n\n columns.forEach((_, idx) => {\n const headerCell = headerCells[idx];\n const filterCell = filterCellRefs.current[idx];\n if (!headerCell || !filterCell) {\n return;\n }\n\n const width = `${headerCell.getBoundingClientRect().width}px`;\n filterCell.style.width = width;\n filterCell.style.minWidth = width;\n filterCell.style.maxWidth = width;\n });\n };\n\n // Re-sync whenever the header row's size changes.\n const resizeObserver = new ResizeObserver(syncColumnWidths);\n // The virtualized table remounts its header row when its width, rows, or columns change,\n // so follow the current header row instead of observing a detached one.\n let headerRow: Element | null = null;\n const observeHeaderRow = (): void => {\n const currentHeaderRow = scrollContainer.querySelector('thead tr');\n if (currentHeaderRow === headerRow) {\n return;\n }\n if (headerRow) {\n resizeObserver.unobserve(headerRow);\n }\n headerRow = currentHeaderRow;\n if (headerRow) {\n resizeObserver.observe(headerRow);\n }\n syncColumnWidths();\n };\n\n observeHeaderRow();\n const mutationObserver = new MutationObserver(observeHeaderRow);\n mutationObserver.observe(scrollContainer, { childList: true, subtree: true });\n\n return (): void => {\n mutationObserver.disconnect();\n resizeObserver.disconnect();\n };\n }, [panelContainer, spec.enableFiltering, columns]);\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 <div ref={setPanelContainer} style={{ display: 'contents' }}>\n {confirmDialog}\n {spec.enableFiltering && (\n <div\n style={{\n overflow: 'hidden',\n background: theme.palette.background.default,\n borderBottom: `1px solid ${theme.palette.divider}`,\n width: contentDimensions.width,\n boxSizing: 'border-box',\n }}\n >\n <div\n ref={filterRowInnerRef}\n style={{\n display: 'flex',\n width: 'max-content',\n willChange: 'transform',\n }}\n >\n {columns.map((column, idx) => {\n const filters = getSelectedFilterValues(column.accessorKey as string);\n const columnWidth = column.width || spec.defaultColumnWidth;\n const anchorEl = filterAnchorEl[column.accessorKey as string];\n\n return (\n <div\n key={`column-${column.accessorKey}`}\n ref={(el) => {\n filterCellRefs.current[idx] = el;\n }}\n style={{\n padding: '8px',\n borderRight: idx < columns.length - 1 ? `1px solid ${theme.palette.divider}` : 'none',\n // These are just a starting size for the first paint —\n // the width-sync effect above overwrites them with the\n // table's actual rendered column widths.\n width: columnWidth,\n minWidth: columnWidth,\n maxWidth: columnWidth,\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n boxSizing: 'border-box',\n flex: 'none',\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 anchorEl &&\n createPortal(\n <div\n style={{\n position: 'fixed',\n top: anchorEl.getBoundingClientRect().bottom + 4,\n left: anchorEl.getBoundingClientRect().left,\n zIndex: theme.zIndex.modal,\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 document.body,\n )}\n </div>\n );\n })}\n </div>\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 </div>\n );\n}\n"],"names":["Box","Typography","useTheme","formatValue","Table","transformData","useSelection","useSelectionItemActions","CalculationsMap","replaceVariablesInString","useAllVariableValues","useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","createPortal","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","toSorted","filteredValues","String","formatted","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","component","action","hover","generateColumnConfig","columnSettings","allVariables","gaugeRangeByColumn","defaultEnableSorting","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","panelContainer","setPanelContainer","filterRowInnerRef","filterCellRefs","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","sort","desc","sorting","setSorting","filterAnchorEl","setFilterAnchorEl","openFilterColumn","setOpenFilterColumn","getSelectedFilterValues","columnId","f","updateColumnFilter","newFilters","handleFilterClick","event","preventDefault","stopPropagation","handleFilterClose","currentTarget","handleClick","closest","timer","setTimeout","document","addEventListener","clearTimeout","removeEventListener","pagination","setPagination","pageIndex","pageSize","scrollContainer","querySelector","filterRowInner","syncFilterRowScroll","transform","scrollLeft","passive","syncColumnWidths","headerCells","querySelectorAll","idx","headerCell","filterCell","getBoundingClientRect","maxWidth","resizeObserver","ResizeObserver","headerRow","observeHeaderRow","currentHeaderRow","unobserve","observe","mutationObserver","MutationObserver","childList","subtree","disconnect","justifyContent","ref","borderBottom","willChange","filters","columnWidth","defaultColumnWidth","anchorEl","el","borderRight","position","flex","textOverflow","whiteSpace","button","onClick","main","flexShrink","transition","onMouseEnter","onMouseLeave","top","bottom","left","zIndex","modal","body","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 type { Theme } from '@mui/material';\nimport { Box, Typography, useTheme } from '@mui/material';\nimport type { FormatOptions, TableCellConfigs, TableColumnConfig } from '@perses-dev/components';\nimport { formatValue, Table, transformData, useSelection } from '@perses-dev/components';\nimport { useSelectionItemActions } from '@perses-dev/dashboards';\nimport type { ActionOptions, PanelData, PanelProps, VariableStateMap } from '@perses-dev/plugin-system';\nimport { CalculationsMap, replaceVariablesInString, useAllVariableValues } from '@perses-dev/plugin-system';\nimport type { JsonData, QueryDataType, TimeSeriesData } from '@perses-dev/spec';\nimport type { ColumnFiltersState, PaginationState, RowSelectionState, SortingState } from '@tanstack/react-table';\nimport type { ReactElement } from 'react';\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport type { CellSettings, ColumnSettings, TableOptions } from '../models';\nimport { evaluateConditionalFormatting } 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<ReactElement | string | number>();\n return typeof cellValue === 'number' && column.format\n ? formatValue(cellValue, column.format)\n : (cellValue as ReactElement | string);\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).toSorted();\n const filteredValues = searchTerm\n ? values.filter((v) => String(v.formatted).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 <Box\n component=\"label\"\n sx={{\n display: 'flex',\n alignItems: 'center',\n cursor: 'pointer',\n padding: '2px 0',\n borderRadius: '2px',\n '&:hover': {\n backgroundColor: theme.palette.action.hover,\n },\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 </Box>\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 defaultEnableSorting = false,\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: enableSorting ?? defaultEnableSorting,\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 enableSorting: defaultEnableSorting,\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 | JsonData>;\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 // Refs used to keep the filter row in sync with the table's horizontal\n const [panelContainer, setPanelContainer] = useState<HTMLDivElement | null>(null);\n const filterRowInnerRef = useRef<HTMLDivElement>(null);\n const filterCellRefs = useRef<Array<HTMLDivElement | null>>([]);\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 spec.enableSorting ?? false,\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 spec.enableSorting ?? false,\n );\n if (columnConfig !== undefined) {\n columns.push(columnConfig);\n }\n }\n }\n }\n\n return columns;\n }, [\n keys,\n spec.columnSettings,\n spec.defaultColumnHidden,\n spec.enableSorting,\n allVariables,\n gaugeRangeByColumn,\n spec.cellSettings,\n ]);\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 const columnSetting = spec.columnSettings?.find((col) => col.name === key);\n\n // First, try to get cell config from global cell settings\n let cellConfig = evaluateConditionalFormatting(value, spec.cellSettings ?? [], columnSetting);\n\n // Then, try to get cell config from column-specific cell settings\n if (columnSetting?.cellSettings?.length) {\n const columnCellConfig = evaluateConditionalFormatting(value, columnSetting.cellSettings, columnSetting);\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\n if (openFilterColumn === columnId) {\n handleFilterClose();\n return;\n }\n\n setFilterAnchorEl({ ...filterAnchorEl, [columnId]: event.currentTarget });\n setOpenFilterColumn(columnId);\n };\n\n const handleFilterClose = useCallback((): 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, handleFilterClose]);\n\n // Keep ref in sync with filtered data for use in selection handler\n useLayoutEffect(() => {\n filteredDataRef.current = filteredData;\n }, [filteredData]);\n\n const [pagination, setPagination] = useState<PaginationState | undefined>(\n spec.pagination ? { pageIndex: 0, pageSize: 10 } : undefined,\n );\n\n if (spec.pagination && !pagination) {\n setPagination({ pageIndex: 0, pageSize: 10 });\n } else if (!spec.pagination && pagination) {\n setPagination(undefined);\n }\n\n // Sync the filter row's horizontal position with the table scroll.\n useEffect(() => {\n if (!spec.enableFiltering) {\n return;\n }\n\n const scrollContainer = panelContainer?.querySelector<HTMLElement>('.MuiTableContainer-root');\n const filterRowInner = filterRowInnerRef.current;\n\n if (!scrollContainer || !filterRowInner) {\n return;\n }\n\n const syncFilterRowScroll = (): void => {\n filterRowInner.style.transform = `translateX(-${scrollContainer.scrollLeft}px)`;\n\n setOpenFilterColumn((current) => (current === null ? current : null));\n setFilterAnchorEl((current) => (Object.keys(current).length === 0 ? current : {}));\n };\n\n filterRowInner.style.transform = `translateX(-${scrollContainer.scrollLeft}px)`;\n\n scrollContainer.addEventListener('scroll', syncFilterRowScroll, { passive: true });\n return (): void => {\n scrollContainer.removeEventListener('scroll', syncFilterRowScroll);\n };\n }, [panelContainer, spec.enableFiltering]);\n\n // Sync filter cell widths with the actual rendered table column widths to keep them aligned.\n useEffect(() => {\n if (!spec.enableFiltering) {\n return;\n }\n\n const scrollContainer = panelContainer?.querySelector<HTMLElement>('.MuiTableContainer-root');\n if (!scrollContainer) {\n return;\n }\n\n const syncColumnWidths = (): void => {\n const headerCells = scrollContainer.querySelectorAll<HTMLElement>('thead tr th');\n\n columns.forEach((_, idx) => {\n const headerCell = headerCells[idx];\n const filterCell = filterCellRefs.current[idx];\n if (!headerCell || !filterCell) {\n return;\n }\n\n const width = `${headerCell.getBoundingClientRect().width}px`;\n filterCell.style.width = width;\n filterCell.style.minWidth = width;\n filterCell.style.maxWidth = width;\n });\n };\n\n // Re-sync whenever the header row's size changes.\n const resizeObserver = new ResizeObserver(syncColumnWidths);\n // The virtualized table remounts its header row when its width, rows, or columns change,\n // so follow the current header row instead of observing a detached one.\n let headerRow: Element | null = null;\n const observeHeaderRow = (): void => {\n const currentHeaderRow = scrollContainer.querySelector('thead tr');\n if (currentHeaderRow === headerRow) {\n return;\n }\n if (headerRow) {\n resizeObserver.unobserve(headerRow);\n }\n headerRow = currentHeaderRow;\n if (headerRow) {\n resizeObserver.observe(headerRow);\n }\n syncColumnWidths();\n };\n\n observeHeaderRow();\n const mutationObserver = new MutationObserver(observeHeaderRow);\n mutationObserver.observe(scrollContainer, { childList: true, subtree: true });\n\n return (): void => {\n mutationObserver.disconnect();\n resizeObserver.disconnect();\n };\n }, [panelContainer, spec.enableFiltering, columns]);\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 <div ref={setPanelContainer} style={{ display: 'contents' }}>\n {confirmDialog}\n {spec.enableFiltering && (\n <div\n style={{\n overflow: 'hidden',\n background: theme.palette.background.default,\n borderBottom: `1px solid ${theme.palette.divider}`,\n width: contentDimensions.width,\n boxSizing: 'border-box',\n }}\n >\n <div\n ref={filterRowInnerRef}\n style={{\n display: 'flex',\n width: 'max-content',\n willChange: 'transform',\n }}\n >\n {columns.map((column, idx) => {\n const filters = getSelectedFilterValues(column.accessorKey as string);\n const columnWidth = column.width || spec.defaultColumnWidth;\n const anchorEl = filterAnchorEl[column.accessorKey as string];\n\n return (\n <div\n key={`column-${column.accessorKey}`}\n ref={(el) => {\n filterCellRefs.current[idx] = el;\n }}\n style={{\n padding: '8px',\n borderRight: idx < columns.length - 1 ? `1px solid ${theme.palette.divider}` : 'none',\n // These are just a starting size for the first paint —\n // the width-sync effect above overwrites them with the\n // table's actual rendered column widths.\n width: columnWidth,\n minWidth: columnWidth,\n maxWidth: columnWidth,\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n boxSizing: 'border-box',\n flex: 'none',\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 anchorEl &&\n createPortal(\n <div\n style={{\n position: 'fixed',\n top: anchorEl.getBoundingClientRect().bottom + 4,\n left: anchorEl.getBoundingClientRect().left,\n zIndex: theme.zIndex.modal,\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 document.body,\n )}\n </div>\n );\n })}\n </div>\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 </div>\n );\n}\n"],"names":["Box","Typography","useTheme","formatValue","Table","transformData","useSelection","useSelectionItemActions","CalculationsMap","replaceVariablesInString","useAllVariableValues","useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","createPortal","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","toSorted","filteredValues","String","formatted","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","component","action","hover","generateColumnConfig","columnSettings","allVariables","gaugeRangeByColumn","defaultEnableSorting","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","panelContainer","setPanelContainer","filterRowInnerRef","filterCellRefs","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","sort","desc","sorting","setSorting","filterAnchorEl","setFilterAnchorEl","openFilterColumn","setOpenFilterColumn","getSelectedFilterValues","columnId","f","updateColumnFilter","newFilters","handleFilterClick","event","preventDefault","stopPropagation","handleFilterClose","currentTarget","handleClick","closest","timer","setTimeout","document","addEventListener","clearTimeout","removeEventListener","pagination","setPagination","pageIndex","pageSize","scrollContainer","querySelector","filterRowInner","syncFilterRowScroll","transform","scrollLeft","passive","syncColumnWidths","headerCells","querySelectorAll","idx","headerCell","filterCell","getBoundingClientRect","maxWidth","resizeObserver","ResizeObserver","headerRow","observeHeaderRow","currentHeaderRow","unobserve","observe","mutationObserver","MutationObserver","childList","subtree","disconnect","justifyContent","ref","borderBottom","willChange","filters","columnWidth","defaultColumnWidth","anchorEl","el","borderRight","position","flex","textOverflow","whiteSpace","button","onClick","main","flexShrink","transition","onMouseEnter","onMouseLeave","top","bottom","left","zIndex","modal","body","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;;AAGjC,SAASA,GAAG,EAAEC,UAAU,EAAEC,QAAQ,QAAQ,gBAAgB;AAE1D,SAASC,WAAW,EAAEC,KAAK,EAAEC,aAAa,EAAEC,YAAY,QAAQ,yBAAyB;AACzF,SAASC,uBAAuB,QAAQ,yBAAyB;AAEjE,SAASC,eAAe,EAAEC,wBAAwB,EAAEC,oBAAoB,QAAQ,4BAA4B;AAI5G,SAASC,WAAW,EAAEC,SAAS,EAAEC,eAAe,EAAEC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AAC3F,SAASC,YAAY,QAAQ,YAAY;AAGzC,SAASC,6BAA6B,QAAQ,qBAAY;AAC1D,SAASC,iBAAiB,EAAEC,sBAAsB,QAAQ,yBAAsB;AAChF,SAASC,aAAa,QAAQ,qBAAkB;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,OAAO5C,eAAe,CAAC,cAAc;QAC3C,IAAI,OAAO4C,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,MAAC9D;QAAI+D,IAAI;YAAEC,SAAS;YAAQC,YAAY;YAAUC,OAAO;YAAQC,KAAK;QAAE;;0BACtE,KAACnE;gBAAI+D,IAAI;oBAAEK,UAAU;oBAAGC,cAAc;oBAAGC,iBAAiBR;oBAAYS,QAAQ;oBAAIC,UAAU;gBAAS;0BACnG,cAAA,KAACxE;oBACC+D,IAAI;wBACFG,OAAO,GAAGR,QAAQ,CAAC,CAAC;wBACpBa,QAAQ;wBACRD,iBAAiBd,aAAa;wBAC9Ba,cAAc;oBAChB;;;0BAGJ,KAACpE;gBAAWwE,SAAQ;gBAAQV,IAAI;oBAAEW,UAAU;oBAAIC,WAAW;gBAAQ;0BAChElB,SAAStD,YAAYoB,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,GACjDtD,YAAYqF,WAAWJ,OAAO3B,MAAM,IACnC+B;QACP;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,GAAGtF,SAAS;IAC7C,MAAM+B,SAAS;WAAI,IAAIwD,IAAIN;KAAW,CAACO,MAAM,CAAC,CAACC,IAAMA,MAAM,MAAMC,QAAQ;IACzE,MAAMC,iBAAiBN,aACnBtD,OAAOyD,MAAM,CAAC,CAACC,IAAMG,OAAOH,EAAEI,SAAS,EAAEC,WAAW,GAAGC,QAAQ,CAACV,WAAWS,WAAW,OACtF/D;IACJ,IAAIA,OAAOI,MAAM,KAAK,GAAG;QACvB,qBACE,KAAC6D;YACCC,sBAAoB;YACpBC,OAAO;gBACLhD,OAAO;gBACPiD,SAAS;gBACT7C,iBAAiB8B,MAAMgB,OAAO,CAACC,UAAU,CAACC,KAAK;gBAC/CC,QAAQ,CAAC,UAAU,EAAEnB,MAAMgB,OAAO,CAACI,OAAO,EAAE;gBAC5CnD,cAAc;gBACdoD,WAAWrB,MAAMsB,OAAO,CAAC,EAAE;YAC7B;sBAEA,cAAA,KAACV;gBAAIE,OAAO;oBAAES,OAAOvB,MAAMgB,OAAO,CAACQ,IAAI,CAACC,SAAS;oBAAEC,UAAU;gBAAG;0BAAG;;;IAGzE;IAEA,qBACE,MAACd;QACCC,sBAAoB;QACpBC,OAAO;YACLhD,OAAO;YACPiD,SAAS;YACT7C,iBAAiB8B,MAAMgB,OAAO,CAACC,UAAU,CAACC,KAAK;YAC/CC,QAAQ,CAAC,UAAU,EAAEnB,MAAMgB,OAAO,CAACI,OAAO,EAAE;YAC5CnD,cAAc;YACdoD,WAAWrB,MAAMsB,OAAO,CAAC,EAAE;YAC3BK,WAAW;YACXC,WAAW;QACb;;0BAEA,KAACC;gBACCC,MAAK;gBACLC,aAAY;gBACZ5G,OAAO8E;gBACP+B,UAAU,CAACC,IAAM/B,cAAc+B,EAAEC,MAAM,CAAC/G,KAAK;gBAC7C2F,OAAO;oBACLhD,OAAO;oBACPiD,SAAS;oBACToB,cAAc;oBACdT,UAAU;oBACVP,QAAQ,CAAC,UAAU,EAAEnB,MAAMgB,OAAO,CAACI,OAAO,EAAE;oBAC5CnD,cAAc;oBACdC,iBAAiB8B,MAAMgB,OAAO,CAACC,UAAU,CAACmB,OAAO;oBACjDb,OAAOvB,MAAMgB,OAAO,CAACQ,IAAI,CAACa,OAAO;oBACjCC,WAAW;gBACb;;0BAEF,KAAC1B;gBAAIE,OAAO;oBAAEqB,cAAc;oBAAGT,UAAU;oBAAIa,YAAY;gBAAO;0BAC9D,cAAA,MAACC;oBAAM1B,OAAO;wBAAElD,SAAS;wBAAQC,YAAY;wBAAU4E,QAAQ;oBAAU;;sCACvE,KAACZ;4BACCC,MAAK;4BACLY,SAAS5C,eAAe/C,MAAM,KAAKJ,OAAOI,MAAM,IAAIJ,OAAOI,MAAM,GAAG;4BACpEiF,UAAU,CAACC,IAAMlC,eAAekC,EAAEC,MAAM,CAACQ,OAAO,GAAG/F,OAAOgG,GAAG,CAAC,CAACtC,IAAMA,EAAEuC,QAAQ,IAAI,EAAE;4BACrF9B,OAAO;gCAAE+B,aAAa;4BAAE;;sCAE1B,MAACC;4BAAKhC,OAAO;gCAAES,OAAOvB,MAAMgB,OAAO,CAACQ,IAAI,CAACa,OAAO;4BAAC;;gCAAG;gCAAa1F,OAAOI,MAAM;gCAAC;;;;;;0BAGnF,KAACgG;gBACCjC,OAAO;oBACLkC,QAAQ;oBACR7B,QAAQ;oBACR8B,WAAW,CAAC,UAAU,EAAEjD,MAAMgB,OAAO,CAACI,OAAO,EAAE;gBACjD;;YAEDb,eAAeoC,GAAG,CAAC,CAACxH,OAAO+H,sBAC1B,KAACtC;oBAA2BE,OAAO;wBAAEqB,cAAc;oBAAE;8BACnD,cAAA,MAACvI;wBACCuJ,WAAU;wBACVxF,IAAI;4BACFC,SAAS;4BACTC,YAAY;4BACZ4E,QAAQ;4BACR1B,SAAS;4BACT9C,cAAc;4BACd,WAAW;gCACTC,iBAAiB8B,MAAMgB,OAAO,CAACoC,MAAM,CAACC,KAAK;4BAC7C;wBACF;;0CAEA,KAACxB;gCACCC,MAAK;gCACLY,SAAS5C,eAAea,QAAQ,CAACxF,MAAMyH,QAAQ;gCAC/CZ,UAAU,CAACC;oCACT,IAAIA,EAAEC,MAAM,CAACQ,OAAO,EAAE;wCACpB3C,eAAe;+CAAID;4CAAgB3E,MAAMyH,QAAQ;yCAAC;oCACpD,OAAO;wCACL7C,eAAeD,eAAeM,MAAM,CAAC,CAACC,IAAMA,MAAMlF,MAAMyH,QAAQ;oCAClE;gCACF;gCACA9B,OAAO;oCAAE+B,aAAa;gCAAE;;0CAE1B,KAACC;gCACChC,OAAO;oCACLY,UAAU;oCACVH,OAAOvB,MAAMgB,OAAO,CAACQ,IAAI,CAACa,OAAO;gCACnC;0CAEClH,UAAU,QAAQA,UAAUI,aAAaJ,MAAMsF,SAAS,KAAK,KAAK,YAAYD,OAAOrF,MAAMsF,SAAS;;;;mBAhCjG,CAAC,MAAM,EAAEyC,OAAO;;;AAuClC;AAEA;;;;CAIC,GACD,SAASI,qBACP5G,IAAY,EACZ6G,cAAgC,EAChCC,YAA8B,EAC9BC,kBAA8C,EAC9C/E,qBAAqC,EAAE,EACvCgF,uBAAuB,KAAK;IAE5B,KAAK,MAAM1E,UAAUuE,eAAgB;QACnC,IAAIvE,OAAOtC,IAAI,KAAKA,MAAM;YACxB,IAAIsC,OAAO2E,IAAI,EAAE;gBACf,OAAOpI;YACT;YAEA,MAAM,EAAEmB,IAAI,EAAEkH,MAAM,EAAEC,iBAAiB,EAAEC,aAAa,EAAEhG,KAAK,EAAEiG,KAAK,EAAEC,QAAQ,EAAE,GAAGhF;YACnF,MAAMiF,mBAAmBD,WACrB;gBAAE,GAAGA,QAAQ;gBAAEE,KAAK7J,yBAAyB2J,SAASE,GAAG,EAAEV;YAAc,IACzEjI;YAEJ,OAAO;gBACL4I,aAAazH;gBACbkH,QAAQA,UAAUlH;gBAClBmH;gBACAC,eAAeA,iBAAiBJ;gBAChC5F;gBACAiG;gBACAC,UAAUC;gBACV,GAAGlF,0BAA0BC,QAAQyE,kBAAkB,CAAC/G,KAAK,EAAEgC,mBAAmB;YACpF;QACF;IACF;IAEA,OAAO;QACLyF,aAAazH;QACbkH,QAAQlH;QACRoH,eAAeJ;IACjB;AACF;AAEA,OAAO,SAASU,0BAA0BlI,IAAkB;IAC1D,wFAAwF;IACxF,OAAO;QACLmI,MAAMrJ,uBAAuBkB;IAC/B;AACF;AAIA,OAAO,SAASoI,WAAW,EAAEC,iBAAiB,EAAErI,IAAI,EAAEwD,YAAY,EAAc;IAC9E,MAAMM,QAAQlG;IACd,MAAM0J,eAAelJ;IAErB,MAAMkK,mBAAmBtI,KAAKuI,SAAS,EAAEC,WAAW;IACpD,MAAM,EAAEC,YAAY,EAAEC,YAAY,EAAEC,cAAc,EAAE,GAAG3K;IAEvD,MAAM4K,oBAAoB5I,KAAK6I,OAAO,GAAI7I,KAAK6I,OAAO,GAAqBxJ;IAC3E,MAAMyJ,wBACJF,mBAAmBJ,WAAWI,kBAAkBG,eAAe,GAAGH,kBAAkBI,WAAW,GAAG,EAAE;IAEtG,MAAM,EAAEC,oBAAoB,EAAEC,aAAa,EAAEC,aAAa,EAAE,GAAGlL,wBAAwB;QACrF4K,SAASC;QACTM,eAAe9B;IACjB;IAEA,MAAM+B,kBAAkB5K,OAAuC,EAAE;IACjE,uEAAuE;IACvE,MAAM,CAAC6K,gBAAgBC,kBAAkB,GAAG7K,SAAgC;IAC5E,MAAM8K,oBAAoB/K,OAAuB;IACjD,MAAMgL,iBAAiBhL,OAAqC,EAAE;IAE9D,8DAA8D;IAC9D,MAAMiL,eAAelL,QAAQ;QAC3B,MAAMmL,SAA4B,CAAC;QACnClB,aAAamB,OAAO,CAAC,CAACC,GAAGC;YACvBH,MAAM,CAACG,GAAG,GAAG;QACf;QACA,OAAOH;IACT,GAAG;QAAClB;KAAa;IAEjB,MAAMsB,2BAA2B1L,YAC/B,CAAC2L;QACC,MAAMC,eAAqE,EAAE;QAC7E,KAAK,MAAM,CAACH,IAAII,WAAW,IAAIC,OAAOC,OAAO,CAACJ,iBAAkB;YAC9D,IAAIE,YAAY;gBACd,MAAMlD,QAAQqD,SAASP,IAAI;gBAC3B,IAAIT,gBAAgBiB,OAAO,CAACtD,MAAM,KAAK3H,WAAW;oBAChD4K,aAAaM,IAAI,CAAC;wBAAET;wBAAIU,MAAMnB,gBAAgBiB,OAAO,CAACtD,MAAM;oBAAC;gBAC/D;YACF;QACF;QAEA,IAAIiD,aAAapJ,MAAM,KAAK,GAAG;YAC7B8H;QACF,OAAO;YACLD,aAAauB;QACf;IACF,GACA;QAACvB;QAAcC;KAAe;IAGhC,iCAAiC;IACjC,MAAM8B,UAA0CjM,QAAQ;QACtD,mEAAmE;QACnE,OAAOK,kBAAkB2E,cAAcxD;IACzC,GAAG;QAACwD;QAAcxD;KAAK;IAEvB,iEAAiE;IACjE,MAAMP,OAAOjB,QAAQ,IAAMT,cAAc0M,SAASzK,KAAK0K,UAAU,IAAI,EAAE,GAAG;QAACD;QAASzK,KAAK0K,UAAU;KAAC;IAEpG,MAAMC,OAAiBnM,QAAQ;QAC7B,MAAMmL,SAAmB,EAAE;QAE3B,KAAK,MAAMiB,SAASnL,KAAM;YACxB,KAAK,MAAMoL,OAAOV,OAAOQ,IAAI,CAACC,OAAQ;gBACpC,IAAI,CAACjB,OAAOlF,QAAQ,CAACoG,MAAM;oBACzBlB,OAAOY,IAAI,CAACM;gBACd;YACF;QACF;QAEA,wEAAwE;QACxE,oFAAoF;QACpF,KAAK,MAAMC,OAAO9K,KAAKqH,cAAc,IAAI,EAAE,CAAE;YAC3C,IAAI,CAACsC,OAAOlF,QAAQ,CAACqG,IAAItK,IAAI,GAAG;gBAC9BmJ,OAAOY,IAAI,CAACO,IAAItK,IAAI;YACtB;QACF;QAEA,OAAOmJ;IACT,GAAG;QAAClK;QAAMO,KAAKqH,cAAc;KAAC;IAE9B,MAAM0D,gBAAgBvM,QAAQ;QAC5B,MAAMuM,gBAA+C,CAAC;QACtD,MAAMC,WAAWhL,MAAMqH;QACvB,IAAI2D,UAAU;YACZ,IAAK,IAAIC,IAAI,GAAGA,IAAID,SAASnK,MAAM,EAAEoK,IAAK;gBACxC,MAAM,EAAEzK,IAAI,EAAEW,MAAM,EAAE,GAAG6J,QAAQ,CAACC,EAAE,IAAI,CAAC;gBACzC,IAAIzK,QAAQW,QAAQ;oBAClB4J,aAAa,CAACvK,KAAK,GAAGW;gBACxB;YACF;QACF;QAEA,OAAO4J;IACT,GAAG;QAAC/K;KAAK;IAET,MAAMkL,qBAAqB1M,QAAQ;QACjC,MAAM2M,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,OAAO9L,KAAM;gBACtB,MAAM+L,MAAMD,GAAG,CAACV,IAAI;gBACpB,IAAIW,QAAQ,MAAMA,QAAQ,QAAQA,QAAQnM,WAAW;oBACnD;gBACF;gBACA,IAAIgM,WAAWI,GAAG,CAACnH,OAAOkH,OAAO;oBAC/B;gBACF;gBAEA,IAAI,OAAOA,QAAQ,YAAY,OAAOA,QAAQ,UAAU;oBACtDL,YAAY,CAACN,IAAI,CAACN,IAAI,CAAC;wBACrB7D,UAAU8E;wBACVjH,WAAW6G,gBAAgB,OAAOI,QAAQ,WAAW3N,YAAY2N,KAAKJ,gBAAgBI;oBACxF;oBACAH,WAAWK,GAAG,CAACpH,OAAOkH,MAAM;gBAC9B;YACF;QACF;QACA,OAAOL;IACT,GAAG;QAAC1L;QAAMkL;QAAMI;KAAc;IAE9B,MAAMxD,qBAAqB/I,QAAQ;QACjC,MAAMmL,SAAqC,CAAC;QAE5C,KAAK,MAAMkB,OAAOF,KAAM;YACtB,IAAIrJ,MAAMpC,OAAOyM,iBAAiB;YAClC,IAAItK,MAAMnC,OAAO0M,iBAAiB;YAElC,KAAK,MAAML,OAAO9L,KAAM;gBACtB,MAAMG,eAAee,qBAAqB4K,GAAG,CAACV,IAAI;gBAClD,IAAIjL,iBAAiBP,WAAW;oBAC9B;gBACF;gBACAiC,MAAMC,KAAKD,GAAG,CAACA,KAAK1B;gBACpByB,MAAME,KAAKF,GAAG,CAACA,KAAKzB;YACtB;YAEA,IAAI0B,QAAQpC,OAAOyM,iBAAiB,IAAItK,QAAQnC,OAAO0M,iBAAiB,EAAE;gBACxEjC,MAAM,CAACkB,IAAI,GAAG;oBAAEvJ;oBAAKD;gBAAI;YAC3B;QACF;QAEA,OAAOsI;IACT,GAAG;QAAClK;QAAMkL;KAAK;IAEf,mFAAmF;IACnF,MAAMkB,UAA6CrN,QAAQ;QACzD,MAAMqN,UAA6C,EAAE;QACrD,MAAMC,oBAAoB,IAAI7H;QAE9B,uCAAuC;QACvC,KAAK,MAAM8H,iBAAiB/L,KAAKqH,cAAc,IAAI,EAAE,CAAE;YACrD,IAAIyE,kBAAkBE,GAAG,CAACD,cAAcvL,IAAI,GAAG,UAAU,kBAAkB;YAE3E,MAAMyL,eAAe7E,qBACnB2E,cAAcvL,IAAI,EAClBR,KAAKqH,cAAc,IAAI,EAAE,EACzBC,cACAC,oBACAvH,KAAKsD,YAAY,IAAI,EAAE,EACvBtD,KAAK4H,aAAa,IAAI;YAExB,IAAIqE,iBAAiB5M,WAAW;gBAC9BwM,QAAQtB,IAAI,CAAC0B;gBACbH,kBAAkBI,GAAG,CAACH,cAAcvL,IAAI;YAC1C;QACF;QAEA,wDAAwD;QACxD,IAAI,CAACR,KAAKmM,mBAAmB,EAAE;YAC7B,KAAK,MAAMtB,OAAOF,KAAM;gBACtB,IAAI,CAACmB,kBAAkBE,GAAG,CAACnB,MAAM;oBAC/B,MAAMoB,eAAe7E,qBACnByD,KACA7K,KAAKqH,cAAc,IAAI,EAAE,EACzBC,cACAC,oBACAvH,KAAKsD,YAAY,IAAI,EAAE,EACvBtD,KAAK4H,aAAa,IAAI;oBAExB,IAAIqE,iBAAiB5M,WAAW;wBAC9BwM,QAAQtB,IAAI,CAAC0B;oBACf;gBACF;YACF;QACF;QAEA,OAAOJ;IACT,GAAG;QACDlB;QACA3K,KAAKqH,cAAc;QACnBrH,KAAKmM,mBAAmB;QACxBnM,KAAK4H,aAAa;QAClBN;QACAC;QACAvH,KAAKsD,YAAY;KAClB;IAED,wGAAwG;IACxG,MAAM,CAAC8I,eAAeC,iBAAiB,GAAG3N,SAA6B,EAAE;IAEzE,2CAA2C;IAC3C,MAAM4N,eAAe9N,QAAQ;QAC3B,IAAI,CAACwB,KAAKuM,eAAe,IAAIH,cAAcvL,MAAM,KAAK,GAAG;YACvD,OAAOpB;QACT;QAEA,OAAOA,KAAKyE,MAAM,CAAC,CAACqH;YAClB,OAAOa,cAAcI,KAAK,CAAC,CAACtI;gBAC1B,MAAMjF,QAAQsM,GAAG,CAACrH,OAAO4F,EAAE,CAAC;gBAC5B,MAAM2C,eAAevI,OAAOjF,KAAK;gBAEjC,IAAI,CAACwN,gBAAgBA,aAAa5L,MAAM,KAAK,GAAG,OAAO;gBAEvD,OAAO4L,aAAahI,QAAQ,CAACxF;YAC/B;QACF;IACF,GAAG;QAACQ;QAAM2M;QAAepM,KAAKuM,eAAe;KAAC;IAE9C,4GAA4G;IAC5G,MAAMG,cAAgClO,QAAQ;QAC5C,+EAA+E;QAC/E,IAAIwB,KAAKsD,YAAY,KAAKjE,aAAa,CAACW,KAAKqH,cAAc,EAAEsF,KAAK,CAAC7B,MAAQA,IAAIxH,YAAY,KAAKjE,YAAY;YAC1G,OAAO,CAAC;QACV;QAEA,MAAMsK,SAA2B,CAAC;QAElC,IAAI3C,QAAQ;QACZ,KAAK,MAAMuE,OAAOe,aAAc;YAC9B,+FAA+F;YAC/F,4DAA4D;YAC5D,MAAMM,YAAYjC,KAAKkC,MAAM,CAC3B,CAACC,KAAKjC;gBACJiC,GAAG,CAACjC,IAAI,GAAGxL;gBACX,OAAOyN;YACT,GACA,CAAC;YAGH,MAAMC,YAAY;gBAChB,GAAGH,SAAS;gBACZ,GAAGrB,GAAG;YACR;YAEA,qFAAqF;YACrF,KAAK,MAAM,CAACV,KAAK5L,MAAM,IAAIkL,OAAOC,OAAO,CAAC2C,WAAY;gBACpD,MAAMhB,gBAAgB/L,KAAKqH,cAAc,EAAE2F,KAAK,CAAClC,MAAQA,IAAItK,IAAI,KAAKqK;gBAEtE,0DAA0D;gBAC1D,IAAInI,aAAa9D,8BAA8BK,OAAOe,KAAKsD,YAAY,IAAI,EAAE,EAAEyI;gBAE/E,kEAAkE;gBAClE,IAAIA,eAAezI,cAAczC,QAAQ;oBACvC,MAAM8B,mBAAmB/D,8BAA8BK,OAAO8M,cAAczI,YAAY,EAAEyI;oBAC1F,gEAAgE;oBAChE,IAAIpJ,kBAAkB;wBACpBD,aAAaC;oBACf;gBACF;gBAEA,IAAID,YAAY;oBACdiH,MAAM,CAAC,GAAG3C,MAAM,CAAC,EAAE6D,KAAK,CAAC,GAAGnI;gBAC9B;YACF;YACAsE;QACF;QAEA,OAAO2C;IACT,GAAG;QAAC2C;QAAc3B;QAAM3K,KAAKsD,YAAY;QAAEtD,KAAKqH,cAAc;KAAC;IAE/D,SAAS4F;QACP,OACEjN,KAAKqH,cAAc,EACfnD,OAAO,CAACpB,SAAWA,OAAOoK,IAAI,KAAK7N,WACpCoH,IAAI,CAAC3D;YACJ,OAAO;gBACLgH,IAAIhH,OAAOtC,IAAI;gBACf2M,MAAMrK,OAAOoK,IAAI,KAAK;YACxB;QACF,MAAM,EAAE;IAEd;IAEA,MAAM,CAACE,SAASC,WAAW,GAAG3O,SAAuBuO;IAErD,MAAM,CAACK,gBAAgBC,kBAAkB,GAAG7O,SAAgD,CAAC;IAC7F,MAAM,CAAC8O,kBAAkBC,oBAAoB,GAAG/O,SAAwB;IAExE,mCAAmC;IACnC,MAAMgP,0BAA0B,CAACC;QAC/B,MAAMzJ,SAASkI,cAAcY,IAAI,CAAC,CAACY,IAAMA,EAAE9D,EAAE,KAAK6D;QAClD,OAAOzJ,SAAUA,OAAOjF,KAAK,GAA8B,EAAE;IAC/D;IAEA,uBAAuB;IACvB,MAAM4O,qBAAqB,CAACF,UAAkBlN;QAC5C,MAAMqN,aAAa1B,cAAclI,MAAM,CAAC,CAAC0J,IAAMA,EAAE9D,EAAE,KAAK6D;QACxD,IAAIlN,OAAOI,MAAM,GAAG,GAAG;YACrBiN,WAAWvD,IAAI,CAAC;gBAAET,IAAI6D;gBAAU1O,OAAOwB;YAAO;QAChD;QACA4L,iBAAiByB;IACnB;IAEA,uBAAuB;IACvB,MAAMC,oBAAoB,CAACC,OAA4CL;QACrEK,MAAMC,cAAc;QACpBD,MAAME,eAAe;QAErB,IAAIV,qBAAqBG,UAAU;YACjCQ;YACA;QACF;QAEAZ,kBAAkB;YAAE,GAAGD,cAAc;YAAE,CAACK,SAAS,EAAEK,MAAMI,aAAa;QAAC;QACvEX,oBAAoBE;IACtB;IAEA,MAAMQ,oBAAoB9P,YAAY;QACpCkP,kBAAkB,CAAC;QACnBE,oBAAoB;IACtB,GAAG,EAAE;IAEL,qCAAqC;IACrCnP,UAAU;QACR,IAAI,CAACkP,kBAAkB;QAEvB,MAAMa,cAAc,CAACtI;YACnB,MAAMC,SAASD,EAAEC,MAAM;YACvB,IAAI,CAACA,OAAOsI,OAAO,CAAC,6BAA6B,CAACtI,OAAOsI,OAAO,CAAC,WAAW;gBAC1EH;YACF;QACF;QAEA,MAAMI,QAAQC,WAAW;YACvBC,SAASC,gBAAgB,CAAC,SAASL;QACrC,GAAG;QAEH,OAAO;YACLM,aAAaJ;YACbE,SAASG,mBAAmB,CAAC,SAASP;QACxC;IACF,GAAG;QAACb;QAAkBW;KAAkB;IAExC,mEAAmE;IACnE5P,gBAAgB;QACd8K,gBAAgBiB,OAAO,GAAGgC;IAC5B,GAAG;QAACA;KAAa;IAEjB,MAAM,CAACuC,YAAYC,cAAc,GAAGpQ,SAClCsB,KAAK6O,UAAU,GAAG;QAAEE,WAAW;QAAGC,UAAU;IAAG,IAAI3P;IAGrD,IAAIW,KAAK6O,UAAU,IAAI,CAACA,YAAY;QAClCC,cAAc;YAAEC,WAAW;YAAGC,UAAU;QAAG;IAC7C,OAAO,IAAI,CAAChP,KAAK6O,UAAU,IAAIA,YAAY;QACzCC,cAAczP;IAChB;IAEA,mEAAmE;IACnEf,UAAU;QACR,IAAI,CAAC0B,KAAKuM,eAAe,EAAE;YACzB;QACF;QAEA,MAAM0C,kBAAkB3F,gBAAgB4F,cAA2B;QACnE,MAAMC,iBAAiB3F,kBAAkBc,OAAO;QAEhD,IAAI,CAAC2E,mBAAmB,CAACE,gBAAgB;YACvC;QACF;QAEA,MAAMC,sBAAsB;YAC1BD,eAAevK,KAAK,CAACyK,SAAS,GAAG,CAAC,YAAY,EAAEJ,gBAAgBK,UAAU,CAAC,GAAG,CAAC;YAE/E7B,oBAAoB,CAACnD,UAAaA,YAAY,OAAOA,UAAU;YAC/DiD,kBAAkB,CAACjD,UAAaH,OAAOQ,IAAI,CAACL,SAASzJ,MAAM,KAAK,IAAIyJ,UAAU,CAAC;QACjF;QAEA6E,eAAevK,KAAK,CAACyK,SAAS,GAAG,CAAC,YAAY,EAAEJ,gBAAgBK,UAAU,CAAC,GAAG,CAAC;QAE/EL,gBAAgBP,gBAAgB,CAAC,UAAUU,qBAAqB;YAAEG,SAAS;QAAK;QAChF,OAAO;YACLN,gBAAgBL,mBAAmB,CAAC,UAAUQ;QAChD;IACF,GAAG;QAAC9F;QAAgBtJ,KAAKuM,eAAe;KAAC;IAEzC,6FAA6F;IAC7FjO,UAAU;QACR,IAAI,CAAC0B,KAAKuM,eAAe,EAAE;YACzB;QACF;QAEA,MAAM0C,kBAAkB3F,gBAAgB4F,cAA2B;QACnE,IAAI,CAACD,iBAAiB;YACpB;QACF;QAEA,MAAMO,mBAAmB;YACvB,MAAMC,cAAcR,gBAAgBS,gBAAgB,CAAc;YAElE7D,QAAQjC,OAAO,CAAC,CAACC,GAAG8F;gBAClB,MAAMC,aAAaH,WAAW,CAACE,IAAI;gBACnC,MAAME,aAAapG,eAAea,OAAO,CAACqF,IAAI;gBAC9C,IAAI,CAACC,cAAc,CAACC,YAAY;oBAC9B;gBACF;gBAEA,MAAMjO,QAAQ,GAAGgO,WAAWE,qBAAqB,GAAGlO,KAAK,CAAC,EAAE,CAAC;gBAC7DiO,WAAWjL,KAAK,CAAChD,KAAK,GAAGA;gBACzBiO,WAAWjL,KAAK,CAACxC,QAAQ,GAAGR;gBAC5BiO,WAAWjL,KAAK,CAACmL,QAAQ,GAAGnO;YAC9B;QACF;QAEA,kDAAkD;QAClD,MAAMoO,iBAAiB,IAAIC,eAAeT;QAC1C,yFAAyF;QACzF,wEAAwE;QACxE,IAAIU,YAA4B;QAChC,MAAMC,mBAAmB;YACvB,MAAMC,mBAAmBnB,gBAAgBC,aAAa,CAAC;YACvD,IAAIkB,qBAAqBF,WAAW;gBAClC;YACF;YACA,IAAIA,WAAW;gBACbF,eAAeK,SAAS,CAACH;YAC3B;YACAA,YAAYE;YACZ,IAAIF,WAAW;gBACbF,eAAeM,OAAO,CAACJ;YACzB;YACAV;QACF;QAEAW;QACA,MAAMI,mBAAmB,IAAIC,iBAAiBL;QAC9CI,iBAAiBD,OAAO,CAACrB,iBAAiB;YAAEwB,WAAW;YAAMC,SAAS;QAAK;QAE3E,OAAO;YACLH,iBAAiBI,UAAU;YAC3BX,eAAeW,UAAU;QAC3B;IACF,GAAG;QAACrH;QAAgBtJ,KAAKuM,eAAe;QAAEV;KAAQ;IAElD,IAAIxD,sBAAsBhJ,WAAW;QACnC,OAAO;IACT;IAEA,IAAI,CAACI,MAAMoB,QAAQ;QACjB,qBACE,KAACnD;YACC+D,IAAI;gBACFC,SAAS;gBACTkP,gBAAgB;gBAChBjP,YAAY;gBACZM,QAAQ;YACV;sBAEA,cAAA,KAACtE;0BAAW;;;IAGlB;IAEA,qBACE,MAAC+G;QAAImM,KAAKtH;QAAmB3E,OAAO;YAAElD,SAAS;QAAW;;YACvDwH;YACAlJ,KAAKuM,eAAe,kBACnB,KAAC7H;gBACCE,OAAO;oBACL1C,UAAU;oBACV6C,YAAYjB,MAAMgB,OAAO,CAACC,UAAU,CAACmB,OAAO;oBAC5C4K,cAAc,CAAC,UAAU,EAAEhN,MAAMgB,OAAO,CAACI,OAAO,EAAE;oBAClDtD,OAAOyG,kBAAkBzG,KAAK;oBAC9BwE,WAAW;gBACb;0BAEA,cAAA,KAAC1B;oBACCmM,KAAKrH;oBACL5E,OAAO;wBACLlD,SAAS;wBACTE,OAAO;wBACPmP,YAAY;oBACd;8BAEClF,QAAQpF,GAAG,CAAC,CAAC3D,QAAQ6M;wBACpB,MAAMqB,UAAUtD,wBAAwB5K,OAAOmF,WAAW;wBAC1D,MAAMgJ,cAAcnO,OAAOlB,KAAK,IAAI5B,KAAKkR,kBAAkB;wBAC3D,MAAMC,WAAW7D,cAAc,CAACxK,OAAOmF,WAAW,CAAW;wBAE7D,qBACE,MAACvD;4BAECmM,KAAK,CAACO;gCACJ3H,eAAea,OAAO,CAACqF,IAAI,GAAGyB;4BAChC;4BACAxM,OAAO;gCACLC,SAAS;gCACTwM,aAAa1B,MAAM9D,QAAQhL,MAAM,GAAG,IAAI,CAAC,UAAU,EAAEiD,MAAMgB,OAAO,CAACI,OAAO,EAAE,GAAG;gCAC/E,uDAAuD;gCACvD,uDAAuD;gCACvD,yCAAyC;gCACzCtD,OAAOqP;gCACP7O,UAAU6O;gCACVlB,UAAUkB;gCACVvP,SAAS;gCACTC,YAAY;gCACZ2P,UAAU;gCACVlL,WAAW;gCACXmL,MAAM;4BACR;;8CAEA,KAAC3K;oCACChC,OAAO;wCACL+B,aAAa;wCACbnB,UAAU;wCACVH,OAAOvB,MAAMgB,OAAO,CAACQ,IAAI,CAACC,SAAS;wCACnCgM,MAAM;wCACNrP,UAAU;wCACVsP,cAAc;wCACdC,YAAY;oCACd;8CAECT,QAAQnQ,MAAM,GAAG,GAAGmQ,QAAQnQ,MAAM,CAAC,MAAM,CAAC,GAAG;;8CAEhD,KAAC6Q;oCACCC,SAAS,CAAC5L;wCACRgI,kBAAkBhI,GAAGjD,OAAOmF,WAAW;oCACzC;oCACArD,OAAO;wCACLK,QAAQ,CAAC,UAAU,EAAEnB,MAAMgB,OAAO,CAACI,OAAO,EAAE;wCAC5CH,YAAYjB,MAAMgB,OAAO,CAACC,UAAU,CAACC,KAAK;wCAC1CuB,QAAQ;wCACRf,UAAU;wCACVH,OAAO2L,QAAQnQ,MAAM,GAAGiD,MAAMgB,OAAO,CAACqB,OAAO,CAACyL,IAAI,GAAG9N,MAAMgB,OAAO,CAACQ,IAAI,CAACC,SAAS;wCACjFV,SAAS;wCACT9C,cAAc;wCACdK,UAAU;wCACVH,QAAQ;wCACR4P,YAAY;wCACZC,YAAY;oCACd;oCACAC,cAAc,CAAChM;wCACbA,EAAEqI,aAAa,CAACxJ,KAAK,CAACG,UAAU,GAAGjB,MAAMgB,OAAO,CAACoC,MAAM,CAACC,KAAK;oCAC/D;oCACA6K,cAAc,CAACjM;wCACbA,EAAEqI,aAAa,CAACxJ,KAAK,CAACG,UAAU,GAAGjB,MAAMgB,OAAO,CAACC,UAAU,CAACC,KAAK;oCACnE;oCACAY,MAAK;8CACN;;gCAIA4H,qBAAqB1K,OAAOmF,WAAW,IACtCkJ,0BACAxS,2BACE,KAAC+F;oCACCE,OAAO;wCACL0M,UAAU;wCACVW,KAAKd,SAASrB,qBAAqB,GAAGoC,MAAM,GAAG;wCAC/CC,MAAMhB,SAASrB,qBAAqB,GAAGqC,IAAI;wCAC3CC,QAAQtO,MAAMsO,MAAM,CAACC,KAAK;oCAC5B;8CAEA,cAAA,KAAC3O;wCACCC,WAAWuH,kBAAkB,CAACpI,OAAOmF,WAAW,CAAW,IAAI,EAAE;wCACjErE,gBAAgBoN;wCAChBnN,gBAAgB,CAACpD,SAAWoN,mBAAmB/K,OAAOmF,WAAW,EAAYxH;wCAC7EqD,OAAOA;;oCAGX2K,SAAS6D,IAAI;;2BA/EZ,CAAC,OAAO,EAAExP,OAAOmF,WAAW,EAAE;oBAmFzC;;;0BAIN,KAACnK;gBACC2B,MAAM6M;gBACNT,SAASA;gBACTa,aAAaA;gBACbzK,QAAQjC,KAAKuM,eAAe,GAAGlE,kBAAkBpG,MAAM,GAAG,KAAKoG,kBAAkBpG,MAAM;gBACvFL,OAAOyG,kBAAkBzG,KAAK;gBAC9B2Q,SAASvS,KAAKuS,OAAO;gBACrBrB,oBAAoBlR,KAAKkR,kBAAkB;gBAC3CsB,qBAAqBxS,KAAKwS,mBAAmB;gBAC7CpF,SAASA;gBACTqF,iBAAiBpF;gBACjBwB,YAAYA;gBACZ6D,oBAAoB5D;gBACpB6D,mBAAmBrK;gBACnBoB,cAAcA;gBACdkJ,sBAAsB7I;gBACtB8I,gBAAgB,CAAC,EAAE/I,EAAE,EAAErK,IAAI,EAAE,GAAKwJ,qBAAqB;wBAAEa;wBAAIrK,MAAMA;oBAAgC;gBACnGqT,gBAAgB3J,iBAAiBA,cAActI,MAAM,GAAG;;;;AAIhE"}
|
|
@@ -107,7 +107,7 @@ export type TableSettingsEditorProps = OptionsEditorProps<TableOptions>;
|
|
|
107
107
|
/**
|
|
108
108
|
* Formats the display text and colors based on cell settings
|
|
109
109
|
*/
|
|
110
|
-
export declare function formatCellDisplay(value: unknown, setting: CellSettings, defaultText?: string): TableCellConfig;
|
|
110
|
+
export declare function formatCellDisplay(value: unknown, setting: CellSettings, defaultText?: string, format?: FormatOptions): TableCellConfig;
|
|
111
111
|
/**
|
|
112
112
|
* Evaluates if a condition matches the given value
|
|
113
113
|
*/
|
|
@@ -115,7 +115,7 @@ export declare function evaluateCondition(condition: Condition, value: unknown):
|
|
|
115
115
|
/**
|
|
116
116
|
* Evaluates all conditions and returns the cell config for the first matching condition
|
|
117
117
|
*/
|
|
118
|
-
export declare function evaluateConditionalFormatting(value: unknown, settings: CellSettings[]): TableCellConfig | undefined;
|
|
118
|
+
export declare function evaluateConditionalFormatting(value: unknown, settings: CellSettings[], columnSetting?: ColumnSettings): TableCellConfig | undefined;
|
|
119
119
|
/**
|
|
120
120
|
* Renders the condition editor component for a given condition
|
|
121
121
|
* This function can be used by both CellEditor and ColumnEditor to maintain consistency
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-model.d.ts","sourceRoot":"","sources":["../../../src/models/table-model.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"table-model.d.ts","sourceRoot":"","sources":["../../../src/models/table-model.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { TextField, Stack, MenuItem, Typography } from "@mui/material";
|
|
14
|
+
import { formatValue } from "@perses-dev/components";
|
|
14
15
|
import React from "react";
|
|
15
16
|
/**
|
|
16
17
|
* Creates the initial/empty options for a Table panel.
|
|
@@ -30,8 +31,9 @@ function parseRangeBound(rawValue) {
|
|
|
30
31
|
}
|
|
31
32
|
/**
|
|
32
33
|
* Formats the display text and colors based on cell settings
|
|
33
|
-
*/ export function formatCellDisplay(value, setting, defaultText) {
|
|
34
|
-
const
|
|
34
|
+
*/ export function formatCellDisplay(value, setting, defaultText, format) {
|
|
35
|
+
const formattedValue = typeof value === 'number' && format ? formatValue(value, format) : String(value);
|
|
36
|
+
const baseText = setting.text || defaultText || formattedValue;
|
|
35
37
|
const displayText = `${setting.prefix ?? ''}${baseText}${setting.suffix ?? ''}`;
|
|
36
38
|
return {
|
|
37
39
|
text: displayText,
|
|
@@ -92,7 +94,7 @@ function parseRangeBound(rawValue) {
|
|
|
92
94
|
}
|
|
93
95
|
/**
|
|
94
96
|
* Evaluates all conditions and returns the cell config for the first matching condition
|
|
95
|
-
*/ export function evaluateConditionalFormatting(value, settings) {
|
|
97
|
+
*/ export function evaluateConditionalFormatting(value, settings, columnSetting) {
|
|
96
98
|
for (const setting of settings){
|
|
97
99
|
if (evaluateCondition(setting.condition, value)) {
|
|
98
100
|
// Handle special default text cases
|
|
@@ -107,7 +109,7 @@ function parseRangeBound(rawValue) {
|
|
|
107
109
|
break;
|
|
108
110
|
}
|
|
109
111
|
}
|
|
110
|
-
return formatCellDisplay(value, setting, defaultText);
|
|
112
|
+
return formatCellDisplay(value, setting, defaultText, columnSetting?.format);
|
|
111
113
|
}
|
|
112
114
|
}
|
|
113
115
|
return undefined; // No conditions matched
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/models/table-model.ts"],"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 { TextField, Stack, MenuItem, Typography } from '@mui/material';\nimport type { TableDensity, TableCellConfig, FormatOptions, Transform } from '@perses-dev/components';\nimport type { ActionOptions, OptionsEditorProps, SelectionOptions } from '@perses-dev/plugin-system';\nimport type { Definition, UnknownSpec } from '@perses-dev/spec';\nimport React from 'react';\n\nexport interface ColumnSettings {\n name: string;\n\n // Text to display in the header for the column.\n header?: string;\n /**\n * Text to display when hovering over the header text. This can be useful for\n * providing additional information about the column when you want to keep the\n * header text relatively short to manage the column width.\n */\n headerDescription?: string;\n /**\n * Text to display when hovering over a cell. This can be useful for\n * providing additional information about the column when the content is\n * ellipsized to fit in the space.\n */\n cellDescription?: string;\n\n /**\n * Panel plugin to render.\n * By default, the cells are rendered as text.\n */\n plugin?: Definition<UnknownSpec>;\n\n /** Formatting options. Only applicable if plugin is unset. */\n format?: FormatOptions;\n\n // Alignment of the content in the cell.\n align?: 'left' | 'center' | 'right';\n\n // When `true`, the column will be sortable.\n // When unset, inherits TableOptions.enableSorting from General Settings.\n enableSorting?: boolean;\n\n // Default sort order for the column.\n sort?: 'asc' | 'desc';\n\n /**\n * Width of the column when rendered in a table. It should be a number in pixels\n * or \"auto\" to allow the table to automatically adjust the width to fill\n * space.\n */\n width?: number | 'auto';\n // When `true`, the column will not be displayed.\n hide?: boolean;\n // Customize cell display based on their value for this specific column.\n cellSettings?: CellSettings[];\n\n dataLink?: DataLink;\n}\n\nexport interface DataLink {\n url: string;\n title?: string;\n openNewTab: boolean;\n}\n\nexport interface ValueCondition {\n kind: 'Value';\n spec: {\n value: string;\n };\n}\n\nexport interface RangeCondition {\n kind: 'Range';\n spec: {\n min?: number;\n max?: number;\n };\n}\n\nexport interface RegexCondition {\n kind: 'Regex';\n spec: {\n expr: string;\n };\n}\n\nexport interface MiscCondition {\n kind: 'Misc';\n spec: {\n value: 'empty' | 'null' | 'NaN' | 'true' | 'false';\n };\n}\n\nexport type Condition = ValueCondition | RangeCondition | RegexCondition | MiscCondition;\n\nexport interface CellSettings {\n condition: Condition;\n text?: string;\n prefix?: string;\n suffix?: string;\n textColor?: `#${string}`;\n backgroundColor?: `#${string}`;\n}\n\n/**\n * The schema for a Table panel.\n */\nexport interface TableDefinition extends Definition<TableOptions> {\n kind: 'Table';\n}\n\n/**\n * The Options object type supported by the Table panel plugin.\n */\nexport interface TableOptions {\n // Change row height.\n density?: TableDensity;\n // When set to 'auto', the table will try to automatically adjust the width of columns to fit without overflowing.\n // Only for column without custom width specified in columnSettings.\n defaultColumnWidth?: 'auto' | number;\n // When set to 'auto', the table will calculate the cell height based on the line height of the theme and the density setting of the table.\n // Only for column without custom height specified in columnSettings.\n defaultColumnHeight?: 'auto' | number;\n // When true, columns are hidden by default unless specified in columnSettings.\n defaultColumnHidden?: boolean;\n // Enable pagination.\n pagination?: boolean;\n // Enable filtering for individual columns.\n enableFiltering?: boolean;\n // When true, columns are sortable by default unless overridden in columnSettings.\n enableSorting?: boolean;\n // Enable row selection.\n selection?: SelectionOptions;\n // Customize actions available for selected rows.\n actions?: ActionOptions;\n // Customize column display and order them by their index in the array.\n columnSettings?: ColumnSettings[];\n // Customize cell display based on their value.\n cellSettings?: CellSettings[];\n // Apply transforms to the data before rendering the table.\n transforms?: Transform[];\n}\n\n/**\n * Creates the initial/empty options for a Table panel.\n */\nexport function createInitialTableOptions(): TableOptions {\n return {\n density: 'standard',\n enableFiltering: true,\n };\n}\n\nexport type TableSettingsEditorProps = OptionsEditorProps<TableOptions>;\n\nfunction parseRangeBound(rawValue: string): number | undefined {\n const trimmed = rawValue.trim();\n if (trimmed === '') {\n return undefined;\n }\n\n const parsed = Number(trimmed);\n return Number.isNaN(parsed) ? undefined : parsed;\n}\n\n/**\n * Formats the display text and colors based on cell settings\n */\nexport function formatCellDisplay(value: unknown, setting: CellSettings, defaultText?: string): TableCellConfig {\n const baseText = setting.text || defaultText || String(value);\n const displayText = `${setting.prefix ?? ''}${baseText}${setting.suffix ?? ''}`;\n return {\n text: displayText,\n textColor: setting.textColor,\n backgroundColor: setting.backgroundColor,\n };\n}\n\n/**\n * Evaluates if a condition matches the given value\n */\nexport function evaluateCondition(condition: Condition, value: unknown): boolean {\n switch (condition.kind) {\n case 'Value':\n return condition.spec?.value === String(value);\n\n case 'Range': {\n if (Number.isNaN(Number(value))) return false;\n const numericValue = Number(value);\n\n // Both min and max defined\n if (condition.spec?.min !== undefined && condition.spec?.max !== undefined) {\n return numericValue >= +condition.spec.min && numericValue <= +condition.spec.max;\n }\n\n // Only min defined\n if (condition.spec?.min !== undefined) {\n return numericValue >= +condition.spec.min;\n }\n\n // Only max defined\n if (condition.spec?.max !== undefined) {\n return numericValue <= +condition.spec.max;\n }\n\n return false;\n }\n\n case 'Regex':\n if (!condition.spec?.expr) return false;\n try {\n const regex = new RegExp(condition.spec.expr);\n return regex.test(String(value));\n } catch {\n return false; // Invalid regex\n }\n\n case 'Misc':\n switch (condition.spec?.value) {\n case 'empty':\n return value === '';\n case 'null':\n return value === null || value === undefined;\n case 'NaN':\n return Number.isNaN(value);\n case 'true':\n return value === true;\n case 'false':\n return value === false;\n default:\n return false;\n }\n\n default:\n return false;\n }\n}\n\n/**\n * Evaluates all conditions and returns the cell config for the first matching condition\n */\nexport function evaluateConditionalFormatting(value: unknown, settings: CellSettings[]): TableCellConfig | undefined {\n for (const setting of settings) {\n if (evaluateCondition(setting.condition, value)) {\n // Handle special default text cases\n let defaultText: string | undefined;\n if (setting.condition.kind === 'Misc') {\n switch (setting.condition.spec?.value) {\n case 'null':\n defaultText = 'null';\n break;\n case 'NaN':\n defaultText = 'NaN';\n break;\n }\n }\n\n return formatCellDisplay(value, setting, defaultText);\n }\n }\n\n return undefined; // No conditions matched\n}\n\n/**\n * Renders the condition editor component for a given condition\n * This function can be used by both CellEditor and ColumnEditor to maintain consistency\n */\nexport function renderConditionEditor(\n condition: Condition,\n onChange: (condition: Condition) => void,\n size: 'small' | 'medium' = 'small',\n): React.ReactElement | null {\n if (condition.kind === 'Value') {\n return React.createElement(TextField, {\n label: 'Value',\n placeholder: 'Exact value',\n value: condition.spec?.value ?? '',\n onChange: (e: { target: { value: string } }) =>\n onChange({ ...condition, spec: { value: e.target.value } } as ValueCondition),\n fullWidth: true,\n size: size,\n });\n } else if (condition.kind === 'Range') {\n return React.createElement(\n Stack,\n {\n gap: 1,\n direction: 'row',\n },\n [\n React.createElement(TextField, {\n key: 'min',\n label: 'From',\n placeholder: 'Start of range',\n value: condition.spec?.min ?? '',\n onChange: (e: { target: { value: string } }) => {\n const nextMin = parseRangeBound(e.target.value);\n onChange({ ...condition, spec: { ...condition.spec, min: nextMin } } as RangeCondition);\n },\n type: 'number',\n slotProps: { htmlInput: { step: 'any' } },\n fullWidth: true,\n size: size,\n }),\n React.createElement(TextField, {\n key: 'max',\n label: 'To',\n placeholder: 'End of range (inclusive)',\n value: condition.spec?.max ?? '',\n onChange: (e: { target: { value: string } }) => {\n const nextMax = parseRangeBound(e.target.value);\n onChange({ ...condition, spec: { ...condition.spec, max: nextMax } } as RangeCondition);\n },\n type: 'number',\n slotProps: { htmlInput: { step: 'any' } },\n fullWidth: true,\n size: size,\n }),\n ],\n );\n } else if (condition.kind === 'Regex') {\n return React.createElement(TextField, {\n label: 'Regular Expression',\n placeholder: 'JavaScript regular expression',\n value: condition.spec?.expr ?? '',\n onChange: (e: { target: { value: string } }) =>\n onChange({ ...condition, spec: { expr: e.target.value } } as RegexCondition),\n fullWidth: true,\n size: size,\n });\n } else if (condition.kind === 'Misc') {\n const options = [\n { value: 'empty', label: 'Empty', caption: 'Matches empty string' },\n { value: 'null', label: 'Null', caption: 'Matches null or undefined' },\n { value: 'NaN', label: 'NaN', caption: 'Matches Not a Number value' },\n { value: 'true', label: 'True', caption: 'Matches true boolean' },\n { value: 'false', label: 'False', caption: 'Matches false boolean' },\n ];\n\n return React.createElement(\n TextField,\n {\n select: true,\n label: 'Value',\n value: condition.spec?.value ?? '',\n onChange: (e: { target: { value: string } }) =>\n onChange({ ...condition, spec: { value: e.target.value } } as MiscCondition),\n fullWidth: true,\n size: size,\n },\n options.map((option) =>\n React.createElement(\n MenuItem,\n {\n key: option.value,\n value: option.value,\n },\n React.createElement(Stack, { key: 'stack' }, [\n React.createElement(Typography, { key: 'title' }, option.label),\n React.createElement(\n Typography,\n {\n key: 'caption',\n variant: 'caption',\n },\n option.caption,\n ),\n ]),\n ),\n ),\n );\n }\n return null;\n}\n"],"names":["TextField","Stack","MenuItem","Typography","React","createInitialTableOptions","density","enableFiltering","parseRangeBound","rawValue","trimmed","trim","undefined","parsed","Number","isNaN","formatCellDisplay","value","setting","defaultText","baseText","text","String","displayText","prefix","suffix","textColor","backgroundColor","evaluateCondition","condition","kind","spec","numericValue","min","max","expr","regex","RegExp","test","evaluateConditionalFormatting","settings","renderConditionEditor","onChange","size","createElement","label","placeholder","e","target","fullWidth","gap","direction","key","nextMin","type","slotProps","htmlInput","step","nextMax","options","caption","select","map","option","variant"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/models/table-model.ts"],"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 { TextField, Stack, MenuItem, Typography } from '@mui/material';\nimport { formatValue } from '@perses-dev/components';\nimport type { TableDensity, TableCellConfig, FormatOptions, Transform } from '@perses-dev/components';\nimport type { ActionOptions, OptionsEditorProps, SelectionOptions } from '@perses-dev/plugin-system';\nimport type { Definition, UnknownSpec } from '@perses-dev/spec';\nimport React from 'react';\n\nexport interface ColumnSettings {\n name: string;\n\n // Text to display in the header for the column.\n header?: string;\n /**\n * Text to display when hovering over the header text. This can be useful for\n * providing additional information about the column when you want to keep the\n * header text relatively short to manage the column width.\n */\n headerDescription?: string;\n /**\n * Text to display when hovering over a cell. This can be useful for\n * providing additional information about the column when the content is\n * ellipsized to fit in the space.\n */\n cellDescription?: string;\n\n /**\n * Panel plugin to render.\n * By default, the cells are rendered as text.\n */\n plugin?: Definition<UnknownSpec>;\n\n /** Formatting options. Only applicable if plugin is unset. */\n format?: FormatOptions;\n\n // Alignment of the content in the cell.\n align?: 'left' | 'center' | 'right';\n\n // When `true`, the column will be sortable.\n // When unset, inherits TableOptions.enableSorting from General Settings.\n enableSorting?: boolean;\n\n // Default sort order for the column.\n sort?: 'asc' | 'desc';\n\n /**\n * Width of the column when rendered in a table. It should be a number in pixels\n * or \"auto\" to allow the table to automatically adjust the width to fill\n * space.\n */\n width?: number | 'auto';\n // When `true`, the column will not be displayed.\n hide?: boolean;\n // Customize cell display based on their value for this specific column.\n cellSettings?: CellSettings[];\n\n dataLink?: DataLink;\n}\n\nexport interface DataLink {\n url: string;\n title?: string;\n openNewTab: boolean;\n}\n\nexport interface ValueCondition {\n kind: 'Value';\n spec: {\n value: string;\n };\n}\n\nexport interface RangeCondition {\n kind: 'Range';\n spec: {\n min?: number;\n max?: number;\n };\n}\n\nexport interface RegexCondition {\n kind: 'Regex';\n spec: {\n expr: string;\n };\n}\n\nexport interface MiscCondition {\n kind: 'Misc';\n spec: {\n value: 'empty' | 'null' | 'NaN' | 'true' | 'false';\n };\n}\n\nexport type Condition = ValueCondition | RangeCondition | RegexCondition | MiscCondition;\n\nexport interface CellSettings {\n condition: Condition;\n text?: string;\n prefix?: string;\n suffix?: string;\n textColor?: `#${string}`;\n backgroundColor?: `#${string}`;\n}\n\n/**\n * The schema for a Table panel.\n */\nexport interface TableDefinition extends Definition<TableOptions> {\n kind: 'Table';\n}\n\n/**\n * The Options object type supported by the Table panel plugin.\n */\nexport interface TableOptions {\n // Change row height.\n density?: TableDensity;\n // When set to 'auto', the table will try to automatically adjust the width of columns to fit without overflowing.\n // Only for column without custom width specified in columnSettings.\n defaultColumnWidth?: 'auto' | number;\n // When set to 'auto', the table will calculate the cell height based on the line height of the theme and the density setting of the table.\n // Only for column without custom height specified in columnSettings.\n defaultColumnHeight?: 'auto' | number;\n // When true, columns are hidden by default unless specified in columnSettings.\n defaultColumnHidden?: boolean;\n // Enable pagination.\n pagination?: boolean;\n // Enable filtering for individual columns.\n enableFiltering?: boolean;\n // When true, columns are sortable by default unless overridden in columnSettings.\n enableSorting?: boolean;\n // Enable row selection.\n selection?: SelectionOptions;\n // Customize actions available for selected rows.\n actions?: ActionOptions;\n // Customize column display and order them by their index in the array.\n columnSettings?: ColumnSettings[];\n // Customize cell display based on their value.\n cellSettings?: CellSettings[];\n // Apply transforms to the data before rendering the table.\n transforms?: Transform[];\n}\n\n/**\n * Creates the initial/empty options for a Table panel.\n */\nexport function createInitialTableOptions(): TableOptions {\n return {\n density: 'standard',\n enableFiltering: true,\n };\n}\n\nexport type TableSettingsEditorProps = OptionsEditorProps<TableOptions>;\n\nfunction parseRangeBound(rawValue: string): number | undefined {\n const trimmed = rawValue.trim();\n if (trimmed === '') {\n return undefined;\n }\n\n const parsed = Number(trimmed);\n return Number.isNaN(parsed) ? undefined : parsed;\n}\n\n/**\n * Formats the display text and colors based on cell settings\n */\nexport function formatCellDisplay(\n value: unknown,\n setting: CellSettings,\n defaultText?: string,\n format?: FormatOptions,\n): TableCellConfig {\n const formattedValue = typeof value === 'number' && format ? formatValue(value, format) : String(value);\n\n const baseText = setting.text || defaultText || formattedValue;\n const displayText = `${setting.prefix ?? ''}${baseText}${setting.suffix ?? ''}`;\n return {\n text: displayText,\n textColor: setting.textColor,\n backgroundColor: setting.backgroundColor,\n };\n}\n\n/**\n * Evaluates if a condition matches the given value\n */\nexport function evaluateCondition(condition: Condition, value: unknown): boolean {\n switch (condition.kind) {\n case 'Value':\n return condition.spec?.value === String(value);\n\n case 'Range': {\n if (Number.isNaN(Number(value))) return false;\n const numericValue = Number(value);\n\n // Both min and max defined\n if (condition.spec?.min !== undefined && condition.spec?.max !== undefined) {\n return numericValue >= +condition.spec.min && numericValue <= +condition.spec.max;\n }\n\n // Only min defined\n if (condition.spec?.min !== undefined) {\n return numericValue >= +condition.spec.min;\n }\n\n // Only max defined\n if (condition.spec?.max !== undefined) {\n return numericValue <= +condition.spec.max;\n }\n\n return false;\n }\n\n case 'Regex':\n if (!condition.spec?.expr) return false;\n try {\n const regex = new RegExp(condition.spec.expr);\n return regex.test(String(value));\n } catch {\n return false; // Invalid regex\n }\n\n case 'Misc':\n switch (condition.spec?.value) {\n case 'empty':\n return value === '';\n case 'null':\n return value === null || value === undefined;\n case 'NaN':\n return Number.isNaN(value);\n case 'true':\n return value === true;\n case 'false':\n return value === false;\n default:\n return false;\n }\n\n default:\n return false;\n }\n}\n\n/**\n * Evaluates all conditions and returns the cell config for the first matching condition\n */\nexport function evaluateConditionalFormatting(\n value: unknown,\n settings: CellSettings[],\n columnSetting?: ColumnSettings,\n): TableCellConfig | undefined {\n for (const setting of settings) {\n if (evaluateCondition(setting.condition, value)) {\n // Handle special default text cases\n let defaultText: string | undefined;\n if (setting.condition.kind === 'Misc') {\n switch (setting.condition.spec?.value) {\n case 'null':\n defaultText = 'null';\n break;\n case 'NaN':\n defaultText = 'NaN';\n break;\n }\n }\n\n return formatCellDisplay(value, setting, defaultText, columnSetting?.format);\n }\n }\n\n return undefined; // No conditions matched\n}\n\n/**\n * Renders the condition editor component for a given condition\n * This function can be used by both CellEditor and ColumnEditor to maintain consistency\n */\nexport function renderConditionEditor(\n condition: Condition,\n onChange: (condition: Condition) => void,\n size: 'small' | 'medium' = 'small',\n): React.ReactElement | null {\n if (condition.kind === 'Value') {\n return React.createElement(TextField, {\n label: 'Value',\n placeholder: 'Exact value',\n value: condition.spec?.value ?? '',\n onChange: (e: { target: { value: string } }) =>\n onChange({\n ...condition,\n spec: { value: e.target.value },\n } as ValueCondition),\n fullWidth: true,\n size: size,\n });\n } else if (condition.kind === 'Range') {\n return React.createElement(\n Stack,\n {\n gap: 1,\n direction: 'row',\n },\n [\n React.createElement(TextField, {\n key: 'min',\n label: 'From',\n placeholder: 'Start of range',\n value: condition.spec?.min ?? '',\n onChange: (e: { target: { value: string } }) => {\n const nextMin = parseRangeBound(e.target.value);\n onChange({\n ...condition,\n spec: { ...condition.spec, min: nextMin },\n } as RangeCondition);\n },\n type: 'number',\n slotProps: { htmlInput: { step: 'any' } },\n fullWidth: true,\n size: size,\n }),\n React.createElement(TextField, {\n key: 'max',\n label: 'To',\n placeholder: 'End of range (inclusive)',\n value: condition.spec?.max ?? '',\n onChange: (e: { target: { value: string } }) => {\n const nextMax = parseRangeBound(e.target.value);\n onChange({\n ...condition,\n spec: { ...condition.spec, max: nextMax },\n } as RangeCondition);\n },\n type: 'number',\n slotProps: { htmlInput: { step: 'any' } },\n fullWidth: true,\n size: size,\n }),\n ],\n );\n } else if (condition.kind === 'Regex') {\n return React.createElement(TextField, {\n label: 'Regular Expression',\n placeholder: 'JavaScript regular expression',\n value: condition.spec?.expr ?? '',\n onChange: (e: { target: { value: string } }) =>\n onChange({\n ...condition,\n spec: { expr: e.target.value },\n } as RegexCondition),\n fullWidth: true,\n size: size,\n });\n } else if (condition.kind === 'Misc') {\n const options = [\n { value: 'empty', label: 'Empty', caption: 'Matches empty string' },\n { value: 'null', label: 'Null', caption: 'Matches null or undefined' },\n { value: 'NaN', label: 'NaN', caption: 'Matches Not a Number value' },\n { value: 'true', label: 'True', caption: 'Matches true boolean' },\n { value: 'false', label: 'False', caption: 'Matches false boolean' },\n ];\n\n return React.createElement(\n TextField,\n {\n select: true,\n label: 'Value',\n value: condition.spec?.value ?? '',\n onChange: (e: { target: { value: string } }) =>\n onChange({\n ...condition,\n spec: { value: e.target.value },\n } as MiscCondition),\n fullWidth: true,\n size: size,\n },\n options.map((option) =>\n React.createElement(\n MenuItem,\n {\n key: option.value,\n value: option.value,\n },\n React.createElement(Stack, { key: 'stack' }, [\n React.createElement(Typography, { key: 'title' }, option.label),\n React.createElement(\n Typography,\n {\n key: 'caption',\n variant: 'caption',\n },\n option.caption,\n ),\n ]),\n ),\n ),\n );\n }\n return null;\n}\n"],"names":["TextField","Stack","MenuItem","Typography","formatValue","React","createInitialTableOptions","density","enableFiltering","parseRangeBound","rawValue","trimmed","trim","undefined","parsed","Number","isNaN","formatCellDisplay","value","setting","defaultText","format","formattedValue","String","baseText","text","displayText","prefix","suffix","textColor","backgroundColor","evaluateCondition","condition","kind","spec","numericValue","min","max","expr","regex","RegExp","test","evaluateConditionalFormatting","settings","columnSetting","renderConditionEditor","onChange","size","createElement","label","placeholder","e","target","fullWidth","gap","direction","key","nextMin","type","slotProps","htmlInput","step","nextMax","options","caption","select","map","option","variant"],"mappings":"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"}
|