@perses-dev/dashboards 0.10.0 → 0.11.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 (193) hide show
  1. package/dist/cjs/components/Dashboard.js +4 -5
  2. package/dist/cjs/components/DashboardToolbar.js +11 -5
  3. package/dist/cjs/components/GridLayout/GridItemContent.js +3 -11
  4. package/dist/cjs/components/GridLayout/GridLayout.js +8 -6
  5. package/dist/cjs/components/GridLayout/GridTitle.js +9 -11
  6. package/dist/cjs/components/Panel/DeletePanelDialog.js +12 -8
  7. package/dist/cjs/components/Panel/Panel.js +4 -13
  8. package/dist/cjs/components/Panel/Panel.test.js +4 -3
  9. package/dist/cjs/components/PanelDrawer/PanelDrawer.js +1 -1
  10. package/dist/cjs/components/PanelDrawer/PanelDrawer.test.js +3 -3
  11. package/dist/cjs/components/PanelDrawer/PanelEditorForm.js +21 -15
  12. package/dist/cjs/components/PanelDrawer/PanelPreview.js +9 -3
  13. package/dist/cjs/components/PanelGroupDialog/DeletePanelGroupDialog.js +13 -11
  14. package/dist/cjs/components/PanelGroupDialog/PanelGroupDialog.js +70 -111
  15. package/dist/cjs/components/PanelGroupDialog/PanelGroupDialog.test.js +22 -16
  16. package/dist/cjs/components/PanelGroupDialog/PanelGroupEditorForm.js +92 -0
  17. package/dist/cjs/components/PanelGroupDialog/index.js +29 -0
  18. package/dist/cjs/components/TimeRangeControls/TimeRangeControls.js +8 -11
  19. package/dist/cjs/components/TimeRangeControls/TimeRangeControls.test.js +20 -13
  20. package/dist/cjs/components/Variables/Variable.js +1 -0
  21. package/dist/cjs/components/Variables/VariableEditor.js +33 -0
  22. package/dist/cjs/components/Variables/VariableList.js +0 -1
  23. package/dist/cjs/components/index.js +1 -0
  24. package/dist/cjs/context/DashboardProvider/DashboardProvider.js +20 -8
  25. package/dist/cjs/context/DashboardProvider/dashboard-provider-api.js +122 -29
  26. package/dist/cjs/context/DashboardProvider/{panel-editing-slice.js → panel-editor-slice.js} +32 -13
  27. package/dist/cjs/context/DashboardProvider/panel-group-editor-slice.js +102 -0
  28. package/dist/cjs/context/DashboardProvider/panel-group-slice.js +187 -17
  29. package/dist/cjs/context/TimeRangeProvider.js +20 -44
  30. package/dist/cjs/context/index.js +1 -1
  31. package/dist/cjs/context/useDashboardSpec.js +61 -0
  32. package/dist/cjs/index.js +1 -0
  33. package/dist/cjs/test/render.js +25 -5
  34. package/dist/cjs/test/setup-tests.js +4 -1
  35. package/dist/cjs/test/testDashboard.js +11 -10
  36. package/dist/cjs/utils/index.js +28 -0
  37. package/dist/cjs/utils/time-range-params.js +145 -0
  38. package/dist/cjs/views/ViewDashboard/DashboardApp.js +2 -4
  39. package/dist/cjs/views/ViewDashboard/ViewDashboard.js +5 -22
  40. package/dist/cjs/views/ViewDashboard/tests/panelGroups.test.js +42 -93
  41. package/dist/components/Dashboard.js +5 -6
  42. package/dist/components/Dashboard.js.map +1 -1
  43. package/dist/components/DashboardToolbar.d.ts.map +1 -1
  44. package/dist/components/DashboardToolbar.js +13 -7
  45. package/dist/components/DashboardToolbar.js.map +1 -1
  46. package/dist/components/GridLayout/GridItemContent.d.ts +2 -4
  47. package/dist/components/GridLayout/GridItemContent.d.ts.map +1 -1
  48. package/dist/components/GridLayout/GridItemContent.js +4 -12
  49. package/dist/components/GridLayout/GridItemContent.js.map +1 -1
  50. package/dist/components/GridLayout/GridLayout.d.ts +2 -3
  51. package/dist/components/GridLayout/GridLayout.d.ts.map +1 -1
  52. package/dist/components/GridLayout/GridLayout.js +9 -7
  53. package/dist/components/GridLayout/GridLayout.js.map +1 -1
  54. package/dist/components/GridLayout/GridTitle.d.ts +2 -1
  55. package/dist/components/GridLayout/GridTitle.d.ts.map +1 -1
  56. package/dist/components/GridLayout/GridTitle.js +10 -12
  57. package/dist/components/GridLayout/GridTitle.js.map +1 -1
  58. package/dist/components/Panel/DeletePanelDialog.d.ts +1 -1
  59. package/dist/components/Panel/DeletePanelDialog.d.ts.map +1 -1
  60. package/dist/components/Panel/DeletePanelDialog.js +13 -9
  61. package/dist/components/Panel/DeletePanelDialog.js.map +1 -1
  62. package/dist/components/Panel/Panel.d.ts +2 -2
  63. package/dist/components/Panel/Panel.d.ts.map +1 -1
  64. package/dist/components/Panel/Panel.js +5 -14
  65. package/dist/components/Panel/Panel.js.map +1 -1
  66. package/dist/components/Panel/Panel.test.d.ts +1 -1
  67. package/dist/components/Panel/Panel.test.d.ts.map +1 -1
  68. package/dist/components/Panel/Panel.test.js +4 -3
  69. package/dist/components/Panel/Panel.test.js.map +1 -1
  70. package/dist/components/PanelDrawer/PanelDrawer.js +2 -2
  71. package/dist/components/PanelDrawer/PanelDrawer.js.map +1 -1
  72. package/dist/components/PanelDrawer/PanelDrawer.test.js +3 -3
  73. package/dist/components/PanelDrawer/PanelDrawer.test.js.map +1 -1
  74. package/dist/components/PanelDrawer/PanelEditorForm.d.ts +1 -1
  75. package/dist/components/PanelDrawer/PanelEditorForm.d.ts.map +1 -1
  76. package/dist/components/PanelDrawer/PanelEditorForm.js +22 -16
  77. package/dist/components/PanelDrawer/PanelEditorForm.js.map +1 -1
  78. package/dist/components/PanelDrawer/PanelPreview.d.ts +2 -2
  79. package/dist/components/PanelDrawer/PanelPreview.d.ts.map +1 -1
  80. package/dist/components/PanelDrawer/PanelPreview.js +9 -3
  81. package/dist/components/PanelDrawer/PanelPreview.js.map +1 -1
  82. package/dist/components/PanelGroupDialog/DeletePanelGroupDialog.d.ts +1 -2
  83. package/dist/components/PanelGroupDialog/DeletePanelGroupDialog.d.ts.map +1 -1
  84. package/dist/components/PanelGroupDialog/DeletePanelGroupDialog.js +13 -11
  85. package/dist/components/PanelGroupDialog/DeletePanelGroupDialog.js.map +1 -1
  86. package/dist/components/PanelGroupDialog/PanelGroupDialog.d.ts +4 -2
  87. package/dist/components/PanelGroupDialog/PanelGroupDialog.d.ts.map +1 -1
  88. package/dist/components/PanelGroupDialog/PanelGroupDialog.js +73 -112
  89. package/dist/components/PanelGroupDialog/PanelGroupDialog.js.map +1 -1
  90. package/dist/components/PanelGroupDialog/PanelGroupDialog.test.js +21 -15
  91. package/dist/components/PanelGroupDialog/PanelGroupDialog.test.js.map +1 -1
  92. package/dist/components/PanelGroupDialog/PanelGroupEditorForm.d.ts +12 -0
  93. package/dist/components/PanelGroupDialog/PanelGroupEditorForm.d.ts.map +1 -0
  94. package/dist/components/PanelGroupDialog/PanelGroupEditorForm.js +82 -0
  95. package/dist/components/PanelGroupDialog/PanelGroupEditorForm.js.map +1 -0
  96. package/dist/components/PanelGroupDialog/index.d.ts +3 -0
  97. package/dist/components/PanelGroupDialog/index.d.ts.map +1 -0
  98. package/dist/components/PanelGroupDialog/index.js +16 -0
  99. package/dist/components/PanelGroupDialog/index.js.map +1 -0
  100. package/dist/components/TimeRangeControls/TimeRangeControls.d.ts.map +1 -1
  101. package/dist/components/TimeRangeControls/TimeRangeControls.js +11 -14
  102. package/dist/components/TimeRangeControls/TimeRangeControls.js.map +1 -1
  103. package/dist/components/TimeRangeControls/TimeRangeControls.test.js +21 -14
  104. package/dist/components/TimeRangeControls/TimeRangeControls.test.js.map +1 -1
  105. package/dist/components/Variables/Variable.js +1 -0
  106. package/dist/components/Variables/Variable.js.map +1 -1
  107. package/dist/components/Variables/VariableEditor.d.ts.map +1 -1
  108. package/dist/components/Variables/VariableEditor.js +33 -0
  109. package/dist/components/Variables/VariableEditor.js.map +1 -1
  110. package/dist/components/Variables/VariableList.js +0 -1
  111. package/dist/components/Variables/VariableList.js.map +1 -1
  112. package/dist/components/index.d.ts +1 -0
  113. package/dist/components/index.d.ts.map +1 -1
  114. package/dist/components/index.js +1 -0
  115. package/dist/components/index.js.map +1 -1
  116. package/dist/context/DashboardProvider/DashboardProvider.d.ts +7 -5
  117. package/dist/context/DashboardProvider/DashboardProvider.d.ts.map +1 -1
  118. package/dist/context/DashboardProvider/DashboardProvider.js +19 -7
  119. package/dist/context/DashboardProvider/DashboardProvider.js.map +1 -1
  120. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts +64 -22
  121. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts.map +1 -1
  122. package/dist/context/DashboardProvider/dashboard-provider-api.js +133 -26
  123. package/dist/context/DashboardProvider/dashboard-provider-api.js.map +1 -1
  124. package/dist/context/DashboardProvider/index.d.ts +2 -0
  125. package/dist/context/DashboardProvider/index.d.ts.map +1 -1
  126. package/dist/context/DashboardProvider/index.js.map +1 -1
  127. package/dist/context/DashboardProvider/{panel-editing-slice.d.ts → panel-editor-slice.d.ts} +28 -13
  128. package/dist/context/DashboardProvider/panel-editor-slice.d.ts.map +1 -0
  129. package/dist/context/DashboardProvider/{panel-editing-slice.js → panel-editor-slice.js} +33 -14
  130. package/dist/context/DashboardProvider/panel-editor-slice.js.map +1 -0
  131. package/dist/context/DashboardProvider/panel-group-editor-slice.d.ts +40 -0
  132. package/dist/context/DashboardProvider/panel-group-editor-slice.d.ts.map +1 -0
  133. package/dist/context/DashboardProvider/panel-group-editor-slice.js +96 -0
  134. package/dist/context/DashboardProvider/panel-group-editor-slice.js.map +1 -0
  135. package/dist/context/DashboardProvider/panel-group-slice.d.ts +75 -10
  136. package/dist/context/DashboardProvider/panel-group-slice.d.ts.map +1 -1
  137. package/dist/context/DashboardProvider/panel-group-slice.js +189 -17
  138. package/dist/context/DashboardProvider/panel-group-slice.js.map +1 -1
  139. package/dist/context/TimeRangeProvider.d.ts +9 -2
  140. package/dist/context/TimeRangeProvider.d.ts.map +1 -1
  141. package/dist/context/TimeRangeProvider.js +15 -43
  142. package/dist/context/TimeRangeProvider.js.map +1 -1
  143. package/dist/context/index.d.ts +1 -1
  144. package/dist/context/index.d.ts.map +1 -1
  145. package/dist/context/index.js +1 -1
  146. package/dist/context/index.js.map +1 -1
  147. package/dist/context/useDashboardSpec.d.ts +3 -0
  148. package/dist/context/useDashboardSpec.d.ts.map +1 -0
  149. package/dist/context/useDashboardSpec.js +55 -0
  150. package/dist/context/useDashboardSpec.js.map +1 -0
  151. package/dist/index.d.ts +1 -0
  152. package/dist/index.d.ts.map +1 -1
  153. package/dist/index.js +1 -0
  154. package/dist/index.js.map +1 -1
  155. package/dist/test/render.d.ts +2 -1
  156. package/dist/test/render.d.ts.map +1 -1
  157. package/dist/test/render.js +25 -5
  158. package/dist/test/render.js.map +1 -1
  159. package/dist/test/setup-tests.d.ts.map +1 -1
  160. package/dist/test/setup-tests.js +4 -0
  161. package/dist/test/setup-tests.js.map +1 -1
  162. package/dist/test/testDashboard.d.ts.map +1 -1
  163. package/dist/test/testDashboard.js +11 -10
  164. package/dist/test/testDashboard.js.map +1 -1
  165. package/dist/utils/index.d.ts +2 -0
  166. package/dist/utils/index.d.ts.map +1 -0
  167. package/dist/utils/index.js +15 -0
  168. package/dist/utils/index.js.map +1 -0
  169. package/dist/utils/time-range-params.d.ts +25 -0
  170. package/dist/utils/time-range-params.d.ts.map +1 -0
  171. package/dist/utils/time-range-params.js +137 -0
  172. package/dist/utils/time-range-params.js.map +1 -0
  173. package/dist/views/ViewDashboard/DashboardApp.d.ts.map +1 -1
  174. package/dist/views/ViewDashboard/DashboardApp.js +1 -3
  175. package/dist/views/ViewDashboard/DashboardApp.js.map +1 -1
  176. package/dist/views/ViewDashboard/ViewDashboard.d.ts.map +1 -1
  177. package/dist/views/ViewDashboard/ViewDashboard.js +5 -22
  178. package/dist/views/ViewDashboard/ViewDashboard.js.map +1 -1
  179. package/dist/views/ViewDashboard/tests/panelGroups.test.js +45 -96
  180. package/dist/views/ViewDashboard/tests/panelGroups.test.js.map +1 -1
  181. package/package.json +5 -4
  182. package/dist/cjs/context/DashboardProvider/layout-slice.js +0 -200
  183. package/dist/cjs/context/QueryStringProvider.js +0 -89
  184. package/dist/context/DashboardProvider/layout-slice.d.ts +0 -57
  185. package/dist/context/DashboardProvider/layout-slice.d.ts.map +0 -1
  186. package/dist/context/DashboardProvider/layout-slice.js +0 -196
  187. package/dist/context/DashboardProvider/layout-slice.js.map +0 -1
  188. package/dist/context/DashboardProvider/panel-editing-slice.d.ts.map +0 -1
  189. package/dist/context/DashboardProvider/panel-editing-slice.js.map +0 -1
  190. package/dist/context/QueryStringProvider.d.ts +0 -13
  191. package/dist/context/QueryStringProvider.d.ts.map +0 -1
  192. package/dist/context/QueryStringProvider.js +0 -40
  193. package/dist/context/QueryStringProvider.js.map +0 -1
