@perses-dev/table-plugin 0.8.1 → 0.10.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 (164) hide show
  1. package/__mf/css/async/2341.d3010b86.css +1 -0
  2. package/__mf/css/async/5263.d3010b86.css +1 -0
  3. package/__mf/css/async/6759.d3010b86.css +1 -0
  4. package/__mf/js/{Table.1ddb6c06.js → Table.02a0172e.js} +4 -4
  5. package/__mf/js/async/2178.23b43aaf.js +1 -0
  6. package/__mf/js/async/2472.d6b3b5c6.js +22 -0
  7. package/__mf/js/async/2849.0d68beb5.js +2 -0
  8. package/__mf/js/async/{4075.e2a2c230.js → 4075.98f26cf8.js} +1 -1
  9. package/__mf/js/async/{4238.ea9515aa.js → 4238.8989501f.js} +1 -1
  10. package/__mf/js/async/6377.1f2ba730.js +38 -0
  11. package/__mf/js/async/9830.a2983642.js +7 -0
  12. package/__mf/js/async/__federation_expose_Table.0dbf0d6d.js +1 -0
  13. package/__mf/js/{main.688de0b9.js → main.f7b12b00.js} +4 -4
  14. package/lib/Table.d.ts +2 -2
  15. package/lib/Table.d.ts.map +1 -1
  16. package/lib/Table.js +2 -6
  17. package/lib/Table.js.map +1 -1
  18. package/lib/cjs/Table.js +9 -13
  19. package/lib/cjs/components/CellsEditor/CellsEditor.js +30 -0
  20. package/lib/cjs/{CellsEditor → components/CellsEditor}/index.js +0 -1
  21. package/lib/cjs/components/ColumnsEditor/ColumnEditor.js +241 -0
  22. package/lib/cjs/{CellsEditor/CellEditor.js → components/ConditionalPanel.js} +167 -197
  23. package/lib/cjs/components/TablePanel.js +576 -0
  24. package/lib/cjs/{TableSettingsEditor.js → components/TableSettingsEditor.js} +32 -4
  25. package/lib/cjs/components/index.js +37 -0
  26. package/lib/cjs/index.js +2 -9
  27. package/lib/cjs/models/index.js +31 -0
  28. package/lib/cjs/{table-model.js → models/model.js} +1 -12
  29. package/lib/cjs/models/table-model.js +252 -0
  30. package/lib/{CellsEditor → components/CellsEditor}/CellsEditor.d.ts +1 -1
  31. package/lib/components/CellsEditor/CellsEditor.d.ts.map +1 -0
  32. package/lib/components/CellsEditor/CellsEditor.js +22 -0
  33. package/lib/components/CellsEditor/CellsEditor.js.map +1 -0
  34. package/lib/components/CellsEditor/index.d.ts +2 -0
  35. package/lib/components/CellsEditor/index.d.ts.map +1 -0
  36. package/lib/{CellsEditor → components/CellsEditor}/index.js +0 -1
  37. package/lib/components/CellsEditor/index.js.map +1 -0
  38. package/lib/{ColumnsEditor → components/ColumnsEditor}/ColumnEditor.d.ts +1 -1
  39. package/lib/components/ColumnsEditor/ColumnEditor.d.ts.map +1 -0
  40. package/lib/components/ColumnsEditor/ColumnEditor.js +233 -0
  41. package/lib/components/ColumnsEditor/ColumnEditor.js.map +1 -0
  42. package/lib/components/ColumnsEditor/ColumnEditorContainer.d.ts.map +1 -0
  43. package/lib/components/ColumnsEditor/ColumnEditorContainer.js.map +1 -0
  44. package/lib/{ColumnsEditor → components/ColumnsEditor}/ColumnsEditor.d.ts +1 -1
  45. package/lib/components/ColumnsEditor/ColumnsEditor.d.ts.map +1 -0
  46. package/lib/components/ColumnsEditor/ColumnsEditor.js.map +1 -0
  47. package/lib/components/ColumnsEditor/index.d.ts.map +1 -0
  48. package/lib/components/ColumnsEditor/index.js.map +1 -0
  49. package/lib/components/ConditionalPanel.d.ts +15 -0
  50. package/lib/components/ConditionalPanel.d.ts.map +1 -0
  51. package/lib/{CellsEditor/CellEditor.js → components/ConditionalPanel.js} +159 -197
  52. package/lib/components/ConditionalPanel.js.map +1 -0
  53. package/lib/components/EmbeddedPanel.d.ts.map +1 -0
  54. package/lib/components/EmbeddedPanel.js.map +1 -0
  55. package/lib/{TableCellsEditor.d.ts → components/TableCellsEditor.d.ts} +1 -1
  56. package/lib/components/TableCellsEditor.d.ts.map +1 -0
  57. package/lib/components/TableCellsEditor.js.map +1 -0
  58. package/lib/{TableColumnsEditor.d.ts → components/TableColumnsEditor.d.ts} +1 -1
  59. package/lib/components/TableColumnsEditor.d.ts.map +1 -0
  60. package/lib/components/TableColumnsEditor.js.map +1 -0
  61. package/lib/{TablePanel.d.ts → components/TablePanel.d.ts} +1 -1
  62. package/lib/components/TablePanel.d.ts.map +1 -0
  63. package/lib/components/TablePanel.js +560 -0
  64. package/lib/components/TablePanel.js.map +1 -0
  65. package/lib/{TableSettingsEditor.d.ts → components/TableSettingsEditor.d.ts} +1 -1
  66. package/lib/components/TableSettingsEditor.d.ts.map +1 -0
  67. package/lib/{TableSettingsEditor.js → components/TableSettingsEditor.js} +32 -4
  68. package/lib/components/TableSettingsEditor.js.map +1 -0
  69. package/lib/{TableTransformsEditor.d.ts → components/TableTransformsEditor.d.ts} +1 -1
  70. package/lib/components/TableTransformsEditor.d.ts.map +1 -0
  71. package/lib/components/TableTransformsEditor.js.map +1 -0
  72. package/lib/components/index.d.ts +9 -0
  73. package/lib/components/index.d.ts.map +1 -0
  74. package/lib/components/index.js +22 -0
  75. package/lib/components/index.js.map +1 -0
  76. package/lib/index.d.ts +2 -9
  77. package/lib/index.d.ts.map +1 -1
  78. package/lib/index.js +2 -9
  79. package/lib/index.js.map +1 -1
  80. package/lib/models/index.d.ts +3 -0
  81. package/lib/models/index.d.ts.map +1 -0
  82. package/lib/{table-model.js → models/index.js} +4 -9
  83. package/lib/models/index.js.map +1 -0
  84. package/lib/models/model.d.ts.map +1 -0
  85. package/lib/models/model.js +15 -0
  86. package/lib/models/model.js.map +1 -0
  87. package/lib/{table-model.d.ts → models/table-model.d.ts} +24 -1
  88. package/lib/models/table-model.d.ts.map +1 -0
  89. package/lib/models/table-model.js +233 -0
  90. package/lib/models/table-model.js.map +1 -0
  91. package/mf-manifest.json +21 -22
  92. package/mf-stats.json +22 -23
  93. package/package.json +6 -6
  94. package/__mf/css/async/2341.cbbd94a8.css +0 -1
  95. package/__mf/css/async/5263.cbbd94a8.css +0 -1
  96. package/__mf/css/async/6759.cbbd94a8.css +0 -1
  97. package/__mf/js/async/3391.62c7afd4.js +0 -73
  98. package/__mf/js/async/4300.fc319dfb.js +0 -38
  99. package/__mf/js/async/4368.3e460b07.js +0 -1
  100. package/__mf/js/async/5061.85655462.js +0 -2
  101. package/__mf/js/async/5377.6522c49a.js +0 -1
  102. package/__mf/js/async/8313.b86a056a.js +0 -7
  103. package/__mf/js/async/__federation_expose_Table.3668e352.js +0 -1
  104. package/lib/CellsEditor/CellEditor.d.ts +0 -10
  105. package/lib/CellsEditor/CellEditor.d.ts.map +0 -1
  106. package/lib/CellsEditor/CellEditor.js.map +0 -1
  107. package/lib/CellsEditor/CellsEditor.d.ts.map +0 -1
  108. package/lib/CellsEditor/CellsEditor.js +0 -123
  109. package/lib/CellsEditor/CellsEditor.js.map +0 -1
  110. package/lib/CellsEditor/index.d.ts +0 -3
  111. package/lib/CellsEditor/index.d.ts.map +0 -1
  112. package/lib/CellsEditor/index.js.map +0 -1
  113. package/lib/ColumnsEditor/ColumnEditor.d.ts.map +0 -1
  114. package/lib/ColumnsEditor/ColumnEditor.js +0 -213
  115. package/lib/ColumnsEditor/ColumnEditor.js.map +0 -1
  116. package/lib/ColumnsEditor/ColumnEditorContainer.d.ts.map +0 -1
  117. package/lib/ColumnsEditor/ColumnEditorContainer.js.map +0 -1
  118. package/lib/ColumnsEditor/ColumnsEditor.d.ts.map +0 -1
  119. package/lib/ColumnsEditor/ColumnsEditor.js.map +0 -1
  120. package/lib/ColumnsEditor/index.d.ts.map +0 -1
  121. package/lib/ColumnsEditor/index.js.map +0 -1
  122. package/lib/EmbeddedPanel.d.ts.map +0 -1
  123. package/lib/EmbeddedPanel.js.map +0 -1
  124. package/lib/TableCellsEditor.d.ts.map +0 -1
  125. package/lib/TableCellsEditor.js.map +0 -1
  126. package/lib/TableColumnsEditor.d.ts.map +0 -1
  127. package/lib/TableColumnsEditor.js.map +0 -1
  128. package/lib/TablePanel.d.ts.map +0 -1
  129. package/lib/TablePanel.js +0 -325
  130. package/lib/TablePanel.js.map +0 -1
  131. package/lib/TableSettingsEditor.d.ts.map +0 -1
  132. package/lib/TableSettingsEditor.js.map +0 -1
  133. package/lib/TableTransformsEditor.d.ts.map +0 -1
  134. package/lib/TableTransformsEditor.js.map +0 -1
  135. package/lib/cjs/CellsEditor/CellsEditor.js +0 -136
  136. package/lib/cjs/ColumnsEditor/ColumnEditor.js +0 -221
  137. package/lib/cjs/TablePanel.js +0 -341
  138. package/lib/cjs/model.js +0 -4
  139. package/lib/model.d.ts.map +0 -1
  140. package/lib/model.js +0 -3
  141. package/lib/model.js.map +0 -1
  142. package/lib/table-model.d.ts.map +0 -1
  143. package/lib/table-model.js.map +0 -1
  144. /package/__mf/js/async/{3391.62c7afd4.js.LICENSE.txt → 2472.d6b3b5c6.js.LICENSE.txt} +0 -0
  145. /package/__mf/js/async/{5061.85655462.js.LICENSE.txt → 2849.0d68beb5.js.LICENSE.txt} +0 -0
  146. /package/__mf/js/async/{8313.b86a056a.js.LICENSE.txt → 9830.a2983642.js.LICENSE.txt} +0 -0
  147. /package/lib/cjs/{ColumnsEditor → components/ColumnsEditor}/ColumnEditorContainer.js +0 -0
  148. /package/lib/cjs/{ColumnsEditor → components/ColumnsEditor}/ColumnsEditor.js +0 -0
  149. /package/lib/cjs/{ColumnsEditor → components/ColumnsEditor}/index.js +0 -0
  150. /package/lib/cjs/{EmbeddedPanel.js → components/EmbeddedPanel.js} +0 -0
  151. /package/lib/cjs/{TableCellsEditor.js → components/TableCellsEditor.js} +0 -0
  152. /package/lib/cjs/{TableColumnsEditor.js → components/TableColumnsEditor.js} +0 -0
  153. /package/lib/cjs/{TableTransformsEditor.js → components/TableTransformsEditor.js} +0 -0
  154. /package/lib/{ColumnsEditor → components/ColumnsEditor}/ColumnEditorContainer.d.ts +0 -0
  155. /package/lib/{ColumnsEditor → components/ColumnsEditor}/ColumnEditorContainer.js +0 -0
  156. /package/lib/{ColumnsEditor → components/ColumnsEditor}/ColumnsEditor.js +0 -0
  157. /package/lib/{ColumnsEditor → components/ColumnsEditor}/index.d.ts +0 -0
  158. /package/lib/{ColumnsEditor → components/ColumnsEditor}/index.js +0 -0
  159. /package/lib/{EmbeddedPanel.d.ts → components/EmbeddedPanel.d.ts} +0 -0
  160. /package/lib/{EmbeddedPanel.js → components/EmbeddedPanel.js} +0 -0
  161. /package/lib/{TableCellsEditor.js → components/TableCellsEditor.js} +0 -0
  162. /package/lib/{TableColumnsEditor.js → components/TableColumnsEditor.js} +0 -0
  163. /package/lib/{TableTransformsEditor.js → components/TableTransformsEditor.js} +0 -0
  164. /package/lib/{model.d.ts → models/model.d.ts} +0 -0
