@perses-dev/dashboards 0.27.0 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/cjs/components/GridLayout/GridItemContent.js +22 -4
  2. package/dist/cjs/components/GridLayout/GridLayout.js +31 -2
  3. package/dist/cjs/components/Panel/Panel.js +2 -2
  4. package/dist/cjs/components/PanelDrawer/PanelEditorForm.js +41 -34
  5. package/dist/cjs/components/PanelDrawer/PanelPreview.js +32 -18
  6. package/dist/cjs/components/PanelDrawer/usePanelEditor.js +87 -0
  7. package/dist/cjs/context/DashboardProvider/DashboardProvider.js +4 -4
  8. package/dist/cjs/context/DashboardProvider/common.js +26 -6
  9. package/dist/cjs/context/DashboardProvider/panel-editor-slice.js +8 -32
  10. package/dist/cjs/stories/decorators/WithDataQueriesProvider.js +39 -0
  11. package/dist/cjs/stories/decorators/WithDatasourceStore.js +2 -47
  12. package/dist/cjs/stories/decorators/index.js +1 -0
  13. package/dist/cjs/test/datasource-provider.js +70 -0
  14. package/dist/cjs/test/index.js +1 -0
  15. package/dist/cjs/test/plugin-registry.js +11 -5
  16. package/dist/cjs/test/testDashboard.js +79 -79
  17. package/dist/cjs/utils/index.js +1 -0
  18. package/dist/cjs/utils/time.js +27 -0
  19. package/dist/components/GridLayout/GridItemContent.d.ts +1 -0
  20. package/dist/components/GridLayout/GridItemContent.d.ts.map +1 -1
  21. package/dist/components/GridLayout/GridItemContent.js +22 -4
  22. package/dist/components/GridLayout/GridItemContent.js.map +1 -1
  23. package/dist/components/GridLayout/GridLayout.d.ts.map +1 -1
  24. package/dist/components/GridLayout/GridLayout.js +31 -2
  25. package/dist/components/GridLayout/GridLayout.js.map +1 -1
  26. package/dist/components/Panel/Panel.d.ts +1 -1
  27. package/dist/components/Panel/Panel.d.ts.map +1 -1
  28. package/dist/components/Panel/Panel.js +3 -3
  29. package/dist/components/Panel/Panel.js.map +1 -1
  30. package/dist/components/PanelDrawer/PanelEditorForm.d.ts.map +1 -1
  31. package/dist/components/PanelDrawer/PanelEditorForm.js +42 -35
  32. package/dist/components/PanelDrawer/PanelEditorForm.js.map +1 -1
  33. package/dist/components/PanelDrawer/PanelPreview.d.ts +1 -1
  34. package/dist/components/PanelDrawer/PanelPreview.d.ts.map +1 -1
  35. package/dist/components/PanelDrawer/PanelPreview.js +32 -18
  36. package/dist/components/PanelDrawer/PanelPreview.js.map +1 -1
  37. package/dist/components/PanelDrawer/usePanelEditor.d.ts +15 -0
  38. package/dist/components/PanelDrawer/usePanelEditor.d.ts.map +1 -0
  39. package/dist/components/PanelDrawer/usePanelEditor.js +84 -0
  40. package/dist/components/PanelDrawer/usePanelEditor.js.map +1 -0
  41. package/dist/context/DashboardProvider/DashboardProvider.d.ts.map +1 -1
  42. package/dist/context/DashboardProvider/DashboardProvider.js +4 -4
  43. package/dist/context/DashboardProvider/DashboardProvider.js.map +1 -1
  44. package/dist/context/DashboardProvider/common.d.ts +2 -0
  45. package/dist/context/DashboardProvider/common.d.ts.map +1 -1
  46. package/dist/context/DashboardProvider/common.js +17 -2
  47. package/dist/context/DashboardProvider/common.js.map +1 -1
  48. package/dist/context/DashboardProvider/panel-editor-slice.d.ts +3 -6
  49. package/dist/context/DashboardProvider/panel-editor-slice.d.ts.map +1 -1
  50. package/dist/context/DashboardProvider/panel-editor-slice.js +9 -33
  51. package/dist/context/DashboardProvider/panel-editor-slice.js.map +1 -1
  52. package/dist/stories/decorators/WithDataQueriesProvider.js +33 -0
  53. package/dist/stories/decorators/WithDataQueriesProvider.js.map +1 -0
  54. package/dist/stories/decorators/WithDatasourceStore.js +1 -46
  55. package/dist/stories/decorators/WithDatasourceStore.js.map +1 -1
  56. package/dist/stories/decorators/index.js +1 -0
  57. package/dist/stories/decorators/index.js.map +1 -1
  58. package/dist/test/datasource-provider.d.ts +6 -0
  59. package/dist/test/datasource-provider.d.ts.map +1 -0
  60. package/dist/test/datasource-provider.js +60 -0
  61. package/dist/test/datasource-provider.js.map +1 -0
  62. package/dist/test/index.d.ts +1 -0
  63. package/dist/test/index.d.ts.map +1 -1
  64. package/dist/test/index.js +1 -0
  65. package/dist/test/index.js.map +1 -1
  66. package/dist/test/plugin-registry.d.ts.map +1 -1
  67. package/dist/test/plugin-registry.js +11 -5
  68. package/dist/test/plugin-registry.js.map +1 -1
  69. package/dist/test/testDashboard.js +79 -79
  70. package/dist/test/testDashboard.js.map +1 -1
  71. package/dist/utils/index.d.ts +1 -0
  72. package/dist/utils/index.d.ts.map +1 -1
  73. package/dist/utils/index.js +1 -0
  74. package/dist/utils/index.js.map +1 -1
  75. package/dist/utils/time.d.ts +5 -0
  76. package/dist/utils/time.d.ts.map +1 -0
  77. package/dist/utils/time.js +23 -0
  78. package/dist/utils/time.js.map +1 -0
  79. package/package.json +6 -6
