@perses-dev/dashboards 0.52.0-rc.0 → 0.52.0-rc.1

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 (31) hide show
  1. package/dist/cjs/components/LeaveDialog/LeaveDialog.js +45 -17
  2. package/dist/cjs/components/Panel/PanelActions.js +1 -1
  3. package/dist/cjs/components/PanelDrawer/PanelEditorForm.js +204 -185
  4. package/dist/cjs/components/Variables/VariableEditor.js +22 -15
  5. package/dist/cjs/context/DashboardProvider/DashboardProviderWithQueryParams.js +26 -4
  6. package/dist/cjs/context/VariableProvider/query-params.js +12 -14
  7. package/dist/cjs/test/render.js +6 -8
  8. package/dist/components/LeaveDialog/LeaveDialog.d.ts +6 -1
  9. package/dist/components/LeaveDialog/LeaveDialog.d.ts.map +1 -1
  10. package/dist/components/LeaveDialog/LeaveDialog.js +40 -15
  11. package/dist/components/LeaveDialog/LeaveDialog.js.map +1 -1
  12. package/dist/components/Panel/HeaderIconButton.d.ts +1 -1
  13. package/dist/components/Panel/PanelActions.js +1 -1
  14. package/dist/components/Panel/PanelActions.js.map +1 -1
  15. package/dist/components/PanelDrawer/PanelEditorForm.d.ts.map +1 -1
  16. package/dist/components/PanelDrawer/PanelEditorForm.js +207 -188
  17. package/dist/components/PanelDrawer/PanelEditorForm.js.map +1 -1
  18. package/dist/components/Variables/VariableEditor.d.ts.map +1 -1
  19. package/dist/components/Variables/VariableEditor.js +24 -17
  20. package/dist/components/Variables/VariableEditor.js.map +1 -1
  21. package/dist/context/DashboardProvider/DashboardProviderWithQueryParams.d.ts.map +1 -1
  22. package/dist/context/DashboardProvider/DashboardProviderWithQueryParams.js +26 -4
  23. package/dist/context/DashboardProvider/DashboardProviderWithQueryParams.js.map +1 -1
  24. package/dist/context/VariableProvider/query-params.d.ts +4 -3
  25. package/dist/context/VariableProvider/query-params.d.ts.map +1 -1
  26. package/dist/context/VariableProvider/query-params.js +9 -14
  27. package/dist/context/VariableProvider/query-params.js.map +1 -1
  28. package/dist/test/render.d.ts.map +1 -1
  29. package/dist/test/render.js +6 -8
  30. package/dist/test/render.js.map +1 -1
  31. package/package.json +6 -6
@@ -14,31 +14,59 @@
14
14
  Object.defineProperty(exports, "__esModule", {
15
15
  value: true
16
16
  });
