@perses-dev/dashboards 0.10.0 → 0.12.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 (225) hide show
  1. package/dist/cjs/components/Dashboard.js +4 -5
  2. package/dist/cjs/components/DashboardToolbar.js +18 -5
  3. package/dist/cjs/components/GridLayout/GridItemContent.js +3 -11
  4. package/dist/cjs/components/GridLayout/GridLayout.js +20 -20
  5. package/dist/cjs/components/GridLayout/GridTitle.js +9 -11
  6. package/dist/cjs/components/Panel/DeletePanelDialog.js +12 -10
  7. package/dist/cjs/components/Panel/Panel.js +12 -22
  8. package/dist/cjs/components/Panel/Panel.test.js +5 -3
  9. package/dist/cjs/components/Panel/index.js +1 -0
  10. package/dist/cjs/components/PanelDrawer/PanelDrawer.js +1 -1
  11. package/dist/cjs/components/PanelDrawer/PanelDrawer.test.js +13 -5
  12. package/dist/cjs/components/PanelDrawer/PanelEditorForm.js +21 -15
  13. package/dist/cjs/components/PanelDrawer/PanelPreview.js +9 -3
  14. package/dist/cjs/components/PanelGroupDialog/DeletePanelGroupDialog.js +13 -11
  15. package/dist/cjs/components/PanelGroupDialog/PanelGroupDialog.js +70 -111
  16. package/dist/cjs/components/PanelGroupDialog/PanelGroupDialog.test.js +22 -16
  17. package/dist/cjs/components/PanelGroupDialog/PanelGroupEditorForm.js +92 -0
  18. package/dist/cjs/components/PanelGroupDialog/index.js +29 -0
  19. package/dist/cjs/components/TimeRangeControls/TimeRangeControls.js +8 -11
  20. package/dist/cjs/components/TimeRangeControls/TimeRangeControls.test.js +20 -13
  21. package/dist/cjs/components/Variables/Variable.js +1 -0
  22. package/dist/cjs/components/Variables/VariableEditor.js +40 -6
  23. package/dist/cjs/components/Variables/VariableEditorForm/VariableEditorForm.js +9 -5
  24. package/dist/cjs/components/Variables/VariableList.js +0 -1
  25. package/dist/cjs/components/index.js +1 -0
  26. package/dist/cjs/context/DashboardProvider/DashboardProvider.js +26 -8
  27. package/dist/cjs/context/DashboardProvider/common.js +10 -0
  28. package/dist/cjs/context/DashboardProvider/dashboard-provider-api.js +122 -29
  29. package/dist/cjs/context/DashboardProvider/delete-panel-group-slice.js +70 -0
  30. package/dist/cjs/context/DashboardProvider/delete-panel-slice.js +85 -0
  31. package/dist/cjs/context/DashboardProvider/panel-editor-slice.js +182 -0
  32. package/dist/cjs/context/DashboardProvider/panel-group-editor-slice.js +89 -0
  33. package/dist/cjs/context/DashboardProvider/panel-group-slice.js +83 -18
  34. package/dist/cjs/context/DashboardProvider/panel-slice.js +36 -0
  35. package/dist/cjs/context/TimeRangeProvider.js +20 -44
  36. package/dist/cjs/context/index.js +1 -1
  37. package/dist/cjs/context/useDashboardSpec.js +90 -0
  38. package/dist/cjs/index.js +1 -0
  39. package/dist/cjs/test/render.js +25 -5
  40. package/dist/cjs/test/setup-tests.js +4 -1
  41. package/dist/cjs/test/testDashboard.js +11 -10
  42. package/dist/cjs/utils/index.js +28 -0
  43. package/dist/cjs/utils/time-range-params.js +151 -0
  44. package/dist/cjs/views/ViewDashboard/DashboardApp.js +2 -5
  45. package/dist/cjs/views/ViewDashboard/ViewDashboard.js +5 -22
  46. package/dist/cjs/views/ViewDashboard/tests/panelGroups.test.js +42 -93
  47. package/dist/components/Dashboard.js +5 -6
  48. package/dist/components/Dashboard.js.map +1 -1
  49. package/dist/components/DashboardToolbar.d.ts.map +1 -1
  50. package/dist/components/DashboardToolbar.js +20 -7
  51. package/dist/components/DashboardToolbar.js.map +1 -1
  52. package/dist/components/GridLayout/GridItemContent.d.ts +2 -4
  53. package/dist/components/GridLayout/GridItemContent.d.ts.map +1 -1
  54. package/dist/components/GridLayout/GridItemContent.js +4 -12
  55. package/dist/components/GridLayout/GridItemContent.js.map +1 -1
  56. package/dist/components/GridLayout/GridLayout.d.ts +2 -3
  57. package/dist/components/GridLayout/GridLayout.d.ts.map +1 -1
  58. package/dist/components/GridLayout/GridLayout.js +22 -22
  59. package/dist/components/GridLayout/GridLayout.js.map +1 -1
  60. package/dist/components/GridLayout/GridTitle.d.ts +2 -1
  61. package/dist/components/GridLayout/GridTitle.d.ts.map +1 -1
  62. package/dist/components/GridLayout/GridTitle.js +10 -12
  63. package/dist/components/GridLayout/GridTitle.js.map +1 -1
  64. package/dist/components/Panel/DeletePanelDialog.d.ts +0 -1
  65. package/dist/components/Panel/DeletePanelDialog.d.ts.map +1 -1
  66. package/dist/components/Panel/DeletePanelDialog.js +13 -11
  67. package/dist/components/Panel/DeletePanelDialog.js.map +1 -1
  68. package/dist/components/Panel/Panel.d.ts +2 -2
  69. package/dist/components/Panel/Panel.d.ts.map +1 -1
  70. package/dist/components/Panel/Panel.js +12 -22
  71. package/dist/components/Panel/Panel.js.map +1 -1
  72. package/dist/components/Panel/Panel.test.d.ts +1 -1
  73. package/dist/components/Panel/Panel.test.d.ts.map +1 -1
  74. package/dist/components/Panel/Panel.test.js +5 -3
  75. package/dist/components/Panel/Panel.test.js.map +1 -1
  76. package/dist/components/Panel/index.d.ts +1 -0
  77. package/dist/components/Panel/index.d.ts.map +1 -1
  78. package/dist/components/Panel/index.js +1 -0
  79. package/dist/components/Panel/index.js.map +1 -1
  80. package/dist/components/PanelDrawer/PanelDrawer.js +2 -2
  81. package/dist/components/PanelDrawer/PanelDrawer.js.map +1 -1
  82. package/dist/components/PanelDrawer/PanelDrawer.test.js +13 -5
  83. package/dist/components/PanelDrawer/PanelDrawer.test.js.map +1 -1
  84. package/dist/components/PanelDrawer/PanelEditorForm.d.ts +1 -1
  85. package/dist/components/PanelDrawer/PanelEditorForm.d.ts.map +1 -1
  86. package/dist/components/PanelDrawer/PanelEditorForm.js +22 -16
  87. package/dist/components/PanelDrawer/PanelEditorForm.js.map +1 -1
  88. package/dist/components/PanelDrawer/PanelPreview.d.ts +2 -2
  89. package/dist/components/PanelDrawer/PanelPreview.d.ts.map +1 -1
  90. package/dist/components/PanelDrawer/PanelPreview.js +9 -3
  91. package/dist/components/PanelDrawer/PanelPreview.js.map +1 -1
  92. package/dist/components/PanelGroupDialog/DeletePanelGroupDialog.d.ts +1 -2
  93. package/dist/components/PanelGroupDialog/DeletePanelGroupDialog.d.ts.map +1 -1
  94. package/dist/components/PanelGroupDialog/DeletePanelGroupDialog.js +13 -11
  95. package/dist/components/PanelGroupDialog/DeletePanelGroupDialog.js.map +1 -1
  96. package/dist/components/PanelGroupDialog/PanelGroupDialog.d.ts +4 -2
  97. package/dist/components/PanelGroupDialog/PanelGroupDialog.d.ts.map +1 -1
  98. package/dist/components/PanelGroupDialog/PanelGroupDialog.js +73 -112
  99. package/dist/components/PanelGroupDialog/PanelGroupDialog.js.map +1 -1
  100. package/dist/components/PanelGroupDialog/PanelGroupDialog.test.js +21 -15
  101. package/dist/components/PanelGroupDialog/PanelGroupDialog.test.js.map +1 -1
  102. package/dist/components/PanelGroupDialog/PanelGroupEditorForm.d.ts +12 -0
  103. package/dist/components/PanelGroupDialog/PanelGroupEditorForm.d.ts.map +1 -0
  104. package/dist/components/PanelGroupDialog/PanelGroupEditorForm.js +82 -0
  105. package/dist/components/PanelGroupDialog/PanelGroupEditorForm.js.map +1 -0
  106. package/dist/components/PanelGroupDialog/index.d.ts +3 -0
  107. package/dist/components/PanelGroupDialog/index.d.ts.map +1 -0
  108. package/dist/components/PanelGroupDialog/index.js +16 -0
  109. package/dist/components/PanelGroupDialog/index.js.map +1 -0
  110. package/dist/components/TimeRangeControls/TimeRangeControls.d.ts.map +1 -1
  111. package/dist/components/TimeRangeControls/TimeRangeControls.js +11 -14
  112. package/dist/components/TimeRangeControls/TimeRangeControls.js.map +1 -1
  113. package/dist/components/TimeRangeControls/TimeRangeControls.test.js +21 -14
  114. package/dist/components/TimeRangeControls/TimeRangeControls.test.js.map +1 -1
  115. package/dist/components/Variables/Variable.js +1 -0
  116. package/dist/components/Variables/Variable.js.map +1 -1
  117. package/dist/components/Variables/VariableEditor.d.ts.map +1 -1
  118. package/dist/components/Variables/VariableEditor.js +40 -6
  119. package/dist/components/Variables/VariableEditor.js.map +1 -1
  120. package/dist/components/Variables/VariableEditorForm/VariableEditorForm.d.ts.map +1 -1
  121. package/dist/components/Variables/VariableEditorForm/VariableEditorForm.js +9 -5
  122. package/dist/components/Variables/VariableEditorForm/VariableEditorForm.js.map +1 -1
  123. package/dist/components/Variables/VariableList.js +0 -1
  124. package/dist/components/Variables/VariableList.js.map +1 -1
  125. package/dist/components/index.d.ts +1 -0
  126. package/dist/components/index.d.ts.map +1 -1
  127. package/dist/components/index.js +1 -0
  128. package/dist/components/index.js.map +1 -1
  129. package/dist/context/DashboardProvider/DashboardProvider.d.ts +10 -5
  130. package/dist/context/DashboardProvider/DashboardProvider.d.ts.map +1 -1
  131. package/dist/context/DashboardProvider/DashboardProvider.js +26 -8
  132. package/dist/context/DashboardProvider/DashboardProvider.js.map +1 -1
  133. package/dist/context/DashboardProvider/common.d.ts +7 -0
  134. package/dist/context/DashboardProvider/common.d.ts.map +1 -1
  135. package/dist/context/DashboardProvider/common.js +8 -1
  136. package/dist/context/DashboardProvider/common.js.map +1 -1
  137. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts +65 -22
  138. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts.map +1 -1
  139. package/dist/context/DashboardProvider/dashboard-provider-api.js +133 -26
  140. package/dist/context/DashboardProvider/dashboard-provider-api.js.map +1 -1
  141. package/dist/context/DashboardProvider/delete-panel-group-slice.d.ts +23 -0
  142. package/dist/context/DashboardProvider/delete-panel-group-slice.d.ts.map +1 -0
  143. package/dist/context/DashboardProvider/delete-panel-group-slice.js +64 -0
  144. package/dist/context/DashboardProvider/delete-panel-group-slice.js.map +1 -0
  145. package/dist/context/DashboardProvider/delete-panel-slice.d.ts +36 -0
  146. package/dist/context/DashboardProvider/delete-panel-slice.d.ts.map +1 -0
  147. package/dist/context/DashboardProvider/delete-panel-slice.js +81 -0
  148. package/dist/context/DashboardProvider/delete-panel-slice.js.map +1 -0
  149. package/dist/context/DashboardProvider/index.d.ts +3 -0
  150. package/dist/context/DashboardProvider/index.d.ts.map +1 -1
  151. package/dist/context/DashboardProvider/index.js.map +1 -1
  152. package/dist/context/DashboardProvider/panel-editor-slice.d.ts +56 -0
  153. package/dist/context/DashboardProvider/panel-editor-slice.d.ts.map +1 -0
  154. package/dist/context/DashboardProvider/panel-editor-slice.js +178 -0
  155. package/dist/context/DashboardProvider/panel-editor-slice.js.map +1 -0
  156. package/dist/context/DashboardProvider/panel-group-editor-slice.d.ts +33 -0
  157. package/dist/context/DashboardProvider/panel-group-editor-slice.d.ts.map +1 -0
  158. package/dist/context/DashboardProvider/panel-group-editor-slice.js +83 -0
  159. package/dist/context/DashboardProvider/panel-group-editor-slice.js.map +1 -0
  160. package/dist/context/DashboardProvider/panel-group-slice.d.ts +60 -11
  161. package/dist/context/DashboardProvider/panel-group-slice.d.ts.map +1 -1
  162. package/dist/context/DashboardProvider/panel-group-slice.js +85 -18
  163. package/dist/context/DashboardProvider/panel-group-slice.js.map +1 -1
  164. package/dist/context/DashboardProvider/panel-slice.d.ts +23 -0
  165. package/dist/context/DashboardProvider/panel-slice.d.ts.map +1 -0
  166. package/dist/context/DashboardProvider/panel-slice.js +32 -0
  167. package/dist/context/DashboardProvider/panel-slice.js.map +1 -0
  168. package/dist/context/TimeRangeProvider.d.ts +9 -2
  169. package/dist/context/TimeRangeProvider.d.ts.map +1 -1
  170. package/dist/context/TimeRangeProvider.js +15 -43
  171. package/dist/context/TimeRangeProvider.js.map +1 -1
  172. package/dist/context/index.d.ts +1 -1
  173. package/dist/context/index.d.ts.map +1 -1
  174. package/dist/context/index.js +1 -1
  175. package/dist/context/index.js.map +1 -1
  176. package/dist/context/useDashboardSpec.d.ts +11 -0
  177. package/dist/context/useDashboardSpec.d.ts.map +1 -0
  178. package/dist/context/useDashboardSpec.js +84 -0
  179. package/dist/context/useDashboardSpec.js.map +1 -0
  180. package/dist/index.d.ts +1 -0
  181. package/dist/index.d.ts.map +1 -1
  182. package/dist/index.js +1 -0
  183. package/dist/index.js.map +1 -1
  184. package/dist/test/render.d.ts +2 -1
  185. package/dist/test/render.d.ts.map +1 -1
  186. package/dist/test/render.js +25 -5
  187. package/dist/test/render.js.map +1 -1
  188. package/dist/test/setup-tests.d.ts.map +1 -1
  189. package/dist/test/setup-tests.js +4 -0
  190. package/dist/test/setup-tests.js.map +1 -1
  191. package/dist/test/testDashboard.d.ts.map +1 -1
  192. package/dist/test/testDashboard.js +11 -10
  193. package/dist/test/testDashboard.js.map +1 -1
  194. package/dist/utils/index.d.ts +2 -0
  195. package/dist/utils/index.d.ts.map +1 -0
  196. package/dist/utils/index.js +15 -0
  197. package/dist/utils/index.js.map +1 -0
  198. package/dist/utils/time-range-params.d.ts +25 -0
  199. package/dist/utils/time-range-params.d.ts.map +1 -0
  200. package/dist/utils/time-range-params.js +143 -0
  201. package/dist/utils/time-range-params.js.map +1 -0
  202. package/dist/views/ViewDashboard/DashboardApp.d.ts.map +1 -1
  203. package/dist/views/ViewDashboard/DashboardApp.js +1 -4
  204. package/dist/views/ViewDashboard/DashboardApp.js.map +1 -1
  205. package/dist/views/ViewDashboard/ViewDashboard.d.ts.map +1 -1
  206. package/dist/views/ViewDashboard/ViewDashboard.js +5 -22
  207. package/dist/views/ViewDashboard/ViewDashboard.js.map +1 -1
  208. package/dist/views/ViewDashboard/tests/panelGroups.test.js +45 -96
  209. package/dist/views/ViewDashboard/tests/panelGroups.test.js.map +1 -1
  210. package/package.json +5 -4
  211. package/dist/cjs/context/DashboardProvider/layout-slice.js +0 -200
  212. package/dist/cjs/context/DashboardProvider/panel-editing-slice.js +0 -156
  213. package/dist/cjs/context/QueryStringProvider.js +0 -89
  214. package/dist/context/DashboardProvider/layout-slice.d.ts +0 -57
  215. package/dist/context/DashboardProvider/layout-slice.d.ts.map +0 -1
  216. package/dist/context/DashboardProvider/layout-slice.js +0 -196
  217. package/dist/context/DashboardProvider/layout-slice.js.map +0 -1
  218. package/dist/context/DashboardProvider/panel-editing-slice.d.ts +0 -70
  219. package/dist/context/DashboardProvider/panel-editing-slice.d.ts.map +0 -1
  220. package/dist/context/DashboardProvider/panel-editing-slice.js +0 -152
  221. package/dist/context/DashboardProvider/panel-editing-slice.js.map +0 -1
  222. package/dist/context/QueryStringProvider.d.ts +0 -13
  223. package/dist/context/QueryStringProvider.d.ts.map +0 -1
  224. package/dist/context/QueryStringProvider.js +0 -40
  225. package/dist/context/QueryStringProvider.js.map +0 -1
