@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.
Files changed (35) hide show
  1. package/dist/cjs/components/PanelSpecEditor/PanelAnnotationsEditor.js +246 -0
  2. package/dist/cjs/components/PanelSpecEditor/PanelSpecEditor.js +16 -1
  3. package/dist/cjs/components/PluginRegistry/PluginRegistry.js +4 -0
  4. package/dist/cjs/remote/PluginRuntime.js +12 -12
  5. package/dist/cjs/remote/remotePluginLoader.js +3 -1
  6. package/dist/cjs/runtime/UsageMetricsProvider.js +4 -2
  7. package/dist/cjs/runtime/item-actions.js +9 -10
  8. package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.d.ts +15 -0
  9. package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.d.ts.map +1 -0
  10. package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.js +238 -0
  11. package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.js.map +1 -0
  12. package/dist/components/PanelSpecEditor/PanelSpecEditor.d.ts.map +1 -1
  13. package/dist/components/PanelSpecEditor/PanelSpecEditor.js +16 -1
  14. package/dist/components/PanelSpecEditor/PanelSpecEditor.js.map +1 -1
  15. package/dist/components/PluginRegistry/PluginRegistry.d.ts.map +1 -1
  16. package/dist/components/PluginRegistry/PluginRegistry.js +4 -0
  17. package/dist/components/PluginRegistry/PluginRegistry.js.map +1 -1
  18. package/dist/model/panels.d.ts +6 -0
  19. package/dist/model/panels.d.ts.map +1 -1
  20. package/dist/model/panels.js.map +1 -1
  21. package/dist/remote/PluginRuntime.js +12 -12
  22. package/dist/remote/PluginRuntime.js.map +1 -1
  23. package/dist/remote/remotePluginLoader.d.ts +5 -0
  24. package/dist/remote/remotePluginLoader.d.ts.map +1 -1
  25. package/dist/remote/remotePluginLoader.js +3 -1
  26. package/dist/remote/remotePluginLoader.js.map +1 -1
  27. package/dist/runtime/UsageMetricsProvider.d.ts +2 -0
  28. package/dist/runtime/UsageMetricsProvider.d.ts.map +1 -1
  29. package/dist/runtime/UsageMetricsProvider.js +5 -3
  30. package/dist/runtime/UsageMetricsProvider.js.map +1 -1
  31. package/dist/runtime/item-actions.d.ts +3 -0
  32. package/dist/runtime/item-actions.d.ts.map +1 -1
  33. package/dist/runtime/item-actions.js +9 -10
  34. package/dist/runtime/item-actions.js.map +1 -1
  35. package/package.json +4 -4