17
- Object.defineProperty(exports, "LeaveDialog", {
18
- enumerable: true,
19
- get: function() {
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
+ LeaveDialog: function() {
20
25
  return LeaveDialog;
26
+ },
27
+ Prompt: function() {
28
+ return Prompt;
21
29
  }
22
30
  });
23
31
  const _jsxruntime = require("react/jsx-runtime");
24
32
  const _react = require("react");
25
- function LeaveDialog({ original, current }) {
33
+ const _reactrouterdom = require("react-router-dom");
34
+ const _components = require("@perses-dev/components");
35
+ const handleRouteChange = (event)=>{
36
+ event.preventDefault();
37
+ event.returnValue = ''; // Required for Chrome
38
+ return ''; // Required for other browsers
39
+ };
40
+ function Prompt({ isBlocked, message }) {
41
+ const blocker = (0, _reactrouterdom.useBlocker)(isBlocked);
42
+ const isBlockedState = blocker.state === 'blocked';
43
+ const isProceedingState = blocker.state === 'proceeding';
26
44
  (0, _react.useEffect)(()=>{
27
- const handleBeforeUnload = (event)=>{
28
- if (JSON.stringify(original) === JSON.stringify(current)) {
29
- return null;
30
- }
31
- event.preventDefault();
32
- event.returnValue = ''; // Required for Chrome
33
- return ''; // Required for other browsers
34
- };
35
- window.addEventListener('beforeunload', handleBeforeUnload);
45
+ if (isBlocked) {
46
+ window.addEventListener('beforeunload', handleRouteChange);
47
+ } else {
48
+ window.removeEventListener('beforeunload', handleRouteChange);
49
+ }
36
50
  return ()=>{
37
- window.removeEventListener('beforeunload', handleBeforeUnload);
51
+ window.removeEventListener('beforeunload', handleRouteChange);
38
52
  };
39
53
  }, [
40
- original,
41
- current
54
+ blocker,
55
+ isBlocked,
56
+ isBlockedState
42
57
  ]);
43
- return /*#__PURE__*/ (0, _jsxruntime.jsx)(_jsxruntime.Fragment, {});
58
+ const handleDiscardChanges = ()=>blocker.proceed?.();
59
+ const handleCancel = ()=>blocker.reset?.();
60
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.DiscardChangesConfirmationDialog, {
61
+ description: message,
62
+ isOpen: isBlockedState || isProceedingState,
63
+ onDiscardChanges: handleDiscardChanges,
64
+ onCancel: handleCancel
65
+ });
66
+ }
67
+ function LeaveDialog({ original, current }) {
68
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(Prompt, {
69
+ isBlocked: JSON.stringify(original) !== JSON.stringify(current),
70
+ message: "You have unsaved changes, are you sure you want to leave?"
71
+ });
44
72
  }
@@ -344,7 +344,7 @@ const OverflowMenu = ({ children, title })=>{
344
344
  // do not show overflow menu if there is no content (for example, edit actions are hidden)
345
345
  const hasContent = /*#__PURE__*/ (0, _react.isValidElement)(children) || Array.isArray(children) && children.some(_react.isValidElement);
346
346
  if (!hasContent) {
347
- return undefined;
347
+ return null;
348
348
  }
349
349
  const handleClick = (event)=>{
350
350
  setAnchorPosition(event.currentTarget.getBoundingClientRect());
@@ -31,6 +31,7 @@ _export(exports, {
31
31
  const _jsxruntime = require("react/jsx-runtime");
32
32
  const _react = require("react");
33
33
  const _material = require("@mui/material");
34
+ const _core = require("@perses-dev/core");
34
35
  const _components = require("@perses-dev/components");
35
36
  const _pluginsystem = require("@perses-dev/plugin-system");
36
37
  const _reacthookform = require("react-hook-form");
@@ -40,6 +41,7 @@ const _PanelPreview = require("./PanelPreview");
40
41
  const _usePanelEditor = require("./usePanelEditor");
41
42
  function PanelEditorForm(props) {
42
43
  const { initialValues, initialAction, onSave, onClose } = props;
44
+ const pluginEditorRef = (0, _react.useRef)(null);
43
45
  const panelGroups = (0, _context.useListPanelGroups)();
44
46
  const { panelDefinition, setName, setDescription, setLinks, setQueries, setPlugin, setPanelDefinition } = (0, _usePanelEditor.usePanelEditor)(initialValues.panelDefinition);
45
47
  const { plugin } = panelDefinition.spec;
@@ -50,6 +52,9 @@ function PanelEditorForm(props) {
50
52
  mode: 'onBlur',
51
53
  defaultValues: initialValues
52
54
  });
55
+ const { dashboard } = (0, _context.useDashboard)();
56
+ const dashboardDuration = dashboard?.kind === 'Dashboard' ? dashboard.spec.duration : _core.DEFAULT_DASHBOARD_DURATION;
57
+ const initialTimeRange = (0, _pluginsystem.useInitialTimeRange)(dashboardDuration);
53
58
  // Use common plugin editor logic even though we've split the inputs up in this form
54
59
  const pluginEditor = (0, _pluginsystem.usePluginEditor)({
55
60
  pluginTypes: [
@@ -88,9 +93,11 @@ function PanelEditorForm(props) {
88
93
  setLinks,
89
94
  links
90
95
  ]);
91
- const processForm = (data)=>{
96
+ const processForm = (0, _react.useCallback)((data)=>{
92
97
  onSave(data);
93
- };
98
+ }, [
99
+ onSave
100
+ ]);
94
101
  // When user click on cancel, several possibilities:
95
102
  // - create action: ask for discard approval
96
103
  // - update action: ask for discard approval if changed
@@ -123,199 +130,211 @@ function PanelEditorForm(props) {
123
130
  control: form.control,
124
131
  name: 'panelDefinition.spec.plugin.kind'
125
132
  });
126
- return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_reacthookform.FormProvider, {
127
- ...form,
128
- children: [
129
- /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Box, {
130
- sx: {
131
- display: 'flex',
132
- alignItems: 'center',
133
- padding: (theme)=>theme.spacing(1, 2),
134
- borderBottom: (theme)=>`1px solid ${theme.palette.divider}`
135
- },
136
- children: [
137
- /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Typography, {
138
- variant: "h2",
139
- children: [
140
- titleAction,
141
- " Panel"
142
- ]
143
- }),
144
- /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Stack, {
145
- direction: "row",
146
- spacing: 1,
147
- marginLeft: "auto",
148
- children: [
149
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Button, {
150
- variant: "contained",
151
- disabled: !form.formState.isValid,
152
- onClick: form.handleSubmit(processForm),
153
- children: submitText
154
- }),
155
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Button, {
156
- color: "secondary",
157
- variant: "outlined",
158
- onClick: handleCancel,
159
- children: "Cancel"
160
- })
161
- ]
162
- })
163
- ]
164
- }),
165
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
166
- id: panelEditorFormId,
167
- sx: {
168
- flex: 1,
169
- overflowY: 'scroll',
170
- padding: (theme)=>theme.spacing(2)
171
- },
172
- children: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Grid, {
173
- container: true,
174
- spacing: 2,
133
+ const { timeRange } = (0, _pluginsystem.useTimeRangeParams)(initialTimeRange);
134
+ const handleSubmit = (0, _react.useCallback)(()=>{
135
+ pluginEditorRef.current?.flushChanges?.();
136
+ form.handleSubmit(processForm)();
137
+ }, [
138
+ form,
139
+ processForm
140
+ ]);
141
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.TimeRangeProvider, {
142
+ timeRange: timeRange,
143
+ children: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_reacthookform.FormProvider, {
144
+ ...form,
145
+ children: [
146
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Box, {
147
+ sx: {
148
+ display: 'flex',
149
+ alignItems: 'center',
150
+ padding: (theme)=>theme.spacing(1, 2),
151
+ borderBottom: (theme)=>`1px solid ${theme.palette.divider}`
152
+ },
175
153
  children: [
176
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Grid, {
177
- item: true,
178
- xs: 8,
179
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reacthookform.Controller, {
180
- control: form.control,
181
- name: "panelDefinition.spec.display.name",
182
- render: ({ field, fieldState })=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TextField, {
183
- ...field,
184
- required: true,
185
- fullWidth: true,
186
- label: "Name",
187
- error: !!fieldState.error,
188
- helperText: fieldState.error?.message,
189
- value: watchedName ?? '',
190
- onChange: (event)=>{
191
- field.onChange(event);
192
- setName(event.target.value);
193
- }
194
- })
195
- })
196
- }),
197
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Grid, {
198
- item: true,
199
- xs: 4,
200
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reacthookform.Controller, {
201
- control: form.control,
202
- name: "groupId",
203
- render: ({ field, fieldState })=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TextField, {
204
- select: true,
205
- ...field,
206
- required: true,
207
- fullWidth: true,
208
- label: "Group",
209
- error: !!fieldState.error,
210
- helperText: fieldState.error?.message,
211
- onChange: (event)=>{
212
- field.onChange(event);
213
- },
214
- children: panelGroups.map((panelGroup, index)=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.MenuItem, {
215
- value: panelGroup.id,
216
- children: panelGroup.title ?? `Group ${index + 1}`
217
- }, panelGroup.id))
218
- })
219
- })
220
- }),
221
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Grid, {
222
- item: true,
223
- xs: 8,
224
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reacthookform.Controller, {
225
- control: form.control,
226
- name: "panelDefinition.spec.display.description",
227
- render: ({ field, fieldState })=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TextField, {
228
- ...field,
229
- fullWidth: true,
230
- label: "Description",
231
- error: !!fieldState.error,
232
- helperText: fieldState.error?.message,
233
- value: watchedDescription ?? '',
234
- onChange: (event)=>{
235
- field.onChange(event);
236
- setDescription(event.target.value);
237
- }
238
- })
239
- })
240
- }),
241
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Grid, {
242
- item: true,
243
- xs: 4,
244
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reacthookform.Controller, {
245
- control: form.control,
246
- name: "panelDefinition.spec.plugin.kind",
247
- render: ({ field, fieldState })=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.PluginKindSelect, {
248
- ...field,
249
- pluginTypes: [
250
- 'Panel'
251
- ],
252
- required: true,
253
- fullWidth: true,
254
- label: "Type",
255
- disabled: pluginEditor.isLoading,
256
- error: !!pluginEditor.error || !!fieldState.error,
257
- helperText: pluginEditor.error?.message ?? fieldState.error?.message,
258
- value: {
259
- type: 'Panel',
260
- kind: watchedPluginKind
261
- },
262
- onChange: (event)=>{
263
- field.onChange(event.kind);
264
- pluginEditor.onSelectionChange(event);
265
- }
266
- })
267
- })
154
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Typography, {
155
+ variant: "h2",
156
+ children: [
157
+ titleAction,
158
+ " Panel"
159
+ ]
268
160
  }),
