@perses-dev/dashboards 0.15.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/DashboardToolbar/DashboardToolbar.js +8 -12
- package/dist/cjs/components/DownloadButton/DownloadButton.js +109 -0
- package/dist/cjs/{utils/component-ids.js → components/DownloadButton/index.js} +11 -14
- package/dist/cjs/components/GridLayout/GridLayout.js +13 -2
- package/dist/cjs/components/GridLayout/GridTitle.js +11 -17
- package/dist/cjs/components/Panel/Panel.js +4 -2
- package/dist/cjs/components/Panel/PanelHeader.js +54 -50
- package/dist/cjs/components/PanelDrawer/PanelDrawer.js +1 -3
- package/dist/cjs/components/PanelDrawer/PanelDrawer.test.js +23 -0
- package/dist/cjs/components/TimeRangeControls/TimeRangeControls.test.js +3 -1
- package/dist/cjs/components/Variables/Variable.js +7 -46
- package/dist/cjs/components/Variables/VariableEditor.js +157 -126
- package/dist/cjs/components/Variables/VariableEditorForm/VariableEditorForm.js +353 -161
- package/dist/cjs/components/Variables/VariableList.js +15 -8
- package/dist/cjs/components/Variables/variable-model.js +74 -0
- package/dist/cjs/components/index.js +1 -0
- package/dist/cjs/context/DashboardProvider/panel-editor-slice.js +40 -15
- package/dist/cjs/context/DashboardProvider/panel-group-editor-slice.js +5 -9
- package/dist/cjs/context/DashboardProvider/panel-group-slice.js +16 -1
- package/dist/cjs/views/ViewDashboard/tests/panelGroups.test.js +15 -21
- package/dist/components/DashboardToolbar/DashboardToolbar.d.ts.map +1 -1
- package/dist/components/DashboardToolbar/DashboardToolbar.js +8 -12
- package/dist/components/DashboardToolbar/DashboardToolbar.js.map +1 -1
- package/dist/components/DownloadButton/DownloadButton.d.ts +3 -0
- package/dist/components/DownloadButton/DownloadButton.d.ts.map +1 -0
- package/dist/components/DownloadButton/DownloadButton.js +60 -0
- package/dist/components/DownloadButton/DownloadButton.js.map +1 -0
- package/dist/components/DownloadButton/index.d.ts +2 -0
- package/dist/components/DownloadButton/index.d.ts.map +1 -0
- package/dist/{utils/component-ids.js → components/DownloadButton/index.js} +2 -14
- package/dist/components/DownloadButton/index.js.map +1 -0
- package/dist/components/GridLayout/GridLayout.d.ts.map +1 -1
- package/dist/components/GridLayout/GridLayout.js +13 -2
- package/dist/components/GridLayout/GridLayout.js.map +1 -1
- package/dist/components/GridLayout/GridTitle.d.ts.map +1 -1
- package/dist/components/GridLayout/GridTitle.js +11 -17
- package/dist/components/GridLayout/GridTitle.js.map +1 -1
- package/dist/components/Panel/Panel.d.ts.map +1 -1
- package/dist/components/Panel/Panel.js +4 -2
- package/dist/components/Panel/Panel.js.map +1 -1
- package/dist/components/Panel/PanelHeader.d.ts.map +1 -1
- package/dist/components/Panel/PanelHeader.js +54 -50
- package/dist/components/Panel/PanelHeader.js.map +1 -1
- package/dist/components/PanelDrawer/PanelDrawer.js +1 -3
- package/dist/components/PanelDrawer/PanelDrawer.js.map +1 -1
- package/dist/components/PanelDrawer/PanelDrawer.test.js +23 -0
- package/dist/components/PanelDrawer/PanelDrawer.test.js.map +1 -1
- package/dist/components/TimeRangeControls/TimeRangeControls.test.js +4 -2
- package/dist/components/TimeRangeControls/TimeRangeControls.test.js.map +1 -1
- package/dist/components/Variables/Variable.d.ts.map +1 -1
- package/dist/components/Variables/Variable.js +8 -47
- package/dist/components/Variables/Variable.js.map +1 -1
- package/dist/components/Variables/VariableEditor.d.ts.map +1 -1
- package/dist/components/Variables/VariableEditor.js +159 -128
- package/dist/components/Variables/VariableEditor.js.map +1 -1
- package/dist/components/Variables/VariableEditorForm/VariableEditorForm.d.ts.map +1 -1
- package/dist/components/Variables/VariableEditorForm/VariableEditorForm.js +315 -162
- package/dist/components/Variables/VariableEditorForm/VariableEditorForm.js.map +1 -1
- package/dist/components/Variables/VariableEditorForm/variable-editor-form-model.js.map +1 -1
- package/dist/components/Variables/VariableList.d.ts.map +1 -1
- package/dist/components/Variables/VariableList.js +15 -8
- package/dist/components/Variables/VariableList.js.map +1 -1
- package/dist/components/Variables/variable-model.d.ts +8 -0
- package/dist/components/Variables/variable-model.d.ts.map +1 -0
- package/dist/components/Variables/variable-model.js +64 -0
- package/dist/components/Variables/variable-model.js.map +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/context/DashboardProvider/panel-editor-slice.d.ts.map +1 -1
- package/dist/context/DashboardProvider/panel-editor-slice.js +40 -15
- package/dist/context/DashboardProvider/panel-editor-slice.js.map +1 -1
- package/dist/context/DashboardProvider/panel-group-editor-slice.d.ts.map +1 -1
- package/dist/context/DashboardProvider/panel-group-editor-slice.js +5 -9
- package/dist/context/DashboardProvider/panel-group-editor-slice.js.map +1 -1
- package/dist/context/DashboardProvider/panel-group-slice.d.ts +9 -0
- package/dist/context/DashboardProvider/panel-group-slice.d.ts.map +1 -1
- package/dist/context/DashboardProvider/panel-group-slice.js +17 -0
- package/dist/context/DashboardProvider/panel-group-slice.js.map +1 -1
- package/dist/views/ViewDashboard/tests/panelGroups.test.js +15 -21
- package/dist/views/ViewDashboard/tests/panelGroups.test.js.map +1 -1
- package/package.json +4 -4
- package/dist/utils/component-ids.d.ts +0 -8
- package/dist/utils/component-ids.d.ts.map +0 -1
- package/dist/utils/component-ids.js.map +0 -1
|
@@ -27,6 +27,7 @@ const _components = require("@perses-dev/components");
|
|
|
27
27
|
const _context = require("../../context");
|
|
28
28
|
const _variables = require("../Variables");
|
|
29
29
|
const _timeRangeControls = require("../TimeRangeControls");
|
|
30
|
+
const _downloadButton = require("../DownloadButton");
|
|
30
31
|
function _interopRequireDefault(obj) {
|
|
31
32
|
return obj && obj.__esModule ? obj : {
|
|
32
33
|
default: obj
|
|
@@ -60,9 +61,7 @@ const DashboardToolbar = (props)=>{
|
|
|
60
61
|
/*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
61
62
|
direction: "row",
|
|
62
63
|
spacing: 1,
|
|
63
|
-
|
|
64
|
-
marginLeft: 'auto'
|
|
65
|
-
},
|
|
64
|
+
marginLeft: "auto",
|
|
66
65
|
children: [
|
|
67
66
|
/*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Button, {
|
|
68
67
|
variant: "contained",
|
|
@@ -94,11 +93,9 @@ const DashboardToolbar = (props)=>{
|
|
|
94
93
|
})
|
|
95
94
|
}),
|
|
96
95
|
/*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
97
|
-
direction:
|
|
96
|
+
direction: "row",
|
|
98
97
|
spacing: 1,
|
|
99
|
-
|
|
100
|
-
marginLeft: 'auto'
|
|
101
|
-
},
|
|
98
|
+
marginLeft: "auto",
|
|
102
99
|
children: [
|
|
103
100
|
/*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Button, {
|
|
104
101
|
startIcon: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_plusBoxOutline.default, {}),
|
|
@@ -117,7 +114,7 @@ const DashboardToolbar = (props)=>{
|
|
|
117
114
|
})
|
|
118
115
|
]
|
|
119
116
|
}) : /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
120
|
-
spacing:
|
|
117
|
+
spacing: 1,
|
|
121
118
|
padding: 2,
|
|
122
119
|
children: [
|
|
123
120
|
/*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Box, {
|
|
@@ -129,12 +126,11 @@ const DashboardToolbar = (props)=>{
|
|
|
129
126
|
dashboardTitle,
|
|
130
127
|
/*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
131
128
|
direction: "row",
|
|
132
|
-
spacing:
|
|
133
|
-
|
|
134
|
-
marginLeft: 'auto'
|
|
135
|
-
},
|
|
129
|
+
spacing: 1,
|
|
130
|
+
marginLeft: "auto",
|
|
136
131
|
children: [
|
|
137
132
|
/*#__PURE__*/ (0, _jsxRuntime.jsx)(_timeRangeControls.TimeRangeControls, {}),
|
|
133
|
+
/*#__PURE__*/ (0, _jsxRuntime.jsx)(_downloadButton.DownloadButton, {}),
|
|
138
134
|
isLaptopSize && /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Button, {
|
|
139
135
|
variant: "outlined",
|
|
140
136
|
startIcon: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_pencilOutline.default, {}),
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Copyright 2022 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, "DownloadButton", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: ()=>DownloadButton
|
|
20
|
+
});
|
|
21
|
+
const _jsxRuntime = require("react/jsx-runtime");
|
|
22
|
+
const _react = /*#__PURE__*/ _interopRequireWildcard(require("react"));
|
|
23
|
+
const _downloadOutline = /*#__PURE__*/ _interopRequireDefault(require("mdi-material-ui/DownloadOutline"));
|
|
24
|
+
const _material = require("@mui/material");
|
|
25
|
+
const _context = require("../../context");
|
|
26
|
+
function _interopRequireDefault(obj) {
|
|
27
|
+
return obj && obj.__esModule ? obj : {
|
|
28
|
+
default: obj
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
32
|
+
if (typeof WeakMap !== "function") return null;
|
|
33
|
+
var cacheBabelInterop = new WeakMap();
|
|
34
|
+
var cacheNodeInterop = new WeakMap();
|
|
35
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
36
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
37
|
+
})(nodeInterop);
|
|
38
|
+
}
|
|
39
|
+
function _interopRequireWildcard(obj, nodeInterop) {
|
|
40
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
41
|
+
return obj;
|
|
42
|
+
}
|
|
43
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
44
|
+
return {
|
|
45
|
+
default: obj
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
49
|
+
if (cache && cache.has(obj)) {
|
|
50
|
+
return cache.get(obj);
|
|
51
|
+
}
|
|
52
|
+
var newObj = {};
|
|
53
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
54
|
+
for(var key in obj){
|
|
55
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
56
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
57
|
+
if (desc && (desc.get || desc.set)) {
|
|
58
|
+
Object.defineProperty(newObj, key, desc);
|
|
59
|
+
} else {
|
|
60
|
+
newObj[key] = obj[key];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
newObj.default = obj;
|
|
65
|
+
if (cache) {
|
|
66
|
+
cache.set(obj, newObj);
|
|
67
|
+
}
|
|
68
|
+
return newObj;
|
|
69
|
+
}
|
|
70
|
+
function DownloadButton() {
|
|
71
|
+
const { dashboard } = (0, _context.useDashboard)();
|
|
72
|
+
const hiddenLinkRef = (0, _react.useRef)(null);
|
|
73
|
+
const onDownloadButtonClick = ()=>{
|
|
74
|
+
if (!hiddenLinkRef || !hiddenLinkRef.current) return;
|
|
75
|
+
// Create blob URL
|
|
76
|
+
const hiddenLinkUrl = URL.createObjectURL(new Blob([
|
|
77
|
+
JSON.stringify(dashboard)
|
|
78
|
+
], {
|
|
79
|
+
type: 'application/json'
|
|
80
|
+
}));
|
|
81
|
+
// Simulate click
|
|
82
|
+
hiddenLinkRef.current.href = hiddenLinkUrl;
|
|
83
|
+
hiddenLinkRef.current.click();
|
|
84
|
+
// Remove blob URL (for memory management)
|
|
85
|
+
URL.revokeObjectURL(hiddenLinkUrl);
|
|
86
|
+
};
|
|
87
|
+
return /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
88
|
+
children: [
|
|
89
|
+
/*#__PURE__*/ (0, _jsxRuntime.jsx)(DownloadIconButton, {
|
|
90
|
+
title: "Download JSON",
|
|
91
|
+
onClick: onDownloadButtonClick,
|
|
92
|
+
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_downloadOutline.default, {})
|
|
93
|
+
}),
|
|
94
|
+
/*#__PURE__*/ (0, _jsxRuntime.jsx)("a", {
|
|
95
|
+
ref: hiddenLinkRef,
|
|
96
|
+
style: {
|
|
97
|
+
display: 'none'
|
|
98
|
+
},
|
|
99
|
+
download: `${dashboard.metadata.name}.json`
|
|
100
|
+
})
|
|
101
|
+
]
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
const DownloadIconButton = (0, _material.styled)(_material.IconButton)(({ theme })=>({
|
|
105
|
+
border: `1px solid ${theme.palette.grey[300]}`,
|
|
106
|
+
borderRadius: theme.shape.borderRadius,
|
|
107
|
+
padding: '4px',
|
|
108
|
+
color: theme.palette.grey[900]
|
|
109
|
+
}));
|
|
@@ -14,18 +14,15 @@
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", {
|
|
15
15
|
value: true
|
|
16
16
|
});
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
id.current = `${prefix}-${globalThis.useIdValue++}`;
|
|
29
|
-
}
|
|
30
|
-
return id.current;
|
|
17
|
+
_exportStar(require("./DownloadButton"), exports);
|
|
18
|
+
function _exportStar(from, to) {
|
|
19
|
+
Object.keys(from).forEach(function(k) {
|
|
20
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) Object.defineProperty(to, k, {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: function() {
|
|
23
|
+
return from[k];
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
return from;
|
|
31
28
|
}
|
|
@@ -28,6 +28,7 @@ const _gridTitle = require("./GridTitle");
|
|
|
28
28
|
const _gridItemContent = require("./GridItemContent");
|
|
29
29
|
const _gridContainer = require("./GridContainer");
|
|
30
30
|
const ResponsiveGridLayout = (0, _reactGridLayout.WidthProvider)(_reactGridLayout.Responsive);
|
|
31
|
+
const SMALL_LAYOUT_BREAKPOINT = 'sm';
|
|
31
32
|
function GridLayout(props) {
|
|
32
33
|
const { panelGroupId /*...others */ } = props;
|
|
33
34
|
const theme = (0, _material.useTheme)();
|
|
@@ -36,6 +37,16 @@ function GridLayout(props) {
|
|
|
36
37
|
var ref;
|
|
37
38
|
const [isOpen, setIsOpen] = (0, _react.useState)((ref = !groupDefinition.isCollapsed) !== null && ref !== void 0 ? ref : true);
|
|
38
39
|
const { isEditMode } = (0, _context.useEditMode)();
|
|
40
|
+
const handleLayoutChange = (currentLayout, allLayouts)=>{
|
|
41
|
+
// Using the value from `allLayouts` instead of `currentLayout` because of
|
|
42
|
+
// a bug in react-layout-grid where `currentLayout` does not adjust properly
|
|
43
|
+
// when going to a smaller breakpoint and then back to a larger breakpoint.
|
|
44
|
+
// https://github.com/react-grid-layout/react-grid-layout/issues/1663
|
|
45
|
+
const smallLayout = allLayouts[SMALL_LAYOUT_BREAKPOINT];
|
|
46
|
+
if (smallLayout) {
|
|
47
|
+
updatePanelGroupLayouts(smallLayout);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
39
50
|
return /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_gridContainer.GridContainer, {
|
|
40
51
|
children: [
|
|
41
52
|
groupDefinition.title !== undefined && /*#__PURE__*/ (0, _jsxRuntime.jsx)(_gridTitle.GridTitle, {
|
|
@@ -72,9 +83,9 @@ function GridLayout(props) {
|
|
|
72
83
|
10
|
|
73
84
|
],
|
|
74
85
|
layouts: {
|
|
75
|
-
|
|
86
|
+
[SMALL_LAYOUT_BREAKPOINT]: groupDefinition.itemLayouts
|
|
76
87
|
},
|
|
77
|
-
onLayoutChange:
|
|
88
|
+
onLayoutChange: handleLayoutChange,
|
|
78
89
|
children: groupDefinition.itemLayouts.map(({ i })=>/*#__PURE__*/ (0, _jsxRuntime.jsx)("div", {
|
|
79
90
|
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components.ErrorBoundary, {
|
|
80
91
|
FallbackComponent: _components.ErrorAlert,
|
|
@@ -19,11 +19,10 @@ Object.defineProperty(exports, "GridTitle", {
|
|
|
19
19
|
get: ()=>GridTitle
|
|
20
20
|
});
|
|
21
21
|
const _jsxRuntime = require("react/jsx-runtime");
|
|
22
|
-
const _react = require("react");
|
|
23
22
|
const _material = require("@mui/material");
|
|
24
|
-
const _chevronUp = /*#__PURE__*/ _interopRequireDefault(require("mdi-material-ui/ChevronUp"));
|
|
25
23
|
const _chevronDown = /*#__PURE__*/ _interopRequireDefault(require("mdi-material-ui/ChevronDown"));
|
|
26
|
-
const
|
|
24
|
+
const _chevronRight = /*#__PURE__*/ _interopRequireDefault(require("mdi-material-ui/ChevronRight"));
|
|
25
|
+
const _chartBoxPlusOutline = /*#__PURE__*/ _interopRequireDefault(require("mdi-material-ui/ChartBoxPlusOutline"));
|
|
27
26
|
const _pencilOutline = /*#__PURE__*/ _interopRequireDefault(require("mdi-material-ui/PencilOutline"));
|
|
28
27
|
const _arrowUp = /*#__PURE__*/ _interopRequireDefault(require("mdi-material-ui/ArrowUp"));
|
|
29
28
|
const _arrowDown = /*#__PURE__*/ _interopRequireDefault(require("mdi-material-ui/ArrowDown"));
|
|
@@ -36,7 +35,6 @@ function _interopRequireDefault(obj) {
|
|
|
36
35
|
}
|
|
37
36
|
function GridTitle(props) {
|
|
38
37
|
const { panelGroupId , title , collapse } = props;
|
|
39
|
-
const [isHovered, setIsHovered] = (0, _react.useState)(false);
|
|
40
38
|
const { openAddPanel , openEditPanelGroup , moveUp , moveDown } = (0, _context.usePanelGroupActions)(panelGroupId);
|
|
41
39
|
const { openDeletePanelGroupDialog } = (0, _context.useDeletePanelGroupDialog)();
|
|
42
40
|
const { isEditMode } = (0, _context.useEditMode)();
|
|
@@ -55,44 +53,40 @@ function GridTitle(props) {
|
|
|
55
53
|
padding: (theme)=>theme.spacing(1),
|
|
56
54
|
backgroundColor: (theme)=>theme.palette.background.default
|
|
57
55
|
},
|
|
58
|
-
onMouseEnter: ()=>setIsHovered(true),
|
|
59
|
-
onMouseLeave: ()=>setIsHovered(false),
|
|
60
56
|
children: collapse ? /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
61
57
|
children: [
|
|
62
58
|
/*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.IconButton, {
|
|
63
59
|
onClick: collapse.onToggleOpen,
|
|
64
|
-
children: collapse.isOpen ? /*#__PURE__*/ (0, _jsxRuntime.jsx)(
|
|
60
|
+
children: collapse.isOpen ? /*#__PURE__*/ (0, _jsxRuntime.jsx)(_chevronDown.default, {}) : /*#__PURE__*/ (0, _jsxRuntime.jsx)(_chevronRight.default, {})
|
|
65
61
|
}),
|
|
66
62
|
text,
|
|
67
|
-
isEditMode &&
|
|
63
|
+
isEditMode && /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
68
64
|
direction: "row",
|
|
69
|
-
|
|
70
|
-
marginLeft: 'auto'
|
|
71
|
-
},
|
|
65
|
+
marginLeft: "auto",
|
|
72
66
|
children: [
|
|
73
67
|
/*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.IconButton, {
|
|
74
|
-
"aria-label":
|
|
68
|
+
"aria-label": `add panel to group ${title}`,
|
|
75
69
|
onClick: openAddPanel,
|
|
76
|
-
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(
|
|
70
|
+
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_chartBoxPlusOutline.default, {})
|
|
77
71
|
}),
|
|
78
72
|
/*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.IconButton, {
|
|
79
|
-
"aria-label":
|
|
73
|
+
"aria-label": `edit group ${title}`,
|
|
80
74
|
onClick: openEditPanelGroup,
|
|
81
75
|
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_pencilOutline.default, {})
|
|
82
76
|
}),
|
|
83
77
|
/*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.IconButton, {
|
|
84
|
-
"aria-label":
|
|
78
|
+
"aria-label": `delete group ${title}`,
|
|
85
79
|
onClick: ()=>openDeletePanelGroupDialog(panelGroupId),
|
|
86
80
|
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_deleteOutline.default, {})
|
|
87
81
|
}),
|
|
88
82
|
/*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.IconButton, {
|
|
89
|
-
"aria-label":
|
|
83
|
+
"aria-label": `move group ${title} down`,
|
|
90
84
|
disabled: moveDown === undefined,
|
|
91
85
|
onClick: moveDown,
|
|
92
86
|
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_arrowDown.default, {})
|
|
93
87
|
}),
|
|
94
88
|
/*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.IconButton, {
|
|
95
|
-
"aria-label":
|
|
89
|
+
"aria-label": `move group ${title} up`,
|
|
96
90
|
disabled: moveUp === undefined,
|
|
97
91
|
onClick: moveUp,
|
|
98
92
|
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_arrowUp.default, {})
|
|
@@ -24,7 +24,6 @@ const _useResizeObserver = /*#__PURE__*/ _interopRequireDefault(require("use-res
|
|
|
24
24
|
const _reactIntersectionObserver = require("react-intersection-observer");
|
|
25
25
|
const _components = require("@perses-dev/components");
|
|
26
26
|
const _material = require("@mui/material");
|
|
27
|
-
const _componentIds = require("../../utils/component-ids");
|
|
28
27
|
const _panelHeader = require("./PanelHeader");
|
|
29
28
|
const _panelContent = require("./PanelContent");
|
|
30
29
|
function _interopRequireDefault(obj) {
|
|
@@ -35,7 +34,7 @@ function _interopRequireDefault(obj) {
|
|
|
35
34
|
function Panel(props) {
|
|
36
35
|
const { definition , editHandlers , onMouseEnter , onMouseLeave , sx , ...others } = props;
|
|
37
36
|
// Make sure we have an ID we can use for aria attributes
|
|
38
|
-
const generatedPanelId = (0,
|
|
37
|
+
const generatedPanelId = (0, _components.useId)('Panel');
|
|
39
38
|
const headerId = `${generatedPanelId}-header`;
|
|
40
39
|
const [contentElement, setContentElement] = (0, _react.useState)(null);
|
|
41
40
|
const [isHovered, setIsHovered] = (0, _react.useState)(false);
|
|
@@ -109,6 +108,9 @@ function Panel(props) {
|
|
|
109
108
|
ref: setContentElement,
|
|
110
109
|
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components.ErrorBoundary, {
|
|
111
110
|
FallbackComponent: _components.ErrorAlert,
|
|
111
|
+
resetKeys: [
|
|
112
|
+
definition.spec.plugin.spec
|
|
113
|
+
],
|
|
112
114
|
children: inView === true && /*#__PURE__*/ (0, _jsxRuntime.jsx)(_panelContent.PanelContent, {
|
|
113
115
|
panelPluginKind: definition.spec.plugin.kind,
|
|
114
116
|
spec: definition.spec.plugin.spec,
|
|
@@ -33,58 +33,55 @@ function _interopRequireDefault(obj) {
|
|
|
33
33
|
function PanelHeader({ id , title , description , editHandlers , isHovered , sx , ...rest }) {
|
|
34
34
|
const titleElementId = `${id}-title`;
|
|
35
35
|
const descriptionTooltipId = `${id}-description`;
|
|
36
|
-
// Don't show any actions unless panel is hovered
|
|
37
36
|
let action = undefined;
|
|
38
|
-
if (
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
className: "drag-handle",
|
|
63
|
-
sx: {
|
|
64
|
-
cursor: 'grab'
|
|
65
|
-
}
|
|
66
|
-
})
|
|
67
|
-
})
|
|
68
|
-
]
|
|
69
|
-
});
|
|
70
|
-
} else if (description !== undefined) {
|
|
71
|
-
// If there aren't edit handlers and we have a description, show a button with a tooltip for the panel description
|
|
72
|
-
action = /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components.InfoTooltip, {
|
|
73
|
-
id: descriptionTooltipId,
|
|
74
|
-
description: description,
|
|
75
|
-
placement: _components.TooltipPlacement.Bottom,
|
|
76
|
-
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(HeaderIconButton, {
|
|
77
|
-
"aria-label": "Panel Description",
|
|
78
|
-
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_informationOutline.default, {
|
|
79
|
-
"aria-describedby": "info-tooltip",
|
|
80
|
-
"aria-hidden": false,
|
|
37
|
+
if (editHandlers !== undefined) {
|
|
38
|
+
// If there are edit handlers, always just show the edit buttons
|
|
39
|
+
action = /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
40
|
+
direction: "row",
|
|
41
|
+
spacing: 0.5,
|
|
42
|
+
alignItems: "center",
|
|
43
|
+
children: [
|
|
44
|
+
/*#__PURE__*/ (0, _jsxRuntime.jsx)(HeaderIconButton, {
|
|
45
|
+
"aria-label": `edit panel ${title}`,
|
|
46
|
+
size: "small",
|
|
47
|
+
onClick: editHandlers.onEditPanelClick,
|
|
48
|
+
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_pencilOutline.default, {})
|
|
49
|
+
}),
|
|
50
|
+
/*#__PURE__*/ (0, _jsxRuntime.jsx)(HeaderIconButton, {
|
|
51
|
+
"aria-label": `delete panel ${title}`,
|
|
52
|
+
size: "small",
|
|
53
|
+
onClick: editHandlers.onDeletePanelClick,
|
|
54
|
+
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_deleteOutline.default, {})
|
|
55
|
+
}),
|
|
56
|
+
/*#__PURE__*/ (0, _jsxRuntime.jsx)(HeaderIconButton, {
|
|
57
|
+
"aria-label": `move panel ${title}`,
|
|
58
|
+
size: "small",
|
|
59
|
+
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_dragVertical.default, {
|
|
60
|
+
className: "drag-handle",
|
|
81
61
|
sx: {
|
|
82
|
-
|
|
62
|
+
cursor: 'grab'
|
|
83
63
|
}
|
|
84
64
|
})
|
|
85
65
|
})
|
|
86
|
-
|
|
87
|
-
}
|
|
66
|
+
]
|
|
67
|
+
});
|
|
68
|
+
} else if (description !== undefined && isHovered) {
|
|
69
|
+
// If there aren't edit handlers and we have a description, show a button with a tooltip for the panel description
|
|
70
|
+
action = /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components.InfoTooltip, {
|
|
71
|
+
id: descriptionTooltipId,
|
|
72
|
+
description: description,
|
|
73
|
+
placement: _components.TooltipPlacement.Bottom,
|
|
74
|
+
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(HeaderIconButton, {
|
|
75
|
+
"aria-label": "Panel Description",
|
|
76
|
+
children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_informationOutline.default, {
|
|
77
|
+
"aria-describedby": "info-tooltip",
|
|
78
|
+
"aria-hidden": false,
|
|
79
|
+
sx: {
|
|
80
|
+
color: (theme)=>theme.palette.grey[700]
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
});
|
|
88
85
|
}
|
|
89
86
|
return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.CardHeader, {
|
|
90
87
|
id: id,
|
|
@@ -95,6 +92,15 @@ function PanelHeader({ id , title , description , editHandlers , isHovered , sx
|
|
|
95
92
|
title: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Typography, {
|
|
96
93
|
id: titleElementId,
|
|
97
94
|
variant: "subtitle1",
|
|
95
|
+
sx: {
|
|
96
|
+
// `minHeight` guarantees that the header has the correct height
|
|
97
|
+
// when there is no title (i.e. in the preview)
|
|
98
|
+
lineHeight: '24px',
|
|
99
|
+
minHeight: '24px',
|
|
100
|
+
whiteSpace: 'nowrap',
|
|
101
|
+
overflow: 'hidden',
|
|
102
|
+
textOverflow: 'ellipsis'
|
|
103
|
+
},
|
|
98
104
|
children: title
|
|
99
105
|
}),
|
|
100
106
|
action: action,
|
|
@@ -102,9 +108,7 @@ function PanelHeader({ id , title , description , editHandlers , isHovered , sx
|
|
|
102
108
|
padding: theme.spacing(1),
|
|
103
109
|
borderBottom: `solid 1px ${theme.palette.divider}`,
|
|
104
110
|
'.MuiCardHeader-content': {
|
|
105
|
-
|
|
106
|
-
overflow: 'hidden',
|
|
107
|
-
textOverflow: 'ellipsis'
|
|
111
|
+
overflow: 'hidden'
|
|
108
112
|
}
|
|
109
113
|
}), sx),
|
|
110
114
|
...rest
|
|
@@ -70,9 +70,7 @@ const PanelDrawer = ()=>{
|
|
|
70
70
|
/*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
71
71
|
direction: "row",
|
|
72
72
|
spacing: 1,
|
|
73
|
-
|
|
74
|
-
marginLeft: 'auto'
|
|
75
|
-
},
|
|
73
|
+
marginLeft: "auto",
|
|
76
74
|
children: [
|
|
77
75
|
/*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Button, {
|
|
78
76
|
type: "submit",
|
|
@@ -70,6 +70,29 @@ describe('Panel Drawer', ()=>{
|
|
|
70
70
|
}
|
|
71
71
|
});
|
|
72
72
|
});
|
|
73
|
+
it('should add panel with duplicate panel name', async ()=>{
|
|
74
|
+
const storeApi = renderPanelDrawer();
|
|
75
|
+
(0, _testUtils.act)(()=>storeApi.getState().openAddPanel());
|
|
76
|
+
const nameInput = await _react.screen.findByLabelText(/Name/);
|
|
77
|
+
_userEvent.default.type(nameInput, 'cpu');
|
|
78
|
+
_userEvent.default.click(_react.screen.getByText('Add'));
|
|
79
|
+
const panels = storeApi.getState().panels;
|
|
80
|
+
expect(panels).toMatchObject({
|
|
81
|
+
// make sure we don't have duplicate panel key by appending "-1"
|
|
82
|
+
'cpu-1': {
|
|
83
|
+
kind: 'Panel',
|
|
84
|
+
spec: {
|
|
85
|
+
display: {
|
|
86
|
+
name: 'cpu'
|
|
87
|
+
},
|
|
88
|
+
plugin: {
|
|
89
|
+
kind: '',
|
|
90
|
+
spec: {}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
});
|
|
73
96
|
it('should edit an existing panel', async ()=>{
|
|
74
97
|
const storeApi = renderPanelDrawer();
|
|
75
98
|
// Open the drawer for an existing panel
|
|
@@ -80,7 +80,9 @@ describe('TimeRangeControls', ()=>{
|
|
|
80
80
|
_userEvent.default.click(secondSelected);
|
|
81
81
|
expect(history.location.search).toEqual('?start=12h');
|
|
82
82
|
// back button should return to first option selected
|
|
83
|
-
|
|
83
|
+
(0, _react.act)(()=>{
|
|
84
|
+
history.back();
|
|
85
|
+
});
|
|
84
86
|
expect(history.location.search).toEqual('?start=5m');
|
|
85
87
|
});
|
|
86
88
|
// TODO: add additional tests for absolute time selection, other inputs, form validation, etc.
|
|
@@ -22,8 +22,8 @@ const _jsxRuntime = require("react/jsx-runtime");
|
|
|
22
22
|
const _react = require("react");
|
|
23
23
|
const _material = require("@mui/material");
|
|
24
24
|
const _pluginSystem = require("@perses-dev/plugin-system");
|
|
25
|
-
const _reactQuery = require("@tanstack/react-query");
|
|
26
25
|
const _context = require("../../context");
|
|
26
|
+
const _variableModel = require("./variable-model");
|
|
27
27
|
function TemplateVariable({ name }) {
|
|
28
28
|
var ref;
|
|
29
29
|
const ctx = (0, _context.useTemplateVariable)(name);
|
|
@@ -45,60 +45,16 @@ function TemplateVariable({ name }) {
|
|
|
45
45
|
]
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
|
-
/**
|
|
49
|
-
* Returns a serialized string of the current state of variable values.
|
|
50
|
-
*/ function getVariableValuesKey(v) {
|
|
51
|
-
return Object.values(v).map((v)=>JSON.stringify(v.value)).join(',');
|
|
52
|
-
}
|
|
53
48
|
function ListVariable({ name }) {
|
|
54
49
|
var ref, ref1, ref2, ref3;
|
|
55
50
|
const ctx = (0, _context.useTemplateVariable)(name);
|
|
56
51
|
const definition = ctx.definition;
|
|
57
|
-
const
|
|
52
|
+
const variablesOptionsQuery = (0, _variableModel.useListVariablePluginValues)(definition);
|
|
58
53
|
const { setVariableValue , setVariableLoading , setVariableOptions } = (0, _context.useTemplateVariableActions)();
|
|
59
|
-
const datasourceStore = (0, _pluginSystem.useDatasourceStore)();
|
|
60
|
-
const allVariables = (0, _pluginSystem.useTemplateVariableValues)();
|
|
61
|
-
const { timeRange } = (0, _pluginSystem.useTimeRange)();
|
|
62
|
-
const variablePluginCtx = {
|
|
63
|
-
timeRange,
|
|
64
|
-
datasourceStore,
|
|
65
|
-
variables: allVariables
|
|
66
|
-
};
|
|
67
|
-
const spec = definition.spec.plugin.spec;
|
|
68
|
-
let dependsOnVariables;
|
|
69
|
-
if (variablePlugin === null || variablePlugin === void 0 ? void 0 : variablePlugin.dependsOn) {
|
|
70
|
-
const dependencies = variablePlugin.dependsOn(spec, variablePluginCtx);
|
|
71
|
-
dependsOnVariables = dependencies.variables;
|
|
72
|
-
}
|
|
73
|
-
const variables = (0, _pluginSystem.useTemplateVariableValues)(dependsOnVariables);
|
|
74
54
|
const allowMultiple = (definition === null || definition === void 0 ? void 0 : definition.spec.allow_multiple) === true;
|
|
75
55
|
const allowAllValue = (definition === null || definition === void 0 ? void 0 : definition.spec.allow_all_value) === true;
|
|
76
56
|
var ref4;
|
|
77
57
|
const title = (ref4 = (ref = definition === null || definition === void 0 ? void 0 : definition.spec.display) === null || ref === void 0 ? void 0 : ref.name) !== null && ref4 !== void 0 ? ref4 : name;
|
|
78
|
-
let waitToLoad = false;
|
|
79
|
-
if (dependsOnVariables) {
|
|
80
|
-
waitToLoad = dependsOnVariables.some((v)=>{
|
|
81
|
-
var ref;
|
|
82
|
-
return (ref = variables[v]) === null || ref === void 0 ? void 0 : ref.loading;
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
const variablesValueKey = getVariableValuesKey(variables);
|
|
86
|
-
const variablesOptionsQuery = (0, _reactQuery.useQuery)([
|
|
87
|
-
name,
|
|
88
|
-
definition,
|
|
89
|
-
variablesValueKey,
|
|
90
|
-
timeRange
|
|
91
|
-
], async ()=>{
|
|
92
|
-
const resp = await (variablePlugin === null || variablePlugin === void 0 ? void 0 : variablePlugin.getVariableOptions(spec, {
|
|
93
|
-
datasourceStore,
|
|
94
|
-
variables,
|
|
95
|
-
timeRange
|
|
96
|
-
}));
|
|
97
|
-
var ref;
|
|
98
|
-
return (ref = resp === null || resp === void 0 ? void 0 : resp.data) !== null && ref !== void 0 ? ref : [];
|
|
99
|
-
}, {
|
|
100
|
-
enabled: !!variablePlugin || waitToLoad
|
|
101
|
-
});
|
|
102
58
|
(0, _react.useEffect)(()=>{
|
|
103
59
|
setVariableLoading(name, variablesOptionsQuery.isFetching);
|
|
104
60
|
if (variablesOptionsQuery.data) {
|
|
@@ -199,6 +155,11 @@ function ListVariable({ name }) {
|
|
|
199
155
|
disabled: true,
|
|
200
156
|
children: "Loading"
|
|
201
157
|
}),
|
|
158
|
+
finalOptions.length === 0 && /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.MenuItem, {
|
|
159
|
+
value: "empty",
|
|
160
|
+
disabled: true,
|
|
161
|
+
children: "No options"
|
|
162
|
+
}),
|
|
202
163
|
finalOptions.map((option)=>/*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.MenuItem, {
|
|
203
164
|
value: option.value,
|
|
204
165
|
children: option.label
|