@@ -19,11 +19,14 @@ Object.defineProperty(exports, "GridItemContent", {
19
19
  get: ()=>GridItemContent
20
20
  });
21
21
  const _jsxRuntime = require("react/jsx-runtime");
22
+ const _pluginSystem = require("@perses-dev/plugin-system");
22
23
  const _context = require("../../context");
24
+ const _utils = require("../../utils");
23
25
  const _panel = require("../Panel/Panel");
24
26
  function GridItemContent(props) {
25
- const { panelGroupItemId } = props;
27
+ const { panelGroupItemId , width } = props;
26
28
  const panelDefinition = (0, _context.usePanel)(panelGroupItemId);
29
+ const { spec: { queries } , } = panelDefinition;
27
30
  const { isEditMode } = (0, _context.useEditMode)();
28
31
  const { openEditPanel , openDeletePanelDialog , duplicatePanel } = (0, _context.usePanelActions)(panelGroupItemId);
29
32
  // Provide actions to the panel when in edit mode
@@ -35,8 +38,23 @@ function GridItemContent(props) {
35
38
  onDeletePanelClick: openDeletePanelDialog
36
39
  };
37
40
  }
38
- return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_panel.Panel, {
39
- definition: panelDefinition,
40
- editHandlers: editHandlers
41
+ // map TimeSeriesQueryDefinition to Definition<UnknownSpec>
42
+ const suggestedStepMs = (0, _utils.useSuggestedStepMs)(width);
43
+ const queryDefinitions = queries !== null && queries !== void 0 ? queries : [];
44
+ const definitions = queryDefinitions.map((query)=>{
45
+ return {
46
+ kind: query.spec.plugin.kind,
47
+ spec: query.spec.plugin.spec
48
+ };
49
+ });
50
+ return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_pluginSystem.DataQueriesProvider, {
51
+ definitions: definitions,
52
+ options: {
53
+ suggestedStepMs
54
+ },
55
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_panel.Panel, {
56
+ definition: panelDefinition,
57
+ editHandlers: editHandlers
58
+ })
41
59
  });
42
60
  }
@@ -28,6 +28,7 @@ const _constants = require("../../constants");
28
28
  const _gridTitle = require("./GridTitle");
29
29
  const _gridItemContent = require("./GridItemContent");