@@ -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,151 @@
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
+ (0, _react.useEffect)(()=>{
115
+ if (paramsEnabled && !start) {
116
+ if ((0, _core.isRelativeTimeRange)(initialTimeRange)) {
117
+ setQuery({
118
+ start: initialTimeRange.pastDuration,
119
+ end: undefined
120
+ });
121
+ }
122
+ }
123
+ }, [
124
+ initialTimeRange,
125
+ paramsEnabled,
126
+ start,
127
+ setQuery
128
+ ]);
129
+ const setTimeRange = (0, _react.useCallback)((value)=>{
130
+ if ((0, _core.isRelativeTimeRange)(value)) {
131
+ setQuery({
132
+ start: value.pastDuration,
133
+ end: undefined
134
+ });
135
+ } else {
136
+ setQuery(value);
137
+ }
138
+ }, [
139
+ setQuery
140
+ ]);
141
+ if (!paramsEnabled) {
142
+ return {
143
+ timeRange: timeRangeState,
144
+ setTimeRange: setTimeRangeState
145
+ };
146
+ }
147
+ return {
148
+ timeRange: initialTimeRange,
149
+ setTimeRange: setTimeRange
150
+ };
151
+ }
@@ -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 : {
@@ -35,7 +33,6 @@ const DashboardApp = (props)=>{
35
33
  const { dashboardResource } = props;
36
34
  return /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Box, {
37
35
  sx: {
38
- padding: (theme)=>theme.spacing(1, 0),
39
36
  flexGrow: 1,
40
37
  overflowX: 'hidden',
41
38
  overflowY: 'auto',
@@ -56,8 +53,8 @@ const DashboardApp = (props)=>{
56
53
  children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components1.Dashboard, {})
57
54
  }),
58
55
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components1.PanelDrawer, {}),
59
- /*#__PURE__*/ (0, _jsxRuntime.jsx)(_panelGroupDialog.default, {}),
60
- /*#__PURE__*/ (0, _jsxRuntime.jsx)(_deletePanelGroupDialog.default, {}),
56
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components1.PanelGroupDialog, {}),
57
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components1.DeletePanelGroupDialog, {}),
61
58
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_deletePanelDialog.default, {})
62
59
  ]
