@perses-dev/table-plugin 0.10.1 → 0.11.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/__mf/js/{Table.7e37b83d.js → Table.7c94517d.js} +5 -5
  2. package/__mf/js/async/{8728.546704f2.js → 1103.ffbc2bec.js} +1 -1
  3. package/__mf/js/async/1117.87be49e9.js +2 -0
  4. package/__mf/js/async/1490.9d97e5d1.js +22 -0
  5. package/__mf/js/async/2473.2c502914.js +1 -0
  6. package/__mf/js/async/{7208.125848cf.js → 3919.927efb3c.js} +5 -5
  7. package/__mf/js/async/5413.6d8fc766.js +1 -0
  8. package/__mf/js/async/5501.bc363348.js +1 -0
  9. package/__mf/js/async/7794.0374cd38.js +1 -0
  10. package/__mf/js/async/{7417.86d0bc09.js → 8094.c02682f3.js} +1 -1
  11. package/__mf/js/async/{6587.d2b9768c.js → 868.9f710584.js} +2 -2
  12. package/__mf/js/async/__federation_expose_Table.61be353a.js +1 -0
  13. package/__mf/js/{main.289caaea.js → main.1250232e.js} +5 -5
  14. package/lib/cjs/components/ColumnsEditor/ColumnEditor.js +10 -0
  15. package/lib/cjs/components/ColumnsEditor/DataLinkEditorDialog.js +139 -0
  16. package/lib/cjs/components/TablePanel.js +37 -16
  17. package/lib/components/ColumnsEditor/ColumnEditor.d.ts.map +1 -1
  18. package/lib/components/ColumnsEditor/ColumnEditor.js +10 -0
  19. package/lib/components/ColumnsEditor/ColumnEditor.js.map +1 -1
  20. package/lib/components/ColumnsEditor/DataLinkEditorDialog.d.ts +5 -0
  21. package/lib/components/ColumnsEditor/DataLinkEditorDialog.d.ts.map +1 -0
  22. package/lib/components/ColumnsEditor/DataLinkEditorDialog.js +126 -0
  23. package/lib/components/ColumnsEditor/DataLinkEditorDialog.js.map +1 -0
  24. package/lib/components/TablePanel.d.ts.map +1 -1
  25. package/lib/components/TablePanel.js +38 -17
  26. package/lib/components/TablePanel.js.map +1 -1
  27. package/lib/models/table-model.d.ts +6 -0
  28. package/lib/models/table-model.d.ts.map +1 -1
  29. package/lib/models/table-model.js.map +1 -1
  30. package/mf-manifest.json +20 -20
  31. package/mf-stats.json +20 -20
  32. package/package.json +5 -5
  33. package/__mf/js/async/1490.7aa42bc8.js +0 -22
  34. package/__mf/js/async/4761.08da9107.js +0 -1
  35. package/__mf/js/async/5501.fa3f80e1.js +0 -1
  36. package/__mf/js/async/5806.44fbc2a8.js +0 -1
  37. package/__mf/js/async/7142.5d923107.js +0 -1
  38. package/__mf/js/async/9355.8b0c6885.js +0 -2
  39. package/__mf/js/async/__federation_expose_Table.4836d198.js +0 -1
  40. /package/__mf/js/async/{9355.8b0c6885.js.LICENSE.txt → 1117.87be49e9.js.LICENSE.txt} +0 -0
  41. /package/__mf/js/async/{1490.7aa42bc8.js.LICENSE.txt → 1490.9d97e5d1.js.LICENSE.txt} +0 -0
  42. /package/__mf/js/async/{7208.125848cf.js.LICENSE.txt → 3919.927efb3c.js.LICENSE.txt} +0 -0
  43. /package/__mf/js/async/{6587.d2b9768c.js.LICENSE.txt → 868.9f710584.js.LICENSE.txt} +0 -0