30
30
  const _gridContainer = require("./GridContainer");
31
+ const DEFAULT_MARGIN = 10;
31
32
  const ResponsiveGridLayout = (0, _reactGridLayout.WidthProvider)(_reactGridLayout.Responsive);
32
33
  function GridLayout(props) {
33
34
  const { panelGroupId /*...others */ } = props;
@@ -37,6 +38,7 @@ function GridLayout(props) {
37
38
  var ref;
38
39
  const [isOpen, setIsOpen] = (0, _react.useState)((ref = !groupDefinition.isCollapsed) !== null && ref !== void 0 ? ref : true);
39
40
  const { isEditMode } = (0, _context.useEditMode)();
41
+ const [gridColWidth, setGridColWidth] = (0, _react.useState)(0);
40
42
  const handleLayoutChange = (currentLayout, allLayouts)=>{
41
43
  // Using the value from `allLayouts` instead of `currentLayout` because of
42
44
  // a bug in react-layout-grid where `currentLayout` does not adjust properly
@@ -47,6 +49,16 @@ function GridLayout(props) {
47
49
  updatePanelGroupLayouts(smallLayout);
48
50
  }
49
51
  };
52
+ /**
53
+ * Calculate the column width so we can determine the width of each panel for suggested step ms
54
+ * https://github.com/react-grid-layout/react-grid-layout/blob/master/lib/calculateUtils.js#L14-L35
55
+ */ const handleWidthChange = (containerWidth, margin, cols, containerPadding)=>{
56
+ const marginX = margin[0];
57
+ const marginWidth = marginX * (cols - 1);
58
+ const containerPaddingWidth = containerPadding[0] * 2;
59
+ // exclude margin and padding from total width
60
+ setGridColWidth((containerWidth - marginWidth - containerPaddingWidth) / cols);
61
+ };
50
62
  return /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_gridContainer.GridContainer, {
51
63
  children: [
52
64
  groupDefinition.title !== undefined && /*#__PURE__*/ (0, _jsxRuntime.jsx)(_gridTitle.GridTitle, {
@@ -76,6 +88,10 @@ function GridLayout(props) {
76
88
  ],
77
89
  isDraggable: isEditMode,
78
90
  isResizable: isEditMode,
91
+ margin: [
92
+ DEFAULT_MARGIN,
93
+ DEFAULT_MARGIN
94
+ ],
79
95
  containerPadding: [
80
96
  0,
81
97
  10
@@ -84,14 +100,16 @@ function GridLayout(props) {
84
100
  [_constants.GRID_LAYOUT_SMALL_BREAKPOINT]: groupDefinition.itemLayouts
85
101
  },
86
102
  onLayoutChange: handleLayoutChange,
87
- children: groupDefinition.itemLayouts.map(({ i })=>/*#__PURE__*/ (0, _jsxRuntime.jsx)("div", {
103
+ onWidthChange: handleWidthChange,
104
+ children: groupDefinition.itemLayouts.map(({ i , w })=>/*#__PURE__*/ (0, _jsxRuntime.jsx)("div", {
88
105
  children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components.ErrorBoundary, {
89
106
  FallbackComponent: _components.ErrorAlert,
90
107
  children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_gridItemContent.GridItemContent, {
91
108
  panelGroupItemId: {
92
109
  panelGroupId,
93
110
  panelGroupItemLayoutId: i
94
- }
111
+ },
112
+ width: calculateGridItemWidth(w, gridColWidth)
95
113
  })
96
114
  })
97
115
  }, i))
@@ -100,3 +118,14 @@ function GridLayout(props) {
100
118
  ]
101
119
  });
102
120
  }
121
+ /**
122
+ * Calculates grid item width
123
+ * @param w number of columns the grid item spans
124
+ * @param colWidth the width of each column in px
125
+ * @returns grid item's width in px
126
+ * https://github.com/react-grid-layout/react-grid-layout/blob/master/lib/calculateUtils.js#L14-L35
127
+ */ const calculateGridItemWidth = (w, colWidth)=>{
128
+ // 0 * Infinity === NaN, which causes problems with resize contraints
129
+ if (!Number.isFinite(w)) return w;
130
+ return Math.round(colWidth * w + Math.max(0, w - 1) * DEFAULT_MARGIN);
131
+ };
@@ -31,7 +31,7 @@ function _interopRequireDefault(obj) {
31
31
  default: obj
32
32
  };
33
33
  }
34
- function Panel(props) {
34
+ const Panel = /*#__PURE__*/ (0, _react.memo)(function Panel(props) {
35
35
  const { definition , editHandlers , onMouseEnter , onMouseLeave , sx , ...others } = props;
36
36
  // Make sure we have an ID we can use for aria attributes
37
37
  const generatedPanelId = (0, _components.useId)('Panel');
@@ -116,4 +116,4 @@ function Panel(props) {
116
116
  })
117
117
  ]
118
118
  });
119
- }
119
+ });
@@ -31,25 +31,26 @@ const _components = require("@perses-dev/components");
31
31
  const _pluginSystem = require("@perses-dev/plugin-system");