63
60
  })
@@ -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
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Dashboard.tsx"],"sourcesContent":["// Copyright 2022 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, BoxProps } from '@mui/material';\nimport { ErrorBoundary, ErrorAlert } from '@perses-dev/components';\nimport { useLayouts } from '../context';\nimport { GridLayout } from './GridLayout';\n\nexport type DashboardProps = BoxProps;\n\n/**\n * Renders a Dashboard for the provided Dashboard spec.\n */\nexport function Dashboard(props: DashboardProps) {\n const { layouts } = useLayouts();\n return (\n <Box {...props}>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n {layouts.map((layout, groupIndex) => (\n <GridLayout key={layout.id} groupIndex={groupIndex} groupDefinition={layout} />\n ))}\n </ErrorBoundary>\n </Box>\n );\n}\n"],"names":["Box","ErrorBoundary","ErrorAlert","useLayouts","GridLayout","Dashboard","props","layouts","FallbackComponent","map","layout","groupIndex","groupDefinition","id"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC;AAAA,SAASA,GAAG,QAAkB,eAAe,CAAC;AAC9C,SAASC,aAAa,EAAEC,UAAU,QAAQ,wBAAwB,CAAC;AACnE,SAASC,UAAU,QAAQ,YAAY,CAAC;AACxC,SAASC,UAAU,QAAQ,cAAc,CAAC;AAI1C;;CAEC,GACD,OAAO,SAASC,SAAS,CAACC,KAAqB,EAAE;IAC/C,MAAM,EAAEC,OAAO,CAAA,EAAE,GAAGJ,UAAU,EAAE,AAAC;IACjC,qBACE,KAACH,GAAG;QAAE,GAAGM,KAAK;kBACZ,cAAA,KAACL,aAAa;YAACO,iBAAiB,EAAEN,UAAU;sBACzCK,OAAO,CAACE,GAAG,CAAC,CAACC,MAAM,EAAEC,UAAU,iBAC9B,KAACP,UAAU;oBAAiBO,UAAU,EAAEA,UAAU;oBAAEC,eAAe,EAAEF,MAAM;mBAA1DA,MAAM,CAACG,EAAE,CAAqD,AAChF,CAAC;UACY;MACZ,CACN;AACJ,CAAC"}
1
+ {"version":3,"sources":["../../src/components/Dashboard.tsx"],"sourcesContent":["// Copyright 2022 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, BoxProps } from '@mui/material';\nimport { ErrorBoundary, ErrorAlert } from '@perses-dev/components';\nimport { usePanelGroupIds } from '../context';\nimport { GridLayout } from './GridLayout';\n\nexport type DashboardProps = BoxProps;\n\n/**\n * Renders a Dashboard for the provided Dashboard spec.\n */\nexport function Dashboard(props: DashboardProps) {\n const panelGroupIds = usePanelGroupIds();\n return (\n <Box {...props}>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n {panelGroupIds.map((panelGroupId) => (\n <GridLayout key={panelGroupId} panelGroupId={panelGroupId} />\n ))}\n </ErrorBoundary>\n </Box>\n );\n}\n"],"names":["Box","ErrorBoundary","ErrorAlert","usePanelGroupIds","GridLayout","Dashboard","props","panelGroupIds","FallbackComponent","map","panelGroupId"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC;AAAA,SAASA,GAAG,QAAkB,eAAe,CAAC;AAC9C,SAASC,aAAa,EAAEC,UAAU,QAAQ,wBAAwB,CAAC;AACnE,SAASC,gBAAgB,QAAQ,YAAY,CAAC;AAC9C,SAASC,UAAU,QAAQ,cAAc,CAAC;AAI1C;;CAEC,GACD,OAAO,SAASC,SAAS,CAACC,KAAqB,EAAE;IAC/C,MAAMC,aAAa,GAAGJ,gBAAgB,EAAE,AAAC;IACzC,qBACE,KAACH,GAAG;QAAE,GAAGM,KAAK;kBACZ,cAAA,KAACL,aAAa;YAACO,iBAAiB,EAAEN,UAAU;sBACzCK,aAAa,CAACE,GAAG,CAAC,CAACC,YAAY,iBAC9B,KAACN,UAAU;oBAAoBM,YAAY,EAAEA,YAAY;mBAAxCA,YAAY,CAAgC,AAC9D,CAAC;UACY;MACZ,CACN;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardToolbar.d.ts","sourceRoot":"","sources":["../../src/components/DashboardToolbar.tsx"],"names":[],"mappings":";AAqBA,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,gBAAgB,UAAW,qBAAqB,gBA6E5D,CAAC"}
1
+ {"version":3,"file":"DashboardToolbar.d.ts","sourceRoot":"","sources":["../../src/components/DashboardToolbar.tsx"],"names":[],"mappings":";AAuBA,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,gBAAgB,UAAW,qBAAqB,gBA6F5D,CAAC"}
@@ -11,22 +11,34 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
14
- import { Typography, Stack, Button, Box } from '@mui/material';
14
+ import { useState } from 'react';
15
+ import { Typography, Stack, Button, Box, useTheme, useMediaQuery } from '@mui/material';
15
16
  import PencilIcon from 'mdi-material-ui/PencilOutline';
16
17
  import AddPanelGroupIcon from 'mdi-material-ui/PlusBoxOutline';
17
18
  import AddPanelIcon from 'mdi-material-ui/ChartBoxPlusOutline';
18
19
  import { ErrorBoundary, ErrorAlert } from '@perses-dev/components';
19
- import { usePanelGroupDialog, useEditMode, usePanels } from '../context';
20
+ import { useDashboardActions, useDashboardSpec, useEditMode } from '../context';
20
21
  import { TemplateVariableList, TimeRangeControls } from '../components';
21
22
  export const DashboardToolbar = (props)=>{
22
23
  const { dashboardName } = props;
23
24
  const { isEditMode , setEditMode } = useEditMode();
24
- const { openPanelGroupDialog } = usePanelGroupDialog();
25
- const { addPanel } = usePanels();
25
+ const { openAddPanelGroup , openAddPanel , save } = useDashboardActions();
26
+ const isLaptopSize = useMediaQuery(useTheme().breakpoints.up('sm'));
27
+ const [originalSpec, setOriginalSpec] = useState(undefined);
28
+ const { spec , resetSpec } = useDashboardSpec();
26
29
  const onEditButtonClick = ()=>{
30
+ setOriginalSpec(spec);
27
31
  setEditMode(true);
28
32
  };
29
33
  const onCancelButtonClick = ()=>{
34
+ // Reset to the original spec and exit edit mode
35
+ if (originalSpec) {
36
+ resetSpec(originalSpec);
37
+ }
38
+ setEditMode(false);
39
+ };
40
+ const onSave = ()=>{
41
+ save();
30
42
  setEditMode(false);
31
43
  };
32
44
  return /*#__PURE__*/ _jsx(_Fragment, {
@@ -57,6 +69,7 @@ export const DashboardToolbar = (props)=>{
57
69
  children: [
58
70
  /*#__PURE__*/ _jsx(Button, {
59
71
  variant: "contained",
72
+ onClick: onSave,
60
73
  children: "Save"
61
74
  }),
62
75
  /*#__PURE__*/ _jsx(Button, {
@@ -90,12 +103,12 @@ export const DashboardToolbar = (props)=>{
90
103
  children: [
91
104
  /*#__PURE__*/ _jsx(Button, {
92
105
  startIcon: /*#__PURE__*/ _jsx(AddPanelGroupIcon, {}),
93
- onClick: ()=>openPanelGroupDialog(),
106
+ onClick: openAddPanelGroup,
94
107
  children: "Add Panel Group"
95
108
  }),
96
109
  /*#__PURE__*/ _jsx(Button, {
97
110
  startIcon: /*#__PURE__*/ _jsx(AddPanelIcon, {}),
98
- onClick: ()=>addPanel(0),
111
+ onClick: openAddPanel,
99
112
  children: "Add Panel"
100
113
  }),
101
114
  /*#__PURE__*/ _jsx(TimeRangeControls, {})
@@ -126,7 +139,7 @@ export const DashboardToolbar = (props)=>{
126
139
  },
127
140
  children: [
128
141
  /*#__PURE__*/ _jsx(TimeRangeControls, {}),
129
- /*#__PURE__*/ _jsx(Button, {
142
+ isLaptopSize && /*#__PURE__*/ _jsx(Button, {
130
143
  variant: "outlined",
131
144
  startIcon: /*#__PURE__*/ _jsx(PencilIcon, {}),
132
145
  onClick: onEditButtonClick,