@@ -0,0 +1,139 @@
1
+ // Copyright 2025 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ Object.defineProperty(exports, "DataLinkEditor", {
18
+ enumerable: true,
19
+ get: function() {
20
+ return DataLinkEditor;
21
+ }
22
+ });
23
+ const _jsxruntime = require("react/jsx-runtime");
24
+ const _components = require("@perses-dev/components");
25
+ const _material = require("@mui/material");
26
+ const _Plus = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/Plus"));
27
+ const _Minus = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/Minus"));
28
+ function _interop_require_default(obj) {
29
+ return obj && obj.__esModule ? obj : {
30
+ default: obj
31
+ };
32
+ }
33
+ const DataLinkEditor = (props)=>{
34
+ const { onChange, column, column: { dataLink } } = props;
35
+ if (!dataLink) {
36
+ return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Stack, {
37
+ sx: {
38
+ width: '100%',
39
+ alignItems: 'center'
40
+ },
41
+ direction: "row",
42
+ children: [
43
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Typography, {
44
+ flex: 1,
45
+ variant: "subtitle1",
46
+ mb: 2,
47
+ fontStyle: "italic",
48
+ children: "No link defined"
49
+ }),
50
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
51
+ style: {
52
+ width: 'fit-content',
53
+ height: 'fit-content'
54
+ },
55
+ onClick: ()=>onChange({
56
+ ...column,
57
+ dataLink: {
58
+ url: '',
59
+ openNewTab: true,
60
+ title: ''
61
+ }
62
+ }),
63
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Plus.default, {})
64
+ })
65
+ ]
66
+ });
67
+ }
68
+ const { url, openNewTab, title } = dataLink;
69
+ return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Stack, {
70
+ sx: {
71
+ width: '100%',
72
+ alignItems: 'center'
73
+ },
74
+ direction: "row",
75
+ children: [
76
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.LinkEditorForm, {
77
+ mode: "inline",
78
+ url: {
79
+ label: 'Url',
80
+ onChange: (url)=>{
81
+ onChange({
82
+ ...column,
83
+ dataLink: {
84
+ ...dataLink,
85
+ url
86
+ }
87
+ });
88
+ },
89
+ value: url,
90
+ placeholder: 'URL',
91
+ error: {
92
+ hasError: false,
93
+ helperText: ''
94
+ }
95
+ },
96
+ name: {
97
+ label: 'Name',
98
+ onChange: (title)=>{
99
+ onChange({
100
+ ...column,
101
+ dataLink: {
102
+ ...dataLink,
103
+ title
104
+ }
105
+ });
106
+ },
107
+ value: title ?? '',
108
+ placeholder: 'Name'
109
+ },
110
+ newTabOpen: {
111
+ label: 'Open in new tab',
112
+ onChange: (openNewTab)=>{
113
+ onChange({
114
+ ...column,
115
+ dataLink: {
116
+ ...dataLink,
117
+ openNewTab
118
+ }
119
+ });
120
+ },
121
+ value: openNewTab
122
+ }
123
+ }),
124
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
125
+ style: {
126
+ width: 'fit-content',
127
+ height: 'fit-content'
128
+ },
129
+ onClick: ()=>{
130
+ onChange({
131
+ ...column,
132
+ dataLink: undefined
133
+ });
134
+ },
135
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Minus.default, {})
136
+ })
137
+ ]
138
+ });
139
+ };
@@ -198,13 +198,15 @@ function ColumnFilterDropdown({ allValues, selectedValues, onFilterChange, theme
198
198
  if (column.hide) {
199
199
  return undefined;
200
200
  }
201
+ const { name, header, headerDescription, enableSorting, width, align, dataLink } = column;
201
202
  return {
202
203
  accessorKey: name,
203
- header: column.header ?? name,
204
- headerDescription: column.headerDescription,
205
- enableSorting: column.enableSorting,
206
- width: column.width,
207
- align: column.align,
204
+ header: header ?? name,
205
+ headerDescription,
206
+ enableSorting,
207
+ width,
208
+ align,
209
+ dataLink,
208
210
  ...generateCellContentConfig(column)
209
211
  };
210
212
  }
@@ -298,22 +300,27 @@ function TablePanel({ contentDimensions, spec, queryResults }) {
298
300
  data,
299
301
  keys
300
302
  ]);