269
- /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Grid, {
270
- item: true,
271
- xs: 12,
161
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Stack, {
162
+ direction: "row",
163
+ spacing: 1,
164
+ marginLeft: "auto",
272
165
  children: [
273
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Typography, {
274
- variant: "h4",
275
- marginBottom: 1,
276
- children: "Preview"
166
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Button, {
167
+ variant: "contained",
168
+ disabled: !form.formState.isValid,
169
+ onClick: handleSubmit,
170
+ children: submitText
277
171
  }),
278
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.ErrorBoundary, {
279
- FallbackComponent: _components.ErrorAlert,
280
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_PanelPreview.PanelPreview, {
281
- panelDefinition: panelDefinition
282
- })
172
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Button, {
173
+ color: "secondary",
174
+ variant: "outlined",
175
+ onClick: handleCancel,
176
+ children: "Cancel"
283
177
  })
284
178
  ]
285
- }),
286
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Grid, {
287
- item: true,
288
- xs: 12,
289
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.ErrorBoundary, {
290
- FallbackComponent: _components.ErrorAlert,
291
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.PanelSpecEditor, {
179
+ })
180
+ ]
181
+ }),
182
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
183
+ id: panelEditorFormId,
184
+ sx: {
185
+ flex: 1,
186
+ overflowY: 'scroll',
187
+ padding: (theme)=>theme.spacing(2)
188
+ },
189
+ children: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Grid, {
190
+ container: true,
191
+ spacing: 2,
192
+ children: [
193
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Grid, {
194
+ item: true,
195
+ xs: 8,
196
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reacthookform.Controller, {
197
+ control: form.control,
198
+ name: "panelDefinition.spec.display.name",
199
+ render: ({ field, fieldState })=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TextField, {
200
+ ...field,
201
+ required: true,
202
+ fullWidth: true,
203
+ label: "Name",
204
+ error: !!fieldState.error,
205
+ helperText: fieldState.error?.message,
206
+ value: watchedName ?? '',
207
+ onChange: (event)=>{
208
+ field.onChange(event);
209
+ setName(event.target.value);
210
+ }
211
+ })
212
+ })
213
+ }),
214
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Grid, {
215
+ item: true,
216
+ xs: 4,
217
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reacthookform.Controller, {
218
+ control: form.control,
219
+ name: "groupId",
220
+ render: ({ field, fieldState })=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TextField, {
221
+ select: true,
222
+ ...field,
223
+ required: true,
224
+ fullWidth: true,
225
+ label: "Group",
226
+ error: !!fieldState.error,
227
+ helperText: fieldState.error?.message,
228
+ onChange: (event)=>{
229
+ field.onChange(event);
230
+ },
231
+ children: panelGroups.map((panelGroup, index)=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.MenuItem, {
232
+ value: panelGroup.id,
233
+ children: panelGroup.title ?? `Group ${index + 1}`
234
+ }, panelGroup.id))
235
+ })
236
+ })
237
+ }),
238
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Grid, {
239
+ item: true,
240
+ xs: 8,
241
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reacthookform.Controller, {
242
+ control: form.control,
243
+ name: "panelDefinition.spec.display.description",
244
+ render: ({ field, fieldState })=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TextField, {
245
+ ...field,
246
+ fullWidth: true,
247
+ label: "Description",
248
+ error: !!fieldState.error,
249
+ helperText: fieldState.error?.message,
250
+ value: watchedDescription ?? '',
251
+ onChange: (event)=>{
252
+ field.onChange(event);
253
+ setDescription(event.target.value);
254
+ }
255
+ })
256
+ })
257
+ }),
258
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Grid, {
259
+ item: true,
260
+ xs: 4,
261
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reacthookform.Controller, {
292
262
  control: form.control,
293
- panelDefinition: panelDefinition,
294
- onJSONChange: handlePanelDefinitionChange,
295
- onQueriesChange: (queries)=>{
296
- setQueries(queries);
297
- },
298
- onPluginSpecChange: (spec)=>{
299
- pluginEditor.onSpecChange(spec);
300
- }
263
+ name: "panelDefinition.spec.plugin.kind",
264
+ render: ({ field, fieldState })=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.PluginKindSelect, {
265
+ ...field,
266
+ pluginTypes: [
267
+ 'Panel'
268
+ ],
269
+ required: true,
270
+ fullWidth: true,
271
+ label: "Type",
272
+ disabled: pluginEditor.isLoading,
273
+ error: !!pluginEditor.error || !!fieldState.error,
274
+ helperText: pluginEditor.error?.message ?? fieldState.error?.message,
275
+ value: {
276
+ type: 'Panel',
277
+ kind: watchedPluginKind
278
+ },
279
+ onChange: (event)=>{
280
+ field.onChange(event.kind);
281
+ pluginEditor.onSelectionChange(event);
282
+ }
283
+ })
284
+ })
285
+ }),
286
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Grid, {
287
+ item: true,
288
+ xs: 12,
289
+ children: [
290
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Typography, {
291
+ variant: "h4",
292
+ marginBottom: 1,
293
+ children: "Preview"
294
+ }),
295
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.ErrorBoundary, {
296
+ FallbackComponent: _components.ErrorAlert,
297
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_PanelPreview.PanelPreview, {
298
+ panelDefinition: panelDefinition
299
+ })
300
+ })
301
+ ]
302
+ }),
303
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Grid, {
304
+ item: true,
305
+ xs: 12,
306
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.ErrorBoundary, {
307
+ FallbackComponent: _components.ErrorAlert,
308
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.PanelSpecEditor, {
309
+ ref: pluginEditorRef,
310
+ control: form.control,
311
+ panelDefinition: panelDefinition,
312
+ onJSONChange: handlePanelDefinitionChange,
313
+ onQueriesChange: (queries)=>{
314
+ setQueries(queries);
315
+ },
316
+ onPluginSpecChange: (spec)=>{
317
+ pluginEditor.onSpecChange(spec);
318
+ }
319
+ })
301
320
  })