32
32
  const _context = require("../../context");
33
33
  const _panelPreview = require("./PanelPreview");
34
+ const _usePanelEditor = require("./usePanelEditor");
34
35
  function PanelEditorForm(props) {
35
36
  var ref;
36
- const { initialValues , onChange } = props;
37
+ const { initialValues: { panelDefinition: initialPanelDef , groupId: initialGroupId } , onChange , } = props;
37
38
  const panelGroups = (0, _context.useListPanelGroups)();
38
- const [name, setName] = (0, _react.useState)(initialValues.name);
39
- const [description, setDescription] = (0, _react.useState)(initialValues.description);
40
- const [groupId, setGroupId] = (0, _react.useState)(initialValues.groupId);
41
- const [kind, setKind] = (0, _react.useState)(initialValues.kind);
42
- const [spec, setSpec] = (0, _react.useState)(initialValues.spec);
39
+ const [groupId, setGroupId] = (0, _react.useState)(initialGroupId);
40
+ const { panelDefinition , setName , setDescription , setQueries , setPlugin , setPanelDefinition } = (0, _usePanelEditor.usePanelEditor)(initialPanelDef);
41
+ const { plugin } = panelDefinition.spec;
43
42
  // Use common plugin editor logic even though we've split the inputs up in this form
44
43
  const pluginEditor = (0, _pluginSystem.usePluginEditor)({
45
44
  pluginType: 'Panel',
46
45
  value: {
47
- kind,
48
- spec
46
+ kind: plugin.kind,
47
+ spec: plugin.spec
49
48
  },
50
49
  onChange: (plugin)=>{
51
- setKind(plugin.kind);
52
- setSpec(plugin.spec);
50
+ setPlugin(plugin);
51
+ },
52
+ onHideQueryEditorChange: (isHidden)=>{
53
+ setQueries(undefined, isHidden);
53
54
  }
54
55
  });
55
56
  // Ignore string values (which would be an "empty" value from the Select) since we don't allow them to unset it
@@ -60,24 +61,26 @@ function PanelEditorForm(props) {
60
61
  }
61
62
  setGroupId(value);
62
63
  };
64
+ const handlePanelDefinitionChange = (nextPanelDef)=>{
65
+ const { kind: pluginKind , spec: pluginSpec } = nextPanelDef.spec.plugin;
66
+ // if panel plugin kind and spec are modified, then need to save current spec
67
+ if (panelDefinition.spec.plugin.kind !== pluginKind && JSON.stringify(panelDefinition.spec.plugin.spec) !== JSON.stringify(pluginSpec)) {
68
+ pluginEditor.rememberCurrentSpecState();
69
+ }
70
+ setPanelDefinition(nextPanelDef);
71
+ };
63
72
  (0, _react.useEffect)(()=>{
64
73
  const values = {
65
- name,
66
- description,
67
74
  groupId,
68
- kind,
69
- spec
75
+ panelDefinition
70
76
  };
71
77
  onChange(values);
72
78
  }, [
73
- name,
74
- description,
75
79
  groupId,
76
- kind,
77
- spec,
80
+ panelDefinition,
78
81
  onChange
79
82
  ]);