303
+ // Generate columns and map each column accessor to its settings index and data key
301
304
  const columns = (0, _react.useMemo)(()=>{
302
305
  const columns = [];
303
- // Taking the customized columns first for the ordering of the columns in the table
304
- const customizedColumns = spec.columnSettings?.map((column)=>column.name).filter((name)=>keys.includes(name)) ?? [];
305
- const defaultColumns = keys.filter((key)=>!customizedColumns.includes(key));
306
- for (const key of customizedColumns){
307
- const columnConfig = generateColumnConfig(key, spec.columnSettings ?? []);
306
+ const customizedColumns = new Set();
307
+ // Process columnSettings if they exist
308
+ for (const columnSetting of spec.columnSettings ?? []){
309
+ if (customizedColumns.has(columnSetting.name)) continue; // Skip duplicates
310
+ const columnConfig = generateColumnConfig(columnSetting.name, spec.columnSettings ?? []);
308
311
  if (columnConfig !== undefined) {
309
312
  columns.push(columnConfig);
313
+ customizedColumns.add(columnSetting.name);
310
314
  }
311
315
  }
316
+ // Add remaining columns if defaultColumnHidden is false
312
317
  if (!spec.defaultColumnHidden) {
313
- for (const key of defaultColumns){
314
- const columnConfig = generateColumnConfig(key, spec.columnSettings ?? []);
315
- if (columnConfig !== undefined) {
316
- columns.push(columnConfig);
318
+ for (const key of keys){
319
+ if (!customizedColumns.has(key)) {
320
+ const columnConfig = generateColumnConfig(key, spec.columnSettings ?? []);
321
+ if (columnConfig !== undefined) {
322
+ columns.push(columnConfig);
323
+ }
317
324
  }
318
325
  }
319
326
  }
@@ -342,10 +349,11 @@ function TablePanel({ contentDimensions, spec, queryResults }) {
342
349
  ...keysAsObj,
343
350
  ...row
344
351
  };
352
+ // Generate cellConfigs for each column (including duplicates with different headers)
345
353
  for (const [key, value] of Object.entries(extendRow)){
346
354
  // First, try to get cell config from global cell settings
347
355
  let cellConfig = (0, _models.evaluateConditionalFormatting)(value, spec.cellSettings ?? []);
348
- // Then, try to get cell config from column-specific cell settings if conditional formatting is enabled
356
+ // Then, try to get cell config from column-specific cell settings
349
357
  const columnSetting = spec.columnSettings?.find((col)=>col.name === key);
350
358
  if (columnSetting?.cellSettings?.length) {
351
359
  const columnCellConfig = (0, _models.evaluateConditionalFormatting)(value, columnSetting.cellSettings);
@@ -473,7 +481,20 @@ function TablePanel({ contentDimensions, spec, queryResults }) {
473
481
  if (contentDimensions === undefined) {
474
482
  return null;
475
483
  }
476
- return /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
484
+ if (!data?.length) {
485
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
486
+ sx: {
487
+ display: 'flex',
488
+ justifyContent: 'center',
489
+ alignItems: 'center',
490
+ height: '100%'
491
+ },
492
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Typography, {
493
+ children: "No data"
494
+ })
495
+ });
496
+ }
497
+ return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
477
498
  children: [
478
499
  spec.enableFiltering && /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
479
500
  style: {
@@ -1 +1 @@
1
- {"version":3,"file":"ColumnEditor.d.ts","sourceRoot":"","sources":["../../../../src/components/ColumnsEditor/ColumnEditor.tsx"],"names":[],"mappings":"AAaA,OAAO,EAA8B,UAAU,EAAqB,MAAM,eAAe,CAAC;AAC1F,OAAO,EAAE,YAAY,EAAY,MAAM,OAAO,CAAC;AAY/C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAQ9C,KAAK,eAAe,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;AAEzD,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC;IAC1E,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CAC5C;AAED,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,EAAE,iBAAiB,GAAG,YAAY,CAkL7F"}
1
+ {"version":3,"file":"ColumnEditor.d.ts","sourceRoot":"","sources":["../../../../src/components/ColumnsEditor/ColumnEditor.tsx"],"names":[],"mappings":"AAaA,OAAO,EAA8B,UAAU,EAAqB,MAAM,eAAe,CAAC;AAC1F,OAAO,EAAE,YAAY,EAAY,MAAM,OAAO,CAAC;AAa/C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAS9C,KAAK,eAAe,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;AAEzD,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC;IAC1E,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CAC5C;AAED,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,EAAE,iBAAiB,GAAG,YAAY,CAuL7F"}
@@ -16,6 +16,7 @@ import { useState } from 'react';
16
16
  import { AlignSelector, FormatControls, OptionsEditorColumn, OptionsEditorControl, OptionsEditorGrid, OptionsEditorGroup, SortSelectorButtons } from '@perses-dev/components';
17
17
  import { PluginKindSelect } from '@perses-dev/plugin-system';
18
18
  import { ConditionalPanel } from '../ConditionalPanel';
19
+ import { DataLinkEditor } from './DataLinkEditorDialog';
19
20
  const DEFAULT_FORMAT = {
20
21
  unit: 'decimal',
21
22
  shortValues: true
@@ -208,6 +209,15 @@ export function ColumnEditor({ column, onChange, ...others }) {
208
209
  })
209
210
  ]
210
211
  })
212
+ }),
213
+ /*#__PURE__*/ _jsx(OptionsEditorColumn, {
214
+ children: /*#__PURE__*/ _jsx(OptionsEditorGroup, {
215
+ title: "Link",
216
+ children: /*#__PURE__*/ _jsx(DataLinkEditor, {
217
+ column: column,
218
+ onChange: onChange
219
+ })
220
+ })
211
221
  })
212
222
  ]
213
223
  }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/ColumnsEditor/ColumnEditor.tsx"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Button, ButtonGroup, Stack, StackProps, Switch, TextField } from '@mui/material';\nimport { ReactElement, useState } from 'react';\nimport {\n AlignSelector,\n FormatControls,\n OptionsEditorColumn,\n OptionsEditorControl,\n OptionsEditorGrid,\n OptionsEditorGroup,\n SortSelectorButtons,\n} from '@perses-dev/components';\nimport { FormatOptions } from '@perses-dev/core';\nimport { PluginKindSelect } from '@perses-dev/plugin-system';\nimport { ColumnSettings } from '../../models';\nimport { ConditionalPanel } from '../ConditionalPanel';\n\nconst DEFAULT_FORMAT: FormatOptions = {\n unit: 'decimal',\n shortValues: true,\n};\n\ntype OmittedMuiProps = 'children' | 'value' | 'onChange';\n\nexport interface ColumnEditorProps extends Omit<StackProps, OmittedMuiProps> {\n column: ColumnSettings;\n onChange: (column: ColumnSettings) => void;\n}\n\nexport function ColumnEditor({ column, onChange, ...others }: ColumnEditorProps): ReactElement {\n const [width, setWidth] = useState<number>(\n column.width === undefined || column.width === 'auto' ? 100 : column.width\n );\n\n return (\n <Stack {...others}>\n <OptionsEditorGrid>\n <OptionsEditorColumn>\n <OptionsEditorGroup title=\"Column\">\n <OptionsEditorControl\n label=\"Name*\"\n control={\n <TextField\n value={column.name}\n onChange={(e) => onChange({ ...column, name: e.target.value })}\n required\n />\n }\n />\n <OptionsEditorControl\n label=\"Header\"\n control={\n <TextField\n value={column.header ?? ''}\n onChange={(e) => onChange({ ...column, header: e.target.value ? e.target.value : undefined })}\n />\n }\n />\n <OptionsEditorControl\n label=\"Header Tooltip\"\n control={\n <TextField\n value={column.headerDescription ?? ''}\n onChange={(e) =>\n onChange({ ...column, headerDescription: e.target.value ? e.target.value : undefined })\n }\n />\n }\n />\n <OptionsEditorControl\n label=\"Cell Tooltip\"\n control={\n <TextField\n value={column.cellDescription ?? ''}\n onChange={(e) =>\n onChange({ ...column, cellDescription: e.target.value ? e.target.value : undefined })\n }\n />\n }\n />\n <OptionsEditorControl\n label=\"Enable sorting\"\n control={\n <Switch\n checked={column.enableSorting ?? false}\n onChange={(e) => onChange({ ...column, enableSorting: e.target.checked })}\n />\n }\n />\n {column.enableSorting && (\n <OptionsEditorControl\n label=\"Default Sort\"\n control={\n <SortSelectorButtons\n size=\"medium\"\n value={column.sort}\n sx={{\n margin: 0.5,\n }}\n onChange={(sort) => onChange({ ...column, sort: sort })}\n />\n }\n />\n )}\n </OptionsEditorGroup>\n </OptionsEditorColumn>\n\n <OptionsEditorColumn>\n <OptionsEditorGroup title=\"Visual\">\n <OptionsEditorControl\n label=\"Show column\"\n control={\n <Switch\n checked={!(column.hide ?? false)}\n onChange={(e) => onChange({ ...column, hide: !e.target.checked })}\n />\n }\n />\n <OptionsEditorControl\n label=\"Display\"\n control={\n <ButtonGroup aria-label=\"Display\" size=\"small\">\n <Button\n variant={!column.plugin ? 'contained' : 'outlined'}\n onClick={() => onChange({ ...column, plugin: undefined })}\n >\n Text\n </Button>\n <Button\n variant={column.plugin ? 'contained' : 'outlined'}\n onClick={() => onChange({ ...column, plugin: { kind: 'StatChart', spec: {} } })}\n >\n Embedded Panel\n </Button>\n </ButtonGroup>\n }\n />\n {column.plugin ? (\n <OptionsEditorControl\n label=\"Panel Type\"\n control={\n <PluginKindSelect\n pluginTypes={['Panel']}\n value={{ type: 'Panel', kind: column.plugin.kind }}\n onChange={(event) => onChange({ ...column, plugin: { kind: event.kind, spec: {} } })}\n />\n }\n />\n ) : (\n <FormatControls\n value={column.format ?? DEFAULT_FORMAT}\n onChange={(newFormat): void =>\n onChange({\n ...column,\n format: newFormat,\n })\n }\n />\n )}\n <OptionsEditorControl\n label=\"Alignment\"\n control={\n <AlignSelector\n size=\"small\"\n value={column.align ?? 'left'}\n onChange={(align) => onChange({ ...column, align: align })}\n />\n }\n />\n <OptionsEditorControl\n label=\"Custom width\"\n control={\n <Switch\n checked={column.width !== undefined && column.width !== 'auto'}\n onChange={(e) => onChange({ ...column, width: e.target.checked ? width : 'auto' })}\n />\n }\n />\n {column.width !== undefined && column.width !== 'auto' && (\n <OptionsEditorControl\n label=\"Width\"\n control={\n <TextField\n type=\"number\"\n value={width}\n slotProps={{ htmlInput: { min: 1 } }}\n onChange={(e) => {\n setWidth(+e.target.value);\n onChange({ ...column, width: +e.target.value });\n }}\n />\n }\n />\n )}\n </OptionsEditorGroup>\n </OptionsEditorColumn>\n </OptionsEditorGrid>\n <Stack sx={{ px: 8 }}>\n <OptionsEditorGroup title=\"Conditional Cell Format\">\n <ConditionalPanel\n cellSettings={column.cellSettings}\n onChange={(cellSettings) => onChange({ ...column, cellSettings })}\n />\n </OptionsEditorGroup>\n </Stack>\n </Stack>\n );\n}\n"],"names":["Button","ButtonGroup","Stack","Switch","TextField","useState","AlignSelector","FormatControls","OptionsEditorColumn","OptionsEditorControl","OptionsEditorGrid","OptionsEditorGroup","SortSelectorButtons","PluginKindSelect","ConditionalPanel","DEFAULT_FORMAT","unit","shortValues","ColumnEditor","column","onChange","others","width","setWidth","undefined","title","label","control","value","name","e","target","required","header","headerDescription","cellDescription","checked","enableSorting","size","sort","sx","margin","hide","aria-label","variant","plugin","onClick","kind","spec","pluginTypes","type","event","format","newFormat","align","slotProps","htmlInput","min","px","cellSettings"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/components/ColumnsEditor/ColumnEditor.tsx"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Button, ButtonGroup, Stack, StackProps, Switch, TextField } from '@mui/material';\nimport { ReactElement, useState } from 'react';\nimport {\n AlignSelector,\n FormatControls,\n OptionsEditorColumn,\n OptionsEditorControl,\n OptionsEditorGrid,\n OptionsEditorGroup,\n SortSelectorButtons,\n} from '@perses-dev/components';\nimport { FormatOptions } from '@perses-dev/core';\nimport { PluginKindSelect } from '@perses-dev/plugin-system';\n\nimport { ColumnSettings } from '../../models';\nimport { ConditionalPanel } from '../ConditionalPanel';\nimport { DataLinkEditor } from './DataLinkEditorDialog';\n\nconst DEFAULT_FORMAT: FormatOptions = {\n unit: 'decimal',\n shortValues: true,\n};\n\ntype OmittedMuiProps = 'children' | 'value' | 'onChange';\n\nexport interface ColumnEditorProps extends Omit<StackProps, OmittedMuiProps> {\n column: ColumnSettings;\n onChange: (column: ColumnSettings) => void;\n}\n\nexport function ColumnEditor({ column, onChange, ...others }: ColumnEditorProps): ReactElement {\n const [width, setWidth] = useState<number>(\n column.width === undefined || column.width === 'auto' ? 100 : column.width\n );\n\n return (\n <Stack {...others}>\n <OptionsEditorGrid>\n <OptionsEditorColumn>\n <OptionsEditorGroup title=\"Column\">\n <OptionsEditorControl\n label=\"Name*\"\n control={\n <TextField\n value={column.name}\n onChange={(e) => onChange({ ...column, name: e.target.value })}\n required\n />\n }\n />\n <OptionsEditorControl\n label=\"Header\"\n control={\n <TextField\n value={column.header ?? ''}\n onChange={(e) => onChange({ ...column, header: e.target.value ? e.target.value : undefined })}\n />\n }\n />\n <OptionsEditorControl\n label=\"Header Tooltip\"\n control={\n <TextField\n value={column.headerDescription ?? ''}\n onChange={(e) =>\n onChange({ ...column, headerDescription: e.target.value ? e.target.value : undefined })\n }\n />\n }\n />\n <OptionsEditorControl\n label=\"Cell Tooltip\"\n control={\n <TextField\n value={column.cellDescription ?? ''}\n onChange={(e) =>\n onChange({ ...column, cellDescription: e.target.value ? e.target.value : undefined })\n }\n />\n }\n />\n <OptionsEditorControl\n label=\"Enable sorting\"\n control={\n <Switch\n checked={column.enableSorting ?? false}\n onChange={(e) => onChange({ ...column, enableSorting: e.target.checked })}\n />\n }\n />\n {column.enableSorting && (\n <OptionsEditorControl\n label=\"Default Sort\"\n control={\n <SortSelectorButtons\n size=\"medium\"\n value={column.sort}\n sx={{\n margin: 0.5,\n }}\n onChange={(sort) => onChange({ ...column, sort: sort })}\n />\n }\n />\n )}\n </OptionsEditorGroup>\n </OptionsEditorColumn>\n\n <OptionsEditorColumn>\n <OptionsEditorGroup title=\"Visual\">\n <OptionsEditorControl\n label=\"Show column\"\n control={\n <Switch\n checked={!(column.hide ?? false)}\n onChange={(e) => onChange({ ...column, hide: !e.target.checked })}\n />\n }\n />\n <OptionsEditorControl\n label=\"Display\"\n control={\n <ButtonGroup aria-label=\"Display\" size=\"small\">\n <Button\n variant={!column.plugin ? 'contained' : 'outlined'}\n onClick={() => onChange({ ...column, plugin: undefined })}\n >\n Text\n </Button>\n <Button\n variant={column.plugin ? 'contained' : 'outlined'}\n onClick={() => onChange({ ...column, plugin: { kind: 'StatChart', spec: {} } })}\n >\n Embedded Panel\n </Button>\n </ButtonGroup>\n }\n />\n {column.plugin ? (\n <OptionsEditorControl\n label=\"Panel Type\"\n control={\n <PluginKindSelect\n pluginTypes={['Panel']}\n value={{ type: 'Panel', kind: column.plugin.kind }}\n onChange={(event) => onChange({ ...column, plugin: { kind: event.kind, spec: {} } })}\n />\n }\n />\n ) : (\n <FormatControls\n value={column.format ?? DEFAULT_FORMAT}\n onChange={(newFormat): void =>\n onChange({\n ...column,\n format: newFormat,\n })\n }\n />\n )}\n <OptionsEditorControl\n label=\"Alignment\"\n control={\n <AlignSelector\n size=\"small\"\n value={column.align ?? 'left'}\n onChange={(align) => onChange({ ...column, align: align })}\n />\n }\n />\n <OptionsEditorControl\n label=\"Custom width\"\n control={\n <Switch\n checked={column.width !== undefined && column.width !== 'auto'}\n onChange={(e) => onChange({ ...column, width: e.target.checked ? width : 'auto' })}\n />\n }\n />\n {column.width !== undefined && column.width !== 'auto' && (\n <OptionsEditorControl\n label=\"Width\"\n control={\n <TextField\n type=\"number\"\n value={width}\n slotProps={{ htmlInput: { min: 1 } }}\n onChange={(e) => {\n setWidth(+e.target.value);\n onChange({ ...column, width: +e.target.value });\n }}\n />\n }\n />\n )}\n </OptionsEditorGroup>\n </OptionsEditorColumn>\n <OptionsEditorColumn>\n <OptionsEditorGroup title=\"Link\">\n <DataLinkEditor column={column} onChange={onChange} />\n </OptionsEditorGroup>\n </OptionsEditorColumn>\n </OptionsEditorGrid>\n <Stack sx={{ px: 8 }}>\n <OptionsEditorGroup title=\"Conditional Cell Format\">\n <ConditionalPanel\n cellSettings={column.cellSettings}\n onChange={(cellSettings) => onChange({ ...column, cellSettings })}\n />\n </OptionsEditorGroup>\n </Stack>\n </Stack>\n );\n}\n"],"names":["Button","ButtonGroup","Stack","Switch","TextField","useState","AlignSelector","FormatControls","OptionsEditorColumn","OptionsEditorControl","OptionsEditorGrid","OptionsEditorGroup","SortSelectorButtons","PluginKindSelect","ConditionalPanel","DataLinkEditor","DEFAULT_FORMAT","unit","shortValues","ColumnEditor","column","onChange","others","width","setWidth","undefined","title","label","control","value","name","e","target","required","header","headerDescription","cellDescription","checked","enableSorting","size","sort","sx","margin","hide","aria-label","variant","plugin","onClick","kind","spec","pluginTypes","type","event","format","newFormat","align","slotProps","htmlInput","min","px","cellSettings"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { ReactElement } from 'react';
2
+ import { ColumnEditorProps } from './ColumnEditor';
3
+ export type Props = Pick<ColumnEditorProps, 'onChange' | 'column'>;
4
+ export declare const DataLinkEditor: (props: Props) => ReactElement;
5
+ //# sourceMappingURL=DataLinkEditorDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataLinkEditorDialog.d.ts","sourceRoot":"","sources":["../../../../src/components/ColumnsEditor/DataLinkEditorDialog.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAIrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;AAEnE,eAAO,MAAM,cAAc,GAAI,OAAO,KAAK,KAAG,YAgE7C,CAAC"}
@@ -0,0 +1,126 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Copyright 2025 The Perses Authors
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { LinkEditorForm } from '@perses-dev/components';
15
+ import { IconButton, Stack, Typography } from '@mui/material';
16
+ import PlusIcon from 'mdi-material-ui/Plus';
17
+ import MinusIcon from 'mdi-material-ui/Minus';
18
+ export const DataLinkEditor = (props)=>{
19
+ const { onChange, column, column: { dataLink } } = props;
20
+ if (!dataLink) {
21
+ return /*#__PURE__*/ _jsxs(Stack, {
22
+ sx: {
23
+ width: '100%',
24
+ alignItems: 'center'
25
+ },
26
+ direction: "row",
27
+ children: [
28
+ /*#__PURE__*/ _jsx(Typography, {
29
+ flex: 1,
30
+ variant: "subtitle1",
31
+ mb: 2,
32
+ fontStyle: "italic",
33
+ children: "No link defined"
34
+ }),
35
+ /*#__PURE__*/ _jsx(IconButton, {
36
+ style: {
37
+ width: 'fit-content',
38
+ height: 'fit-content'
39
+ },
40
+ onClick: ()=>onChange({
41
+ ...column,
42
+ dataLink: {
43
+ url: '',
44
+ openNewTab: true,
45
+ title: ''
46
+ }
47
+ }),
48
+ children: /*#__PURE__*/ _jsx(PlusIcon, {})
49
+ })
50
+ ]
51
+ });
52
+ }
53
+ const { url, openNewTab, title } = dataLink;
54
+ return /*#__PURE__*/ _jsxs(Stack, {
55
+ sx: {
56
+ width: '100%',
57
+ alignItems: 'center'
58
+ },
59
+ direction: "row",
60
+ children: [
61
+ /*#__PURE__*/ _jsx(LinkEditorForm, {
62
+ mode: "inline",
63
+ url: {
64
+ label: 'Url',
65
+ onChange: (url)=>{
66
+ onChange({
67
+ ...column,
68
+ dataLink: {
69
+ ...dataLink,
70
+ url
71
+ }
72
+ });
73
+ },
74
+ value: url,
75
+ placeholder: 'URL',
76
+ error: {
77
+ hasError: false,
78
+ helperText: ''
79
+ }
80
+ },
81
+ name: {
82
+ label: 'Name',
83
+ onChange: (title)=>{
84
+ onChange({
85
+ ...column,
86
+ dataLink: {
87
+ ...dataLink,
88
+ title
89
+ }
90
+ });
91
+ },
92
+ value: title ?? '',
93
+ placeholder: 'Name'
94
+ },
95
+ newTabOpen: {
96
+ label: 'Open in new tab',
97
+ onChange: (openNewTab)=>{
98
+ onChange({
99
+ ...column,
100
+ dataLink: {
101
+ ...dataLink,
102
+ openNewTab
103
+ }
104
+ });
105
+ },
106
+ value: openNewTab
107
+ }
108
+ }),
109
+ /*#__PURE__*/ _jsx(IconButton, {
110
+ style: {
111
+ width: 'fit-content',
112
+ height: 'fit-content'
113
+ },
114
+ onClick: ()=>{
115
+ onChange({
116
+ ...column,
117
+ dataLink: undefined
118
+ });
119
+ },
120
+ children: /*#__PURE__*/ _jsx(MinusIcon, {})
121
+ })
122
+ ]
123
+ });
124
+ };
125
+
126
+ //# sourceMappingURL=DataLinkEditorDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/ColumnsEditor/DataLinkEditorDialog.tsx"],"sourcesContent":["// Copyright 2025 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { LinkEditorForm } from '@perses-dev/components';\nimport { ReactElement } from 'react';\nimport { IconButton, Stack, Typography } from '@mui/material';\nimport PlusIcon from 'mdi-material-ui/Plus';\nimport MinusIcon from 'mdi-material-ui/Minus';\nimport { ColumnEditorProps } from './ColumnEditor';\n\nexport type Props = Pick<ColumnEditorProps, 'onChange' | 'column'>;\n\nexport const DataLinkEditor = (props: Props): ReactElement => {\n const {\n onChange,\n column,\n column: { dataLink },\n } = props;\n\n if (!dataLink) {\n return (\n <Stack sx={{ width: '100%', alignItems: 'center' }} direction=\"row\">\n <Typography flex={1} variant=\"subtitle1\" mb={2} fontStyle=\"italic\">\n No link defined\n </Typography>\n <IconButton\n style={{ width: 'fit-content', height: 'fit-content' }}\n onClick={() => onChange({ ...column, dataLink: { url: '', openNewTab: true, title: '' } })}\n >\n <PlusIcon />\n </IconButton>\n </Stack>\n );\n }\n\n const { url, openNewTab, title } = dataLink;\n\n return (\n <Stack sx={{ width: '100%', alignItems: 'center' }} direction=\"row\">\n <LinkEditorForm\n mode=\"inline\"\n url={{\n label: 'Url',\n onChange: (url) => {\n onChange({ ...column, dataLink: { ...dataLink, url } });\n },\n value: url,\n placeholder: 'URL',\n error: { hasError: false, helperText: '' },\n }}\n name={{\n label: 'Name',\n onChange: (title) => {\n onChange({ ...column, dataLink: { ...dataLink, title } });\n },\n value: title ?? '',\n placeholder: 'Name',\n }}\n newTabOpen={{\n label: 'Open in new tab',\n onChange: (openNewTab) => {\n onChange({ ...column, dataLink: { ...dataLink, openNewTab } });\n },\n value: openNewTab,\n }}\n />\n <IconButton\n style={{ width: 'fit-content', height: 'fit-content' }}\n onClick={() => {\n onChange({ ...column, dataLink: undefined });\n }}\n >\n <MinusIcon />\n </IconButton>\n </Stack>\n );\n};\n"],"names":["LinkEditorForm","IconButton","Stack","Typography","PlusIcon","MinusIcon","DataLinkEditor","props","onChange","column","dataLink","sx","width","alignItems","direction","flex","variant","mb","fontStyle","style","height","onClick","url","openNewTab","title","mode","label","value","placeholder","error","hasError","helperText","name","newTabOpen","undefined"],"mappings":";AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,cAAc,QAAQ,yBAAyB;AAExD,SAASC,UAAU,EAAEC,KAAK,EAAEC,UAAU,QAAQ,gBAAgB;AAC9D,OAAOC,cAAc,uBAAuB;AAC5C,OAAOC,eAAe,wBAAwB;AAK9C,OAAO,MAAMC,iBAAiB,CAACC;IAC7B,MAAM,EACJC,QAAQ,EACRC,MAAM,EACNA,QAAQ,EAAEC,QAAQ,EAAE,EACrB,GAAGH;IAEJ,IAAI,CAACG,UAAU;QACb,qBACE,MAACR;YAAMS,IAAI;gBAAEC,OAAO;gBAAQC,YAAY;YAAS;YAAGC,WAAU;;8BAC5D,KAACX;oBAAWY,MAAM;oBAAGC,SAAQ;oBAAYC,IAAI;oBAAGC,WAAU;8BAAS;;8BAGnE,KAACjB;oBACCkB,OAAO;wBAAEP,OAAO;wBAAeQ,QAAQ;oBAAc;oBACrDC,SAAS,IAAMb,SAAS;4BAAE,GAAGC,MAAM;4BAAEC,UAAU;gCAAEY,KAAK;gCAAIC,YAAY;gCAAMC,OAAO;4BAAG;wBAAE;8BAExF,cAAA,KAACpB;;;;IAIT;IAEA,MAAM,EAAEkB,GAAG,EAAEC,UAAU,EAAEC,KAAK,EAAE,GAAGd;IAEnC,qBACE,MAACR;QAAMS,IAAI;YAAEC,OAAO;YAAQC,YAAY;QAAS;QAAGC,WAAU;;0BAC5D,KAACd;gBACCyB,MAAK;gBACLH,KAAK;oBACHI,OAAO;oBACPlB,UAAU,CAACc;wBACTd,SAAS;4BAAE,GAAGC,MAAM;4BAAEC,UAAU;gCAAE,GAAGA,QAAQ;gCAAEY;4BAAI;wBAAE;oBACvD;oBACAK,OAAOL;oBACPM,aAAa;oBACbC,OAAO;wBAAEC,UAAU;wBAAOC,YAAY;oBAAG;gBAC3C;gBACAC,MAAM;oBACJN,OAAO;oBACPlB,UAAU,CAACgB;wBACThB,SAAS;4BAAE,GAAGC,MAAM;4BAAEC,UAAU;gCAAE,GAAGA,QAAQ;gCAAEc;4BAAM;wBAAE;oBACzD;oBACAG,OAAOH,SAAS;oBAChBI,aAAa;gBACf;gBACAK,YAAY;oBACVP,OAAO;oBACPlB,UAAU,CAACe;wBACTf,SAAS;4BAAE,GAAGC,MAAM;4BAAEC,UAAU;gCAAE,GAAGA,QAAQ;gCAAEa;4BAAW;wBAAE;oBAC9D;oBACAI,OAAOJ;gBACT;;0BAEF,KAACtB;gBACCkB,OAAO;oBAAEP,OAAO;oBAAeQ,QAAQ;gBAAc;gBACrDC,SAAS;oBACPb,SAAS;wBAAE,GAAGC,MAAM;wBAAEC,UAAUwB;oBAAU;gBAC5C;0BAEA,cAAA,KAAC7B;;;;AAIT,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"file":"TablePanel.d.ts","sourceRoot":"","sources":["../../../src/components/TablePanel.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAa,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,EAAE,YAAY,EAAgC,MAAM,OAAO,CAAC;AACnE,OAAO,EAAkD,cAAc,EAAiB,MAAM,kBAAkB,CAAC;AAGjH,OAAO,EAAkB,YAAY,EAAiC,MAAM,WAAW,CAAC;AAqKxF,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,YAAY,GAAG;IAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;CAAE,CAK3F;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;AAElE,wBAAgB,UAAU,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI,CAgXrG"}
1
+ {"version":3,"file":"TablePanel.d.ts","sourceRoot":"","sources":["../../../src/components/TablePanel.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAa,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,EAAE,YAAY,EAAgC,MAAM,OAAO,CAAC;AACnE,OAAO,EAAkD,cAAc,EAAiB,MAAM,kBAAkB,CAAC;AAGjH,OAAO,EAAkB,YAAY,EAAiC,MAAM,WAAW,CAAC;AAuKxF,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,YAAY,GAAG;IAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;CAAE,CAK3F;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;AAElE,wBAAgB,UAAU,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI,CAmYrG"}
@@ -14,7 +14,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
14
14
  import { Table } from '@perses-dev/components';
15
15
  import { useEffect, useMemo, useState } from 'react';
16
16
  import { formatValue, transformData } from '@perses-dev/core';
17
- import { useTheme } from '@mui/material';
17
+ import { useTheme, Typography, Box } from '@mui/material';
18
18
  import { evaluateConditionalFormatting } from '../models';
19
19
  import { EmbeddedPanel } from './EmbeddedPanel';
20
20
  function generateCellContentConfig(column) {
@@ -180,13 +180,15 @@ function ColumnFilterDropdown({ allValues, selectedValues, onFilterChange, theme
180
180
  if (column.hide) {
181
181
  return undefined;
182
182
  }
183
+ const { name, header, headerDescription, enableSorting, width, align, dataLink } = column;
183
184
  return {
184
185
  accessorKey: name,
185
- header: column.header ?? name,
186
- headerDescription: column.headerDescription,
187
- enableSorting: column.enableSorting,
188
- width: column.width,
189
- align: column.align,
186
+ header: header ?? name,
187
+ headerDescription,
188
+ enableSorting,
189
+ width,
190
+ align,
191
+ dataLink,
190
192
  ...generateCellContentConfig(column)
191
193
  };
192
194
  }
@@ -280,22 +282,27 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
280
282
  data,
281
283
  keys
282
284
  ]);
285
+ // Generate columns and map each column accessor to its settings index and data key
283
286
  const columns = useMemo(()=>{
284
287
  const columns = [];
285
- // Taking the customized columns first for the ordering of the columns in the table
286
- const customizedColumns = spec.columnSettings?.map((column)=>column.name).filter((name)=>keys.includes(name)) ?? [];
287
- const defaultColumns = keys.filter((key)=>!customizedColumns.includes(key));
288
- for (const key of customizedColumns){
289
- const columnConfig = generateColumnConfig(key, spec.columnSettings ?? []);
288
+ const customizedColumns = new Set();
289
+ // Process columnSettings if they exist
290
+ for (const columnSetting of spec.columnSettings ?? []){
291
+ if (customizedColumns.has(columnSetting.name)) continue; // Skip duplicates
292
+ const columnConfig = generateColumnConfig(columnSetting.name, spec.columnSettings ?? []);
290
293
  if (columnConfig !== undefined) {
291
294
  columns.push(columnConfig);
295
+ customizedColumns.add(columnSetting.name);
292
296
  }
293
297
  }
298
+ // Add remaining columns if defaultColumnHidden is false
294
299
  if (!spec.defaultColumnHidden) {
295
- for (const key of defaultColumns){
296
- const columnConfig = generateColumnConfig(key, spec.columnSettings ?? []);
297
- if (columnConfig !== undefined) {
298
- columns.push(columnConfig);
300
+ for (const key of keys){
301
+ if (!customizedColumns.has(key)) {
302
+ const columnConfig = generateColumnConfig(key, spec.columnSettings ?? []);
303
+ if (columnConfig !== undefined) {
304
+ columns.push(columnConfig);
305
+ }
299
306
  }
300
307
  }
301
308
  }
@@ -324,10 +331,11 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
324
331
  ...keysAsObj,
325
332
  ...row
326
333
  };
334
+ // Generate cellConfigs for each column (including duplicates with different headers)
327
335
  for (const [key, value] of Object.entries(extendRow)){
328
336
  // First, try to get cell config from global cell settings
329
337
  let cellConfig = evaluateConditionalFormatting(value, spec.cellSettings ?? []);
330
- // Then, try to get cell config from column-specific cell settings if conditional formatting is enabled
338
+ // Then, try to get cell config from column-specific cell settings
331
339
  const columnSetting = spec.columnSettings?.find((col)=>col.name === key);
332
340
  if (columnSetting?.cellSettings?.length) {
333
341
  const columnCellConfig = evaluateConditionalFormatting(value, columnSetting.cellSettings);
@@ -455,7 +463,20 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
455
463
  if (contentDimensions === undefined) {
456
464
  return null;
457
465
  }
458
- return /*#__PURE__*/ _jsxs("div", {
466
+ if (!data?.length) {
467
+ return /*#__PURE__*/ _jsx(Box, {
468
+ sx: {
469
+ display: 'flex',
470
+ justifyContent: 'center',
471
+ alignItems: 'center',
472
+ height: '100%'
473
+ },
474
+ children: /*#__PURE__*/ _jsx(Typography, {
475
+ children: "No data"
476
+ })
477
+ });
478
+ }
479
+ return /*#__PURE__*/ _jsxs(_Fragment, {
459
480
  children: [
460
481
  spec.enableFiltering && /*#__PURE__*/ _jsx("div", {
461
482
  style: {