@perses-dev/dashboards 0.0.0-snapshot-explorer-plugin-c4a7621 → 0.0.0-snapshot-profile-8090608

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 (136) hide show
  1. package/dist/cjs/components/DashboardToolbar/DashboardToolbar.js +3 -3
  2. package/dist/cjs/components/DeletePanelDialog/DeletePanelDialog.js +2 -0
  3. package/dist/cjs/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js +2 -0
  4. package/dist/cjs/components/DownloadButton/DownloadButton.js +135 -29
  5. package/dist/cjs/components/GridLayout/GridItemContent.js +3 -2
  6. package/dist/cjs/components/GridLayout/GridLayout.js +6 -10
  7. package/dist/cjs/components/Panel/Panel.js +6 -2
  8. package/dist/cjs/components/Panel/PanelActions.js +204 -55
  9. package/dist/cjs/components/Panel/PanelContent.js +56 -10
  10. package/dist/cjs/components/Panel/PanelHeader.js +10 -46
  11. package/dist/cjs/components/Panel/PanelPluginLoader.js +56 -0
  12. package/dist/cjs/components/Panel/index.js +1 -0
  13. package/dist/cjs/components/PanelDrawer/PanelEditorForm.js +21 -9
  14. package/dist/cjs/components/Variables/Variable.js +10 -1
  15. package/dist/cjs/constants/styles.js +7 -3
  16. package/dist/cjs/constants/user-interface-text.js +1 -2
  17. package/dist/cjs/context/DashboardProvider/dashboard-provider-api.js +12 -1
  18. package/dist/cjs/context/VariableProvider/VariableProvider.js +16 -20
  19. package/dist/cjs/test/datasource-provider.js +1 -1
  20. package/dist/cjs/test/plugin-registry.js +4 -1
  21. package/dist/cjs/views/ViewDashboard/DashboardApp.js +4 -1
  22. package/dist/cjs/views/ViewDashboard/ViewDashboard.js +3 -1
  23. package/dist/components/DashboardToolbar/DashboardToolbar.d.ts +2 -0
  24. package/dist/components/DashboardToolbar/DashboardToolbar.d.ts.map +1 -1
  25. package/dist/components/DashboardToolbar/DashboardToolbar.js +3 -3
  26. package/dist/components/DashboardToolbar/DashboardToolbar.js.map +1 -1
  27. package/dist/components/Datasources/DatasourceEditor.js.map +1 -1
  28. package/dist/components/DeletePanelDialog/DeletePanelDialog.js +3 -1
  29. package/dist/components/DeletePanelDialog/DeletePanelDialog.js.map +1 -1
  30. package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.d.ts.map +1 -1
  31. package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js +3 -1
  32. package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js.map +1 -1
  33. package/dist/components/DownloadButton/DownloadButton.d.ts +1 -5
  34. package/dist/components/DownloadButton/DownloadButton.d.ts.map +1 -1
  35. package/dist/components/DownloadButton/DownloadButton.js +94 -29
  36. package/dist/components/DownloadButton/DownloadButton.js.map +1 -1
  37. package/dist/components/GridLayout/GridContainer.js.map +1 -1
  38. package/dist/components/GridLayout/GridItemContent.d.ts.map +1 -1
  39. package/dist/components/GridLayout/GridItemContent.js +4 -3
  40. package/dist/components/GridLayout/GridItemContent.js.map +1 -1
  41. package/dist/components/GridLayout/GridLayout.d.ts.map +1 -1
  42. package/dist/components/GridLayout/GridLayout.js +8 -12
  43. package/dist/components/GridLayout/GridLayout.js.map +1 -1
  44. package/dist/components/GridLayout/GridTitle.js.map +1 -1
  45. package/dist/components/Panel/HeaderIconButton.d.ts +1 -1
  46. package/dist/components/Panel/HeaderIconButton.d.ts.map +1 -1
  47. package/dist/components/Panel/Panel.d.ts +5 -0
  48. package/dist/components/Panel/Panel.d.ts.map +1 -1
  49. package/dist/components/Panel/Panel.js +11 -2
  50. package/dist/components/Panel/Panel.js.map +1 -1
  51. package/dist/components/Panel/PanelActions.d.ts +8 -2
  52. package/dist/components/Panel/PanelActions.d.ts.map +1 -1
  53. package/dist/components/Panel/PanelActions.js +208 -59
  54. package/dist/components/Panel/PanelActions.js.map +1 -1
  55. package/dist/components/Panel/PanelContent.d.ts +5 -4
  56. package/dist/components/Panel/PanelContent.d.ts.map +1 -1
  57. package/dist/components/Panel/PanelContent.js +58 -12
  58. package/dist/components/Panel/PanelContent.js.map +1 -1
  59. package/dist/components/Panel/PanelHeader.d.ts +3 -1
  60. package/dist/components/Panel/PanelHeader.d.ts.map +1 -1
  61. package/dist/components/Panel/PanelHeader.js +12 -43
  62. package/dist/components/Panel/PanelHeader.js.map +1 -1
  63. package/dist/components/Panel/PanelLinks.js.map +1 -1
  64. package/dist/components/Panel/PanelPluginLoader.d.ts +13 -0
  65. package/dist/components/Panel/PanelPluginLoader.d.ts.map +1 -0
  66. package/dist/components/Panel/PanelPluginLoader.js +51 -0
  67. package/dist/components/Panel/PanelPluginLoader.js.map +1 -0
  68. package/dist/components/Panel/index.d.ts +1 -0
  69. package/dist/components/Panel/index.d.ts.map +1 -1
  70. package/dist/components/Panel/index.js +1 -0
  71. package/dist/components/Panel/index.js.map +1 -1
  72. package/dist/components/PanelDrawer/PanelEditorForm.d.ts.map +1 -1
  73. package/dist/components/PanelDrawer/PanelEditorForm.js +21 -9
  74. package/dist/components/PanelDrawer/PanelEditorForm.js.map +1 -1
  75. package/dist/components/SaveChangesConfirmationDialog/SaveChangesConfirmationDialog.js.map +1 -1
  76. package/dist/components/SaveDashboardButton/SaveDashboardButton.js.map +1 -1
  77. package/dist/components/Variables/BuiltinVariableAccordions.js.map +1 -1
  78. package/dist/components/Variables/Variable.js +10 -1
  79. package/dist/components/Variables/Variable.js.map +1 -1
  80. package/dist/components/Variables/VariableEditor.js.map +1 -1
  81. package/dist/components/Variables/VariableList.js.map +1 -1
  82. package/dist/constants/styles.d.ts +2 -1
  83. package/dist/constants/styles.d.ts.map +1 -1
  84. package/dist/constants/styles.js +2 -1
  85. package/dist/constants/styles.js.map +1 -1
  86. package/dist/constants/user-interface-text.d.ts +0 -1
  87. package/dist/constants/user-interface-text.d.ts.map +1 -1
  88. package/dist/constants/user-interface-text.js +1 -2
  89. package/dist/constants/user-interface-text.js.map +1 -1
  90. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts +11 -2
  91. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts.map +1 -1
  92. package/dist/context/DashboardProvider/dashboard-provider-api.js +12 -2
  93. package/dist/context/DashboardProvider/dashboard-provider-api.js.map +1 -1
  94. package/dist/context/DashboardProvider/delete-panel-slice.js.map +1 -1
  95. package/dist/context/DashboardProvider/duplicate-panel-slice.js.map +1 -1
  96. package/dist/context/DashboardProvider/panel-editor-slice.js.map +1 -1
  97. package/dist/context/DashboardProvider/panel-group-slice.d.ts +1 -1
  98. package/dist/context/DashboardProvider/panel-group-slice.d.ts.map +1 -1
  99. package/dist/context/DashboardProvider/panel-group-slice.js.map +1 -1
  100. package/dist/context/DatasourceStoreProvider.js.map +1 -1
  101. package/dist/context/VariableProvider/VariableProvider.d.ts.map +1 -1
  102. package/dist/context/VariableProvider/VariableProvider.js +13 -12
  103. package/dist/context/VariableProvider/VariableProvider.js.map +1 -1
  104. package/dist/context/VariableProvider/query-params.js.map +1 -1
  105. package/dist/context/useDashboard.js.map +1 -1
  106. package/dist/test/datasource-provider.d.ts +1 -1
  107. package/dist/test/datasource-provider.d.ts.map +1 -1
  108. package/dist/test/datasource-provider.js +1 -1
  109. package/dist/test/datasource-provider.js.map +1 -1
  110. package/dist/test/plugin-registry.d.ts.map +1 -1
  111. package/dist/test/plugin-registry.js +4 -1
  112. package/dist/test/plugin-registry.js.map +1 -1
  113. package/dist/utils/panelUtils.js.map +1 -1
  114. package/dist/views/ViewDashboard/DashboardApp.d.ts +2 -0
  115. package/dist/views/ViewDashboard/DashboardApp.d.ts.map +1 -1
  116. package/dist/views/ViewDashboard/DashboardApp.js +4 -1
  117. package/dist/views/ViewDashboard/DashboardApp.js.map +1 -1
  118. package/dist/views/ViewDashboard/ViewDashboard.d.ts.map +1 -1
  119. package/dist/views/ViewDashboard/ViewDashboard.js +3 -1
  120. package/dist/views/ViewDashboard/ViewDashboard.js.map +1 -1
  121. package/package.json +9 -9
  122. package/dist/cjs/stories/decorators/WithDashboard.js +0 -41
  123. package/dist/cjs/stories/decorators/WithDatasourceStore.js +0 -39
  124. package/dist/cjs/stories/decorators/WithVariables.js +0 -37
  125. package/dist/cjs/stories/decorators/constants.js +0 -39
  126. package/dist/cjs/stories/decorators/index.js +0 -33
  127. package/dist/stories/decorators/WithDashboard.js +0 -33
  128. package/dist/stories/decorators/WithDashboard.js.map +0 -1
  129. package/dist/stories/decorators/WithDatasourceStore.js +0 -31
  130. package/dist/stories/decorators/WithDatasourceStore.js.map +0 -1
  131. package/dist/stories/decorators/WithVariables.js +0 -29
  132. package/dist/stories/decorators/WithVariables.js.map +0 -1
  133. package/dist/stories/decorators/constants.js +0 -31
  134. package/dist/stories/decorators/constants.js.map +0 -1
  135. package/dist/stories/decorators/index.js +0 -18
  136. package/dist/stories/decorators/index.js.map +0 -1