@@ -16,9 +16,9 @@ Object.defineProperty(exports, "__esModule", {
16
16
  });
17
17
  _exportStar(require("./DashboardProvider"), exports);
18
18
  _exportStar(require("./DatasourceStoreProvider"), exports);
19
- _exportStar(require("./QueryStringProvider"), exports);
20
19
  _exportStar(require("./TemplateVariableProvider"), exports);
21
20
  _exportStar(require("./TimeRangeProvider"), exports);
21
+ _exportStar(require("./useDashboardSpec"), exports);
22
22
  function _exportStar(from, to) {
23
23
  Object.keys(from).forEach(function(k) {
24
24
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) Object.defineProperty(to, k, {
@@ -0,0 +1,61 @@
1
+ // Copyright 2022 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ Object.defineProperty(exports, "useDashboardSpec", {
18
+ enumerable: true,
19
+ get: ()=>useDashboardSpec
20
+ });
21
+ const _dashboardProvider = require("./DashboardProvider");
22
+ const _templateVariableProvider = require("./TemplateVariableProvider");
23
+ function useDashboardSpec() {
24
+ const { panels , panelGroups , defaultTimeRange } = (0, _dashboardProvider.useDashboardStore)(({ panels , panelGroups , defaultTimeRange })=>({
25
+ panels,
26
+ panelGroups,
27
+ defaultTimeRange
28
+ }));
29
+ const variables = (0, _templateVariableProvider.useTemplateVariableDefinitions)();
30
+ const layouts = convertPanelGroupsToLayouts(panelGroups);
31
+ return {
32
+ panels,
33
+ layouts,
34
+ variables,
35
+ duration: defaultTimeRange.pastDuration
36
+ };
37
+ }
38
+ function convertPanelGroupsToLayouts(panelGroups) {
39
+ const layouts = [];
40
+ Object.values(panelGroups).forEach((group)=>{
41
+ const { title , isCollapsed , items } = group;
42
+ let display = undefined;
43
+ if (title) {
44
+ display = {
45
+ title,
46
+ collapse: {
47
+ open: !isCollapsed
48
+ }
49
+ };
50
+ }
51
+ const layout = {
52
+ kind: 'Grid',
53
+ spec: {
54
+ display,
55
+ items
56
+ }
57
+ };
58
+ layouts.push(layout);
59
+ });
60
+ return layouts;
61
+ }
package/dist/cjs/index.js CHANGED
@@ -16,6 +16,7 @@ Object.defineProperty(exports, "__esModule", {
16
16
  });
17
17
  _exportStar(require("./components"), exports);
18
18
  _exportStar(require("./context"), exports);
19
+ _exportStar(require("./utils"), exports);
19
20
  _exportStar(require("./views"), exports);
20
21
  function _exportStar(from, to) {
21
22
  Object.keys(from).forEach(function(k) {
@@ -20,8 +20,13 @@ Object.defineProperty(exports, "renderWithContext", {
20
20
  });
21
21
  const _jsxRuntime = require("react/jsx-runtime");
22
22
  const _react = require("@testing-library/react");
23
+ const _reactRouterDom = require("react-router-dom");
24
+ const _history = require("history");
25
+ const _useQueryParams = require("use-query-params");
26
+ const _reactRouter6 = require("use-query-params/adapters/react-router-6");
23
27
  const _reactQuery = require("@tanstack/react-query");
24
- function renderWithContext(ui, options) {
28
+ const _components = require("@perses-dev/components");
29
+ function renderWithContext(ui, options, history) {
25
30
  // Create a new QueryClient for each test to avoid caching issues
26
31
  const queryClient = new _reactQuery.QueryClient({
27
32
  defaultOptions: {
@@ -31,8 +36,23 @@ function renderWithContext(ui, options) {
31
36
  }
32
37
  }
33
38
  });
34
- return (0, _react.render)(/*#__PURE__*/ (0, _jsxRuntime.jsx)(_reactQuery.QueryClientProvider, {
35
- client: queryClient,
36
- children: ui
37
- }), options);
39
+ const BaseRender = ()=>{
40
+ const HistoryRouter = _reactRouterDom.unstable_HistoryRouter;
41
+ history = history !== null && history !== void 0 ? history : (0, _history.createMemoryHistory)();
42
+ return /*#__PURE__*/ (0, _jsxRuntime.jsx)(HistoryRouter, {
43
+ history: history,
44
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_reactQuery.QueryClientProvider, {
45
+ client: queryClient,
46
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_useQueryParams.QueryParamProvider, {
47
+ adapter: _reactRouter6.ReactRouter6Adapter,
48
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components.ChartsThemeProvider, {
49
+ themeName: "perses",
50
+ chartsTheme: _components.testChartsTheme,
51
+ children: ui
52
+ })
53
+ })
54
+ })
55
+ });
56
+ };
57
+ return (0, _react.render)(/*#__PURE__*/ (0, _jsxRuntime.jsx)(BaseRender, {}), options);
38
58
  }
@@ -10,11 +10,14 @@
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
- // Add testing library assertions
14
13
  "use strict";
15
14
  Object.defineProperty(exports, "__esModule", {
16
15
  value: true
17
16
  });
17
+ const _reactIntersectionObserver = require("react-intersection-observer");
18
18
  require("@testing-library/jest-dom/extend-expect");
19
19
  // Always mock e-charts during tests since we don't have a proper canvas in jsdom
20
20
  jest.mock('echarts/core');
21
+ // Tell react-intersection-observer that everything should be considered in-view for tests (see package documentation
22
+ // for other options)
23
+ (0, _reactIntersectionObserver.defaultFallbackInView)(true);
@@ -28,7 +28,7 @@ const testDashboard = {
28
28
  version: 0
29
29
  },
30
30
  spec: {
31
- duration: '24h',
31
+ duration: '5m',
32
32
  variables: [
33
33
  {
34
34
  kind: 'TextVariable',
@@ -144,6 +144,7 @@ const testDashboard = {
144
144
  }
145
145
  }
146
146
  },
147
+ // This panel is referenced in more than one layout below
147
148
  diskIO: {
148
149
  kind: 'Panel',
149
150
  spec: {
@@ -242,6 +243,15 @@ const testDashboard = {
242
243
  kind: 'Grid',
243
244
  spec: {
244
245
  items: [
246
+ {
247
+ x: 0,
248
+ y: 0,
249
+ width: 6,
250
+ height: 2,
251
+ content: {
252
+ $ref: '#/spec/panels/diskIO'
253
+ }
254
+ },
245
255
  {
246
256
  x: 8,
247
257
  y: 0,
@@ -265,15 +275,6 @@ const testDashboard = {
265
275
  }
266
276
  },
267
277
  items: [
268
- {
269
- x: 0,
270
- y: 0,
271
- width: 6,
272
- height: 2,
273
- content: {
274
- $ref: '#/spec/panels/diskIO'
275
- }
276
- },
277
278
  {
278
279
  x: 18,
279
280
  y: 0,
@@ -0,0 +1,28 @@
1
+ // Copyright 2022 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ _exportStar(require("./time-range-params"), exports);
18
+ function _exportStar(from, to) {
19
+ Object.keys(from).forEach(function(k) {
20
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) Object.defineProperty(to, k, {
21
+ enumerable: true,
22
+ get: function() {
23
+ return from[k];
24
+ }
25
+ });
26
+ });
27
+ return from;
28
+ }
@@ -0,0 +1,145 @@
1
+ // Copyright 2022 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ 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
+ encodeTimeRangeValue: ()=>encodeTimeRangeValue,
25
+ decodeTimeRangeValue: ()=>decodeTimeRangeValue,
26
+ TimeRangeParam: ()=>TimeRangeParam,
27
+ timeRangeQueryConfig: ()=>timeRangeQueryConfig,
28
+ useInitialTimeRange: ()=>useInitialTimeRange,
29
+ useSetTimeRangeParams: ()=>useSetTimeRangeParams
30
+ });
31
+ const _react = require("react");
32
+ const _useQueryParams = require("use-query-params");
33
+ const _dateFns = require("date-fns");
34
+ const _core = require("@perses-dev/core");
35
+ /* Interprets an encoded string and returns either the string or null/undefined if not available */ function getEncodedValue(input, allowEmptyString) {
36
+ if (input == null) {
37
+ return input;
38
+ }
39
+ // '' or []
40
+ if (input.length === 0 && (!allowEmptyString || allowEmptyString && input !== '')) {
41
+ return null;
42
+ }
43
+ const str = input instanceof Array ? input[0] : input;
44
+ if (str == null) {
45
+ return str;
46
+ }
47
+ if (!allowEmptyString && str === '') {
48
+ return null;
49
+ }
50
+ return str;
51
+ }
52
+ function encodeTimeRangeValue(timeOptionValue) {
53
+ if (!timeOptionValue) {
54
+ return timeOptionValue;
55
+ }
56
+ if (typeof timeOptionValue === 'string') {
57
+ if ((0, _core.isDurationString)(timeOptionValue)) {
58
+ return timeOptionValue;
59
+ }
60
+ }
61
+ return ((0, _dateFns.getUnixTime)(timeOptionValue) * 1000).toString();
62
+ }
63
+ function decodeTimeRangeValue(input) {
64
+ const paramString = getEncodedValue(input);
65
+ if (paramString == null) return paramString;
66
+ return (0, _core.isDurationString)(paramString) ? paramString : new Date(Number(paramString));
67
+ }
68
+ const TimeRangeParam = {
69
+ encode: encodeTimeRangeValue,
70
+ decode: decodeTimeRangeValue,
71
+ equals: (valueA, valueB)=>{
72
+ if (valueA === valueB) return true;
73
+ if (valueA == null || valueB == null) return valueA === valueB;
74
+ return valueA.valueOf() === valueB.valueOf();
75
+ }
76
+ };
77
+ const timeRangeQueryConfig = {
78
+ start: TimeRangeParam,
79
+ end: TimeRangeParam
80
+ };
81
+ function useInitialTimeRange(dashboardDuration) {
82
+ const [query] = (0, _useQueryParams.useQueryParams)(timeRangeQueryConfig);
83
+ const { start , end } = query;
84
+ return (0, _react.useMemo)(()=>{
85
+ let initialTimeRange = {
86
+ pastDuration: dashboardDuration
87
+ };
88
+ if (!start) {
89
+ return initialTimeRange;
90
+ }
91
+ const startStr = start.toString();
92
+ if ((0, _core.isDurationString)(startStr)) {
93
+ initialTimeRange = {
94
+ pastDuration: startStr
95
+ };
96
+ } else if ((0, _dateFns.isDate)(start) && (0, _dateFns.isDate)(end)) {
97
+ initialTimeRange = {
98
+ start: start,
99
+ end: end
100
+ };
101
+ }
102
+ return initialTimeRange;
103
+ }, [
104
+ start,
105
+ end,
106
+ dashboardDuration
107
+ ]);
108
+ }
109
+ function useSetTimeRangeParams(initialTimeRange, paramsEnabled = true) {
110
+ const [query, setQuery] = (0, _useQueryParams.useQueryParams)(timeRangeQueryConfig);
111
+ // fallback when app does not want query string as source of truth
112
+ const [timeRangeState, setTimeRangeState] = (0, _react.useState)(initialTimeRange);
113
+ const { start } = query;
114
+ // set start param on page load if empty
115
+ if (paramsEnabled && !start) {
116
+ if ((0, _core.isRelativeTimeRange)(initialTimeRange)) {
117
+ setQuery({
118
+ start: initialTimeRange.pastDuration,
119
+ end: undefined
120
+ });
121
+ }
122
+ }
123
+ const setTimeRange = (0, _react.useCallback)((value)=>{
124
+ if ((0, _core.isRelativeTimeRange)(value)) {
125
+ setQuery({
126
+ start: value.pastDuration,
127
+ end: undefined
128
+ });
129
+ } else {
130
+ setQuery(value);
131
+ }
132
+ }, [
133
+ setQuery
134
+ ]);
135
+ if (!paramsEnabled) {
136
+ return {
137
+ timeRange: timeRangeState,
138
+ setTimeRange: setTimeRangeState
139
+ };
140
+ }
141
+ return {
142
+ timeRange: initialTimeRange,
143
+ setTimeRange: setTimeRange
144
+ };
145
+ }
@@ -22,9 +22,7 @@ const _jsxRuntime = require("react/jsx-runtime");
22
22
  const _material = require("@mui/material");
23
23
  const _components = require("@perses-dev/components");
24
24
  const _components1 = require("../../components");
25
- const _panelGroupDialog = /*#__PURE__*/ _interopRequireDefault(require("../../components/PanelGroupDialog/PanelGroupDialog"));
26
25
  const _dashboardToolbar = require("../../components/DashboardToolbar");
27
- const _deletePanelGroupDialog = /*#__PURE__*/ _interopRequireDefault(require("../../components/PanelGroupDialog/DeletePanelGroupDialog"));
28
26
  const _deletePanelDialog = /*#__PURE__*/ _interopRequireDefault(require("../../components/Panel/DeletePanelDialog"));
29
27
  function _interopRequireDefault(obj) {
30
28
  return obj && obj.__esModule ? obj : {
@@ -56,8 +54,8 @@ const DashboardApp = (props)=>{
56
54
  children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components1.Dashboard, {})
57
55
  }),
58
56
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components1.PanelDrawer, {}),
59
- /*#__PURE__*/ (0, _jsxRuntime.jsx)(_panelGroupDialog.default, {}),
60
- /*#__PURE__*/ (0, _jsxRuntime.jsx)(_deletePanelGroupDialog.default, {}),
57
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components1.PanelGroupDialog, {}),
58
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components1.DeletePanelGroupDialog, {}),
61
59
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_deletePanelDialog.default, {})
62
60
  ]
63
61
  })
@@ -19,36 +19,18 @@ Object.defineProperty(exports, "ViewDashboard", {
19
19
  get: ()=>ViewDashboard
20
20
  });
21
21
  const _jsxRuntime = require("react/jsx-runtime");
22
- const _react = require("react");
23
22
  const _material = require("@mui/material");
24
- const _core = require("@perses-dev/core");
25
- const _pluginSystem = require("@perses-dev/plugin-system");
26
23
  const _components = require("@perses-dev/components");
27
24
  const _context = require("../../context");
25
+ const _utils = require("../../utils");
28
26
  const _dashboardApp = require("./DashboardApp");
29
27
  function ViewDashboard(props) {
30
28
  const { dashboardResource , datasourceApi , sx , ...others } = props;
31
29
  const { spec } = dashboardResource;
32
- const { queryString , setQueryString } = (0, _pluginSystem.useQueryString)();
33
30
  var _duration;
34
31
  const dashboardDuration = (_duration = spec.duration) !== null && _duration !== void 0 ? _duration : '1h';
35
- const defaultTimeRange = (0, _core.getDefaultTimeRange)(dashboardDuration, queryString);
36
- // TODO: add reusable sync query string or no-op util
37
- (0, _react.useEffect)(()=>{
38
- const currentParams = Object.fromEntries([
39
- ...queryString
40
- ]);
41
- // if app does not provide query string implementation, setTimeRange is used instead
42
- if (!currentParams.start && setQueryString) {
43
- // default to duration in dashboard definition if start param is not already set
44
- queryString.set('start', dashboardDuration);
45
- setQueryString(queryString);
46
- }
47
- }, [
48
- dashboardDuration,
49
- queryString,
50
- setQueryString
51
- ]);
32
+ const initialTimeRange = (0, _utils.useInitialTimeRange)(dashboardDuration);
33
+ const { timeRange , setTimeRange } = (0, _utils.useSetTimeRangeParams)(initialTimeRange, true);
52
34
  return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_context.DatasourceStoreProvider, {
53
35
  dashboardResource: dashboardResource,
54
36
  datasourceApi: datasourceApi,
@@ -57,7 +39,8 @@ function ViewDashboard(props) {
57
39
  dashboardSpec: spec
58
40
  },
59
41
  children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_context.TimeRangeProvider, {
60
- initialTimeRange: defaultTimeRange,
42
+ timeRange: timeRange,
43
+ setTimeRange: setTimeRange,
61
44
  children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_context.TemplateVariableProvider, {
62
45
  initialVariableDefinitions: spec.variables,
63
46
  children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Box, {
@@ -19,7 +19,6 @@ const _react = require("@testing-library/react");
19
19
  const _userEvent = /*#__PURE__*/ _interopRequireDefault(require("@testing-library/user-event"));
20
20
  const _context = require("../../../context");
21
21
  const _test = require("../../../test");
22
- const _testDashboard = /*#__PURE__*/ _interopRequireDefault(require("../../../test/testDashboard"));
23
22
  const _dashboardApp = require("../DashboardApp");
24
23
  function _interopRequireDefault(obj) {
25
24
  return obj && obj.__esModule ? obj : {
@@ -28,47 +27,25 @@ function _interopRequireDefault(obj) {
28
27
  }
29
28
  describe('Panel Groups', ()=>{
30
29
  const renderDashboard = ()=>{
31
- const { store , DashboardProviderSpy } = (0, _test.createDashboardProviderSpy)();
32
- (0, _test.renderWithContext)(/*#__PURE__*/ (0, _jsxRuntime.jsx)(_context.QueryStringProvider, {
33
- queryString: new URLSearchParams('https://localhost:3000/'),
34
- children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_context.TimeRangeProvider, {
35
- initialTimeRange: {
36
- pastDuration: '30m'
37
- },
38
- children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_context.TemplateVariableProvider, {
39
- children: /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_context.DashboardProvider, {
40
- initialState: {
41
- dashboardSpec: (0, _test.getTestDashboard)().spec,
42
- isEditMode: true
43
- },
44
- children: [
45
- /*#__PURE__*/ (0, _jsxRuntime.jsx)(DashboardProviderSpy, {}),
46
- /*#__PURE__*/ (0, _jsxRuntime.jsx)(_dashboardApp.DashboardApp, {
47
- dashboardResource: (0, _test.getTestDashboard)()
48
- })
49
- ]
30
+ (0, _test.renderWithContext)(/*#__PURE__*/ (0, _jsxRuntime.jsx)(_context.TimeRangeProvider, {
31
+ timeRange: {
32
+ pastDuration: '30m'
33
+ },
34
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_context.TemplateVariableProvider, {
35
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_context.DashboardProvider, {
36
+ initialState: {
37
+ dashboardSpec: (0, _test.getTestDashboard)().spec,
38
+ isEditMode: true
39
+ },
40
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_dashboardApp.DashboardApp, {
41
+ dashboardResource: (0, _test.getTestDashboard)()
50
42
  })
51
43
  })
52
44
  })
53
45
  }));
54
- const { value: storeApi } = store;
55
- if (storeApi === undefined) {
56
- throw new Error('Expected dashboard store to be set after initial render');
57
- }
58
- return storeApi;
59
46
  };
60
- beforeEach(()=>{
61
- const mockIntersectionObserver = jest.fn();
62
- mockIntersectionObserver.mockReturnValue({
63
- observe: ()=>null,
64
- unobserve: ()=>null,
65
- disconnect: ()=>null
66
- });
67
- window.IntersectionObserver = mockIntersectionObserver;
68
- });
69
47
  it('should delete panel', ()=>{
70
- var ref;
71
- const storeApi = renderDashboard();
48
+ renderDashboard();
72
49
  const panel = _react.screen.getByText('CPU');
73
50
  _userEvent.default.hover(panel);
74
51
  const deletePanelButton = _react.screen.getByLabelText('delete panel');
@@ -76,37 +53,28 @@ describe('Panel Groups', ()=>{
76
53
  _react.screen.getByText('Delete Panel');
77
54
  const deleteButton = _react.screen.getByText('Delete');
78
55
  _userEvent.default.click(deleteButton);
79
- const layouts = storeApi.getState().layouts;
80
- const deletedPanel = _testDashboard.default.spec.panels['cpu'];
81
- expect((ref = layouts[0]) === null || ref === void 0 ? void 0 : ref.items).toEqual(expect.not.objectContaining(deletedPanel));
82
- const panels = storeApi.getState().panels;
83
- // should remove cpu from state.panels since it's not used anymore
84
- expect(panels).toEqual(expect.not.objectContaining({
85
- cpu: _testDashboard.default.spec.panels['cpu']
86
- }));
56
+ // The panel should disappear
57
+ const deletedPanel = _react.screen.queryByText('CPU');
58
+ expect(deletedPanel).not.toBeInTheDocument();
87
59
  });
88
- it('should only delete panel from panel group if panel is referenced more than once', ()=>{
89
- var ref;
90
- const storeApi = renderDashboard();
91
- const panel = _react.screen.getByText('Disk I/O Utilization');
60
+ it('should only delete panel from panel group if panel is not referenced more than once', ()=>{
61
+ renderDashboard();
62
+ const panels = _react.screen.getAllByText('Disk I/O Utilization');
63
+ expect(panels).toHaveLength(2);
64
+ const panel = panels[0];
65
+ if (panel === undefined) throw new Error('Missing panel');
92
66
  _userEvent.default.hover(panel);
93
67
  const deletePanelButton = _react.screen.getByLabelText('delete panel');
94
68
  _userEvent.default.click(deletePanelButton);
95
69
  _react.screen.getByText('Delete Panel');
96
70
  const deleteButton = _react.screen.getByText('Delete');
97
71
  _userEvent.default.click(deleteButton);
98
- const layouts = storeApi.getState().layouts;
99
- const deletedPanel = _testDashboard.default.spec.panels['diskIO'];
100
- expect((ref = layouts[0]) === null || ref === void 0 ? void 0 : ref.items).toEqual(expect.not.objectContaining(deletedPanel));
101
- const panels = storeApi.getState().panels;
102
- // should NOT remove diskIO from state.panels since it's used in another panel group
103
- expect(panels).toEqual(expect.objectContaining({
104
- diskIO: _testDashboard.default.spec.panels['diskIO']
105
- }));
72
+ // The deleted panel should still be on screen in the other group
73
+ const deletedPanel = _react.screen.queryByText('Disk I/O Utilization');
74
+ expect(deletedPanel).toBeInTheDocument();
106
75
  });
107
76
  it('should swap panels', ()=>{
108
- var ref, ref1, ref2;
109
- const storeApi = renderDashboard();
77
+ renderDashboard();
110
78
  // should move panel down
111
79
  const group1 = _react.screen.getByText('CPU Stats');
112
80
  _userEvent.default.hover(group1);
@@ -118,13 +86,14 @@ describe('Panel Groups', ()=>{
118
86
  _userEvent.default.hover(group2);
119
87
  const moveGroupUpBtn = _react.screen.getByLabelText('move group up');
120
88
  _userEvent.default.click(moveGroupUpBtn);
121
- const layouts = storeApi.getState().layouts;
122
- expect((ref = layouts[0]) === null || ref === void 0 ? void 0 : ref.title).toBe(undefined);
123
- expect((ref1 = layouts[1]) === null || ref1 === void 0 ? void 0 : ref1.title).toBe('Disk Stats');
124
- expect((ref2 = layouts[2]) === null || ref2 === void 0 ? void 0 : ref2.title).toBe('CPU Stats');
125
- });
89
+ /* TODO: Figure out how to test this visually without coupling to the store
90
+ const layouts = storeApi.getState().layouts;
91
+ expect(layouts[0]?.title).toBe(undefined);
92
+ expect(layouts[1]?.title).toBe('Disk Stats');
93
+ expect(layouts[2]?.title).toBe('CPU Stats');
94
+ */ });
126
95
  it('should delete a panel group', ()=>{
127
- const storeApi = renderDashboard();
96
+ renderDashboard();
128
97
  const group = _react.screen.getByText('CPU Stats');
129
98
  _userEvent.default.hover(group);
130
99
  const deleteGroupIcon = _react.screen.getByLabelText('delete group');
@@ -132,34 +101,14 @@ describe('Panel Groups', ()=>{
132
101
  _react.screen.getByText('Delete Panel Group');
133
102
  const deleteButton = _react.screen.getByText('Delete');
134
103
  _userEvent.default.click(deleteButton);
135
- // should remove group from state.layouts
136
- const layouts = storeApi.getState().layouts;
137
- expect(layouts).toHaveLength(2);
138
- const deletedLayout = {
139
- id: 0,
140
- title: 'CPU Stats',
141
- isCollapsed: false,
142
- items: [
143
- {
144
- x: 0,
145
- y: 0,
146
- width: 12,
147
- height: 4,
148
- content: {
149
- $ref: '#/spec/panels/cpu'
150
- }
151
- }
152
- ]
153
- };
154
- expect(layouts).toEqual(expect.not.objectContaining(deletedLayout));
155
- const panels = storeApi.getState().panels;
156
- // should remove cpu from state.panels since it's not used anymore
157
- expect(panels).toEqual(expect.not.objectContaining({
158
- cpu: _testDashboard.default.spec.panels['cpu']
159
- }));
160
- // should not remove diskIO from state.panels since it's still used in another group
161
- expect(panels).toEqual(expect.objectContaining({
162
- diskIO: _testDashboard.default.spec.panels['diskIO']
163
- }));
104
+ // should remove group
105
+ const deletedGroup = _react.screen.queryByText('CPU Stats');
106
+ expect(deletedGroup).not.toBeInTheDocument();
107
+ // CPU panel should be completely gone since it wasn't in any other group
108
+ let panel = _react.screen.queryByText('CPU');
109
+ expect(panel).not.toBeInTheDocument();
110
+ // A DiskIO panel should still be present in the other group that wasn't deleted
111
+ panel = _react.screen.queryByText('Disk I/O Utilization');
112
+ expect(panel).toBeInTheDocument();
164
113
  });
165
114
  });
@@ -13,20 +13,19 @@
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
14
14
  import { Box } from '@mui/material';
15
15
  import { ErrorBoundary, ErrorAlert } from '@perses-dev/components';
16
- import { useLayouts } from '../context';
16
+ import { usePanelGroupIds } from '../context';
17
17
  import { GridLayout } from './GridLayout';
18
18
  /**
19
19
  * Renders a Dashboard for the provided Dashboard spec.
20
20
  */ export function Dashboard(props) {
21
- const { layouts } = useLayouts();
21
+ const panelGroupIds = usePanelGroupIds();
22
22
  return /*#__PURE__*/ _jsx(Box, {
23
23
  ...props,
24
24
  children: /*#__PURE__*/ _jsx(ErrorBoundary, {
25
25
  FallbackComponent: ErrorAlert,
26
- children: layouts.map((layout, groupIndex)=>/*#__PURE__*/ _jsx(GridLayout, {
27
- groupIndex: groupIndex,
28
- groupDefinition: layout
29
- }, layout.id))
26
+ children: panelGroupIds.map((panelGroupId)=>/*#__PURE__*/ _jsx(GridLayout, {
27
+ panelGroupId: panelGroupId
28
+ }, panelGroupId))
30
29
  })
31
30
  });
32
31
  }