302
321
  })
303
- })
304
- ]
322
+ ]
323
+ })
324
+ }),
325
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.DiscardChangesConfirmationDialog, {
326
+ description: "You have unapplied changes in this panel. Are you sure you want to discard these changes? Changes cannot be recovered.",
327
+ isOpen: isDiscardDialogOpened,
328
+ onCancel: ()=>{
329
+ setDiscardDialogOpened(false);
330
+ },
331
+ onDiscardChanges: ()=>{
332
+ setDiscardDialogOpened(false);
333
+ onClose();
334
+ }
305
335
  })
306
- }),
307
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.DiscardChangesConfirmationDialog, {
308
- description: "You have unapplied changes in this panel. Are you sure you want to discard these changes? Changes cannot be recovered.",
309
- isOpen: isDiscardDialogOpened,
310
- onCancel: ()=>{
311
- setDiscardDialogOpened(false);
312
- },
313
- onDiscardChanges: ()=>{
314
- setDiscardDialogOpened(false);
315
- onClose();
316
- }
317
- })
318
- ]
336
+ ]
337
+ })
319
338
  });
320
339
  }
321
340
  const panelEditorFormId = 'panel-editor-form';
@@ -32,6 +32,7 @@ const _jsxruntime = require("react/jsx-runtime");
32
32
  const _react = require("react");
