@perses-dev/dashboards 0.52.0-beta.4 → 0.52.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/GridLayout/GridItemContent.js +137 -17
- package/dist/cjs/components/GridLayout/GridLayout.js +78 -126
- package/dist/cjs/components/GridLayout/Row.js +150 -0
- package/dist/cjs/components/GridLayout/index.js +1 -0
- package/dist/cjs/components/LeaveDialog/LeaveDialog.js +44 -0
- package/dist/cjs/components/LeaveDialog/index.js +30 -0
- package/dist/cjs/components/Panel/Panel.js +7 -2
- package/dist/cjs/components/Panel/PanelActions.js +25 -5
- package/dist/cjs/components/Panel/PanelHeader.js +33 -15
- package/dist/cjs/components/PanelDrawer/PanelDrawer.js +58 -21
- package/dist/cjs/components/PanelGroupDialog/PanelGroupDialog.js +3 -0
- package/dist/cjs/components/PanelGroupDialog/PanelGroupEditorForm.js +35 -15
- package/dist/cjs/components/index.js +1 -0
- package/dist/cjs/constants/user-interface-text.js +4 -2
- package/dist/cjs/context/DashboardProvider/DashboardProvider.js +7 -8
- package/dist/cjs/context/DashboardProvider/DashboardProviderWithQueryParams.js +3 -3
- package/dist/cjs/context/DashboardProvider/panel-editor-slice.js +1 -0
- package/dist/cjs/context/DashboardProvider/panel-group-editor-slice.js +6 -2
- package/dist/cjs/context/DashboardProvider/panel-group-slice.js +1 -0
- package/dist/cjs/context/DashboardProvider/view-panel-slice.js +10 -3
- package/dist/cjs/context/VariableProvider/VariableProvider.js +1 -1
- package/dist/cjs/context/useDashboard.js +5 -4
- package/dist/cjs/views/ViewDashboard/DashboardApp.js +7 -3
- package/dist/cjs/views/ViewDashboard/ViewDashboard.js +9 -8
- package/dist/components/DashboardToolbar/DashboardToolbar.d.ts +2 -2
- package/dist/components/DashboardToolbar/DashboardToolbar.d.ts.map +1 -1
- package/dist/components/DashboardToolbar/DashboardToolbar.js.map +1 -1
- package/dist/components/GridLayout/GridItemContent.d.ts.map +1 -1
- package/dist/components/GridLayout/GridItemContent.js +99 -20
- package/dist/components/GridLayout/GridItemContent.js.map +1 -1
- package/dist/components/GridLayout/GridLayout.d.ts +8 -0
- package/dist/components/GridLayout/GridLayout.d.ts.map +1 -1
- package/dist/components/GridLayout/GridLayout.js +72 -126
- package/dist/components/GridLayout/GridLayout.js.map +1 -1
- package/dist/components/GridLayout/Row.d.ts +17 -0
- package/dist/components/GridLayout/Row.d.ts.map +1 -0
- package/dist/components/GridLayout/Row.js +142 -0
- package/dist/components/GridLayout/Row.js.map +1 -0
- package/dist/components/GridLayout/index.d.ts +1 -0
- package/dist/components/GridLayout/index.d.ts.map +1 -1
- package/dist/components/GridLayout/index.js +1 -0
- package/dist/components/GridLayout/index.js.map +1 -1
- package/dist/components/LeaveDialog/LeaveDialog.d.ts +7 -0
- package/dist/components/LeaveDialog/LeaveDialog.d.ts.map +1 -0
- package/dist/components/LeaveDialog/LeaveDialog.js +36 -0
- package/dist/components/LeaveDialog/LeaveDialog.js.map +1 -0
- package/dist/components/LeaveDialog/index.d.ts +2 -0
- package/dist/components/LeaveDialog/index.d.ts.map +1 -0
- package/dist/components/LeaveDialog/index.js +15 -0
- package/dist/components/LeaveDialog/index.js.map +1 -0
- package/dist/components/Panel/Panel.d.ts +6 -0
- package/dist/components/Panel/Panel.d.ts.map +1 -1
- package/dist/components/Panel/Panel.js +7 -2
- package/dist/components/Panel/Panel.js.map +1 -1
- package/dist/components/Panel/PanelActions.d.ts +5 -0
- package/dist/components/Panel/PanelActions.d.ts.map +1 -1
- package/dist/components/Panel/PanelActions.js +25 -5
- package/dist/components/Panel/PanelActions.js.map +1 -1
- package/dist/components/Panel/PanelHeader.d.ts +7 -1
- package/dist/components/Panel/PanelHeader.d.ts.map +1 -1
- package/dist/components/Panel/PanelHeader.js +34 -16
- package/dist/components/Panel/PanelHeader.js.map +1 -1
- package/dist/components/PanelDrawer/PanelDrawer.d.ts.map +1 -1
- package/dist/components/PanelDrawer/PanelDrawer.js +59 -22
- package/dist/components/PanelDrawer/PanelDrawer.js.map +1 -1
- package/dist/components/PanelGroupDialog/PanelGroupDialog.d.ts.map +1 -1
- package/dist/components/PanelGroupDialog/PanelGroupDialog.js +3 -0
- package/dist/components/PanelGroupDialog/PanelGroupDialog.js.map +1 -1
- package/dist/components/PanelGroupDialog/PanelGroupEditorForm.d.ts +1 -0
- package/dist/components/PanelGroupDialog/PanelGroupEditorForm.d.ts.map +1 -1
- package/dist/components/PanelGroupDialog/PanelGroupEditorForm.js +36 -16
- package/dist/components/PanelGroupDialog/PanelGroupEditorForm.js.map +1 -1
- 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/constants/user-interface-text.d.ts +2 -0
- package/dist/constants/user-interface-text.d.ts.map +1 -1
- package/dist/constants/user-interface-text.js +4 -2
- package/dist/constants/user-interface-text.js.map +1 -1
- package/dist/context/DashboardProvider/DashboardProvider.d.ts +5 -5
- package/dist/context/DashboardProvider/DashboardProvider.d.ts.map +1 -1
- package/dist/context/DashboardProvider/DashboardProvider.js +7 -8
- package/dist/context/DashboardProvider/DashboardProvider.js.map +1 -1
- package/dist/context/DashboardProvider/DashboardProviderWithQueryParams.js +4 -4
- package/dist/context/DashboardProvider/DashboardProviderWithQueryParams.js.map +1 -1
- package/dist/context/DashboardProvider/common.d.ts +1 -1
- package/dist/context/DashboardProvider/common.d.ts.map +1 -1
- package/dist/context/DashboardProvider/common.js.map +1 -1
- package/dist/context/DashboardProvider/panel-editor-slice.d.ts +1 -0
- package/dist/context/DashboardProvider/panel-editor-slice.d.ts.map +1 -1
- package/dist/context/DashboardProvider/panel-editor-slice.js +1 -0
- package/dist/context/DashboardProvider/panel-editor-slice.js.map +1 -1
- package/dist/context/DashboardProvider/panel-group-editor-slice.d.ts +1 -0
- package/dist/context/DashboardProvider/panel-group-editor-slice.d.ts.map +1 -1
- package/dist/context/DashboardProvider/panel-group-editor-slice.js +6 -2
- package/dist/context/DashboardProvider/panel-group-editor-slice.js.map +1 -1
- package/dist/context/DashboardProvider/panel-group-slice.d.ts +3 -0
- package/dist/context/DashboardProvider/panel-group-slice.d.ts.map +1 -1
- package/dist/context/DashboardProvider/panel-group-slice.js +1 -0
- package/dist/context/DashboardProvider/panel-group-slice.js.map +1 -1
- package/dist/context/DashboardProvider/view-panel-slice.d.ts +6 -2
- package/dist/context/DashboardProvider/view-panel-slice.d.ts.map +1 -1
- package/dist/context/DashboardProvider/view-panel-slice.js +10 -3
- package/dist/context/DashboardProvider/view-panel-slice.js.map +1 -1
- package/dist/context/VariableProvider/VariableProvider.js +1 -1
- package/dist/context/VariableProvider/VariableProvider.js.map +1 -1
- package/dist/context/useDashboard.js +5 -4
- package/dist/context/useDashboard.js.map +1 -1
- package/dist/views/ViewDashboard/DashboardApp.d.ts +7 -6
- package/dist/views/ViewDashboard/DashboardApp.d.ts.map +1 -1
- package/dist/views/ViewDashboard/DashboardApp.js +8 -4
- package/dist/views/ViewDashboard/DashboardApp.js.map +1 -1
- package/dist/views/ViewDashboard/ViewDashboard.d.ts.map +1 -1
- package/dist/views/ViewDashboard/ViewDashboard.js +9 -8
- package/dist/views/ViewDashboard/ViewDashboard.js.map +1 -1
- package/package.json +5 -5
|
@@ -34,7 +34,7 @@ function _interop_require_default(obj) {
|
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
const Panel = /*#__PURE__*/ (0, _react.memo)(function Panel(props) {
|
|
37
|
-
const { definition, readHandlers, editHandlers, onMouseEnter, onMouseLeave, sx, panelOptions, panelGroupItemId, ...others } = props;
|
|
37
|
+
const { definition, readHandlers, editHandlers, onMouseEnter, onMouseLeave, sx, panelOptions, panelGroupItemId, viewQueriesHandler, ...others } = props;
|
|
38
38
|
// Make sure we have an ID we can use for aria attributes
|
|
39
39
|
const generatedPanelId = (0, _components.useId)('Panel');
|
|
40
40
|
const headerId = `${generatedPanelId}-header`;
|
|
@@ -142,6 +142,8 @@ const Panel = /*#__PURE__*/ (0, _react.memo)(function Panel(props) {
|
|
|
142
142
|
const handleMouseLeave = (e)=>{
|
|
143
143
|
onMouseLeave?.(e);
|
|
144
144
|
};
|
|
145
|
+
// default value for showIcons: if the dashboard is in editing mode or the panel is in fullscreen mode: 'always', otherwise 'hover'
|
|
146
|
+
const showIcons = panelOptions?.showIcons ?? (editHandlers || readHandlers?.isPanelViewed ? 'always' : 'hover');
|
|
145
147
|
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Card, {
|
|
146
148
|
component: "section",
|
|
147
149
|
sx: (0, _components.combineSx)({
|
|
@@ -172,11 +174,14 @@ const Panel = /*#__PURE__*/ (0, _react.memo)(function Panel(props) {
|
|
|
172
174
|
queryResults: queryResults,
|
|
173
175
|
readHandlers: readHandlers,
|
|
174
176
|
editHandlers: editHandlers,
|
|
177
|
+
viewQueriesHandler: viewQueriesHandler,
|
|
175
178
|
links: definition.spec.links,
|
|
176
179
|
pluginActions: pluginActions,
|
|
180
|
+
showIcons: showIcons,
|
|
177
181
|
sx: {
|
|
178
182
|
paddingX: `${chartsTheme.container.padding.default}px`
|
|
179
|
-
}
|
|
183
|
+
},
|
|
184
|
+
dimension: contentDimensions
|
|
180
185
|
}),
|
|
181
186
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.CardContent, {
|
|
182
187
|
component: "figure",
|
|
@@ -24,6 +24,7 @@ const _jsxruntime = require("react/jsx-runtime");
|
|
|
24
24
|
const _material = require("@mui/material");
|
|
25
25
|
const _react = require("react");
|
|
26
26
|
const _components = require("@perses-dev/components");
|
|
27
|
+
const _DatabaseSearch = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/DatabaseSearch"));
|
|
27
28
|
const _ArrowCollapse = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/ArrowCollapse"));
|
|
28
29
|
const _ArrowExpand = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/ArrowExpand"));
|
|
29
30
|
const _PencilOutline = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/PencilOutline"));
|
|
@@ -47,7 +48,7 @@ const ConditionalBox = (0, _material.styled)(_material.Box)({
|
|
|
47
48
|
flexGrow: 1,
|
|
48
49
|
justifyContent: 'flex-end'
|
|
49
50
|
});
|
|
50
|
-
const PanelActions = ({ editHandlers, readHandlers, extra, title, description, descriptionTooltipId, links, queryResults, pluginActions = [] })=>{
|
|
51
|
+
const PanelActions = ({ editHandlers, readHandlers, viewQueriesHandler, extra, title, description, descriptionTooltipId, links, queryResults, pluginActions = [], showIcons })=>{
|
|
51
52
|
const descriptionAction = (0, _react.useMemo)(()=>{
|
|
52
53
|
if (description && description.trim().length > 0) {
|
|
53
54
|
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
|
|
@@ -124,6 +125,23 @@ const PanelActions = ({ editHandlers, readHandlers, extra, title, description, d
|
|
|
124
125
|
readHandlers,
|
|
125
126
|
title
|
|
126
127
|
]);
|
|
128
|
+
const viewQueryAction = (0, _react.useMemo)(()=>{
|
|
129
|
+
if (!viewQueriesHandler?.onClick) return null;
|
|
130
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
|
|
131
|
+
description: _constants.TOOLTIP_TEXT.queryView,
|
|
132
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_HeaderIconButton.HeaderIconButton, {
|
|
133
|
+
"aria-label": _constants.ARIA_LABEL_TEXT.openQueryView(title),
|
|
134
|
+
size: "small",
|
|
135
|
+
onClick: viewQueriesHandler.onClick,
|
|
136
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_DatabaseSearch.default, {
|
|
137
|
+
fontSize: "inherit"
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
});
|
|
141
|
+
}, [
|
|
142
|
+
viewQueriesHandler,
|
|
143
|
+
title
|
|
144
|
+
]);
|
|
127
145
|
const editActions = (0, _react.useMemo)(()=>{
|
|
128
146
|
if (editHandlers !== undefined) {
|
|
129
147
|
// If there are edit handlers, always just show the edit buttons
|
|
@@ -203,8 +221,8 @@ const PanelActions = ({ editHandlers, readHandlers, extra, title, description, d
|
|
|
203
221
|
flexGrow: 1
|
|
204
222
|
}
|
|
205
223
|
});
|
|
206
|
-
// if the panel is in non-editing, non-fullscreen mode
|
|
207
|
-
const OnHover = ({ children })=>
|
|
224
|
+
// By default, the panel header shows certain icons only on hover if the panel is in non-editing, non-fullscreen mode
|
|
225
|
+
const OnHover = ({ children })=>showIcons === 'hover' ? /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
|
|
208
226
|
sx: {
|
|
209
227
|
display: 'var(--panel-hover, none)'
|
|
210
228
|
},
|
|
@@ -235,6 +253,7 @@ const PanelActions = ({ editHandlers, readHandlers, extra, title, description, d
|
|
|
235
253
|
" ",
|
|
236
254
|
extraActions,
|
|
237
255
|
" ",
|
|
256
|
+
viewQueryAction,
|
|
238
257
|
readActions,
|
|
239
258
|
" ",
|
|
240
259
|
pluginActions,
|
|
@@ -266,13 +285,14 @@ const PanelActions = ({ editHandlers, readHandlers, extra, title, description, d
|
|
|
266
285
|
/*#__PURE__*/ (0, _jsxruntime.jsxs)(OnHover, {
|
|
267
286
|
children: [
|
|
268
287
|
extraActions,
|
|
269
|
-
" ",
|
|
270
288
|
readActions,
|
|
271
289
|
/*#__PURE__*/ (0, _jsxruntime.jsxs)(OverflowMenu, {
|
|
272
290
|
title: title,
|
|
273
291
|
children: [
|
|
274
292
|
editActions,
|
|
275
293
|
" ",
|
|
294
|
+
viewQueryAction,
|
|
295
|
+
" ",
|
|
276
296
|
pluginActions
|
|
277
297
|
]
|
|
278
298
|
}),
|
|
@@ -303,7 +323,7 @@ const PanelActions = ({ editHandlers, readHandlers, extra, title, description, d
|
|
|
303
323
|
/*#__PURE__*/ (0, _jsxruntime.jsxs)(OnHover, {
|
|
304
324
|
children: [
|
|
305
325
|
extraActions,
|
|
306
|
-
|
|
326
|
+
viewQueryAction,
|
|
307
327
|
readActions,
|
|
308
328
|
" ",
|
|
309
329
|
editActions,
|
|
@@ -24,13 +24,24 @@ const _jsxruntime = require("react/jsx-runtime");
|
|
|
24
24
|
const _material = require("@mui/material");
|
|
25
25
|
const _components = require("@perses-dev/components");
|
|
26
26
|
const _pluginsystem = require("@perses-dev/plugin-system");
|
|
27
|
+
const _react = require("react");
|
|
27
28
|
const _constants = require("../../constants");
|
|
28
29
|
const _PanelActions = require("./PanelActions");
|
|
29
|
-
function PanelHeader({ id, title: rawTitle, description: rawDescription, links, queryResults, readHandlers, editHandlers, sx, extra, pluginActions, ...rest }) {
|
|
30
|
+
function PanelHeader({ id, title: rawTitle, description: rawDescription, links, queryResults, readHandlers, editHandlers, sx, extra, pluginActions, showIcons, viewQueriesHandler, dimension, ...rest }) {
|
|
30
31
|
const titleElementId = `${id}-title`;
|
|
31
32
|
const descriptionTooltipId = `${id}-description`;
|
|
32
33
|
const title = (0, _pluginsystem.useReplaceVariablesInString)(rawTitle);
|
|
33
34
|
const description = (0, _pluginsystem.useReplaceVariablesInString)(rawDescription);
|
|
35
|
+
const textRef = (0, _react.useRef)(null);
|
|
36
|
+
const [isEllipsisActive, setIsEllipsisActive] = (0, _react.useState)(false);
|
|
37
|
+
(0, _react.useEffect)(()=>{
|
|
38
|
+
if (textRef.current && dimension?.width) {
|
|
39
|
+
setIsEllipsisActive(textRef.current.scrollWidth > textRef.current.clientWidth);
|
|
40
|
+
}
|
|
41
|
+
}, [
|
|
42
|
+
title,
|
|
43
|
+
dimension?.width
|
|
44
|
+
]);
|
|
34
45
|
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.CardHeader, {
|
|
35
46
|
id: id,
|
|
36
47
|
component: "header",
|
|
@@ -42,19 +53,24 @@ function PanelHeader({ id, title: rawTitle, description: rawDescription, links,
|
|
|
42
53
|
alignItems: "center",
|
|
43
54
|
height: "var(--panel-header-height, 30px)",
|
|
44
55
|
children: [
|
|
45
|
-
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Tooltip, {
|
|
57
|
+
title: title,
|
|
58
|
+
disableHoverListener: !isEllipsisActive,
|
|
59
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Typography, {
|
|
60
|
+
id: titleElementId,
|
|
61
|
+
variant: "subtitle1",
|
|
62
|
+
ref: textRef,
|
|
63
|
+
sx: {
|
|
64
|
+
// `minHeight` guarantees that the header has the correct height
|
|
65
|
+
// when there is no title (i.e. in the preview)
|
|
66
|
+
lineHeight: '24px',
|
|
67
|
+
minHeight: '26px',
|
|
68
|
+
whiteSpace: 'nowrap',
|
|
69
|
+
overflow: 'hidden',
|
|
70
|
+
textOverflow: 'ellipsis'
|
|
71
|
+
},
|
|
72
|
+
children: title
|
|
73
|
+
})
|
|
58
74
|
}),
|
|
59
75
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(_PanelActions.PanelActions, {
|
|
60
76
|
title: title,
|
|
@@ -63,9 +79,11 @@ function PanelHeader({ id, title: rawTitle, description: rawDescription, links,
|
|
|
63
79
|
links: links,
|
|
64
80
|
readHandlers: readHandlers,
|
|
65
81
|
editHandlers: editHandlers,
|
|
82
|
+
viewQueriesHandler: viewQueriesHandler,
|
|
66
83
|
extra: extra,
|
|
67
84
|
queryResults: queryResults,
|
|
68
|
-
pluginActions: pluginActions
|
|
85
|
+
pluginActions: pluginActions,
|
|
86
|
+
showIcons: showIcons
|
|
69
87
|
})
|
|
70
88
|
]
|
|
71
89
|
}),
|
|
@@ -23,6 +23,7 @@ Object.defineProperty(exports, "PanelDrawer", {
|
|
|
23
23
|
const _jsxruntime = require("react/jsx-runtime");
|
|
24
24
|
const _react = require("react");
|
|
25
25
|
const _components = require("@perses-dev/components");
|
|
26
|
+
const _pluginsystem = require("@perses-dev/plugin-system");
|
|
26
27
|
const _context = require("../../context");
|
|
27
28
|
const _PanelEditorForm = require("./PanelEditorForm");
|
|
28
29
|
const PanelDrawer = ()=>{
|
|
@@ -30,42 +31,78 @@ const PanelDrawer = ()=>{
|
|
|
30
31
|
// When the user clicks close, start closing but don't call the store yet to keep values stable during animtation
|
|
31
32
|
const [isClosing, setIsClosing] = (0, _react.useState)(false);
|
|
32
33
|
// Drawer is open if we have a model and we're not transitioning out
|
|
33
|
-
const isOpen = panelEditor !== undefined && isClosing
|
|
34
|
-
|
|
34
|
+
const isOpen = panelEditor !== undefined && !isClosing;
|
|
35
|
+
const handleSave = (0, _react.useCallback)((values)=>{
|
|
35
36
|
// This shouldn't happen since we don't render the submit button until we have a model, but check to make TS happy
|
|
36
37
|
if (panelEditor === undefined || values === undefined) {
|
|
37
38
|
throw new Error('Cannot apply changes');
|
|
38
39
|
}
|
|
39
40
|
panelEditor.applyChanges(values);
|
|
40
41
|
setIsClosing(true);
|
|
41
|
-
}
|
|
42
|
+
}, [
|
|
43
|
+
panelEditor
|
|
44
|
+
]);
|
|
42
45
|
const handleClose = ()=>{
|
|
43
46
|
setIsClosing(true);
|
|
44
47
|
};
|
|
45
48
|
// Don't call closeDrawer on the store until the Drawer has completely transitioned out and reset close state
|
|
46
|
-
const handleExited = ()=>{
|
|
49
|
+
const handleExited = (0, _react.useCallback)(()=>{
|
|
47
50
|
panelEditor?.close();
|
|
48
51
|
setIsClosing(false);
|
|
49
|
-
}
|
|
52
|
+
}, [
|
|
53
|
+
panelEditor
|
|
54
|
+
]);
|
|
50
55
|
// Disables closing on click out. This is a quick-win solution to avoid losing draft changes.
|
|
51
56
|
// -> TODO find a way to enable closing by clicking-out in edit view, with a discard confirmation modal popping up
|
|
52
57
|
const handleClickOut = ()=>{
|
|
53
58
|
/* do nothing */ };
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
59
|
+
const drawer = (0, _react.useMemo)(()=>{
|
|
60
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.Drawer, {
|
|
61
|
+
isOpen: isOpen,
|
|
62
|
+
onClose: handleClickOut,
|
|
63
|
+
SlideProps: {
|
|
64
|
+
onExited: handleExited
|
|
65
|
+
},
|
|
66
|
+
"data-testid": "panel-editor",
|
|
67
|
+
children: panelEditor && /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.ErrorBoundary, {
|
|
68
|
+
FallbackComponent: _components.ErrorAlert,
|
|
69
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_PanelEditorForm.PanelEditorForm, {
|
|
70
|
+
initialAction: panelEditor.mode,
|
|
71
|
+
initialValues: panelEditor.initialValues,
|
|
72
|
+
onSave: handleSave,
|
|
73
|
+
onClose: handleClose
|
|
74
|
+
})
|
|
68
75
|
})
|
|
69
|
-
})
|
|
70
|
-
}
|
|
76
|
+
});
|
|
77
|
+
}, [
|
|
78
|
+
handleExited,
|
|
79
|
+
handleSave,
|
|
80
|
+
isOpen,
|
|
81
|
+
panelEditor
|
|
82
|
+
]);
|
|
83
|
+
// If the panel editor is using a repeat variable, we need to wrap the drawer in a VariableContext.Provider
|
|
84
|
+
if (panelEditor?.panelGroupItemId?.repeatVariable) {
|
|
85
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsx)(RepeatVariableWrapper, {
|
|
86
|
+
repeatVariable: panelEditor.panelGroupItemId.repeatVariable,
|
|
87
|
+
children: drawer
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return drawer;
|
|
71
91
|
};
|
|
92
|
+
// Wraps the drawer in a VariableContext.Provider to provide the repeat variable value
|
|
93
|
+
// This is necessary for previewing panels that use repeat variables and query editor
|
|
94
|
+
function RepeatVariableWrapper({ repeatVariable, children }) {
|
|
95
|
+
const variables = (0, _pluginsystem.useVariableValues)();
|
|
96
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.VariableContext.Provider, {
|
|
97
|
+
value: {
|
|
98
|
+
state: {
|
|
99
|
+
...variables,
|
|
100
|
+
[repeatVariable[0]]: {
|
|
101
|
+
value: repeatVariable[1],
|
|
102
|
+
loading: false
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
children: children
|
|
107
|
+
});
|
|
108
|
+
}
|
|
@@ -24,6 +24,7 @@ const _jsxruntime = require("react/jsx-runtime");
|
|
|
24
24
|
const _material = require("@mui/material");
|
|
25
25
|
const _Close = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/Close"));
|
|
26
26
|
const _react = require("react");
|
|
27
|
+
const _pluginsystem = require("@perses-dev/plugin-system");
|
|
27
28
|
const _context = require("../../context");
|
|
28
29
|
const _PanelGroupEditorForm = require("./PanelGroupEditorForm");
|
|
29
30
|
function _interop_require_default(obj) {
|
|
@@ -33,6 +34,7 @@ function _interop_require_default(obj) {
|
|
|
33
34
|
}
|
|
34
35
|
function PanelGroupDialog() {
|
|
35
36
|
const panelGroupEditor = (0, _context.usePanelGroupEditor)();
|
|
37
|
+
const variables = (0, _pluginsystem.useVariableValues)();
|
|
36
38
|
// When the user clicks close, start closing but don't call the store yet to keep values stable during animtation
|
|
37
39
|
const [isClosing, setIsClosing] = (0, _react.useState)(false);
|
|
38
40
|
const handleClose = ()=>setIsClosing(true);
|
|
@@ -81,6 +83,7 @@ function PanelGroupDialog() {
|
|
|
81
83
|
},
|
|
82
84
|
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_PanelGroupEditorForm.PanelGroupEditorForm, {
|
|
83
85
|
initialValues: panelGroupEditor.initialValues,
|
|
86
|
+
variables: Object.keys(variables),
|
|
84
87
|
onSubmit: handleSubmit
|
|
85
88
|
})
|
|
86
89
|
}),
|
|
@@ -32,18 +32,16 @@ const _jsxruntime = require("react/jsx-runtime");
|
|
|
32
32
|
const _react = require("react");
|
|
33
33
|
const _material = require("@mui/material");
|
|
34
34
|
function PanelGroupEditorForm(props) {
|
|
35
|
-
const { initialValues, onSubmit } = props;
|
|
35
|
+
const { initialValues, variables, onSubmit } = props;
|
|
36
36
|
const [title, setTitle] = (0, _react.useState)(initialValues.title);
|
|
37
37
|
const [isCollapsed, setIsCollapsed] = (0, _react.useState)(initialValues.isCollapsed);
|
|
38
|
-
const
|
|
39
|
-
const next = e.target.value;
|
|
40
|
-
setIsCollapsed(next === 'Closed');
|
|
41
|
-
};
|
|
38
|
+
const [repeatVariable, setRepeatVariable] = (0, _react.useState)(initialValues.repeatVariable);
|
|
42
39
|
const handleSubmit = (e)=>{
|
|
43
40
|
e.preventDefault();
|
|
44
41
|
onSubmit({
|
|
45
42
|
title,
|
|
46
|
-
isCollapsed
|
|
43
|
+
isCollapsed,
|
|
44
|
+
repeatVariable
|
|
47
45
|
});
|
|
48
46
|
};
|
|
49
47
|
return /*#__PURE__*/ (0, _jsxruntime.jsxs)("form", {
|
|
@@ -58,25 +56,21 @@ function PanelGroupEditorForm(props) {
|
|
|
58
56
|
label: "Name",
|
|
59
57
|
variant: "outlined",
|
|
60
58
|
value: title,
|
|
61
|
-
onChange: (e)=>setTitle(e.target.value)
|
|
59
|
+
onChange: (e)=>setTitle(e.target.value),
|
|
60
|
+
"data-testid": "panel-group-editor-name"
|
|
62
61
|
})
|
|
63
62
|
}),
|
|
64
63
|
/*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.FormControl, {
|
|
65
64
|
fullWidth: true,
|
|
66
65
|
margin: "normal",
|
|
67
66
|
children: [
|
|
68
|
-
/*#__PURE__*/ (0, _jsxruntime.
|
|
69
|
-
|
|
70
|
-
children: "Collapse State"
|
|
71
|
-
}),
|
|
72
|
-
/*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Select, {
|
|
67
|
+
/*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.TextField, {
|
|
68
|
+
select: true,
|
|
73
69
|
required: true,
|
|
74
|
-
displayEmpty: true,
|
|
75
|
-
labelId: "select-collapse-state",
|
|
76
70
|
label: "Collapse State",
|
|
77
71
|
size: "small",
|
|
78
72
|
value: isCollapsed ? 'Closed' : 'Open',
|
|
79
|
-
onChange:
|
|
73
|
+
onChange: (e)=>setIsCollapsed(e.target.value === 'Closed'),
|
|
80
74
|
children: [
|
|
81
75
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.MenuItem, {
|
|
82
76
|
value: "Open",
|
|
@@ -87,6 +81,32 @@ function PanelGroupEditorForm(props) {
|
|
|
87
81
|
children: "Closed"
|
|
88
82
|
})
|
|
89
83
|
]
|
|
84
|
+
}),
|
|
85
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.FormControl, {
|
|
86
|
+
fullWidth: true,
|
|
87
|
+
margin: "normal",
|
|
88
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.TextField, {
|
|
89
|
+
select: true,
|
|
90
|
+
label: "Repeat Variable",
|
|
91
|
+
variant: "outlined",
|
|
92
|
+
value: repeatVariable ?? '',
|
|
93
|
+
onChange: (e)=>setRepeatVariable(e.target.value === '' ? undefined : e.target.value),
|
|
94
|
+
children: [
|
|
95
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.MenuItem, {
|
|
96
|
+
value: "",
|
|
97
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Typography, {
|
|
98
|
+
sx: {
|
|
99
|
+
fontStyle: 'italic'
|
|
100
|
+
},
|
|
101
|
+
children: "None"
|
|
102
|
+
})
|
|
103
|
+
}),
|
|
104
|
+
variables?.sort((a, b)=>a.localeCompare(b)).map((variable)=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.MenuItem, {
|
|
105
|
+
value: variable,
|
|
106
|
+
children: variable
|
|
107
|
+
}, variable))
|
|
108
|
+
]
|
|
109
|
+
})
|
|
90
110
|
})
|
|
91
111
|
]
|
|
92
112
|
})
|
|
@@ -28,6 +28,7 @@ _export_star(require("./EditJsonButton"), exports);
|
|
|
28
28
|
_export_star(require("./EditJsonDialog"), exports);
|
|
29
29
|
_export_star(require("./EmptyDashboard"), exports);
|
|
30
30
|
_export_star(require("./GridLayout"), exports);
|
|
31
|
+
_export_star(require("./LeaveDialog"), exports);
|
|
31
32
|
_export_star(require("./Panel"), exports);
|
|
32
33
|
_export_star(require("./PanelDrawer"), exports);
|
|
33
34
|
_export_star(require("./PanelGroupDialog"), exports);
|
|
@@ -50,7 +50,8 @@ const TOOLTIP_TEXT = {
|
|
|
50
50
|
movePanel: 'Move',
|
|
51
51
|
// Variable editor buttons
|
|
52
52
|
refreshVariableValues: 'Refresh values',
|
|
53
|
-
copyVariableValues: 'Copy values to clipboard'
|
|
53
|
+
copyVariableValues: 'Copy values to clipboard',
|
|
54
|
+
queryView: 'Open query view'
|
|
54
55
|
};
|
|
55
56
|
const ARIA_LABEL_TEXT = {
|
|
56
57
|
// Group buttons
|
|
@@ -65,5 +66,6 @@ const ARIA_LABEL_TEXT = {
|
|
|
65
66
|
duplicatePanel: (panelName)=>`duplicate panel ${panelName}`,
|
|
66
67
|
deletePanel: (panelName)=>`delete panel ${panelName}`,
|
|
67
68
|
showPanelActions: (panelName)=>`show panel actions for ${panelName}`,
|
|
68
|
-
movePanel: (panelName)=>`move panel ${panelName}
|
|
69
|
+
movePanel: (panelName)=>`move panel ${panelName}`,
|
|
70
|
+
openQueryView: (panelName)=>`open query view for panel ${panelName}`
|
|
69
71
|
};
|
|
@@ -61,14 +61,15 @@ function useDashboardStore(selector) {
|
|
|
61
61
|
return (0, _traditional.useStoreWithEqualityFn)(store, selector, _shallow.shallow);
|
|
62
62
|
}
|
|
63
63
|
function DashboardProvider(props) {
|
|
64
|
+
// Prevent calling createDashboardStore every time it rerenders
|
|
64
65
|
const createDashboardStore = (0, _react.useCallback)(initStore, [
|
|
65
66
|
props
|
|
66
67
|
]);
|
|
68
|
+
const [store] = (0, _react.useState)(createDashboardStore(props));
|
|
67
69
|
// load plugin to retrieve initial spec if default panel kind is defined
|
|
68
70
|
const { defaultPluginKinds } = (0, _pluginsystem.usePluginRegistry)();
|
|
69
71
|
const defaultPanelKind = defaultPluginKinds?.['Panel'] ?? '';
|
|
70
72
|
const { data: plugin } = (0, _pluginsystem.usePlugin)('Panel', defaultPanelKind);
|
|
71
|
-
const [store] = (0, _react.useState)(createDashboardStore(props)); // prevent calling createDashboardStore every time it rerenders
|
|
72
73
|
(0, _react.useEffect)(()=>{
|
|
73
74
|
if (plugin === undefined) return;
|
|
74
75
|
const defaultPanelSpec = plugin.createInitialOptions ? plugin.createInitialOptions() : {};
|
|
@@ -90,12 +91,8 @@ function DashboardProvider(props) {
|
|
|
90
91
|
}
|
|
91
92
|
function initStore(props) {
|
|
92
93
|
const { initialState: { dashboardResource, isEditMode, viewPanelRef, setViewPanelRef } } = props;
|
|
93
|
-
const { kind, metadata, spec: { display, duration, refreshInterval = _core.DEFAULT_REFRESH_INTERVAL, datasources } } = dashboardResource;
|
|
94
|
+
const { kind, metadata, spec: { display, duration, refreshInterval = _core.DEFAULT_REFRESH_INTERVAL, datasources, layouts = [], panels = {} } } = dashboardResource;
|
|
94
95
|
const ttl = 'ttl' in dashboardResource.spec ? dashboardResource.spec.ttl : undefined;
|
|
95
|
-
let { spec: { layouts, panels } } = dashboardResource;
|
|
96
|
-
// Set fallbacks in case the frontend is used with a non-Perses backend
|
|
97
|
-
layouts = layouts ?? [];
|
|
98
|
-
panels = panels ?? {};
|
|
99
96
|
const store = (0, _zustand.createStore)()((0, _immer.immer)((0, _middleware.devtools)((...args)=>{
|
|
100
97
|
const [set] = args;
|
|
101
98
|
return {
|
|
@@ -118,9 +115,11 @@ function initStore(props) {
|
|
|
118
115
|
datasources,
|
|
119
116
|
ttl,
|
|
120
117
|
isEditMode: !!isEditMode,
|
|
121
|
-
setEditMode: (isEditMode)=>
|
|
118
|
+
setEditMode: (isEditMode)=>{
|
|
119
|
+
set({
|
|
122
120
|
isEditMode
|
|
123
|
-
})
|
|
121
|
+
});
|
|
122
|
+
},
|
|
124
123
|
setDashboard: ({ kind, metadata, spec: { display, panels = {}, layouts = [], duration, refreshInterval, datasources = {} } })=>{
|
|
125
124
|
set((state)=>{
|
|
126
125
|
state.kind = kind;
|
|
@@ -24,12 +24,12 @@ const _jsxruntime = require("react/jsx-runtime");
|
|
|
24
24
|
const _usequeryparams = require("use-query-params");
|
|
25
25
|
const _DashboardProvider = require("./DashboardProvider");
|
|
26
26
|
function DashboardProviderWithQueryParams({ children, initialState }) {
|
|
27
|
-
const [viewPanelRef, setViewPanelRef] = (0, _usequeryparams.useQueryParam)('viewPanelRef', _usequeryparams.
|
|
27
|
+
const [viewPanelRef, setViewPanelRef] = (0, _usequeryparams.useQueryParam)('viewPanelRef', _usequeryparams.JsonParam);
|
|
28
28
|
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_DashboardProvider.DashboardProvider, {
|
|
29
29
|
initialState: {
|
|
30
|
+
...initialState,
|
|
30
31
|
viewPanelRef: viewPanelRef ?? undefined,
|
|
31
|
-
setViewPanelRef: setViewPanelRef
|
|
32
|
-
...initialState
|
|
32
|
+
setViewPanelRef: setViewPanelRef
|
|
33
33
|
},
|
|
34
34
|
children: children
|
|
35
35
|
});
|
|
@@ -29,12 +29,14 @@ const createPanelGroupEditorSlice = (set, get)=>({
|
|
|
29
29
|
mode: 'Add',
|
|
30
30
|
initialValues: {
|
|
31
31
|
title: '',
|
|
32
|
-
isCollapsed: false
|
|
32
|
+
isCollapsed: false,
|
|
33
|
+
repeatVariable: ''
|
|
33
34
|
},
|
|
34
35
|
applyChanges (next) {
|
|
35
36
|
const newGroup = (0, _panelgroupslice.createEmptyPanelGroup)();
|
|
36
37
|
newGroup.title = next.title;
|
|
37
38
|
newGroup.isCollapsed = next.isCollapsed;
|
|
39
|
+
newGroup.repeatVariable = next.repeatVariable;
|
|
38
40
|
set((draft)=>{
|
|
39
41
|
(0, _panelgroupslice.addPanelGroup)(draft, newGroup);
|
|
40
42
|
});
|
|
@@ -60,7 +62,8 @@ const createPanelGroupEditorSlice = (set, get)=>({
|
|
|
60
62
|
mode: 'Edit',
|
|
61
63
|
initialValues: {
|
|
62
64
|
title: existingGroup.title ?? '',
|
|
63
|
-
isCollapsed: existingGroup.isCollapsed
|
|
65
|
+
isCollapsed: existingGroup.isCollapsed,
|
|
66
|
+
repeatVariable: existingGroup.repeatVariable ?? ''
|
|
64
67
|
},
|
|
65
68
|
applyChanges (next) {
|
|
66
69
|
set((draft)=>{
|
|
@@ -70,6 +73,7 @@ const createPanelGroupEditorSlice = (set, get)=>({
|
|
|
70
73
|
}
|
|
71
74
|
group.title = next.title;
|
|
72
75
|
group.isCollapsed = next.isCollapsed;
|
|
76
|
+
group.repeatVariable = next.repeatVariable;
|
|
73
77
|
});
|
|
74
78
|
},
|
|
75
79
|
close () {
|
|
@@ -100,6 +100,7 @@ function convertLayoutsToPanelGroups(layouts) {
|
|
|
100
100
|
panelGroups[panelGroupId] = {
|
|
101
101
|
id: panelGroupId,
|
|
102
102
|
isCollapsed: layout.spec.display?.collapse?.open === false,
|
|
103
|
+
repeatVariable: layout.spec.repeatVariable,
|
|
103
104
|
title: layout.spec.display?.title,
|
|
104
105
|
itemLayouts,
|
|
105
106
|
itemPanelKeys
|
|
@@ -55,12 +55,13 @@ function getViewPanelGroupId(panelGroups, panelGroupItemId, panelRef) {
|
|
|
55
55
|
// Find the PanelGroupItemId of a Panel from a PanelRef
|
|
56
56
|
function findPanelGroupItemIdOfPanelRef(panelGroups, panelRef) {
|
|
57
57
|
for (const panelGroup of Object.values(panelGroups)){
|
|
58
|
-
const itemPanel = Object.entries(panelGroup.itemPanelKeys ?? []).find(([_, value])=>value === panelRef);
|
|
58
|
+
const itemPanel = Object.entries(panelGroup.itemPanelKeys ?? []).find(([_, value])=>value === panelRef.ref);
|
|
59
59
|
if (itemPanel) {
|
|
60
60
|
const [key] = itemPanel;
|
|
61
61
|
return {
|
|
62
62
|
panelGroupId: panelGroup.id,
|
|
63
|
-
panelGroupItemLayoutId: key
|
|
63
|
+
panelGroupItemLayoutId: key,
|
|
64
|
+
repeatVariable: panelRef.repeatVariable
|
|
64
65
|
};
|
|
65
66
|
}
|
|
66
67
|
}
|
|
@@ -73,7 +74,13 @@ function findPanelRefOfPanelGroupItemId(panelGroups, panelGroupItemId) {
|
|
|
73
74
|
}
|
|
74
75
|
const panelGroup = panelGroups[panelGroupItemId.panelGroupId];
|
|
75
76
|
if (panelGroup) {
|
|
76
|
-
|
|
77
|
+
const panelRef = panelGroup.itemPanelKeys[panelGroupItemId.panelGroupItemLayoutId];
|
|
78
|
+
if (panelRef) {
|
|
79
|
+
return {
|
|
80
|
+
ref: panelRef,
|
|
81
|
+
repeatVariable: panelGroupItemId.repeatVariable
|
|
82
|
+
};
|
|
83
|
+
}
|
|
77
84
|
}
|
|
78
85
|
return undefined;
|
|
79
86
|
}
|
|
@@ -362,7 +362,7 @@ function createVariableDefinitionStore({ initialVariableDefinitions = [], extern
|
|
|
362
362
|
return (0, _utils.checkSavedDefaultVariableStatus)(get().variableDefinitions, get().variableState);
|
|
363
363
|
}
|
|
364
364
|
}))));
|
|
365
|
-
return store;
|
|
365
|
+
return store;
|
|
366
366
|
}
|
|
367
367
|
function VariableProvider({ children, initialVariableDefinitions = [], externalVariableDefinitions = [], builtinVariableDefinitions = [] }) {
|
|
368
368
|
const [store] = (0, _react.useState)(()=>createVariableDefinitionStore({
|
|
@@ -82,11 +82,11 @@ function convertPanelGroupsToLayouts(panelGroups, panelGroupOrder) {
|
|
|
82
82
|
if (group === undefined) {
|
|
83
83
|
throw new Error('panel group not found');
|
|
84
84
|
}
|
|
85
|
-
const { title, isCollapsed, itemLayouts, itemPanelKeys } = group;
|
|
85
|
+
const { title, isCollapsed, repeatVariable, itemLayouts, itemPanelKeys } = group;
|
|
86
86
|
let display = undefined;
|
|
87
|
-
if (title) {
|
|
87
|
+
if (title || isCollapsed !== undefined) {
|
|
88
88
|
display = {
|
|
89
|
-
title,
|
|
89
|
+
title: title ?? '',
|
|
90
90
|
collapse: {
|
|
91
91
|
open: !isCollapsed
|
|
92
92
|
}
|
|
@@ -108,7 +108,8 @@ function convertPanelGroupsToLayouts(panelGroups, panelGroupOrder) {
|
|
|
108
108
|
height: layout.h,
|
|
109
109
|
content: (0, _core.createPanelRef)(panelKey)
|
|
110
110
|
};
|
|
111
|
-
})
|
|
111
|
+
}),
|
|
112
|
+
repeatVariable: repeatVariable
|
|
112
113
|
}
|
|
113
114
|
};
|
|
114
115
|
layouts.push(layout);
|