@@ -0,0 +1,238 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Copyright The Perses Authors
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { useMemo, useState } from 'react';
15
+ import { Alert, Box, Button, IconButton, Stack, Switch, Table, TableBody, TableCell as MuiTableCell, TableContainer, TableHead, TableRow, styled } from '@mui/material';
16
+ import AddIcon from 'mdi-material-ui/Plus';
17
+ import PencilIcon from 'mdi-material-ui/Pencil';
18
+ import TrashIcon from 'mdi-material-ui/TrashCan';
19
+ import ArrowUp from 'mdi-material-ui/ArrowUp';
20
+ import ArrowDown from 'mdi-material-ui/ArrowDown';
21
+ import { ValidationProvider } from '../../context';
22
+ import { AnnotationEditorForm } from '../Annotations';
23
+ const TableCell = styled(MuiTableCell)(({ theme })=>({
24
+ borderBottom: `solid 1px ${theme.palette.divider}`
25
+ }));
26
+ function findDuplicateNames(specs) {
27
+ const seen = new Set();
28
+ const duplicates = new Set();
29
+ for (const spec of specs){
30
+ const name = spec.display.name;
31
+ if (seen.has(name)) {
32
+ duplicates.add(name);
33
+ }
34
+ seen.add(name);
35
+ }
36
+ return Array.from(duplicates);
37
+ }
38
+ /**
39
+ * Panel-level annotations editor, rendered as a common tab in the panel editor for panel plugins
40
+ * that declare `supportsAnnotations`. Reuses {@link AnnotationEditorForm} for the per-annotation form
41
+ * and propagates every committed change through `onChange`, so it fits the inline panel-editor flow
42
+ * (no separate apply step).
43
+ */ export function PanelAnnotationsEditor({ value, onChange, isReadonly }) {
44
+ const [target, setTarget] = useState(null);
45
+ const [formAction, setFormAction] = useState('update');
46
+ const duplicateNames = useMemo(()=>findDuplicateNames(value), [
47
+ value
48
+ ]);
49
+ const initialSpec = useMemo(()=>{
50
+ if (target?.kind === 'new') {
51
+ return {
52
+ display: {
53
+ name: 'NewAnnotation'
54
+ },
55
+ plugin: {}
56
+ };
57
+ }
58
+ if (target?.kind === 'edit') {
59
+ return value[target.index];
60
+ }
61
+ return undefined;
62
+ }, [
63
+ target,
64
+ value
65
+ ]);
66
+ const removeAnnotation = (index)=>{
67
+ onChange(value.filter((_, i)=>i !== index));
68
+ };
69
+ const changeAnnotationOrder = (index, direction)=>{
70
+ const step = direction === 'up' ? -1 : 1;
71
+ const swapWith = index + step;
72
+ const current = value[index];
73
+ const adjacent = value[swapWith];
74
+ if (!current || !adjacent) {
75
+ return;
76
+ }
77
+ const next = [
78
+ ...value
79
+ ];
80
+ next[index] = adjacent;
81
+ next[swapWith] = current;
82
+ onChange(next);
83
+ };
84
+ const toggleAnnotationVisibility = (index, visible)=>{
85
+ onChange(value.map((spec, i)=>i === index ? {
86
+ ...spec,
87
+ display: {
88
+ ...spec.display,
89
+ hidden: !visible
90
+ }
91
+ } : spec));
92
+ };
93
+ const handleSave = (definition)=>{
94
+ if (target?.kind === 'new') {
95
+ onChange([
96
+ ...value,
97
+ definition
98
+ ]);
99
+ } else if (target?.kind === 'edit') {
100
+ onChange(value.map((spec, i)=>i === target.index ? definition : spec));
101
+ }
102
+ setTarget(null);
103
+ };
104
+ if (target !== null && initialSpec) {
105
+ return /*#__PURE__*/ _jsx(ValidationProvider, {
106
+ children: /*#__PURE__*/ _jsx(AnnotationEditorForm, {
107
+ initialAnnotationSpec: initialSpec,
108
+ action: formAction,
109
+ isDraft: true,
110
+ isReadonly: isReadonly,
111
+ onActionChange: setFormAction,
112
+ onSave: handleSave,
113
+ onClose: ()=>setTarget(null)
114
+ })
115
+ });
116
+ }
117
+ return /*#__PURE__*/ _jsxs(Stack, {
118
+ spacing: 2,
119
+ padding: 1,
120
+ children: [
121
+ duplicateNames.map((name)=>/*#__PURE__*/ _jsx(Alert, {
122
+ severity: "error",
123
+ children: `Duplicate annotation name: ${name}`
124
+ }, name)),
125
+ /*#__PURE__*/ _jsx(TableContainer, {
126
+ children: /*#__PURE__*/ _jsxs(Table, {
127
+ "aria-label": "table of panel annotations",
128
+ children: [
129
+ /*#__PURE__*/ _jsx(TableHead, {
130
+ children: /*#__PURE__*/ _jsxs(TableRow, {
131
+ children: [
132
+ /*#__PURE__*/ _jsx(TableCell, {
133
+ children: "Visibility"
134
+ }),
135
+ /*#__PURE__*/ _jsx(TableCell, {
136
+ children: "Name"
137
+ }),
138
+ /*#__PURE__*/ _jsx(TableCell, {
139
+ children: "Type"
140
+ }),
141
+ /*#__PURE__*/ _jsx(TableCell, {
142
+ children: "Description"
143
+ }),
144
+ /*#__PURE__*/ _jsx(TableCell, {
145
+ align: "right",
146
+ children: "Actions"
147
+ })
148
+ ]
149
+ })
150
+ }),
151
+ /*#__PURE__*/ _jsx(TableBody, {
152
+ children: value.map((annotation, index)=>/*#__PURE__*/ _jsxs(TableRow, {
153
+ children: [
154
+ /*#__PURE__*/ _jsx(TableCell, {
155
+ component: "th",
156
+ scope: "row",
157
+ children: /*#__PURE__*/ _jsx(Switch, {
158
+ checked: annotation.display?.hidden !== true,
159
+ disabled: isReadonly,
160
+ onChange: (e)=>toggleAnnotationVisibility(index, e.target.checked)
161
+ })
162
+ }),
163
+ /*#__PURE__*/ _jsx(TableCell, {
164
+ component: "th",
165
+ scope: "row",
166
+ sx: {
167
+ fontWeight: 'bold'
168
+ },
169
+ children: annotation.display.name
170
+ }),
171
+ /*#__PURE__*/ _jsx(TableCell, {
172
+ children: annotation.plugin.kind
173
+ }),
174
+ /*#__PURE__*/ _jsx(TableCell, {
175
+ children: annotation.display?.description ?? ''
176
+ }),
177
+ /*#__PURE__*/ _jsxs(TableCell, {
178
+ align: "right",
179
+ sx: {
180
+ whiteSpace: 'nowrap'
181
+ },
182
+ children: [
183
+ /*#__PURE__*/ _jsx(IconButton, {
184
+ onClick: ()=>changeAnnotationOrder(index, 'up'),
185
+ disabled: isReadonly || index === 0,
186
+ children: /*#__PURE__*/ _jsx(ArrowUp, {})
187
+ }),
188
+ /*#__PURE__*/ _jsx(IconButton, {
189
+ onClick: ()=>changeAnnotationOrder(index, 'down'),
190
+ disabled: isReadonly || index === value.length - 1,
191
+ children: /*#__PURE__*/ _jsx(ArrowDown, {})
192
+ }),
193
+ /*#__PURE__*/ _jsx(IconButton, {
194
+ onClick: ()=>{
195
+ setFormAction('update');
196
+ setTarget({
197
+ kind: 'edit',
198
+ index
199
+ });
200
+ },
201
+ children: /*#__PURE__*/ _jsx(PencilIcon, {})
202
+ }),
203
+ /*#__PURE__*/ _jsx(IconButton, {
204
+ disabled: isReadonly,
205
+ onClick: ()=>removeAnnotation(index),
206
+ children: /*#__PURE__*/ _jsx(TrashIcon, {})
207
+ })
208
+ ]
209
+ })
210
+ ]
211
+ }, `${annotation.display.name}-${index}`))
212
+ })
213
+ ]
214
+ })
215
+ }),
216
+ /*#__PURE__*/ _jsx(Box, {
217
+ display: "flex",
218
+ children: /*#__PURE__*/ _jsx(Button, {
219
+ variant: "contained",
220
+ startIcon: /*#__PURE__*/ _jsx(AddIcon, {}),
221
+ sx: {
222
+ marginLeft: 'auto'
223
+ },
224
+ disabled: isReadonly,
225
+ onClick: ()=>{
226
+ setFormAction('create');
227
+ setTarget({
228
+ kind: 'new'
229
+ });
230
+ },
231
+ children: "Add Annotation"
232
+ })
233
+ })
234
+ ]
235
+ });
236
+ }
237
+
238
+ //# sourceMappingURL=PanelAnnotationsEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/PanelSpecEditor/PanelAnnotationsEditor.tsx"],"sourcesContent":["// Copyright 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, useMemo, useState } from 'react';\nimport {\n Alert,\n Box,\n Button,\n IconButton,\n Stack,\n Switch,\n Table,\n TableBody,\n TableCell as MuiTableCell,\n TableContainer,\n TableHead,\n TableRow,\n styled,\n} from '@mui/material';\nimport AddIcon from 'mdi-material-ui/Plus';\nimport PencilIcon from 'mdi-material-ui/Pencil';\nimport TrashIcon from 'mdi-material-ui/TrashCan';\nimport ArrowUp from 'mdi-material-ui/ArrowUp';\nimport ArrowDown from 'mdi-material-ui/ArrowDown';\nimport { AnnotationSpec, Definition, UnknownSpec } from '@perses-dev/spec';\nimport { Action } from '@perses-dev/client';\nimport { ValidationProvider } from '../../context';\nimport { AnnotationEditorForm } from '../Annotations';\n\nconst TableCell = styled(MuiTableCell)(({ theme }) => ({\n borderBottom: `solid 1px ${theme.palette.divider}`,\n}));\n\n// The annotation being edited: an existing entry by index, a brand new one, or nothing (list view).\ntype EditTarget = { kind: 'edit'; index: number } | { kind: 'new' } | null;\n\nfunction findDuplicateNames(specs: AnnotationSpec[]): string[] {\n const seen = new Set<string>();\n const duplicates = new Set<string>();\n for (const spec of specs) {\n const name = spec.display.name;\n if (seen.has(name)) {\n duplicates.add(name);\n }\n seen.add(name);\n }\n return Array.from(duplicates);\n}\n\nexport interface PanelAnnotationsEditorProps {\n value: AnnotationSpec[];\n onChange: (annotations: AnnotationSpec[]) => void;\n isReadonly?: boolean;\n}\n\n/**\n * Panel-level annotations editor, rendered as a common tab in the panel editor for panel plugins\n * that declare `supportsAnnotations`. Reuses {@link AnnotationEditorForm} for the per-annotation form\n * and propagates every committed change through `onChange`, so it fits the inline panel-editor flow\n * (no separate apply step).\n */\nexport function PanelAnnotationsEditor({ value, onChange, isReadonly }: PanelAnnotationsEditorProps): ReactElement {\n const [target, setTarget] = useState<EditTarget>(null);\n const [formAction, setFormAction] = useState<Action>('update');\n\n const duplicateNames = useMemo(() => findDuplicateNames(value), [value]);\n\n const initialSpec: AnnotationSpec | undefined = useMemo(() => {\n if (target?.kind === 'new') {\n return { display: { name: 'NewAnnotation' }, plugin: {} as Definition<UnknownSpec> };\n }\n if (target?.kind === 'edit') {\n return value[target.index];\n }\n return undefined;\n }, [target, value]);\n\n const removeAnnotation = (index: number): void => {\n onChange(value.filter((_, i) => i !== index));\n };\n\n const changeAnnotationOrder = (index: number, direction: 'up' | 'down'): void => {\n const step = direction === 'up' ? -1 : 1;\n const swapWith = index + step;\n const current = value[index];\n const adjacent = value[swapWith];\n if (!current || !adjacent) {\n return;\n }\n const next = [...value];\n next[index] = adjacent;\n next[swapWith] = current;\n onChange(next);\n };\n\n const toggleAnnotationVisibility = (index: number, visible: boolean): void => {\n onChange(\n value.map((spec, i) => (i === index ? { ...spec, display: { ...spec.display, hidden: !visible } } : spec))\n );\n };\n\n const handleSave = (definition: AnnotationSpec): void => {\n if (target?.kind === 'new') {\n onChange([...value, definition]);\n } else if (target?.kind === 'edit') {\n onChange(value.map((spec, i) => (i === target.index ? definition : spec)));\n }\n setTarget(null);\n };\n\n if (target !== null && initialSpec) {\n return (\n <ValidationProvider>\n <AnnotationEditorForm\n initialAnnotationSpec={initialSpec}\n action={formAction}\n isDraft={true}\n isReadonly={isReadonly}\n onActionChange={setFormAction}\n onSave={handleSave}\n onClose={() => setTarget(null)}\n />\n </ValidationProvider>\n );\n }\n\n return (\n <Stack spacing={2} padding={1}>\n {duplicateNames.map((name) => (\n <Alert severity=\"error\" key={name}>\n {`Duplicate annotation name: ${name}`}\n </Alert>\n ))}\n <TableContainer>\n <Table aria-label=\"table of panel annotations\">\n <TableHead>\n <TableRow>\n <TableCell>Visibility</TableCell>\n <TableCell>Name</TableCell>\n <TableCell>Type</TableCell>\n <TableCell>Description</TableCell>\n <TableCell align=\"right\">Actions</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {value.map((annotation, index) => (\n <TableRow key={`${annotation.display.name}-${index}`}>\n <TableCell component=\"th\" scope=\"row\">\n <Switch\n checked={annotation.display?.hidden !== true}\n disabled={isReadonly}\n onChange={(e) => toggleAnnotationVisibility(index, e.target.checked)}\n />\n </TableCell>\n <TableCell component=\"th\" scope=\"row\" sx={{ fontWeight: 'bold' }}>\n {annotation.display.name}\n </TableCell>\n <TableCell>{annotation.plugin.kind}</TableCell>\n <TableCell>{annotation.display?.description ?? ''}</TableCell>\n <TableCell align=\"right\" sx={{ whiteSpace: 'nowrap' }}>\n <IconButton onClick={() => changeAnnotationOrder(index, 'up')} disabled={isReadonly || index === 0}>\n <ArrowUp />\n </IconButton>\n <IconButton\n onClick={() => changeAnnotationOrder(index, 'down')}\n disabled={isReadonly || index === value.length - 1}\n >\n <ArrowDown />\n </IconButton>\n <IconButton\n onClick={() => {\n setFormAction('update');\n setTarget({ kind: 'edit', index });\n }}\n >\n <PencilIcon />\n </IconButton>\n <IconButton disabled={isReadonly} onClick={() => removeAnnotation(index)}>\n <TrashIcon />\n </IconButton>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n <Box display=\"flex\">\n <Button\n variant=\"contained\"\n startIcon={<AddIcon />}\n sx={{ marginLeft: 'auto' }}\n disabled={isReadonly}\n onClick={() => {\n setFormAction('create');\n setTarget({ kind: 'new' });\n }}\n >\n Add Annotation\n </Button>\n </Box>\n </Stack>\n );\n}\n"],"names":["useMemo","useState","Alert","Box","Button","IconButton","Stack","Switch","Table","TableBody","TableCell","MuiTableCell","TableContainer","TableHead","TableRow","styled","AddIcon","PencilIcon","TrashIcon","ArrowUp","ArrowDown","ValidationProvider","AnnotationEditorForm","theme","borderBottom","palette","divider","findDuplicateNames","specs","seen","Set","duplicates","spec","name","display","has","add","Array","from","PanelAnnotationsEditor","value","onChange","isReadonly","target","setTarget","formAction","setFormAction","duplicateNames","initialSpec","kind","plugin","index","undefined","removeAnnotation","filter","_","i","changeAnnotationOrder","direction","step","swapWith","current","adjacent","next","toggleAnnotationVisibility","visible","map","hidden","handleSave","definition","initialAnnotationSpec","action","isDraft","onActionChange","onSave","onClose","spacing","padding","severity","aria-label","align","annotation","component","scope","checked","disabled","e","sx","fontWeight","description","whiteSpace","onClick","length","variant","startIcon","marginLeft"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PanelSpecEditor.d.ts","sourceRoot":"","sources":["../../../src/components/PanelSpecEditor/PanelSpecEditor.tsx"],"names":[],"mappings":";AAcA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,OAAO,EAAc,MAAM,iBAAiB,CAAC;AAGtD,OAAO,EAAE,iBAAiB,EAAe,MAAM,aAAa,CAAC;AAI7D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACpC,eAAe,EAAE,eAAe,CAAC;IACjC,eAAe,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IACtD,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAC5D,kBAAkB,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IAChD,YAAY,EAAE,CAAC,kBAAkB,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD;AAED,eAAO,MAAM,eAAe,kHAsG1B,CAAC"}
1
+ {"version":3,"file":"PanelSpecEditor.d.ts","sourceRoot":"","sources":["../../../src/components/PanelSpecEditor/PanelSpecEditor.tsx"],"names":[],"mappings":";AAcA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,OAAO,EAAc,MAAM,iBAAiB,CAAC;AAGtD,OAAO,EAAE,iBAAiB,EAAe,MAAM,aAAa,CAAC;AAI7D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGlD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACpC,eAAe,EAAE,eAAe,CAAC;IACjC,eAAe,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IACtD,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAC5D,kBAAkB,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IAChD,YAAY,EAAE,CAAC,kBAAkB,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD;AAED,eAAO,MAAM,eAAe,kHAyH1B,CAAC"}
@@ -18,6 +18,7 @@ import { LinksEditor } from '../LinksEditor';
18
18
  import { useDataQueriesContext, usePlugin } from '../../runtime';