@@ -22,14 +22,16 @@ Object.defineProperty(exports, "PanelContent", {
22
22
  });
23
23
  const _jsxruntime = require("react/jsx-runtime");
24
24
  const _pluginsystem = require("@perses-dev/plugin-system");
25
+ const _components = require("@perses-dev/components");
25
26
  const _material = require("@mui/material");
27
+ const _PanelPluginLoader = require("./PanelPluginLoader");
26
28
  function PanelContent(props) {
27
- const { panelPluginKind, contentDimensions, definition, ...others } = props;
28
- const { data: plugin, isLoading } = (0, _pluginsystem.usePlugin)('Panel', panelPluginKind, {
29
+ const { panelPluginKind, definition, queryResults, spec, contentDimensions } = props;
30
+ const { data: plugin, isLoading: isPanelLoading } = (0, _pluginsystem.usePlugin)('Panel', panelPluginKind, {
29
31
  throwOnError: true
30
32
  });
31
- const PanelComponent = plugin?.PanelComponent;
32
- if (isLoading) {
33
+ // Show fullsize skeleton if the panel plugin is loading.
34
+ if (isPanelLoading) {
33
35
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Skeleton, {
34
36
  variant: "rectangular",
35
37
  width: contentDimensions?.width,
@@ -37,12 +39,56 @@ function PanelContent(props) {
37
39
  "aria-label": "Loading..."
38
40
  });
39
41
  }
40
- if (PanelComponent === undefined) {
41
- throw new Error(`Missing PanelComponent from panel plugin for kind '${panelPluginKind}'`);
42
+ // Render the panel if any query has data, or the panel doesn't have a query attached (for example MarkdownPanel).
43
+ // Loading indicator or errors of other queries are shown in the panel header.
44
+ const queryResultsWithData = queryResults.flatMap((q)=>q.data ? [
45
+ {
46
+ data: q.data,
47
+ definition: q.definition
48
+ }
49
+ ] : []);
50
+ if (queryResultsWithData.length > 0 || queryResults.length === 0) {
51
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_PanelPluginLoader.PanelPluginLoader, {
52
+ kind: panelPluginKind,
53
+ spec: spec,
54
+ contentDimensions: contentDimensions,
55
+ definition: definition,
56
+ queryResults: queryResultsWithData
57
+ });
58
+ }
59
+ // No query has data, show loading overlay if any query is fetching data.
60
+ if (queryResults.some((q)=>q.isFetching)) {
61
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(PanelLoading, {
62
+ plugin: plugin,
63
+ spec: spec,
64
+ definition: definition,
65
+ contentDimensions: contentDimensions
66
+ });
67
+ }
68
+ // No query has data or is loading, show the error if any query has an error.
69
+ // The error will be catched in <ErrorBoundary> of <Panel>.
70
+ const queryError = queryResults.find((q)=>q.error);
71
+ if (queryError) {
72
+ throw queryError.error;
42
73
  }
43
- return /*#__PURE__*/ (0, _jsxruntime.jsx)(PanelComponent, {
44
- ...others,
45
- contentDimensions: contentDimensions,
46
- definition: definition
74
+ // At this point, one or more queries are defined, but no query has data, is loading, or has an error.
75
+ // This can happen if all queries are disabled (e.g. dependent dashboard variables are loading, or they are not in the viewport of the browser).
76
+ // Most likely, some query will be enabled later. Render the panel loading skeleton.
77
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(PanelLoading, {
78
+ plugin: plugin,
79
+ spec: spec,
80
+ definition: definition,
81
+ contentDimensions: contentDimensions
47
82
  });
48
83
  }
84
+ function PanelLoading({ plugin, spec, definition, contentDimensions }) {
85
+ if (plugin?.LoadingComponent) {
86
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(plugin.LoadingComponent, {
87
+ spec: spec,
88
+ contentDimensions: contentDimensions,
89
+ definition: definition,
90
+ queryResults: []
91
+ });
92
+ }
93
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.LoadingOverlay, {});
94
+ }
@@ -24,17 +24,9 @@ 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 _InformationOutline = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/InformationOutline"));
28
27
  const _constants = require("../../constants");
29
28
  const _PanelActions = require("./PanelActions");
30
- const _PanelLinks = require("./PanelLinks");
31
- const _HeaderIconButton = require("./HeaderIconButton");
32
- function _interop_require_default(obj) {
33
- return obj && obj.__esModule ? obj : {
34
- default: obj
35
- };
36
- }
37
- function PanelHeader({ id, title: rawTitle, description: rawDescription, links, readHandlers, editHandlers, sx, extra, ...rest }) {
29
+ function PanelHeader({ id, title: rawTitle, description: rawDescription, links, queryResults, readHandlers, editHandlers, sx, extra, ...rest }) {
38
30
  const titleElementId = `${id}-title`;
39
31
  const descriptionTooltipId = `${id}-description`;
40
32
  const title = (0, _pluginsystem.useReplaceVariablesInString)(rawTitle);
@@ -62,39 +54,18 @@ function PanelHeader({ id, title: rawTitle, description: rawDescription, links,
62
54
  },
63
55
  children: title
64
56
  }),
65
- description !== undefined && description.trim().length > 0 && /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
66
- sx: {
67
- display: editHandlers === undefined ? 'var(--panel-hover, none)' : 'flex'
68
- },
69
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
70
- id: descriptionTooltipId,
71
- description: description,
72
- enterDelay: 100,
73
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_HeaderIconButton.HeaderIconButton, {
74
- "aria-label": "panel description",
75
- size: "small",
76
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_InformationOutline.default, {
77
- "aria-describedby": "info-tooltip",
78
- "aria-hidden": false,
79
- fontSize: "inherit",
80
- sx: {
81
- color: (theme)=>theme.palette.text.secondary
82
- }
83
- })
84
- })
85
- })
86
- }),
87
- links !== undefined && links.length > 0 && /*#__PURE__*/ (0, _jsxruntime.jsx)(_PanelLinks.PanelLinks, {
88
- links: links
57
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_PanelActions.PanelActions, {
58
+ title: title,
59
+ description: description,
60
+ descriptionTooltipId: descriptionTooltipId,
61
+ links: links,
62
+ queryResults: queryResults,
63
+ readHandlers: readHandlers,
64
+ editHandlers: editHandlers,
65
+ extra: extra
89
66
  })
90
67
  ]