@@ -0,0 +1,576 @@
1
+ // Copyright 2024 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
+ function _export(target, all) {
18
+ for(var name in all)Object.defineProperty(target, name, {
19
+ enumerable: true,
20
+ get: all[name]
21
+ });
22
+ }
23
+ _export(exports, {
24
+ TablePanel: function() {
25
+ return TablePanel;
26
+ },
27
+ getTablePanelQueryOptions: function() {
28
+ return getTablePanelQueryOptions;
29
+ }
30
+ });
31
+ const _jsxruntime = require("react/jsx-runtime");
32
+ const _components = require("@perses-dev/components");
33
+ const _react = require("react");
34
+ const _core = require("@perses-dev/core");
35
+ const _material = require("@mui/material");
36
+ const _models = require("../models");
37
+ const _EmbeddedPanel = require("./EmbeddedPanel");
38
+ function generateCellContentConfig(column) {
39
+ const plugin = column.plugin;
40
+ if (plugin !== undefined) {
41
+ return {
42
+ cell: (ctx)=>{
43
+ const panelData = ctx.getValue();
44
+ if (!panelData) return /*#__PURE__*/ (0, _jsxruntime.jsx)(_jsxruntime.Fragment, {});
45
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_EmbeddedPanel.EmbeddedPanel, {
46
+ kind: plugin.kind,
47
+ spec: plugin.spec,
48
+ queryResults: [
49
+ panelData
50
+ ]
51
+ });
52
+ },
53
+ cellDescription: column.cellDescription ? ()=>`${column.cellDescription}` : ()=>''
54
+ };
55
+ }
56
+ return {
57
+ cell: (ctx)=>{
58
+ const cellValue = ctx.getValue();
59
+ return typeof cellValue === 'number' && column.format ? (0, _core.formatValue)(cellValue, column.format) : cellValue;
60
+ },
61
+ cellDescription: column.cellDescription ? ()=>`${column.cellDescription}` : undefined
62
+ };
63
+ }
64
+ function ColumnFilterDropdown({ allValues, selectedValues, onFilterChange, theme }) {
65
+ const values = [
66
+ ...new Set(allValues)
67
+ ].filter((v)=>v != null).sort();
68
+ if (values.length === 0) {
69
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
70
+ "data-filter-dropdown": true,
71
+ style: {
72
+ width: 200,
73
+ padding: 10,
74
+ backgroundColor: theme.palette.background.paper,
75
+ border: `1px solid ${theme.palette.divider}`,
76
+ borderRadius: 4,
77
+ boxShadow: theme.shadows[4]
78
+ },
79
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
80
+ style: {
81
+ color: theme.palette.text.secondary,
82
+ fontSize: 14
83
+ },
84
+ children: "No values found"
85
+ })
86
+ });
87
+ }
88
+ return /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
89
+ "data-filter-dropdown": true,
90
+ style: {
91
+ width: 200,
92
+ padding: 10,
93
+ backgroundColor: theme.palette.background.paper,
94
+ border: `1px solid ${theme.palette.divider}`,
95
+ borderRadius: 4,
96
+ boxShadow: theme.shadows[4],
97
+ maxHeight: 250,
98
+ overflowY: 'auto'
99
+ },
100
+ children: [
101
+ /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
102
+ style: {
103
+ marginBottom: 8,
104
+ fontSize: 14,
105
+ fontWeight: 'bold'
106
+ },
107
+ children: /*#__PURE__*/ (0, _jsxruntime.jsxs)("label", {
108
+ style: {
109
+ display: 'flex',
110
+ alignItems: 'center',
111
+ cursor: 'pointer'
112
+ },
113
+ children: [
114
+ /*#__PURE__*/ (0, _jsxruntime.jsx)("input", {
115
+ type: "checkbox",
116
+ checked: selectedValues.length === values.length && values.length > 0,
117
+ onChange: (e)=>onFilterChange(e.target.checked ? values : []),
118
+ style: {
119
+ marginRight: 8
120
+ }
121
+ }),
122
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)("span", {
123
+ style: {
124
+ color: theme.palette.text.primary
125
+ },
126
+ children: [
127
+ "Select All (",
128
+ values.length,
129
+ ")"
130
+ ]
131
+ })
132
+ ]
133
+ })
134
+ }),
135
+ /*#__PURE__*/ (0, _jsxruntime.jsx)("hr", {
136
+ style: {
137
+ margin: '8px 0',
138
+ border: 'none',
139
+ borderTop: `1px solid ${theme.palette.divider}`
140
+ }
141
+ }),
142
+ values.map((value, index)=>/*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
143
+ style: {
144
+ marginBottom: 4
145
+ },
146
+ children: /*#__PURE__*/ (0, _jsxruntime.jsxs)("label", {
147
+ style: {
148
+ display: 'flex',
149
+ alignItems: 'center',
150
+ cursor: 'pointer',
151
+ padding: '2px 0',
152
+ borderRadius: 2
153
+ },
154
+ onMouseEnter: (e)=>{
155
+ e.currentTarget.style.backgroundColor = theme.palette.action.hover;
156
+ },
157
+ onMouseLeave: (e)=>{
158
+ e.currentTarget.style.backgroundColor = 'transparent';
159
+ },
160
+ children: [
161
+ /*#__PURE__*/ (0, _jsxruntime.jsx)("input", {
162
+ type: "checkbox",
163
+ checked: selectedValues.includes(value),
164
+ onChange: (e)=>{
165
+ if (e.target.checked) {
166
+ onFilterChange([
167
+ ...selectedValues,
168
+ value
169
+ ]);
170
+ } else {
171
+ onFilterChange(selectedValues.filter((v)=>v !== value));
172
+ }
173
+ },
174
+ style: {
175
+ marginRight: 8
176
+ }
177
+ }),
178
+ /*#__PURE__*/ (0, _jsxruntime.jsx)("span", {
179
+ style: {
180
+ fontSize: 14,
181
+ color: theme.palette.text.primary
182
+ },
183
+ children: value === null || value === undefined || value === '' ? '(empty)' : String(value)
184
+ })
185
+ ]
186
+ })
187
+ }, `value-${index}`))
188
+ ]
189
+ });
190
+ }
191
+ /*
192
+ * Generate column config from column definitions, if a column has multiple definitions, the first one will be used.
193
+ * If column is hidden, return undefined.
194
+ * If column do not have a definition, return a default column config.
195
+ */ function generateColumnConfig(name, columnSettings) {
196
+ for (const column of columnSettings){
197
+ if (column.name === name) {
198
+ if (column.hide) {
199
+ return undefined;
200
+ }
201
+ return {
202
+ accessorKey: name,
203
+ header: column.header ?? name,
204
+ headerDescription: column.headerDescription,
205
+ enableSorting: column.enableSorting,
206
+ width: column.width,
207
+ align: column.align,
208
+ ...generateCellContentConfig(column)
209
+ };
210
+ }
211
+ }
212
+ return {
213
+ accessorKey: name,
214
+ header: name
215
+ };
216
+ }
217
+ function getTablePanelQueryOptions(spec) {
218
+ // if any cell renders a panel plugin, perform a range query instead of an instant query
219
+ return {
220
+ mode: (spec.columnSettings ?? []).some((c)=>c.plugin) ? 'range' : 'instant'
221
+ };
222
+ }
223
+ function TablePanel({ contentDimensions, spec, queryResults }) {
224
+ const theme = (0, _material.useTheme)();
225
+ // TODO: handle other query types
226
+ const queryMode = getTablePanelQueryOptions(spec).mode;
227
+ const rawData = (0, _react.useMemo)(()=>{
228
+ // Transform query results to a tabular format:
229
+ // [ { timestamp: 123, value: 456, labelName1: labelValue1 }, ... ]
230
+ return queryResults.flatMap((data, queryIndex)=>data.data.series.map((ts)=>({
231
+ data,
232
+ ts,
233
+ queryIndex
234
+ }))).map(({ data, ts, queryIndex })=>{
235
+ if (ts.values[0] === undefined) {
236
+ return {
237
+ ...ts.labels
238
+ };
239
+ }
240
+ // If there are multiple queries, we need to add the query index to the value key and label key to avoid conflicts
241
+ const valueColumnName = queryResults.length === 1 ? 'value' : `value #${queryIndex + 1}`;
242
+ const labels = queryResults.length === 1 ? ts.labels : Object.entries(ts.labels ?? {}).reduce((acc, [key, value])=>{
243
+ if (key) acc[`${key} #${queryIndex + 1}`] = value;
244
+ return acc;
245
+ }, {});
246
+ // If the cell visualization is a panel plugin, filter the data by the current series
247
+ const columnValue = (spec.columnSettings ?? []).find((x)=>x.name === valueColumnName)?.plugin ? {
248
+ ...data,
249
+ data: {
250
+ ...data.data,
251
+ series: data.data.series.filter((s)=>s === ts)
252
+ }
253
+ } : ts.values[0][1];
254
+ if (queryMode === 'instant') {
255
+ // Timestamp is not indexed as it will be the same for all queries
256
+ return {
257
+ timestamp: ts.values[0][0],
258
+ [valueColumnName]: columnValue,
259
+ ...labels
260
+ };
261
+ } else {
262
+ // Don't add a timestamp for range queries
263
+ return {
264
+ [valueColumnName]: columnValue,
265
+ ...labels
266
+ };
267
+ }
268
+ });
269
+ }, [
270
+ queryResults,
271
+ queryMode,
272
+ spec.columnSettings
273
+ ]);
274
+ // Transform will be applied by their orders on the original data
275
+ const data = (0, _core.transformData)(rawData, spec.transforms ?? []);
276
+ const keys = (0, _react.useMemo)(()=>{
277
+ const result = [];
278
+ for (const entry of data){
279
+ for (const key of Object.keys(entry)){
280
+ if (!result.includes(key)) {
281
+ result.push(key);
282
+ }
283
+ }
284
+ }
285
+ return result;
286
+ }, [
287
+ data
288
+ ]);
289
+ // fetch unique values for each column of filtering
290
+ const columnUniqueValues = (0, _react.useMemo)(()=>{
291
+ const uniqueValues = {};
292
+ keys.forEach((key)=>{
293
+ const values = data.map((row)=>row[key]).filter((val)=>val !== null && val !== undefined && val !== '');
294
+ uniqueValues[key] = Array.from(new Set(values));
295
+ });
296
+ return uniqueValues;
297
+ }, [
298
+ data,
299
+ keys
300
+ ]);
301
+ const columns = (0, _react.useMemo)(()=>{
302
+ 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 ?? []);
308
+ if (columnConfig !== undefined) {
309
+ columns.push(columnConfig);
310
+ }
311
+ }
312
+ if (!spec.defaultColumnHidden) {
313
+ for (const key of defaultColumns){
314
+ const columnConfig = generateColumnConfig(key, spec.columnSettings ?? []);
315
+ if (columnConfig !== undefined) {
316
+ columns.push(columnConfig);
317
+ }
318
+ }
319
+ }
320
+ return columns;
321
+ }, [
322
+ keys,
323
+ spec.columnSettings,
324
+ spec.defaultColumnHidden
325
+ ]);
326
+ // Generate cell settings that will be used by the table to render cells (text color, background color, ...)
327
+ const cellConfigs = (0, _react.useMemo)(()=>{
328
+ // If there are no cell settings globally or per column, return an empty object
329
+ if (spec.cellSettings === undefined && !spec.columnSettings?.some((col)=>col.cellSettings !== undefined)) {
330
+ return {};
331
+ }
332
+ const result = {};
333
+ let index = 0;
334
+ for (const row of data){
335
+ // Transforming key to object to extend the row with undefined values if the key is not present
336
+ // for checking the cell config "Misc" condition with "null"
337
+ const keysAsObj = keys.reduce((acc, key)=>{
338
+ acc[key] = undefined;
339
+ return acc;
340
+ }, {});
341
+ const extendRow = {
342
+ ...keysAsObj,
343
+ ...row
344
+ };
345
+ for (const [key, value] of Object.entries(extendRow)){
346
+ // First, try to get cell config from global cell settings
347
+ 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
349
+ const columnSetting = spec.columnSettings?.find((col)=>col.name === key);
350
+ if (columnSetting?.cellSettings?.length) {
351
+ const columnCellConfig = (0, _models.evaluateConditionalFormatting)(value, columnSetting.cellSettings);
352
+ // Column-specific settings take precedence over global settings
353
+ if (columnCellConfig) {
354
+ cellConfig = columnCellConfig;
355
+ }
356
+ }
357
+ if (cellConfig) {
358
+ result[`${index}_${key}`] = cellConfig;
359
+ }
360
+ }
361
+ index++;
362
+ }
363
+ return result;
364
+ }, [
365
+ data,
366
+ keys,
367
+ spec.cellSettings,
368
+ spec.columnSettings
369
+ ]);
370
+ function generateDefaultSortingState() {
371
+ return spec.columnSettings?.filter((column)=>column.sort !== undefined).map((column)=>{
372
+ return {
373
+ id: column.name,
374
+ desc: column.sort === 'desc'
375
+ };
376
+ }) ?? [];
377
+ }
378
+ const [sorting, setSorting] = (0, _react.useState)(generateDefaultSortingState());
379
+ // Filtering state
380
+ const [columnFilters, setColumnFilters] = (0, _react.useState)([]);
381
+ const [filterAnchorEl, setFilterAnchorEl] = (0, _react.useState)({});
382
+ const [openFilterColumn, setOpenFilterColumn] = (0, _react.useState)(null);
383
+ // get selected values for a column
384
+ const getSelectedFilterValues = (columnId)=>{
385
+ const filter = columnFilters.find((f)=>f.id === columnId);
386
+ return filter ? filter.value : [];
387
+ };
388
+ // update column filter
389
+ const updateColumnFilter = (columnId, values)=>{
390
+ const newFilters = columnFilters.filter((f)=>f.id !== columnId);
391
+ if (values.length > 0) {
392
+ newFilters.push({
393
+ id: columnId,
394
+ value: values
395
+ });
396
+ }
397
+ setColumnFilters(newFilters);
398
+ };
399
+ // Handle filter clicks
400
+ const handleFilterClick = (event, columnId)=>{
401
+ event.preventDefault();
402
+ event.stopPropagation();
403
+ setFilterAnchorEl({
404
+ ...filterAnchorEl,
405
+ [columnId]: event.currentTarget
406
+ });
407
+ setOpenFilterColumn(columnId);
408
+ };
409
+ const handleFilterClose = ()=>{
410
+ setFilterAnchorEl({});
411
+ setOpenFilterColumn(null);
412
+ };
413
+ // Close filter when clicking outside
414
+ (0, _react.useEffect)(()=>{
415
+ if (!openFilterColumn) return;
416
+ const handleClick = (e)=>{
417
+ const target = e.target;
418
+ if (!target.closest('[data-filter-dropdown]') && !target.closest('button')) {
419
+ handleFilterClose();
420
+ }
421
+ };
422
+ const timer = setTimeout(()=>{
423
+ document.addEventListener('click', handleClick);
424
+ }, 100);
425
+ return ()=>{
426
+ clearTimeout(timer);
427
+ document.removeEventListener('click', handleClick);
428
+ };
429
+ }, [
430
+ openFilterColumn
431
+ ]);
432
+ // filter data based on the current filters
433
+ const filteredData = (0, _react.useMemo)(()=>{
434
+ let filtered = [
435
+ ...data
436
+ ];
437
+ // apply column filters if enabled
438
+ if (spec.enableFiltering && columnFilters.length > 0) {
439
+ filtered = filtered.filter((row)=>{
440
+ return columnFilters.every((filter)=>{
441
+ const value = row[filter.id];
442
+ const filterValues = filter.value;
443
+ if (!filterValues || filterValues.length === 0) return true; // No filter values means no filtering
444
+ // Check if the row value is in the selected filter values
445
+ return filterValues.includes(value);
446
+ });
447
+ });
448
+ }
449
+ return filtered;
450
+ }, [
451
+ data,
452
+ columnFilters,
453
+ spec.enableFiltering
454
+ ]);
455
+ const [pagination, setPagination] = (0, _react.useState)(spec.pagination ? {
456
+ pageIndex: 0,
457
+ pageSize: 10
458
+ } : undefined);
459
+ (0, _react.useEffect)(()=>{
460
+ // If the pagination setting changes from no pagination to pagination, but the pagination state is undefined, update the pagination state
461
+ if (spec.pagination && !pagination) {
462
+ setPagination({
463
+ pageIndex: 0,
464
+ pageSize: 10
465
+ });
466
+ } else if (!spec.pagination && pagination) {
467
+ setPagination(undefined);
468
+ }
469
+ }, [
470
+ spec.pagination,
471
+ pagination
472
+ ]);
473
+ if (contentDimensions === undefined) {
474
+ return null;
475
+ }
476
+ return /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
477
+ children: [
478
+ spec.enableFiltering && /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
479
+ style: {
480
+ display: 'flex',
481
+ background: theme.palette.background.default,
482
+ borderBottom: `1px solid ${theme.palette.divider}`,
483
+ width: contentDimensions.width,
484
+ boxSizing: 'border-box'
485
+ },
486
+ children: columns.map((column, idx)=>{
487
+ const filters = getSelectedFilterValues(column.accessorKey);
488
+ const columnWidth = column.width || spec.defaultColumnWidth;
489
+ return /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
490
+ style: {
491
+ padding: '8px',
492
+ borderRight: idx < columns.length - 1 ? `1px solid ${theme.palette.divider}` : 'none',
493
+ width: columnWidth,
494
+ minWidth: columnWidth,
495
+ maxWidth: columnWidth,
496
+ display: 'flex',
497
+ alignItems: 'center',
498
+ position: 'relative',
499
+ boxSizing: 'border-box',
500
+ flex: typeof columnWidth === 'number' ? 'none' : '1 1 auto'
501
+ },
502
+ children: [
503
+ /*#__PURE__*/ (0, _jsxruntime.jsx)("span", {
504
+ style: {
505
+ marginRight: 8,
506
+ fontSize: '12px',
507
+ color: theme.palette.text.secondary,
508
+ flex: 1,
509
+ overflow: 'hidden',
510
+ textOverflow: 'ellipsis',
511
+ whiteSpace: 'nowrap'
512
+ },
513
+ children: filters.length ? `${filters.length} items` : 'All'
514
+ }),
515
+ /*#__PURE__*/ (0, _jsxruntime.jsx)("button", {
516
+ onClick: (e)=>{
517
+ handleFilterClick(e, column.accessorKey);
518
+ },
519
+ style: {
520
+ border: `1px solid ${theme.palette.divider}`,
521
+ background: theme.palette.background.paper,
522
+ cursor: 'pointer',
523
+ fontSize: '12px',
524
+ color: filters.length ? theme.palette.primary.main : theme.palette.text.secondary,
525
+ padding: '4px 8px',
526
+ borderRadius: '4px',
527
+ minWidth: '20px',
528
+ height: '24px',
529
+ flexShrink: 0,
530
+ transition: 'all 0.2s ease'
531
+ },
532
+ onMouseEnter: (e)=>{
533
+ e.currentTarget.style.background = theme.palette.action.hover;
534
+ },
535
+ onMouseLeave: (e)=>{
536
+ e.currentTarget.style.background = theme.palette.background.paper;
537
+ },
538
+ type: "button",
539
+ children: "▼"
540
+ }),
541
+ openFilterColumn === column.accessorKey && /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
542
+ style: {
543
+ position: 'absolute',
544
+ top: '100%',
545
+ left: 0,
546
+ zIndex: 1000,
547
+ marginTop: 4
548
+ },
549
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(ColumnFilterDropdown, {
550
+ allValues: columnUniqueValues[column.accessorKey] || [],
551
+ selectedValues: filters,
552
+ onFilterChange: (values)=>updateColumnFilter(column.accessorKey, values),
553
+ theme: theme
554
+ })
555
+ })
556
+ ]
557
+ }, `filter-${idx}`);
558
+ })
559
+ }),
560
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.Table, {
561
+ data: filteredData,
562
+ columns: columns,
563
+ cellConfigs: cellConfigs,
564
+ height: spec.enableFiltering ? contentDimensions.height - 40 : contentDimensions.height,
565
+ width: contentDimensions.width,
566
+ density: spec.density,
567
+ defaultColumnWidth: spec.defaultColumnWidth,
568
+ defaultColumnHeight: spec.defaultColumnHeight,
569
+ sorting: sorting,
570
+ onSortingChange: setSorting,
571
+ pagination: pagination,
572
+ onPaginationChange: setPagination
573
+ })
574
+ ]
575
+ });
576
+ }
@@ -44,10 +44,12 @@ function DefaultColumnsDimensionsControl({ label, defaultValue, value, onChange
44
44
  control: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TextField, {
45
45
  type: "number",
46
46
  value: value ?? defaultValue,
47
- InputProps: {
48
- inputProps: {
49
- min: 1,
50
- step: 1
47
+ slotProps: {
48
+ input: {
49
+ inputProps: {
50
+ min: 1,
51
+ step: 1
52
+ }
51
53
  }
52
54
  },
53
55
  onChange: (e)=>onChange(parseInt(e.target.value))
@@ -69,6 +71,12 @@ function TableSettingsEditor({ onChange, value }) {
69
71
  pagination: newValue
70
72
  });
71
73
  }
74
+ function handleDefaultColumnHiddenChange(_event, newValue) {
75
+ onChange({
76
+ ...value,
77
+ defaultColumnHidden: newValue
78
+ });
79
+ }
72
80
  function handleAutoWidthChange(newValue) {
73
81
  onChange({
74
82
  ...value,
@@ -81,6 +89,12 @@ function TableSettingsEditor({ onChange, value }) {
81
89
  defaultColumnHeight: newValue
82
90
  });
83
91
  }
92
+ function handleEnableFilteringChange(_event, checked) {
93
+ onChange({
94
+ ...value,
95
+ enableFiltering: checked
96
+ });
97
+ }
84
98
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.OptionsEditorGrid, {
85
99
  children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.OptionsEditorColumn, {
86
100
  children: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_components.OptionsEditorGroup, {
@@ -97,6 +111,20 @@ function TableSettingsEditor({ onChange, value }) {
97
111
  onChange: handlePaginationChange
98
112
  })
99
113
  }),
114
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.OptionsEditorControl, {
115
+ label: "Columns Hidden by Default",
116
+ control: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Switch, {
117
+ checked: !!value.defaultColumnHidden,
118
+ onChange: handleDefaultColumnHiddenChange
119
+ })
120
+ }),
121
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.OptionsEditorControl, {
122
+ label: "Enable Column Filtering",
123
+ control: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Switch, {
124
+ checked: !!value.enableFiltering,
125
+ onChange: handleEnableFilteringChange
126
+ })
127
+ }),
100
128
  /*#__PURE__*/ (0, _jsxruntime.jsx)(DefaultColumnsDimensionsControl, {
101
129
  label: "Width",
102
130
  defaultValue: _components.DEFAULT_COLUMN_WIDTH,
@@ -0,0 +1,37 @@
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
+ _export_star(require("./CellsEditor"), exports);
18
+ _export_star(require("./ColumnsEditor"), exports);
19
+ _export_star(require("./EmbeddedPanel"), exports);
20
+ _export_star(require("./TableCellsEditor"), exports);
21
+ _export_star(require("./TableColumnsEditor"), exports);
22
+ _export_star(require("./TablePanel"), exports);
23
+ _export_star(require("./TableSettingsEditor"), exports);
24
+ _export_star(require("./TableTransformsEditor"), exports);
25
+ function _export_star(from, to) {
26
+ Object.keys(from).forEach(function(k) {
27
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
28
+ Object.defineProperty(to, k, {
29
+ enumerable: true,
30
+ get: function() {
31
+ return from[k];
32
+ }
33
+ });
34
+ }
35
+ });
36
+ return from;
37
+ }