@perses-dev/plugin-system 0.51.1 → 0.52.0-beta.1
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/PluginEditor/PluginEditor.js +41 -15
- package/dist/cjs/model/index.js +1 -0
- package/dist/cjs/model/profile-queries.js +16 -0
- package/dist/cjs/runtime/DataQueriesProvider/DataQueriesProvider.js +10 -2
- package/dist/cjs/runtime/DataQueriesProvider/model.js +17 -4
- package/dist/cjs/runtime/RouterProvider.js +113 -0
- package/dist/cjs/runtime/index.js +2 -0
- package/dist/cjs/runtime/profile-queries.js +65 -0
- package/dist/cjs/test/mock-data.js +23 -0
- package/dist/components/PluginEditor/PluginEditor.d.ts.map +1 -1
- package/dist/components/PluginEditor/PluginEditor.js +37 -16
- package/dist/components/PluginEditor/PluginEditor.js.map +1 -1
- package/dist/components/PluginKindSelect/PluginKindSelect.d.ts +1 -1
- package/dist/components/PluginKindSelect/PluginKindSelect.js +1 -1
- package/dist/components/PluginKindSelect/PluginKindSelect.js.map +1 -1
- package/dist/model/index.d.ts +1 -0
- package/dist/model/index.d.ts.map +1 -1
- package/dist/model/index.js +1 -0
- package/dist/model/index.js.map +1 -1
- package/dist/model/panels.d.ts +8 -0
- package/dist/model/panels.d.ts.map +1 -1
- package/dist/model/panels.js.map +1 -1
- package/dist/model/plugins.d.ts +2 -0
- package/dist/model/plugins.d.ts.map +1 -1
- package/dist/model/plugins.js.map +1 -1
- package/dist/model/profile-queries.d.ts +19 -0
- package/dist/model/profile-queries.d.ts.map +1 -0
- package/dist/model/profile-queries.js +15 -0
- package/dist/model/profile-queries.js.map +1 -0
- package/dist/runtime/DataQueriesProvider/DataQueriesProvider.d.ts.map +1 -1
- package/dist/runtime/DataQueriesProvider/DataQueriesProvider.js +10 -2
- package/dist/runtime/DataQueriesProvider/DataQueriesProvider.js.map +1 -1
- package/dist/runtime/DataQueriesProvider/model.d.ts.map +1 -1
- package/dist/runtime/DataQueriesProvider/model.js +17 -4
- package/dist/runtime/DataQueriesProvider/model.js.map +1 -1
- package/dist/runtime/RouterProvider.d.ts +32 -0
- package/dist/runtime/RouterProvider.d.ts.map +1 -0
- package/dist/runtime/RouterProvider.js +58 -0
- package/dist/runtime/RouterProvider.js.map +1 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +2 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/profile-queries.d.ts +10 -0
- package/dist/runtime/profile-queries.d.ts.map +1 -0
- package/dist/runtime/profile-queries.js +52 -0
- package/dist/runtime/profile-queries.js.map +1 -0
- package/dist/test/mock-data.d.ts +2 -1
- package/dist/test/mock-data.d.ts.map +1 -1
- package/dist/test/mock-data.js +20 -0
- package/dist/test/mock-data.js.map +1 -1
- package/package.json +3 -3
|
@@ -22,10 +22,16 @@ Object.defineProperty(exports, "PluginEditor", {
|
|
|
22
22
|
});
|
|
23
23
|
const _jsxruntime = require("react/jsx-runtime");
|
|
24
24
|
const _material = require("@mui/material");
|
|
25
|
+
const _Reload = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/Reload"));
|
|
25
26
|
const _components = require("@perses-dev/components");
|
|
26
27
|
const _PluginKindSelect = require("../PluginKindSelect");
|
|
27
28
|
const _PluginSpecEditor = require("../PluginSpecEditor");
|
|
28
29
|
const _plugineditorapi = require("./plugin-editor-api");
|
|
30
|
+
function _interop_require_default(obj) {
|
|
31
|
+
return obj && obj.__esModule ? obj : {
|
|
32
|
+
default: obj
|
|
33
|
+
};
|
|
34
|
+
}
|
|
29
35
|
function PluginEditor(props) {
|
|
30
36
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
31
37
|
const { value, pluginTypes, pluginKindLabel, onChange: _, isReadonly, ...others } = props;
|
|
@@ -33,23 +39,43 @@ function PluginEditor(props) {
|
|
|
33
39
|
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Box, {
|
|
34
40
|
...others,
|
|
35
41
|
children: [
|
|
36
|
-
/*#__PURE__*/ (0, _jsxruntime.
|
|
37
|
-
fullWidth: false,
|
|
42
|
+
/*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Box, {
|
|
38
43
|
sx: {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
},
|
|
42
|
-
margin: "dense",
|
|
43
|
-
label: pluginKindLabel,
|
|
44
|
-
pluginTypes: pluginTypes,
|
|
45
|
-
disabled: isLoading,
|
|
46
|
-
value: pendingSelection ? pendingSelection : value.selection,
|
|
47
|
-
InputProps: {
|
|
48
|
-
readOnly: isReadonly
|
|
44
|
+
display: 'flex',
|
|
45
|
+
flexDirection: 'row'
|
|
49
46
|
},
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
children: [
|
|
48
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_PluginKindSelect.PluginKindSelect, {
|
|
49
|
+
fullWidth: false,
|
|
50
|
+
sx: {
|
|
51
|
+
mb: 2,
|
|
52
|
+
minWidth: 120
|
|
53
|
+
},
|
|
54
|
+
margin: "dense",
|
|
55
|
+
label: pluginKindLabel,
|
|
56
|
+
pluginTypes: pluginTypes,
|
|
57
|
+
disabled: isLoading,
|
|
58
|
+
value: pendingSelection ? pendingSelection : value.selection,
|
|
59
|
+
InputProps: {
|
|
60
|
+
readOnly: isReadonly
|
|
61
|
+
},
|
|
62
|
+
error: !!error,
|
|
63
|
+
helperText: error?.message,
|
|
64
|
+
onChange: onSelectionChange
|
|
65
|
+
}),
|
|
66
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Button, {
|
|
67
|
+
variant: "contained",
|
|
68
|
+
sx: {
|
|
69
|
+
marginTop: 1.5,
|
|
70
|
+
marginBottom: 1.5,
|
|
71
|
+
paddingTop: 0.5,
|
|
72
|
+
marginLeft: 'auto'
|
|
73
|
+
},
|
|
74
|
+
startIcon: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Reload.default, {}),
|
|
75
|
+
onClick: ()=>onSpecChange(value.spec),
|
|
76
|
+
children: "Run Query"
|
|
77
|
+
})
|
|
78
|
+
]
|
|
53
79
|
}),
|
|
54
80
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(_components.ErrorBoundary, {
|
|
55
81
|
FallbackComponent: _components.ErrorAlert,
|
package/dist/cjs/model/index.js
CHANGED
|
@@ -22,6 +22,7 @@ _export_star(require("./plugin-base"), exports);
|
|
|
22
22
|
_export_star(require("./plugin-loading"), exports);
|
|
23
23
|
_export_star(require("./time-series-queries"), exports);
|
|
24
24
|
_export_star(require("./trace-queries"), exports);
|
|
25
|
+
_export_star(require("./profile-queries"), exports);
|
|
25
26
|
_export_star(require("./variables"), exports);
|
|
26
27
|
function _export_star(from, to) {
|
|
27
28
|
Object.keys(from).forEach(function(k) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Copyright 2025 The Perses Authors
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
"use strict";
|
|
14
|
+
Object.defineProperty(exports, "__esModule", {
|
|
15
|
+
value: true
|
|
16
|
+
});
|
|
@@ -38,6 +38,7 @@ const _jsxruntime = require("react/jsx-runtime");
|
|
|
38
38
|
const _react = require("react");
|
|
39
39
|
const _timeseriesqueries = require("../time-series-queries");
|
|
40
40
|
const _tracequeries = require("../trace-queries");
|
|
41
|
+
const _profilequeries = require("../profile-queries");
|
|
41
42
|
const _UsageMetricsProvider = require("../UsageMetricsProvider");
|
|
42
43
|
const _model = require("./model");
|
|
43
44
|
const DataQueriesContext = /*#__PURE__*/ (0, _react.createContext)(undefined);
|
|
@@ -83,17 +84,22 @@ function DataQueriesProvider(props) {
|
|
|
83
84
|
const timeSeriesResults = (0, _timeseriesqueries.useTimeSeriesQueries)(timeSeriesQueries, options, queryOptions);
|
|
84
85
|
const traceQueries = queryDefinitions.filter((definition)=>definition.kind === 'TraceQuery');
|
|
85
86
|
const traceResults = (0, _tracequeries.useTraceQueries)(traceQueries);
|
|
87
|
+
const profileQueries = queryDefinitions.filter((definition)=>definition.kind === 'ProfileQuery');
|
|
88
|
+
const profileResults = (0, _profilequeries.useProfileQueries)(profileQueries);
|
|
86
89
|
const refetchAll = (0, _react.useCallback)(()=>{
|
|
87
90
|
timeSeriesResults.forEach((result)=>result.refetch());
|
|
88
91
|
traceResults.forEach((result)=>result.refetch());
|
|
92
|
+
profileResults.forEach((result)=>result.refetch());
|
|
89
93
|
}, [
|
|
90
94
|
timeSeriesResults,
|
|
91
|
-
traceResults
|
|
95
|
+
traceResults,
|
|
96
|
+
profileResults
|
|
92
97
|
]);
|
|
93
98
|
const ctx = (0, _react.useMemo)(()=>{
|
|
94
99
|
const mergedQueryResults = [
|
|
95
100
|
...(0, _model.transformQueryResults)(timeSeriesResults, timeSeriesQueries),
|
|
96
|
-
...(0, _model.transformQueryResults)(traceResults, traceQueries)
|
|
101
|
+
...(0, _model.transformQueryResults)(traceResults, traceQueries),
|
|
102
|
+
...(0, _model.transformQueryResults)(profileResults, profileQueries)
|
|
97
103
|
];
|
|
98
104
|
if (queryOptions?.enabled) {
|
|
99
105
|
for (const result of mergedQueryResults){
|
|
@@ -118,6 +124,8 @@ function DataQueriesProvider(props) {
|
|
|
118
124
|
timeSeriesResults,
|
|
119
125
|
traceQueries,
|
|
120
126
|
traceResults,
|
|
127
|
+
profileQueries,
|
|
128
|
+
profileResults,
|
|
121
129
|
refetchAll,
|
|
122
130
|
queryOptions?.enabled,
|
|
123
131
|
usageMetrics
|
|
@@ -49,11 +49,15 @@ function useQueryType() {
|
|
|
49
49
|
const { data: traceQueryPlugins, isLoading: isTraceQueryPluginLoading } = (0, _pluginregistry.useListPluginMetadata)([
|
|
50
50
|
'TraceQuery'
|
|
51
51
|
]);
|
|
52
|
+
const { data: profileQueryPlugins, isLoading: isProfileQueryPluginLoading } = (0, _pluginregistry.useListPluginMetadata)([
|
|
53
|
+
'ProfileQuery'
|
|
54
|
+
]);
|
|
52
55
|
// For example, `map: {"TimeSeriesQuery":["PrometheusTimeSeriesQuery"],"TraceQuery":["TempoTraceQuery"]}`
|
|
53
56
|
const queryTypeMap = (0, _react.useMemo)(()=>{
|
|
54
57
|
const map = {
|
|
55
58
|
TimeSeriesQuery: [],
|
|
56
|
-
TraceQuery: []
|
|
59
|
+
TraceQuery: [],
|
|
60
|
+
ProfileQuery: []
|
|
57
61
|
};
|
|
58
62
|
if (timeSeriesQueryPlugins) {
|
|
59
63
|
timeSeriesQueryPlugins.forEach((plugin)=>{
|
|
@@ -65,10 +69,16 @@ function useQueryType() {
|
|
|
65
69
|
map[plugin.kind]?.push(plugin.spec.name);
|
|
66
70
|
});
|
|
67
71
|
}
|
|
72
|
+
if (profileQueryPlugins) {
|
|
73
|
+
profileQueryPlugins.forEach((plugin)=>{
|
|
74
|
+
map[plugin.kind]?.push(plugin.spec.name);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
68
77
|
return map;
|
|
69
78
|
}, [
|
|
70
79
|
timeSeriesQueryPlugins,
|
|
71
|
-
traceQueryPlugins
|
|
80
|
+
traceQueryPlugins,
|
|
81
|
+
profileQueryPlugins
|
|
72
82
|
]);
|
|
73
83
|
const getQueryType = (0, _react.useCallback)((pluginKind)=>{
|
|
74
84
|
const isLoading = (pluginKind)=>{
|
|
@@ -77,8 +87,10 @@ function useQueryType() {
|
|
|
77
87
|
return isTimeSeriesQueryLoading;
|
|
78
88
|
case 'TempoTraceQuery':
|
|
79
89
|
return isTraceQueryPluginLoading;
|
|
90
|
+
case 'PyroscopeProfileQuery':
|
|
91
|
+
return isProfileQueryPluginLoading;
|
|
80
92
|
}
|
|
81
|
-
return isTraceQueryPluginLoading || isTimeSeriesQueryLoading;
|
|
93
|
+
return isTraceQueryPluginLoading || isTimeSeriesQueryLoading || isProfileQueryPluginLoading;
|
|
82
94
|
};
|
|
83
95
|
if (isLoading(pluginKind)) {
|
|
84
96
|
return undefined;
|
|
@@ -92,7 +104,8 @@ function useQueryType() {
|
|
|
92
104
|
}, [
|
|
93
105
|
queryTypeMap,
|
|
94
106
|
isTimeSeriesQueryLoading,
|
|
95
|
-
isTraceQueryPluginLoading
|
|
107
|
+
isTraceQueryPluginLoading,
|
|
108
|
+
isProfileQueryPluginLoading
|
|
96
109
|
]);
|
|
97
110
|
return getQueryType;
|
|
98
111
|
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// Copyright 2025 The Perses Authors
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
"use strict";
|
|
14
|
+
Object.defineProperty(exports, "__esModule", {
|
|
15
|
+
value: true
|
|
16
|
+
});
|
|
17
|
+
function _export(target, all) {
|
|
18
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: all[name]
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
_export(exports, {
|
|
24
|
+
ReactRouterProvider: function() {
|
|
25
|
+
return ReactRouterProvider;
|
|
26
|
+
},
|
|
27
|
+
RouterContext: function() {
|
|
28
|
+
return RouterContext;
|
|
29
|
+
},
|
|
30
|
+
RouterProvider: function() {
|
|
31
|
+
return RouterProvider;
|
|
32
|
+
},
|
|
33
|
+
useRouterContext: function() {
|
|
34
|
+
return useRouterContext;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
const _jsxruntime = require("react/jsx-runtime");
|
|
38
|
+
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
|
|
39
|
+
const _reactrouterdom = require("react-router-dom");
|
|
40
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
41
|
+
if (typeof WeakMap !== "function") return null;
|
|
42
|
+
var cacheBabelInterop = new WeakMap();
|
|
43
|
+
var cacheNodeInterop = new WeakMap();
|
|
44
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
45
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
46
|
+
})(nodeInterop);
|
|
47
|
+
}
|
|
48
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
49
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
50
|
+
return obj;
|
|
51
|
+
}
|
|
52
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
53
|
+
return {
|
|
54
|
+
default: obj
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
58
|
+
if (cache && cache.has(obj)) {
|
|
59
|
+
return cache.get(obj);
|
|
60
|
+
}
|
|
61
|
+
var newObj = {
|
|
62
|
+
__proto__: null
|
|
63
|
+
};
|
|
64
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
65
|
+
for(var key in obj){
|
|
66
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
67
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
68
|
+
if (desc && (desc.get || desc.set)) {
|
|
69
|
+
Object.defineProperty(newObj, key, desc);
|
|
70
|
+
} else {
|
|
71
|
+
newObj[key] = obj[key];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
newObj.default = obj;
|
|
76
|
+
if (cache) {
|
|
77
|
+
cache.set(obj, newObj);
|
|
78
|
+
}
|
|
79
|
+
return newObj;
|
|
80
|
+
}
|
|
81
|
+
const RouterContext = /*#__PURE__*/ (0, _react.createContext)(undefined);
|
|
82
|
+
function useRouterContext() {
|
|
83
|
+
const ctx = (0, _react.useContext)(RouterContext);
|
|
84
|
+
if (ctx === undefined) {
|
|
85
|
+
throw new Error('No RouterContext found. Did you forget a <RouterProvider>?');
|
|
86
|
+
}
|
|
87
|
+
return ctx;
|
|
88
|
+
}
|
|
89
|
+
function RouterProvider(props) {
|
|
90
|
+
const { RouterComponent, navigate, children } = props;
|
|
91
|
+
const ctx = (0, _react.useMemo)(()=>{
|
|
92
|
+
return {
|
|
93
|
+
RouterComponent,
|
|
94
|
+
navigate
|
|
95
|
+
};
|
|
96
|
+
}, [
|
|
97
|
+
RouterComponent,
|
|
98
|
+
navigate
|
|
99
|
+
]);
|
|
100
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsx)(RouterContext.Provider, {
|
|
101
|
+
value: ctx,
|
|
102
|
+
children: children
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function ReactRouterProvider(props) {
|
|
106
|
+
const { children } = props;
|
|
107
|
+
const navigate = (0, _reactrouterdom.useNavigate)();
|
|
108
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsx)(RouterProvider, {
|
|
109
|
+
RouterComponent: _reactrouterdom.Link,
|
|
110
|
+
navigate: navigate,
|
|
111
|
+
children: children
|
|
112
|
+
});
|
|
113
|
+
}
|
|
@@ -21,8 +21,10 @@ _export_star(require("./variables"), exports);
|
|
|
21
21
|
_export_star(require("./TimeRangeProvider"), exports);
|
|
22
22
|
_export_star(require("./time-series-queries"), exports);
|
|
23
23
|
_export_star(require("./trace-queries"), exports);
|
|
24
|
+
_export_star(require("./profile-queries"), exports);
|
|
24
25
|
_export_star(require("./DataQueriesProvider"), exports);
|
|
25
26
|
_export_star(require("./QueryCountProvider"), exports);
|
|
27
|
+
_export_star(require("./RouterProvider"), exports);
|
|
26
28
|
_export_star(require("./UsageMetricsProvider"), exports);
|
|
27
29
|
function _export_star(from, to) {
|
|
28
30
|
Object.keys(from).forEach(function(k) {
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Copyright 2025 The Perses Authors
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
"use strict";
|
|
14
|
+
Object.defineProperty(exports, "__esModule", {
|
|
15
|
+
value: true
|
|
16
|
+
});
|
|
17
|
+
function _export(target, all) {
|
|
18
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: all[name]
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
_export(exports, {
|
|
24
|
+
PROFILE_QUERY_KEY: function() {
|
|
25
|
+
return PROFILE_QUERY_KEY;
|
|
26
|
+
},
|
|
27
|
+
useProfileQueries: function() {
|
|
28
|
+
return useProfileQueries;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
const _reactquery = require("@tanstack/react-query");
|
|
32
|
+
const _datasources = require("./datasources");
|
|
33
|
+
const _pluginregistry = require("./plugin-registry");
|
|
34
|
+
const _TimeRangeProvider = require("./TimeRangeProvider");
|
|
35
|
+
const PROFILE_QUERY_KEY = 'ProfileQuery';
|
|
36
|
+
function useProfileQueries(definitions) {
|
|
37
|
+
const { getPlugin } = (0, _pluginregistry.usePluginRegistry)();
|
|
38
|
+
const datasourceStore = (0, _datasources.useDatasourceStore)();
|
|
39
|
+
const { absoluteTimeRange } = (0, _TimeRangeProvider.useTimeRange)();
|
|
40
|
+
const context = {
|
|
41
|
+
datasourceStore,
|
|
42
|
+
absoluteTimeRange
|
|
43
|
+
};
|
|
44
|
+
// useQueries() handles data fetching from query plugins (e.g. traceQL queries, promQL queries)
|
|
45
|
+
// https://tanstack.com/query/v4/docs/react/reference/useQuery
|
|
46
|
+
return (0, _reactquery.useQueries)({
|
|
47
|
+
queries: definitions.map((definition)=>{
|
|
48
|
+
const queryKey = [
|
|
49
|
+
definition,
|
|
50
|
+
datasourceStore,
|
|
51
|
+
absoluteTimeRange
|
|
52
|
+
]; // `queryKey` watches and reruns `queryFn` if keys in the array change
|
|
53
|
+
const profileQueryKind = definition?.spec?.plugin?.kind;
|
|
54
|
+
return {
|
|
55
|
+
queryKey: queryKey,
|
|
56
|
+
queryFn: async ()=>{
|
|
57
|
+
const plugin = await getPlugin(PROFILE_QUERY_KEY, profileQueryKind);
|
|
58
|
+
const data = await plugin.getProfileData(definition.spec.plugin.spec, context);
|
|
59
|
+
return data;
|
|
60
|
+
},
|
|
61
|
+
structuralSharing: false
|
|
62
|
+
};
|
|
63
|
+
})
|
|
64
|
+
});
|
|
65
|
+
}
|
|
@@ -21,6 +21,9 @@ function _export(target, all) {
|
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
23
|
_export(exports, {
|
|
24
|
+
MOCK_PROFILE_DATA: function() {
|
|
25
|
+
return MOCK_PROFILE_DATA;
|
|
26
|
+
},
|
|
24
27
|
MOCK_TIME_SERIES_DATA: function() {
|
|
25
28
|
return MOCK_TIME_SERIES_DATA;
|
|
26
29
|
},
|
|
@@ -99,3 +102,23 @@ const MOCK_TRACE_DATA = {
|
|
|
99
102
|
executedQueryString: '{ duration > 1000ms }'
|
|
100
103
|
}
|
|
101
104
|
};
|
|
105
|
+
const MOCK_PROFILE_DATA = {
|
|
106
|
+
profile: {
|
|
107
|
+
stackTrace: {
|
|
108
|
+
id: 0,
|
|
109
|
+
name: 'root',
|
|
110
|
+
level: 0,
|
|
111
|
+
start: 1699916103945861,
|
|
112
|
+
end: 1699916105065861,
|
|
113
|
+
total: 1000,
|
|
114
|
+
self: 500,
|
|
115
|
+
children: []
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
metadata: {
|
|
119
|
+
spyName: '',
|
|
120
|
+
sampleRate: 1000000000,
|
|
121
|
+
units: 'samples',
|
|
122
|
+
name: 'cpu'
|
|
123
|
+
}
|
|
124
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginEditor.d.ts","sourceRoot":"","sources":["../../../src/components/PluginEditor/PluginEditor.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PluginEditor.d.ts","sourceRoot":"","sources":["../../../src/components/PluginEditor/PluginEditor.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAGrC,OAAO,EAAE,iBAAiB,EAAmB,MAAM,qBAAqB,CAAC;AAEzE;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAyCnE"}
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
-
import { Box } from '@mui/material';
|
|
14
|
+
import { Box, Button } from '@mui/material';
|
|
15
|
+
import Reload from 'mdi-material-ui/Reload';
|
|
15
16
|
import { ErrorAlert, ErrorBoundary } from '@perses-dev/components';
|
|
16
17
|
import { PluginKindSelect } from '../PluginKindSelect';
|
|
17
18
|
import { PluginSpecEditor } from '../PluginSpecEditor';
|
|
@@ -30,23 +31,43 @@ import { usePluginEditor } from './plugin-editor-api';
|
|
|
30
31
|
return /*#__PURE__*/ _jsxs(Box, {
|
|
31
32
|
...others,
|
|
32
33
|
children: [
|
|
33
|
-
/*#__PURE__*/
|
|
34
|
-
fullWidth: false,
|
|
34
|
+
/*#__PURE__*/ _jsxs(Box, {
|
|
35
35
|
sx: {
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
display: 'flex',
|
|
37
|
+
flexDirection: 'row'
|
|
38
38
|
},
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
children: [
|
|
40
|
+
/*#__PURE__*/ _jsx(PluginKindSelect, {
|
|
41
|
+
fullWidth: false,
|
|
42
|
+
sx: {
|
|
43
|
+
mb: 2,
|
|
44
|
+
minWidth: 120
|
|
45
|
+
},
|
|
46
|
+
margin: "dense",
|
|
47
|
+
label: pluginKindLabel,
|
|
48
|
+
pluginTypes: pluginTypes,
|
|
49
|
+
disabled: isLoading,
|
|
50
|
+
value: pendingSelection ? pendingSelection : value.selection,
|
|
51
|
+
InputProps: {
|
|
52
|
+
readOnly: isReadonly
|
|
53
|
+
},
|
|
54
|
+
error: !!error,
|
|
55
|
+
helperText: error?.message,
|
|
56
|
+
onChange: onSelectionChange
|
|
57
|
+
}),
|
|
58
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
59
|
+
variant: "contained",
|
|
60
|
+
sx: {
|
|
61
|
+
marginTop: 1.5,
|
|
62
|
+
marginBottom: 1.5,
|
|
63
|
+
paddingTop: 0.5,
|
|
64
|
+
marginLeft: 'auto'
|
|
65
|
+
},
|
|
66
|
+
startIcon: /*#__PURE__*/ _jsx(Reload, {}),
|
|
67
|
+
onClick: ()=>onSpecChange(value.spec),
|
|
68
|
+
children: "Run Query"
|
|
69
|
+
})
|
|
70
|
+
]
|
|
50
71
|
}),
|
|
51
72
|
/*#__PURE__*/ _jsx(ErrorBoundary, {
|
|
52
73
|
FallbackComponent: ErrorAlert,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/PluginEditor/PluginEditor.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box } from '@mui/material';\nimport { ErrorAlert, ErrorBoundary } from '@perses-dev/components';\nimport { ReactElement } from 'react';\nimport { PluginKindSelect } from '../PluginKindSelect';\nimport { PluginSpecEditor } from '../PluginSpecEditor';\nimport { PluginEditorProps, usePluginEditor } from './plugin-editor-api';\n\n/**\n * A combination `PluginKindSelect` and `PluginSpecEditor` component. This is meant for editing the `plugin` property\n * that's common in our JSON specs where a user selects a plugin `kind` and then edits the `spec` via that plugin's\n * editor component. It takes care of transitioning from one plugin kind to another \"all at once\" so that when the\n * plugin's kind changes, the spec is also changed at the same time so those options editor components don't see a\n * previous plugin's spec state. If you just want this behavior, but in a different UI layout from this, try the\n * `usePluginEditor` hook that powers this component.\n */\nexport function PluginEditor(props: PluginEditorProps): ReactElement {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { value, pluginTypes, pluginKindLabel, onChange: _, isReadonly, ...others } = props;\n const { pendingSelection, isLoading, error, onSelectionChange, onSpecChange } = usePluginEditor(props);\n return (\n <Box {...others}>\n <PluginKindSelect\n
|
|
1
|
+
{"version":3,"sources":["../../../src/components/PluginEditor/PluginEditor.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, Button } from '@mui/material';\nimport Reload from 'mdi-material-ui/Reload';\nimport { ErrorAlert, ErrorBoundary } from '@perses-dev/components';\nimport { ReactElement } from 'react';\nimport { PluginKindSelect } from '../PluginKindSelect';\nimport { PluginSpecEditor } from '../PluginSpecEditor';\nimport { PluginEditorProps, usePluginEditor } from './plugin-editor-api';\n\n/**\n * A combination `PluginKindSelect` and `PluginSpecEditor` component. This is meant for editing the `plugin` property\n * that's common in our JSON specs where a user selects a plugin `kind` and then edits the `spec` via that plugin's\n * editor component. It takes care of transitioning from one plugin kind to another \"all at once\" so that when the\n * plugin's kind changes, the spec is also changed at the same time so those options editor components don't see a\n * previous plugin's spec state. If you just want this behavior, but in a different UI layout from this, try the\n * `usePluginEditor` hook that powers this component.\n */\nexport function PluginEditor(props: PluginEditorProps): ReactElement {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { value, pluginTypes, pluginKindLabel, onChange: _, isReadonly, ...others } = props;\n const { pendingSelection, isLoading, error, onSelectionChange, onSpecChange } = usePluginEditor(props);\n return (\n <Box {...others}>\n <Box sx={{ display: 'flex', flexDirection: 'row' }}>\n <PluginKindSelect\n fullWidth={false}\n sx={{ mb: 2, minWidth: 120 }}\n margin=\"dense\"\n label={pluginKindLabel}\n pluginTypes={pluginTypes}\n disabled={isLoading}\n value={pendingSelection ? pendingSelection : value.selection}\n InputProps={{ readOnly: isReadonly }}\n error={!!error}\n helperText={error?.message}\n onChange={onSelectionChange}\n />\n\n <Button\n variant=\"contained\"\n sx={{ marginTop: 1.5, marginBottom: 1.5, paddingTop: 0.5, marginLeft: 'auto' }}\n startIcon={<Reload />}\n onClick={() => onSpecChange(value.spec)}\n >\n Run Query\n </Button>\n </Box>\n\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <PluginSpecEditor\n pluginSelection={value.selection}\n value={value.spec}\n onChange={onSpecChange}\n isReadonly={isReadonly}\n />\n </ErrorBoundary>\n </Box>\n );\n}\n"],"names":["Box","Button","Reload","ErrorAlert","ErrorBoundary","PluginKindSelect","PluginSpecEditor","usePluginEditor","PluginEditor","props","value","pluginTypes","pluginKindLabel","onChange","_","isReadonly","others","pendingSelection","isLoading","error","onSelectionChange","onSpecChange","sx","display","flexDirection","fullWidth","mb","minWidth","margin","label","disabled","selection","InputProps","readOnly","helperText","message","variant","marginTop","marginBottom","paddingTop","marginLeft","startIcon","onClick","spec","FallbackComponent","pluginSelection"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,GAAG,EAAEC,MAAM,QAAQ,gBAAgB;AAC5C,OAAOC,YAAY,yBAAyB;AAC5C,SAASC,UAAU,EAAEC,aAAa,QAAQ,yBAAyB;AAEnE,SAASC,gBAAgB,QAAQ,sBAAsB;AACvD,SAASC,gBAAgB,QAAQ,sBAAsB;AACvD,SAA4BC,eAAe,QAAQ,sBAAsB;AAEzE;;;;;;;CAOC,GACD,OAAO,SAASC,aAAaC,KAAwB;IACnD,6DAA6D;IAC7D,MAAM,EAAEC,KAAK,EAAEC,WAAW,EAAEC,eAAe,EAAEC,UAAUC,CAAC,EAAEC,UAAU,EAAE,GAAGC,QAAQ,GAAGP;IACpF,MAAM,EAAEQ,gBAAgB,EAAEC,SAAS,EAAEC,KAAK,EAAEC,iBAAiB,EAAEC,YAAY,EAAE,GAAGd,gBAAgBE;IAChG,qBACE,MAACT;QAAK,GAAGgB,MAAM;;0BACb,MAAChB;gBAAIsB,IAAI;oBAAEC,SAAS;oBAAQC,eAAe;gBAAM;;kCAC/C,KAACnB;wBACCoB,WAAW;wBACXH,IAAI;4BAAEI,IAAI;4BAAGC,UAAU;wBAAI;wBAC3BC,QAAO;wBACPC,OAAOjB;wBACPD,aAAaA;wBACbmB,UAAUZ;wBACVR,OAAOO,mBAAmBA,mBAAmBP,MAAMqB,SAAS;wBAC5DC,YAAY;4BAAEC,UAAUlB;wBAAW;wBACnCI,OAAO,CAAC,CAACA;wBACTe,YAAYf,OAAOgB;wBACnBtB,UAAUO;;kCAGZ,KAACnB;wBACCmC,SAAQ;wBACRd,IAAI;4BAAEe,WAAW;4BAAKC,cAAc;4BAAKC,YAAY;4BAAKC,YAAY;wBAAO;wBAC7EC,yBAAW,KAACvC;wBACZwC,SAAS,IAAMrB,aAAaX,MAAMiC,IAAI;kCACvC;;;;0BAKH,KAACvC;gBAAcwC,mBAAmBzC;0BAChC,cAAA,KAACG;oBACCuC,iBAAiBnC,MAAMqB,SAAS;oBAChCrB,OAAOA,MAAMiC,IAAI;oBACjB9B,UAAUQ;oBACVN,YAAYA;;;;;AAKtB"}
|
|
@@ -10,7 +10,7 @@ export interface PluginKindSelectProps extends Omit<TextFieldProps, 'value' | 'o
|
|
|
10
10
|
/**
|
|
11
11
|
* Displays a MUI Select input for selecting a plugin's kind from a list of all the available plugins of some specific
|
|
12
12
|
* plugin types. (e.g. "Show a list of all the Panel plugins", or "Show a list of all the Variable plugins", or "Show
|
|
13
|
-
* a list of all the TimeSeriesQuery, TraceQuery, and LogQuery plugins").
|
|
13
|
+
* a list of all the TimeSeriesQuery, TraceQuery, ProfileQuery, and LogQuery plugins").
|
|
14
14
|
* The value of the select is the kind of the plugin, but you can also listen to the `onPluginTypeChange` event to know
|
|
15
15
|
* when the user changes the plugin type (it fires at start for the default value.)
|
|
16
16
|
*/
|
|
@@ -17,7 +17,7 @@ import { useListPluginMetadata } from '../../runtime';
|
|
|
17
17
|
/**
|
|
18
18
|
* Displays a MUI Select input for selecting a plugin's kind from a list of all the available plugins of some specific
|
|
19
19
|
* plugin types. (e.g. "Show a list of all the Panel plugins", or "Show a list of all the Variable plugins", or "Show
|
|
20
|
-
* a list of all the TimeSeriesQuery, TraceQuery, and LogQuery plugins").
|
|
20
|
+
* a list of all the TimeSeriesQuery, TraceQuery, ProfileQuery, and LogQuery plugins").
|
|
21
21
|
* The value of the select is the kind of the plugin, but you can also listen to the `onPluginTypeChange` event to know
|
|
22
22
|
* when the user changes the plugin type (it fires at start for the default value.)
|
|
23
23
|
*/ export const PluginKindSelect = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/PluginKindSelect/PluginKindSelect.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { MenuItem, TextField, TextFieldProps } from '@mui/material';\nimport { forwardRef, ReactElement, useCallback } from 'react';\nimport { PluginType } from '../../model';\nimport { useListPluginMetadata } from '../../runtime';\nimport { PluginEditorSelection } from '../PluginEditor';\n\nexport interface PluginKindSelectProps extends Omit<TextFieldProps, 'value' | 'onChange' | 'children'> {\n pluginTypes: PluginType[];\n value?: PluginEditorSelection;\n onChange?: (s: PluginEditorSelection) => void;\n}\n\n/**\n * Displays a MUI Select input for selecting a plugin's kind from a list of all the available plugins of some specific\n * plugin types. (e.g. \"Show a list of all the Panel plugins\", or \"Show a list of all the Variable plugins\", or \"Show\n * a list of all the TimeSeriesQuery, TraceQuery, and LogQuery plugins\").\n * The value of the select is the kind of the plugin, but you can also listen to the `onPluginTypeChange` event to know\n * when the user changes the plugin type (it fires at start for the default value.)\n */\nexport const PluginKindSelect = forwardRef((props: PluginKindSelectProps, ref): ReactElement => {\n const { pluginTypes, value: propValue, onChange, ...others } = props;\n const { data, isLoading } = useListPluginMetadata(pluginTypes);\n\n // Pass an empty value while options are still loading so MUI doesn't complain about us using an \"out of range\" value\n const value = !propValue || isLoading ? '' : selectionToOptionValue(propValue);\n\n const handleChange = (event: { target: { value: string } }): void => {\n onChange?.(optionValueToSelection(event.target.value));\n };\n\n const renderValue = useCallback(\n (selected: unknown) => {\n if (selected === '') {\n return '';\n }\n const selectedValue = optionValueToSelection(selected as string);\n return data?.find((v) => v.kind === selectedValue.type && v.spec.name === selectedValue.kind)?.spec.display.name;\n },\n [data]\n );\n\n // TODO: Does this need a loading indicator of some kind?\n return (\n <TextField\n select\n inputRef={ref}\n {...others}\n value={value}\n aria-label={value}\n onChange={handleChange}\n SelectProps={{ renderValue }}\n data-testid=\"plugin-kind-select\"\n >\n {isLoading && <MenuItem value=\"\">Loading...</MenuItem>}\n {data?.map((metadata) => (\n <MenuItem\n data-testid=\"option\"\n key={metadata.kind + metadata.spec.name}\n value={selectionToOptionValue({ type: metadata.kind, kind: metadata.spec.name })}\n >\n {metadata.spec.display.name}\n </MenuItem>\n ))}\n </TextField>\n );\n});\nPluginKindSelect.displayName = 'PluginKindSelect';\n\n// Delimiter used to stringify/parse option values\nconst OPTION_VALUE_DELIMITER = '_____';\n\n/**\n * Given a PluginEditorSelection,\n * returns a string value like `{type}_____{kind}` that can be used as a Select input value.\n * @param selector\n */\nfunction selectionToOptionValue(selector: PluginEditorSelection): string {\n return [selector.type, selector.kind].join(OPTION_VALUE_DELIMITER);\n}\n\n/**\n * Given an option value name like `{type}_____{kind}`,\n * returns a PluginEditorSelection to be used by the query data model.\n * @param optionValue\n */\nfunction optionValueToSelection(optionValue: string): PluginEditorSelection {\n const words = optionValue.split(OPTION_VALUE_DELIMITER);\n const type = words[0] as PluginType | undefined;\n const kind = words[1];\n if (type === undefined || kind === undefined) {\n throw new Error('Invalid optionValue string');\n }\n return {\n type,\n kind,\n };\n}\n"],"names":["MenuItem","TextField","forwardRef","useCallback","useListPluginMetadata","PluginKindSelect","props","ref","pluginTypes","value","propValue","onChange","others","data","isLoading","selectionToOptionValue","handleChange","event","optionValueToSelection","target","renderValue","selected","selectedValue","find","v","kind","type","spec","name","display","select","inputRef","aria-label","SelectProps","data-testid","map","metadata","displayName","OPTION_VALUE_DELIMITER","selector","join","optionValue","words","split","undefined","Error"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,QAAQ,EAAEC,SAAS,QAAwB,gBAAgB;AACpE,SAASC,UAAU,EAAgBC,WAAW,QAAQ,QAAQ;AAE9D,SAASC,qBAAqB,QAAQ,gBAAgB;AAStD;;;;;;CAMC,GACD,OAAO,MAAMC,iCAAmBH,WAAW,CAACI,OAA8BC;IACxE,MAAM,EAAEC,WAAW,EAAEC,OAAOC,SAAS,EAAEC,QAAQ,EAAE,GAAGC,QAAQ,GAAGN;IAC/D,MAAM,EAAEO,IAAI,EAAEC,SAAS,EAAE,GAAGV,sBAAsBI;IAElD,qHAAqH;IACrH,MAAMC,QAAQ,CAACC,aAAaI,YAAY,KAAKC,uBAAuBL;IAEpE,MAAMM,eAAe,CAACC;QACpBN,WAAWO,uBAAuBD,MAAME,MAAM,CAACV,KAAK;IACtD;IAEA,MAAMW,cAAcjB,YAClB,CAACkB;QACC,IAAIA,aAAa,IAAI;YACnB,OAAO;QACT;QACA,MAAMC,gBAAgBJ,uBAAuBG;QAC7C,OAAOR,MAAMU,KAAK,CAACC,IAAMA,EAAEC,IAAI,KAAKH,cAAcI,IAAI,IAAIF,EAAEG,IAAI,CAACC,IAAI,KAAKN,cAAcG,IAAI,GAAGE,KAAKE,QAAQD;IAC9G,GACA;QAACf;KAAK;IAGR,yDAAyD;IACzD,qBACE,MAACZ;QACC6B,MAAM;QACNC,UAAUxB;QACT,GAAGK,MAAM;QACVH,OAAOA;QACPuB,cAAYvB;QACZE,UAAUK;QACViB,aAAa;YAAEb;QAAY;QAC3Bc,eAAY;;YAEXpB,2BAAa,KAACd;gBAASS,OAAM;0BAAG;;YAChCI,MAAMsB,IAAI,CAACC,yBACV,KAACpC;oBACCkC,eAAY;oBAEZzB,OAAOM,uBAAuB;wBAAEW,MAAMU,SAASX,IAAI;wBAAEA,MAAMW,SAAST,IAAI,CAACC,IAAI;oBAAC;8BAE7EQ,SAAST,IAAI,CAACE,OAAO,CAACD,IAAI;mBAHtBQ,SAASX,IAAI,GAAGW,SAAST,IAAI,CAACC,IAAI;;;AAQjD,GAAG;AACHvB,iBAAiBgC,WAAW,GAAG;AAE/B,kDAAkD;AAClD,MAAMC,yBAAyB;AAE/B;;;;CAIC,GACD,SAASvB,uBAAuBwB,QAA+B;IAC7D,OAAO;QAACA,SAASb,IAAI;QAAEa,SAASd,IAAI;KAAC,CAACe,IAAI,CAACF;AAC7C;AAEA;;;;CAIC,GACD,SAASpB,uBAAuBuB,WAAmB;IACjD,MAAMC,QAAQD,YAAYE,KAAK,CAACL;IAChC,MAAMZ,OAAOgB,KAAK,CAAC,EAAE;IACrB,MAAMjB,OAAOiB,KAAK,CAAC,EAAE;IACrB,IAAIhB,SAASkB,aAAanB,SAASmB,WAAW;QAC5C,MAAM,IAAIC,MAAM;IAClB;IACA,OAAO;QACLnB;QACAD;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/PluginKindSelect/PluginKindSelect.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { MenuItem, TextField, TextFieldProps } from '@mui/material';\nimport { forwardRef, ReactElement, useCallback } from 'react';\nimport { PluginType } from '../../model';\nimport { useListPluginMetadata } from '../../runtime';\nimport { PluginEditorSelection } from '../PluginEditor';\n\nexport interface PluginKindSelectProps extends Omit<TextFieldProps, 'value' | 'onChange' | 'children'> {\n pluginTypes: PluginType[];\n value?: PluginEditorSelection;\n onChange?: (s: PluginEditorSelection) => void;\n}\n\n/**\n * Displays a MUI Select input for selecting a plugin's kind from a list of all the available plugins of some specific\n * plugin types. (e.g. \"Show a list of all the Panel plugins\", or \"Show a list of all the Variable plugins\", or \"Show\n * a list of all the TimeSeriesQuery, TraceQuery, ProfileQuery, and LogQuery plugins\").\n * The value of the select is the kind of the plugin, but you can also listen to the `onPluginTypeChange` event to know\n * when the user changes the plugin type (it fires at start for the default value.)\n */\nexport const PluginKindSelect = forwardRef((props: PluginKindSelectProps, ref): ReactElement => {\n const { pluginTypes, value: propValue, onChange, ...others } = props;\n const { data, isLoading } = useListPluginMetadata(pluginTypes);\n\n // Pass an empty value while options are still loading so MUI doesn't complain about us using an \"out of range\" value\n const value = !propValue || isLoading ? '' : selectionToOptionValue(propValue);\n\n const handleChange = (event: { target: { value: string } }): void => {\n onChange?.(optionValueToSelection(event.target.value));\n };\n\n const renderValue = useCallback(\n (selected: unknown) => {\n if (selected === '') {\n return '';\n }\n const selectedValue = optionValueToSelection(selected as string);\n return data?.find((v) => v.kind === selectedValue.type && v.spec.name === selectedValue.kind)?.spec.display.name;\n },\n [data]\n );\n\n // TODO: Does this need a loading indicator of some kind?\n return (\n <TextField\n select\n inputRef={ref}\n {...others}\n value={value}\n aria-label={value}\n onChange={handleChange}\n SelectProps={{ renderValue }}\n data-testid=\"plugin-kind-select\"\n >\n {isLoading && <MenuItem value=\"\">Loading...</MenuItem>}\n {data?.map((metadata) => (\n <MenuItem\n data-testid=\"option\"\n key={metadata.kind + metadata.spec.name}\n value={selectionToOptionValue({ type: metadata.kind, kind: metadata.spec.name })}\n >\n {metadata.spec.display.name}\n </MenuItem>\n ))}\n </TextField>\n );\n});\nPluginKindSelect.displayName = 'PluginKindSelect';\n\n// Delimiter used to stringify/parse option values\nconst OPTION_VALUE_DELIMITER = '_____';\n\n/**\n * Given a PluginEditorSelection,\n * returns a string value like `{type}_____{kind}` that can be used as a Select input value.\n * @param selector\n */\nfunction selectionToOptionValue(selector: PluginEditorSelection): string {\n return [selector.type, selector.kind].join(OPTION_VALUE_DELIMITER);\n}\n\n/**\n * Given an option value name like `{type}_____{kind}`,\n * returns a PluginEditorSelection to be used by the query data model.\n * @param optionValue\n */\nfunction optionValueToSelection(optionValue: string): PluginEditorSelection {\n const words = optionValue.split(OPTION_VALUE_DELIMITER);\n const type = words[0] as PluginType | undefined;\n const kind = words[1];\n if (type === undefined || kind === undefined) {\n throw new Error('Invalid optionValue string');\n }\n return {\n type,\n kind,\n };\n}\n"],"names":["MenuItem","TextField","forwardRef","useCallback","useListPluginMetadata","PluginKindSelect","props","ref","pluginTypes","value","propValue","onChange","others","data","isLoading","selectionToOptionValue","handleChange","event","optionValueToSelection","target","renderValue","selected","selectedValue","find","v","kind","type","spec","name","display","select","inputRef","aria-label","SelectProps","data-testid","map","metadata","displayName","OPTION_VALUE_DELIMITER","selector","join","optionValue","words","split","undefined","Error"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,QAAQ,EAAEC,SAAS,QAAwB,gBAAgB;AACpE,SAASC,UAAU,EAAgBC,WAAW,QAAQ,QAAQ;AAE9D,SAASC,qBAAqB,QAAQ,gBAAgB;AAStD;;;;;;CAMC,GACD,OAAO,MAAMC,iCAAmBH,WAAW,CAACI,OAA8BC;IACxE,MAAM,EAAEC,WAAW,EAAEC,OAAOC,SAAS,EAAEC,QAAQ,EAAE,GAAGC,QAAQ,GAAGN;IAC/D,MAAM,EAAEO,IAAI,EAAEC,SAAS,EAAE,GAAGV,sBAAsBI;IAElD,qHAAqH;IACrH,MAAMC,QAAQ,CAACC,aAAaI,YAAY,KAAKC,uBAAuBL;IAEpE,MAAMM,eAAe,CAACC;QACpBN,WAAWO,uBAAuBD,MAAME,MAAM,CAACV,KAAK;IACtD;IAEA,MAAMW,cAAcjB,YAClB,CAACkB;QACC,IAAIA,aAAa,IAAI;YACnB,OAAO;QACT;QACA,MAAMC,gBAAgBJ,uBAAuBG;QAC7C,OAAOR,MAAMU,KAAK,CAACC,IAAMA,EAAEC,IAAI,KAAKH,cAAcI,IAAI,IAAIF,EAAEG,IAAI,CAACC,IAAI,KAAKN,cAAcG,IAAI,GAAGE,KAAKE,QAAQD;IAC9G,GACA;QAACf;KAAK;IAGR,yDAAyD;IACzD,qBACE,MAACZ;QACC6B,MAAM;QACNC,UAAUxB;QACT,GAAGK,MAAM;QACVH,OAAOA;QACPuB,cAAYvB;QACZE,UAAUK;QACViB,aAAa;YAAEb;QAAY;QAC3Bc,eAAY;;YAEXpB,2BAAa,KAACd;gBAASS,OAAM;0BAAG;;YAChCI,MAAMsB,IAAI,CAACC,yBACV,KAACpC;oBACCkC,eAAY;oBAEZzB,OAAOM,uBAAuB;wBAAEW,MAAMU,SAASX,IAAI;wBAAEA,MAAMW,SAAST,IAAI,CAACC,IAAI;oBAAC;8BAE7EQ,SAAST,IAAI,CAACE,OAAO,CAACD,IAAI;mBAHtBQ,SAASX,IAAI,GAAGW,SAAST,IAAI,CAACC,IAAI;;;AAQjD,GAAG;AACHvB,iBAAiBgC,WAAW,GAAG;AAE/B,kDAAkD;AAClD,MAAMC,yBAAyB;AAE/B;;;;CAIC,GACD,SAASvB,uBAAuBwB,QAA+B;IAC7D,OAAO;QAACA,SAASb,IAAI;QAAEa,SAASd,IAAI;KAAC,CAACe,IAAI,CAACF;AAC7C;AAEA;;;;CAIC,GACD,SAASpB,uBAAuBuB,WAAmB;IACjD,MAAMC,QAAQD,YAAYE,KAAK,CAACL;IAChC,MAAMZ,OAAOgB,KAAK,CAAC,EAAE;IACrB,MAAMjB,OAAOiB,KAAK,CAAC,EAAE;IACrB,IAAIhB,SAASkB,aAAanB,SAASmB,WAAW;QAC5C,MAAM,IAAIC,MAAM;IAClB;IACA,OAAO;QACLnB;QACAD;IACF;AACF"}
|
package/dist/model/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/model/index.ts"],"names":[],"mappings":"AAaA,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/model/index.ts"],"names":[],"mappings":"AAaA,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC"}
|
package/dist/model/index.js
CHANGED
package/dist/model/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/model/index.ts"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nexport * from './datasource';\nexport * from './legend';\nexport * from './panels';\nexport * from './plugins';\nexport * from './plugin-base';\nexport * from './plugin-loading';\nexport * from './time-series-queries';\nexport * from './trace-queries';\nexport * from './variables';\n"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,cAAc,eAAe;AAC7B,cAAc,WAAW;AACzB,cAAc,WAAW;AACzB,cAAc,YAAY;AAC1B,cAAc,gBAAgB;AAC9B,cAAc,mBAAmB;AACjC,cAAc,wBAAwB;AACtC,cAAc,kBAAkB;AAChC,cAAc,cAAc"}
|
|
1
|
+
{"version":3,"sources":["../../src/model/index.ts"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nexport * from './datasource';\nexport * from './legend';\nexport * from './panels';\nexport * from './plugins';\nexport * from './plugin-base';\nexport * from './plugin-loading';\nexport * from './time-series-queries';\nexport * from './trace-queries';\nexport * from './profile-queries';\nexport * from './variables';\n"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,cAAc,eAAe;AAC7B,cAAc,WAAW;AACzB,cAAc,WAAW;AACzB,cAAc,YAAY;AAC1B,cAAc,gBAAgB;AAC9B,cAAc,mBAAmB;AACjC,cAAc,wBAAwB;AACtC,cAAc,kBAAkB;AAChC,cAAc,oBAAoB;AAClC,cAAc,cAAc"}
|
package/dist/model/panels.d.ts
CHANGED
|
@@ -6,6 +6,10 @@ import { OptionsEditorProps, Plugin } from './plugin-base';
|
|
|
6
6
|
export type PanelOptionsEditorComponent<T> = Pick<OptionsEditorTab, 'label'> & {
|
|
7
7
|
content: React.ComponentType<OptionsEditorProps<T>>;
|
|
8
8
|
};
|
|
9
|
+
export type PanelAction<TPanelProps> = {
|
|
10
|
+
component: React.ComponentType<TPanelProps>;
|
|
11
|
+
location?: string;
|
|
12
|
+
};
|
|
9
13
|
/**
|
|
10
14
|
* Plugin the provides custom visualizations inside a Panel.
|
|
11
15
|
*/
|
|
@@ -36,6 +40,10 @@ export interface PanelPlugin<Spec = UnknownSpec, TPanelProps = PanelProps<Spec>>
|
|
|
36
40
|
* @default false
|
|
37
41
|
*/
|
|
38
42
|
hideQueryEditor?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* List of panel actions that will be rendered in the panel header
|
|
45
|
+
*/
|
|
46
|
+
actions?: Array<PanelAction<TPanelProps>>;
|
|
39
47
|
}
|
|
40
48
|
/**
|
|
41
49
|
* The props provided by Perses to a panel plugin's PanelComponent.
|