80
- var _title, ref1;
83
+ var _name, _title, _description, ref1;
81
84
  return(// Grid maxHeight allows user to scroll inside Drawer to see all content
82
85
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Box, {
83
86
  component: "form",
@@ -98,9 +101,11 @@ function PanelEditorForm(props) {
98
101
  required: true,
99
102
  fullWidth: true,
100
103
  label: "Name",
101
- value: name,
104
+ value: (_name = panelDefinition.spec.display.name) !== null && _name !== void 0 ? _name : '',
102
105
  variant: "outlined",
103
- onChange: (e)=>setName(e.target.value)
106
+ onChange: (e)=>{
107
+ setName(e.target.value);
108
+ }
104
109
  })
105
110
  }),
106
111
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Grid, {
@@ -133,9 +138,11 @@ function PanelEditorForm(props) {
133
138
  children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.TextField, {
134
139
  fullWidth: true,
135
140
  label: "Description",
136
- value: description,
141
+ value: (_description = panelDefinition.spec.display.description) !== null && _description !== void 0 ? _description : '',
137
142
  variant: "outlined",
138
- onChange: (e)=>setDescription(e.target.value)
143
+ onChange: (e)=>{
144
+ setDescription(e.target.value);
145
+ }
139
146
  })
140
147
  }),
141
148
  /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Grid, {
@@ -156,7 +163,7 @@ function PanelEditorForm(props) {
156
163
  required: true,
157
164
  labelId: "panel-type-label",
158
165
  label: "Type",
159
- value: pluginEditor.pendingKind ? pluginEditor.pendingKind : kind,
166
+ value: pluginEditor.pendingKind ? pluginEditor.pendingKind : plugin.kind,
160
167
  onChange: pluginEditor.onKindChange
161
168
  })
162
169
  ]
@@ -178,11 +185,7 @@ function PanelEditorForm(props) {
178
185
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components.ErrorBoundary, {
179
186
  FallbackComponent: _components.ErrorAlert,
180
187
  children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_panelPreview.PanelPreview, {
181
- kind: kind,
182
- name: name,
183
- description: description,
184
- spec: spec,
185
- groupId: groupId
188
+ panelDefinition: panelDefinition
186
189
  })
187
190
  })
188
191
  ]
@@ -192,11 +195,15 @@ function PanelEditorForm(props) {
192
195
  xs: 12,
193
196
  children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components.ErrorBoundary, {
194
197
  FallbackComponent: _components.ErrorAlert,
195
- children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_pluginSystem.PluginSpecEditor, {
196
- pluginType: "Panel",
197
- pluginKind: kind,
198
- value: spec,
199
- onChange: pluginEditor.onSpecChange
198
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_pluginSystem.PanelSpecEditor, {
199
+ panelDefinition: panelDefinition,
200
+ onJSONChange: handlePanelDefinitionChange,
201
+ onQueriesChange: (queries)=>{
202
+ setQueries(queries);
203
+ },
204
+ onPluginSpecChange: (spec)=>{
205
+ pluginEditor.onSpecChange(spec);
206
+ }
200
207
  })
201
208
  })
202
209
  })
@@ -19,29 +19,43 @@ Object.defineProperty(exports, "PanelPreview", {
19
19
  get: ()=>PanelPreview
20
20
  });
21
21
  const _jsxRuntime = require("react/jsx-runtime");
22
+ const _react = require("react");
22
23
  const _material = require("@mui/material");
24
+ const _pluginSystem = require("@perses-dev/plugin-system");
23
25
  const _panel = require("../Panel");
