@perses-dev/dashboards 0.54.0-beta.5 → 0.54.0-beta.7

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 (101) hide show
  1. package/dist/cjs/components/Annotations/AnnotationsEditor.js +302 -0
  2. package/dist/cjs/components/Annotations/EditAnnotationsButton.js +83 -0
  3. package/dist/cjs/components/DashboardToolbar/DashboardToolbar.js +3 -1
  4. package/dist/cjs/components/Variables/VariableEditor.js +2 -2
  5. package/dist/cjs/constants/user-interface-text.js +1 -0
  6. package/dist/cjs/context/AnnotationProvider/AnnotationHydrationWrapper.js +50 -0
  7. package/dist/cjs/context/AnnotationProvider/AnnotationProvider.js +145 -0
  8. package/dist/cjs/{model/DashboardResource.js → context/AnnotationProvider/index.js} +14 -0
  9. package/dist/cjs/context/DatasourceStoreProvider.js +34 -4
  10. package/dist/cjs/context/index.js +1 -0
  11. package/dist/cjs/context/useDashboard.js +8 -0
  12. package/dist/cjs/model/index.js +0 -1
  13. package/dist/cjs/views/ViewDashboard/DashboardApp.js +2 -1
  14. package/dist/cjs/views/ViewDashboard/ViewDashboard.js +29 -25
  15. package/dist/components/Annotations/AnnotationsEditor.d.ts +8 -0
  16. package/dist/components/Annotations/AnnotationsEditor.d.ts.map +1 -0
  17. package/dist/components/Annotations/AnnotationsEditor.js +289 -0
  18. package/dist/components/Annotations/AnnotationsEditor.js.map +1 -0
  19. package/dist/components/Annotations/EditAnnotationsButton.d.ts +18 -0
  20. package/dist/components/Annotations/EditAnnotationsButton.d.ts.map +1 -0
  21. package/dist/components/Annotations/EditAnnotationsButton.js +70 -0
  22. package/dist/components/Annotations/EditAnnotationsButton.js.map +1 -0
  23. package/dist/components/DashboardToolbar/DashboardToolbar.d.ts +1 -0
  24. package/dist/components/DashboardToolbar/DashboardToolbar.d.ts.map +1 -1
  25. package/dist/components/DashboardToolbar/DashboardToolbar.js +3 -1
  26. package/dist/components/DashboardToolbar/DashboardToolbar.js.map +1 -1
  27. package/dist/components/Datasources/DatasourceEditor.d.ts.map +1 -1
  28. package/dist/components/Datasources/DatasourceEditor.js.map +1 -1
  29. package/dist/components/DownloadButton/serializeDashboard.d.ts +1 -1
  30. package/dist/components/DownloadButton/serializeDashboard.d.ts.map +1 -1
  31. package/dist/components/DownloadButton/serializeDashboard.js.map +1 -1
  32. package/dist/components/LeaveDialog/LeaveDialog.d.ts +1 -1
  33. package/dist/components/LeaveDialog/LeaveDialog.d.ts.map +1 -1
  34. package/dist/components/LeaveDialog/LeaveDialog.js.map +1 -1
  35. package/dist/components/PanelDrawer/PanelEditorForm.d.ts +1 -1
  36. package/dist/components/PanelDrawer/PanelEditorForm.d.ts.map +1 -1
  37. package/dist/components/PanelDrawer/PanelEditorForm.js.map +1 -1
  38. package/dist/components/Variables/VariableEditor.d.ts.map +1 -1
  39. package/dist/components/Variables/VariableEditor.js +2 -2
  40. package/dist/components/Variables/VariableEditor.js.map +1 -1
  41. package/dist/constants/user-interface-text.d.ts +1 -0
  42. package/dist/constants/user-interface-text.d.ts.map +1 -1
  43. package/dist/constants/user-interface-text.js +1 -0
  44. package/dist/constants/user-interface-text.js.map +1 -1
  45. package/dist/context/AnnotationProvider/AnnotationHydrationWrapper.d.ts +7 -0
  46. package/dist/context/AnnotationProvider/AnnotationHydrationWrapper.d.ts.map +1 -0
  47. package/dist/context/AnnotationProvider/AnnotationHydrationWrapper.js +48 -0
  48. package/dist/context/AnnotationProvider/AnnotationHydrationWrapper.js.map +1 -0
  49. package/dist/context/AnnotationProvider/AnnotationProvider.d.ts +40 -0
  50. package/dist/context/AnnotationProvider/AnnotationProvider.d.ts.map +1 -0
  51. package/dist/context/AnnotationProvider/AnnotationProvider.js +114 -0
  52. package/dist/context/AnnotationProvider/AnnotationProvider.js.map +1 -0
  53. package/dist/context/AnnotationProvider/index.d.ts +2 -0
  54. package/dist/context/AnnotationProvider/index.d.ts.map +1 -0
  55. package/dist/{model/DashboardResource.js → context/AnnotationProvider/index.js} +2 -2
  56. package/dist/context/AnnotationProvider/index.js.map +1 -0
  57. package/dist/context/DashboardProvider/DashboardProvider.d.ts +1 -2
  58. package/dist/context/DashboardProvider/DashboardProvider.d.ts.map +1 -1
  59. package/dist/context/DashboardProvider/DashboardProvider.js.map +1 -1
  60. package/dist/context/DashboardProvider/common.d.ts +1 -1
  61. package/dist/context/DashboardProvider/common.d.ts.map +1 -1
  62. package/dist/context/DashboardProvider/common.js.map +1 -1
  63. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts +2 -1
  64. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts.map +1 -1
  65. package/dist/context/DashboardProvider/dashboard-provider-api.js.map +1 -1
  66. package/dist/context/DashboardProvider/panel-editor-slice.d.ts +1 -1
  67. package/dist/context/DashboardProvider/panel-editor-slice.d.ts.map +1 -1
  68. package/dist/context/DashboardProvider/panel-editor-slice.js.map +1 -1
  69. package/dist/context/DatasourceStoreProvider.d.ts +1 -2
  70. package/dist/context/DatasourceStoreProvider.d.ts.map +1 -1
  71. package/dist/context/DatasourceStoreProvider.js +35 -5
  72. package/dist/context/DatasourceStoreProvider.js.map +1 -1
  73. package/dist/context/index.d.ts +1 -0
  74. package/dist/context/index.d.ts.map +1 -1
  75. package/dist/context/index.js +1 -0
  76. package/dist/context/index.js.map +1 -1
  77. package/dist/context/useDashboard.d.ts +1 -1
  78. package/dist/context/useDashboard.d.ts.map +1 -1
  79. package/dist/context/useDashboard.js +8 -0
  80. package/dist/context/useDashboard.js.map +1 -1
  81. package/dist/model/index.d.ts +0 -1
  82. package/dist/model/index.d.ts.map +1 -1
  83. package/dist/model/index.js +0 -1
  84. package/dist/model/index.js.map +1 -1
  85. package/dist/test/dashboard-provider.d.ts +1 -1
  86. package/dist/test/dashboard-provider.d.ts.map +1 -1
  87. package/dist/test/dashboard-provider.js.map +1 -1
  88. package/dist/test/testDashboard.d.ts +1 -1
  89. package/dist/test/testDashboard.d.ts.map +1 -1
  90. package/dist/test/testDashboard.js.map +1 -1
  91. package/dist/views/ViewDashboard/DashboardApp.d.ts +2 -1
  92. package/dist/views/ViewDashboard/DashboardApp.d.ts.map +1 -1
  93. package/dist/views/ViewDashboard/DashboardApp.js +2 -1
  94. package/dist/views/ViewDashboard/DashboardApp.js.map +1 -1
  95. package/dist/views/ViewDashboard/ViewDashboard.d.ts.map +1 -1
  96. package/dist/views/ViewDashboard/ViewDashboard.js +30 -26
  97. package/dist/views/ViewDashboard/ViewDashboard.js.map +1 -1
  98. package/package.json +5 -4
  99. package/dist/model/DashboardResource.d.ts +0 -9
  100. package/dist/model/DashboardResource.d.ts.map +0 -1
  101. package/dist/model/DashboardResource.js.map +0 -1