91
68
  }),
92
- action: /*#__PURE__*/ (0, _jsxruntime.jsx)(_PanelActions.PanelActions, {
93
- title: title,
94
- readHandlers: readHandlers,
95
- editHandlers: editHandlers,
96
- extra: extra
97
- }),
98
69
  sx: (0, _components.combineSx)((theme)=>({
99
70
  containerType: 'inline-size',
100
71
  containerName: _constants.HEADER_ACTIONS_CONTAINER_NAME,
@@ -102,13 +73,6 @@ function PanelHeader({ id, title: rawTitle, description: rawDescription, links,
102
73
  borderBottom: `solid 1px ${theme.palette.divider}`,
103
74
  '.MuiCardHeader-content': {
104
75
  overflow: 'hidden'
105
- },
106
- '.MuiCardHeader-action': {
107
- // Overriding the negative margins from MUI's defaults, so we
108
- // can vertically center the icons. Moving these values to a wrapper
109
- // inside the action in `HeaderActionWrapper` below.
110
- // https://github.com/mui/material-ui/blob/master/packages/mui-material/src/CardHeader/CardHeader.js#L56-L58
111
- margin: 'auto'
112
76
  }
113
77
  }), sx),
114
78
  ...rest
@@ -0,0 +1,56 @@
1
+ // Copyright 2025 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, "PanelPluginLoader", {
18
+ enumerable: true,
19
+ get: function() {
20
+ return PanelPluginLoader;
21
+ }
22
+ });
23
+ const _jsxruntime = require("react/jsx-runtime");
24
+ const _pluginsystem = require("@perses-dev/plugin-system");
25
+ const _material = require("@mui/material");
26
+ function PanelPluginLoader(props) {
27
+ const { kind, spec, contentDimensions, definition, queryResults } = props;
28
+ const { data: plugin, isLoading: isPanelLoading } = (0, _pluginsystem.usePlugin)('Panel', kind, {
29
+ throwOnError: true
30
+ });
31
+ const PanelComponent = plugin?.PanelComponent;
32
+ const supportedQueryTypes = plugin?.supportedQueryTypes || [];
33
+ // Show fullsize skeleton if the panel plugin is loading.
34
+ if (isPanelLoading) {
35
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Skeleton, {
36
+ variant: "rectangular",
37
+ width: contentDimensions?.width,
38
+ height: contentDimensions?.height,
39
+ "aria-label": "Loading..."
40
+ });
41
+ }
42
+ if (PanelComponent === undefined) {
43
+ throw new Error(`Missing PanelComponent from panel plugin for kind '${kind}'`);
44
+ }
45
+ for (const queryResult of queryResults){
46
+ if (!supportedQueryTypes.includes(queryResult.definition.kind)) {
47
+ throw new Error(`This panel does not support queries of type '${queryResult.definition.kind}'. Supported query types: ${supportedQueryTypes.join(', ')}.`);
48
+ }
49
+ }
50
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(PanelComponent, {
51
+ spec: spec,
52
+ contentDimensions: contentDimensions,
53
+ definition: definition,
54
+ queryResults: queryResults
55
+ });
56
+ }
@@ -15,6 +15,7 @@ Object.defineProperty(exports, "__esModule", {
15
15
  value: true
16
16
  });