24
- function PanelPreview({ name , description , kind , spec }) {
25
- const definition = {
26
- kind: 'Panel',
27
- spec: {
28
- display: {
29
- name,
30
- description: description === '' ? undefined : description
31
- },
32
- plugin: {
33
- kind,
34
- spec
35
- }
36
- }
37
- };
38
- if (kind === '') {
26
+ const _utils = require("../../utils");
27
+ const PANEL_PREVIEW_HEIGHT = 300;
28
+ const PANEL_PREVIEW_DEFAULT_WIDTH = 840;
29
+ function PanelPreview({ panelDefinition }) {
30
+ const boxRef = (0, _react.useRef)(null);
31
+ let width = PANEL_PREVIEW_DEFAULT_WIDTH;
32
+ if (boxRef.current !== null) {
33
+ width = boxRef.current.getBoundingClientRect().width;
34
+ }
35
+ const suggestedStepMs = (0, _utils.useSuggestedStepMs)(width);
36
+ if (panelDefinition.spec.plugin.kind === '') {
39
37
  return null;
40
38
  }
39
+ var _queries;
40
+ const queries = (_queries = panelDefinition.spec.queries) !== null && _queries !== void 0 ? _queries : [];
41
+ // map TimeSeriesQueryDefinition to Definition<UnknownSpec>
42
+ const definitions = queries.length ? queries.map((query)=>{
43
+ return {
44
+ kind: query.spec.plugin.kind,
45
+ spec: query.spec.plugin.spec
46
+ };
47
+ }) : [];
41
48
  return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Box, {
42
- height: 300,
43
- children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_panel.Panel, {
44
- definition: definition
49
+ ref: boxRef,
50
+ height: PANEL_PREVIEW_HEIGHT,
51
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_pluginSystem.DataQueriesProvider, {
52
+ definitions: definitions,
53
+ options: {
54
+ suggestedStepMs
55
+ },
56
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_panel.Panel, {
57
+ definition: panelDefinition
58
+ })
45
59
  })
46
60
  });
47
61
  }
@@ -0,0 +1,87 @@
1
+ // Copyright 2023 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, "usePanelEditor", {
18
+ enumerable: true,
19
+ get: ()=>usePanelEditor
20
+ });
21
+ const _react = require("react");
22
+ const usePanelEditor = (panelDefinition)=>{
23
+ const { display , plugin: pluginDefinition , queries: initialQueries } = panelDefinition.spec;
24
+ const [name, setName] = (0, _react.useState)(display.name);
25
+ const [description, setDescription] = (0, _react.useState)(display.description);
26
+ const [plugin, setPlugin] = (0, _react.useState)(pluginDefinition);
27
+ // need to keep track of prevQueries if switching from a panel with no queries (ex: markdown) to one with queries
28
+ const [prevQueries, setPrevQueries] = (0, _react.useState)(initialQueries);
29
+ const [currentQueries, setCurrentQueries] = (0, _react.useState)(initialQueries);
30
+ /**
31
+ * If hideQueryEditor is true, set panelDefinition.spec.queries to undefined.
32
+ * If hideQueryEditor is false and query is undefined, set panelDefinition.spec.queries to previous queries.
33
+ */ const setQueries = (0, _react.useCallback)((queries, hideQueryEditor)=>{
34
+ if (hideQueryEditor) {
35
+ setPrevQueries(currentQueries);
36
+ setCurrentQueries(undefined);
37
+ } else {
38
+ setCurrentQueries(queries === undefined ? prevQueries : queries);
39
+ }
40
+ }, [
41
+ setCurrentQueries,
42
+ currentQueries,
43
+ setPrevQueries,
44
+ prevQueries
45
+ ]);
46
+ // reset panel definition
47
+ const setPanelDefinition = (0, _react.useCallback)((panelDefinition)=>{
48
+ const { display , plugin , queries } = panelDefinition.spec;
49
+ setName(display.name);
50
+ setDescription(display.description);
51
+ setPlugin(plugin);
52
+ setQueries(queries);
53
+ }, [
54
+ setName,
55
+ setDescription,
56
+ setPlugin,
57
+ setQueries
58
+ ]);
59
+ return (0, _react.useMemo)(()=>({
60
+ panelDefinition: {
61
+ kind: 'Panel',
62
+ spec: {
63
+ display: {
64
+ name,
65
+ description
66
+ },
67
+ plugin,
68
+ queries: currentQueries
69
+ }
70
+ },
71
+ setName,
72
+ setDescription,
73
+ setQueries,
74
+ setPlugin,
75
+ setPanelDefinition
76
+ }), [
77
+ name,
78
+ description,
79
+ plugin,
80
+ currentQueries,
81
+ setName,
82
+ setDescription,
83
+ setQueries,
84
+ setPlugin,
85
+ setPanelDefinition
86
+ ]);
87
+ };
@@ -41,6 +41,7 @@ const _deletePanelSlice = require("./delete-panel-slice");
41
41
  const _discardChangesDialogSlice = require("./discard-changes-dialog-slice");
