@perses-dev/dashboards 0.52.0 → 0.53.0-beta.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.
- package/dist/cjs/components/DashboardStickyToolbar/DashboardStickyToolbar.js +0 -2
- package/dist/cjs/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js +5 -20
- package/dist/cjs/components/GridLayout/GridItemContent.js +6 -64
- package/dist/cjs/components/LeaveDialog/LeaveDialog.js +10 -1
- package/dist/cjs/components/PanelDrawer/PanelEditorForm.js +186 -183
- package/dist/cjs/components/PanelDrawer/PanelPreview.js +3 -0
- package/dist/cjs/components/PanelGroupDialog/PanelGroupDialog.js +6 -21
- package/dist/cjs/components/QueryViewerDialog/QueryViewerDialog.js +121 -0
- package/dist/cjs/components/QueryViewerDialog/index.js +30 -0
- package/dist/cjs/components/Variables/ListVariableListBox.js +201 -0
- package/dist/cjs/components/Variables/Variable.js +130 -72
- package/dist/cjs/components/Variables/index.js +1 -0
- package/dist/cjs/components/index.js +2 -1
- package/dist/cjs/context/PanelEditorProvider/PanelEditorProvider.js +49 -0
- package/dist/cjs/context/PanelEditorProvider/index.js +23 -0
- package/dist/cjs/context/index.js +1 -0
- package/dist/components/DashboardStickyToolbar/DashboardStickyToolbar.d.ts.map +1 -1
- package/dist/components/DashboardStickyToolbar/DashboardStickyToolbar.js +0 -2
- package/dist/components/DashboardStickyToolbar/DashboardStickyToolbar.js.map +1 -1
- package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.d.ts.map +1 -1
- package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js +5 -15
- package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js.map +1 -1
- package/dist/components/GridLayout/GridItemContent.d.ts.map +1 -1
- package/dist/components/GridLayout/GridItemContent.js +8 -66
- package/dist/components/GridLayout/GridItemContent.js.map +1 -1
- package/dist/components/LeaveDialog/LeaveDialog.d.ts +2 -1
- package/dist/components/LeaveDialog/LeaveDialog.d.ts.map +1 -1
- package/dist/components/LeaveDialog/LeaveDialog.js +10 -1
- package/dist/components/LeaveDialog/LeaveDialog.js.map +1 -1
- package/dist/components/PanelDrawer/PanelEditorForm.d.ts.map +1 -1
- package/dist/components/PanelDrawer/PanelEditorForm.js +186 -183
- package/dist/components/PanelDrawer/PanelEditorForm.js.map +1 -1
- package/dist/components/PanelDrawer/PanelPreview.d.ts.map +1 -1
- package/dist/components/PanelDrawer/PanelPreview.js +4 -1
- package/dist/components/PanelDrawer/PanelPreview.js.map +1 -1
- package/dist/components/PanelGroupDialog/PanelGroupDialog.d.ts.map +1 -1
- package/dist/components/PanelGroupDialog/PanelGroupDialog.js +5 -15
- package/dist/components/PanelGroupDialog/PanelGroupDialog.js.map +1 -1
- package/dist/components/QueryViewerDialog/QueryViewerDialog.d.ts +9 -0
- package/dist/components/QueryViewerDialog/QueryViewerDialog.d.ts.map +1 -0
- package/dist/components/QueryViewerDialog/QueryViewerDialog.js +72 -0
- package/dist/components/QueryViewerDialog/QueryViewerDialog.js.map +1 -0
- package/dist/components/QueryViewerDialog/index.d.ts +2 -0
- package/dist/components/QueryViewerDialog/index.d.ts.map +1 -0
- package/dist/components/QueryViewerDialog/index.js +15 -0
- package/dist/components/QueryViewerDialog/index.js.map +1 -0
- package/dist/components/Variables/ListVariableListBox.d.ts +16 -0
- package/dist/components/Variables/ListVariableListBox.d.ts.map +1 -0
- package/dist/components/Variables/ListVariableListBox.js +141 -0
- package/dist/components/Variables/ListVariableListBox.js.map +1 -0
- package/dist/components/Variables/Variable.d.ts.map +1 -1
- package/dist/components/Variables/Variable.js +134 -76
- package/dist/components/Variables/Variable.js.map +1 -1
- package/dist/components/Variables/index.d.ts +1 -0
- package/dist/components/Variables/index.d.ts.map +1 -1
- package/dist/components/Variables/index.js +1 -0
- package/dist/components/Variables/index.js.map +1 -1
- package/dist/components/index.d.ts +2 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -1
- package/dist/components/index.js.map +1 -1
- package/dist/context/PanelEditorProvider/PanelEditorProvider.d.ts +13 -0
- package/dist/context/PanelEditorProvider/PanelEditorProvider.d.ts.map +1 -0
- package/dist/context/PanelEditorProvider/PanelEditorProvider.js +33 -0
- package/dist/context/PanelEditorProvider/PanelEditorProvider.js.map +1 -0
- package/dist/context/PanelEditorProvider/index.d.ts +3 -0
- package/dist/context/PanelEditorProvider/index.d.ts.map +1 -0
- package/dist/context/PanelEditorProvider/index.js +16 -0
- package/dist/context/PanelEditorProvider/index.js.map +1 -0
- package/dist/context/index.d.ts +1 -0
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +1 -0
- package/dist/context/index.js.map +1 -1
- package/package.json +5 -5
|
@@ -19,6 +19,7 @@ import { PluginKindSelect, usePluginEditor, PanelSpecEditor, getTitleAction, get
|
|
|
19
19
|
import { Controller, FormProvider, useForm, useWatch } from 'react-hook-form';
|
|
20
20
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
21
21
|
import { useDashboard, useListPanelGroups } from '../../context';
|
|
22
|
+
import { PanelEditorProvider } from '../../context/PanelEditorProvider/PanelEditorProvider';
|
|
22
23
|
import { PanelPreview } from './PanelPreview';
|
|
23
24
|
import { usePanelEditor } from './usePanelEditor';
|
|
24
25
|
export function PanelEditorForm(props) {
|
|
@@ -122,200 +123,202 @@ export function PanelEditorForm(props) {
|
|
|
122
123
|
]);
|
|
123
124
|
return /*#__PURE__*/ _jsx(TimeRangeProvider, {
|
|
124
125
|
timeRange: timeRange,
|
|
125
|
-
children: /*#__PURE__*/
|
|
126
|
+
children: /*#__PURE__*/ _jsx(FormProvider, {
|
|
126
127
|
...form,
|
|
127
|
-
children:
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
/*#__PURE__*/ _jsxs(Typography, {
|
|
137
|
-
variant: "h2",
|
|
138
|
-
children: [
|
|
139
|
-
titleAction,
|
|
140
|
-
" Panel"
|
|
141
|
-
]
|
|
142
|
-
}),
|
|
143
|
-
/*#__PURE__*/ _jsxs(Stack, {
|
|
144
|
-
direction: "row",
|
|
145
|
-
spacing: 1,
|
|
146
|
-
marginLeft: "auto",
|
|
147
|
-
children: [
|
|
148
|
-
/*#__PURE__*/ _jsx(Button, {
|
|
149
|
-
variant: "contained",
|
|
150
|
-
disabled: !form.formState.isValid,
|
|
151
|
-
onClick: handleSubmit,
|
|
152
|
-
children: submitText
|
|
153
|
-
}),
|
|
154
|
-
/*#__PURE__*/ _jsx(Button, {
|
|
155
|
-
color: "secondary",
|
|
156
|
-
variant: "outlined",
|
|
157
|
-
onClick: handleCancel,
|
|
158
|
-
children: "Cancel"
|
|
159
|
-
})
|
|
160
|
-
]
|
|
161
|
-
})
|
|
162
|
-
]
|
|
163
|
-
}),
|
|
164
|
-
/*#__PURE__*/ _jsx(Box, {
|
|
165
|
-
id: panelEditorFormId,
|
|
166
|
-
sx: {
|
|
167
|
-
flex: 1,
|
|
168
|
-
overflowY: 'scroll',
|
|
169
|
-
padding: (theme)=>theme.spacing(2)
|
|
170
|
-
},
|
|
171
|
-
children: /*#__PURE__*/ _jsxs(Grid, {
|
|
172
|
-
container: true,
|
|
173
|
-
spacing: 2,
|
|
128
|
+
children: /*#__PURE__*/ _jsxs(PanelEditorProvider, {
|
|
129
|
+
children: [
|
|
130
|
+
/*#__PURE__*/ _jsxs(Box, {
|
|
131
|
+
sx: {
|
|
132
|
+
display: 'flex',
|
|
133
|
+
alignItems: 'center',
|
|
134
|
+
padding: (theme)=>theme.spacing(1, 2),
|
|
135
|
+
borderBottom: (theme)=>`1px solid ${theme.palette.divider}`
|
|
136
|
+
},
|
|
174
137
|
children: [
|
|
175
|
-
/*#__PURE__*/
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
render: ({ field, fieldState })=>/*#__PURE__*/ _jsx(TextField, {
|
|
182
|
-
...field,
|
|
183
|
-
required: true,
|
|
184
|
-
fullWidth: true,
|
|
185
|
-
label: "Name",
|
|
186
|
-
error: !!fieldState.error,
|
|
187
|
-
helperText: fieldState.error?.message,
|
|
188
|
-
value: watchedName ?? '',
|
|
189
|
-
onChange: (event)=>{
|
|
190
|
-
field.onChange(event);
|
|
191
|
-
setName(event.target.value);
|
|
192
|
-
}
|
|
193
|
-
})
|
|
194
|
-
})
|
|
195
|
-
}),
|
|
196
|
-
/*#__PURE__*/ _jsx(Grid, {
|
|
197
|
-
item: true,
|
|
198
|
-
xs: 4,
|
|
199
|
-
children: /*#__PURE__*/ _jsx(Controller, {
|
|
200
|
-
control: form.control,
|
|
201
|
-
name: "groupId",
|
|
202
|
-
render: ({ field, fieldState })=>/*#__PURE__*/ _jsx(TextField, {
|
|
203
|
-
select: true,
|
|
204
|
-
...field,
|
|
205
|
-
required: true,
|
|
206
|
-
fullWidth: true,
|
|
207
|
-
label: "Group",
|
|
208
|
-
error: !!fieldState.error,
|
|
209
|
-
helperText: fieldState.error?.message,
|
|
210
|
-
onChange: (event)=>{
|
|
211
|
-
field.onChange(event);
|
|
212
|
-
},
|
|
213
|
-
children: panelGroups.map((panelGroup, index)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
214
|
-
value: panelGroup.id,
|
|
215
|
-
children: panelGroup.title ?? `Group ${index + 1}`
|
|
216
|
-
}, panelGroup.id))
|
|
217
|
-
})
|
|
218
|
-
})
|
|
219
|
-
}),
|
|
220
|
-
/*#__PURE__*/ _jsx(Grid, {
|
|
221
|
-
item: true,
|
|
222
|
-
xs: 8,
|
|
223
|
-
children: /*#__PURE__*/ _jsx(Controller, {
|
|
224
|
-
control: form.control,
|
|
225
|
-
name: "panelDefinition.spec.display.description",
|
|
226
|
-
render: ({ field, fieldState })=>/*#__PURE__*/ _jsx(TextField, {
|
|
227
|
-
...field,
|
|
228
|
-
fullWidth: true,
|
|
229
|
-
label: "Description",
|
|
230
|
-
error: !!fieldState.error,
|
|
231
|
-
helperText: fieldState.error?.message,
|
|
232
|
-
value: watchedDescription ?? '',
|
|
233
|
-
onChange: (event)=>{
|
|
234
|
-
field.onChange(event);
|
|
235
|
-
setDescription(event.target.value);
|
|
236
|
-
}
|
|
237
|
-
})
|
|
238
|
-
})
|
|
239
|
-
}),
|
|
240
|
-
/*#__PURE__*/ _jsx(Grid, {
|
|
241
|
-
item: true,
|
|
242
|
-
xs: 4,
|
|
243
|
-
children: /*#__PURE__*/ _jsx(Controller, {
|
|
244
|
-
control: form.control,
|
|
245
|
-
name: "panelDefinition.spec.plugin.kind",
|
|
246
|
-
render: ({ field, fieldState })=>/*#__PURE__*/ _jsx(PluginKindSelect, {
|
|
247
|
-
...field,
|
|
248
|
-
pluginTypes: [
|
|
249
|
-
'Panel'
|
|
250
|
-
],
|
|
251
|
-
required: true,
|
|
252
|
-
fullWidth: true,
|
|
253
|
-
label: "Type",
|
|
254
|
-
disabled: pluginEditor.isLoading,
|
|
255
|
-
error: !!pluginEditor.error || !!fieldState.error,
|
|
256
|
-
helperText: pluginEditor.error?.message ?? fieldState.error?.message,
|
|
257
|
-
value: {
|
|
258
|
-
type: 'Panel',
|
|
259
|
-
kind: watchedPluginKind
|
|
260
|
-
},
|
|
261
|
-
onChange: (event)=>{
|
|
262
|
-
field.onChange(event.kind);
|
|
263
|
-
pluginEditor.onSelectionChange(event);
|
|
264
|
-
}
|
|
265
|
-
})
|
|
266
|
-
})
|
|
138
|
+
/*#__PURE__*/ _jsxs(Typography, {
|
|
139
|
+
variant: "h2",
|
|
140
|
+
children: [
|
|
141
|
+
titleAction,
|
|
142
|
+
" Panel"
|
|
143
|
+
]
|
|
267
144
|
}),
|
|
268
|
-
/*#__PURE__*/ _jsxs(
|
|
269
|
-
|
|
270
|
-
|
|
145
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
146
|
+
direction: "row",
|
|
147
|
+
spacing: 1,
|
|
148
|
+
marginLeft: "auto",
|
|
271
149
|
children: [
|
|
272
|
-
/*#__PURE__*/ _jsx(
|
|
273
|
-
variant: "
|
|
274
|
-
|
|
275
|
-
|
|
150
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
151
|
+
variant: "contained",
|
|
152
|
+
disabled: !form.formState.isValid,
|
|
153
|
+
onClick: handleSubmit,
|
|
154
|
+
children: submitText
|
|
276
155
|
}),
|
|
277
|
-
/*#__PURE__*/ _jsx(
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
156
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
157
|
+
color: "secondary",
|
|
158
|
+
variant: "outlined",
|
|
159
|
+
onClick: handleCancel,
|
|
160
|
+
children: "Cancel"
|
|
282
161
|
})
|
|
283
162
|
]
|
|
284
|
-
})
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
163
|
+
})
|
|
164
|
+
]
|
|
165
|
+
}),
|
|
166
|
+
/*#__PURE__*/ _jsx(Box, {
|
|
167
|
+
id: panelEditorFormId,
|
|
168
|
+
sx: {
|
|
169
|
+
flex: 1,
|
|
170
|
+
overflowY: 'scroll',
|
|
171
|
+
padding: (theme)=>theme.spacing(2)
|
|
172
|
+
},
|
|
173
|
+
children: /*#__PURE__*/ _jsxs(Grid, {
|
|
174
|
+
container: true,
|
|
175
|
+
spacing: 2,
|
|
176
|
+
children: [
|
|
177
|
+
/*#__PURE__*/ _jsx(Grid, {
|
|
178
|
+
item: true,
|
|
179
|
+
xs: 8,
|
|
180
|
+
children: /*#__PURE__*/ _jsx(Controller, {
|
|
181
|
+
control: form.control,
|
|
182
|
+
name: "panelDefinition.spec.display.name",
|
|
183
|
+
render: ({ field, fieldState })=>/*#__PURE__*/ _jsx(TextField, {
|
|
184
|
+
...field,
|
|
185
|
+
required: true,
|
|
186
|
+
fullWidth: true,
|
|
187
|
+
label: "Name",
|
|
188
|
+
error: !!fieldState.error,
|
|
189
|
+
helperText: fieldState.error?.message,
|
|
190
|
+
value: watchedName ?? '',
|
|
191
|
+
onChange: (event)=>{
|
|
192
|
+
field.onChange(event);
|
|
193
|
+
setName(event.target.value);
|
|
194
|
+
}
|
|
195
|
+
})
|
|
196
|
+
})
|
|
197
|
+
}),
|
|
198
|
+
/*#__PURE__*/ _jsx(Grid, {
|
|
199
|
+
item: true,
|
|
200
|
+
xs: 4,
|
|
201
|
+
children: /*#__PURE__*/ _jsx(Controller, {
|
|
202
|
+
control: form.control,
|
|
203
|
+
name: "groupId",
|
|
204
|
+
render: ({ field, fieldState })=>/*#__PURE__*/ _jsx(TextField, {
|
|
205
|
+
select: true,
|
|
206
|
+
...field,
|
|
207
|
+
required: true,
|
|
208
|
+
fullWidth: true,
|
|
209
|
+
label: "Group",
|
|
210
|
+
error: !!fieldState.error,
|
|
211
|
+
helperText: fieldState.error?.message,
|
|
212
|
+
onChange: (event)=>{
|
|
213
|
+
field.onChange(event);
|
|
214
|
+
},
|
|
215
|
+
children: panelGroups.map((panelGroup, index)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
216
|
+
value: panelGroup.id,
|
|
217
|
+
children: panelGroup.title ?? `Group ${index + 1}`
|
|
218
|
+
}, panelGroup.id))
|
|
219
|
+
})
|
|
220
|
+
})
|
|
221
|
+
}),
|
|
222
|
+
/*#__PURE__*/ _jsx(Grid, {
|
|
223
|
+
item: true,
|
|
224
|
+
xs: 8,
|
|
225
|
+
children: /*#__PURE__*/ _jsx(Controller, {
|
|
226
|
+
control: form.control,
|
|
227
|
+
name: "panelDefinition.spec.display.description",
|
|
228
|
+
render: ({ field, fieldState })=>/*#__PURE__*/ _jsx(TextField, {
|
|
229
|
+
...field,
|
|
230
|
+
fullWidth: true,
|
|
231
|
+
label: "Description",
|
|
232
|
+
error: !!fieldState.error,
|
|
233
|
+
helperText: fieldState.error?.message,
|
|
234
|
+
value: watchedDescription ?? '',
|
|
235
|
+
onChange: (event)=>{
|
|
236
|
+
field.onChange(event);
|
|
237
|
+
setDescription(event.target.value);
|
|
238
|
+
}
|
|
239
|
+
})
|
|
240
|
+
})
|
|
241
|
+
}),
|
|
242
|
+
/*#__PURE__*/ _jsx(Grid, {
|
|
243
|
+
item: true,
|
|
244
|
+
xs: 4,
|
|
245
|
+
children: /*#__PURE__*/ _jsx(Controller, {
|
|
292
246
|
control: form.control,
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
247
|
+
name: "panelDefinition.spec.plugin.kind",
|
|
248
|
+
render: ({ field, fieldState })=>/*#__PURE__*/ _jsx(PluginKindSelect, {
|
|
249
|
+
...field,
|
|
250
|
+
pluginTypes: [
|
|
251
|
+
'Panel'
|
|
252
|
+
],
|
|
253
|
+
required: true,
|
|
254
|
+
fullWidth: true,
|
|
255
|
+
label: "Type",
|
|
256
|
+
disabled: pluginEditor.isLoading,
|
|
257
|
+
error: !!pluginEditor.error || !!fieldState.error,
|
|
258
|
+
helperText: pluginEditor.error?.message ?? fieldState.error?.message,
|
|
259
|
+
value: {
|
|
260
|
+
type: 'Panel',
|
|
261
|
+
kind: watchedPluginKind
|
|
262
|
+
},
|
|
263
|
+
onChange: (event)=>{
|
|
264
|
+
field.onChange(event.kind);
|
|
265
|
+
pluginEditor.onSelectionChange(event);
|
|
266
|
+
}
|
|
267
|
+
})
|
|
268
|
+
})
|
|
269
|
+
}),
|
|
270
|
+
/*#__PURE__*/ _jsxs(Grid, {
|
|
271
|
+
item: true,
|
|
272
|
+
xs: 12,
|
|
273
|
+
children: [
|
|
274
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
275
|
+
variant: "h4",
|
|
276
|
+
marginBottom: 1,
|
|
277
|
+
children: "Preview"
|
|
278
|
+
}),
|
|
279
|
+
/*#__PURE__*/ _jsx(ErrorBoundary, {
|
|
280
|
+
FallbackComponent: ErrorAlert,
|
|
281
|
+
children: /*#__PURE__*/ _jsx(PanelPreview, {
|
|
282
|
+
panelDefinition: panelDefinition
|
|
283
|
+
})
|
|
284
|
+
})
|
|
285
|
+
]
|
|
286
|
+
}),
|
|
287
|
+
/*#__PURE__*/ _jsx(Grid, {
|
|
288
|
+
item: true,
|
|
289
|
+
xs: 12,
|
|
290
|
+
children: /*#__PURE__*/ _jsx(ErrorBoundary, {
|
|
291
|
+
FallbackComponent: ErrorAlert,
|
|
292
|
+
children: /*#__PURE__*/ _jsx(PanelSpecEditor, {
|
|
293
|
+
ref: pluginEditorRef,
|
|
294
|
+
control: form.control,
|
|
295
|
+
panelDefinition: panelDefinition,
|
|
296
|
+
onJSONChange: handlePanelDefinitionChange,
|
|
297
|
+
onQueriesChange: (queries)=>{
|
|
298
|
+
setQueries(queries);
|
|
299
|
+
},
|
|
300
|
+
onPluginSpecChange: (spec)=>{
|
|
301
|
+
pluginEditor.onSpecChange(spec);
|
|
302
|
+
}
|
|
303
|
+
})
|
|
301
304
|
})
|
|
302
305
|
})
|
|
303
|
-
|
|
304
|
-
|
|
306
|
+
]
|
|
307
|
+
})
|
|
308
|
+
}),
|
|
309
|
+
/*#__PURE__*/ _jsx(DiscardChangesConfirmationDialog, {
|
|
310
|
+
description: "You have unapplied changes in this panel. Are you sure you want to discard these changes? Changes cannot be recovered.",
|
|
311
|
+
isOpen: isDiscardDialogOpened,
|
|
312
|
+
onCancel: ()=>{
|
|
313
|
+
setDiscardDialogOpened(false);
|
|
314
|
+
},
|
|
315
|
+
onDiscardChanges: ()=>{
|
|
316
|
+
setDiscardDialogOpened(false);
|
|
317
|
+
onClose();
|
|
318
|
+
}
|
|
305
319
|
})
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
description: "You have unapplied changes in this panel. Are you sure you want to discard these changes? Changes cannot be recovered.",
|
|
309
|
-
isOpen: isDiscardDialogOpened,
|
|
310
|
-
onCancel: ()=>{
|
|
311
|
-
setDiscardDialogOpened(false);
|
|
312
|
-
},
|
|
313
|
-
onDiscardChanges: ()=>{
|
|
314
|
-
setDiscardDialogOpened(false);
|
|
315
|
-
onClose();
|
|
316
|
-
}
|
|
317
|
-
})
|
|
318
|
-
]
|
|
320
|
+
]
|
|
321
|
+
})
|
|
319
322
|
})
|
|
320
323
|
});
|
|
321
324
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/PanelDrawer/PanelEditorForm.tsx"],"sourcesContent":["// Copyright 2023 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 { ReactElement, useCallback, useEffect, useRef, useState } from 'react';\nimport { Box, Button, Grid, MenuItem, Stack, TextField, Typography } from '@mui/material';\nimport { Action, DEFAULT_DASHBOARD_DURATION, PanelDefinition, PanelEditorValues } from '@perses-dev/core';\nimport { DiscardChangesConfirmationDialog, ErrorAlert, ErrorBoundary } from '@perses-dev/components';\nimport {\n PluginKindSelect,\n usePluginEditor,\n PanelSpecEditor,\n getTitleAction,\n getSubmitText,\n useValidationSchemas,\n PluginEditorRef,\n TimeRangeProvider,\n useTimeRangeParams,\n useInitialTimeRange,\n} from '@perses-dev/plugin-system';\nimport { Controller, FormProvider, SubmitHandler, useForm, useWatch } from 'react-hook-form';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useDashboard, useListPanelGroups } from '../../context';\nimport { PanelPreview } from './PanelPreview';\nimport { usePanelEditor } from './usePanelEditor';\n\nexport interface PanelEditorFormProps {\n initialValues: PanelEditorValues;\n initialAction: Action;\n onSave: (values: PanelEditorValues) => void;\n onClose: () => void;\n}\n\nexport function PanelEditorForm(props: PanelEditorFormProps): ReactElement {\n const { initialValues, initialAction, onSave, onClose } = props;\n const pluginEditorRef = useRef<PluginEditorRef>(null);\n const panelGroups = useListPanelGroups();\n const { panelDefinition, setName, setDescription, setLinks, setQueries, setPlugin, setPanelDefinition } =\n usePanelEditor(initialValues.panelDefinition);\n const { plugin } = panelDefinition.spec;\n const [isDiscardDialogOpened, setDiscardDialogOpened] = useState<boolean>(false);\n\n const { panelEditorSchema } = useValidationSchemas();\n const form = useForm<PanelEditorValues>({\n resolver: zodResolver(panelEditorSchema),\n mode: 'onBlur',\n defaultValues: initialValues,\n });\n\n const { dashboard } = useDashboard();\n const dashboardDuration = dashboard?.kind === 'Dashboard' ? dashboard.spec.duration : DEFAULT_DASHBOARD_DURATION;\n const initialTimeRange = useInitialTimeRange(dashboardDuration);\n\n // Use common plugin editor logic even though we've split the inputs up in this form\n const pluginEditor = usePluginEditor({\n pluginTypes: ['Panel'],\n value: { selection: { kind: plugin.kind, type: 'Panel' }, spec: plugin.spec },\n onChange: (plugin) => {\n form.setValue('panelDefinition.spec.plugin', { kind: plugin.selection.kind, spec: plugin.spec });\n setPlugin({\n kind: plugin.selection.kind,\n spec: plugin.spec,\n });\n },\n onHideQueryEditorChange: (isHidden) => {\n setQueries(undefined, isHidden);\n },\n });\n\n const titleAction = getTitleAction(initialAction, true);\n const submitText = getSubmitText(initialAction, true);\n\n const links = useWatch({ control: form.control, name: 'panelDefinition.spec.links' });\n useEffect(() => {\n setLinks(links);\n }, [setLinks, links]);\n\n const processForm: SubmitHandler<PanelEditorValues> = useCallback(\n (data) => {\n onSave(data);\n },\n [onSave]\n );\n\n // When user click on cancel, several possibilities:\n // - create action: ask for discard approval\n // - update action: ask for discard approval if changed\n // - read action: don´t ask for discard approval\n function handleCancel(): void {\n if (JSON.stringify(initialValues) !== JSON.stringify(form.getValues())) {\n setDiscardDialogOpened(true);\n } else {\n onClose();\n }\n }\n\n const handlePanelDefinitionChange = (nextPanelDefStr: string): void => {\n const nextPanelDef: PanelDefinition = JSON.parse(nextPanelDefStr);\n const { kind: pluginKind, spec: pluginSpec } = nextPanelDef.spec.plugin;\n // if panel plugin kind and spec are modified, then need to save current spec\n if (\n panelDefinition.spec.plugin.kind !== pluginKind &&\n JSON.stringify(panelDefinition.spec.plugin.spec) !== JSON.stringify(pluginSpec)\n ) {\n pluginEditor.rememberCurrentSpecState();\n }\n setPanelDefinition(nextPanelDef);\n };\n\n const watchedName = useWatch({ control: form.control, name: 'panelDefinition.spec.display.name' });\n const watchedDescription = useWatch({ control: form.control, name: 'panelDefinition.spec.display.description' });\n const watchedPluginKind = useWatch({ control: form.control, name: 'panelDefinition.spec.plugin.kind' });\n const { timeRange } = useTimeRangeParams(initialTimeRange);\n\n const handleSubmit = useCallback(() => {\n pluginEditorRef.current?.flushChanges?.();\n form.handleSubmit(processForm)();\n }, [form, processForm]);\n\n return (\n <TimeRangeProvider timeRange={timeRange}>\n <FormProvider {...form}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n padding: (theme) => theme.spacing(1, 2),\n borderBottom: (theme) => `1px solid ${theme.palette.divider}`,\n }}\n >\n <Typography variant=\"h2\">{titleAction} Panel</Typography>\n <Stack direction=\"row\" spacing={1} marginLeft=\"auto\">\n <Button variant=\"contained\" disabled={!form.formState.isValid} onClick={handleSubmit}>\n {submitText}\n </Button>\n <Button color=\"secondary\" variant=\"outlined\" onClick={handleCancel}>\n Cancel\n </Button>\n </Stack>\n </Box>\n <Box id={panelEditorFormId} sx={{ flex: 1, overflowY: 'scroll', padding: (theme) => theme.spacing(2) }}>\n <Grid container spacing={2}>\n <Grid item xs={8}>\n <Controller\n control={form.control}\n name=\"panelDefinition.spec.display.name\"\n render={({ field, fieldState }) => (\n <TextField\n {...field}\n required\n fullWidth\n label=\"Name\"\n error={!!fieldState.error}\n helperText={fieldState.error?.message}\n value={watchedName ?? ''}\n onChange={(event) => {\n field.onChange(event);\n setName(event.target.value);\n }}\n />\n )}\n />\n </Grid>\n <Grid item xs={4}>\n <Controller\n control={form.control}\n name=\"groupId\"\n render={({ field, fieldState }) => (\n <TextField\n select\n {...field}\n required\n fullWidth\n label=\"Group\"\n error={!!fieldState.error}\n helperText={fieldState.error?.message}\n onChange={(event) => {\n field.onChange(event);\n }}\n >\n {panelGroups.map((panelGroup, index) => (\n <MenuItem key={panelGroup.id} value={panelGroup.id}>\n {panelGroup.title ?? `Group ${index + 1}`}\n </MenuItem>\n ))}\n </TextField>\n )}\n />\n </Grid>\n <Grid item xs={8}>\n <Controller\n control={form.control}\n name=\"panelDefinition.spec.display.description\"\n render={({ field, fieldState }) => (\n <TextField\n {...field}\n fullWidth\n label=\"Description\"\n error={!!fieldState.error}\n helperText={fieldState.error?.message}\n value={watchedDescription ?? ''}\n onChange={(event) => {\n field.onChange(event);\n setDescription(event.target.value);\n }}\n />\n )}\n />\n </Grid>\n <Grid item xs={4}>\n <Controller\n control={form.control}\n name=\"panelDefinition.spec.plugin.kind\"\n render={({ field, fieldState }) => (\n <PluginKindSelect\n {...field}\n pluginTypes={['Panel']}\n required\n fullWidth\n label=\"Type\"\n disabled={pluginEditor.isLoading}\n error={!!pluginEditor.error || !!fieldState.error}\n helperText={pluginEditor.error?.message ?? fieldState.error?.message}\n value={{ type: 'Panel', kind: watchedPluginKind }}\n onChange={(event) => {\n field.onChange(event.kind);\n pluginEditor.onSelectionChange(event);\n }}\n />\n )}\n />\n </Grid>\n <Grid item xs={12}>\n <Typography variant=\"h4\" marginBottom={1}>\n Preview\n </Typography>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <PanelPreview panelDefinition={panelDefinition} />\n </ErrorBoundary>\n </Grid>\n <Grid item xs={12}>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <PanelSpecEditor\n ref={pluginEditorRef}\n control={form.control}\n panelDefinition={panelDefinition}\n onJSONChange={handlePanelDefinitionChange}\n onQueriesChange={(queries) => {\n setQueries(queries);\n }}\n onPluginSpecChange={(spec) => {\n pluginEditor.onSpecChange(spec);\n }}\n />\n </ErrorBoundary>\n </Grid>\n </Grid>\n </Box>\n <DiscardChangesConfirmationDialog\n description=\"You have unapplied changes in this panel. Are you sure you want to discard these changes? Changes cannot be recovered.\"\n isOpen={isDiscardDialogOpened}\n onCancel={() => {\n setDiscardDialogOpened(false);\n }}\n onDiscardChanges={() => {\n setDiscardDialogOpened(false);\n onClose();\n }}\n />\n </FormProvider>\n </TimeRangeProvider>\n );\n}\n\n/**\n * The `id` attribute added to the `PanelEditorForm` component, allowing submit buttons to live outside the form.\n */\nexport const panelEditorFormId = 'panel-editor-form';\n"],"names":["useCallback","useEffect","useRef","useState","Box","Button","Grid","MenuItem","Stack","TextField","Typography","DEFAULT_DASHBOARD_DURATION","DiscardChangesConfirmationDialog","ErrorAlert","ErrorBoundary","PluginKindSelect","usePluginEditor","PanelSpecEditor","getTitleAction","getSubmitText","useValidationSchemas","TimeRangeProvider","useTimeRangeParams","useInitialTimeRange","Controller","FormProvider","useForm","useWatch","zodResolver","useDashboard","useListPanelGroups","PanelPreview","usePanelEditor","PanelEditorForm","props","initialValues","initialAction","onSave","onClose","pluginEditorRef","panelGroups","panelDefinition","setName","setDescription","setLinks","setQueries","setPlugin","setPanelDefinition","plugin","spec","isDiscardDialogOpened","setDiscardDialogOpened","panelEditorSchema","form","resolver","mode","defaultValues","dashboard","dashboardDuration","kind","duration","initialTimeRange","pluginEditor","pluginTypes","value","selection","type","onChange","setValue","onHideQueryEditorChange","isHidden","undefined","titleAction","submitText","links","control","name","processForm","data","handleCancel","JSON","stringify","getValues","handlePanelDefinitionChange","nextPanelDefStr","nextPanelDef","parse","pluginKind","pluginSpec","rememberCurrentSpecState","watchedName","watchedDescription","watchedPluginKind","timeRange","handleSubmit","current","flushChanges","sx","display","alignItems","padding","theme","spacing","borderBottom","palette","divider","variant","direction","marginLeft","disabled","formState","isValid","onClick","color","id","panelEditorFormId","flex","overflowY","container","item","xs","render","field","fieldState","required","fullWidth","label","error","helperText","message","event","target","select","map","panelGroup","index","title","isLoading","onSelectionChange","marginBottom","FallbackComponent","ref","onJSONChange","onQueriesChange","queries","onPluginSpecChange","onSpecChange","description","isOpen","onCancel","onDiscardChanges"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/PanelDrawer/PanelEditorForm.tsx"],"sourcesContent":["// Copyright 2023 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 { ReactElement, useCallback, useEffect, useRef, useState } from 'react';\nimport { Box, Button, Grid, MenuItem, Stack, TextField, Typography } from '@mui/material';\nimport { Action, DEFAULT_DASHBOARD_DURATION, PanelDefinition, PanelEditorValues } from '@perses-dev/core';\nimport { DiscardChangesConfirmationDialog, ErrorAlert, ErrorBoundary } from '@perses-dev/components';\nimport {\n PluginKindSelect,\n usePluginEditor,\n PanelSpecEditor,\n getTitleAction,\n getSubmitText,\n useValidationSchemas,\n PluginEditorRef,\n TimeRangeProvider,\n useTimeRangeParams,\n useInitialTimeRange,\n} from '@perses-dev/plugin-system';\nimport { Controller, FormProvider, SubmitHandler, useForm, useWatch } from 'react-hook-form';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useDashboard, useListPanelGroups } from '../../context';\nimport { PanelEditorProvider } from '../../context/PanelEditorProvider/PanelEditorProvider';\nimport { PanelPreview } from './PanelPreview';\nimport { usePanelEditor } from './usePanelEditor';\n\nexport interface PanelEditorFormProps {\n initialValues: PanelEditorValues;\n initialAction: Action;\n onSave: (values: PanelEditorValues) => void;\n onClose: () => void;\n}\n\nexport function PanelEditorForm(props: PanelEditorFormProps): ReactElement {\n const { initialValues, initialAction, onSave, onClose } = props;\n const pluginEditorRef = useRef<PluginEditorRef>(null);\n const panelGroups = useListPanelGroups();\n const { panelDefinition, setName, setDescription, setLinks, setQueries, setPlugin, setPanelDefinition } =\n usePanelEditor(initialValues.panelDefinition);\n const { plugin } = panelDefinition.spec;\n const [isDiscardDialogOpened, setDiscardDialogOpened] = useState<boolean>(false);\n\n const { panelEditorSchema } = useValidationSchemas();\n const form = useForm<PanelEditorValues>({\n resolver: zodResolver(panelEditorSchema),\n mode: 'onBlur',\n defaultValues: initialValues,\n });\n\n const { dashboard } = useDashboard();\n const dashboardDuration = dashboard?.kind === 'Dashboard' ? dashboard.spec.duration : DEFAULT_DASHBOARD_DURATION;\n const initialTimeRange = useInitialTimeRange(dashboardDuration);\n\n // Use common plugin editor logic even though we've split the inputs up in this form\n const pluginEditor = usePluginEditor({\n pluginTypes: ['Panel'],\n value: { selection: { kind: plugin.kind, type: 'Panel' }, spec: plugin.spec },\n onChange: (plugin) => {\n form.setValue('panelDefinition.spec.plugin', { kind: plugin.selection.kind, spec: plugin.spec });\n setPlugin({\n kind: plugin.selection.kind,\n spec: plugin.spec,\n });\n },\n onHideQueryEditorChange: (isHidden) => {\n setQueries(undefined, isHidden);\n },\n });\n\n const titleAction = getTitleAction(initialAction, true);\n const submitText = getSubmitText(initialAction, true);\n\n const links = useWatch({ control: form.control, name: 'panelDefinition.spec.links' });\n useEffect(() => {\n setLinks(links);\n }, [setLinks, links]);\n\n const processForm: SubmitHandler<PanelEditorValues> = useCallback(\n (data) => {\n onSave(data);\n },\n [onSave]\n );\n\n // When user click on cancel, several possibilities:\n // - create action: ask for discard approval\n // - update action: ask for discard approval if changed\n // - read action: don´t ask for discard approval\n function handleCancel(): void {\n if (JSON.stringify(initialValues) !== JSON.stringify(form.getValues())) {\n setDiscardDialogOpened(true);\n } else {\n onClose();\n }\n }\n\n const handlePanelDefinitionChange = (nextPanelDefStr: string): void => {\n const nextPanelDef: PanelDefinition = JSON.parse(nextPanelDefStr);\n const { kind: pluginKind, spec: pluginSpec } = nextPanelDef.spec.plugin;\n // if panel plugin kind and spec are modified, then need to save current spec\n if (\n panelDefinition.spec.plugin.kind !== pluginKind &&\n JSON.stringify(panelDefinition.spec.plugin.spec) !== JSON.stringify(pluginSpec)\n ) {\n pluginEditor.rememberCurrentSpecState();\n }\n setPanelDefinition(nextPanelDef);\n };\n\n const watchedName = useWatch({ control: form.control, name: 'panelDefinition.spec.display.name' });\n const watchedDescription = useWatch({ control: form.control, name: 'panelDefinition.spec.display.description' });\n const watchedPluginKind = useWatch({ control: form.control, name: 'panelDefinition.spec.plugin.kind' });\n const { timeRange } = useTimeRangeParams(initialTimeRange);\n\n const handleSubmit = useCallback(() => {\n pluginEditorRef.current?.flushChanges?.();\n form.handleSubmit(processForm)();\n }, [form, processForm]);\n\n return (\n <TimeRangeProvider timeRange={timeRange}>\n <FormProvider {...form}>\n <PanelEditorProvider>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n padding: (theme) => theme.spacing(1, 2),\n borderBottom: (theme) => `1px solid ${theme.palette.divider}`,\n }}\n >\n <Typography variant=\"h2\">{titleAction} Panel</Typography>\n <Stack direction=\"row\" spacing={1} marginLeft=\"auto\">\n <Button variant=\"contained\" disabled={!form.formState.isValid} onClick={handleSubmit}>\n {submitText}\n </Button>\n <Button color=\"secondary\" variant=\"outlined\" onClick={handleCancel}>\n Cancel\n </Button>\n </Stack>\n </Box>\n <Box id={panelEditorFormId} sx={{ flex: 1, overflowY: 'scroll', padding: (theme) => theme.spacing(2) }}>\n <Grid container spacing={2}>\n <Grid item xs={8}>\n <Controller\n control={form.control}\n name=\"panelDefinition.spec.display.name\"\n render={({ field, fieldState }) => (\n <TextField\n {...field}\n required\n fullWidth\n label=\"Name\"\n error={!!fieldState.error}\n helperText={fieldState.error?.message}\n value={watchedName ?? ''}\n onChange={(event) => {\n field.onChange(event);\n setName(event.target.value);\n }}\n />\n )}\n />\n </Grid>\n <Grid item xs={4}>\n <Controller\n control={form.control}\n name=\"groupId\"\n render={({ field, fieldState }) => (\n <TextField\n select\n {...field}\n required\n fullWidth\n label=\"Group\"\n error={!!fieldState.error}\n helperText={fieldState.error?.message}\n onChange={(event) => {\n field.onChange(event);\n }}\n >\n {panelGroups.map((panelGroup, index) => (\n <MenuItem key={panelGroup.id} value={panelGroup.id}>\n {panelGroup.title ?? `Group ${index + 1}`}\n </MenuItem>\n ))}\n </TextField>\n )}\n />\n </Grid>\n <Grid item xs={8}>\n <Controller\n control={form.control}\n name=\"panelDefinition.spec.display.description\"\n render={({ field, fieldState }) => (\n <TextField\n {...field}\n fullWidth\n label=\"Description\"\n error={!!fieldState.error}\n helperText={fieldState.error?.message}\n value={watchedDescription ?? ''}\n onChange={(event) => {\n field.onChange(event);\n setDescription(event.target.value);\n }}\n />\n )}\n />\n </Grid>\n <Grid item xs={4}>\n <Controller\n control={form.control}\n name=\"panelDefinition.spec.plugin.kind\"\n render={({ field, fieldState }) => (\n <PluginKindSelect\n {...field}\n pluginTypes={['Panel']}\n required\n fullWidth\n label=\"Type\"\n disabled={pluginEditor.isLoading}\n error={!!pluginEditor.error || !!fieldState.error}\n helperText={pluginEditor.error?.message ?? fieldState.error?.message}\n value={{ type: 'Panel', kind: watchedPluginKind }}\n onChange={(event) => {\n field.onChange(event.kind);\n pluginEditor.onSelectionChange(event);\n }}\n />\n )}\n />\n </Grid>\n\n <Grid item xs={12}>\n <Typography variant=\"h4\" marginBottom={1}>\n Preview\n </Typography>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <PanelPreview panelDefinition={panelDefinition} />\n </ErrorBoundary>\n </Grid>\n <Grid item xs={12}>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <PanelSpecEditor\n ref={pluginEditorRef}\n control={form.control}\n panelDefinition={panelDefinition}\n onJSONChange={handlePanelDefinitionChange}\n onQueriesChange={(queries) => {\n setQueries(queries);\n }}\n onPluginSpecChange={(spec) => {\n pluginEditor.onSpecChange(spec);\n }}\n />\n </ErrorBoundary>\n </Grid>\n </Grid>\n </Box>\n <DiscardChangesConfirmationDialog\n description=\"You have unapplied changes in this panel. Are you sure you want to discard these changes? Changes cannot be recovered.\"\n isOpen={isDiscardDialogOpened}\n onCancel={() => {\n setDiscardDialogOpened(false);\n }}\n onDiscardChanges={() => {\n setDiscardDialogOpened(false);\n onClose();\n }}\n />\n </PanelEditorProvider>\n </FormProvider>\n </TimeRangeProvider>\n );\n}\n\n/**\n * The `id` attribute added to the `PanelEditorForm` component, allowing submit buttons to live outside the form.\n */\nexport const panelEditorFormId = 'panel-editor-form';\n"],"names":["useCallback","useEffect","useRef","useState","Box","Button","Grid","MenuItem","Stack","TextField","Typography","DEFAULT_DASHBOARD_DURATION","DiscardChangesConfirmationDialog","ErrorAlert","ErrorBoundary","PluginKindSelect","usePluginEditor","PanelSpecEditor","getTitleAction","getSubmitText","useValidationSchemas","TimeRangeProvider","useTimeRangeParams","useInitialTimeRange","Controller","FormProvider","useForm","useWatch","zodResolver","useDashboard","useListPanelGroups","PanelEditorProvider","PanelPreview","usePanelEditor","PanelEditorForm","props","initialValues","initialAction","onSave","onClose","pluginEditorRef","panelGroups","panelDefinition","setName","setDescription","setLinks","setQueries","setPlugin","setPanelDefinition","plugin","spec","isDiscardDialogOpened","setDiscardDialogOpened","panelEditorSchema","form","resolver","mode","defaultValues","dashboard","dashboardDuration","kind","duration","initialTimeRange","pluginEditor","pluginTypes","value","selection","type","onChange","setValue","onHideQueryEditorChange","isHidden","undefined","titleAction","submitText","links","control","name","processForm","data","handleCancel","JSON","stringify","getValues","handlePanelDefinitionChange","nextPanelDefStr","nextPanelDef","parse","pluginKind","pluginSpec","rememberCurrentSpecState","watchedName","watchedDescription","watchedPluginKind","timeRange","handleSubmit","current","flushChanges","sx","display","alignItems","padding","theme","spacing","borderBottom","palette","divider","variant","direction","marginLeft","disabled","formState","isValid","onClick","color","id","panelEditorFormId","flex","overflowY","container","item","xs","render","field","fieldState","required","fullWidth","label","error","helperText","message","event","target","select","map","panelGroup","index","title","isLoading","onSelectionChange","marginBottom","FallbackComponent","ref","onJSONChange","onQueriesChange","queries","onPluginSpecChange","onSpecChange","description","isOpen","onCancel","onDiscardChanges"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PanelPreview.d.ts","sourceRoot":"","sources":["../../../src/components/PanelDrawer/PanelPreview.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"PanelPreview.d.ts","sourceRoot":"","sources":["../../../src/components/PanelDrawer/PanelPreview.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAsB,MAAM,OAAO,CAAC;AAGzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAOrD,wBAAgB,YAAY,CAAC,EAAE,eAAe,EAAE,EAAE,IAAI,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,GAAG,YAAY,GAAG,IAAI,CAyCjH"}
|
|
@@ -11,17 +11,20 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
|
-
import { useRef } from 'react';
|
|
14
|
+
import { useContext, useRef } from 'react';
|
|
15
15
|
import { Box } from '@mui/material';
|
|
16
16
|
import { DataQueriesProvider, usePlugin, useSuggestedStepMs } from '@perses-dev/plugin-system';
|
|
17
17
|
import { Panel } from '../Panel';
|
|
18
|
+
import { PanelEditorContext } from '../../context';
|
|
18
19
|
const PANEL_PREVIEW_HEIGHT = 300;
|
|
19
20
|
const PANEL_PREVIEW_DEFAULT_WIDTH = 840;
|
|
20
21
|
export function PanelPreview({ panelDefinition }) {
|
|
21
22
|
const boxRef = useRef(null);
|
|
22
23
|
let width = PANEL_PREVIEW_DEFAULT_WIDTH;
|
|
24
|
+
const panelEditorContext = useContext(PanelEditorContext);
|
|
23
25
|
if (boxRef.current !== null) {
|
|
24
26
|
width = boxRef.current.getBoundingClientRect().width;
|
|
27
|
+
panelEditorContext?.preview?.setPreviewPanelWidth?.(width);
|
|
25
28
|
}
|
|
26
29
|
const suggestedStepMs = useSuggestedStepMs(width);
|
|
27
30
|
const { data: plugin, isLoading } = usePlugin('Panel', panelDefinition.spec.plugin.kind);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/PanelDrawer/PanelPreview.tsx"],"sourcesContent":["// Copyright 2023 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 { ReactElement, useRef } from 'react';\nimport { Box } from '@mui/material';\nimport { DataQueriesProvider, usePlugin, useSuggestedStepMs } from '@perses-dev/plugin-system';\nimport { PanelEditorValues } from '@perses-dev/core';\nimport { Panel } from '../Panel';\n\nconst PANEL_PREVIEW_HEIGHT = 300;\nconst PANEL_PREVIEW_DEFAULT_WIDTH = 840;\n\nexport function PanelPreview({ panelDefinition }: Pick<PanelEditorValues, 'panelDefinition'>): ReactElement | null {\n const boxRef = useRef<HTMLDivElement>(null);\n let width = PANEL_PREVIEW_DEFAULT_WIDTH;\n if (boxRef.current !== null) {\n width = boxRef.current.getBoundingClientRect().width;\n }\n const suggestedStepMs = useSuggestedStepMs(width);\n\n const { data: plugin, isLoading } = usePlugin('Panel', panelDefinition.spec.plugin.kind);\n if (isLoading) {\n return null;\n }\n\n if (panelDefinition.spec.plugin.kind === '') {\n return null;\n }\n\n const queries = panelDefinition.spec.queries ?? [];\n\n // map TimeSeriesQueryDefinition to Definition<UnknownSpec>\n const definitions = queries.length\n ? queries.map((query) => {\n return {\n kind: query.spec.plugin.kind,\n spec: query.spec.plugin.spec,\n };\n })\n : [];\n\n return (\n <Box ref={boxRef} height={PANEL_PREVIEW_HEIGHT}>\n <DataQueriesProvider definitions={definitions} options={{ suggestedStepMs, ...plugin?.queryOptions }}>\n <Panel definition={panelDefinition} />\n </DataQueriesProvider>\n </Box>\n );\n}\n"],"names":["useRef","Box","DataQueriesProvider","usePlugin","useSuggestedStepMs","Panel","PANEL_PREVIEW_HEIGHT","PANEL_PREVIEW_DEFAULT_WIDTH","PanelPreview","panelDefinition","boxRef","width","current","getBoundingClientRect","suggestedStepMs","data","plugin","isLoading","spec","kind","queries","definitions","length","map","query","ref","height","options","queryOptions","definition"],"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,SAAuBA,MAAM,QAAQ,QAAQ;
|
|
1
|
+
{"version":3,"sources":["../../../src/components/PanelDrawer/PanelPreview.tsx"],"sourcesContent":["// Copyright 2023 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 { ReactElement, useContext, useRef } from 'react';\nimport { Box } from '@mui/material';\nimport { DataQueriesProvider, usePlugin, useSuggestedStepMs } from '@perses-dev/plugin-system';\nimport { PanelEditorValues } from '@perses-dev/core';\nimport { Panel } from '../Panel';\nimport { PanelEditorContext } from '../../context';\n\nconst PANEL_PREVIEW_HEIGHT = 300;\nconst PANEL_PREVIEW_DEFAULT_WIDTH = 840;\n\nexport function PanelPreview({ panelDefinition }: Pick<PanelEditorValues, 'panelDefinition'>): ReactElement | null {\n const boxRef = useRef<HTMLDivElement>(null);\n let width = PANEL_PREVIEW_DEFAULT_WIDTH;\n\n const panelEditorContext = useContext(PanelEditorContext);\n\n if (boxRef.current !== null) {\n width = boxRef.current.getBoundingClientRect().width;\n panelEditorContext?.preview?.setPreviewPanelWidth?.(width);\n }\n\n const suggestedStepMs = useSuggestedStepMs(width);\n\n const { data: plugin, isLoading } = usePlugin('Panel', panelDefinition.spec.plugin.kind);\n if (isLoading) {\n return null;\n }\n\n if (panelDefinition.spec.plugin.kind === '') {\n return null;\n }\n\n const queries = panelDefinition.spec.queries ?? [];\n\n // map TimeSeriesQueryDefinition to Definition<UnknownSpec>\n const definitions = queries.length\n ? queries.map((query) => {\n return {\n kind: query.spec.plugin.kind,\n spec: query.spec.plugin.spec,\n };\n })\n : [];\n\n return (\n <Box ref={boxRef} height={PANEL_PREVIEW_HEIGHT}>\n <DataQueriesProvider definitions={definitions} options={{ suggestedStepMs, ...plugin?.queryOptions }}>\n <Panel definition={panelDefinition} />\n </DataQueriesProvider>\n </Box>\n );\n}\n"],"names":["useContext","useRef","Box","DataQueriesProvider","usePlugin","useSuggestedStepMs","Panel","PanelEditorContext","PANEL_PREVIEW_HEIGHT","PANEL_PREVIEW_DEFAULT_WIDTH","PanelPreview","panelDefinition","boxRef","width","panelEditorContext","current","getBoundingClientRect","preview","setPreviewPanelWidth","suggestedStepMs","data","plugin","isLoading","spec","kind","queries","definitions","length","map","query","ref","height","options","queryOptions","definition"],"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,SAAuBA,UAAU,EAAEC,MAAM,QAAQ,QAAQ;AACzD,SAASC,GAAG,QAAQ,gBAAgB;AACpC,SAASC,mBAAmB,EAAEC,SAAS,EAAEC,kBAAkB,QAAQ,4BAA4B;AAE/F,SAASC,KAAK,QAAQ,WAAW;AACjC,SAASC,kBAAkB,QAAQ,gBAAgB;AAEnD,MAAMC,uBAAuB;AAC7B,MAAMC,8BAA8B;AAEpC,OAAO,SAASC,aAAa,EAAEC,eAAe,EAA8C;IAC1F,MAAMC,SAASX,OAAuB;IACtC,IAAIY,QAAQJ;IAEZ,MAAMK,qBAAqBd,WAAWO;IAEtC,IAAIK,OAAOG,OAAO,KAAK,MAAM;QAC3BF,QAAQD,OAAOG,OAAO,CAACC,qBAAqB,GAAGH,KAAK;QACpDC,oBAAoBG,SAASC,uBAAuBL;IACtD;IAEA,MAAMM,kBAAkBd,mBAAmBQ;IAE3C,MAAM,EAAEO,MAAMC,MAAM,EAAEC,SAAS,EAAE,GAAGlB,UAAU,SAASO,gBAAgBY,IAAI,CAACF,MAAM,CAACG,IAAI;IACvF,IAAIF,WAAW;QACb,OAAO;IACT;IAEA,IAAIX,gBAAgBY,IAAI,CAACF,MAAM,CAACG,IAAI,KAAK,IAAI;QAC3C,OAAO;IACT;IAEA,MAAMC,UAAUd,gBAAgBY,IAAI,CAACE,OAAO,IAAI,EAAE;IAElD,2DAA2D;IAC3D,MAAMC,cAAcD,QAAQE,MAAM,GAC9BF,QAAQG,GAAG,CAAC,CAACC;QACX,OAAO;YACLL,MAAMK,MAAMN,IAAI,CAACF,MAAM,CAACG,IAAI;YAC5BD,MAAMM,MAAMN,IAAI,CAACF,MAAM,CAACE,IAAI;QAC9B;IACF,KACA,EAAE;IAEN,qBACE,KAACrB;QAAI4B,KAAKlB;QAAQmB,QAAQvB;kBACxB,cAAA,KAACL;YAAoBuB,aAAaA;YAAaM,SAAS;gBAAEb;gBAAiB,GAAGE,QAAQY,YAAY;YAAC;sBACjG,cAAA,KAAC3B;gBAAM4B,YAAYvB;;;;AAI3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PanelGroupDialog.d.ts","sourceRoot":"","sources":["../../../src/components/PanelGroupDialog/PanelGroupDialog.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PanelGroupDialog.d.ts","sourceRoot":"","sources":["../../../src/components/PanelGroupDialog/PanelGroupDialog.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAY,MAAM,OAAO,CAAC;AAO/C;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,CAkD/C"}
|
|
@@ -11,10 +11,10 @@
|
|
|
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 { IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@mui/material';
|
|
15
|
-
import CloseIcon from 'mdi-material-ui/Close';
|
|
16
14
|
import { useState } from 'react';
|
|
17
15
|
import { useVariableValues } from '@perses-dev/plugin-system';
|
|
16
|
+
import { Dialog } from '@perses-dev/components';
|
|
17
|
+
import { Button } from '@mui/material';
|
|
18
18
|
import { usePanelGroupEditor } from '../../context';
|
|
19
19
|
import { PanelGroupEditorForm, panelGroupEditorFormId } from './PanelGroupEditorForm';
|
|
20
20
|
/**
|
|
@@ -47,23 +47,13 @@ import { PanelGroupEditorForm, panelGroupEditorFormId } from './PanelGroupEditor
|
|
|
47
47
|
},
|
|
48
48
|
children: panelGroupEditor !== undefined && /*#__PURE__*/ _jsxs(_Fragment, {
|
|
49
49
|
children: [
|
|
50
|
-
/*#__PURE__*/ _jsxs(
|
|
50
|
+
/*#__PURE__*/ _jsxs(Dialog.Header, {
|
|
51
51
|
children: [
|
|
52
52
|
panelGroupEditor.mode,
|
|
53
53
|
" Panel Group"
|
|
54
54
|
]
|
|
55
55
|
}),
|
|
56
|
-
/*#__PURE__*/ _jsx(
|
|
57
|
-
"aria-label": "Close",
|
|
58
|
-
onClick: panelGroupEditor.close,
|
|
59
|
-
sx: (theme)=>({
|
|
60
|
-
position: 'absolute',
|
|
61
|
-
top: theme.spacing(0.5),
|
|
62
|
-
right: theme.spacing(0.5)
|
|
63
|
-
}),
|
|
64
|
-
children: /*#__PURE__*/ _jsx(CloseIcon, {})
|
|
65
|
-
}),
|
|
66
|
-
/*#__PURE__*/ _jsx(DialogContent, {
|
|
56
|
+
/*#__PURE__*/ _jsx(Dialog.Content, {
|
|
67
57
|
dividers: true,
|
|
68
58
|
sx: {
|
|
69
59
|
width: '500px'
|
|
@@ -74,7 +64,7 @@ import { PanelGroupEditorForm, panelGroupEditorFormId } from './PanelGroupEditor
|
|
|
74
64
|
onSubmit: handleSubmit
|
|
75
65
|
})
|
|
76
66
|
}),
|
|
77
|
-
/*#__PURE__*/ _jsxs(
|
|
67
|
+
/*#__PURE__*/ _jsxs(Dialog.Actions, {
|
|
78
68
|
children: [
|
|
79
69
|
/*#__PURE__*/ _jsx(Button, {
|
|
80
70
|
variant: "contained",
|