17
17
  _export_star(require("./Panel"), exports);
18
+ _export_star(require("./PanelPluginLoader"), exports);
18
19
  function _export_star(from, to) {
19
20
  Object.keys(from).forEach(function(k) {
20
21
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
@@ -44,6 +44,12 @@ function PanelEditorForm(props) {
44
44
  const { panelDefinition, setName, setDescription, setLinks, setQueries, setPlugin, setPanelDefinition } = (0, _usePanelEditor.usePanelEditor)(initialValues.panelDefinition);
45
45
  const { plugin } = panelDefinition.spec;
46
46
  const [isDiscardDialogOpened, setDiscardDialogOpened] = (0, _react.useState)(false);
47
+ const { panelEditorSchema } = (0, _pluginsystem.useValidationSchemas)();
48
+ const form = (0, _reacthookform.useForm)({
49
+ resolver: (0, _zod.zodResolver)(panelEditorSchema),
50
+ mode: 'onBlur',
51
+ defaultValues: initialValues
52
+ });
47
53
  // Use common plugin editor logic even though we've split the inputs up in this form
48
54
  const pluginEditor = (0, _pluginsystem.usePluginEditor)({
49
55
  pluginTypes: [
@@ -72,12 +78,6 @@ function PanelEditorForm(props) {
72
78
  });
73
79
  const titleAction = (0, _pluginsystem.getTitleAction)(initialAction, true);
74
80
  const submitText = (0, _pluginsystem.getSubmitText)(initialAction, true);
75
- const { panelEditorSchema } = (0, _pluginsystem.useValidationSchemas)();
76
- const form = (0, _reacthookform.useForm)({
77
- resolver: (0, _zod.zodResolver)(panelEditorSchema),
78
- mode: 'onBlur',
79
- defaultValues: initialValues
80
- });
81
81
  const links = (0, _reacthookform.useWatch)({
82
82
  control: form.control,
83
83
  name: 'panelDefinition.spec.links'
@@ -111,6 +111,18 @@ function PanelEditorForm(props) {
111
111
  }
112
112
  setPanelDefinition(nextPanelDef);
113
113
  };
114
+ const watchedName = (0, _reacthookform.useWatch)({
115
+ control: form.control,
116
+ name: 'panelDefinition.spec.display.name'
117
+ });
118
+ const watchedDescription = (0, _reacthookform.useWatch)({
119
+ control: form.control,
120
+ name: 'panelDefinition.spec.display.description'
121
+ });
122
+ const watchedPluginKind = (0, _reacthookform.useWatch)({
123
+ control: form.control,
124
+ name: 'panelDefinition.spec.plugin.kind'
125
+ });
114
126
  return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_reacthookform.FormProvider, {
115
127
  ...form,
116
128
  children: [
@@ -174,7 +186,7 @@ function PanelEditorForm(props) {
174
186
  label: "Name",
175
187
  error: !!fieldState.error,
176
188
  helperText: fieldState.error?.message,
177
- value: field.value ?? '',
189
+ value: watchedName ?? '',
178
190
  onChange: (event)=>{
179
191
  field.onChange(event);
180
192
  setName(event.target.value);
@@ -218,7 +230,7 @@ function PanelEditorForm(props) {
218
230
  label: "Description",
219
231
  error: !!fieldState.error,
220
232
  helperText: fieldState.error?.message,
221
- value: field.value ?? '',
233
+ value: watchedDescription ?? '',
222
234
  onChange: (event)=>{
223
235
  field.onChange(event);
224
236
  setDescription(event.target.value);
@@ -245,7 +257,7 @@ function PanelEditorForm(props) {
245
257
  helperText: pluginEditor.error?.message ?? fieldState.error?.message,
246
258
  value: {
247
259
  type: 'Panel',
248
- kind: field.value
260
+ kind: watchedPluginKind
249
261
  },
250
262
  onChange: (event)=>{
251
263
  field.onChange(event.kind);
@@ -209,6 +209,8 @@ function ListVariable({ name, source }) {
209
209
  const { setVariableValue, setVariableLoading, setVariableOptions } = (0, _context.useVariableDefinitionActions)();
210
210
  const { selectedOptions, value, loading, options, viewOptions } = useListVariableState(definition?.spec, ctx.state, variablesOptionsQuery);
211
211
  const [inputWidth, setInputWidth] = (0, _react.useState)(_constants.MIN_VARIABLE_WIDTH);
212
+ // Used for multiple value variables, it will not clear variable input when selecting an option
213
+ const [inputValue, setInputValue] = (0, _react.useState)('');
212
214
  const title = definition?.spec.display?.name ?? name;
213
215
  const allowMultiple = definition?.spec.allowMultiple === true;
214
216
  const allowAllValue = definition?.spec.allowAllValue === true;
@@ -259,7 +261,8 @@ function ListVariable({ name, source }) {
259
261
  renderInput: (params)=>{
260
262
  return allowMultiple ? /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TextField, {
261
263
  ...params,
262
- label: title
264
+ label: title,
265
+ onChange: (e)=>setInputValue(e.target.value)
263
266
  }) : /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TextField, {
264
267
  ...params,
265
268
  label: title,
@@ -284,11 +287,17 @@ function ListVariable({ name, source }) {
284
287
  setVariableValue(name, variableOptionToVariableValue(value), source);
285
288
  }
286
289
  },
290
+ inputValue: allowMultiple ? inputValue : undefined,
287
291
  onInputChange: (_, newInputValue)=>{
288
292
  if (!allowMultiple) {
289
293
  setInputWidth(getWidthPx(newInputValue, 'list'));
290
294
  }
291
295
  },
296
+ onBlur: ()=>{
297
+ if (allowMultiple) {
298
+ setInputValue('');
299
+ }
300
+ },
292
301
  options: viewOptions
293
302
  }),
294
303
  loading && /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.LinearProgress, {})
@@ -24,8 +24,11 @@ _export(exports, {
24
24
  HEADER_ACTIONS_CONTAINER_NAME: function() {
25
25
  return HEADER_ACTIONS_CONTAINER_NAME;
26
26
  },
27
- HEADER_ACTIONS_MIN_WIDTH: function() {
28
- return HEADER_ACTIONS_MIN_WIDTH;
27
+ HEADER_MEDIUM_WIDTH: function() {
28
+ return HEADER_MEDIUM_WIDTH;
29
+ },
30
+ HEADER_SMALL_WIDTH: function() {
31
+ return HEADER_SMALL_WIDTH;
29
32
  },
30
33
  MAX_VARIABLE_WIDTH: function() {
31
34
  return MAX_VARIABLE_WIDTH;
@@ -46,5 +49,6 @@ const editButtonStyle = {
46
49
  };
47
50
  const MIN_VARIABLE_WIDTH = 120;
48
51
  const MAX_VARIABLE_WIDTH = 500;
49
- const HEADER_ACTIONS_MIN_WIDTH = 200;
52
+ const HEADER_SMALL_WIDTH = 170;
53
+ const HEADER_MEDIUM_WIDTH = 220;
50
54
  const HEADER_ACTIONS_CONTAINER_NAME = 'header-actions-container';
@@ -32,7 +32,6 @@ const TOOLTIP_TEXT = {
32
32
  // Toolbar buttons
33
33
  addPanel: 'Add panel',
34
34
  addGroup: 'Add panel group',
35
- downloadDashboard: 'Download JSON',
36
35
  editDatasources: 'Edit datasources',
37
36
  editJson: 'Edit JSON',
38
37
  editVariables: 'Edit variables',
@@ -65,6 +64,6 @@ const ARIA_LABEL_TEXT = {
65
64
  editPanel: (panelName)=>`edit panel ${panelName}`,
66
65
  duplicatePanel: (panelName)=>`duplicate panel ${panelName}`,
67
66
  deletePanel: (panelName)=>`delete panel ${panelName}`,
68
- showPanelActions: (panelName)=>`show panel actions for ${panelName} `,
67
+ showPanelActions: (panelName)=>`show panel actions for ${panelName}`,
69
68
  movePanel: (panelName)=>`move panel ${panelName}`
70
69
  };
@@ -71,6 +71,9 @@ _export(exports, {
71
71
  },
72
72
  useViewPanel: function() {
73
73
  return useViewPanel;
74
+ },
75
+ useViewPanelGroup: function() {
76
+ return useViewPanelGroup;
74
77
  }
75
78
  });
76
79
  const _react = require("react");
@@ -230,10 +233,18 @@ const selectDashboardDuration = (state)=>state.duration;
230
233
  function useDashboardDuration() {
231
234
  return (0, _DashboardProvider.useDashboardStore)(selectDashboardDuration);
232
235
  }
233
- const selectViewPanel = (state)=>state.getViewPanel();
236
+ const selectViewPanel = (state)=>({
237
+ setViewPanel: state.setViewPanel,
238
+ getViewPanel: state.getViewPanel,
239
+ viewPanelId: state.getViewPanel()
240
+ });
234
241
  function useViewPanel() {
235
242
  return (0, _DashboardProvider.useDashboardStore)(selectViewPanel);
236
243
  }
244
+ const selectViewPanelGroup = (state)=>state.getViewPanel();
245
+ function useViewPanelGroup() {
246
+ return (0, _DashboardProvider.useDashboardStore)(selectViewPanelGroup);
247
+ }
237
248
  const selectSaveChangesConfirmationDialog = ({ saveChangesConfirmationDialog, openSaveChangesConfirmationDialog, closeSaveChangesConfirmationDialog })=>({
238
249
  saveChangesConfirmationDialog,
239
250
  openSaveChangesConfirmationDialog,
@@ -52,17 +52,13 @@ const _zustand = require("zustand");
52
52
  const _traditional = require("zustand/traditional");
53
53
  const _immer = require("zustand/middleware/immer");
54
54
  const _middleware = require("zustand/middleware");
55
- const _immer1 = /*#__PURE__*/ _interop_require_default(require("immer"));
55
+ const _shallow = require("zustand/shallow");
56
+ const _immer1 = require("immer");
56
57
  const _pluginsystem = require("@perses-dev/plugin-system");
57
58
  const _core = require("@perses-dev/core");
58
59
  const _utils = require("./utils");
59
60
  const _hydrationUtils = require("./hydrationUtils");
60
61
  const _queryparams = require("./query-params");
61
- function _interop_require_default(obj) {
62
- return obj && obj.__esModule ? obj : {
63
- default: obj
64
- };
65
- }
66
62
  /**
67
63
  * Context object for {@link VariableDefinitionStore}.
68
64
  */ const VariableDefinitionStoreContext = /*#__PURE__*/ (0, _react.createContext)(undefined);
@@ -125,7 +121,7 @@ function useVariableDefinitionAndState(name, source) {
125
121
  }
126
122
  function useVariableDefinitionActions() {
127
123
  const store = useVariableDefinitionStoreCtx();
128
- return (0, _zustand.useStore)(store, (s)=>{
124
+ return (0, _traditional.useStoreWithEqualityFn)(store, (s)=>{
129
125
  return {
130
126
  setVariableValue: s.setVariableValue,
131
127
  setVariableLoading: s.setVariableLoading,
@@ -134,7 +130,7 @@ function useVariableDefinitionActions() {
134
130
  setVariableDefaultValues: s.setVariableDefaultValues,
135
131
  getSavedVariablesStatus: s.getSavedVariablesStatus
136
132
  };
137
- });
133
+ }, _shallow.shallow);
138
134
  }
139
135
  function useVariableDefinitions() {
140
136
  const store = useVariableDefinitionStoreCtx();
@@ -326,7 +322,7 @@ function createVariableDefinitionStore({ initialVariableDefinitions = [], extern
326
322
  setVariableDefaultValues: ()=>{
327
323
  const variableDefinitions = get().variableDefinitions;
328
324
  const variableState = get().variableState;
329
- const updatedVariables = (0, _immer1.default)(variableDefinitions, (draft)=>{
325
+ const updatedVariables = (0, _immer1.produce)(variableDefinitions, (draft)=>{
330
326
  draft.forEach((variable, index)=>{
331
327
  const name = variable.spec.name;
332
328
  if (variable.kind === 'ListVariable') {
@@ -336,7 +332,7 @@ function createVariableDefinitionStore({ initialVariableDefinitions = [], extern
336
332
  if (currentVariable?.value !== undefined) {
337
333
  draft[index] = {
338
334
  kind: 'ListVariable',
339
- spec: (0, _immer1.default)(variable.spec, (specDraft)=>{
335
+ spec: (0, _immer1.produce)(variable.spec, (specDraft)=>{
340
336
  specDraft.defaultValue = currentVariable.value;
341
337
  })
342
338
  };
@@ -349,7 +345,7 @@ function createVariableDefinitionStore({ initialVariableDefinitions = [], extern
349
345
  if (currentVariable?.value !== undefined) {
350
346
  draft[index] = {
351
347
  kind: 'TextVariable',
352
- spec: (0, _immer1.default)(variable.spec, (specDraft)=>{
348
+ spec: (0, _immer1.produce)(variable.spec, (specDraft)=>{
353
349
  specDraft.value = currentVariableValue;
354
350
  })
355
351
  };
@@ -369,10 +365,10 @@ function createVariableDefinitionStore({ initialVariableDefinitions = [], extern
369
365
  return store; // TODO: @Gladorme check if we can avoid this cast
370
366
  }
371
367
  function VariableProvider({ children, initialVariableDefinitions = [], externalVariableDefinitions = [], builtinVariableDefinitions = [] }) {
372
- const [store] = (0, _react.useState)(createVariableDefinitionStore({
373
- initialVariableDefinitions,
374
- externalVariableDefinitions
375
- }));
368
+ const [store] = (0, _react.useState)(()=>createVariableDefinitionStore({
369
+ initialVariableDefinitions,
370
+ externalVariableDefinitions
371
+ }));
376
372
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(VariableDefinitionStoreContext.Provider, {
377
373
  value: store,
378
374
  children: /*#__PURE__*/ (0, _jsxruntime.jsx)(PluginProvider, {
@@ -384,11 +380,11 @@ function VariableProvider({ children, initialVariableDefinitions = [], externalV
384
380
  function VariableProviderWithQueryParams({ children, initialVariableDefinitions = [], externalVariableDefinitions = [], builtinVariableDefinitions: builtinVariables = [] }) {
385
381
  const allVariableDefs = (0, _utils.mergeVariableDefinitions)(initialVariableDefinitions, externalVariableDefinitions);
386
382
  const queryParams = (0, _queryparams.useVariableQueryParams)(allVariableDefs);
387
- const [store] = (0, _react.useState)(createVariableDefinitionStore({
388
- initialVariableDefinitions,
389
- externalVariableDefinitions,
390
- queryParams
391
- }));
383
+ const [store] = (0, _react.useState)(()=>createVariableDefinitionStore({
384
+ initialVariableDefinitions,
385
+ externalVariableDefinitions,
386
+ queryParams
387
+ }));
392
388
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(VariableDefinitionStoreContext.Provider, {
393
389
  value: store,
394
390
  children: /*#__PURE__*/ (0, _jsxruntime.jsx)(PluginProvider, {
@@ -32,7 +32,7 @@ _export(exports, {
32
32
  }
33
33
  });
34
34
  const _dashboardprovider = require("./dashboard-provider");
35
- const prometheusDemoUrl = 'https://prometheus.demo.do.prometheus.io';
35
+ const prometheusDemoUrl = 'https://prometheus.demo.prometheus.io';
36
36
  const prometheusDemo = {
37
37
  kind: 'GlobalDatasource',
38
38
  metadata: {
@@ -38,7 +38,10 @@ const FakeTimeSeriesPlugin = {
38
38
  content: FakeTimeSeriesChartOptionEditor
39
39
  }
40
40
  ],
41
- createInitialOptions: ()=>({})
41
+ createInitialOptions: ()=>({}),
42
+ supportedQueryTypes: [
43
+ 'TimeSeriesQuery'
44
+ ]
42
45
  };
43
46
  const MOCK_TIME_SERIES_PANEL = {
44
47
  kind: 'Panel',
@@ -28,7 +28,7 @@ const _pluginsystem = require("@perses-dev/plugin-system");
28
28
  const _components1 = require("../../components");
29
29
  const _context = require("../../context");
30
30
  const DashboardApp = (props)=>{
31
- const { dashboardResource, dashboardTitleComponent, emptyDashboardProps, onSave, onDiscard, initialVariableIsSticky, isReadonly, isCreating } = props;
31
+ const { dashboardResource, dashboardTitleComponent, emptyDashboardProps, onSave, onDiscard, initialVariableIsSticky, isReadonly, isVariableEnabled, isDatasourceEnabled, isCreating } = props;
32
32
  const chartsTheme = (0, _components.useChartsTheme)();
33
33
  const { isEditMode, setEditMode } = (0, _context.useEditMode)();
34
34
  const { dashboard, setDashboard } = (0, _context.useDashboard)();
@@ -81,6 +81,8 @@ const DashboardApp = (props)=>{
81
81
  initialVariableIsSticky: initialVariableIsSticky,
82
82
  onSave: onSave,
83
83
  isReadonly: isReadonly,
84
+ isVariableEnabled: isVariableEnabled,
85
+ isDatasourceEnabled: isDatasourceEnabled,
84
86
  onEditButtonClick: onEditButtonClick,
85
87
  onCancelButtonClick: onCancelButtonClick
86
88
  }),
@@ -103,6 +105,7 @@ const DashboardApp = (props)=>{
103
105
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.ChartsProvider, {
104
106
  chartsTheme: chartsTheme,
105
107
  enablePinning: false,
108
+ enableSyncGrouping: false,
106
109
  children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_components1.PanelDrawer, {})
107
110
  }),
108
111
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_components1.PanelGroupDialog, {}),
@@ -30,7 +30,7 @@ const _context = require("../../context");
30
30
  const _DashboardProviderWithQueryParams = require("../../context/DashboardProvider/DashboardProviderWithQueryParams");
31
31
  const _DashboardApp = require("./DashboardApp");
32
32
  function ViewDashboard(props) {
33
- const { dashboardResource, datasourceApi, externalVariableDefinitions, dashboardTitleComponent, emptyDashboardProps, onSave, onDiscard, initialVariableIsSticky, isReadonly, isEditing, isCreating, sx, ...others } = props;
33
+ const { dashboardResource, datasourceApi, externalVariableDefinitions, dashboardTitleComponent, emptyDashboardProps, onSave, onDiscard, initialVariableIsSticky, isReadonly, isVariableEnabled, isDatasourceEnabled, isEditing, isCreating, sx, ...others } = props;
34
34
  const { spec } = dashboardResource;
35
35
  const dashboardDuration = spec.duration ?? _core.DEFAULT_DASHBOARD_DURATION;
36
36
  const dashboardRefreshInterval = spec.refreshInterval ?? _core.DEFAULT_REFRESH_INTERVAL;
@@ -109,6 +109,8 @@ function ViewDashboard(props) {
109
109
  onDiscard: onDiscard,
110
110
  initialVariableIsSticky: initialVariableIsSticky,
111
111
  isReadonly: isReadonly,
112
+ isVariableEnabled: isVariableEnabled,
113
+ isDatasourceEnabled: isDatasourceEnabled,
112
114
  isCreating: isCreating
113
115
  })
114
116
  })
@@ -5,6 +5,8 @@ export interface DashboardToolbarProps {
5
5
  dashboardTitleComponent?: JSX.Element;
6
6
  initialVariableIsSticky?: boolean;
7
7
  isReadonly: boolean;
8
+ isVariableEnabled: boolean;
9
+ isDatasourceEnabled: boolean;
8
10
  onEditButtonClick: () => void;
9
11
  onCancelButtonClick: () => void;
10
12
  onSave?: OnSaveDashboard;
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardToolbar.d.ts","sourceRoot":"","sources":["../../../src/components/DashboardToolbar/DashboardToolbar.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AACrC,OAAO,EAAE,eAAe,EAAe,MAAM,eAAe,CAAC;AAW7D,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IACtC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,eAAO,MAAM,gBAAgB,UAAW,qBAAqB,KAAG,YA8F/D,CAAC"}
1
+ {"version":3,"file":"DashboardToolbar.d.ts","sourceRoot":"","sources":["../../../src/components/DashboardToolbar/DashboardToolbar.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AACrC,OAAO,EAAE,eAAe,EAAe,MAAM,eAAe,CAAC;AAW7D,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IACtC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,eAAO,MAAM,gBAAgB,UAAW,qBAAqB,KAAG,YAgG/D,CAAC"}
@@ -25,7 +25,7 @@ import { EditJsonButton } from '../EditJsonButton';
25
25
  import { SaveDashboardButton } from '../SaveDashboardButton';
26
26
  import { DashboardStickyToolbar } from '../DashboardStickyToolbar';
27
27
  export const DashboardToolbar = (props)=>{
28
- const { dashboardName, dashboardTitleComponent, initialVariableIsSticky, isReadonly, onEditButtonClick, onCancelButtonClick, onSave } = props;
28
+ const { dashboardName, dashboardTitleComponent, initialVariableIsSticky, isReadonly, isVariableEnabled, isDatasourceEnabled, onEditButtonClick, onCancelButtonClick, onSave } = props;
29
29
  const { isEditMode } = useEditMode();
30
30
  const isBiggerThanSm = useMediaQuery(useTheme().breakpoints.up('sm'));
31
31
  const isBiggerThanMd = useMediaQuery(useTheme().breakpoints.up('md'));
@@ -66,8 +66,8 @@ export const DashboardToolbar = (props)=>{
66
66
  ml: 1,
67
67
  whiteSpace: "nowrap",
68
68
  children: [
69
- /*#__PURE__*/ _jsx(EditVariablesButton, {}),
70
- /*#__PURE__*/ _jsx(EditDatasourcesButton, {}),
69
+ isVariableEnabled && /*#__PURE__*/ _jsx(EditVariablesButton, {}),
70
+ isDatasourceEnabled && /*#__PURE__*/ _jsx(EditDatasourcesButton, {}),
71
71
  /*#__PURE__*/ _jsx(AddPanelButton, {}),
72
72
  /*#__PURE__*/ _jsx(AddGroupButton, {})
73
73
  ]