@perses-dev/plugin-system 0.52.0-rc.0 → 0.52.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/DatasourceSelect.js +2 -1
- package/dist/cjs/components/LegendOptionsEditor/LegendOptionsEditor.js +73 -73
- package/dist/cjs/components/MultiQueryEditor/MultiQueryEditor.js +5 -2
- package/dist/cjs/components/MultiQueryEditor/QueryEditorContainer.js +13 -4
- package/dist/cjs/components/PanelSpecEditor/PanelSpecEditor.js +7 -5
- package/dist/cjs/components/PluginEditor/PluginEditor.js +25 -21
- package/dist/cjs/components/PluginKindSelect/PluginKindSelect.js +6 -3
- package/dist/cjs/components/Variables/VariableEditorForm/VariableEditorForm.js +5 -11
- package/dist/cjs/components/Variables/VariableEditorForm/VariablePreview.js +2 -13
- package/dist/cjs/context/query-params.js +1 -1
- package/dist/cjs/test/utils.js +17 -8
- package/dist/components/DatasourceSelect.d.ts.map +1 -1
- package/dist/components/DatasourceSelect.js +2 -1
- package/dist/components/DatasourceSelect.js.map +1 -1
- package/dist/components/LegendOptionsEditor/LegendOptionsEditor.d.ts.map +1 -1
- package/dist/components/LegendOptionsEditor/LegendOptionsEditor.js +75 -75
- package/dist/components/LegendOptionsEditor/LegendOptionsEditor.js.map +1 -1
- package/dist/components/MultiQueryEditor/MultiQueryEditor.d.ts +3 -2
- package/dist/components/MultiQueryEditor/MultiQueryEditor.d.ts.map +1 -1
- package/dist/components/MultiQueryEditor/MultiQueryEditor.js +6 -3
- package/dist/components/MultiQueryEditor/MultiQueryEditor.js.map +1 -1
- package/dist/components/MultiQueryEditor/QueryEditorContainer.d.ts +3 -2
- package/dist/components/MultiQueryEditor/QueryEditorContainer.d.ts.map +1 -1
- package/dist/components/MultiQueryEditor/QueryEditorContainer.js +13 -4
- package/dist/components/MultiQueryEditor/QueryEditorContainer.js.map +1 -1
- package/dist/components/PanelSpecEditor/PanelSpecEditor.d.ts +3 -2
- package/dist/components/PanelSpecEditor/PanelSpecEditor.d.ts.map +1 -1
- package/dist/components/PanelSpecEditor/PanelSpecEditor.js +7 -5
- package/dist/components/PanelSpecEditor/PanelSpecEditor.js.map +1 -1
- package/dist/components/PluginEditor/PluginEditor.d.ts +3 -3
- package/dist/components/PluginEditor/PluginEditor.d.ts.map +1 -1
- package/dist/components/PluginEditor/PluginEditor.js +26 -22
- package/dist/components/PluginEditor/PluginEditor.js.map +1 -1
- package/dist/components/PluginEditor/plugin-editor-api.d.ts +4 -0
- package/dist/components/PluginEditor/plugin-editor-api.d.ts.map +1 -1
- package/dist/components/PluginEditor/plugin-editor-api.js.map +1 -1
- package/dist/components/PluginKindSelect/PluginKindSelect.d.ts.map +1 -1
- package/dist/components/PluginKindSelect/PluginKindSelect.js +7 -4
- package/dist/components/PluginKindSelect/PluginKindSelect.js.map +1 -1
- package/dist/components/Variables/VariableEditorForm/VariableEditorForm.d.ts.map +1 -1
- package/dist/components/Variables/VariableEditorForm/VariableEditorForm.js +5 -11
- package/dist/components/Variables/VariableEditorForm/VariableEditorForm.js.map +1 -1
- package/dist/components/Variables/VariableEditorForm/VariablePreview.d.ts +0 -2
- package/dist/components/Variables/VariableEditorForm/VariablePreview.d.ts.map +1 -1
- package/dist/components/Variables/VariableEditorForm/VariablePreview.js +2 -13
- package/dist/components/Variables/VariableEditorForm/VariablePreview.js.map +1 -1
- package/dist/context/query-params.js +1 -1
- package/dist/context/query-params.js.map +1 -1
- package/dist/runtime/TimeRangeProvider/query-params.d.ts.map +1 -1
- package/dist/runtime/TimeRangeProvider/query-params.js.map +1 -1
- package/dist/test/utils.d.ts.map +1 -1
- package/dist/test/utils.js +17 -8
- package/dist/test/utils.js.map +1 -1
- package/package.json +5 -5
|
@@ -61,7 +61,7 @@ const emptyDatasourceOption = {
|
|
|
61
61
|
value: ''
|
|
62
62
|
};
|
|
63
63
|
function DatasourceSelect(props) {
|
|
64
|
-
const { datasourcePluginKind, value, project, onChange, ...others } = props;
|
|
64
|
+
const { datasourcePluginKind, value, project, readOnly, onChange, ...others } = props;
|
|
65
65
|
const { data, isLoading } = (0, _runtime.useListDatasourceSelectItems)(datasourcePluginKind, project);
|
|
66
66
|
const variables = (0, _runtime.useVariableValues)();
|
|
67
67
|
const defaultValue = (0, _react.useMemo)(()=>{
|
|
@@ -132,6 +132,7 @@ function DatasourceSelect(props) {
|
|
|
132
132
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
133
133
|
const fakeActionEvent = ()=>{};
|
|
134
134
|
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Autocomplete, {
|
|
135
|
+
readOnly: readOnly,
|
|
135
136
|
options: options,
|
|
136
137
|
renderInput: (params)=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TextField, {
|
|
137
138
|
...params,
|
|
@@ -32,12 +32,6 @@ const POSITION_OPTIONS = Object.entries(_model.LEGEND_POSITIONS_CONFIG).map(([id
|
|
|
32
32
|
...config
|
|
33
33
|
};
|
|
34
34
|
});
|
|
35
|
-
const MODE_OPTIONS = Object.entries(_model.LEGEND_MODE_CONFIG).map(([id, config])=>{
|
|
36
|
-
return {
|
|
37
|
-
id: id,
|
|
38
|
-
...config
|
|
39
|
-
};
|
|
40
|
-
});
|
|
41
35
|
const SIZE_OPTIONS = Object.entries(_model.LEGEND_SIZE_CONFIG).map(([id, config])=>{
|
|
42
36
|
return {
|
|
43
37
|
id: id,
|
|
@@ -58,13 +52,6 @@ function LegendOptionsEditor({ value, onChange, showValuesEditor = true, calcula
|
|
|
58
52
|
position: newValue.id
|
|
59
53
|
});
|
|
60
54
|
};
|
|
61
|
-
const handleLegendModeChange = (_, newValue)=>{
|
|
62
|
-
onChange({
|
|
63
|
-
...value,
|
|
64
|
-
position: currentPosition,
|
|
65
|
-
mode: newValue.id
|
|
66
|
-
});
|
|
67
|
-
};
|
|
68
55
|
const handleLegendSizeChange = (_, newValue)=>{
|
|
69
56
|
onChange({
|
|
70
57
|
...value,
|
|
@@ -85,7 +72,6 @@ function LegendOptionsEditor({ value, onChange, showValuesEditor = true, calcula
|
|
|
85
72
|
const currentPosition = (0, _core.getLegendPosition)(value?.position);
|
|
86
73
|
const legendPositionConfig = _model.LEGEND_POSITIONS_CONFIG[currentPosition];
|
|
87
74
|
const currentMode = (0, _core.getLegendMode)(value?.mode);
|
|
88
|
-
const legendModeConfig = _model.LEGEND_MODE_CONFIG[currentMode];
|
|
89
75
|
const currentSize = (0, _core.getLegendSize)(value?.size);
|
|
90
76
|
const legendSizeConfig = _model.LEGEND_SIZE_CONFIG[currentSize];
|
|
91
77
|
const legendValuesConfig = (0, _react.useMemo)(()=>{
|
|
@@ -147,65 +133,79 @@ function LegendOptionsEditor({ value, onChange, showValuesEditor = true, calcula
|
|
|
147
133
|
onChange: handleLegendShowChange
|
|
148
134
|
})
|
|
149
135
|
}),
|
|
150
|
-
/*#__PURE__*/ (0, _jsxruntime.
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
136
|
+
value && /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
|
|
137
|
+
children: [
|
|
138
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_components.OptionsEditorControl, {
|
|
139
|
+
label: "Position",
|
|
140
|
+
control: /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.SettingsAutocomplete, {
|
|
141
|
+
value: {
|
|
142
|
+
...legendPositionConfig,
|
|
143
|
+
id: currentPosition
|
|
144
|
+
},
|
|
145
|
+
options: POSITION_OPTIONS,
|
|
146
|
+
onChange: handleLegendPositionChange,
|
|
147
|
+
disableClearable: true
|
|
148
|
+
})
|
|
149
|
+
}),
|
|
150
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_components.OptionsEditorControl, {
|
|
151
|
+
label: "Mode",
|
|
152
|
+
control: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.ToggleButtonGroup, {
|
|
153
|
+
color: "primary",
|
|
154
|
+
exclusive: true,
|
|
155
|
+
value: currentMode,
|
|
156
|
+
"aria-label": "Mode",
|
|
157
|
+
onChange: (__, newValue)=>{
|
|
158
|
+
onChange({
|
|
159
|
+
...value,
|
|
160
|
+
position: currentPosition,
|
|
161
|
+
mode: newValue
|
|
162
|
+
});
|
|
163
|
+
},
|
|
164
|
+
children: Object.entries(_model.LEGEND_MODE_CONFIG).map(([modeId, config])=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.ToggleButton, {
|
|
165
|
+
value: modeId,
|
|
166
|
+
selected: currentMode === modeId,
|
|
167
|
+
"aria-label": `display ${modeId} mode`,
|
|
168
|
+
children: config.label
|
|
169
|
+
}, modeId))
|
|
170
|
+
})
|
|
171
|
+
}),
|
|
172
|
+
currentMode === 'table' && /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
|
|
173
|
+
children: [
|
|
174
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_components.OptionsEditorControl, {
|
|
175
|
+
label: "Size",
|
|
176
|
+
control: /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.SettingsAutocomplete, {
|
|
177
|
+
value: {
|
|
178
|
+
...legendSizeConfig,
|
|
179
|
+
id: currentSize
|
|
180
|
+
},
|
|
181
|
+
options: SIZE_OPTIONS,
|
|
182
|
+
onChange: handleLegendSizeChange,
|
|
183
|
+
// TODO: enable sizes for list mode when we normalize the layout of
|
|
184
|
+
// lists to more closely match tables.
|
|
185
|
+
disableClearable: true
|
|
186
|
+
})
|
|
187
|
+
}),
|
|
188
|
+
showValuesEditor && /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.OptionsEditorControl, {
|
|
189
|
+
label: "Values",
|
|
190
|
+
control: // For some reason, the inferred option type doesn't always seem to work
|
|
191
|
+
// quite right when `multiple` is true. Explicitly setting the generics
|
|
192
|
+
// to work around this.
|
|
193
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_components.SettingsAutocomplete, {
|
|
194
|
+
multiple: true,
|
|
195
|
+
disableCloseOnSelect: true,
|
|
196
|
+
disableClearable: true,
|
|
197
|
+
value: legendValuesConfig,
|
|
198
|
+
options: valueOptions,
|
|
199
|
+
onChange: handleLegendValueChange,
|
|
200
|
+
limitTags: 1,
|
|
201
|
+
ChipProps: {
|
|
202
|
+
size: 'small'
|
|
203
|
+
}
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
]
|
|
207
|
+
})
|
|
208
|
+
]
|
|
209
209
|
})
|
|
210
210
|
]
|
|
211
211
|
});
|
|
@@ -60,7 +60,8 @@ function useDefaultQueryDefinition(queryTypes) {
|
|
|
60
60
|
isLoading
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
|
-
|
|
63
|
+
const MultiQueryEditor = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
|
|
64
|
+
const { queryTypes, queries = [], onChange } = props;
|
|
64
65
|
const { defaultInitialQueryDefinition, isLoading } = useDefaultQueryDefinition(queryTypes);
|
|
65
66
|
// State for which queries are collapsed
|
|
66
67
|
const [queriesCollapsed, setQueriesCollapsed] = (0, _react.useState)(queries.map(()=>false));
|
|
@@ -122,6 +123,7 @@ function MultiQueryEditor({ queryTypes, queries = [], onChange }) {
|
|
|
122
123
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Stack, {
|
|
123
124
|
spacing: 1,
|
|
124
125
|
children: queryDefinitions.map((query, i)=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_QueryEditorContainer.QueryEditorContainer, {
|
|
126
|
+
ref: ref,
|
|
125
127
|
queryTypes: queryTypes,
|
|
126
128
|
index: i,
|
|
127
129
|
query: query,
|
|
@@ -142,4 +144,5 @@ function MultiQueryEditor({ queryTypes, queries = [], onChange }) {
|
|
|
142
144
|
})
|
|
143
145
|
]
|
|
144
146
|
});
|
|
145
|
-
}
|
|
147
|
+
});
|
|
148
|
+
MultiQueryEditor.displayName = 'MultiQueryEditor';
|
|
@@ -26,13 +26,16 @@ const _material = require("@mui/material");
|
|
|
26
26
|
const _DeleteOutline = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/DeleteOutline"));
|
|
27
27
|
const _ChevronDown = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/ChevronDown"));
|
|
28
28
|
const _ChevronRight = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/ChevronRight"));
|
|
29
|
+
const _react = require("react");
|
|
29
30
|
const _PluginEditor = require("../PluginEditor");
|
|
31
|
+
const _runtime = require("../../runtime");
|
|
30
32
|
function _interop_require_default(obj) {
|
|
31
33
|
return obj && obj.__esModule ? obj : {
|
|
32
34
|
default: obj
|
|
33
35
|
};
|
|
34
36
|
}
|
|
35
|
-
const QueryEditorContainer = (
|
|
37
|
+
const QueryEditorContainer = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
|
|
38
|
+
const { queryTypes, index, query, isCollapsed, onDelete, onChange, onCollapseExpand } = props;
|
|
36
39
|
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Stack, {
|
|
37
40
|
spacing: 1,
|
|
38
41
|
children: [
|
|
@@ -68,21 +71,24 @@ const QueryEditorContainer = ({ queryTypes, index, query, isCollapsed, onDelete,
|
|
|
68
71
|
]
|
|
69
72
|
}),
|
|
70
73
|
!isCollapsed && /*#__PURE__*/ (0, _jsxruntime.jsx)(QueryEditor, {
|
|
74
|
+
ref: ref,
|
|
71
75
|
queryTypes: queryTypes,
|
|
72
76
|
value: query,
|
|
73
77
|
onChange: (next)=>onChange(index, next)
|
|
74
78
|
})
|
|
75
79
|
]
|
|
76
80
|
}, index);
|
|
77
|
-
};
|
|
81
|
+
});
|
|
82
|
+
QueryEditorContainer.displayName = 'QueryEditorContainer';
|
|
78
83
|
/**
|
|
79
84
|
* Editor for a query definition. This component is responsible for rendering the plugin editor for the given query.
|
|
80
85
|
* This will allow user to select a plugin extending from the given supported query types, and then edit the plugin
|
|
81
86
|
* spec for this plugin.
|
|
82
87
|
* @param props
|
|
83
88
|
* @constructor
|
|
84
|
-
*/
|
|
89
|
+
*/ const QueryEditor = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
|
|
85
90
|
const { value, onChange, queryTypes, ...others } = props;
|
|
91
|
+
const { refresh } = (0, _runtime.useTimeRange)();
|
|
86
92
|
const handlePluginChange = (next)=>{
|
|
87
93
|
onChange((0, _immer.produce)(value, (draft)=>{
|
|
88
94
|
draft.kind = next.selection.type;
|
|
@@ -93,6 +99,8 @@ const QueryEditorContainer = ({ queryTypes, index, query, isCollapsed, onDelete,
|
|
|
93
99
|
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
|
|
94
100
|
...others,
|
|
95
101
|
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_PluginEditor.PluginEditor, {
|
|
102
|
+
postExecuteRunQuery: refresh,
|
|
103
|
+
ref: ref,
|
|
96
104
|
withRunQueryButton: true,
|
|
97
105
|
pluginTypes: queryTypes,
|
|
98
106
|
pluginKindLabel: "Query Type",
|
|
@@ -106,4 +114,5 @@ const QueryEditorContainer = ({ queryTypes, index, query, isCollapsed, onDelete,
|
|
|
106
114
|
onChange: handlePluginChange
|
|
107
115
|
})
|
|
108
116
|
});
|
|
109
|
-
}
|
|
117
|
+
});
|
|
118
|
+
QueryEditor.displayName = 'QueryEditor';
|
|
@@ -23,10 +23,11 @@ Object.defineProperty(exports, "PanelSpecEditor", {
|
|
|
23
23
|
const _jsxruntime = require("react/jsx-runtime");
|
|
24
24
|
const _components = require("@perses-dev/components");
|
|
25
25
|
const _reacthookform = require("react-hook-form");
|
|
26
|
+
const _react = require("react");
|
|
26
27
|
const _runtime = require("../../runtime");
|
|
27
28
|
const _OptionsEditorTabs = require("../OptionsEditorTabs");
|
|
28
29
|
const _MultiQueryEditor = require("../MultiQueryEditor");
|
|
29
|
-
|
|
30
|
+
const PanelSpecEditor = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
|
|
30
31
|
const { control, panelDefinition, onJSONChange, onQueriesChange, onPluginSpecChange } = props;
|
|
31
32
|
const { kind } = panelDefinition.spec.plugin;
|
|
32
33
|
const { data: plugin, isLoading, error } = (0, _runtime.usePlugin)('Panel', kind);
|
|
@@ -35,11 +36,10 @@ function PanelSpecEditor(props) {
|
|
|
35
36
|
error: error
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
|
-
// TODO: Proper loading indicator
|
|
39
39
|
if (isLoading) {
|
|
40
40
|
return null;
|
|
41
41
|
}
|
|
42
|
-
if (plugin
|
|
42
|
+
if (!plugin) {
|
|
43
43
|
throw new Error(`Missing implementation for panel plugin with kind '${kind}'`);
|
|
44
44
|
}
|
|
45
45
|
const { panelOptionsEditorComponents, hideQueryEditor } = plugin;
|
|
@@ -51,6 +51,7 @@ function PanelSpecEditor(props) {
|
|
|
51
51
|
control: control,
|
|
52
52
|
name: "panelDefinition.spec.queries",
|
|
53
53
|
render: ({ field })=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_MultiQueryEditor.MultiQueryEditor, {
|
|
54
|
+
ref: ref,
|
|
54
55
|
queryTypes: plugin.supportedQueryTypes ?? [],
|
|
55
56
|
queries: panelDefinition.spec.queries ?? [],
|
|
56
57
|
onChange: (queries)=>{
|
|
@@ -61,7 +62,7 @@ function PanelSpecEditor(props) {
|
|
|
61
62
|
})
|
|
62
63
|
});
|
|
63
64
|
}
|
|
64
|
-
if (panelOptionsEditorComponents
|
|
65
|
+
if (panelOptionsEditorComponents) {
|
|
65
66
|
tabs = tabs.concat(panelOptionsEditorComponents.map(({ label, content: OptionsEditorComponent })=>({
|
|
66
67
|
label,
|
|
67
68
|
content: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reacthookform.Controller, {
|
|
@@ -105,4 +106,5 @@ function PanelSpecEditor(props) {
|
|
|
105
106
|
tabs: tabs
|
|
106
107
|
}, tabs.length)
|
|
107
108
|
});
|
|
108
|
-
}
|
|
109
|
+
});
|
|
110
|
+
PanelSpecEditor.displayName = 'PanelSpecEditor';
|
|
@@ -33,17 +33,16 @@ function _interop_require_default(obj) {
|
|
|
33
33
|
default: obj
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const { value, withRunQueryButton = true, pluginTypes, pluginKindLabel, onChange: _, isReadonly, ...others } = props;
|
|
36
|
+
const PluginEditor = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
|
|
37
|
+
const { value, withRunQueryButton = true, pluginTypes, pluginKindLabel, onChange: _, isReadonly, postExecuteRunQuery: refresh, ...others } = props;
|
|
39
38
|
const { pendingSelection, isLoading, error, onSelectionChange, onSpecChange } = (0, _plugineditorapi.usePluginEditor)(props);
|
|
40
39
|
/*
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
We could technically merge the watchedQuery, watchedOtherSpecs into a single watched-object,
|
|
41
|
+
because at the end of the day, they are all specs.
|
|
42
|
+
However, let's have them separated to keep the code simple and readable.
|
|
43
|
+
Reason: Only Query string field is common between all of them. Other specs may be different
|
|
44
|
+
Example: Legend, and MinSteps
|
|
45
|
+
*/ const [watchedQuery, setWatchQuery] = (0, _react.useState)(value.spec['query']);
|
|
47
46
|
const [watchedOtherSpecs, setWatchOtherSpecs] = (0, _react.useState)(value.spec);
|
|
48
47
|
const runQueryHandler = (0, _react.useCallback)(()=>{
|
|
49
48
|
onSpecChange({
|
|
@@ -51,11 +50,13 @@ function PluginEditor(props) {
|
|
|
51
50
|
...watchedOtherSpecs,
|
|
52
51
|
query: watchedQuery
|
|
53
52
|
});
|
|
53
|
+
refresh?.();
|
|
54
54
|
}, [
|
|
55
55
|
value.spec,
|
|
56
56
|
onSpecChange,
|
|
57
57
|
watchedQuery,
|
|
58
|
-
watchedOtherSpecs
|
|
58
|
+
watchedOtherSpecs,
|
|
59
|
+
refresh
|
|
59
60
|
]);
|
|
60
61
|
const queryHandlerSettings = (0, _react.useMemo)(()=>{
|
|
61
62
|
return withRunQueryButton ? {
|
|
@@ -70,19 +71,25 @@ function PluginEditor(props) {
|
|
|
70
71
|
}, [
|
|
71
72
|
withRunQueryButton
|
|
72
73
|
]);
|
|
74
|
+
(0, _react.useImperativeHandle)(ref, ()=>({
|
|
75
|
+
flushChanges: runQueryHandler
|
|
76
|
+
}));
|
|
73
77
|
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Box, {
|
|
74
78
|
...others,
|
|
75
79
|
children: [
|
|
76
80
|
/*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Box, {
|
|
77
81
|
sx: {
|
|
78
82
|
display: 'flex',
|
|
79
|
-
flexDirection: 'row'
|
|
83
|
+
flexDirection: 'row',
|
|
84
|
+
alignItems: 'center',
|
|
85
|
+
justifyContent: 'space-between',
|
|
86
|
+
gap: 1,
|
|
87
|
+
mb: 1
|
|
80
88
|
},
|
|
81
89
|
children: [
|
|
82
90
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(_PluginKindSelect.PluginKindSelect, {
|
|
83
91
|
fullWidth: false,
|
|
84
92
|
sx: {
|
|
85
|
-
mb: 2,
|
|
86
93
|
minWidth: 120
|
|
87
94
|
},
|
|
88
95
|
margin: "dense",
|
|
@@ -90,8 +97,10 @@ function PluginEditor(props) {
|
|
|
90
97
|
pluginTypes: pluginTypes,
|
|
91
98
|
disabled: isLoading,
|
|
92
99
|
value: pendingSelection ? pendingSelection : value.selection,
|
|
93
|
-
|
|
94
|
-
|
|
100
|
+
slotProps: {
|
|
101
|
+
input: {
|
|
102
|
+
readOnly: isReadonly
|
|
103
|
+
}
|
|
95
104
|
},
|
|
96
105
|
error: !!error,
|
|
97
106
|
helperText: error?.message,
|
|
@@ -100,12 +109,6 @@ function PluginEditor(props) {
|
|
|
100
109
|
withRunQueryButton && !isLoading && /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Button, {
|
|
101
110
|
"data-testid": "run_query_button",
|
|
102
111
|
variant: "contained",
|
|
103
|
-
sx: {
|
|
104
|
-
marginTop: 1.5,
|
|
105
|
-
marginBottom: 1.5,
|
|
106
|
-
paddingTop: 0.5,
|
|
107
|
-
marginLeft: 'auto'
|
|
108
|
-
},
|
|
109
112
|
startIcon: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Reload.default, {}),
|
|
110
113
|
onClick: runQueryHandler,
|
|
111
114
|
children: "Run Query"
|
|
@@ -124,4 +127,5 @@ function PluginEditor(props) {
|
|
|
124
127
|
})
|
|
125
128
|
]
|
|
126
129
|
});
|
|
127
|
-
}
|
|
130
|
+
});
|
|
131
|
+
PluginEditor.displayName = 'PluginEditor';
|
|
@@ -27,6 +27,9 @@ const _runtime = require("../../runtime");
|
|
|
27
27
|
const PluginKindSelect = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
|
|
28
28
|
const { pluginTypes, value: propValue, onChange, ...others } = props;
|
|
29
29
|
const { data, isLoading } = (0, _runtime.useListPluginMetadata)(pluginTypes);
|
|
30
|
+
const sortedData = (0, _react.useMemo)(()=>data?.sort((a, b)=>a.spec.display.name.localeCompare(b.spec.display.name)), [
|
|
31
|
+
data
|
|
32
|
+
]);
|
|
30
33
|
// Pass an empty value while options are still loading so MUI doesn't complain about us using an "out of range" value
|
|
31
34
|
const value = !propValue || isLoading ? '' : selectionToOptionValue(propValue);
|
|
32
35
|
const handleChange = (event)=>{
|
|
@@ -37,9 +40,9 @@ const PluginKindSelect = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
|
|
|
37
40
|
return '';
|
|
38
41
|
}
|
|
39
42
|
const selectedValue = optionValueToSelection(selected);
|
|
40
|
-
return
|
|
43
|
+
return sortedData?.find((v)=>v.kind === selectedValue.type && v.spec.name === selectedValue.kind)?.spec.display.name;
|
|
41
44
|
}, [
|
|
42
|
-
|
|
45
|
+
sortedData
|
|
43
46
|
]);
|
|
44
47
|
// TODO: Does this need a loading indicator of some kind?
|
|
45
48
|
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.TextField, {
|
|
@@ -58,7 +61,7 @@ const PluginKindSelect = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
|
|
|
58
61
|
value: "",
|
|
59
62
|
children: "Loading..."
|
|
60
63
|
}),
|
|
61
|
-
|
|
64
|
+
sortedData?.map((metadata)=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.MenuItem, {
|
|
62
65
|
"data-testid": "option",
|
|
63
66
|
value: selectionToOptionValue({
|
|
64
67
|
type: metadata.kind,
|
|
@@ -106,12 +106,7 @@ function ListVariableEditorForm({ action, control }) {
|
|
|
106
106
|
/** We use `previewSpec` to know when to explicitly update the
|
|
107
107
|
* spec that will be used for preview. The reason why we do this is to avoid
|
|
108
108
|
* having to re-fetch the values when the user is still editing the spec.
|
|
109
|
-
*/ const
|
|
110
|
-
const { refresh } = (0, _runtime.useTimeRange)();
|
|
111
|
-
const refreshPreview = ()=>{
|
|
112
|
-
refresh();
|
|
113
|
-
setPreviewSpec(form.getValues());
|
|
114
|
-
};
|
|
109
|
+
*/ const previewSpec = form.getValues();
|
|
115
110
|
const plugin = (0, _reacthookform.useWatch)({
|
|
116
111
|
control,
|
|
117
112
|
name: 'spec.plugin'
|
|
@@ -131,6 +126,7 @@ function ListVariableEditorForm({ action, control }) {
|
|
|
131
126
|
if (values.spec.allowMultiple === undefined) {
|
|
132
127
|
form.setValue('spec.allowMultiple', false);
|
|
133
128
|
}
|
|
129
|
+
const { refresh } = (0, _runtime.useTimeRange)();
|
|
134
130
|
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
|
|
135
131
|
children: [
|
|
136
132
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Typography, {
|
|
@@ -149,8 +145,7 @@ function ListVariableEditorForm({ action, control }) {
|
|
|
149
145
|
previewSpec
|
|
150
146
|
],
|
|
151
147
|
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_VariablePreview.VariableListPreview, {
|
|
152
|
-
definition: previewSpec
|
|
153
|
-
onRefresh: refreshPreview
|
|
148
|
+
definition: previewSpec
|
|
154
149
|
})
|
|
155
150
|
})
|
|
156
151
|
}) : /*#__PURE__*/ (0, _jsxruntime.jsx)(_VariablePreview.VariablePreview, {
|
|
@@ -164,6 +159,7 @@ function ListVariableEditorForm({ action, control }) {
|
|
|
164
159
|
name: "spec.plugin",
|
|
165
160
|
render: ({ field })=>{
|
|
166
161
|
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_PluginEditor.PluginEditor, {
|
|
162
|
+
postExecuteRunQuery: refresh,
|
|
167
163
|
withRunQueryButton: true,
|
|
168
164
|
width: "100%",
|
|
169
165
|
pluginTypes: [
|
|
@@ -175,9 +171,7 @@ function ListVariableEditorForm({ action, control }) {
|
|
|
175
171
|
type: 'Variable',
|
|
176
172
|
kind: kind ?? 'StaticListVariable'
|
|
177
173
|
},
|
|
178
|
-
spec: pluginSpec ?? {
|
|
179
|
-
values: []
|
|
180
|
-
}
|
|
174
|
+
spec: pluginSpec ?? {}
|
|
181
175
|
},
|
|
182
176
|
isReadonly: action === 'read',
|
|
183
177
|
onChange: (v)=>{
|
|
@@ -32,7 +32,6 @@ const _jsxruntime = require("react/jsx-runtime");
|
|
|
32
32
|
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
|
|
33
33
|
const _material = require("@mui/material");
|
|
34
34
|
const _components = require("@perses-dev/components");
|
|
35
|
-
const _Refresh = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/Refresh"));
|
|
36
35
|
const _ClipboardOutline = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/ClipboardOutline"));
|
|
37
36
|
const _constants = require("../../../constants");
|
|
38
37
|
const _variablemodel = require("../variable-model");
|
|
@@ -84,7 +83,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
84
83
|
}
|
|
85
84
|
const DEFAULT_MAX_PREVIEW_VALUES = 50;
|
|
86
85
|
function VariablePreview(props) {
|
|
87
|
-
const { values,
|
|
86
|
+
const { values, isLoading, error } = props;
|
|
88
87
|
const [maxValues, setMaxValues] = (0, _react.useState)(DEFAULT_MAX_PREVIEW_VALUES);
|
|
89
88
|
const { infoSnackbar } = (0, _components.useSnackbar)();
|
|
90
89
|
const showAll = ()=>{
|
|
@@ -106,14 +105,6 @@ function VariablePreview(props) {
|
|
|
106
105
|
variant: "h4",
|
|
107
106
|
children: "Preview Values"
|
|
108
107
|
}),
|
|
109
|
-
onRefresh && /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
|
|
110
|
-
description: _constants.TOOLTIP_TEXT.refreshVariableValues,
|
|
111
|
-
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
|
|
112
|
-
onClick: onRefresh,
|
|
113
|
-
size: "small",
|
|
114
|
-
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Refresh.default, {})
|
|
115
|
-
})
|
|
116
|
-
}),
|
|
117
108
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
|
|
118
109
|
description: _constants.TOOLTIP_TEXT.copyVariableValues,
|
|
119
110
|
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
|
|
@@ -172,18 +163,16 @@ function VariablePreview(props) {
|
|
|
172
163
|
});
|
|
173
164
|
}
|
|
174
165
|
function VariableListPreview(props) {
|
|
175
|
-
const {
|
|
166
|
+
const { definition } = props;
|
|
176
167
|
const { data, isFetching, error } = (0, _variablemodel.useListVariablePluginValues)(definition);
|
|
177
168
|
const errorMessage = error?.message;
|
|
178
169
|
const variablePreview = (0, _react.useMemo)(()=>/*#__PURE__*/ (0, _jsxruntime.jsx)(VariablePreview, {
|
|
179
170
|
values: data?.map((val)=>val.value) || [],
|
|
180
|
-
onRefresh: onRefresh,
|
|
181
171
|
isLoading: isFetching,
|
|
182
172
|
error: errorMessage
|
|
183
173
|
}), [
|
|
184
174
|
errorMessage,
|
|
185
175
|
isFetching,
|
|
186
|
-
onRefresh,
|
|
187
176
|
data
|
|
188
177
|
]);
|
|
189
178
|
return variablePreview;
|
package/dist/cjs/test/utils.js
CHANGED
|
@@ -22,7 +22,9 @@ Object.defineProperty(exports, "getTestContextWrapper", {
|
|
|
22
22
|
});
|
|
23
23
|
const _jsxruntime = require("react/jsx-runtime");
|
|
24
24
|
const _reactquery = require("@tanstack/react-query");
|
|
25
|
+
const _core = require("@perses-dev/core");
|
|
25
26
|
const _components = require("../components");
|
|
27
|
+
const _runtime = require("../runtime");
|
|
26
28
|
const _testplugins = require("./test-plugins");
|
|
27
29
|
function getTestContextWrapper(contextOptions) {
|
|
28
30
|
// Create a new QueryClient for each test to avoid caching issues
|
|
@@ -34,15 +36,22 @@ function getTestContextWrapper(contextOptions) {
|
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
});
|
|
39
|
+
const timeRange = {
|
|
40
|
+
start: new Date(Date.now() - Number(_core.DEFAULT_DASHBOARD_DURATION)),
|
|
41
|
+
end: new Date()
|
|
42
|
+
};
|
|
37
43
|
return function Wrapper({ children }) {
|
|
38
|
-
return /*#__PURE__*/ (0, _jsxruntime.jsx)(
|
|
39
|
-
|
|
40
|
-
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_runtime.TimeRangeProvider, {
|
|
45
|
+
timeRange: timeRange,
|
|
46
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reactquery.QueryClientProvider, {
|
|
47
|
+
client: queryClient,
|
|
48
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.PluginRegistry, {
|
|
49
|
+
pluginLoader: _testplugins.testPluginLoader,
|
|
50
|
+
defaultPluginKinds: contextOptions?.defaultPluginKinds ?? {
|
|
51
|
+
TimeSeriesQuery: 'PrometheusTimeSeriesQuery'
|
|
52
|
+
},
|
|
53
|
+
children: children
|
|
54
|
+
})
|
|
46
55
|
})
|
|
47
56
|
});
|
|
48
57
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatasourceSelect.d.ts","sourceRoot":"","sources":["../../src/components/DatasourceSelect.tsx"],"names":[],"mappings":"AAcA,OAAO,EAML,mBAAmB,EACnB,eAAe,EAGhB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAW,MAAM,OAAO,CAAC;AAC9C,OAAO,EAEL,yBAAyB,EACzB,4BAA4B,EAG5B,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAOpB,KAAK,eAAe,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;AAWzD,MAAM,MAAM,qBAAqB,CAAC,CAAC,GAAG,kBAAkB,IAAI,CAAC,GAAG,YAAY,CAAC;AAE7E,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,mBAAmB,GAAG,eAAe,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IACjH,KAAK,EAAE,qBAAqB,CAAC;IAC7B,QAAQ,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAChD,oBAAoB,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"DatasourceSelect.d.ts","sourceRoot":"","sources":["../../src/components/DatasourceSelect.tsx"],"names":[],"mappings":"AAcA,OAAO,EAML,mBAAmB,EACnB,eAAe,EAGhB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAW,MAAM,OAAO,CAAC;AAC9C,OAAO,EAEL,yBAAyB,EACzB,4BAA4B,EAG5B,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAOpB,KAAK,eAAe,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;AAWzD,MAAM,MAAM,qBAAqB,CAAC,CAAC,GAAG,kBAAkB,IAAI,CAAC,GAAG,YAAY,CAAC;AAE7E,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,mBAAmB,GAAG,eAAe,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IACjH,KAAK,EAAE,qBAAqB,CAAC;IAC7B,QAAQ,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAChD,oBAAoB,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,CAkH3E;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,YAAY,CAahH;AAKD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,4BAA4B,GAAG,YAAY,GAAG,MAAM,CAKnG;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,qBAAqB,CAehF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,qBAAqB,GAAG,SAAS,GAAG,KAAK,IAAI,YAAY,CAEpG;AAED,eAAO,MAAM,+BAA+B,UACnC,qBAAqB,GAAG,SAAS,aAC7B,gBAAgB,8BACC,yBAAyB,EAAE,GAAG,SAAS,KAClE,kBAAkB,GAAG,SA4BvB,CAAC;AAEF,eAAO,MAAM,kCAAkC,UACtC,qBAAqB,wBACN,MAAM,KAC3B,kBAQF,CAAC"}
|
|
@@ -27,7 +27,7 @@ const emptyDatasourceOption = {
|
|
|
27
27
|
* Displays a MUI input for selecting a Datasource of a particular kind. Note: The 'value' and `onChange` handler for
|
|
28
28
|
* the input deal with a `DatasourceSelector`.
|
|
29
29
|
*/ export function DatasourceSelect(props) {
|
|
30
|
-
const { datasourcePluginKind, value, project, onChange, ...others } = props;
|
|
30
|
+
const { datasourcePluginKind, value, project, readOnly, onChange, ...others } = props;
|
|
31
31
|
const { data, isLoading } = useListDatasourceSelectItems(datasourcePluginKind, project);
|
|
32
32
|
const variables = useVariableValues();
|
|
33
33
|
const defaultValue = useMemo(()=>{
|
|
@@ -98,6 +98,7 @@ const emptyDatasourceOption = {
|
|
|
98
98
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
99
99
|
const fakeActionEvent = ()=>{};
|
|
100
100
|
return /*#__PURE__*/ _jsx(Autocomplete, {
|
|
101
|
+
readOnly: readOnly,
|
|
101
102
|
options: options,
|
|
102
103
|
renderInput: (params)=>/*#__PURE__*/ _jsx(TextField, {
|
|
103
104
|
...params,
|