33
33
  const _material = require("@mui/material");
34
34
  const _Plus = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/Plus"));
35
+ const _core = require("@perses-dev/core");
35
36
  const _useimmer = require("use-immer");
36
37
  const _Pencil = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/Pencil"));
37
38
  const _TrashCan = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/TrashCan"));
@@ -163,26 +164,32 @@ function VariableEditor(props) {
163
164
  draft.push(v);
164
165
  });
165
166
  };
167
+ const { dashboard } = (0, _context.useDashboard)();
168
+ const dashboardDuration = dashboard?.kind === 'Dashboard' ? dashboard.spec.duration : _core.DEFAULT_DASHBOARD_DURATION;
169
+ const initialTimeRange = (0, _pluginsystem.useInitialTimeRange)(dashboardDuration);
166
170
  return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
167
171
  children: [
168
172
  currentEditingVariableDefinition && /*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.ValidationProvider, {
169
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.VariableEditorForm, {
170
- initialVariableDefinition: currentEditingVariableDefinition,
171
- action: variableFormAction,
172
- isDraft: true,
173
- onActionChange: setVariableFormAction,
174
- onSave: (definition)=>{
175
- setVariableDefinitions((draft)=>{
176
- draft[variableEditIdx] = definition;
173
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.TimeRangeProvider, {
174
+ timeRange: initialTimeRange,
175
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.VariableEditorForm, {
176
+ initialVariableDefinition: currentEditingVariableDefinition,
177
+ action: variableFormAction,
178
+ isDraft: true,
179
+ onActionChange: setVariableFormAction,
180
+ onSave: (definition)=>{
181
+ setVariableDefinitions((draft)=>{
182
+ draft[variableEditIdx] = definition;
183
+ setVariableEditIdx(null);
184
+ });
185
+ },
186
+ onClose: ()=>{
187
+ if (variableFormAction === 'create') {
188
+ removeVariable(variableEditIdx);
189
+ }
177
190
  setVariableEditIdx(null);
178
- });
179
- },
180
- onClose: ()=>{
181
- if (variableFormAction === 'create') {
182
- removeVariable(variableEditIdx);
183
191
  }
184
- setVariableEditIdx(null);
185
- }
192
+ })
186
193
  })
187
194
  }),
188
195
  !currentEditingVariableDefinition && /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
@@ -21,15 +21,37 @@ Object.defineProperty(exports, "DashboardProviderWithQueryParams", {
21
21
  }
22
22
  });
23
23
  const _jsxruntime = require("react/jsx-runtime");
24
- const _usequeryparams = require("use-query-params");
24
+ const _zod = require("zod");
25
+ const _react = require("react");
26
+ const _nuqs = require("nuqs");
25
27
  const _DashboardProvider = require("./DashboardProvider");
26
28
  function DashboardProviderWithQueryParams({ children, initialState }) {
27
- const [viewPanelRef, setViewPanelRef] = (0, _usequeryparams.useQueryParam)('viewPanelRef', _usequeryparams.JsonParam);
29
+ const [viewPanelRef, setViewPanelRef] = (0, _nuqs.useQueryState)('viewPanelRef', (0, _nuqs.parseAsJson)(_zod.z.object({
30
+ ref: _zod.z.string(),
31
+ repeatVariable: _zod.z.tuple([
32
+ _zod.z.string(),
33
+ _zod.z.string()
34
+ ]).optional()
35
+ }).optional()));
36
+ // nuqs returns null when the query param is not present, but our state expects undefined when not present
37
+ const viewPanelRefNotNull = (0, _react.useMemo)(()=>{
38
+ return viewPanelRef ?? undefined;
39
+ }, [
40
+ viewPanelRef
41
+ ]);
42
+ const handleSetViewPanelRef = (0, _react.useCallback)((panelRef)=>{
43
+ if (panelRef) {
44
+ return setViewPanelRef(panelRef);
45
+ }
46
+ return setViewPanelRef(null);
47
+ }, [
48
+ setViewPanelRef
49
+ ]);
28
50
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_DashboardProvider.DashboardProvider, {
29
51
  initialState: {
30
52
  ...initialState,
31
- viewPanelRef: viewPanelRef ?? undefined,
32
- setViewPanelRef: setViewPanelRef
53
+ viewPanelRef: viewPanelRefNotNull,
54
+ setViewPanelRef: handleSetViewPanelRef
33
55
  },
34
56
  children: children
35
57
  });