@perses-dev/table-plugin 0.11.0 → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__mf/js/{Table.2fc0ce5e.js → Table.e34e0ae1.js} +3 -3
- package/__mf/js/async/208.2b17c08c.js +3 -0
- package/__mf/js/async/2082.78532c3c.js +1 -0
- package/__mf/js/async/54.8b007a26.js +22 -0
- package/__mf/js/async/550.8bab52fc.js +7 -0
- package/__mf/js/async/9701.3b068d23.js +1 -0
- package/__mf/js/async/__federation_expose_Table.894a962f.js +1 -0
- package/__mf/js/{main.83aeba98.js → main.5b8b137b.js} +3 -3
- package/lib/Table.d.ts.map +1 -1
- package/lib/Table.js +8 -1
- package/lib/Table.js.map +1 -1
- package/lib/TableExportAction.d.ts +20 -0
- package/lib/TableExportAction.d.ts.map +1 -0
- package/lib/TableExportAction.js +123 -0
- package/lib/TableExportAction.js.map +1 -0
- package/lib/cjs/Table.js +8 -1
- package/lib/cjs/TableExportAction.js +181 -0
- package/lib/cjs/components/TablePanel.js +6 -46
- package/lib/cjs/table-data-utils.js +83 -0
- package/lib/components/ConditionalPanel.d.ts +3 -2
- package/lib/components/ConditionalPanel.d.ts.map +1 -1
- package/lib/components/ConditionalPanel.js.map +1 -1
- package/lib/components/EmbeddedPanel.d.ts +2 -1
- package/lib/components/EmbeddedPanel.d.ts.map +1 -1
- package/lib/components/EmbeddedPanel.js.map +1 -1
- package/lib/components/TablePanel.d.ts.map +1 -1
- package/lib/components/TablePanel.js +6 -46
- package/lib/components/TablePanel.js.map +1 -1
- package/lib/table-data-utils.d.ts +32 -0
- package/lib/table-data-utils.d.ts.map +1 -0
- package/lib/table-data-utils.js +81 -0
- package/lib/table-data-utils.js.map +1 -0
- package/mf-manifest.json +15 -15
- package/mf-stats.json +18 -18
- package/package.json +5 -5
- package/__mf/js/async/4510.a0a1dd48.js +0 -7
- package/__mf/js/async/54.467c4f98.js +0 -22
- package/__mf/js/async/5413.6d8fc766.js +0 -1
- package/__mf/js/async/7794.0374cd38.js +0 -1
- package/__mf/js/async/9010.fd805430.js +0 -1
- package/__mf/js/async/__federation_expose_Table.b3466cfe.js +0 -1
- /package/__mf/js/async/{54.467c4f98.js.LICENSE.txt → 54.8b007a26.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{4510.a0a1dd48.js.LICENSE.txt → 550.8bab52fc.js.LICENSE.txt} +0 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { PanelData } from '@perses-dev/plugin-system';
|
|
3
|
+
import { TimeSeriesData } from '@perses-dev/core';
|
|
4
|
+
import { TableProps } from './components';
|
|
5
|
+
import type { TableOptions } from './models';
|
|
6
|
+
export interface ExportColumn {
|
|
7
|
+
key: string;
|
|
8
|
+
header: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Converts raw query results into the same tabular structure that TablePanel
|
|
12
|
+
* renders, applying indexed column naming and configured transforms so the
|
|
13
|
+
* CSV output matches the visual table.
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildTableData(queryResults: Array<PanelData<TimeSeriesData>>, spec: TableOptions): {
|
|
16
|
+
data: Array<Record<string, unknown>>;
|
|
17
|
+
columns: ExportColumn[];
|
|
18
|
+
};
|
|
19
|
+
export declare const TableExportAction: React.FC<TableProps>;
|
|
20
|
+
//# sourceMappingURL=TableExportAction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TableExportAction.d.ts","sourceRoot":"","sources":["../../src/TableExportAction.tsx"],"names":[],"mappings":"AAaA,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,EAAkB,SAAS,EAAoB,MAAM,2BAA2B,CAAC;AAIxF,OAAO,EAAE,cAAc,EAAiB,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,EAC9C,IAAI,EAAE,YAAY,GACjB;IAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAAC,OAAO,EAAE,YAAY,EAAE,CAAA;CAAE,CAiCnE;AAED,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CAgDlD,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// Copyright 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 React, { useCallback, useMemo } from 'react';
|
|
15
|
+
import { escapeCsvValue, sanitizeFilename } from '@perses-dev/plugin-system';
|
|
16
|
+
import { InfoTooltip } from '@perses-dev/components';
|
|
17
|
+
import { IconButton } from '@mui/material';
|
|
18
|
+
import DownloadIcon from 'mdi-material-ui/Download';
|
|
19
|
+
import { transformData } from '@perses-dev/core';
|
|
20
|
+
import { buildRawTableData } from './table-data-utils';
|
|
21
|
+
/**
|
|
22
|
+
* Converts raw query results into the same tabular structure that TablePanel
|
|
23
|
+
* renders, applying indexed column naming and configured transforms so the
|
|
24
|
+
* CSV output matches the visual table.
|
|
25
|
+
*/ export function buildTableData(queryResults, spec) {
|
|
26
|
+
// Use shared utility with forExport=true to get raw scalar values
|
|
27
|
+
const rawData = buildRawTableData(queryResults, spec, {
|
|
28
|
+
forExport: true
|
|
29
|
+
});
|
|
30
|
+
const transformed = transformData(rawData, spec.transforms ?? []);
|
|
31
|
+
const allKeys = [];
|
|
32
|
+
for (const entry of transformed){
|
|
33
|
+
for (const key of Object.keys(entry)){
|
|
34
|
+
if (!allKeys.includes(key)) allKeys.push(key);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const columnSettings = spec.columnSettings ?? [];
|
|
38
|
+
const columns = [];
|
|
39
|
+
const customized = new Set();
|
|
40
|
+
for (const col of columnSettings){
|
|
41
|
+
if (customized.has(col.name)) continue;
|
|
42
|
+
customized.add(col.name);
|
|
43
|
+
if (col.hide) continue;
|
|
44
|
+
columns.push({
|
|
45
|
+
key: col.name,
|
|
46
|
+
header: col.header ?? col.name
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (!spec.defaultColumnHidden) {
|
|
50
|
+
for (const key of allKeys){
|
|
51
|
+
if (!customized.has(key)) {
|
|
52
|
+
columns.push({
|
|
53
|
+
key,
|
|
54
|
+
header: key
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
data: transformed,
|
|
61
|
+
columns
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export const TableExportAction = ({ queryResults, spec, definition })=>{
|
|
65
|
+
const tableData = useMemo(()=>buildTableData(queryResults, spec), [
|
|
66
|
+
queryResults,
|
|
67
|
+
spec
|
|
68
|
+
]);
|
|
69
|
+
const canExport = tableData.data.length > 0 && tableData.columns.length > 0;
|
|
70
|
+
const handleExport = useCallback(()=>{
|
|
71
|
+
if (!canExport) return;
|
|
72
|
+
try {
|
|
73
|
+
const title = definition?.spec?.display?.name || 'Table Data';
|
|
74
|
+
const { data, columns } = tableData;
|
|
75
|
+
const headerRow = columns.map((c)=>escapeCsvValue(c.header)).join(',');
|
|
76
|
+
const dataRows = data.map((row)=>columns.map((col)=>escapeCsvValue(row[col.key])).join(','));
|
|
77
|
+
const csvString = [
|
|
78
|
+
headerRow,
|
|
79
|
+
...dataRows
|
|
80
|
+
].join('\n') + '\n';
|
|
81
|
+
const csvBlob = new Blob([
|
|
82
|
+
csvString
|
|
83
|
+
], {
|
|
84
|
+
type: 'text/csv;charset=utf-8'
|
|
85
|
+
});
|
|
86
|
+
const baseFilename = sanitizeFilename(title);
|
|
87
|
+
const filename = `${baseFilename}_data.csv`;
|
|
88
|
+
const url = URL.createObjectURL(csvBlob);
|
|
89
|
+
try {
|
|
90
|
+
const link = document.createElement('a');
|
|
91
|
+
link.href = url;
|
|
92
|
+
link.download = filename;
|
|
93
|
+
document.body.appendChild(link);
|
|
94
|
+
link.click();
|
|
95
|
+
document.body.removeChild(link);
|
|
96
|
+
} finally{
|
|
97
|
+
URL.revokeObjectURL(url);
|
|
98
|
+
}
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.error('Table CSV export failed:', error);
|
|
101
|
+
}
|
|
102
|
+
}, [
|
|
103
|
+
canExport,
|
|
104
|
+
tableData,
|
|
105
|
+
definition
|
|
106
|
+
]);
|
|
107
|
+
if (!canExport) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
return /*#__PURE__*/ _jsx(InfoTooltip, {
|
|
111
|
+
description: "Export as CSV",
|
|
112
|
+
children: /*#__PURE__*/ _jsx(IconButton, {
|
|
113
|
+
size: "small",
|
|
114
|
+
onClick: handleExport,
|
|
115
|
+
"aria-label": "Export table data as CSV",
|
|
116
|
+
children: /*#__PURE__*/ _jsx(DownloadIcon, {
|
|
117
|
+
fontSize: "inherit"
|
|
118
|
+
})
|
|
119
|
+
})
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
//# sourceMappingURL=TableExportAction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/TableExportAction.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 React, { useCallback, useMemo } from 'react';\nimport { escapeCsvValue, PanelData, sanitizeFilename } from '@perses-dev/plugin-system';\nimport { InfoTooltip } from '@perses-dev/components';\nimport { IconButton } from '@mui/material';\nimport DownloadIcon from 'mdi-material-ui/Download';\nimport { TimeSeriesData, transformData } from '@perses-dev/core';\nimport { TableProps } from './components';\nimport type { TableOptions } from './models';\nimport { buildRawTableData } from './table-data-utils';\n\nexport interface ExportColumn {\n key: string;\n header: string;\n}\n\n/**\n * Converts raw query results into the same tabular structure that TablePanel\n * renders, applying indexed column naming and configured transforms so the\n * CSV output matches the visual table.\n */\nexport function buildTableData(\n queryResults: Array<PanelData<TimeSeriesData>>,\n spec: TableOptions\n): { data: Array<Record<string, unknown>>; columns: ExportColumn[] } {\n // Use shared utility with forExport=true to get raw scalar values\n const rawData = buildRawTableData(queryResults, spec, { forExport: true });\n\n const transformed = transformData(rawData, spec.transforms ?? []);\n\n const allKeys: string[] = [];\n for (const entry of transformed) {\n for (const key of Object.keys(entry)) {\n if (!allKeys.includes(key)) allKeys.push(key);\n }\n }\n\n const columnSettings = spec.columnSettings ?? [];\n const columns: ExportColumn[] = [];\n const customized = new Set<string>();\n\n for (const col of columnSettings) {\n if (customized.has(col.name)) continue;\n customized.add(col.name);\n if (col.hide) continue;\n columns.push({ key: col.name, header: col.header ?? col.name });\n }\n\n if (!spec.defaultColumnHidden) {\n for (const key of allKeys) {\n if (!customized.has(key)) {\n columns.push({ key, header: key });\n }\n }\n }\n\n return { data: transformed, columns };\n}\n\nexport const TableExportAction: React.FC<TableProps> = ({ queryResults, spec, definition }) => {\n const tableData = useMemo(() => buildTableData(queryResults, spec), [queryResults, spec]);\n\n const canExport = tableData.data.length > 0 && tableData.columns.length > 0;\n\n const handleExport = useCallback(() => {\n if (!canExport) return;\n\n try {\n const title = definition?.spec?.display?.name || 'Table Data';\n const { data, columns } = tableData;\n\n const headerRow = columns.map((c) => escapeCsvValue(c.header)).join(',');\n const dataRows = data.map((row) => columns.map((col) => escapeCsvValue(row[col.key])).join(','));\n\n const csvString = [headerRow, ...dataRows].join('\\n') + '\\n';\n const csvBlob = new Blob([csvString], { type: 'text/csv;charset=utf-8' });\n\n const baseFilename = sanitizeFilename(title);\n const filename = `${baseFilename}_data.csv`;\n\n const url = URL.createObjectURL(csvBlob);\n try {\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n } finally {\n URL.revokeObjectURL(url);\n }\n } catch (error) {\n console.error('Table CSV export failed:', error);\n }\n }, [canExport, tableData, definition]);\n\n if (!canExport) {\n return null;\n }\n\n return (\n <InfoTooltip description=\"Export as CSV\">\n <IconButton size=\"small\" onClick={handleExport} aria-label=\"Export table data as CSV\">\n <DownloadIcon fontSize=\"inherit\" />\n </IconButton>\n </InfoTooltip>\n );\n};\n"],"names":["React","useCallback","useMemo","escapeCsvValue","sanitizeFilename","InfoTooltip","IconButton","DownloadIcon","transformData","buildRawTableData","buildTableData","queryResults","spec","rawData","forExport","transformed","transforms","allKeys","entry","key","Object","keys","includes","push","columnSettings","columns","customized","Set","col","has","name","add","hide","header","defaultColumnHidden","data","TableExportAction","definition","tableData","canExport","length","handleExport","title","display","headerRow","map","c","join","dataRows","row","csvString","csvBlob","Blob","type","baseFilename","filename","url","URL","createObjectURL","link","document","createElement","href","download","body","appendChild","click","removeChild","revokeObjectURL","error","console","description","size","onClick","aria-label","fontSize"],"mappings":"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"}
|
package/lib/cjs/Table.js
CHANGED
|
@@ -23,6 +23,7 @@ Object.defineProperty(exports, "Table", {
|
|
|
23
23
|
const _components = require("./components");
|
|
24
24
|
const _TableItemSelectionActionsEditor = require("./components/TableItemSelectionActionsEditor");
|
|
25
25
|
const _models = require("./models");
|
|
26
|
+
const _TableExportAction = require("./TableExportAction");
|
|
26
27
|
const Table = {
|
|
27
28
|
PanelComponent: _components.TablePanel,
|
|
28
29
|
supportedQueryTypes: [
|
|
@@ -51,5 +52,11 @@ const Table = {
|
|
|
51
52
|
content: _TableItemSelectionActionsEditor.TableItemSelectionActionsEditor
|
|
52
53
|
}
|
|
53
54
|
],
|
|
54
|
-
createInitialOptions: _models.createInitialTableOptions
|
|
55
|
+
createInitialOptions: _models.createInitialTableOptions,
|
|
56
|
+
actions: [
|
|
57
|
+
{
|
|
58
|
+
component: _TableExportAction.TableExportAction,
|
|
59
|
+
location: 'header'
|
|
60
|
+
}
|
|
61
|
+
]
|
|
55
62
|
};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
// Copyright 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: Object.getOwnPropertyDescriptor(all, name).get
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
_export(exports, {
|
|
24
|
+
get TableExportAction () {
|
|
25
|
+
return TableExportAction;
|
|
26
|
+
},
|
|
27
|
+
get buildTableData () {
|
|
28
|
+
return buildTableData;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
const _jsxruntime = require("react/jsx-runtime");
|
|
32
|
+
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
|
|
33
|
+
const _pluginsystem = require("@perses-dev/plugin-system");
|
|
34
|
+
const _components = require("@perses-dev/components");
|
|
35
|
+
const _material = require("@mui/material");
|
|
36
|
+
const _Download = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/Download"));
|
|
37
|
+
const _core = require("@perses-dev/core");
|
|
38
|
+
const _tabledatautils = require("./table-data-utils");
|
|
39
|
+
function _interop_require_default(obj) {
|
|
40
|
+
return obj && obj.__esModule ? obj : {
|
|
41
|
+
default: obj
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
45
|
+
if (typeof WeakMap !== "function") return null;
|
|
46
|
+
var cacheBabelInterop = new WeakMap();
|
|
47
|
+
var cacheNodeInterop = new WeakMap();
|
|
48
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
49
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
50
|
+
})(nodeInterop);
|
|
51
|
+
}
|
|
52
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
53
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
54
|
+
return obj;
|
|
55
|
+
}
|
|
56
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
57
|
+
return {
|
|
58
|
+
default: obj
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
62
|
+
if (cache && cache.has(obj)) {
|
|
63
|
+
return cache.get(obj);
|
|
64
|
+
}
|
|
65
|
+
var newObj = {
|
|
66
|
+
__proto__: null
|
|
67
|
+
};
|
|
68
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
69
|
+
for(var key in obj){
|
|
70
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
71
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
72
|
+
if (desc && (desc.get || desc.set)) {
|
|
73
|
+
Object.defineProperty(newObj, key, desc);
|
|
74
|
+
} else {
|
|
75
|
+
newObj[key] = obj[key];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
newObj.default = obj;
|
|
80
|
+
if (cache) {
|
|
81
|
+
cache.set(obj, newObj);
|
|
82
|
+
}
|
|
83
|
+
return newObj;
|
|
84
|
+
}
|
|
85
|
+
function buildTableData(queryResults, spec) {
|
|
86
|
+
// Use shared utility with forExport=true to get raw scalar values
|
|
87
|
+
const rawData = (0, _tabledatautils.buildRawTableData)(queryResults, spec, {
|
|
88
|
+
forExport: true
|
|
89
|
+
});
|
|
90
|
+
const transformed = (0, _core.transformData)(rawData, spec.transforms ?? []);
|
|
91
|
+
const allKeys = [];
|
|
92
|
+
for (const entry of transformed){
|
|
93
|
+
for (const key of Object.keys(entry)){
|
|
94
|
+
if (!allKeys.includes(key)) allKeys.push(key);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const columnSettings = spec.columnSettings ?? [];
|
|
98
|
+
const columns = [];
|
|
99
|
+
const customized = new Set();
|
|
100
|
+
for (const col of columnSettings){
|
|
101
|
+
if (customized.has(col.name)) continue;
|
|
102
|
+
customized.add(col.name);
|
|
103
|
+
if (col.hide) continue;
|
|
104
|
+
columns.push({
|
|
105
|
+
key: col.name,
|
|
106
|
+
header: col.header ?? col.name
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
if (!spec.defaultColumnHidden) {
|
|
110
|
+
for (const key of allKeys){
|
|
111
|
+
if (!customized.has(key)) {
|
|
112
|
+
columns.push({
|
|
113
|
+
key,
|
|
114
|
+
header: key
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
data: transformed,
|
|
121
|
+
columns
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const TableExportAction = ({ queryResults, spec, definition })=>{
|
|
125
|
+
const tableData = (0, _react.useMemo)(()=>buildTableData(queryResults, spec), [
|
|
126
|
+
queryResults,
|
|
127
|
+
spec
|
|
128
|
+
]);
|
|
129
|
+
const canExport = tableData.data.length > 0 && tableData.columns.length > 0;
|
|
130
|
+
const handleExport = (0, _react.useCallback)(()=>{
|
|
131
|
+
if (!canExport) return;
|
|
132
|
+
try {
|
|
133
|
+
const title = definition?.spec?.display?.name || 'Table Data';
|
|
134
|
+
const { data, columns } = tableData;
|
|
135
|
+
const headerRow = columns.map((c)=>(0, _pluginsystem.escapeCsvValue)(c.header)).join(',');
|
|
136
|
+
const dataRows = data.map((row)=>columns.map((col)=>(0, _pluginsystem.escapeCsvValue)(row[col.key])).join(','));
|
|
137
|
+
const csvString = [
|
|
138
|
+
headerRow,
|
|
139
|
+
...dataRows
|
|
140
|
+
].join('\n') + '\n';
|
|
141
|
+
const csvBlob = new Blob([
|
|
142
|
+
csvString
|
|
143
|
+
], {
|
|
144
|
+
type: 'text/csv;charset=utf-8'
|
|
145
|
+
});
|
|
146
|
+
const baseFilename = (0, _pluginsystem.sanitizeFilename)(title);
|
|
147
|
+
const filename = `${baseFilename}_data.csv`;
|
|
148
|
+
const url = URL.createObjectURL(csvBlob);
|
|
149
|
+
try {
|
|
150
|
+
const link = document.createElement('a');
|
|
151
|
+
link.href = url;
|
|
152
|
+
link.download = filename;
|
|
153
|
+
document.body.appendChild(link);
|
|
154
|
+
link.click();
|
|
155
|
+
document.body.removeChild(link);
|
|
156
|
+
} finally{
|
|
157
|
+
URL.revokeObjectURL(url);
|
|
158
|
+
}
|
|
159
|
+
} catch (error) {
|
|
160
|
+
console.error('Table CSV export failed:', error);
|
|
161
|
+
}
|
|
162
|
+
}, [
|
|
163
|
+
canExport,
|
|
164
|
+
tableData,
|
|
165
|
+
definition
|
|
166
|
+
]);
|
|
167
|
+
if (!canExport) {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
|
|
171
|
+
description: "Export as CSV",
|
|
172
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
|
|
173
|
+
size: "small",
|
|
174
|
+
onClick: handleExport,
|
|
175
|
+
"aria-label": "Export table data as CSV",
|
|
176
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Download.default, {
|
|
177
|
+
fontSize: "inherit"
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
});
|
|
181
|
+
};
|
|
@@ -36,6 +36,7 @@ const _dashboards = require("@perses-dev/dashboards");
|
|
|
36
36
|
const _pluginsystem = require("@perses-dev/plugin-system");
|
|
37
37
|
const _react = require("react");
|
|
38
38
|
const _models = require("../models");
|
|
39
|
+
const _tabledatautils = require("../table-data-utils");
|
|
39
40
|
const _EmbeddedPanel = require("./EmbeddedPanel");
|
|
40
41
|
function generateCellContentConfig(column) {
|
|
41
42
|
const plugin = column.plugin;
|
|
@@ -66,7 +67,7 @@ function generateCellContentConfig(column) {
|
|
|
66
67
|
function ColumnFilterDropdown({ allValues, selectedValues, onFilterChange, theme }) {
|
|
67
68
|
const values = [
|
|
68
69
|
...new Set(allValues)
|
|
69
|
-
].filter((v)=>v
|
|
70
|
+
].filter((v)=>v !== null).sort();
|
|
70
71
|
if (values.length === 0) {
|
|
71
72
|
return /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
|
|
72
73
|
"data-filter-dropdown": true,
|
|
@@ -225,7 +226,7 @@ function ColumnFilterDropdown({ allValues, selectedValues, onFilterChange, theme
|
|
|
225
226
|
function getTablePanelQueryOptions(spec) {
|
|
226
227
|
// if any cell renders a panel plugin, perform a range query instead of an instant query
|
|
227
228
|
return {
|
|
228
|
-
mode: (
|
|
229
|
+
mode: (0, _tabledatautils.getTablePanelQueryMode)(spec)
|
|
229
230
|
};
|
|
230
231
|
}
|
|
231
232
|
function TablePanel({ contentDimensions, spec, queryResults }) {
|
|
@@ -273,53 +274,12 @@ function TablePanel({ contentDimensions, spec, queryResults }) {
|
|
|
273
274
|
clearSelection
|
|
274
275
|
]);
|
|
275
276
|
// TODO: handle other query types
|
|
276
|
-
const queryMode = getTablePanelQueryOptions(spec).mode;
|
|
277
277
|
const rawData = (0, _react.useMemo)(()=>{
|
|
278
|
-
// Transform query results to a tabular format
|
|
279
|
-
|
|
280
|
-
return queryResults.flatMap((data, queryIndex)=>data.data.series.map((ts)=>({
|
|
281
|
-
data,
|
|
282
|
-
ts,
|
|
283
|
-
queryIndex
|
|
284
|
-
}))).map(({ data, ts, queryIndex })=>{
|
|
285
|
-
if (ts.values[0] === undefined) {
|
|
286
|
-
return {
|
|
287
|
-
...ts.labels
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
// If there are multiple queries, we need to add the query index to the value key and label key to avoid conflicts
|
|
291
|
-
const valueColumnName = queryResults.length === 1 ? 'value' : `value #${queryIndex + 1}`;
|
|
292
|
-
const labels = queryResults.length === 1 ? ts.labels : Object.entries(ts.labels ?? {}).reduce((acc, [key, value])=>{
|
|
293
|
-
if (key) acc[`${key} #${queryIndex + 1}`] = value;
|
|
294
|
-
return acc;
|
|
295
|
-
}, {});
|
|
296
|
-
// If the cell visualization is a panel plugin, filter the data by the current series
|
|
297
|
-
const columnValue = (spec.columnSettings ?? []).find((x)=>x.name === valueColumnName)?.plugin ? {
|
|
298
|
-
...data,
|
|
299
|
-
data: {
|
|
300
|
-
...data.data,
|
|
301
|
-
series: data.data.series.filter((s)=>s === ts)
|
|
302
|
-
}
|
|
303
|
-
} : ts.values[0][1];
|
|
304
|
-
if (queryMode === 'instant') {
|
|
305
|
-
// Timestamp is not indexed as it will be the same for all queries
|
|
306
|
-
return {
|
|
307
|
-
timestamp: ts.values[0][0],
|
|
308
|
-
[valueColumnName]: columnValue,
|
|
309
|
-
...labels
|
|
310
|
-
};
|
|
311
|
-
} else {
|
|
312
|
-
// Don't add a timestamp for range queries
|
|
313
|
-
return {
|
|
314
|
-
[valueColumnName]: columnValue,
|
|
315
|
-
...labels
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
});
|
|
278
|
+
// Transform query results to a tabular format using shared utility
|
|
279
|
+
return (0, _tabledatautils.buildRawTableData)(queryResults, spec);
|
|
319
280
|
}, [
|
|
320
281
|
queryResults,
|
|
321
|
-
|
|
322
|
-
spec.columnSettings
|
|
282
|
+
spec
|
|
323
283
|
]);
|
|
324
284
|
// Transform will be applied by their orders on the original data
|
|
325
285
|
const data = (0, _react.useMemo)(()=>(0, _core.transformData)(rawData, spec.transforms ?? []), [
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Copyright 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: Object.getOwnPropertyDescriptor(all, name).get
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
_export(exports, {
|
|
24
|
+
get buildRawTableData () {
|
|
25
|
+
return buildRawTableData;
|
|
26
|
+
},
|
|
27
|
+
get getTablePanelQueryMode () {
|
|
28
|
+
return getTablePanelQueryMode;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
function getTablePanelQueryMode(spec) {
|
|
32
|
+
return (spec.columnSettings ?? []).some((c)=>c.plugin) ? 'range' : 'instant';
|
|
33
|
+
}
|
|
34
|
+
function buildRawTableData(queryResults, spec, options = {}) {
|
|
35
|
+
const { forExport = false } = options;
|
|
36
|
+
const queryMode = getTablePanelQueryMode(spec);
|
|
37
|
+
return queryResults.flatMap((data, queryIndex)=>(data.data?.series ?? []).map((ts)=>({
|
|
38
|
+
data,
|
|
39
|
+
ts,
|
|
40
|
+
queryIndex
|
|
41
|
+
}))).map(({ data, ts, queryIndex })=>{
|
|
42
|
+
if (ts.values[0] === undefined) {
|
|
43
|
+
return {
|
|
44
|
+
...ts.labels
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// If there are multiple queries, add query index to value key and label keys to avoid conflicts
|
|
48
|
+
const valueColumnName = queryResults.length === 1 ? 'value' : `value #${queryIndex + 1}`;
|
|
49
|
+
const labels = queryResults.length === 1 ? ts.labels : Object.entries(ts.labels ?? {}).reduce((acc, [key, value])=>{
|
|
50
|
+
if (key) acc[`${key} #${queryIndex + 1}`] = value;
|
|
51
|
+
return acc;
|
|
52
|
+
}, {});
|
|
53
|
+
// For export: always use raw scalar values
|
|
54
|
+
// For rendering: plugin columns get embedded PanelData objects
|
|
55
|
+
let columnValue;
|
|
56
|
+
if (forExport) {
|
|
57
|
+
columnValue = ts.values[0][1];
|
|
58
|
+
} else {
|
|
59
|
+
const hasPlugin = (spec.columnSettings ?? []).find((x)=>x.name === valueColumnName)?.plugin;
|
|
60
|
+
columnValue = hasPlugin ? {
|
|
61
|
+
...data,
|
|
62
|
+
data: {
|
|
63
|
+
...data.data,
|
|
64
|
+
series: data.data.series.filter((s)=>s === ts)
|
|
65
|
+
}
|
|
66
|
+
} : ts.values[0][1];
|
|
67
|
+
}
|
|
68
|
+
if (queryMode === 'instant') {
|
|
69
|
+
// Timestamp is not indexed as it will be the same for all queries
|
|
70
|
+
return {
|
|
71
|
+
timestamp: ts.values[0][0],
|
|
72
|
+
[valueColumnName]: columnValue,
|
|
73
|
+
...labels
|
|
74
|
+
};
|
|
75
|
+
} else {
|
|
76
|
+
// Don't add a timestamp for range queries
|
|
77
|
+
return {
|
|
78
|
+
[valueColumnName]: columnValue,
|
|
79
|
+
...labels
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
1
2
|
import { Grid2Props as GridProps } from '@mui/material';
|
|
2
3
|
import { CellSettings } from '../models';
|
|
3
4
|
export interface ConditionalRuleProps extends Omit<GridProps, 'onChange'> {
|
|
@@ -5,11 +6,11 @@ export interface ConditionalRuleProps extends Omit<GridProps, 'onChange'> {
|
|
|
5
6
|
onChange: (cell: CellSettings) => void;
|
|
6
7
|
onDelete: () => void;
|
|
7
8
|
}
|
|
8
|
-
export declare function ConditionalRule({ cell, onChange, onDelete, ...props }: ConditionalRuleProps):
|
|
9
|
+
export declare function ConditionalRule({ cell, onChange, onDelete, ...props }: ConditionalRuleProps): ReactElement;
|
|
9
10
|
export interface ConditionalPanelProps {
|
|
10
11
|
cellSettings?: CellSettings[];
|
|
11
12
|
onChange: (cellSettings: CellSettings[] | undefined) => void;
|
|
12
13
|
addButtonText?: string;
|
|
13
14
|
}
|
|
14
|
-
export declare function ConditionalPanel({ cellSettings, onChange, addButtonText, }: ConditionalPanelProps):
|
|
15
|
+
export declare function ConditionalPanel({ cellSettings, onChange, addButtonText, }: ConditionalPanelProps): ReactElement;
|
|
15
16
|
//# sourceMappingURL=ConditionalPanel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConditionalPanel.d.ts","sourceRoot":"","sources":["../../../src/components/ConditionalPanel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ConditionalPanel.d.ts","sourceRoot":"","sources":["../../../src/components/ConditionalPanel.tsx"],"names":[],"mappings":"AAaA,OAAc,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAGL,UAAU,IAAI,SAAS,EAQxB,MAAM,eAAe,CAAC;AAIvB,OAAO,EAAE,YAAY,EAAyB,MAAM,WAAW,CAAC;AAGhE,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC;IACvE,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACvC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,oBAAoB,GAAG,YAAY,CAyH1G;AAGD,MAAM,WAAW,qBAAqB;IACpC,YAAY,CAAC,EAAE,YAAY,EAAE,CAAC;IAC9B,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,GAAG,SAAS,KAAK,IAAI,CAAC;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,YAAiB,EACjB,QAAQ,EACR,aAAwC,GACzC,EAAE,qBAAqB,GAAG,YAAY,CAmDtC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ConditionalPanel.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 React from 'react';\nimport {\n Button,\n Divider,\n Grid2Props as GridProps,\n IconButton,\n MenuItem,\n Stack,\n TextField,\n Tooltip,\n Typography,\n Grid2 as Grid,\n} from '@mui/material';\nimport DeleteIcon from 'mdi-material-ui/DeleteOutline';\nimport AddIcon from 'mdi-material-ui/Plus';\nimport { OptionsColorPicker } from '@perses-dev/components';\nimport { CellSettings, renderConditionEditor } from '../models';\n\n// Individual conditional formatting rule component\nexport interface ConditionalRuleProps extends Omit<GridProps, 'onChange'> {\n cell: CellSettings;\n onChange: (cell: CellSettings) => void;\n onDelete: () => void;\n}\n\nexport function ConditionalRule({ cell, onChange, onDelete, ...props }: ConditionalRuleProps) {\n return (\n <Grid container spacing={2} {...props}>\n <Grid size={{ xs: 5 }}>\n <Stack direction=\"row\" gap={1} width=\"100%\">\n <TextField\n select\n label=\"Type\"\n value={cell.condition.kind}\n onChange={(e) => onChange({ ...cell, condition: { kind: e.target.value } } as CellSettings)}\n required\n sx={{ width: '120px' }}\n >\n <MenuItem value=\"Value\">\n <Stack>\n <Typography>Value</Typography>\n {cell.condition.kind !== 'Value' && (\n <Typography variant=\"caption\">Matches an exact text value</Typography>\n )}\n </Stack>\n </MenuItem>\n <MenuItem value=\"Range\">\n <Stack>\n <Typography>Range</Typography>\n {cell.condition.kind !== 'Range' && (\n <Typography variant=\"caption\">Matches against a numerical range</Typography>\n )}\n </Stack>\n </MenuItem>\n <MenuItem value=\"Regex\">\n <Stack>\n <Typography>Regex</Typography>\n {cell.condition.kind !== 'Regex' && (\n <Typography variant=\"caption\">Matches against a regular expression</Typography>\n )}\n </Stack>\n </MenuItem>\n <MenuItem value=\"Misc\">\n <Stack>\n <Typography>Misc</Typography>\n {cell.condition.kind !== 'Misc' && (\n <Typography variant=\"caption\">Matches against empty, null and NaN values</Typography>\n )}\n </Stack>\n </MenuItem>\n </TextField>\n {renderConditionEditor(\n cell.condition,\n (updatedCondition) => onChange({ ...cell, condition: updatedCondition }),\n 'small'\n )}\n </Stack>\n </Grid>\n <Grid size={{ xs: 4 }}>\n <Stack spacing={1}>\n <TextField\n label=\"Display text\"\n value={cell.text}\n onChange={(e) => onChange({ ...cell, text: e.target.value })}\n fullWidth\n size=\"small\"\n />\n <Stack direction=\"row\" spacing={1}>\n <TextField\n label=\"Prefix\"\n placeholder=\"$\"\n value={cell.prefix ?? ''}\n onChange={(e) => onChange({ ...cell, prefix: e.target.value })}\n size=\"small\"\n />\n <TextField\n label=\"Suffix\"\n placeholder=\"%\"\n value={cell.suffix ?? ''}\n onChange={(e) => onChange({ ...cell, suffix: e.target.value })}\n size=\"small\"\n />\n </Stack>\n </Stack>\n </Grid>\n <Grid size={{ xs: 1 }}>\n <Stack direction=\"row\" justifyContent=\"center\" gap={1}>\n {cell.textColor ? (\n <OptionsColorPicker\n label=\"Text Color\"\n color={cell.textColor ?? '#000'}\n onColorChange={(color) => onChange({ ...cell, textColor: color } as CellSettings)}\n onClear={() => onChange({ ...cell, textColor: undefined } as CellSettings)}\n />\n ) : (\n <IconButton onClick={() => onChange({ ...cell, textColor: '#000' })}>\n <AddIcon />\n </IconButton>\n )}\n </Stack>\n </Grid>\n <Grid size={{ xs: 1 }}>\n <Stack direction=\"row\" justifyContent=\"center\">\n {cell.backgroundColor ? (\n <OptionsColorPicker\n label=\"Background Color\"\n color={cell.backgroundColor ?? '#fff'}\n onColorChange={(color) => onChange({ ...cell, backgroundColor: color } as CellSettings)}\n onClear={() => onChange({ ...cell, backgroundColor: undefined } as CellSettings)}\n />\n ) : (\n <IconButton onClick={() => onChange({ ...cell, backgroundColor: '#000' })}>\n <AddIcon />\n </IconButton>\n )}\n </Stack>\n </Grid>\n <Grid size={{ xs: 1 }} textAlign=\"end\">\n <Tooltip title=\"Remove cell settings\" placement=\"top\">\n <IconButton size=\"small\" sx={{ marginLeft: 'auto' }} onClick={onDelete} key=\"delete-cell-button\">\n <DeleteIcon />\n </IconButton>\n </Tooltip>\n </Grid>\n </Grid>\n );\n}\n\n// Complete conditional formatting panel with headers and list management\nexport interface ConditionalPanelProps {\n cellSettings?: CellSettings[];\n onChange: (cellSettings: CellSettings[] | undefined) => void;\n addButtonText?: string;\n}\n\nexport function ConditionalPanel({\n cellSettings = [],\n onChange,\n addButtonText = 'Add Conditional Format',\n}: ConditionalPanelProps) {\n const handleCellChange = (index: number, updatedCell: CellSettings) => {\n const updatedCells = [...cellSettings];\n updatedCells[index] = updatedCell;\n onChange(updatedCells);\n };\n\n const handleCellDelete = (index: number) => {\n const updatedCells = [...cellSettings];\n updatedCells.splice(index, 1);\n onChange(updatedCells.length > 0 ? updatedCells : undefined);\n };\n\n const handleAddCell = () => {\n const updatedCells = [...cellSettings];\n updatedCells.push({ condition: { kind: 'Value', spec: { value: '' } } });\n onChange(updatedCells);\n };\n\n return (\n <Stack spacing={3} sx={{ mt: 2 }}>\n <Grid container spacing={3}>\n <Grid size={{ xs: 5 }}>\n <Typography variant=\"subtitle1\">Condition</Typography>\n </Grid>\n <Grid size={{ xs: 4 }}>\n <Typography variant=\"subtitle1\">Display Text</Typography>\n </Grid>\n <Grid size={{ xs: 1 }} textAlign=\"center\">\n <Typography variant=\"subtitle1\">Color</Typography>\n </Grid>\n <Grid size={{ xs: 1 }} textAlign=\"center\">\n <Typography variant=\"subtitle1\">Background</Typography>\n </Grid>\n <Grid size={{ xs: 1 }}></Grid>\n </Grid>\n <Stack gap={1.5} divider={<Divider flexItem orientation=\"horizontal\" />}>\n {cellSettings.map((cell, i) => (\n <ConditionalRule\n key={i}\n cell={cell}\n onChange={(updatedCell: CellSettings) => handleCellChange(i, updatedCell)}\n onDelete={() => handleCellDelete(i)}\n />\n ))}\n </Stack>\n <Button variant=\"outlined\" startIcon={<AddIcon />} sx={{ marginTop: 1 }} onClick={handleAddCell}>\n {addButtonText}\n </Button>\n </Stack>\n );\n}\n"],"names":["React","Button","Divider","IconButton","MenuItem","Stack","TextField","Tooltip","Typography","Grid2","Grid","DeleteIcon","AddIcon","OptionsColorPicker","renderConditionEditor","ConditionalRule","cell","onChange","onDelete","props","container","spacing","size","xs","direction","gap","width","select","label","value","condition","kind","e","target","required","sx","variant","updatedCondition","text","fullWidth","placeholder","prefix","suffix","justifyContent","textColor","color","onColorChange","onClear","undefined","onClick","backgroundColor","textAlign","title","placement","marginLeft","ConditionalPanel","cellSettings","addButtonText","handleCellChange","index","updatedCell","updatedCells","handleCellDelete","splice","length","handleAddCell","push","spec","mt","divider","flexItem","orientation","map","i","startIcon","marginTop"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ConditionalPanel.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 React, { ReactElement } from 'react';\nimport {\n Button,\n Divider,\n Grid2Props as GridProps,\n IconButton,\n MenuItem,\n Stack,\n TextField,\n Tooltip,\n Typography,\n Grid2 as Grid,\n} from '@mui/material';\nimport DeleteIcon from 'mdi-material-ui/DeleteOutline';\nimport AddIcon from 'mdi-material-ui/Plus';\nimport { OptionsColorPicker } from '@perses-dev/components';\nimport { CellSettings, renderConditionEditor } from '../models';\n\n// Individual conditional formatting rule component\nexport interface ConditionalRuleProps extends Omit<GridProps, 'onChange'> {\n cell: CellSettings;\n onChange: (cell: CellSettings) => void;\n onDelete: () => void;\n}\n\nexport function ConditionalRule({ cell, onChange, onDelete, ...props }: ConditionalRuleProps): ReactElement {\n return (\n <Grid container spacing={2} {...props}>\n <Grid size={{ xs: 5 }}>\n <Stack direction=\"row\" gap={1} width=\"100%\">\n <TextField\n select\n label=\"Type\"\n value={cell.condition.kind}\n onChange={(e) => onChange({ ...cell, condition: { kind: e.target.value } } as CellSettings)}\n required\n sx={{ width: '120px' }}\n >\n <MenuItem value=\"Value\">\n <Stack>\n <Typography>Value</Typography>\n {cell.condition.kind !== 'Value' && (\n <Typography variant=\"caption\">Matches an exact text value</Typography>\n )}\n </Stack>\n </MenuItem>\n <MenuItem value=\"Range\">\n <Stack>\n <Typography>Range</Typography>\n {cell.condition.kind !== 'Range' && (\n <Typography variant=\"caption\">Matches against a numerical range</Typography>\n )}\n </Stack>\n </MenuItem>\n <MenuItem value=\"Regex\">\n <Stack>\n <Typography>Regex</Typography>\n {cell.condition.kind !== 'Regex' && (\n <Typography variant=\"caption\">Matches against a regular expression</Typography>\n )}\n </Stack>\n </MenuItem>\n <MenuItem value=\"Misc\">\n <Stack>\n <Typography>Misc</Typography>\n {cell.condition.kind !== 'Misc' && (\n <Typography variant=\"caption\">Matches against empty, null and NaN values</Typography>\n )}\n </Stack>\n </MenuItem>\n </TextField>\n {renderConditionEditor(\n cell.condition,\n (updatedCondition) => onChange({ ...cell, condition: updatedCondition }),\n 'small'\n )}\n </Stack>\n </Grid>\n <Grid size={{ xs: 4 }}>\n <Stack spacing={1}>\n <TextField\n label=\"Display text\"\n value={cell.text}\n onChange={(e) => onChange({ ...cell, text: e.target.value })}\n fullWidth\n size=\"small\"\n />\n <Stack direction=\"row\" spacing={1}>\n <TextField\n label=\"Prefix\"\n placeholder=\"$\"\n value={cell.prefix ?? ''}\n onChange={(e) => onChange({ ...cell, prefix: e.target.value })}\n size=\"small\"\n />\n <TextField\n label=\"Suffix\"\n placeholder=\"%\"\n value={cell.suffix ?? ''}\n onChange={(e) => onChange({ ...cell, suffix: e.target.value })}\n size=\"small\"\n />\n </Stack>\n </Stack>\n </Grid>\n <Grid size={{ xs: 1 }}>\n <Stack direction=\"row\" justifyContent=\"center\" gap={1}>\n {cell.textColor ? (\n <OptionsColorPicker\n label=\"Text Color\"\n color={cell.textColor ?? '#000'}\n onColorChange={(color) => onChange({ ...cell, textColor: color } as CellSettings)}\n onClear={() => onChange({ ...cell, textColor: undefined } as CellSettings)}\n />\n ) : (\n <IconButton onClick={() => onChange({ ...cell, textColor: '#000' })}>\n <AddIcon />\n </IconButton>\n )}\n </Stack>\n </Grid>\n <Grid size={{ xs: 1 }}>\n <Stack direction=\"row\" justifyContent=\"center\">\n {cell.backgroundColor ? (\n <OptionsColorPicker\n label=\"Background Color\"\n color={cell.backgroundColor ?? '#fff'}\n onColorChange={(color) => onChange({ ...cell, backgroundColor: color } as CellSettings)}\n onClear={() => onChange({ ...cell, backgroundColor: undefined } as CellSettings)}\n />\n ) : (\n <IconButton onClick={() => onChange({ ...cell, backgroundColor: '#000' })}>\n <AddIcon />\n </IconButton>\n )}\n </Stack>\n </Grid>\n <Grid size={{ xs: 1 }} textAlign=\"end\">\n <Tooltip title=\"Remove cell settings\" placement=\"top\">\n <IconButton size=\"small\" sx={{ marginLeft: 'auto' }} onClick={onDelete} key=\"delete-cell-button\">\n <DeleteIcon />\n </IconButton>\n </Tooltip>\n </Grid>\n </Grid>\n );\n}\n\n// Complete conditional formatting panel with headers and list management\nexport interface ConditionalPanelProps {\n cellSettings?: CellSettings[];\n onChange: (cellSettings: CellSettings[] | undefined) => void;\n addButtonText?: string;\n}\n\nexport function ConditionalPanel({\n cellSettings = [],\n onChange,\n addButtonText = 'Add Conditional Format',\n}: ConditionalPanelProps): ReactElement {\n const handleCellChange = (index: number, updatedCell: CellSettings): void => {\n const updatedCells = [...cellSettings];\n updatedCells[index] = updatedCell;\n onChange(updatedCells);\n };\n\n const handleCellDelete = (index: number): void => {\n const updatedCells = [...cellSettings];\n updatedCells.splice(index, 1);\n onChange(updatedCells.length > 0 ? updatedCells : undefined);\n };\n\n const handleAddCell = (): void => {\n const updatedCells = [...cellSettings];\n updatedCells.push({ condition: { kind: 'Value', spec: { value: '' } } });\n onChange(updatedCells);\n };\n\n return (\n <Stack spacing={3} sx={{ mt: 2 }}>\n <Grid container spacing={3}>\n <Grid size={{ xs: 5 }}>\n <Typography variant=\"subtitle1\">Condition</Typography>\n </Grid>\n <Grid size={{ xs: 4 }}>\n <Typography variant=\"subtitle1\">Display Text</Typography>\n </Grid>\n <Grid size={{ xs: 1 }} textAlign=\"center\">\n <Typography variant=\"subtitle1\">Color</Typography>\n </Grid>\n <Grid size={{ xs: 1 }} textAlign=\"center\">\n <Typography variant=\"subtitle1\">Background</Typography>\n </Grid>\n <Grid size={{ xs: 1 }}></Grid>\n </Grid>\n <Stack gap={1.5} divider={<Divider flexItem orientation=\"horizontal\" />}>\n {cellSettings.map((cell, i) => (\n <ConditionalRule\n key={i}\n cell={cell}\n onChange={(updatedCell: CellSettings) => handleCellChange(i, updatedCell)}\n onDelete={() => handleCellDelete(i)}\n />\n ))}\n </Stack>\n <Button variant=\"outlined\" startIcon={<AddIcon />} sx={{ marginTop: 1 }} onClick={handleAddCell}>\n {addButtonText}\n </Button>\n </Stack>\n );\n}\n"],"names":["React","Button","Divider","IconButton","MenuItem","Stack","TextField","Tooltip","Typography","Grid2","Grid","DeleteIcon","AddIcon","OptionsColorPicker","renderConditionEditor","ConditionalRule","cell","onChange","onDelete","props","container","spacing","size","xs","direction","gap","width","select","label","value","condition","kind","e","target","required","sx","variant","updatedCondition","text","fullWidth","placeholder","prefix","suffix","justifyContent","textColor","color","onColorChange","onClear","undefined","onClick","backgroundColor","textAlign","title","placement","marginLeft","ConditionalPanel","cellSettings","addButtonText","handleCellChange","index","updatedCell","updatedCells","handleCellDelete","splice","length","handleAddCell","push","spec","mt","divider","flexItem","orientation","map","i","startIcon","marginTop"],"mappings":"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"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { PanelData } from '@perses-dev/plugin-system';
|
|
2
2
|
import { QueryDataType, UnknownSpec } from '@perses-dev/core';
|
|
3
|
+
import { ReactElement } from 'react';
|
|
3
4
|
interface EmbeddedPanelProps {
|
|
4
5
|
kind: string;
|
|
5
6
|
spec: UnknownSpec;
|
|
6
7
|
queryResults: Array<PanelData<QueryDataType>>;
|
|
7
8
|
}
|
|
8
|
-
export declare function EmbeddedPanel({ kind, spec, queryResults }: EmbeddedPanelProps):
|
|
9
|
+
export declare function EmbeddedPanel({ kind, spec, queryResults }: EmbeddedPanelProps): ReactElement;
|
|
9
10
|
export {};
|
|
10
11
|
//# sourceMappingURL=EmbeddedPanel.d.ts.map
|