@@ -0,0 +1,302 @@
1
+ // Copyright 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, "AnnotationEditor", {
18
+ enumerable: true,
19
+ get: function() {
20
+ return AnnotationEditor;
21
+ }
22
+ });
23
+ const _jsxruntime = require("react/jsx-runtime");
24
+ const _react = require("react");
25
+ const _material = require("@mui/material");
26
+ const _Plus = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/Plus"));
27
+ const _useimmer = require("use-immer");
28
+ const _Pencil = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/Pencil"));
29
+ const _TrashCan = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/TrashCan"));
30
+ const _ArrowUp = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/ArrowUp"));
31
+ const _ArrowDown = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/ArrowDown"));
32
+ const _pluginsystem = require("@perses-dev/plugin-system");
33
+ const _context = require("../../context");
34
+ function _interop_require_default(obj) {
35
+ return obj && obj.__esModule ? obj : {
36
+ default: obj
37
+ };
38
+ }
39
+ function validateAnnotationSpecs(annotationSpecs) {
40
+ const errors = [];
41
+ const annotationNames = [];
42
+ for (const annotationSpec of annotationSpecs){
43
+ if (annotationNames.includes(annotationSpec.display.name)) {
44
+ errors.push(`Duplicate annotation name: ${annotationSpec.display.name}`);
45
+ } else {
46
+ annotationNames.push(annotationSpec.display.name);
47
+ }
48
+ }
49
+ return {
50
+ errors: errors,
51
+ isValid: errors.length === 0
52
+ };
53
+ }
54
+ function AnnotationEditor(props) {
55
+ const [annotationSpecs, setAnnotationSpecs] = (0, _useimmer.useImmer)(props.annotationSpecs);
56
+ const [annotationEditIdx, setAnnotationEditIdx] = (0, _react.useState)(null);
57
+ const [annotationFormAction, setAnnotationFormAction] = (0, _react.useState)('update');
58
+ const validation = (0, _react.useMemo)(()=>validateAnnotationSpecs(annotationSpecs), [
59
+ annotationSpecs
60
+ ]);
61
+ const currentEditingAnnotationSpec = annotationEditIdx !== null ? annotationSpecs[annotationEditIdx] : undefined;
62
+ const { openDiscardChangesConfirmationDialog, closeDiscardChangesConfirmationDialog } = (0, _context.useDiscardChangesConfirmationDialog)();
63
+ const handleCancel = ()=>{
64
+ if (JSON.stringify(props.annotationSpecs) !== JSON.stringify(annotationSpecs)) {
65
+ openDiscardChangesConfirmationDialog({
66
+ onDiscardChanges: ()=>{
67
+ closeDiscardChangesConfirmationDialog();
68
+ props.onCancel();
69
+ },
70
+ onCancel: ()=>{
71
+ closeDiscardChangesConfirmationDialog();
72
+ },
73
+ description: 'You have unapplied changes. Are you sure you want to discard these changes? Changes cannot be recovered.'
74
+ });
75
+ } else {
76
+ props.onCancel();
77
+ }
78
+ };
79
+ const removeAnnotation = (index)=>{
80
+ setAnnotationSpecs((draft)=>{
81
+ draft.splice(index, 1);
82
+ });
83
+ };
84
+ const addAnnotation = ()=>{
85
+ setAnnotationFormAction('create');
86
+ setAnnotationSpecs((draft)=>{
87
+ draft.push({
88
+ display: {
89
+ name: 'NewAnnotation'
90
+ },
91
+ plugin: {}
92
+ });
93
+ });
94
+ setAnnotationEditIdx(annotationSpecs.length);
95
+ };
96
+ const editAnnotation = (index)=>{
97
+ setAnnotationFormAction('update');
98
+ setAnnotationEditIdx(index);
99
+ };
100
+ const toggleAnnotationVisibility = (index, visible)=>{
101
+ setAnnotationSpecs((draft)=>{
102
+ const v = draft[index];
103
+ if (!v) {
104
+ return;
105
+ }
106
+ v.display.hidden = !visible;
107
+ });
108
+ };
109
+ const changeAnnotationOrder = (index, direction)=>{
110
+ const step = direction === 'up' ? -1 : 1;
111
+ setAnnotationSpecs((draft)=>{
112
+ const current = draft[index];
113
+ const adjacent = draft[index + step];
114
+ if (!current || !adjacent) {
115
+ return;
116
+ }
117
+ draft[index + step] = current;
118
+ draft[index] = adjacent;
119
+ });
120
+ };
121
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_jsxruntime.Fragment, {
122
+ children: annotationEditIdx !== null && currentEditingAnnotationSpec ? /*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.ValidationProvider, {
123
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.AnnotationEditorForm, {
124
+ initialAnnotationSpec: currentEditingAnnotationSpec,
125
+ action: annotationFormAction,
126
+ isDraft: true,
127
+ onActionChange: setAnnotationFormAction,
128
+ onSave: (definition)=>{
129
+ setAnnotationSpecs((draft)=>{
130
+ draft[annotationEditIdx] = definition;
131
+ setAnnotationEditIdx(null);
132
+ });
133
+ },
134
+ onClose: ()=>{
135
+ if (annotationFormAction === 'create') {
136
+ removeAnnotation(annotationEditIdx);
137
+ }
138
+ setAnnotationEditIdx(null);
139
+ }
140
+ })
141
+ }) : /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
142
+ children: [
143
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Box, {
144
+ sx: {
145
+ display: 'flex',
146
+ alignItems: 'center',
147
+ padding: (theme)=>theme.spacing(1, 2),
148
+ borderBottom: (theme)=>`1px solid ${theme.palette.divider}`
149
+ },
150
+ children: [
151
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Typography, {
152
+ variant: "h2",
153
+ children: "Edit Dashboard Annotations"
154
+ }),
155
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Stack, {
156
+ direction: "row",
157
+ spacing: 1,
158
+ marginLeft: "auto",
159
+ children: [
160
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Button, {
161
+ disabled: props.annotationSpecs === annotationSpecs || !validation.isValid,
162
+ variant: "contained",
163
+ onClick: ()=>{
164
+ props.onChange(annotationSpecs);
165
+ },
166
+ children: "Apply"
167
+ }),
168
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Button, {
169
+ color: "secondary",
170
+ variant: "outlined",
171
+ onClick: handleCancel,
172
+ children: "Cancel"
173
+ })
174
+ ]
175
+ })
176
+ ]
177
+ }),
178
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
179
+ padding: 2,
180
+ sx: {
181
+ overflowY: 'scroll'
182
+ },
183
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Stack, {
184
+ spacing: 2,
185
+ children: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Stack, {
186
+ spacing: 2,
187
+ children: [
188
+ !validation.isValid && validation.errors.map((error)=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Alert, {
189
+ severity: "error",
190
+ children: error
191
+ }, error)),
192
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TableContainer, {
193
+ children: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Table, {
194
+ sx: {
195
+ minWidth: 650
196
+ },
197
+ "aria-label": "table of annotations",
198
+ children: [
199
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TableHead, {
200
+ children: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.TableRow, {
201
+ children: [
202
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
203
+ children: "Visibility"
204
+ }),
205
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
206
+ children: "Name"
207
+ }),
208
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
209
+ children: "Type"
210
+ }),
211
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
212
+ children: "Description"
213
+ }),
214
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
215
+ align: "right",
216
+ children: "Actions"
217
+ })
218
+ ]
219
+ })
220
+ }),
221
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TableBody, {
222
+ children: annotationSpecs.map((v, idx)=>/*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.TableRow, {
223
+ children: [
224
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
225
+ component: "th",
226
+ scope: "row",
227
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Switch, {
228
+ checked: v.display?.hidden !== true,
229
+ onChange: (e)=>{
230
+ toggleAnnotationVisibility(idx, e.target.checked);
231
+ }
232
+ })
233
+ }),
234
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
235
+ component: "th",
236
+ scope: "row",
237
+ sx: {
238
+ fontWeight: 'bold'
239
+ },
240
+ children: v.display.name
241
+ }),
242
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
243
+ children: v.plugin.kind
244
+ }),
245
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
246
+ children: v.display?.description ?? ''
247
+ }),
248
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(TableCell, {
249
+ align: "right",
250
+ sx: {
251
+ whiteSpace: 'nowrap'
252
+ },
253
+ children: [
254
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
255
+ onClick: ()=>changeAnnotationOrder(idx, 'up'),
256
+ disabled: idx === 0,
257
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_ArrowUp.default, {})
258
+ }),
259
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
260
+ onClick: ()=>changeAnnotationOrder(idx, 'down'),
261
+ disabled: idx === annotationSpecs.length - 1,
262
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_ArrowDown.default, {})
263
+ }),
264
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
265
+ onClick: ()=>editAnnotation(idx),
266
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Pencil.default, {})
267
+ }),
268
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
269
+ onClick: ()=>removeAnnotation(idx),
270
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_TrashCan.default, {})
271
+ })
272
+ ]
273
+ })
274
+ ]
275
+ }, v.display.name))
276
+ })
277
+ ]
278
+ })
279
+ }),
280
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
281
+ display: "flex",
282
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Button, {
283
+ variant: "contained",
284
+ startIcon: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Plus.default, {}),
285
+ sx: {
286
+ marginLeft: 'auto'
287
+ },
288
+ onClick: addAnnotation,
289
+ children: "Add Annotation"
290
+ })
291
+ })
292
+ ]
293
+ })
294
+ })
295
+ })
296
+ ]
297
+ })
298
+ });
299
+ }
300
+ const TableCell = (0, _material.styled)(_material.TableCell)(({ theme })=>({
301
+ borderBottom: `solid 1px ${theme.palette.divider}`
302
+ }));
@@ -0,0 +1,83 @@
1
+ // Copyright 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, "EditAnnotationsButton", {
18
+ enumerable: true,
19
+ get: function() {
20
+ return EditAnnotationsButton;
21
+ }
22
+ });
23
+ const _jsxruntime = require("react/jsx-runtime");
24
+ const _react = require("react");
25
+ const _material = require("@mui/material");
26
+ const _PencilOutline = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/PencilOutline"));
27
+ const _components = require("@perses-dev/components");
28
+ const _constants = require("../../constants");
29
+ const _context = require("../../context");
30
+ const _AnnotationsEditor = require("./AnnotationsEditor");
31
+ function _interop_require_default(obj) {
32
+ return obj && obj.__esModule ? obj : {
33
+ default: obj
34
+ };
35
+ }
36
+ function EditAnnotationsButton({ variant = 'text', label = 'Annotations', color = 'primary', fullWidth }) {
37
+ const [isAnnotationEditorOpen, setIsAnnotationEditorOpen] = (0, _react.useState)(false);
38
+ const annotationSpecs = (0, _context.useAnnotationSpecs)();
39
+ const { setAnnotationSpecs } = (0, _context.useAnnotationActions)();
40
+ const openAnnotationEditor = ()=>{
41
+ setIsAnnotationEditorOpen(true);
42
+ };
43
+ const closeAnnotationEditor = ()=>{
44
+ setIsAnnotationEditorOpen(false);
45
+ };
46
+ return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
47
+ children: [
48
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
49
+ description: _constants.TOOLTIP_TEXT.editAnnotations,
50
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Button, {
51
+ startIcon: /*#__PURE__*/ (0, _jsxruntime.jsx)(_PencilOutline.default, {}),
52
+ onClick: openAnnotationEditor,
53
+ "aria-label": _constants.TOOLTIP_TEXT.editAnnotations,
54
+ variant: variant,
55
+ color: color,
56
+ fullWidth: fullWidth,
57
+ sx: _constants.editButtonStyle,
58
+ children: label
59
+ })
60
+ }),
61
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.Drawer, {
62
+ isOpen: isAnnotationEditorOpen,
63
+ onClose: closeAnnotationEditor,
64
+ slotProps: {
65
+ paper: {
66
+ sx: {
67
+ width: '50%'
68
+ }
69
+ }
70
+ },
71
+ "data-testid": "annotation-editor",
72
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_AnnotationsEditor.AnnotationEditor, {
73
+ annotationSpecs: annotationSpecs,
74
+ onCancel: closeAnnotationEditor,
75
+ onChange: (annotations)=>{
76
+ setAnnotationSpecs(annotations);
77
+ setIsAnnotationEditorOpen(false);
78
+ }
79
+ })
80
+ })
81
+ ]
82
+ });
83
+ }
@@ -34,10 +34,11 @@ const _EditButton = require("../EditButton");
34
34
  const _EditJsonButton = require("../EditJsonButton");