19
19
  import { OptionsEditorTabs } from '../OptionsEditorTabs';
20
20
  import { MultiQueryEditor } from '../MultiQueryEditor';
21
+ import { PanelAnnotationsEditor } from './PanelAnnotationsEditor';
21
22
  export const PanelSpecEditor = /*#__PURE__*/ forwardRef((props, ref)=>{
22
23
  const { control, panelDefinition, onQueriesChange, onQueryRun, onPluginSpecChange, onJSONChange } = props;
23
24
  const { kind } = panelDefinition.spec.plugin;
@@ -34,7 +35,7 @@ export const PanelSpecEditor = /*#__PURE__*/ forwardRef((props, ref)=>{
34
35
  if (!plugin) {
35
36
  throw new Error(`Missing implementation for panel plugin with kind '${kind}'`);
36
37
  }
37
- const { panelOptionsEditorComponents, hideQueryEditor } = plugin;
38
+ const { panelOptionsEditorComponents, hideQueryEditor, supportsAnnotations } = plugin;
38
39
  let tabs = [];
39
40
  if (!hideQueryEditor) {
40
41
  tabs.push({
@@ -78,6 +79,20 @@ export const PanelSpecEditor = /*#__PURE__*/ forwardRef((props, ref)=>{
78
79
  })
79
80
  })));
80
81
  }
82
+ // annotations are common to all panel plugins, but only shown for plugins that render them
83
+ if (supportsAnnotations) {
84
+ tabs.push({
85
+ label: 'Annotations',
86
+ content: /*#__PURE__*/ _jsx(Controller, {
87
+ control: control,
88
+ name: "panelDefinition.spec.annotations",
89
+ render: ({ field })=>/*#__PURE__*/ _jsx(PanelAnnotationsEditor, {
90
+ value: panelDefinition.spec.annotations ?? [],
91
+ onChange: (annotations)=>field.onChange(annotations)
92
+ })
93
+ })
94
+ });
95
+ }
81
96
  // always show json editor and links editor by default
82
97
  tabs.push({
83
98
  label: 'Links',
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/PanelSpecEditor/PanelSpecEditor.tsx"],"sourcesContent":["// Copyright 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 { ErrorAlert, JSONEditor } from '@perses-dev/components';\nimport { PanelDefinition, QueryDefinition, UnknownSpec } from '@perses-dev/spec';\nimport { Control, Controller } from 'react-hook-form';\nimport { forwardRef, ReactElement } from 'react';\nimport { LinksEditor } from '../LinksEditor';\nimport { PanelEditorValues, PanelPlugin } from '../../model';\nimport { useDataQueriesContext, usePlugin } from '../../runtime';\nimport { OptionsEditorTabs, OptionsEditorTabsProps } from '../OptionsEditorTabs';\nimport { MultiQueryEditor } from '../MultiQueryEditor';\nimport { PluginEditorRef } from '../PluginEditor';\n\nexport interface PanelSpecEditorProps {\n control: Control<PanelEditorValues>;\n panelDefinition: PanelDefinition;\n onQueriesChange: (queries: QueryDefinition[]) => void;\n onQueryRun: (index: number, query: QueryDefinition) => void;\n onPluginSpecChange: (spec: UnknownSpec) => void;\n onJSONChange: (panelDefinitionStr: string) => void;\n}\n\nexport const PanelSpecEditor = forwardRef<PluginEditorRef, PanelSpecEditorProps>((props, ref): ReactElement | null => {\n const { control, panelDefinition, onQueriesChange, onQueryRun, onPluginSpecChange, onJSONChange } = props;\n const { kind } = panelDefinition.spec.plugin;\n const { data: plugin, isLoading, error } = usePlugin('Panel', kind);\n\n const { queryResults } = useDataQueriesContext();\n\n if (error) {\n return <ErrorAlert error={error} />;\n }\n\n if (isLoading) {\n return null;\n }\n\n if (!plugin) {\n throw new Error(`Missing implementation for panel plugin with kind '${kind}'`);\n }\n\n const { panelOptionsEditorComponents, hideQueryEditor } = plugin as PanelPlugin;\n let tabs: OptionsEditorTabsProps['tabs'] = [];\n\n if (!hideQueryEditor) {\n tabs.push({\n label: 'Query',\n content: (\n <Controller\n control={control}\n name=\"panelDefinition.spec.queries\"\n render={({ field }) => (\n <MultiQueryEditor\n ref={ref}\n queryTypes={plugin.supportedQueryTypes ?? []}\n queries={panelDefinition.spec.queries ?? []}\n queryResults={queryResults}\n onChange={(queries) => {\n field.onChange(queries);\n onQueriesChange(queries);\n }}\n onQueryRun={(index, query) => {\n onQueryRun(index, query);\n // If spec has not changed, refetch to update the data\n if (JSON.stringify(panelDefinition.spec.queries?.[index]) === JSON.stringify(query)) {\n queryResults[index]?.refetch?.();\n }\n }}\n />\n )}\n />\n ),\n });\n }\n\n if (panelOptionsEditorComponents) {\n tabs = tabs.concat(\n panelOptionsEditorComponents.map(({ label, content: OptionsEditorComponent }) => ({\n label,\n content: (\n <Controller\n control={control}\n name=\"panelDefinition.spec.plugin.spec\"\n render={({ field }) => (\n <OptionsEditorComponent\n value={panelDefinition.spec.plugin.spec}\n onChange={(spec) => {\n field.onChange(spec);\n onPluginSpecChange(spec);\n }}\n />\n )}\n />\n ),\n }))\n );\n }\n\n // always show json editor and links editor by default\n tabs.push({\n label: 'Links',\n content: <LinksEditor control={control} />,\n });\n tabs.push({\n label: 'JSON',\n content: (\n <Controller\n control={control}\n name=\"panelDefinition\"\n render={({ field }) => (\n <JSONEditor\n maxHeight=\"80vh\"\n value={panelDefinition}\n onChange={(json) => {\n field.onChange(JSON.parse(json));\n onJSONChange(json);\n }}\n />\n )}\n />\n ),\n });\n\n return <OptionsEditorTabs key={tabs.length} tabs={tabs} />;\n});\n\nPanelSpecEditor.displayName = 'PanelSpecEditor';\n"],"names":["ErrorAlert","JSONEditor","Controller","forwardRef","LinksEditor","useDataQueriesContext","usePlugin","OptionsEditorTabs","MultiQueryEditor","PanelSpecEditor","props","ref","control","panelDefinition","onQueriesChange","onQueryRun","onPluginSpecChange","onJSONChange","kind","spec","plugin","data","isLoading","error","queryResults","Error","panelOptionsEditorComponents","hideQueryEditor","tabs","push","label","content","name","render","field","queryTypes","supportedQueryTypes","queries","onChange","index","query","JSON","stringify","refetch","concat","map","OptionsEditorComponent","value","maxHeight","json","parse","length","displayName"],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,UAAU,EAAEC,UAAU,QAAQ,yBAAyB;AAEhE,SAAkBC,UAAU,QAAQ,kBAAkB;AACtD,SAASC,UAAU,QAAsB,QAAQ;AACjD,SAASC,WAAW,QAAQ,iBAAiB;AAE7C,SAASC,qBAAqB,EAAEC,SAAS,QAAQ,gBAAgB;AACjE,SAASC,iBAAiB,QAAgC,uBAAuB;AACjF,SAASC,gBAAgB,QAAQ,sBAAsB;AAYvD,OAAO,MAAMC,gCAAkBN,WAAkD,CAACO,OAAOC;IACvF,MAAM,EAAEC,OAAO,EAAEC,eAAe,EAAEC,eAAe,EAAEC,UAAU,EAAEC,kBAAkB,EAAEC,YAAY,EAAE,GAAGP;IACpG,MAAM,EAAEQ,IAAI,EAAE,GAAGL,gBAAgBM,IAAI,CAACC,MAAM;IAC5C,MAAM,EAAEC,MAAMD,MAAM,EAAEE,SAAS,EAAEC,KAAK,EAAE,GAAGjB,UAAU,SAASY;IAE9D,MAAM,EAAEM,YAAY,EAAE,GAAGnB;IAEzB,IAAIkB,OAAO;QACT,qBAAO,KAACvB;YAAWuB,OAAOA;;IAC5B;IAEA,IAAID,WAAW;QACb,OAAO;IACT;IAEA,IAAI,CAACF,QAAQ;QACX,MAAM,IAAIK,MAAM,CAAC,mDAAmD,EAAEP,KAAK,CAAC,CAAC;IAC/E;IAEA,MAAM,EAAEQ,4BAA4B,EAAEC,eAAe,EAAE,GAAGP;IAC1D,IAAIQ,OAAuC,EAAE;IAE7C,IAAI,CAACD,iBAAiB;QACpBC,KAAKC,IAAI,CAAC;YACRC,OAAO;YACPC,uBACE,KAAC7B;gBACCU,SAASA;gBACToB,MAAK;gBACLC,QAAQ,CAAC,EAAEC,KAAK,EAAE,iBAChB,KAAC1B;wBACCG,KAAKA;wBACLwB,YAAYf,OAAOgB,mBAAmB,IAAI,EAAE;wBAC5CC,SAASxB,gBAAgBM,IAAI,CAACkB,OAAO,IAAI,EAAE;wBAC3Cb,cAAcA;wBACdc,UAAU,CAACD;4BACTH,MAAMI,QAAQ,CAACD;4BACfvB,gBAAgBuB;wBAClB;wBACAtB,YAAY,CAACwB,OAAOC;4BAClBzB,WAAWwB,OAAOC;4BAClB,sDAAsD;4BACtD,IAAIC,KAAKC,SAAS,CAAC7B,gBAAgBM,IAAI,CAACkB,OAAO,EAAE,CAACE,MAAM,MAAME,KAAKC,SAAS,CAACF,QAAQ;gCACnFhB,YAAY,CAACe,MAAM,EAAEI;4BACvB;wBACF;;;QAKV;IACF;IAEA,IAAIjB,8BAA8B;QAChCE,OAAOA,KAAKgB,MAAM,CAChBlB,6BAA6BmB,GAAG,CAAC,CAAC,EAAEf,KAAK,EAAEC,SAASe,sBAAsB,EAAE,GAAM,CAAA;gBAChFhB;gBACAC,uBACE,KAAC7B;oBACCU,SAASA;oBACToB,MAAK;oBACLC,QAAQ,CAAC,EAAEC,KAAK,EAAE,iBAChB,KAACY;4BACCC,OAAOlC,gBAAgBM,IAAI,CAACC,MAAM,CAACD,IAAI;4BACvCmB,UAAU,CAACnB;gCACTe,MAAMI,QAAQ,CAACnB;gCACfH,mBAAmBG;4BACrB;;;YAKV,CAAA;IAEJ;IAEA,sDAAsD;IACtDS,KAAKC,IAAI,CAAC;QACRC,OAAO;QACPC,uBAAS,KAAC3B;YAAYQ,SAASA;;IACjC;IACAgB,KAAKC,IAAI,CAAC;QACRC,OAAO;QACPC,uBACE,KAAC7B;YACCU,SAASA;YACToB,MAAK;YACLC,QAAQ,CAAC,EAAEC,KAAK,EAAE,iBAChB,KAACjC;oBACC+C,WAAU;oBACVD,OAAOlC;oBACPyB,UAAU,CAACW;wBACTf,MAAMI,QAAQ,CAACG,KAAKS,KAAK,CAACD;wBAC1BhC,aAAagC;oBACf;;;IAKV;IAEA,qBAAO,KAAC1C;QAAoCqB,MAAMA;OAAnBA,KAAKuB,MAAM;AAC5C,GAAG;AAEH1C,gBAAgB2C,WAAW,GAAG"}
1
+ {"version":3,"sources":["../../../src/components/PanelSpecEditor/PanelSpecEditor.tsx"],"sourcesContent":["// Copyright 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 { ErrorAlert, JSONEditor } from '@perses-dev/components';\nimport { PanelDefinition, QueryDefinition, UnknownSpec } from '@perses-dev/spec';\nimport { Control, Controller } from 'react-hook-form';\nimport { forwardRef, ReactElement } from 'react';\nimport { LinksEditor } from '../LinksEditor';\nimport { PanelEditorValues, PanelPlugin } from '../../model';\nimport { useDataQueriesContext, usePlugin } from '../../runtime';\nimport { OptionsEditorTabs, OptionsEditorTabsProps } from '../OptionsEditorTabs';\nimport { MultiQueryEditor } from '../MultiQueryEditor';\nimport { PluginEditorRef } from '../PluginEditor';\nimport { PanelAnnotationsEditor } from './PanelAnnotationsEditor';\n\nexport interface PanelSpecEditorProps {\n control: Control<PanelEditorValues>;\n panelDefinition: PanelDefinition;\n onQueriesChange: (queries: QueryDefinition[]) => void;\n onQueryRun: (index: number, query: QueryDefinition) => void;\n onPluginSpecChange: (spec: UnknownSpec) => void;\n onJSONChange: (panelDefinitionStr: string) => void;\n}\n\nexport const PanelSpecEditor = forwardRef<PluginEditorRef, PanelSpecEditorProps>((props, ref): ReactElement | null => {\n const { control, panelDefinition, onQueriesChange, onQueryRun, onPluginSpecChange, onJSONChange } = props;\n const { kind } = panelDefinition.spec.plugin;\n const { data: plugin, isLoading, error } = usePlugin('Panel', kind);\n\n const { queryResults } = useDataQueriesContext();\n\n if (error) {\n return <ErrorAlert error={error} />;\n }\n\n if (isLoading) {\n return null;\n }\n\n if (!plugin) {\n throw new Error(`Missing implementation for panel plugin with kind '${kind}'`);\n }\n\n const { panelOptionsEditorComponents, hideQueryEditor, supportsAnnotations } = plugin as PanelPlugin;\n let tabs: OptionsEditorTabsProps['tabs'] = [];\n\n if (!hideQueryEditor) {\n tabs.push({\n label: 'Query',\n content: (\n <Controller\n control={control}\n name=\"panelDefinition.spec.queries\"\n render={({ field }) => (\n <MultiQueryEditor\n ref={ref}\n queryTypes={plugin.supportedQueryTypes ?? []}\n queries={panelDefinition.spec.queries ?? []}\n queryResults={queryResults}\n onChange={(queries) => {\n field.onChange(queries);\n onQueriesChange(queries);\n }}\n onQueryRun={(index, query) => {\n onQueryRun(index, query);\n // If spec has not changed, refetch to update the data\n if (JSON.stringify(panelDefinition.spec.queries?.[index]) === JSON.stringify(query)) {\n queryResults[index]?.refetch?.();\n }\n }}\n />\n )}\n />\n ),\n });\n }\n\n if (panelOptionsEditorComponents) {\n tabs = tabs.concat(\n panelOptionsEditorComponents.map(({ label, content: OptionsEditorComponent }) => ({\n label,\n content: (\n <Controller\n control={control}\n name=\"panelDefinition.spec.plugin.spec\"\n render={({ field }) => (\n <OptionsEditorComponent\n value={panelDefinition.spec.plugin.spec}\n onChange={(spec) => {\n field.onChange(spec);\n onPluginSpecChange(spec);\n }}\n />\n )}\n />\n ),\n }))\n );\n }\n\n // annotations are common to all panel plugins, but only shown for plugins that render them\n if (supportsAnnotations) {\n tabs.push({\n label: 'Annotations',\n content: (\n <Controller\n control={control}\n name=\"panelDefinition.spec.annotations\"\n render={({ field }) => (\n <PanelAnnotationsEditor\n value={panelDefinition.spec.annotations ?? []}\n onChange={(annotations) => field.onChange(annotations)}\n />\n )}\n />\n ),\n });\n }\n\n // always show json editor and links editor by default\n tabs.push({\n label: 'Links',\n content: <LinksEditor control={control} />,\n });\n tabs.push({\n label: 'JSON',\n content: (\n <Controller\n control={control}\n name=\"panelDefinition\"\n render={({ field }) => (\n <JSONEditor\n maxHeight=\"80vh\"\n value={panelDefinition}\n onChange={(json) => {\n field.onChange(JSON.parse(json));\n onJSONChange(json);\n }}\n />\n )}\n />\n ),\n });\n\n return <OptionsEditorTabs key={tabs.length} tabs={tabs} />;\n});\n\nPanelSpecEditor.displayName = 'PanelSpecEditor';\n"],"names":["ErrorAlert","JSONEditor","Controller","forwardRef","LinksEditor","useDataQueriesContext","usePlugin","OptionsEditorTabs","MultiQueryEditor","PanelAnnotationsEditor","PanelSpecEditor","props","ref","control","panelDefinition","onQueriesChange","onQueryRun","onPluginSpecChange","onJSONChange","kind","spec","plugin","data","isLoading","error","queryResults","Error","panelOptionsEditorComponents","hideQueryEditor","supportsAnnotations","tabs","push","label","content","name","render","field","queryTypes","supportedQueryTypes","queries","onChange","index","query","JSON","stringify","refetch","concat","map","OptionsEditorComponent","value","annotations","maxHeight","json","parse","length","displayName"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PluginRegistry.d.ts","sourceRoot":"","sources":["../../../src/components/PluginRegistry/PluginRegistry.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAgC,SAAS,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC9E,OAAO,EAKL,YAAY,EACZ,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAMrB,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,YAAY,CAAC;IAC3B,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,CAgEvE"}
1
+ {"version":3,"file":"PluginRegistry.d.ts","sourceRoot":"","sources":["../../../src/components/PluginRegistry/PluginRegistry.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAgC,SAAS,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC9E,OAAO,EAKL,YAAY,EACZ,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAMrB,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,YAAY,CAAC;IAC3B,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,CAoEvE"}
@@ -44,8 +44,12 @@ import { resolvePluginKeys } from './getPluginSearchHelper';
44
44
  const resource = pluginIndexes.pluginResourcesByNameKindRegistryVersion.get(resourceKey);
45
45
  if (!resource) continue;
46
46
  const pluginModule = await loadPluginModule(resource);
47
+ // Try to get the plugin implementation from the module using the versioned export first
47
48
  const plugin = pluginModule?.[resourceKey];
48
49
  if (plugin) return plugin;
50
+ // If the plugin module doesn't have a versioned export, fallback to the plugin name
51
+ const versionlessPlugin = pluginModule?.[name];
52
+ if (versionlessPlugin) return versionlessPlugin;
49
53
  }
50
54
  throw new Error(`A ${name} plugin for kind '${kind}' is not installed`);
51
55
  }, [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/PluginRegistry/PluginRegistry.tsx"],"sourcesContent":["// Copyright 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 { UnknownSpec } from '@perses-dev/spec';\nimport { useRef, useCallback, useMemo, ReactNode, ReactElement } from 'react';\nimport {\n PluginModuleResource,\n PluginType,\n PluginImplementation,\n Plugin,\n PluginLoader,\n DefaultPluginKinds,\n} from '../../model';\nimport { PluginRegistryContext } from '../../runtime';\nimport { useEvent } from '../../utils';\nimport { usePluginIndexes, PluginCompoundKey } from './plugin-indexes';\nimport { resolvePluginKeys } from './getPluginSearchHelper';\n\nexport interface PluginRegistryProps {\n pluginLoader: PluginLoader;\n defaultPluginKinds?: DefaultPluginKinds;\n children?: ReactNode;\n}\n\n/**\n * PluginRegistryContext provider that keeps track of all available plugins and provides an API for getting them or\n * querying the metadata about them.\n */\nexport function PluginRegistry(props: PluginRegistryProps): ReactElement {\n const {\n pluginLoader: { getInstalledPlugins, importPluginModule },\n children,\n defaultPluginKinds,\n } = props;\n\n const getPluginIndexes = usePluginIndexes(getInstalledPlugins);\n\n // De-dupe calls to import plugin modules\n const importCache = useRef(new Map<PluginModuleResource, Promise<unknown>>());\n\n // Do useEvent here since this accesses the importPluginModule prop and we want a stable reference to it for the\n // callback below\n const loadPluginModule = useEvent((resource: PluginModuleResource) => {\n let request = importCache.current.get(resource);\n if (request === undefined) {\n request = importPluginModule(resource);\n importCache.current.set(resource, request);\n\n // Remove failed requests from the cache so they can potentially be retried\n request.catch(() => importCache.current.delete(resource));\n }\n return request;\n });\n\n const getPlugin = useCallback(\n async <T extends PluginType>(compoundKeyObj: PluginCompoundKey<T>): Promise<PluginImplementation<T>> => {\n const pluginIndexes = await getPluginIndexes();\n const { kind, name } = compoundKeyObj;\n\n const candidateKeys = resolvePluginKeys(\n pluginIndexes.pluginResourcesByNameKindRegistryVersion.keys(),\n compoundKeyObj\n );\n\n for (const resourceKey of candidateKeys) {\n const resource = pluginIndexes.pluginResourcesByNameKindRegistryVersion.get(resourceKey);\n if (!resource) continue;\n\n const pluginModule = (await loadPluginModule(resource)) as Record<string, Plugin<UnknownSpec>>;\n const plugin = pluginModule?.[resourceKey];\n if (plugin) return plugin as PluginImplementation<T>;\n }\n\n throw new Error(`A ${name} plugin for kind '${kind}' is not installed`);\n },\n [getPluginIndexes, loadPluginModule]\n );\n\n const listPluginMetadata = useCallback(\n async (pluginTypes: PluginType[]) => {\n const pluginIndexes = await getPluginIndexes();\n return pluginTypes.flatMap((type) => pluginIndexes.pluginMetadataByKind.get(type) ?? []);\n },\n [getPluginIndexes]\n );\n\n // Create the registry's context value and render\n const context = useMemo(\n () => ({ getPlugin, listPluginMetadata, defaultPluginKinds }),\n [getPlugin, listPluginMetadata, defaultPluginKinds]\n );\n return <PluginRegistryContext.Provider value={context}>{children}</PluginRegistryContext.Provider>;\n}\n"],"names":["useRef","useCallback","useMemo","PluginRegistryContext","useEvent","usePluginIndexes","resolvePluginKeys","PluginRegistry","props","pluginLoader","getInstalledPlugins","importPluginModule","children","defaultPluginKinds","getPluginIndexes","importCache","Map","loadPluginModule","resource","request","current","get","undefined","set","catch","delete","getPlugin","compoundKeyObj","pluginIndexes","kind","name","candidateKeys","pluginResourcesByNameKindRegistryVersion","keys","resourceKey","pluginModule","plugin","Error","listPluginMetadata","pluginTypes","flatMap","type","pluginMetadataByKind","context","Provider","value"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAGjC,SAASA,MAAM,EAAEC,WAAW,EAAEC,OAAO,QAAiC,QAAQ;AAS9E,SAASC,qBAAqB,QAAQ,gBAAgB;AACtD,SAASC,QAAQ,QAAQ,cAAc;AACvC,SAASC,gBAAgB,QAA2B,mBAAmB;AACvE,SAASC,iBAAiB,QAAQ,0BAA0B;AAQ5D;;;CAGC,GACD,OAAO,SAASC,eAAeC,KAA0B;IACvD,MAAM,EACJC,cAAc,EAAEC,mBAAmB,EAAEC,kBAAkB,EAAE,EACzDC,QAAQ,EACRC,kBAAkB,EACnB,GAAGL;IAEJ,MAAMM,mBAAmBT,iBAAiBK;IAE1C,yCAAyC;IACzC,MAAMK,cAAcf,OAAO,IAAIgB;IAE/B,gHAAgH;IAChH,iBAAiB;IACjB,MAAMC,mBAAmBb,SAAS,CAACc;QACjC,IAAIC,UAAUJ,YAAYK,OAAO,CAACC,GAAG,CAACH;QACtC,IAAIC,YAAYG,WAAW;YACzBH,UAAUR,mBAAmBO;YAC7BH,YAAYK,OAAO,CAACG,GAAG,CAACL,UAAUC;YAElC,2EAA2E;YAC3EA,QAAQK,KAAK,CAAC,IAAMT,YAAYK,OAAO,CAACK,MAAM,CAACP;QACjD;QACA,OAAOC;IACT;IAEA,MAAMO,YAAYzB,YAChB,OAA6B0B;QAC3B,MAAMC,gBAAgB,MAAMd;QAC5B,MAAM,EAAEe,IAAI,EAAEC,IAAI,EAAE,GAAGH;QAEvB,MAAMI,gBAAgBzB,kBACpBsB,cAAcI,wCAAwC,CAACC,IAAI,IAC3DN;QAGF,KAAK,MAAMO,eAAeH,cAAe;YACvC,MAAMb,WAAWU,cAAcI,wCAAwC,CAACX,GAAG,CAACa;YAC5E,IAAI,CAAChB,UAAU;YAEf,MAAMiB,eAAgB,MAAMlB,iBAAiBC;YAC7C,MAAMkB,SAASD,cAAc,CAACD,YAAY;YAC1C,IAAIE,QAAQ,OAAOA;QACrB;QAEA,MAAM,IAAIC,MAAM,CAAC,EAAE,EAAEP,KAAK,kBAAkB,EAAED,KAAK,kBAAkB,CAAC;IACxE,GACA;QAACf;QAAkBG;KAAiB;IAGtC,MAAMqB,qBAAqBrC,YACzB,OAAOsC;QACL,MAAMX,gBAAgB,MAAMd;QAC5B,OAAOyB,YAAYC,OAAO,CAAC,CAACC,OAASb,cAAcc,oBAAoB,CAACrB,GAAG,CAACoB,SAAS,EAAE;IACzF,GACA;QAAC3B;KAAiB;IAGpB,iDAAiD;IACjD,MAAM6B,UAAUzC,QACd,IAAO,CAAA;YAAEwB;YAAWY;YAAoBzB;QAAmB,CAAA,GAC3D;QAACa;QAAWY;QAAoBzB;KAAmB;IAErD,qBAAO,KAACV,sBAAsByC,QAAQ;QAACC,OAAOF;kBAAU/B;;AAC1D"}
1
+ {"version":3,"sources":["../../../src/components/PluginRegistry/PluginRegistry.tsx"],"sourcesContent":["// Copyright 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 { UnknownSpec } from '@perses-dev/spec';\nimport { useRef, useCallback, useMemo, ReactNode, ReactElement } from 'react';\nimport {\n PluginModuleResource,\n PluginType,\n PluginImplementation,\n Plugin,\n PluginLoader,\n DefaultPluginKinds,\n} from '../../model';\nimport { PluginRegistryContext } from '../../runtime';\nimport { useEvent } from '../../utils';\nimport { usePluginIndexes, PluginCompoundKey } from './plugin-indexes';\nimport { resolvePluginKeys } from './getPluginSearchHelper';\n\nexport interface PluginRegistryProps {\n pluginLoader: PluginLoader;\n defaultPluginKinds?: DefaultPluginKinds;\n children?: ReactNode;\n}\n\n/**\n * PluginRegistryContext provider that keeps track of all available plugins and provides an API for getting them or\n * querying the metadata about them.\n */\nexport function PluginRegistry(props: PluginRegistryProps): ReactElement {\n const {\n pluginLoader: { getInstalledPlugins, importPluginModule },\n children,\n defaultPluginKinds,\n } = props;\n\n const getPluginIndexes = usePluginIndexes(getInstalledPlugins);\n\n // De-dupe calls to import plugin modules\n const importCache = useRef(new Map<PluginModuleResource, Promise<unknown>>());\n\n // Do useEvent here since this accesses the importPluginModule prop and we want a stable reference to it for the\n // callback below\n const loadPluginModule = useEvent((resource: PluginModuleResource) => {\n let request = importCache.current.get(resource);\n if (request === undefined) {\n request = importPluginModule(resource);\n importCache.current.set(resource, request);\n\n // Remove failed requests from the cache so they can potentially be retried\n request.catch(() => importCache.current.delete(resource));\n }\n return request;\n });\n\n const getPlugin = useCallback(\n async <T extends PluginType>(compoundKeyObj: PluginCompoundKey<T>): Promise<PluginImplementation<T>> => {\n const pluginIndexes = await getPluginIndexes();\n const { kind, name } = compoundKeyObj;\n\n const candidateKeys = resolvePluginKeys(\n pluginIndexes.pluginResourcesByNameKindRegistryVersion.keys(),\n compoundKeyObj\n );\n\n for (const resourceKey of candidateKeys) {\n const resource = pluginIndexes.pluginResourcesByNameKindRegistryVersion.get(resourceKey);\n if (!resource) continue;\n\n const pluginModule = (await loadPluginModule(resource)) as Record<string, Plugin<UnknownSpec>>;\n // Try to get the plugin implementation from the module using the versioned export first\n const plugin = pluginModule?.[resourceKey];\n if (plugin) return plugin as PluginImplementation<T>;\n // If the plugin module doesn't have a versioned export, fallback to the plugin name\n const versionlessPlugin = pluginModule?.[name];\n if (versionlessPlugin) return versionlessPlugin as PluginImplementation<T>;\n }\n\n throw new Error(`A ${name} plugin for kind '${kind}' is not installed`);\n },\n [getPluginIndexes, loadPluginModule]\n );\n\n const listPluginMetadata = useCallback(\n async (pluginTypes: PluginType[]) => {\n const pluginIndexes = await getPluginIndexes();\n return pluginTypes.flatMap((type) => pluginIndexes.pluginMetadataByKind.get(type) ?? []);\n },\n [getPluginIndexes]\n );\n\n // Create the registry's context value and render\n const context = useMemo(\n () => ({ getPlugin, listPluginMetadata, defaultPluginKinds }),\n [getPlugin, listPluginMetadata, defaultPluginKinds]\n );\n return <PluginRegistryContext.Provider value={context}>{children}</PluginRegistryContext.Provider>;\n}\n"],"names":["useRef","useCallback","useMemo","PluginRegistryContext","useEvent","usePluginIndexes","resolvePluginKeys","PluginRegistry","props","pluginLoader","getInstalledPlugins","importPluginModule","children","defaultPluginKinds","getPluginIndexes","importCache","Map","loadPluginModule","resource","request","current","get","undefined","set","catch","delete","getPlugin","compoundKeyObj","pluginIndexes","kind","name","candidateKeys","pluginResourcesByNameKindRegistryVersion","keys","resourceKey","pluginModule","plugin","versionlessPlugin","Error","listPluginMetadata","pluginTypes","flatMap","type","pluginMetadataByKind","context","Provider","value"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAGjC,SAASA,MAAM,EAAEC,WAAW,EAAEC,OAAO,QAAiC,QAAQ;AAS9E,SAASC,qBAAqB,QAAQ,gBAAgB;AACtD,SAASC,QAAQ,QAAQ,cAAc;AACvC,SAASC,gBAAgB,QAA2B,mBAAmB;AACvE,SAASC,iBAAiB,QAAQ,0BAA0B;AAQ5D;;;CAGC,GACD,OAAO,SAASC,eAAeC,KAA0B;IACvD,MAAM,EACJC,cAAc,EAAEC,mBAAmB,EAAEC,kBAAkB,EAAE,EACzDC,QAAQ,EACRC,kBAAkB,EACnB,GAAGL;IAEJ,MAAMM,mBAAmBT,iBAAiBK;IAE1C,yCAAyC;IACzC,MAAMK,cAAcf,OAAO,IAAIgB;IAE/B,gHAAgH;IAChH,iBAAiB;IACjB,MAAMC,mBAAmBb,SAAS,CAACc;QACjC,IAAIC,UAAUJ,YAAYK,OAAO,CAACC,GAAG,CAACH;QACtC,IAAIC,YAAYG,WAAW;YACzBH,UAAUR,mBAAmBO;YAC7BH,YAAYK,OAAO,CAACG,GAAG,CAACL,UAAUC;YAElC,2EAA2E;YAC3EA,QAAQK,KAAK,CAAC,IAAMT,YAAYK,OAAO,CAACK,MAAM,CAACP;QACjD;QACA,OAAOC;IACT;IAEA,MAAMO,YAAYzB,YAChB,OAA6B0B;QAC3B,MAAMC,gBAAgB,MAAMd;QAC5B,MAAM,EAAEe,IAAI,EAAEC,IAAI,EAAE,GAAGH;QAEvB,MAAMI,gBAAgBzB,kBACpBsB,cAAcI,wCAAwC,CAACC,IAAI,IAC3DN;QAGF,KAAK,MAAMO,eAAeH,cAAe;YACvC,MAAMb,WAAWU,cAAcI,wCAAwC,CAACX,GAAG,CAACa;YAC5E,IAAI,CAAChB,UAAU;YAEf,MAAMiB,eAAgB,MAAMlB,iBAAiBC;YAC7C,wFAAwF;YACxF,MAAMkB,SAASD,cAAc,CAACD,YAAY;YAC1C,IAAIE,QAAQ,OAAOA;YACnB,oFAAoF;YACpF,MAAMC,oBAAoBF,cAAc,CAACL,KAAK;YAC9C,IAAIO,mBAAmB,OAAOA;QAChC;QAEA,MAAM,IAAIC,MAAM,CAAC,EAAE,EAAER,KAAK,kBAAkB,EAAED,KAAK,kBAAkB,CAAC;IACxE,GACA;QAACf;QAAkBG;KAAiB;IAGtC,MAAMsB,qBAAqBtC,YACzB,OAAOuC;QACL,MAAMZ,gBAAgB,MAAMd;QAC5B,OAAO0B,YAAYC,OAAO,CAAC,CAACC,OAASd,cAAce,oBAAoB,CAACtB,GAAG,CAACqB,SAAS,EAAE;IACzF,GACA;QAAC5B;KAAiB;IAGpB,iDAAiD;IACjD,MAAM8B,UAAU1C,QACd,IAAO,CAAA;YAAEwB;YAAWa;YAAoB1B;QAAmB,CAAA,GAC3D;QAACa;QAAWa;QAAoB1B;KAAmB;IAErD,qBAAO,KAACV,sBAAsB0C,QAAQ;QAACC,OAAOF;kBAAUhC;;AAC1D"}
@@ -40,6 +40,12 @@ export interface PanelPlugin<Spec = UnknownSpec, TPanelProps = PanelProps<Spec>>
40
40
  * @default false
41
41
  */
42
42
  hideQueryEditor?: boolean;
43
+ /**
44
+ * If true, the panel editor exposes a common "Annotations" tab so annotations can be configured
45
+ * per panel. Only enable this for panel plugins whose PanelComponent actually renders annotations.
46
+ * @default false
47
+ */
48
+ supportsAnnotations?: boolean;
43
49
  /**
44
50
  * List of panel actions that will be rendered in the panel header
45
51
  */
@@ -1 +1 @@
1
- {"version":3,"file":"panels.d.ts","sourceRoot":"","sources":["../../src/model/panels.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACjH,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE3D,MAAM,MAAM,2BAA2B,CAAC,CAAC,IAAI,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,GAAG;IAC7E,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,WAAW,IAAI;IACrC,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,IAAI,GAAG,WAAW,EAAE,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,CAAE,SAAQ,MAAM,CAAC,IAAI,CAAC;IACnG,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IACjD;;OAEG;IACH,4BAA4B,CAAC,EAAE,KAAK,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC;IACxE;;;OAGG;IACH,gBAAgB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IACpD;;;OAGG;IACH,mBAAmB,CAAC,EAAE,eAAe,EAAE,CAAC;IACxC;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,YAAY,CAAC,CAAC;IAC7D;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;OAEG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,IAAI,EAAE,mBAAmB,GAAG,aAAa;IACnE,IAAI,EAAE,IAAI,CAAC;IACX,iBAAiB,CAAC,EAAE;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,SAAS,CAAC,mBAAmB,GAAG,aAAa;IAC5D,UAAU,EAAE,eAAe,CAAC;IAC5B,IAAI,EAAE,mBAAmB,CAAC;CAC3B;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAElC;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,YAAY,CAAC;IACtB,eAAe,EAAE,eAAe,CAAC;CAClC"}
1
+ {"version":3,"file":"panels.d.ts","sourceRoot":"","sources":["../../src/model/panels.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACjH,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE3D,MAAM,MAAM,2BAA2B,CAAC,CAAC,IAAI,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,GAAG;IAC7E,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,WAAW,IAAI;IACrC,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,IAAI,GAAG,WAAW,EAAE,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,CAAE,SAAQ,MAAM,CAAC,IAAI,CAAC;IACnG,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IACjD;;OAEG;IACH,4BAA4B,CAAC,EAAE,KAAK,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC;IACxE;;;OAGG;IACH,gBAAgB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IACpD;;;OAGG;IACH,mBAAmB,CAAC,EAAE,eAAe,EAAE,CAAC;IACxC;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,YAAY,CAAC,CAAC;IAC7D;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;OAEG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,IAAI,EAAE,mBAAmB,GAAG,aAAa;IACnE,IAAI,EAAE,IAAI,CAAC;IACX,iBAAiB,CAAC,EAAE;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,SAAS,CAAC,mBAAmB,GAAG,aAAa;IAC5D,UAAU,EAAE,eAAe,CAAC;IAC5B,IAAI,EAAE,mBAAmB,CAAC;CAC3B;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAElC;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,YAAY,CAAC;IACtB,eAAe,EAAE,eAAe,CAAC;CAClC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/model/panels.ts"],"sourcesContent":["// Copyright 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 React from 'react';\nimport { PanelDefinition, QueryDataType, QueryDefinition, QueryPluginType, UnknownSpec } from '@perses-dev/spec';\nimport { OptionsEditorTab } from '../components';\nimport { QueryOptions } from '../runtime';\nimport { OptionsEditorProps, Plugin } from './plugin-base';\n\nexport type PanelOptionsEditorComponent<T> = Pick<OptionsEditorTab, 'label'> & {\n content: React.ComponentType<OptionsEditorProps<T>>;\n};\n\nexport type PanelAction<TPanelProps> = {\n component: React.ComponentType<TPanelProps>;\n location?: string; // 'header' or other available locations\n};\n\n/**\n * Plugin the provides custom visualizations inside a Panel.\n */\nexport interface PanelPlugin<Spec = UnknownSpec, TPanelProps = PanelProps<Spec>> extends Plugin<Spec> {\n PanelComponent: React.ComponentType<TPanelProps>;\n /**\n * React components for custom tabs\n */\n panelOptionsEditorComponents?: Array<PanelOptionsEditorComponent<Spec>>;\n /**\n * Show a custom React component when the query is loading.\n * Default: <LoadingOverlay />\n */\n LoadingComponent?: React.ComponentType<TPanelProps>;\n /**\n * List of query types supported by this panel.\n * @default [] (no query types supported) only relevant if hideQueryEditor is true\n */\n supportedQueryTypes?: QueryPluginType[];\n /**\n * Static options for the queries that will be executed.\n * Each {@link QueryPluginType} implementation can have its own options.\n * For example see {@link UseTimeSeriesQueryOptions} for time series queries.\n */\n queryOptions?: QueryOptions | ((spec: Spec) => QueryOptions);\n /**\n * If true, query editor will be hidden for panel plugin\n * @default false\n */\n hideQueryEditor?: boolean;\n /**\n * List of panel actions that will be rendered in the panel header\n */\n actions?: Array<PanelAction<TPanelProps>>;\n}\n\n/**\n * The props provided by Perses to a panel plugin's PanelComponent.\n */\nexport interface PanelProps<Spec, SupportedQueryTypes = QueryDataType> {\n spec: Spec;\n contentDimensions?: {\n width: number;\n height: number;\n };\n definition?: PanelDefinition;\n queryResults: Array<PanelData<SupportedQueryTypes>>;\n}\n\nexport interface PanelData<SupportedQueryTypes = QueryDataType> {\n definition: QueryDefinition;\n data: SupportedQueryTypes;\n}\n\nexport type PanelGroupId = number;\n\n/**\n * Panel values that can be edited in the panel editor.\n */\nexport interface PanelEditorValues {\n groupId: PanelGroupId;\n panelDefinition: PanelDefinition;\n}\n"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAyEjC;;CAEC,GACD,WAGC"}
1
+ {"version":3,"sources":["../../src/model/panels.ts"],"sourcesContent":["// Copyright 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 React from 'react';\nimport { PanelDefinition, QueryDataType, QueryDefinition, QueryPluginType, UnknownSpec } from '@perses-dev/spec';\nimport { OptionsEditorTab } from '../components';\nimport { QueryOptions } from '../runtime';\nimport { OptionsEditorProps, Plugin } from './plugin-base';\n\nexport type PanelOptionsEditorComponent<T> = Pick<OptionsEditorTab, 'label'> & {\n content: React.ComponentType<OptionsEditorProps<T>>;\n};\n\nexport type PanelAction<TPanelProps> = {\n component: React.ComponentType<TPanelProps>;\n location?: string; // 'header' or other available locations\n};\n\n/**\n * Plugin the provides custom visualizations inside a Panel.\n */\nexport interface PanelPlugin<Spec = UnknownSpec, TPanelProps = PanelProps<Spec>> extends Plugin<Spec> {\n PanelComponent: React.ComponentType<TPanelProps>;\n /**\n * React components for custom tabs\n */\n panelOptionsEditorComponents?: Array<PanelOptionsEditorComponent<Spec>>;\n /**\n * Show a custom React component when the query is loading.\n * Default: <LoadingOverlay />\n */\n LoadingComponent?: React.ComponentType<TPanelProps>;\n /**\n * List of query types supported by this panel.\n * @default [] (no query types supported) only relevant if hideQueryEditor is true\n */\n supportedQueryTypes?: QueryPluginType[];\n /**\n * Static options for the queries that will be executed.\n * Each {@link QueryPluginType} implementation can have its own options.\n * For example see {@link UseTimeSeriesQueryOptions} for time series queries.\n */\n queryOptions?: QueryOptions | ((spec: Spec) => QueryOptions);\n /**\n * If true, query editor will be hidden for panel plugin\n * @default false\n */\n hideQueryEditor?: boolean;\n /**\n * If true, the panel editor exposes a common \"Annotations\" tab so annotations can be configured\n * per panel. Only enable this for panel plugins whose PanelComponent actually renders annotations.\n * @default false\n */\n supportsAnnotations?: boolean;\n /**\n * List of panel actions that will be rendered in the panel header\n */\n actions?: Array<PanelAction<TPanelProps>>;\n}\n\n/**\n * The props provided by Perses to a panel plugin's PanelComponent.\n */\nexport interface PanelProps<Spec, SupportedQueryTypes = QueryDataType> {\n spec: Spec;\n contentDimensions?: {\n width: number;\n height: number;\n };\n definition?: PanelDefinition;\n queryResults: Array<PanelData<SupportedQueryTypes>>;\n}\n\nexport interface PanelData<SupportedQueryTypes = QueryDataType> {\n definition: QueryDefinition;\n data: SupportedQueryTypes;\n}\n\nexport type PanelGroupId = number;\n\n/**\n * Panel values that can be edited in the panel editor.\n */\nexport interface PanelEditorValues {\n groupId: PanelGroupId;\n panelDefinition: PanelDefinition;\n}\n"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AA+EjC;;CAEC,GACD,WAGC"}
@@ -84,11 +84,11 @@ const getPluginRuntime = ()=>{
84
84
  }
85
85
  },
86
86
  '@perses-dev/spec': {
87
- version: '0.2.0-rc.0',
87
+ version: '0.3.0-beta.0',
88
88
  lib: ()=>require('@perses-dev/spec'),
89
89
  shareConfig: {
90
90
  singleton: true,
91
- requiredVersion: '^0.2.0-rc.0'
91
+ requiredVersion: '^0.3.0-beta.0'
92
92
  }
93
93
  },
94
94
  '@perses-dev/core': {
@@ -100,43 +100,43 @@ const getPluginRuntime = ()=>{
100
100
  }
101
101
  },
102
102
  '@perses-dev/client': {
103
- version: '0.54.0-rc.1',
103
+ version: '0.55.0-beta.0',
104
104
  lib: ()=>require('@perses-dev/client'),
105
105
  shareConfig: {
106
106
  singleton: true,
107
- requiredVersion: '^0.54.0-rc.1'
107
+ requiredVersion: '^0.55.0-beta.0'
108
108
  }
109
109
  },
110
110
  '@perses-dev/components': {
111
- version: '0.54.0-rc.1',
111
+ version: '0.55.0-beta.0',
112
112
  lib: ()=>require('@perses-dev/components'),
113
113
  shareConfig: {
114
114
  singleton: true,
115
- requiredVersion: '^0.54.0-rc.1'
115
+ requiredVersion: '^0.55.0-beta.0'
116
116
  }
117
117
  },
118
118
  '@perses-dev/plugin-system': {
119
- version: '0.54.0-rc.1',
119
+ version: '0.55.0-beta.0',
120
120
  lib: ()=>require('@perses-dev/plugin-system'),
121
121
  shareConfig: {
122
122
  singleton: true,
123
- requiredVersion: '^0.54.0-rc.1'
123
+ requiredVersion: '^0.55.0-beta.0'
124
124
  }
125
125
  },
126
126
  '@perses-dev/explore': {
127
- version: '0.54.0-rc.1',
127
+ version: '0.55.0-beta.0',
128
128
  lib: ()=>require('@perses-dev/explore'),
129
129
  shareConfig: {
130
130
  singleton: true,
131
- requiredVersion: '^0.54.0-rc.1'
131
+ requiredVersion: '^0.55.0-beta.0'
132
132
  }
133
133
  },
134
134
  '@perses-dev/dashboards': {
135
- version: '0.54.0-rc.1',
135
+ version: '0.55.0-beta.0',
136
136
  lib: ()=>require('@perses-dev/dashboards'),
137
137
  shareConfig: {
138
138
  singleton: true,
139
- requiredVersion: '^0.54.0-rc.1'
139
+ requiredVersion: '^0.55.0-beta.0'
140
140
  }
141
141
  },
142
142
  // Below are the shared modules that are used by the plugins, this can be part of the SDK
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/remote/PluginRuntime.tsx"],"sourcesContent":["// Copyright 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\n/* eslint-disable @typescript-eslint/no-require-imports */\n// Copyright 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 { createInstance, ModuleFederation } from '@module-federation/enhanced/runtime';\n\nimport * as ReactQuery from '@tanstack/react-query';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport * as ReactHookForm from 'react-hook-form';\nimport * as ReactRouterDOM from 'react-router-dom';\nimport { PersesPlugin, RemotePluginModule } from './PersesPlugin.types';\n\nlet instance: ModuleFederation | null = null;\n\nconst getPluginRuntime = (): ModuleFederation => {\n if (instance === null) {\n const pluginRuntime = createInstance({\n name: '@perses/perses-ui-host',\n remotes: [], // all remotes are loaded dynamically\n shared: {\n react: {\n version: React.version,\n lib: () => React,\n shareConfig: {\n singleton: true,\n requiredVersion: `^${React.version}`,\n },\n },\n 'react-dom': {\n version: '18.3.1',\n lib: () => ReactDOM,\n shareConfig: {\n singleton: true,\n requiredVersion: `^18.3.1`,\n },\n },\n 'react-router-dom': {\n version: '6.26.0',\n lib: () => ReactRouterDOM,\n shareConfig: {\n singleton: true,\n requiredVersion: '^6.26.0',\n },\n },\n '@tanstack/react-query': {\n version: '4.39.1',\n lib: () => ReactQuery,\n shareConfig: {\n singleton: true,\n requiredVersion: '^4.39.1',\n },\n },\n 'react-hook-form': {\n version: '7.52.2',\n lib: () => ReactHookForm,\n shareConfig: {\n singleton: true,\n requiredVersion: '^7.52.2',\n },\n },\n echarts: {\n version: '5.5.0',\n lib: () => require('echarts'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^5.5.0',\n },\n },\n '@perses-dev/spec': {\n version: '0.2.0-rc.0',\n lib: () => require('@perses-dev/spec'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.2.0-rc.0',\n },\n },\n '@perses-dev/core': {\n version: '0.53.1',\n lib: () => require('@perses-dev/core'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.53.1',\n },\n },\n '@perses-dev/client': {\n version: '0.54.0-rc.1',\n lib: () => require('@perses-dev/client'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.54.0-rc.1',\n },\n },\n '@perses-dev/components': {\n version: '0.54.0-rc.1',\n lib: () => require('@perses-dev/components'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.54.0-rc.1',\n },\n },\n '@perses-dev/plugin-system': {\n version: '0.54.0-rc.1',\n lib: () => require('@perses-dev/plugin-system'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.54.0-rc.1',\n },\n },\n '@perses-dev/explore': {\n version: '0.54.0-rc.1',\n lib: () => require('@perses-dev/explore'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.54.0-rc.1',\n },\n },\n '@perses-dev/dashboards': {\n version: '0.54.0-rc.1',\n lib: () => require('@perses-dev/dashboards'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.54.0-rc.1',\n },\n },\n // Below are the shared modules that are used by the plugins, this can be part of the SDK\n 'date-fns': {\n version: '4.1.0',\n lib: () => require('date-fns'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^4.1.0',\n },\n },\n 'date-fns-tz': {\n version: '3.2.0',\n lib: () => require('date-fns-tz'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^3.2.0',\n },\n },\n lodash: {\n version: '4.17.21',\n lib: () => require('lodash'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^4.17.21',\n },\n },\n '@emotion/react': {\n version: '11.11.3',\n lib: () => require('@emotion/react'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^11.11.3',\n },\n },\n '@emotion/styled': {\n version: '11.11.0',\n lib: () => require('@emotion/styled'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^11.11.0',\n },\n },\n '@hookform/resolvers/zod': {\n version: '3.3.4',\n lib: () => require('@hookform/resolvers/zod'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^3.3.4',\n },\n },\n 'use-resize-observer': {\n version: '9.1.0',\n lib: () => require('use-resize-observer'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^9.1.0',\n },\n },\n 'mdi-material-ui': {\n version: '7.4.0',\n lib: () => require('mdi-material-ui'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^7.4.0',\n },\n },\n immer: {\n version: '10.1.1',\n lib: () => require('immer'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^10.1.1',\n },\n },\n },\n });\n\n instance = pluginRuntime;\n\n return instance;\n }\n return instance;\n};\n\nfunction getModuleFederationRemoteName(name: string, registry?: string, version?: string): string {\n return `${name}:${registry ?? ''}:${version ?? ''}`;\n}\n\nconst registerRemote = (name: string, registry?: string, version?: string, baseURL?: string): void => {\n const pluginRuntime = getPluginRuntime();\n const registryName = getModuleFederationRemoteName(name, registry, version);\n\n const existingRemote = pluginRuntime.options.remotes.find((remote) => remote.name === registryName);\n if (!existingRemote) {\n const nameVersionRegistry = [name, version, registry].filter(Boolean).join('~');\n const prefix = baseURL || '/plugins';\n const remoteEntryURL = `${prefix}/${nameVersionRegistry}/mf-manifest.json`;\n\n pluginRuntime.registerRemotes([\n {\n name: registryName,\n entry: remoteEntryURL,\n alias: registryName,\n },\n ]);\n }\n};\n\nexport const loadPlugin = async (target: {\n moduleName: string;\n pluginName: string;\n registry?: string;\n version?: string;\n baseURL?: string;\n}): Promise<RemotePluginModule | null> => {\n const { moduleName, pluginName, registry, version, baseURL } = target;\n registerRemote(moduleName, registry, version, baseURL);\n\n const pluginRuntime = getPluginRuntime();\n const registryName = getModuleFederationRemoteName(moduleName, registry, version);\n return pluginRuntime.loadRemote<RemotePluginModule>(`${registryName}/${pluginName}`);\n};\n\nexport function usePluginRuntime({ plugin }: { plugin: PersesPlugin }): {\n pluginRuntime: ModuleFederation;\n loadPlugin: () => Promise<RemotePluginModule | null>;\n} {\n return {\n pluginRuntime: getPluginRuntime(),\n loadPlugin: (): Promise<RemotePluginModule | null> => {\n const { moduleName, name: pluginName, registry, version, baseURL } = plugin;\n return loadPlugin({ moduleName, pluginName, registry, version, baseURL });\n },\n };\n}\n"],"names":["createInstance","ReactQuery","React","ReactDOM","ReactHookForm","ReactRouterDOM","instance","getPluginRuntime","pluginRuntime","name","remotes","shared","react","version","lib","shareConfig","singleton","requiredVersion","echarts","require","lodash","immer","getModuleFederationRemoteName","registry","registerRemote","baseURL","registryName","existingRemote","options","find","remote","nameVersionRegistry","filter","Boolean","join","prefix","remoteEntryURL","registerRemotes","entry","alias","loadPlugin","target","moduleName","pluginName","loadRemote","usePluginRuntime","plugin"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/remote/PluginRuntime.tsx"],"sourcesContent":["// Copyright 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\n/* eslint-disable @typescript-eslint/no-require-imports */\n// Copyright 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 { createInstance, ModuleFederation } from '@module-federation/enhanced/runtime';\n\nimport * as ReactQuery from '@tanstack/react-query';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport * as ReactHookForm from 'react-hook-form';\nimport * as ReactRouterDOM from 'react-router-dom';\nimport { PersesPlugin, RemotePluginModule } from './PersesPlugin.types';\n\nlet instance: ModuleFederation | null = null;\n\nconst getPluginRuntime = (): ModuleFederation => {\n if (instance === null) {\n const pluginRuntime = createInstance({\n name: '@perses/perses-ui-host',\n remotes: [], // all remotes are loaded dynamically\n shared: {\n react: {\n version: React.version,\n lib: () => React,\n shareConfig: {\n singleton: true,\n requiredVersion: `^${React.version}`,\n },\n },\n 'react-dom': {\n version: '18.3.1',\n lib: () => ReactDOM,\n shareConfig: {\n singleton: true,\n requiredVersion: `^18.3.1`,\n },\n },\n 'react-router-dom': {\n version: '6.26.0',\n lib: () => ReactRouterDOM,\n shareConfig: {\n singleton: true,\n requiredVersion: '^6.26.0',\n },\n },\n '@tanstack/react-query': {\n version: '4.39.1',\n lib: () => ReactQuery,\n shareConfig: {\n singleton: true,\n requiredVersion: '^4.39.1',\n },\n },\n 'react-hook-form': {\n version: '7.52.2',\n lib: () => ReactHookForm,\n shareConfig: {\n singleton: true,\n requiredVersion: '^7.52.2',\n },\n },\n echarts: {\n version: '5.5.0',\n lib: () => require('echarts'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^5.5.0',\n },\n },\n '@perses-dev/spec': {\n version: '0.3.0-beta.0',\n lib: () => require('@perses-dev/spec'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.3.0-beta.0',\n },\n },\n '@perses-dev/core': {\n version: '0.53.1',\n lib: () => require('@perses-dev/core'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.53.1',\n },\n },\n '@perses-dev/client': {\n version: '0.55.0-beta.0',\n lib: () => require('@perses-dev/client'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.55.0-beta.0',\n },\n },\n '@perses-dev/components': {\n version: '0.55.0-beta.0',\n lib: () => require('@perses-dev/components'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.55.0-beta.0',\n },\n },\n '@perses-dev/plugin-system': {\n version: '0.55.0-beta.0',\n lib: () => require('@perses-dev/plugin-system'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.55.0-beta.0',\n },\n },\n '@perses-dev/explore': {\n version: '0.55.0-beta.0',\n lib: () => require('@perses-dev/explore'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.55.0-beta.0',\n },\n },\n '@perses-dev/dashboards': {\n version: '0.55.0-beta.0',\n lib: () => require('@perses-dev/dashboards'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^0.55.0-beta.0',\n },\n },\n // Below are the shared modules that are used by the plugins, this can be part of the SDK\n 'date-fns': {\n version: '4.1.0',\n lib: () => require('date-fns'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^4.1.0',\n },\n },\n 'date-fns-tz': {\n version: '3.2.0',\n lib: () => require('date-fns-tz'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^3.2.0',\n },\n },\n lodash: {\n version: '4.17.21',\n lib: () => require('lodash'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^4.17.21',\n },\n },\n '@emotion/react': {\n version: '11.11.3',\n lib: () => require('@emotion/react'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^11.11.3',\n },\n },\n '@emotion/styled': {\n version: '11.11.0',\n lib: () => require('@emotion/styled'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^11.11.0',\n },\n },\n '@hookform/resolvers/zod': {\n version: '3.3.4',\n lib: () => require('@hookform/resolvers/zod'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^3.3.4',\n },\n },\n 'use-resize-observer': {\n version: '9.1.0',\n lib: () => require('use-resize-observer'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^9.1.0',\n },\n },\n 'mdi-material-ui': {\n version: '7.4.0',\n lib: () => require('mdi-material-ui'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^7.4.0',\n },\n },\n immer: {\n version: '10.1.1',\n lib: () => require('immer'),\n shareConfig: {\n singleton: true,\n requiredVersion: '^10.1.1',\n },\n },\n },\n });\n\n instance = pluginRuntime;\n\n return instance;\n }\n return instance;\n};\n\nfunction getModuleFederationRemoteName(name: string, registry?: string, version?: string): string {\n return `${name}:${registry ?? ''}:${version ?? ''}`;\n}\n\nconst registerRemote = (name: string, registry?: string, version?: string, baseURL?: string): void => {\n const pluginRuntime = getPluginRuntime();\n const registryName = getModuleFederationRemoteName(name, registry, version);\n\n const existingRemote = pluginRuntime.options.remotes.find((remote) => remote.name === registryName);\n if (!existingRemote) {\n const nameVersionRegistry = [name, version, registry].filter(Boolean).join('~');\n const prefix = baseURL || '/plugins';\n const remoteEntryURL = `${prefix}/${nameVersionRegistry}/mf-manifest.json`;\n\n pluginRuntime.registerRemotes([\n {\n name: registryName,\n entry: remoteEntryURL,\n alias: registryName,\n },\n ]);\n }\n};\n\nexport const loadPlugin = async (target: {\n moduleName: string;\n pluginName: string;\n registry?: string;\n version?: string;\n baseURL?: string;\n}): Promise<RemotePluginModule | null> => {\n const { moduleName, pluginName, registry, version, baseURL } = target;\n registerRemote(moduleName, registry, version, baseURL);\n\n const pluginRuntime = getPluginRuntime();\n const registryName = getModuleFederationRemoteName(moduleName, registry, version);\n return pluginRuntime.loadRemote<RemotePluginModule>(`${registryName}/${pluginName}`);\n};\n\nexport function usePluginRuntime({ plugin }: { plugin: PersesPlugin }): {\n pluginRuntime: ModuleFederation;\n loadPlugin: () => Promise<RemotePluginModule | null>;\n} {\n return {\n pluginRuntime: getPluginRuntime(),\n loadPlugin: (): Promise<RemotePluginModule | null> => {\n const { moduleName, name: pluginName, registry, version, baseURL } = plugin;\n return loadPlugin({ moduleName, pluginName, registry, version, baseURL });\n },\n };\n}\n"],"names":["createInstance","ReactQuery","React","ReactDOM","ReactHookForm","ReactRouterDOM","instance","getPluginRuntime","pluginRuntime","name","remotes","shared","react","version","lib","shareConfig","singleton","requiredVersion","echarts","require","lodash","immer","getModuleFederationRemoteName","registry","registerRemote","baseURL","registryName","existingRemote","options","find","remote","nameVersionRegistry","filter","Boolean","join","prefix","remoteEntryURL","registerRemotes","entry","alias","loadPlugin","target","moduleName","pluginName","loadRemote","usePluginRuntime","plugin"],"mappings":"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"}