42
42
  const _duplicatePanelSlice = require("./duplicate-panel-slice");
43
43
  const _editJsonDialogSlice = require("./edit-json-dialog-slice");
44
+ const _common = require("./common");
44
45
  const DashboardContext = /*#__PURE__*/ (0, _react.createContext)(undefined);
45
46
  function useDashboardStore(selector) {
46
47
  const store = (0, _react.useContext)(DashboardContext);
@@ -61,12 +62,11 @@ function DashboardProvider(props) {
61
62
  const [store] = (0, _react.useState)(createDashboardStore(props)); // prevent calling createDashboardStore every time it rerenders
62
63
  (0, _react.useEffect)(()=>{
63
64
  if (plugin === undefined) return;
64
- const spec = plugin.createInitialOptions();
65
- // set default panel kind and spec for add panel editor
65
+ const defaultPanelSpec = plugin.createInitialOptions();
66
+ // set default panel kind, spec, and queries for add panel editor
66
67
  store.setState({
67
68
  initialValues: {
68
- kind: defaultPanelKind,
69
- spec
69
+ panelDefinition: (0, _common.createPanelDefinition)(defaultPanelKind, defaultPanelSpec)
70
70
  }
71
71
  });
72
72
  }, [
@@ -10,15 +10,19 @@
10
10
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
- /**
14
- * The middleware applied to the DashboardStore (can be used as generic argument in StateCreator).
15
- */ "use strict";
13
+ "use strict";
16
14
  Object.defineProperty(exports, "__esModule", {
17
15
  value: true
18
16
  });
19
- Object.defineProperty(exports, "generateId", {
20
- enumerable: true,
21
- get: ()=>generateId
17
+ function _export(target, all) {
18
+ for(var name in all)Object.defineProperty(target, name, {
19
+ enumerable: true,
20
+ get: all[name]
21
+ });
22
+ }
23
+ _export(exports, {
24
+ generateId: ()=>generateId,
25
+ createPanelDefinition: ()=>createPanelDefinition
22
26
  });
23
27
  function generateId() {
24
28
  if (globalThis.dashboardStoreId === undefined) {
@@ -26,3 +30,19 @@ function generateId() {
26
30
  }
27
31
  return globalThis.dashboardStoreId++;
28
32
  }
33
+ function createPanelDefinition(defaultPanelKind, defaultPanelSpec) {
34
+ return {
35
+ kind: 'Panel',
36
+ spec: {
37
+ display: {
38
+ name: '',
39
+ description: undefined
40
+ },
41
+ plugin: {
42
+ kind: defaultPanelKind !== null && defaultPanelKind !== void 0 ? defaultPanelKind : '',
43
+ spec: defaultPanelSpec !== null && defaultPanelSpec !== void 0 ? defaultPanelSpec : {}
44
+ },
45
+ queries: []
46
+ }
47
+ };
48
+ }
@@ -40,20 +40,15 @@ function createPanelEditorSlice() {
40
40
  if (panelToEdit === undefined) {
41
41
  throw new Error(`Cannot find Panel with key '${panelKey}'`);
42
42
  }
43
- var _description;
44
43
  const editorState = {
45
44
  mode: 'Edit',
46
45
  initialValues: {
47
- name: panelToEdit.spec.display.name,
48
- description: (_description = panelToEdit.spec.display.description) !== null && _description !== void 0 ? _description : '',
49
46
  groupId: panelGroupItemId.panelGroupId,
50
- kind: panelToEdit.spec.plugin.kind,
51
- spec: panelToEdit.spec.plugin.spec
47
+ panelDefinition: panelToEdit
52
48
  },
53
49
  applyChanges: (next)=>{
54
- const panelDefinititon = createPanelDefinitionFromEditorValues(next);
55
50
  set((state)=>{
56
- state.panels[panelKey] = panelDefinititon;
51
+ state.panels[panelKey] = next.panelDefinition;
57
52
  // If the panel didn't change groups, nothing else to do
58
53
  if (next.groupId === panelGroupId) {
59
54
  return;
@@ -99,7 +94,7 @@ function createPanelEditorSlice() {
99
94
  });
100
95
  },
101
96
  openAddPanel (panelGroupId) {
102
- var ref, ref1;
97
+ var ref;
103
98
  // If a panel group isn't supplied, add to the first group or create a group if there aren't any
104
99
  let newGroup = undefined;
105
100
  panelGroupId !== null && panelGroupId !== void 0 ? panelGroupId : panelGroupId = get().panelGroupOrder[0];
@@ -108,22 +103,19 @@ function createPanelEditorSlice() {
108
103
  newGroup.title = 'Panel Group';
109
104
  panelGroupId = newGroup.id;
110
105
  }
111
- var ref2, ref3;
106
+ var ref1;
112
107
  const editorState = {
113
108
  mode: 'Add',
114
109
  initialValues: {
115
- name: '',
116
- description: '',
117
110
  groupId: panelGroupId,
118
- kind: (ref2 = (ref = get().initialValues) === null || ref === void 0 ? void 0 : ref.kind) !== null && ref2 !== void 0 ? ref2 : '',
119
- spec: (ref3 = (ref1 = get().initialValues) === null || ref1 === void 0 ? void 0 : ref1.spec) !== null && ref3 !== void 0 ? ref3 : {}
111
+ panelDefinition: (ref1 = (ref = get().initialValues) === null || ref === void 0 ? void 0 : ref.panelDefinition) !== null && ref1 !== void 0 ? ref1 : (0, _common.createPanelDefinition)()
120
112
  },
121
113
  applyChanges: (next)=>{
122
- const panelDef = createPanelDefinitionFromEditorValues(next);
123
- const panelKey = (0, _panelUtils.getValidPanelKey)(next.name, get().panels);
114
+ const name = next.panelDefinition.spec.display.name;
115
+ const panelKey = (0, _panelUtils.getValidPanelKey)(name, get().panels);
124
116
  set((state)=>{
125
117
  // Add a panel
126
- state.panels[panelKey] = panelDef;
118
+ state.panels[panelKey] = next.panelDefinition;
127
119
  // Also add a panel group item referencing the panel
128
120
  const group = state.panelGroups[next.groupId];
129
121
  if (group === undefined) {
@@ -158,19 +150,3 @@ function createPanelEditorSlice() {
158
150
  };
159
151
  };
160
152
  }
161
- // Helper to create PanelDefinitions when saving
162
- function createPanelDefinitionFromEditorValues(editorValues) {
163
- return {
164
- kind: 'Panel',
165
- spec: {
166
- display: {
167
- name: editorValues.name,
168
- description: editorValues.description !== '' ? editorValues.description : undefined
169
- },
170
- plugin: {
171
- kind: editorValues.kind,
172
- spec: editorValues.spec
173
- }
174
- }
175
- };
176
- }
@@ -0,0 +1,39 @@
1
+ // Copyright 2023 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, "WithDataQueries", {
18
+ enumerable: true,
19
+ get: ()=>WithDataQueries
20
+ });
21
+ const _jsxRuntime = require("react/jsx-runtime");
22
+ const _pluginSystem = require("@perses-dev/plugin-system");
23
+ // Type guard because storybook types parameters as `any`
24
+ function isWithDataQueriesParameter(parameter) {
25
+ return !!parameter && typeof parameter === 'object' && 'props' in parameter;
26
+ }
27
+ const WithDataQueries = (Story, context)=>{
28
+ const initParameter = context.parameters.WithDataQueries;
29
+ const parameter = isWithDataQueriesParameter(initParameter) ? initParameter : {
30
+ props: {
31
+ definitions: []
32
+ }
33
+ };
34
+ const props = parameter === null || parameter === void 0 ? void 0 : parameter.props;
35
+ return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_pluginSystem.DataQueriesProvider, {
36
+ ...props,
37
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(Story, {})
38
+ });
39
+ };