@perses-dev/plugin-system 0.54.0 → 0.55.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/PanelSpecEditor/PanelAnnotationsEditor.js +246 -0
- package/dist/cjs/components/PanelSpecEditor/PanelSpecEditor.js +16 -1
- package/dist/cjs/components/PluginRegistry/PluginRegistry.js +4 -0
- package/dist/cjs/remote/PluginRuntime.js +12 -12
- package/dist/cjs/remote/remotePluginLoader.js +3 -1
- package/dist/cjs/runtime/UsageMetricsProvider.js +4 -2
- package/dist/cjs/runtime/item-actions.js +9 -10
- package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.d.ts +15 -0
- package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.d.ts.map +1 -0
- package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.js +238 -0
- package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.js.map +1 -0
- package/dist/components/PanelSpecEditor/PanelSpecEditor.d.ts.map +1 -1
- package/dist/components/PanelSpecEditor/PanelSpecEditor.js +16 -1
- package/dist/components/PanelSpecEditor/PanelSpecEditor.js.map +1 -1
- package/dist/components/PluginRegistry/PluginRegistry.d.ts.map +1 -1
- package/dist/components/PluginRegistry/PluginRegistry.js +4 -0
- package/dist/components/PluginRegistry/PluginRegistry.js.map +1 -1
- package/dist/model/panels.d.ts +6 -0
- package/dist/model/panels.d.ts.map +1 -1
- package/dist/model/panels.js.map +1 -1
- package/dist/remote/PluginRuntime.js +12 -12
- package/dist/remote/PluginRuntime.js.map +1 -1
- package/dist/remote/remotePluginLoader.d.ts +5 -0
- package/dist/remote/remotePluginLoader.d.ts.map +1 -1
- package/dist/remote/remotePluginLoader.js +3 -1
- package/dist/remote/remotePluginLoader.js.map +1 -1
- package/dist/runtime/UsageMetricsProvider.d.ts +2 -0
- package/dist/runtime/UsageMetricsProvider.d.ts.map +1 -1
- package/dist/runtime/UsageMetricsProvider.js +5 -3
- package/dist/runtime/UsageMetricsProvider.js.map +1 -1
- package/dist/runtime/item-actions.d.ts +3 -0
- package/dist/runtime/item-actions.d.ts.map +1 -1
- package/dist/runtime/item-actions.js +9 -10
- package/dist/runtime/item-actions.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,246 @@
|
|
|
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, "PanelAnnotationsEditor", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: function() {
|
|
20
|
+
return PanelAnnotationsEditor;
|
|
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 _Pencil = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/Pencil"));
|
|
28
|
+
const _TrashCan = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/TrashCan"));
|
|
29
|
+
const _ArrowUp = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/ArrowUp"));
|
|
30
|
+
const _ArrowDown = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/ArrowDown"));
|
|
31
|
+
const _context = require("../../context");
|
|
32
|
+
const _Annotations = require("../Annotations");
|
|
33
|
+
function _interop_require_default(obj) {
|
|
34
|
+
return obj && obj.__esModule ? obj : {
|
|
35
|
+
default: obj
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const TableCell = (0, _material.styled)(_material.TableCell)(({ theme })=>({
|
|
39
|
+
borderBottom: `solid 1px ${theme.palette.divider}`
|
|
40
|
+
}));
|
|
41
|
+
function findDuplicateNames(specs) {
|
|
42
|
+
const seen = new Set();
|
|
43
|
+
const duplicates = new Set();
|
|
44
|
+
for (const spec of specs){
|
|
45
|
+
const name = spec.display.name;
|
|
46
|
+
if (seen.has(name)) {
|
|
47
|
+
duplicates.add(name);
|
|
48
|
+
}
|
|
49
|
+
seen.add(name);
|
|
50
|
+
}
|
|
51
|
+
return Array.from(duplicates);
|
|
52
|
+
}
|
|
53
|
+
function PanelAnnotationsEditor({ value, onChange, isReadonly }) {
|
|
54
|
+
const [target, setTarget] = (0, _react.useState)(null);
|
|
55
|
+
const [formAction, setFormAction] = (0, _react.useState)('update');
|
|
56
|
+
const duplicateNames = (0, _react.useMemo)(()=>findDuplicateNames(value), [
|
|
57
|
+
value
|
|
58
|
+
]);
|
|
59
|
+
const initialSpec = (0, _react.useMemo)(()=>{
|
|
60
|
+
if (target?.kind === 'new') {
|
|
61
|
+
return {
|
|
62
|
+
display: {
|
|
63
|
+
name: 'NewAnnotation'
|
|
64
|
+
},
|
|
65
|
+
plugin: {}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (target?.kind === 'edit') {
|
|
69
|
+
return value[target.index];
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}, [
|
|
73
|
+
target,
|
|
74
|
+
value
|
|
75
|
+
]);
|
|
76
|
+
const removeAnnotation = (index)=>{
|
|
77
|
+
onChange(value.filter((_, i)=>i !== index));
|
|
78
|
+
};
|
|
79
|
+
const changeAnnotationOrder = (index, direction)=>{
|
|
80
|
+
const step = direction === 'up' ? -1 : 1;
|
|
81
|
+
const swapWith = index + step;
|
|
82
|
+
const current = value[index];
|
|
83
|
+
const adjacent = value[swapWith];
|
|
84
|
+
if (!current || !adjacent) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const next = [
|
|
88
|
+
...value
|
|
89
|
+
];
|
|
90
|
+
next[index] = adjacent;
|
|
91
|
+
next[swapWith] = current;
|
|
92
|
+
onChange(next);
|
|
93
|
+
};
|
|
94
|
+
const toggleAnnotationVisibility = (index, visible)=>{
|
|
95
|
+
onChange(value.map((spec, i)=>i === index ? {
|
|
96
|
+
...spec,
|
|
97
|
+
display: {
|
|
98
|
+
...spec.display,
|
|
99
|
+
hidden: !visible
|
|
100
|
+
}
|
|
101
|
+
} : spec));
|
|
102
|
+
};
|
|
103
|
+
const handleSave = (definition)=>{
|
|
104
|
+
if (target?.kind === 'new') {
|
|
105
|
+
onChange([
|
|
106
|
+
...value,
|
|
107
|
+
definition
|
|
108
|
+
]);
|
|
109
|
+
} else if (target?.kind === 'edit') {
|
|
110
|
+
onChange(value.map((spec, i)=>i === target.index ? definition : spec));
|
|
111
|
+
}
|
|
112
|
+
setTarget(null);
|
|
113
|
+
};
|
|
114
|
+
if (target !== null && initialSpec) {
|
|
115
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_context.ValidationProvider, {
|
|
116
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Annotations.AnnotationEditorForm, {
|
|
117
|
+
initialAnnotationSpec: initialSpec,
|
|
118
|
+
action: formAction,
|
|
119
|
+
isDraft: true,
|
|
120
|
+
isReadonly: isReadonly,
|
|
121
|
+
onActionChange: setFormAction,
|
|
122
|
+
onSave: handleSave,
|
|
123
|
+
onClose: ()=>setTarget(null)
|
|
124
|
+
})
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Stack, {
|
|
128
|
+
spacing: 2,
|
|
129
|
+
padding: 1,
|
|
130
|
+
children: [
|
|
131
|
+
duplicateNames.map((name)=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Alert, {
|
|
132
|
+
severity: "error",
|
|
133
|
+
children: `Duplicate annotation name: ${name}`
|
|
134
|
+
}, name)),
|
|
135
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TableContainer, {
|
|
136
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Table, {
|
|
137
|
+
"aria-label": "table of panel annotations",
|
|
138
|
+
children: [
|
|
139
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TableHead, {
|
|
140
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.TableRow, {
|
|
141
|
+
children: [
|
|
142
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
|
|
143
|
+
children: "Visibility"
|
|
144
|
+
}),
|
|
145
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
|
|
146
|
+
children: "Name"
|
|
147
|
+
}),
|
|
148
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
|
|
149
|
+
children: "Type"
|
|
150
|
+
}),
|
|
151
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
|
|
152
|
+
children: "Description"
|
|
153
|
+
}),
|
|
154
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
|
|
155
|
+
align: "right",
|
|
156
|
+
children: "Actions"
|
|
157
|
+
})
|
|
158
|
+
]
|
|
159
|
+
})
|
|
160
|
+
}),
|
|
161
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TableBody, {
|
|
162
|
+
children: value.map((annotation, index)=>/*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.TableRow, {
|
|
163
|
+
children: [
|
|
164
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
|
|
165
|
+
component: "th",
|
|
166
|
+
scope: "row",
|
|
167
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Switch, {
|
|
168
|
+
checked: annotation.display?.hidden !== true,
|
|
169
|
+
disabled: isReadonly,
|
|
170
|
+
onChange: (e)=>toggleAnnotationVisibility(index, e.target.checked)
|
|
171
|
+
})
|
|
172
|
+
}),
|
|
173
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
|
|
174
|
+
component: "th",
|
|
175
|
+
scope: "row",
|
|
176
|
+
sx: {
|
|
177
|
+
fontWeight: 'bold'
|
|
178
|
+
},
|
|
179
|
+
children: annotation.display.name
|
|
180
|
+
}),
|
|
181
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
|
|
182
|
+
children: annotation.plugin.kind
|
|
183
|
+
}),
|
|
184
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(TableCell, {
|
|
185
|
+
children: annotation.display?.description ?? ''
|
|
186
|
+
}),
|
|
187
|
+
/*#__PURE__*/ (0, _jsxruntime.jsxs)(TableCell, {
|
|
188
|
+
align: "right",
|
|
189
|
+
sx: {
|
|
190
|
+
whiteSpace: 'nowrap'
|
|
191
|
+
},
|
|
192
|
+
children: [
|
|
193
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
|
|
194
|
+
onClick: ()=>changeAnnotationOrder(index, 'up'),
|
|
195
|
+
disabled: isReadonly || index === 0,
|
|
196
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_ArrowUp.default, {})
|
|
197
|
+
}),
|
|
198
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
|
|
199
|
+
onClick: ()=>changeAnnotationOrder(index, 'down'),
|
|
200
|
+
disabled: isReadonly || index === value.length - 1,
|
|
201
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_ArrowDown.default, {})
|
|
202
|
+
}),
|
|
203
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
|
|
204
|
+
onClick: ()=>{
|
|
205
|
+
setFormAction('update');
|
|
206
|
+
setTarget({
|
|
207
|
+
kind: 'edit',
|
|
208
|
+
index
|
|
209
|
+
});
|
|
210
|
+
},
|
|
211
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Pencil.default, {})
|
|
212
|
+
}),
|
|
213
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
|
|
214
|
+
disabled: isReadonly,
|
|
215
|
+
onClick: ()=>removeAnnotation(index),
|
|
216
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_TrashCan.default, {})
|
|
217
|
+
})
|
|
218
|
+
]
|
|
219
|
+
})
|
|
220
|
+
]
|
|
221
|
+
}, `${annotation.display.name}-${index}`))
|
|
222
|
+
})
|
|
223
|
+
]
|
|
224
|
+
})
|
|
225
|
+
}),
|
|
226
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
|
|
227
|
+
display: "flex",
|
|
228
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Button, {
|
|
229
|
+
variant: "contained",
|
|
230
|
+
startIcon: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Plus.default, {}),
|
|
231
|
+
sx: {
|
|
232
|
+
marginLeft: 'auto'
|
|
233
|
+
},
|
|
234
|
+
disabled: isReadonly,
|
|
235
|
+
onClick: ()=>{
|
|
236
|
+
setFormAction('create');
|
|
237
|
+
setTarget({
|
|
238
|
+
kind: 'new'
|
|
239
|
+
});
|
|
240
|
+
},
|
|
241
|
+
children: "Add Annotation"
|
|
242
|
+
})
|
|
243
|
+
})
|
|
244
|
+
]
|
|
245
|
+
});
|
|
246
|
+
}
|
|
@@ -28,6 +28,7 @@ const _LinksEditor = require("../LinksEditor");
|
|
|
28
28
|
const _runtime = require("../../runtime");
|
|
29
29
|
const _OptionsEditorTabs = require("../OptionsEditorTabs");
|
|
30
30
|
const _MultiQueryEditor = require("../MultiQueryEditor");
|
|
31
|
+
const _PanelAnnotationsEditor = require("./PanelAnnotationsEditor");
|
|
31
32
|
const PanelSpecEditor = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
|
|
32
33
|
const { control, panelDefinition, onQueriesChange, onQueryRun, onPluginSpecChange, onJSONChange } = props;
|
|
33
34
|
const { kind } = panelDefinition.spec.plugin;
|
|
@@ -44,7 +45,7 @@ const PanelSpecEditor = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
|
|
|
44
45
|
if (!plugin) {
|
|
45
46
|
throw new Error(`Missing implementation for panel plugin with kind '${kind}'`);
|
|
46
47
|
}
|
|
47
|
-
const { panelOptionsEditorComponents, hideQueryEditor } = plugin;
|
|
48
|
+
const { panelOptionsEditorComponents, hideQueryEditor, supportsAnnotations } = plugin;
|
|
48
49
|
let tabs = [];
|
|
49
50
|
if (!hideQueryEditor) {
|
|
50
51
|
tabs.push({
|
|
@@ -88,6 +89,20 @@ const PanelSpecEditor = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
|
|
|
88
89
|
})
|
|
89
90
|
})));
|
|
90
91
|
}
|
|
92
|
+
// annotations are common to all panel plugins, but only shown for plugins that render them
|
|
93
|
+
if (supportsAnnotations) {
|
|
94
|
+
tabs.push({
|
|
95
|
+
label: 'Annotations',
|
|
96
|
+
content: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reacthookform.Controller, {
|
|
97
|
+
control: control,
|
|
98
|
+
name: "panelDefinition.spec.annotations",
|
|
99
|
+
render: ({ field })=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_PanelAnnotationsEditor.PanelAnnotationsEditor, {
|
|
100
|
+
value: panelDefinition.spec.annotations ?? [],
|
|
101
|
+
onChange: (annotations)=>field.onChange(annotations)
|
|
102
|
+
})
|
|
103
|
+
})
|
|
104
|
+
});
|
|
105
|
+
}
|
|
91
106
|
// always show json editor and links editor by default
|
|
92
107
|
tabs.push({
|
|
93
108
|
label: 'Links',
|
|
@@ -51,8 +51,12 @@ function PluginRegistry(props) {
|
|
|
51
51
|
const resource = pluginIndexes.pluginResourcesByNameKindRegistryVersion.get(resourceKey);
|
|
52
52
|
if (!resource) continue;
|
|
53
53
|
const pluginModule = await loadPluginModule(resource);
|
|
54
|
+
// Try to get the plugin implementation from the module using the versioned export first
|
|
54
55
|
const plugin = pluginModule?.[resourceKey];
|
|
55
56
|
if (plugin) return plugin;
|
|
57
|
+
// If the plugin module doesn't have a versioned export, fallback to the plugin name
|
|
58
|
+
const versionlessPlugin = pluginModule?.[name];
|
|
59
|
+
if (versionlessPlugin) return versionlessPlugin;
|
|
56
60
|
}
|
|
57
61
|
throw new Error(`A ${name} plugin for kind '${kind}' is not installed`);
|
|
58
62
|
}, [
|
|
@@ -148,11 +148,11 @@ const getPluginRuntime = ()=>{
|
|
|
148
148
|
}
|
|
149
149
|
},
|
|
150
150
|
'@perses-dev/spec': {
|
|
151
|
-
version: '0.
|
|
151
|
+
version: '0.3.0-beta.0',
|
|
152
152
|
lib: ()=>require('@perses-dev/spec'),
|
|
153
153
|
shareConfig: {
|
|
154
154
|
singleton: true,
|
|
155
|
-
requiredVersion: '^0.
|
|
155
|
+
requiredVersion: '^0.3.0-beta.0'
|
|
156
156
|
}
|
|
157
157
|
},
|
|
158
158
|
'@perses-dev/core': {
|
|
@@ -164,43 +164,43 @@ const getPluginRuntime = ()=>{
|
|
|
164
164
|
}
|
|
165
165
|
},
|
|
166
166
|
'@perses-dev/client': {
|
|
167
|
-
version: '0.
|
|
167
|
+
version: '0.55.0-beta.0',
|
|
168
168
|
lib: ()=>require('@perses-dev/client'),
|
|
169
169
|
shareConfig: {
|
|
170
170
|
singleton: true,
|
|
171
|
-
requiredVersion: '^0.
|
|
171
|
+
requiredVersion: '^0.55.0-beta.0'
|
|
172
172
|
}
|
|
173
173
|
},
|
|
174
174
|
'@perses-dev/components': {
|
|
175
|
-
version: '0.
|
|
175
|
+
version: '0.55.0-beta.0',
|
|
176
176
|
lib: ()=>require('@perses-dev/components'),
|
|
177
177
|
shareConfig: {
|
|
178
178
|
singleton: true,
|
|
179
|
-
requiredVersion: '^0.
|
|
179
|
+
requiredVersion: '^0.55.0-beta.0'
|
|
180
180
|
}
|
|
181
181
|
},
|
|
182
182
|
'@perses-dev/plugin-system': {
|
|
183
|
-
version: '0.
|
|
183
|
+
version: '0.55.0-beta.0',
|
|
184
184
|
lib: ()=>require('@perses-dev/plugin-system'),
|
|
185
185
|
shareConfig: {
|
|
186
186
|
singleton: true,
|
|
187
|
-
requiredVersion: '^0.
|
|
187
|
+
requiredVersion: '^0.55.0-beta.0'
|
|
188
188
|
}
|
|
189
189
|
},
|
|
190
190
|
'@perses-dev/explore': {
|
|
191
|
-
version: '0.
|
|
191
|
+
version: '0.55.0-beta.0',
|
|
192
192
|
lib: ()=>require('@perses-dev/explore'),
|
|
193
193
|
shareConfig: {
|
|
194
194
|
singleton: true,
|
|
195
|
-
requiredVersion: '^0.
|
|
195
|
+
requiredVersion: '^0.55.0-beta.0'
|
|
196
196
|
}
|
|
197
197
|
},
|
|
198
198
|
'@perses-dev/dashboards': {
|
|
199
|
-
version: '0.
|
|
199
|
+
version: '0.55.0-beta.0',
|
|
200
200
|
lib: ()=>require('@perses-dev/dashboards'),
|
|
201
201
|
shareConfig: {
|
|
202
202
|
singleton: true,
|
|
203
|
-
requiredVersion: '^0.
|
|
203
|
+
requiredVersion: '^0.55.0-beta.0'
|
|
204
204
|
}
|
|
205
205
|
},
|
|
206
206
|
// Below are the shared modules that are used by the plugins, this can be part of the SDK
|
|
@@ -21,6 +21,7 @@ Object.defineProperty(exports, "remotePluginLoader", {
|
|
|
21
21
|
}
|
|
22
22
|
});
|
|
23
23
|
const _pluginsystem = require("@perses-dev/plugin-system");
|
|
24
|
+
const _client = require("@perses-dev/client");
|
|
24
25
|
const _PluginRuntime = require("./PluginRuntime");
|
|
25
26
|
const isPluginMetadata = (plugin)=>{
|
|
26
27
|
return typeof plugin === 'object' && plugin !== null && 'kind' in plugin && 'spec' in plugin && typeof plugin.spec === 'object' && plugin.spec !== null && 'name' in plugin.spec;
|
|
@@ -44,9 +45,10 @@ const paramToOptions = (options)=>{
|
|
|
44
45
|
};
|
|
45
46
|
function remotePluginLoader(options) {
|
|
46
47
|
const { pluginsApiPath, pluginsAssetsPath } = paramToOptions(options);
|
|
48
|
+
const fetchFn = options?.fetchFn ?? _client.fetch;
|
|
47
49
|
return {
|
|
48
50
|
getInstalledPlugins: async ()=>{
|
|
49
|
-
const pluginsResponse = await
|
|
51
|
+
const pluginsResponse = await fetchFn(pluginsApiPath);
|
|
50
52
|
const plugins = await pluginsResponse.json();
|
|
51
53
|
let pluginModules = [];
|
|
52
54
|
if (Array.isArray(plugins)) {
|
|
@@ -70,7 +70,7 @@ const useUsageMetrics = ()=>{
|
|
|
70
70
|
};
|
|
71
71
|
};
|
|
72
72
|
const submitMetrics = async (stats)=>{
|
|
73
|
-
await
|
|
73
|
+
await stats.fetchFn(`${stats.apiPrefix ?? ''}/api/v1/view`, {
|
|
74
74
|
method: 'POST',
|
|
75
75
|
headers: {
|
|
76
76
|
'Content-Type': 'application/json'
|
|
@@ -84,6 +84,7 @@ const submitMetrics = async (stats)=>{
|
|
|
84
84
|
});
|
|
85
85
|
};
|
|
86
86
|
const UsageMetricsProvider = ({ apiPrefix, project, dashboard, children })=>{
|
|
87
|
+
const { fetch } = (0, _client.useFetch)();
|
|
87
88
|
const ctx = {
|
|
88
89
|
project: project,
|
|
89
90
|
dashboard: dashboard,
|
|
@@ -91,7 +92,8 @@ const UsageMetricsProvider = ({ apiPrefix, project, dashboard, children })=>{
|
|
|
91
92
|
startRenderTime: Date.now(),
|
|
92
93
|
renderDurationMs: 0,
|
|
93
94
|
pendingQueries: new Map(),
|
|
94
|
-
apiPrefix
|
|
95
|
+
apiPrefix,
|
|
96
|
+
fetchFn: fetch
|
|
95
97
|
};
|
|
96
98
|
return /*#__PURE__*/ (0, _jsxruntime.jsx)(UsageMetricsContext.Provider, {
|
|
97
99
|
value: ctx,
|
|
@@ -21,7 +21,6 @@ Object.defineProperty(exports, "executeAction", {
|
|
|
21
21
|
}
|
|
22
22
|
});
|
|
23
23
|
const _components = require("@perses-dev/components");
|
|
24
|
-
const _client = require("@perses-dev/client");
|
|
25
24
|
const BODY_METHODS = new Set([
|
|
26
25
|
'POST',
|
|
27
26
|
'PUT',
|
|
@@ -147,7 +146,7 @@ function buildWebhookHeaders(action) {
|
|
|
147
146
|
}
|
|
148
147
|
/**
|
|
149
148
|
* Execute a webhook action in individual mode (one request per selection)
|
|
150
|
-
*/ async function executeWebhookIndividual(action, selectionMap, variableState, setActionStatus) {
|
|
149
|
+
*/ async function executeWebhookIndividual(action, selectionMap, variableState, setActionStatus, fetchFn) {
|
|
151
150
|
const entries = Array.from(selectionMap.entries());
|
|
152
151
|
const count = entries.length;
|
|
153
152
|
const itemResults = new Map();
|
|
@@ -174,7 +173,7 @@ function buildWebhookHeaders(action) {
|
|
|
174
173
|
body = bodyResult.text;
|
|
175
174
|
}
|
|
176
175
|
// Make the request
|
|
177
|
-
const response = await (
|
|
176
|
+
const response = await fetchFn(urlResult.text, {
|
|
178
177
|
method: action.method,
|
|
179
178
|
headers: buildWebhookHeaders(action),
|
|
180
179
|
body: body
|
|
@@ -222,7 +221,7 @@ function buildWebhookHeaders(action) {
|
|
|
222
221
|
}
|
|
223
222
|
/**
|
|
224
223
|
* Execute a webhook action in batch mode (single request with all selections)
|
|
225
|
-
*/ async function executeWebhookBatch(action, selectionMap, variableState, setActionStatus) {
|
|
224
|
+
*/ async function executeWebhookBatch(action, selectionMap, variableState, setActionStatus, fetchFn) {
|
|
226
225
|
const items = Array.from(selectionMap.values());
|
|
227
226
|
setActionStatus(action.name, {
|
|
228
227
|
loading: true
|
|
@@ -239,7 +238,7 @@ function buildWebhookHeaders(action) {
|
|
|
239
238
|
body = bodyResult.text;
|
|
240
239
|
}
|
|
241
240
|
// Make the request
|
|
242
|
-
const response = await (
|
|
241
|
+
const response = await fetchFn(urlResult.text, {
|
|
243
242
|
method: action.method,
|
|
244
243
|
headers: buildWebhookHeaders(action),
|
|
245
244
|
body: body
|
|
@@ -268,11 +267,11 @@ function buildWebhookHeaders(action) {
|
|
|
268
267
|
}
|
|
269
268
|
/**
|
|
270
269
|
* Execute a webhook action
|
|
271
|
-
*/ async function executeWebhookAction(action, selectionMap, variableState, setActionStatus) {
|
|
270
|
+
*/ async function executeWebhookAction(action, selectionMap, variableState, setActionStatus, fetchFn) {
|
|
272
271
|
if (action.batchMode === 'batch') {
|
|
273
|
-
return executeWebhookBatch(action, selectionMap, variableState, setActionStatus);
|
|
272
|
+
return executeWebhookBatch(action, selectionMap, variableState, setActionStatus, fetchFn);
|
|
274
273
|
} else {
|
|
275
|
-
return executeWebhookIndividual(action, selectionMap, variableState, setActionStatus);
|
|
274
|
+
return executeWebhookIndividual(action, selectionMap, variableState, setActionStatus, fetchFn);
|
|
276
275
|
}
|
|
277
276
|
}
|
|
278
277
|
/**
|
|
@@ -285,7 +284,7 @@ function buildWebhookHeaders(action) {
|
|
|
285
284
|
}
|
|
286
285
|
}
|
|
287
286
|
async function executeAction(params) {
|
|
288
|
-
const { action, selectionMap, variableState, setActionStatus } = params;
|
|
287
|
+
const { action, selectionMap, variableState, setActionStatus, fetchFn } = params;
|
|
289
288
|
if (selectionMap.size === 0) {
|
|
290
289
|
return {
|
|
291
290
|
success: true
|
|
@@ -294,7 +293,7 @@ async function executeAction(params) {
|
|
|
294
293
|
if (action.type === 'event') {
|
|
295
294
|
return executeEventAction(action, selectionMap, variableState, setActionStatus);
|
|
296
295
|
} else if (action.type === 'webhook') {
|
|
297
|
-
return executeWebhookAction(action, selectionMap, variableState, setActionStatus);
|
|
296
|
+
return executeWebhookAction(action, selectionMap, variableState, setActionStatus, fetchFn);
|
|
298
297
|
}
|
|
299
298
|
return {
|
|
300
299
|
success: false,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { AnnotationSpec } from '@perses-dev/spec';
|
|
3
|
+
export interface PanelAnnotationsEditorProps {
|
|
4
|
+
value: AnnotationSpec[];
|
|
5
|
+
onChange: (annotations: AnnotationSpec[]) => void;
|
|
6
|
+
isReadonly?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Panel-level annotations editor, rendered as a common tab in the panel editor for panel plugins
|
|
10
|
+
* that declare `supportsAnnotations`. Reuses {@link AnnotationEditorForm} for the per-annotation form
|
|
11
|
+
* and propagates every committed change through `onChange`, so it fits the inline panel-editor flow
|
|
12
|
+
* (no separate apply step).
|
|
13
|
+
*/
|
|
14
|
+
export declare function PanelAnnotationsEditor({ value, onChange, isReadonly }: PanelAnnotationsEditorProps): ReactElement;
|
|
15
|
+
//# sourceMappingURL=PanelAnnotationsEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PanelAnnotationsEditor.d.ts","sourceRoot":"","sources":["../../../src/components/PanelSpecEditor/PanelAnnotationsEditor.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAqB,MAAM,OAAO,CAAC;AAqBxD,OAAO,EAAE,cAAc,EAA2B,MAAM,kBAAkB,CAAC;AAyB3E,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,2BAA2B,GAAG,YAAY,CA6IjH"}
|