35
35
  const _SaveDashboardButton = require("../SaveDashboardButton");
36
36
  const _DashboardStickyToolbar = require("../DashboardStickyToolbar");
37
+ const _EditAnnotationsButton = require("../Annotations/EditAnnotationsButton");
37
38
  const _DashboardLinks = require("../DashboardLinks");
38
39
  const _LinksDisplay = require("../LinksDisplay");
39
40
  const DashboardToolbar = (props)=>{
40
- const { dashboardName, dashboardTitleComponent, initialVariableIsSticky, isReadonly, isVariableEnabled, isDatasourceEnabled, isLinksEnabled = true, onEditButtonClick, onCancelButtonClick, onSave } = props;
41
+ const { dashboardName, dashboardTitleComponent, initialVariableIsSticky, isReadonly, isVariableEnabled, isAnnotationEnabled, isDatasourceEnabled, isLinksEnabled = true, onEditButtonClick, onCancelButtonClick, onSave } = props;
41
42
  const { isEditMode } = (0, _context.useEditMode)();
42
43
  const { timeZone, setTimeZone } = (0, _pluginsystem.useTimeZoneParams)('local');
43
44
  const dashboardLinks = (0, _context.useDashboardLinks)();
@@ -91,6 +92,7 @@ const DashboardToolbar = (props)=>{
91
92
  ml: 1,
92
93
  whiteSpace: "nowrap",
93
94
  children: [
95
+ isAnnotationEnabled && /*#__PURE__*/ (0, _jsxruntime.jsx)(_EditAnnotationsButton.EditAnnotationsButton, {}),
94
96
  isVariableEnabled && /*#__PURE__*/ (0, _jsxruntime.jsx)(_Variables.EditVariablesButton, {}),
95
97
  isDatasourceEnabled && /*#__PURE__*/ (0, _jsxruntime.jsx)(_Datasources.EditDatasourcesButton, {}),
96
98
  isLinksEnabled && /*#__PURE__*/ (0, _jsxruntime.jsx)(_DashboardLinks.EditDashboardLinksButton, {}),
@@ -83,7 +83,7 @@ function VariableEditor(props) {
83
83
  externalVariableDefinitions,
84
84
  variableDefinitions
85
85
  ]);
86
- const currentEditingVariableDefinition = typeof variableEditIdx === 'number' && variableDefinitions[variableEditIdx];
86
+ const currentEditingVariableDefinition = variableEditIdx !== null ? variableDefinitions[variableEditIdx] : undefined;
87
87
  const { openDiscardChangesConfirmationDialog, closeDiscardChangesConfirmationDialog } = (0, _context.useDiscardChangesConfirmationDialog)();
88
88
  const handleCancel = ()=>{
89
89
  if (JSON.stringify(props.variableDefinitions) !== JSON.stringify(variableDefinitions)) {
@@ -166,7 +166,7 @@ function VariableEditor(props) {
166
166
  };
167
167
  return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
168
168
  children: [
169
- currentEditingVariableDefinition && /*#__PURE__*/ (0, _jsxruntime.jsx)(VariableEditorFormWithContext, {
169
+ variableEditIdx !== null && currentEditingVariableDefinition && /*#__PURE__*/ (0, _jsxruntime.jsx)(VariableEditorFormWithContext, {
170
170
  variableDefinitions: variableDefinitions,
171
171
  externalVariableDefinitions: externalVariableDefinitions,
172
172
  builtinVariableDefinitions: builtinVariableDefinitions,
@@ -36,6 +36,7 @@ const TOOLTIP_TEXT = {
36
36
  editJson: 'Edit JSON',
37
37
  editLinks: 'Edit links',
38
38
  editVariables: 'Edit variables',
39
+ editAnnotations: 'Edit annotations',
39
40
  viewJson: 'View JSON',
40
41
  // Group buttons
41
42
  addPanelToGroup: 'Add panel to group',
@@ -0,0 +1,50 @@
1
+ // Copyright 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, "AnnotationHydrationWrapper", {
18
+ enumerable: true,
19
+ get: function() {
20
+ return AnnotationHydrationWrapper;
21
+ }
22
+ });
23
+ const _jsxruntime = require("react/jsx-runtime");
24
+ const _react = require("react");
25
+ const _pluginsystem = require("@perses-dev/plugin-system");
26
+ const _AnnotationProvider = require("./AnnotationProvider");
27
+ function AnnotationHydrationWrapper({ children }) {
28
+ const annotationSpecs = (0, _AnnotationProvider.useAnnotationSpecs)();
29
+ const { setAnnotationState } = (0, _AnnotationProvider.useAnnotationActions)();
30
+ const annotations = (0, _pluginsystem.useAnnotations)(annotationSpecs);
31
+ (0, _react.useEffect)(()=>{
32
+ for (const [index, definition] of annotationSpecs.entries()){
33
+ const query = annotations[index] ?? null;
34
+ if (query) {
35
+ setAnnotationState(definition.display.name, {
36
+ data: query.data ?? null,
37
+ isPending: query.isLoading,
38
+ error: query?.error ?? null
39
+ });
40
+ }
41
+ }
42
+ }, [
43
+ annotationSpecs,
44
+ annotations,
45
+ setAnnotationState
46
+ ]);
47
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_jsxruntime.Fragment, {
48
+ children: children
49
+ });
50
+ }
@@ -0,0 +1,145 @@
1
+ // Copyright 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: Object.getOwnPropertyDescriptor(all, name).get
21
+ });
22
+ }
23
+ _export(exports, {
24
+ get AnnotationProvider () {
25
+ return AnnotationProvider;
26
+ },
27
+ get useAnnotationActions () {
28
+ return useAnnotationActions;
29
+ },
30
+ get useAnnotationSpecAndState () {
31
+ return useAnnotationSpecAndState;
32
+ },
33
+ get useAnnotationSpecs () {
34
+ return useAnnotationSpecs;
35
+ },
36
+ get useAnnotationStates () {
37
+ return useAnnotationStates;
38
+ },
39
+ get useAnnotationStoreCtx () {
40
+ return useAnnotationStoreCtx;
41
+ },
42
+ get useAnnotationsWithData () {
43
+ return useAnnotationsWithData;
44
+ }
45
+ });
46
+ const _jsxruntime = require("react/jsx-runtime");
47
+ const _react = require("react");
48
+ const _zustand = require("zustand");
49
+ const _traditional = require("zustand/traditional");
50
+ const _shallow = require("zustand/shallow");
51
+ const _middleware = require("zustand/middleware");
52
+ const _immer = require("zustand/middleware/immer");
53
+ const _AnnotationHydrationWrapper = require("./AnnotationHydrationWrapper");
54
+ const AnnotationStoreContext = /*#__PURE__*/ (0, _react.createContext)(undefined);
55
+ function useAnnotationStoreCtx() {
56
+ const context = (0, _react.useContext)(AnnotationStoreContext);
57
+ if (!context) {
58
+ return createAnnotationStore({
59
+ initialAnnotationSpecs: []
60
+ });
61
+ }
62
+ return context;
63
+ }
64
+ function useAnnotationSpecs() {
65
+ const store = useAnnotationStoreCtx();
66
+ return (0, _zustand.useStore)(store, (s)=>s.annotationSpecs);
67
+ }
68
+ function useAnnotationStates(annotationNames) {
69
+ const store = useAnnotationStoreCtx();
70
+ return (0, _traditional.useStoreWithEqualityFn)(store, (s)=>{
71
+ if (annotationNames) {
72
+ const result = {};
73
+ annotationNames.forEach((name)=>{
74
+ const s = store.getState().annotationState[name];
75
+ if (s) {
76
+ result[name] = s;
77
+ }
78
+ });
79
+ return result;
80
+ }
81
+ return s.annotationState;
82
+ }, (left, right)=>{
83
+ return JSON.stringify(left) === JSON.stringify(right);
84
+ });
85
+ }
86
+ function useAnnotationActions() {
87
+ const store = useAnnotationStoreCtx();
88
+ return (0, _traditional.useStoreWithEqualityFn)(store, (s)=>{
89
+ return {
90
+ setAnnotationState: s.setAnnotationState,
91
+ setAnnotationSpecs: s.setAnnotationSpecs
92
+ };
93
+ }, _shallow.shallow);
94
+ }
95
+ function useAnnotationSpecAndState(name) {
96
+ const store = useAnnotationStoreCtx();
97
+ return (0, _zustand.useStore)(store, (s)=>{
98
+ return {
99
+ definition: s.annotationSpecs.find((d)=>d.display.name === name),
100
+ state: s.annotationState[name]
101
+ };
102
+ });
103
+ }
104
+ function useAnnotationsWithData() {
105
+ const store = useAnnotationStoreCtx();
106
+ return (0, _zustand.useStore)(store, (s)=>{
107
+ return s.annotationSpecs.map((definition)=>{
108
+ const state = s.annotationState[definition.display.name];
109
+ return {
110
+ definition,
111
+ data: state?.data
112
+ };
113
+ }).filter((annotation)=>!!annotation.data);
114
+ });
115
+ }
116
+ function createAnnotationStore({ initialAnnotationSpecs = [] }) {
117
+ const store = (0, _zustand.createStore)()((0, _middleware.devtools)((0, _immer.immer)((set, _get)=>({
118
+ annotationSpecs: initialAnnotationSpecs,
119
+ annotationState: {},
120
+ setAnnotationSpecs (definitions) {
121
+ set((s)=>{
122
+ s.annotationSpecs = definitions;
123
+ }, false, '[Annotations] setAnnotationSpecs' // Used for action name in Redux devtools
124
+ );
125
+ },
126
+ setAnnotationState: (name, state)=>{
127
+ set((s)=>{
128
+ s.annotationState[name] = state;
129
+ }, false, '[Annotations] setAnnotationState' // Used for action name in Redux devtools
130
+ );
131
+ }
132
+ }))));
133
+ return store;
134
+ }
135
+ function AnnotationProvider({ children, initialAnnotationSpecs = [] }) {
136
+ const [store] = (0, _react.useState)(()=>createAnnotationStore({
137
+ initialAnnotationSpecs
138
+ }));
139
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(AnnotationStoreContext.Provider, {
140
+ value: store,
141
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_AnnotationHydrationWrapper.AnnotationHydrationWrapper, {
142
+ children: children
143
+ })
144
+ });
145
+ }
@@ -14,3 +14,17 @@
14
14
  Object.defineProperty(exports, "__esModule", {
15
15
  value: true
16
16
  });
17
+ _export_star(require("./AnnotationProvider"), exports);
18
+ function _export_star(from, to) {
19
+ Object.keys(from).forEach(function(k) {
20
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
21
+ Object.defineProperty(to, k, {
22
+ enumerable: true,
23
+ get: function() {
24
+ return from[k];
25
+ }
26
+ });
27
+ }
28
+ });
29
+ return from;
30
+ }