@perses-dev/plugin-system 0.52.0-beta.4 → 0.52.0-rc.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 (26) hide show
  1. package/dist/cjs/components/PluginEditor/PluginEditor.js +20 -7
  2. package/dist/cjs/components/Variables/VariableEditorForm/VariableEditorForm.js +36 -80
  3. package/dist/cjs/components/Variables/VariableEditorForm/VariablePreview.js +13 -7
  4. package/dist/cjs/runtime/TimeRangeProvider/TimeRangeProvider.js +6 -1
  5. package/dist/cjs/utils/variables.js +109 -14
  6. package/dist/components/PluginEditor/PluginEditor.d.ts.map +1 -1
  7. package/dist/components/PluginEditor/PluginEditor.js +21 -8
  8. package/dist/components/PluginEditor/PluginEditor.js.map +1 -1
  9. package/dist/components/TimeRangeControls/TimeRangeControls.js.map +1 -1
  10. package/dist/components/Variables/VariableEditorForm/VariableEditorForm.d.ts.map +1 -1
  11. package/dist/components/Variables/VariableEditorForm/VariableEditorForm.js +37 -40
  12. package/dist/components/Variables/VariableEditorForm/VariableEditorForm.js.map +1 -1
  13. package/dist/components/Variables/VariableEditorForm/VariablePreview.d.ts.map +1 -1
  14. package/dist/components/Variables/VariableEditorForm/VariablePreview.js +14 -8
  15. package/dist/components/Variables/VariableEditorForm/VariablePreview.js.map +1 -1
  16. package/dist/model/plugin-base.d.ts +2 -1
  17. package/dist/model/plugin-base.d.ts.map +1 -1
  18. package/dist/model/plugin-base.js.map +1 -1
  19. package/dist/runtime/TimeRangeProvider/TimeRangeProvider.d.ts.map +1 -1
  20. package/dist/runtime/TimeRangeProvider/TimeRangeProvider.js +6 -1
  21. package/dist/runtime/TimeRangeProvider/TimeRangeProvider.js.map +1 -1
  22. package/dist/utils/variables.d.ts +24 -2
  23. package/dist/utils/variables.d.ts.map +1 -1
  24. package/dist/utils/variables.js +102 -14
  25. package/dist/utils/variables.js.map +1 -1
  26. package/package.json +3 -3
@@ -37,26 +37,39 @@ function PluginEditor(props) {
37
37
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
38
38
  const { value, withRunQueryButton = true, pluginTypes, pluginKindLabel, onChange: _, isReadonly, ...others } = props;
39
39
  const { pendingSelection, isLoading, error, onSelectionChange, onSpecChange } = (0, _plugineditorapi.usePluginEditor)(props);
40
- const [watchedQuery, setWatchQuery] = (0, _react.useState)(value.spec['query']);
40
+ /*
41
+ We could technically merge the watchedQuery, watchedOtherSpecs into a single watched-object,
42
+ because at the end of the day, they are all specs.
43
+ However, let's have them separated to keep the code simple and readable.
44
+ Reason: Only Query string field is common between all of them. Other specs may be different
45
+ Example: Legend, and MinSteps
46
+ */ const [watchedQuery, setWatchQuery] = (0, _react.useState)(value.spec['query']);
47
+ const [watchedOtherSpecs, setWatchOtherSpecs] = (0, _react.useState)(value.spec);
41
48
  const runQueryHandler = (0, _react.useCallback)(()=>{
42
49
  onSpecChange({
43
50
  ...value.spec,
51
+ ...watchedOtherSpecs,
44
52
  query: watchedQuery
45
53
  });
46
54
  }, [
47
55
  value.spec,
48
56
  onSpecChange,
49
- watchedQuery
57
+ watchedQuery,
58
+ watchedOtherSpecs
50
59
  ]);
51
- let queryHandlerSettings = undefined;
52
- if (withRunQueryButton) {
53
- queryHandlerSettings = {
60
+ const queryHandlerSettings = (0, _react.useMemo)(()=>{
61
+ return withRunQueryButton ? {
54
62
  runWithOnBlur: false,
55
63
  watchQueryChanges: (query)=>{
56
64
  setWatchQuery(query);
65
+ },
66
+ setWatchOtherSpecs: (otherSpecs)=>{
67
+ setWatchOtherSpecs(otherSpecs);
57
68
  }
58
- };
59
- }
69
+ } : undefined;
70
+ }, [
71
+ withRunQueryButton
72
+ ]);
60
73
  return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Box, {
61
74
  ...others,
62
75
  children: [
@@ -21,57 +21,17 @@ Object.defineProperty(exports, "VariableEditorForm", {
21
21
  }
22
22
  });
23
23
  const _jsxruntime = require("react/jsx-runtime");
24
- const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
24
+ const _react = require("react");
25
25
  const _material = require("@mui/material");
26
26
  const _components = require("@perses-dev/components");
27
27
  const _reacthookform = require("react-hook-form");
28
28
  const _zod = require("@hookform/resolvers/zod");
29
29
  const _utils = require("../../../utils");
30
- const _variablemodel = require("../variable-model");
31
30
  const _PluginEditor = require("../../PluginEditor");
32
31
  const _context = require("../../../context");
32
+ const _variablemodel = require("../variable-model");
33
+ const _runtime = require("../../../runtime");
33
34
  const _VariablePreview = require("./VariablePreview");
34
- function _getRequireWildcardCache(nodeInterop) {
35
- if (typeof WeakMap !== "function") return null;
36
- var cacheBabelInterop = new WeakMap();
37
- var cacheNodeInterop = new WeakMap();
38
- return (_getRequireWildcardCache = function(nodeInterop) {
39
- return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
40
- })(nodeInterop);
41
- }
42
- function _interop_require_wildcard(obj, nodeInterop) {
43
- if (!nodeInterop && obj && obj.__esModule) {
44
- return obj;
45
- }
46
- if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
47
- return {
48
- default: obj
49
- };
50
- }
51
- var cache = _getRequireWildcardCache(nodeInterop);
52
- if (cache && cache.has(obj)) {
53
- return cache.get(obj);
54
- }
55
- var newObj = {
56
- __proto__: null
57
- };
58
- var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
59
- for(var key in obj){
60
- if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
61
- var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
62
- if (desc && (desc.get || desc.set)) {
63
- Object.defineProperty(newObj, key, desc);
64
- } else {
65
- newObj[key] = obj[key];
66
- }
67
- }
68
- }
69
- newObj.default = obj;
70
- if (cache) {
71
- cache.set(obj, newObj);
72
- }
73
- return newObj;
74
- }
75
35
  function FallbackPreview() {
76
36
  return /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
77
37
  children: "Error previewing values"
@@ -147,7 +107,9 @@ function ListVariableEditorForm({ action, control }) {
147
107
  * spec that will be used for preview. The reason why we do this is to avoid
148
108
  * having to re-fetch the values when the user is still editing the spec.
149
109
  */ const [previewSpec, setPreviewSpec] = (0, _react.useState)(form.getValues());
110
+ const { refresh } = (0, _runtime.useTimeRange)();
150
111
  const refreshPreview = ()=>{
112
+ refresh();
151
113
  setPreviewSpec(form.getValues());
152
114
  };
153
115
  const plugin = (0, _reacthookform.useWatch)({
@@ -194,46 +156,40 @@ function ListVariableEditorForm({ action, control }) {
194
156
  }) : /*#__PURE__*/ (0, _jsxruntime.jsx)(_VariablePreview.VariablePreview, {
195
157
  isLoading: true
196
158
  }),
197
- /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Stack, {
198
- children: [
199
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.ClickAwayListener, {
200
- onClickAway: ()=>refreshPreview(),
201
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {})
202
- }),
203
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.ErrorBoundary, {
204
- FallbackComponent: _components.ErrorAlert,
205
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reacthookform.Controller, {
206
- control: control,
207
- name: "spec.plugin",
208
- render: ({ field })=>{
209
- return /*#__PURE__*/ (0, _jsxruntime.jsx)(_PluginEditor.PluginEditor, {
210
- withRunQueryButton: true,
211
- width: "100%",
212
- pluginTypes: [
213
- 'Variable'
214
- ],
215
- pluginKindLabel: "Source",
216
- value: {
217
- selection: {
218
- type: 'Variable',
219
- kind: kind ?? 'StaticListVariable'
220
- },
221
- spec: pluginSpec ?? {
222
- values: []
223
- }
159
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Stack, {
160
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.ErrorBoundary, {
161
+ FallbackComponent: _components.ErrorAlert,
162
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reacthookform.Controller, {
163
+ control: control,
164
+ name: "spec.plugin",
165
+ render: ({ field })=>{
166
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_PluginEditor.PluginEditor, {
167
+ withRunQueryButton: true,
168
+ width: "100%",
169
+ pluginTypes: [
170
+ 'Variable'
171
+ ],
172
+ pluginKindLabel: "Source",
173
+ value: {
174
+ selection: {
175
+ type: 'Variable',
176
+ kind: kind ?? 'StaticListVariable'
224
177
  },
225
- isReadonly: action === 'read',
226
- onChange: (v)=>{
227
- field.onChange({
228
- kind: v.selection.kind,
229
- spec: v.spec
230
- });
178
+ spec: pluginSpec ?? {
179
+ values: []
231
180
  }
232
- });
233
- }
234
- })
181
+ },
182
+ isReadonly: action === 'read',
183
+ onChange: (v)=>{
184
+ field.onChange({
185
+ kind: v.selection.kind,
186
+ spec: v.spec
187
+ });
188
+ }
189
+ });
190
+ }
235
191
  })
236
- ]
192
+ })
237
193
  }),
238
194
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Stack, {
239
195
  children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reacthookform.Controller, {
@@ -172,13 +172,19 @@ function VariablePreview(props) {
172
172
  });
173
173
  }
174
174
  function VariableListPreview(props) {
175
- const { definition, onRefresh } = props;
175
+ const { onRefresh, definition } = props;
176
176
  const { data, isFetching, error } = (0, _variablemodel.useListVariablePluginValues)(definition);
177
177
  const errorMessage = error?.message;
178
- return /*#__PURE__*/ (0, _jsxruntime.jsx)(VariablePreview, {
179
- values: data?.map((val)=>val.value) || [],
180
- onRefresh: onRefresh,
181
- isLoading: isFetching,
182
- error: errorMessage
183
- });
178
+ const variablePreview = (0, _react.useMemo)(()=>/*#__PURE__*/ (0, _jsxruntime.jsx)(VariablePreview, {
179
+ values: data?.map((val)=>val.value) || [],
180
+ onRefresh: onRefresh,
181
+ isLoading: isFetching,
182
+ error: errorMessage
183
+ }), [
184
+ errorMessage,
185
+ isFetching,
186
+ onRefresh,
187
+ data
188
+ ]);
189
+ return variablePreview;
184
190
  }
@@ -100,7 +100,12 @@ function useSuggestedStepMs(width) {
100
100
  }
101
101
  function TimeRangeProvider(props) {
102
102
  const { timeRange, refreshInterval, children, setTimeRange, setRefreshInterval } = props;
103
- const [localTimeRange, setLocalTimeRange] = (0, _react.useState)(timeRange);
103
+ /**
104
+ * TODO: The hook needs refactor. There is a bug here with refreshKey. If the refreshInterval is not set,
105
+ * refreshKey string includes an undefined xx:yy:zz:undefined:0
106
+ * I think exposing refresh functionality also is very risky. A careless usage of refresh may cause
107
+ * infinite rendering loop.
108
+ */ const [localTimeRange, setLocalTimeRange] = (0, _react.useState)(timeRange);
104
109
  const [localRefreshInterval, setLocalRefreshInterval] = (0, _react.useState)(refreshInterval);
105
110
  const [refreshCounter, setRefreshCounter] = (0, _react.useState)(0);
106
111
  (0, _react.useEffect)(()=>{
@@ -21,9 +21,18 @@ function _export(target, all) {
21
21
  });
22
22
  }
23
23
  _export(exports, {
24
+ InterpolationFormat: function() {
25
+ return InterpolationFormat;
26
+ },
27
+ interpolate: function() {
28
+ return interpolate;
29
+ },
24
30
  parseVariables: function() {
25
31
  return parseVariables;
26
32
  },
33
+ parseVariablesAndFormat: function() {
34
+ return parseVariablesAndFormat;
35
+ },
27
36
  replaceVariable: function() {
28
37
  return replaceVariable;
29
38
  },
@@ -32,7 +41,8 @@ _export(exports, {
32
41
  }
33
42
  });
34
43
  function replaceVariables(text, variableState) {
35
- const variables = parseVariables(text);
44
+ const variablesMap = parseVariablesAndFormat(text);
45
+ const variables = Array.from(variablesMap.keys());
36
46
  let finalText = text;
37
47
  variables// Sorting variables by their length.
38
48
  // In order to not have a variable name have contained in another variable name.
@@ -40,20 +50,88 @@ function replaceVariables(text, variableState) {
40
50
  .sort((a, b)=>b.length - a.length).forEach((v)=>{
41
51
  const variable = variableState[v];
42
52
  if (variable && variable.value !== undefined) {
43
- finalText = replaceVariable(finalText, v, variable?.value);
53
+ finalText = replaceVariable(finalText, v, variable?.value, variablesMap.get(v));
44
54
  }
45
55
  });
46
56
  return finalText;
47
57
  }
48
- function replaceVariable(text, varName, variableValue) {
58
+ var InterpolationFormat = /*#__PURE__*/ function(InterpolationFormat) {
59
+ InterpolationFormat["CSV"] = "csv";
60
+ InterpolationFormat["DISTRIBUTED"] = "distributed";
61
+ InterpolationFormat["DOUBLEQUOTE"] = "doublequote";
62
+ InterpolationFormat["GLOB"] = "glob";
63
+ InterpolationFormat["JSON"] = "json";
64
+ InterpolationFormat["LUCENE"] = "lucene";
65
+ InterpolationFormat["PERCENTENCODE"] = "percentencode";
66
+ InterpolationFormat["PIPE"] = "pipe";
67
+ InterpolationFormat["PROMETHEUS"] = "prometheus";
68
+ InterpolationFormat["RAW"] = "raw";
69
+ InterpolationFormat["REGEX"] = "regex";
70
+ InterpolationFormat["SINGLEQUOTE"] = "singlequote";
71
+ InterpolationFormat["SQLSTRING"] = "sqlstring";
72
+ InterpolationFormat["TEXT"] = "text";
73
+ InterpolationFormat["QUERYPARAM"] = "queryparam";
74
+ return InterpolationFormat;
75
+ }({});
76
+ function stringToFormat(val) {
77
+ if (!val) return undefined;
78
+ const lowerVal = val.toLowerCase();
79
+ return Object.values(InterpolationFormat).find((format)=>format === lowerVal) || undefined;
80
+ }
81
+ function interpolate(values, name, format) {
82
+ switch(format){
83
+ case "csv":
84
+ case "raw":
85
+ return values.join(',');
86
+ case "distributed":
87
+ {
88
+ const [first, ...rest] = values;
89
+ return `${[
90
+ first,
91
+ ...rest.map((v)=>`${name}=${v}`)
92
+ ].join(',')}`;
93
+ }
94
+ case "doublequote":
95
+ return values.map((v)=>`"${v}"`).join(',');
96
+ case "glob":
97
+ return `{${values.join(',')}}`;
98
+ case "json":
99
+ return JSON.stringify(values);
100
+ case "lucene":
101
+ return `(${values.map((v)=>`"${v}"`).join(' OR ')})`;
102
+ case "percentencode":
103
+ return encodeURIComponent(values.join(','));
104
+ case "pipe":
105
+ return values.join('|');
106
+ case "regex":
107
+ {
108
+ const escapedRegex = values.map((v)=>v.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'));
109
+ return `(${escapedRegex.join('|')})`;
110
+ }
111
+ case "singlequote":
112
+ return values.map((v)=>`'${v}'`).join(',');
113
+ case "sqlstring":
114
+ return values.map((v)=>`'${v.replace(/'/g, "''")}'`).join(',');
115
+ case "text":
116
+ return values.join(' + ');
117
+ case "queryparam":
118
+ return values.map((v)=>`${name}=${encodeURIComponent(v)}`).join('&');
119
+ case "prometheus":
120
+ default:
121
+ return `(${values.join('|')})`;
122
+ }
123
+ }
124
+ function replaceVariable(text, varName, variableValue, varFormat) {
49
125
  const variableSyntax = '$' + varName;
50
- const alternativeVariableSyntax = '${' + varName + '}';
126
+ const alternativeVariableSyntax = '${' + varName + (varFormat ? ':' + varFormat : '') + '}';
51
127
  let replaceString = '';
52
128
  if (Array.isArray(variableValue)) {
53
- replaceString = `(${variableValue.join('|')})`; // regex style
129
+ replaceString = interpolate(variableValue, varName, varFormat || "prometheus");
54
130
  }
55
131
  if (typeof variableValue === 'string') {
56
- replaceString = variableValue;
132
+ replaceString = interpolate([
133
+ variableValue
134
+ ], varName, varFormat || "raw");
57
135
  }
58
136
  text = text.replaceAll(variableSyntax, replaceString);
59
137
  return text.replaceAll(alternativeVariableSyntax, replaceString);
@@ -62,15 +140,12 @@ function replaceVariable(text, varName, variableValue) {
62
140
  // It supports two formats for referencing variables:
63
141
  // 1. $variableName - This is a simpler format, and the regular expression captures the variable name (\w+ matches one or more word characters).
64
142
  // 2. ${variableName} - This is a more complex format and the regular expression captures the variable name (\w+ matches one or more word characters) in the curly braces.
65
- // 3. [COMING SOON] ${variableName:value} - This is a more complex format that allows specifying a format function as well.
66
- // TODO: Fix this lint error
67
- // eslint-disable-next-line no-useless-escape
68
- const VARIABLE_REGEX = /\$(\w+)|\${(\w+)(?:\.([^:^\}]+))?(?::([^\}]+))?}/gm;
69
- const parseVariables = (text)=>{
70
- const regex = VARIABLE_REGEX;
143
+ // 3. ${variableName:format} - This is a more complex format that allows specifying a format interpolation.
144
+ const VARIABLE_REGEX = /\$(\w+)|\${(\w+)(?:\.([^:^}]+))?(?::([^}]+))?}/gm;
145
+ function parseVariables(text) {
71
146
  const matches = new Set();
72
147
  let match;
73
- while((match = regex.exec(text)) !== null){
148
+ while((match = VARIABLE_REGEX.exec(text)) !== null){
74
149
  if (match) {
75
150
  if (match[1]) {
76
151
  // \$(\w+)\
@@ -83,4 +158,24 @@ const parseVariables = (text)=>{
83
158
  }
84
159
  // return unique matches
85
160
  return Array.from(matches.values());
86
- };
161
+ }
162
+ function parseVariablesAndFormat(text) {
163
+ const matches = new Map();
164
+ let match;
165
+ while((match = VARIABLE_REGEX.exec(text)) !== null){
166
+ if (match) {
167
+ let format = undefined;
168
+ if (match[4]) {
169
+ format = match[4];
170
+ }
171
+ if (match[1]) {
172
+ // \$(\w+)\
173
+ matches.set(match[1], stringToFormat(format));
174
+ } else if (match[2]) {
175
+ // \${(\w+)}\
176
+ matches.set(match[2], stringToFormat(format));
177
+ }
178
+ }
179
+ }
180
+ return matches;
181
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"PluginEditor.d.ts","sourceRoot":"","sources":["../../../src/components/PluginEditor/PluginEditor.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAE,YAAY,EAAyB,MAAM,OAAO,CAAC;AAG5D,OAAO,EAAE,iBAAiB,EAAmB,MAAM,qBAAqB,CAAC;AAEzE;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CA8DnE"}
1
+ {"version":3,"file":"PluginEditor.d.ts","sourceRoot":"","sources":["../../../src/components/PluginEditor/PluginEditor.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAE,YAAY,EAAkC,MAAM,OAAO,CAAC;AAIrE,OAAO,EAAE,iBAAiB,EAAmB,MAAM,qBAAqB,CAAC;AAEzE;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CA0EnE"}
@@ -14,7 +14,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
14
  import { Box, Button } from '@mui/material';
15
15
  import Reload from 'mdi-material-ui/Reload';
16
16
  import { ErrorAlert, ErrorBoundary } from '@perses-dev/components';
17
- import { useCallback, useState } from 'react';
17
+ import { useCallback, useMemo, useState } from 'react';
18
18
  import { PluginKindSelect } from '../PluginKindSelect';
19
19
  import { PluginSpecEditor } from '../PluginSpecEditor';
20
20
  import { usePluginEditor } from './plugin-editor-api';
@@ -29,26 +29,39 @@ import { usePluginEditor } from './plugin-editor-api';
29
29
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
30
30
  const { value, withRunQueryButton = true, pluginTypes, pluginKindLabel, onChange: _, isReadonly, ...others } = props;
31
31
  const { pendingSelection, isLoading, error, onSelectionChange, onSpecChange } = usePluginEditor(props);
32
- const [watchedQuery, setWatchQuery] = useState(value.spec['query']);
32
+ /*
33
+ We could technically merge the watchedQuery, watchedOtherSpecs into a single watched-object,
34
+ because at the end of the day, they are all specs.
35
+ However, let's have them separated to keep the code simple and readable.
36
+ Reason: Only Query string field is common between all of them. Other specs may be different
37
+ Example: Legend, and MinSteps
38
+ */ const [watchedQuery, setWatchQuery] = useState(value.spec['query']);
39
+ const [watchedOtherSpecs, setWatchOtherSpecs] = useState(value.spec);
33
40
  const runQueryHandler = useCallback(()=>{
34
41
  onSpecChange({
35
42
  ...value.spec,
43
+ ...watchedOtherSpecs,
36
44
  query: watchedQuery
37
45
  });
38
46
  }, [
39
47
  value.spec,
40
48
  onSpecChange,
41
- watchedQuery
49
+ watchedQuery,
50
+ watchedOtherSpecs
42
51
  ]);
43
- let queryHandlerSettings = undefined;
44
- if (withRunQueryButton) {
45
- queryHandlerSettings = {
52
+ const queryHandlerSettings = useMemo(()=>{
53
+ return withRunQueryButton ? {
46
54
  runWithOnBlur: false,
47
55
  watchQueryChanges: (query)=>{
48
56
  setWatchQuery(query);
57
+ },
58
+ setWatchOtherSpecs: (otherSpecs)=>{
59
+ setWatchOtherSpecs(otherSpecs);
49
60
  }
50
- };
51
- }
61
+ } : undefined;
62
+ }, [
63
+ withRunQueryButton
64
+ ]);
52
65
  return /*#__PURE__*/ _jsxs(Box, {
53
66
  ...others,
54
67
  children: [
@@ -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, Button } from '@mui/material';\nimport Reload from 'mdi-material-ui/Reload';\nimport { ErrorAlert, ErrorBoundary } from '@perses-dev/components';\nimport { ReactElement, useCallback, useState } 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, withRunQueryButton = true, pluginTypes, pluginKindLabel, onChange: _, isReadonly, ...others } = props;\n const { pendingSelection, isLoading, error, onSelectionChange, onSpecChange } = usePluginEditor(props);\n const [watchedQuery, setWatchQuery] = useState<string>(value.spec['query'] as string);\n\n const runQueryHandler = useCallback((): void => {\n onSpecChange({ ...value.spec, query: watchedQuery });\n }, [value.spec, onSpecChange, watchedQuery]);\n\n let queryHandlerSettings = undefined;\n\n if (withRunQueryButton) {\n queryHandlerSettings = {\n runWithOnBlur: false,\n watchQueryChanges: (query: string): void => {\n setWatchQuery(query);\n },\n };\n }\n\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 {withRunQueryButton && !isLoading && (\n <Button\n data-testid=\"run_query_button\"\n variant=\"contained\"\n sx={{ marginTop: 1.5, marginBottom: 1.5, paddingTop: 0.5, marginLeft: 'auto' }}\n startIcon={<Reload />}\n onClick={runQueryHandler}\n >\n Run Query\n </Button>\n )}\n </Box>\n\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <PluginSpecEditor\n pluginSelection={value.selection}\n value={value.spec}\n onChange={onSpecChange}\n isReadonly={isReadonly}\n queryHandlerSettings={queryHandlerSettings}\n />\n </ErrorBoundary>\n </Box>\n );\n}\n"],"names":["Box","Button","Reload","ErrorAlert","ErrorBoundary","useCallback","useState","PluginKindSelect","PluginSpecEditor","usePluginEditor","PluginEditor","props","value","withRunQueryButton","pluginTypes","pluginKindLabel","onChange","_","isReadonly","others","pendingSelection","isLoading","error","onSelectionChange","onSpecChange","watchedQuery","setWatchQuery","spec","runQueryHandler","query","queryHandlerSettings","undefined","runWithOnBlur","watchQueryChanges","sx","display","flexDirection","fullWidth","mb","minWidth","margin","label","disabled","selection","InputProps","readOnly","helperText","message","data-testid","variant","marginTop","marginBottom","paddingTop","marginLeft","startIcon","onClick","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;AACnE,SAAuBC,WAAW,EAAEC,QAAQ,QAAQ,QAAQ;AAC5D,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,qBAAqB,IAAI,EAAEC,WAAW,EAAEC,eAAe,EAAEC,UAAUC,CAAC,EAAEC,UAAU,EAAE,GAAGC,QAAQ,GAAGR;IAC/G,MAAM,EAAES,gBAAgB,EAAEC,SAAS,EAAEC,KAAK,EAAEC,iBAAiB,EAAEC,YAAY,EAAE,GAAGf,gBAAgBE;IAChG,MAAM,CAACc,cAAcC,cAAc,GAAGpB,SAAiBM,MAAMe,IAAI,CAAC,QAAQ;IAE1E,MAAMC,kBAAkBvB,YAAY;QAClCmB,aAAa;YAAE,GAAGZ,MAAMe,IAAI;YAAEE,OAAOJ;QAAa;IACpD,GAAG;QAACb,MAAMe,IAAI;QAAEH;QAAcC;KAAa;IAE3C,IAAIK,uBAAuBC;IAE3B,IAAIlB,oBAAoB;QACtBiB,uBAAuB;YACrBE,eAAe;YACfC,mBAAmB,CAACJ;gBAClBH,cAAcG;YAChB;QACF;IACF;IAEA,qBACE,MAAC7B;QAAK,GAAGmB,MAAM;;0BACb,MAACnB;gBAAIkC,IAAI;oBAAEC,SAAS;oBAAQC,eAAe;gBAAM;;kCAC/C,KAAC7B;wBACC8B,WAAW;wBACXH,IAAI;4BAAEI,IAAI;4BAAGC,UAAU;wBAAI;wBAC3BC,QAAO;wBACPC,OAAO1B;wBACPD,aAAaA;wBACb4B,UAAUrB;wBACVT,OAAOQ,mBAAmBA,mBAAmBR,MAAM+B,SAAS;wBAC5DC,YAAY;4BAAEC,UAAU3B;wBAAW;wBACnCI,OAAO,CAAC,CAACA;wBACTwB,YAAYxB,OAAOyB;wBACnB/B,UAAUO;;oBAGXV,sBAAsB,CAACQ,2BACtB,KAACpB;wBACC+C,eAAY;wBACZC,SAAQ;wBACRf,IAAI;4BAAEgB,WAAW;4BAAKC,cAAc;4BAAKC,YAAY;4BAAKC,YAAY;wBAAO;wBAC7EC,yBAAW,KAACpD;wBACZqD,SAAS3B;kCACV;;;;0BAML,KAACxB;gBAAcoD,mBAAmBrD;0BAChC,cAAA,KAACK;oBACCiD,iBAAiB7C,MAAM+B,SAAS;oBAChC/B,OAAOA,MAAMe,IAAI;oBACjBX,UAAUQ;oBACVN,YAAYA;oBACZY,sBAAsBA;;;;;AAKhC"}
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, useCallback, useMemo, useState } from 'react';\nimport { UnknownSpec } from '@perses-dev/core';\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, withRunQueryButton = true, pluginTypes, pluginKindLabel, onChange: _, isReadonly, ...others } = props;\n const { pendingSelection, isLoading, error, onSelectionChange, onSpecChange } = usePluginEditor(props);\n\n /* \n We could technically merge the watchedQuery, watchedOtherSpecs into a single watched-object,\n because at the end of the day, they are all specs.\n However, let's have them separated to keep the code simple and readable.\n Reason: Only Query string field is common between all of them. Other specs may be different\n Example: Legend, and MinSteps\n */\n const [watchedQuery, setWatchQuery] = useState<string>(value.spec['query'] as string);\n const [watchedOtherSpecs, setWatchOtherSpecs] = useState<UnknownSpec>(value.spec);\n\n const runQueryHandler = useCallback((): void => {\n onSpecChange({ ...value.spec, ...watchedOtherSpecs, query: watchedQuery });\n }, [value.spec, onSpecChange, watchedQuery, watchedOtherSpecs]);\n\n const queryHandlerSettings = useMemo(() => {\n return withRunQueryButton\n ? {\n runWithOnBlur: false,\n watchQueryChanges: (query: string): void => {\n setWatchQuery(query);\n },\n setWatchOtherSpecs: (otherSpecs: UnknownSpec): void => {\n setWatchOtherSpecs(otherSpecs);\n },\n }\n : undefined;\n }, [withRunQueryButton]);\n\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 {withRunQueryButton && !isLoading && (\n <Button\n data-testid=\"run_query_button\"\n variant=\"contained\"\n sx={{ marginTop: 1.5, marginBottom: 1.5, paddingTop: 0.5, marginLeft: 'auto' }}\n startIcon={<Reload />}\n onClick={runQueryHandler}\n >\n Run Query\n </Button>\n )}\n </Box>\n\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <PluginSpecEditor\n pluginSelection={value.selection}\n value={value.spec}\n onChange={onSpecChange}\n isReadonly={isReadonly}\n queryHandlerSettings={queryHandlerSettings}\n />\n </ErrorBoundary>\n </Box>\n );\n}\n"],"names":["Box","Button","Reload","ErrorAlert","ErrorBoundary","useCallback","useMemo","useState","PluginKindSelect","PluginSpecEditor","usePluginEditor","PluginEditor","props","value","withRunQueryButton","pluginTypes","pluginKindLabel","onChange","_","isReadonly","others","pendingSelection","isLoading","error","onSelectionChange","onSpecChange","watchedQuery","setWatchQuery","spec","watchedOtherSpecs","setWatchOtherSpecs","runQueryHandler","query","queryHandlerSettings","runWithOnBlur","watchQueryChanges","otherSpecs","undefined","sx","display","flexDirection","fullWidth","mb","minWidth","margin","label","disabled","selection","InputProps","readOnly","helperText","message","data-testid","variant","marginTop","marginBottom","paddingTop","marginLeft","startIcon","onClick","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;AACnE,SAAuBC,WAAW,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,QAAQ;AAErE,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,qBAAqB,IAAI,EAAEC,WAAW,EAAEC,eAAe,EAAEC,UAAUC,CAAC,EAAEC,UAAU,EAAE,GAAGC,QAAQ,GAAGR;IAC/G,MAAM,EAAES,gBAAgB,EAAEC,SAAS,EAAEC,KAAK,EAAEC,iBAAiB,EAAEC,YAAY,EAAE,GAAGf,gBAAgBE;IAEhG;;;;;;GAMC,GACD,MAAM,CAACc,cAAcC,cAAc,GAAGpB,SAAiBM,MAAMe,IAAI,CAAC,QAAQ;IAC1E,MAAM,CAACC,mBAAmBC,mBAAmB,GAAGvB,SAAsBM,MAAMe,IAAI;IAEhF,MAAMG,kBAAkB1B,YAAY;QAClCoB,aAAa;YAAE,GAAGZ,MAAMe,IAAI;YAAE,GAAGC,iBAAiB;YAAEG,OAAON;QAAa;IAC1E,GAAG;QAACb,MAAMe,IAAI;QAAEH;QAAcC;QAAcG;KAAkB;IAE9D,MAAMI,uBAAuB3B,QAAQ;QACnC,OAAOQ,qBACH;YACEoB,eAAe;YACfC,mBAAmB,CAACH;gBAClBL,cAAcK;YAChB;YACAF,oBAAoB,CAACM;gBACnBN,mBAAmBM;YACrB;QACF,IACAC;IACN,GAAG;QAACvB;KAAmB;IAEvB,qBACE,MAACd;QAAK,GAAGoB,MAAM;;0BACb,MAACpB;gBAAIsC,IAAI;oBAAEC,SAAS;oBAAQC,eAAe;gBAAM;;kCAC/C,KAAChC;wBACCiC,WAAW;wBACXH,IAAI;4BAAEI,IAAI;4BAAGC,UAAU;wBAAI;wBAC3BC,QAAO;wBACPC,OAAO7B;wBACPD,aAAaA;wBACb+B,UAAUxB;wBACVT,OAAOQ,mBAAmBA,mBAAmBR,MAAMkC,SAAS;wBAC5DC,YAAY;4BAAEC,UAAU9B;wBAAW;wBACnCI,OAAO,CAAC,CAACA;wBACT2B,YAAY3B,OAAO4B;wBACnBlC,UAAUO;;oBAGXV,sBAAsB,CAACQ,2BACtB,KAACrB;wBACCmD,eAAY;wBACZC,SAAQ;wBACRf,IAAI;4BAAEgB,WAAW;4BAAKC,cAAc;4BAAKC,YAAY;4BAAKC,YAAY;wBAAO;wBAC7EC,yBAAW,KAACxD;wBACZyD,SAAS5B;kCACV;;;;0BAML,KAAC3B;gBAAcwD,mBAAmBzD;0BAChC,cAAA,KAACM;oBACCoD,iBAAiBhD,MAAMkC,SAAS;oBAChClC,OAAOA,MAAMe,IAAI;oBACjBX,UAAUQ;oBACVN,YAAYA;oBACZc,sBAAsBA;;;;;AAKhC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/TimeRangeControls/TimeRangeControls.tsx"],"sourcesContent":["// Copyright 2024 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 RefreshIcon from 'mdi-material-ui/Refresh';\n// eslint-disable-next-line import/no-duplicates\nimport ZoomIn from 'mdi-material-ui/PlusCircleOutline';\n// eslint-disable-next-line import/no-duplicates\nimport ZoomOut from 'mdi-material-ui/MinusCircleOutline';\nimport { Stack } from '@mui/material';\nimport {\n RefreshIntervalPicker,\n InfoTooltip,\n TimeOption,\n ToolbarIconButton,\n TimeRangeSelector,\n buildRelativeTimeOption,\n} from '@perses-dev/components';\nimport { AbsoluteTimeRange, DurationString, parseDurationString, RelativeTimeRange } from '@perses-dev/core';\nimport { ReactElement, useCallback } from 'react';\nimport { TOOLTIP_TEXT } from '../../constants';\nimport {\n useTimeRange,\n useShowCustomTimeRangeSetting,\n useTimeRangeOptionsSetting,\n useShowZoomRangeSetting,\n} from '../../runtime';\n\nexport const DEFAULT_REFRESH_INTERVAL_OPTIONS: TimeOption[] = [\n { value: { pastDuration: '0s' }, display: 'Off' },\n { value: { pastDuration: '5s' }, display: '5s' },\n { value: { pastDuration: '10s' }, display: '10s' },\n { value: { pastDuration: '15s' }, display: '15s' },\n { value: { pastDuration: '30s' }, display: '30s' },\n { value: { pastDuration: '60s' }, display: '1m' },\n];\n\nconst DEFAULT_HEIGHT = '34px';\n\ninterface TimeRangeControlsProps {\n // The controls look best at heights >= 28 pixels\n heightPx?: number;\n showTimeRangeSelector?: boolean;\n showRefreshButton?: boolean;\n showRefreshInterval?: boolean;\n showCustomTimeRange?: boolean;\n showZoomButtons?: boolean;\n timePresets?: TimeOption[];\n}\n\nexport function TimeRangeControls({\n heightPx,\n showTimeRangeSelector = true,\n showRefreshButton = true,\n showRefreshInterval = true,\n showCustomTimeRange,\n showZoomButtons = true,\n timePresets,\n}: TimeRangeControlsProps): ReactElement {\n const { timeRange, setTimeRange, refresh, refreshInterval, setRefreshInterval } = useTimeRange();\n\n const showCustomTimeRangeValue = useShowCustomTimeRangeSetting(showCustomTimeRange);\n const showZoomInOutButtons = useShowZoomRangeSetting(showZoomButtons);\n const timePresetsValue = useTimeRangeOptionsSetting(timePresets);\n\n // Convert height to a string, then use the string for styling\n const height = heightPx === undefined ? DEFAULT_HEIGHT : `${heightPx}px`;\n\n // add time preset if one does not match duration given in time range\n if (\n 'pastDuration' in timeRange &&\n !timePresetsValue.some((option) => option.value.pastDuration === timeRange['pastDuration'])\n ) {\n timePresetsValue.push(buildRelativeTimeOption(timeRange['pastDuration']));\n }\n\n // set the new refresh interval both in the dashboard context & as query param\n const handleRefreshIntervalChange = useCallback(\n (duration: DurationString) => {\n setRefreshInterval(duration);\n },\n [setRefreshInterval]\n );\n\n const fromDurationToMillis = (strDuration: string): number => {\n const duration = parseDurationString(strDuration);\n const millis =\n // eslint-disable-next-line prettier/prettier\n ((duration.seconds ?? 0) +\n (duration.minutes ?? 0) * 60 +\n (duration.hours ?? 0) * 3600 +\n (duration.days ?? 0) * 86400 +\n (duration.weeks ?? 0) * 7 * 86400 +\n (duration.months ?? 0) * 30.436875 * 86400 + // avg month duration is ok for zoom purposes\n (duration.years ?? 0) * 365.2425 * 86400) * // avg year duration is ok for zoom purposes\n // eslint-disable-next-line prettier/prettier\n 1000; // to milliseconds\n return millis;\n };\n\n // Function to double current time range, adding 50% before current start and 50% after current end\n const doubleTimeRange = (): AbsoluteTimeRange => {\n let newStart, newEnd, extendEndsBy;\n const now = new Date();\n if (Object.hasOwn(timeRange, 'start')) {\n // current range is absolute\n const absVal = timeRange as AbsoluteTimeRange;\n extendEndsBy = (absVal.end.getTime() - absVal.start.getTime()) / 2; // half it to add 50% before current start and after current end\n newStart = new Date(absVal.start.getTime() - extendEndsBy);\n newEnd = new Date(absVal.end.getTime() + extendEndsBy);\n } else {\n // current range is relative\n const relVal = timeRange as RelativeTimeRange;\n extendEndsBy = fromDurationToMillis(relVal.pastDuration) / 2;\n newEnd = typeof relVal.end === 'undefined' ? now : new Date(relVal.end.getTime() + extendEndsBy);\n newStart = new Date(newEnd.getTime() - extendEndsBy * 4);\n }\n if (newEnd.getTime() > now.getTime()) {\n // if the new computed end is in the future\n newEnd = now;\n newStart.setTime(now.getTime() - extendEndsBy * 4);\n }\n if (newStart.getTime() < 1) {\n newStart.setTime(1);\n }\n return { start: newStart, end: newEnd };\n };\n\n // Function to half current time range, cutting 25% before current start and 25% after current end\n const halfTimeRange = (): AbsoluteTimeRange => {\n let newStart, newEnd;\n if (Object.hasOwn(timeRange, 'start')) {\n const absVal = timeRange as AbsoluteTimeRange;\n const shrinkEndsBy = (absVal.end.getTime() - absVal.start.getTime()) / 4;\n newStart = new Date(absVal.start.getTime() + shrinkEndsBy);\n newEnd = new Date(absVal.end.getTime() - shrinkEndsBy);\n } else {\n const relVal = timeRange as RelativeTimeRange;\n const shrinkEndsBy = fromDurationToMillis(relVal.pastDuration) / 4; // 25% of it to cut after current start and before current end\n const endIsAbsolute = typeof relVal.end !== 'undefined';\n newEnd = endIsAbsolute ? new Date(relVal.end!.getTime() - shrinkEndsBy) : new Date();\n newStart = new Date(newEnd.getTime() - shrinkEndsBy * 2);\n }\n if (newStart.getTime() >= newEnd.getTime() - 1000) {\n newStart.setTime(newEnd.getTime() - 1000);\n }\n return { start: newStart, end: newEnd };\n };\n\n const setHalfTimeRange = (): void => setTimeRange(halfTimeRange());\n const setDoubleTimeRange = (): void => setTimeRange(doubleTimeRange());\n\n return (\n <Stack direction=\"row\" spacing={1}>\n {showTimeRangeSelector && (\n <TimeRangeSelector\n timeOptions={timePresetsValue}\n value={timeRange}\n onChange={setTimeRange}\n height={height}\n showCustomTimeRange={showCustomTimeRangeValue}\n />\n )}\n {showZoomInOutButtons && (\n <InfoTooltip description={TOOLTIP_TEXT.zoomOut}>\n <ToolbarIconButton aria-label={TOOLTIP_TEXT.zoomOut} onClick={setDoubleTimeRange} sx={{ height }}>\n <ZoomOut />\n </ToolbarIconButton>\n </InfoTooltip>\n )}\n {showZoomInOutButtons && (\n <InfoTooltip description={TOOLTIP_TEXT.zoomIn}>\n <ToolbarIconButton aria-label={TOOLTIP_TEXT.zoomIn} onClick={setHalfTimeRange} sx={{ height }}>\n <ZoomIn />\n </ToolbarIconButton>\n </InfoTooltip>\n )}\n {showRefreshButton && (\n <InfoTooltip description={TOOLTIP_TEXT.refresh}>\n <ToolbarIconButton aria-label={TOOLTIP_TEXT.refresh} onClick={refresh} sx={{ height }}>\n <RefreshIcon />\n </ToolbarIconButton>\n </InfoTooltip>\n )}\n {showRefreshInterval && (\n <InfoTooltip description={TOOLTIP_TEXT.refreshInterval}>\n <RefreshIntervalPicker\n timeOptions={DEFAULT_REFRESH_INTERVAL_OPTIONS}\n value={refreshInterval}\n onChange={handleRefreshIntervalChange}\n height={height}\n />\n </InfoTooltip>\n )}\n </Stack>\n );\n}\n"],"names":["RefreshIcon","ZoomIn","ZoomOut","Stack","RefreshIntervalPicker","InfoTooltip","ToolbarIconButton","TimeRangeSelector","buildRelativeTimeOption","parseDurationString","useCallback","TOOLTIP_TEXT","useTimeRange","useShowCustomTimeRangeSetting","useTimeRangeOptionsSetting","useShowZoomRangeSetting","DEFAULT_REFRESH_INTERVAL_OPTIONS","value","pastDuration","display","DEFAULT_HEIGHT","TimeRangeControls","heightPx","showTimeRangeSelector","showRefreshButton","showRefreshInterval","showCustomTimeRange","showZoomButtons","timePresets","timeRange","setTimeRange","refresh","refreshInterval","setRefreshInterval","showCustomTimeRangeValue","showZoomInOutButtons","timePresetsValue","height","undefined","some","option","push","handleRefreshIntervalChange","duration","fromDurationToMillis","strDuration","millis","seconds","minutes","hours","days","weeks","months","years","doubleTimeRange","newStart","newEnd","extendEndsBy","now","Date","Object","hasOwn","absVal","end","getTime","start","relVal","setTime","halfTimeRange","shrinkEndsBy","endIsAbsolute","setHalfTimeRange","setDoubleTimeRange","direction","spacing","timeOptions","onChange","description","zoomOut","aria-label","onClick","sx","zoomIn"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/TimeRangeControls/TimeRangeControls.tsx"],"sourcesContent":["// Copyright 2024 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 RefreshIcon from 'mdi-material-ui/Refresh';\n// eslint-disable-next-line import/no-duplicates\nimport ZoomIn from 'mdi-material-ui/PlusCircleOutline';\n// eslint-disable-next-line import/no-duplicates\nimport ZoomOut from 'mdi-material-ui/MinusCircleOutline';\nimport { Stack } from '@mui/material';\nimport {\n RefreshIntervalPicker,\n InfoTooltip,\n TimeOption,\n ToolbarIconButton,\n TimeRangeSelector,\n buildRelativeTimeOption,\n} from '@perses-dev/components';\nimport { AbsoluteTimeRange, DurationString, parseDurationString, RelativeTimeRange } from '@perses-dev/core';\nimport { ReactElement, useCallback } from 'react';\nimport { TOOLTIP_TEXT } from '../../constants';\nimport {\n useTimeRange,\n useShowCustomTimeRangeSetting,\n useTimeRangeOptionsSetting,\n useShowZoomRangeSetting,\n} from '../../runtime';\n\nexport const DEFAULT_REFRESH_INTERVAL_OPTIONS: TimeOption[] = [\n { value: { pastDuration: '0s' }, display: 'Off' },\n { value: { pastDuration: '5s' }, display: '5s' },\n { value: { pastDuration: '10s' }, display: '10s' },\n { value: { pastDuration: '15s' }, display: '15s' },\n { value: { pastDuration: '30s' }, display: '30s' },\n { value: { pastDuration: '60s' }, display: '1m' },\n];\n\nconst DEFAULT_HEIGHT = '34px';\n\ninterface TimeRangeControlsProps {\n // The controls look best at heights >= 28 pixels\n heightPx?: number;\n showTimeRangeSelector?: boolean;\n showRefreshButton?: boolean;\n showRefreshInterval?: boolean;\n showCustomTimeRange?: boolean;\n showZoomButtons?: boolean;\n timePresets?: TimeOption[];\n}\n\nexport function TimeRangeControls({\n heightPx,\n showTimeRangeSelector = true,\n showRefreshButton = true,\n showRefreshInterval = true,\n showCustomTimeRange,\n showZoomButtons = true,\n timePresets,\n}: TimeRangeControlsProps): ReactElement {\n const { timeRange, setTimeRange, refresh, refreshInterval, setRefreshInterval } = useTimeRange();\n\n const showCustomTimeRangeValue = useShowCustomTimeRangeSetting(showCustomTimeRange);\n const showZoomInOutButtons = useShowZoomRangeSetting(showZoomButtons);\n const timePresetsValue = useTimeRangeOptionsSetting(timePresets);\n\n // Convert height to a string, then use the string for styling\n const height = heightPx === undefined ? DEFAULT_HEIGHT : `${heightPx}px`;\n\n // add time preset if one does not match duration given in time range\n if (\n 'pastDuration' in timeRange &&\n !timePresetsValue.some((option) => option.value.pastDuration === timeRange['pastDuration'])\n ) {\n timePresetsValue.push(buildRelativeTimeOption(timeRange['pastDuration']));\n }\n\n // set the new refresh interval both in the dashboard context & as query param\n const handleRefreshIntervalChange = useCallback(\n (duration: DurationString) => {\n setRefreshInterval(duration);\n },\n [setRefreshInterval]\n );\n\n const fromDurationToMillis = (strDuration: string): number => {\n const duration = parseDurationString(strDuration);\n const millis =\n // eslint-disable-next-line prettier/prettier\n ((duration.seconds ?? 0) +\n (duration.minutes ?? 0) * 60 +\n (duration.hours ?? 0) * 3600 +\n (duration.days ?? 0) * 86400 +\n (duration.weeks ?? 0) * 7 * 86400 +\n (duration.months ?? 0) * 30.436875 * 86400 + // avg month duration is ok for zoom purposes\n (duration.years ?? 0) * 365.2425 * 86400) * // avg year duration is ok for zoom purposes\n // eslint-disable-next-line prettier/prettier\n 1000; // to milliseconds\n return millis;\n };\n\n // Function to double current time range, adding 50% before current start and 50% after current end\n const doubleTimeRange = (): AbsoluteTimeRange => {\n let newStart, newEnd, extendEndsBy;\n const now = new Date();\n if (Object.hasOwn(timeRange, 'start')) {\n // current range is absolute\n const absVal = timeRange as AbsoluteTimeRange;\n extendEndsBy = (absVal.end.getTime() - absVal.start.getTime()) / 2; // half it to add 50% before current start and after current end\n newStart = new Date(absVal.start.getTime() - extendEndsBy);\n newEnd = new Date(absVal.end.getTime() + extendEndsBy);\n } else {\n // current range is relative\n const relVal = timeRange as RelativeTimeRange;\n extendEndsBy = fromDurationToMillis(relVal.pastDuration) / 2;\n newEnd = typeof relVal.end === 'undefined' ? now : new Date(relVal.end.getTime() + extendEndsBy);\n newStart = new Date(newEnd.getTime() - extendEndsBy * 4);\n }\n if (newEnd.getTime() > now.getTime()) {\n // if the new computed end is in the future\n newEnd = now;\n newStart.setTime(now.getTime() - extendEndsBy * 4);\n }\n if (newStart.getTime() < 1) {\n newStart.setTime(1);\n }\n return { start: newStart, end: newEnd };\n };\n\n // Function to half current time range, cutting 25% before current start and 25% after current end\n const halfTimeRange = (): AbsoluteTimeRange => {\n let newStart, newEnd;\n if (Object.hasOwn(timeRange, 'start')) {\n const absVal = timeRange as AbsoluteTimeRange;\n const shrinkEndsBy = (absVal.end.getTime() - absVal.start.getTime()) / 4;\n newStart = new Date(absVal.start.getTime() + shrinkEndsBy);\n newEnd = new Date(absVal.end.getTime() - shrinkEndsBy);\n } else {\n const relVal = timeRange as RelativeTimeRange;\n const shrinkEndsBy = fromDurationToMillis(relVal.pastDuration) / 4; // 25% of it to cut after current start and before current end\n const endIsAbsolute = typeof relVal.end !== 'undefined';\n newEnd = endIsAbsolute ? new Date(relVal.end!.getTime() - shrinkEndsBy) : new Date();\n newStart = new Date(newEnd.getTime() - shrinkEndsBy * 2);\n }\n if (newStart.getTime() >= newEnd.getTime() - 1000) {\n newStart.setTime(newEnd.getTime() - 1000);\n }\n return { start: newStart, end: newEnd };\n };\n\n const setHalfTimeRange = (): void => setTimeRange(halfTimeRange());\n const setDoubleTimeRange = (): void => setTimeRange(doubleTimeRange());\n\n return (\n <Stack direction=\"row\" spacing={1}>\n {showTimeRangeSelector && (\n <TimeRangeSelector\n timeOptions={timePresetsValue}\n value={timeRange}\n onChange={setTimeRange}\n height={height}\n showCustomTimeRange={showCustomTimeRangeValue}\n />\n )}\n {showZoomInOutButtons && (\n <InfoTooltip description={TOOLTIP_TEXT.zoomOut}>\n <ToolbarIconButton aria-label={TOOLTIP_TEXT.zoomOut} onClick={setDoubleTimeRange} sx={{ height }}>\n <ZoomOut />\n </ToolbarIconButton>\n </InfoTooltip>\n )}\n {showZoomInOutButtons && (\n <InfoTooltip description={TOOLTIP_TEXT.zoomIn}>\n <ToolbarIconButton aria-label={TOOLTIP_TEXT.zoomIn} onClick={setHalfTimeRange} sx={{ height }}>\n <ZoomIn />\n </ToolbarIconButton>\n </InfoTooltip>\n )}\n {showRefreshButton && (\n <InfoTooltip description={TOOLTIP_TEXT.refresh}>\n <ToolbarIconButton aria-label={TOOLTIP_TEXT.refresh} onClick={refresh} sx={{ height }}>\n <RefreshIcon />\n </ToolbarIconButton>\n </InfoTooltip>\n )}\n {showRefreshInterval && (\n <InfoTooltip description={TOOLTIP_TEXT.refreshInterval}>\n <RefreshIntervalPicker\n timeOptions={DEFAULT_REFRESH_INTERVAL_OPTIONS}\n value={refreshInterval}\n onChange={handleRefreshIntervalChange}\n height={height}\n />\n </InfoTooltip>\n )}\n </Stack>\n );\n}\n"],"names":["RefreshIcon","ZoomIn","ZoomOut","Stack","RefreshIntervalPicker","InfoTooltip","ToolbarIconButton","TimeRangeSelector","buildRelativeTimeOption","parseDurationString","useCallback","TOOLTIP_TEXT","useTimeRange","useShowCustomTimeRangeSetting","useTimeRangeOptionsSetting","useShowZoomRangeSetting","DEFAULT_REFRESH_INTERVAL_OPTIONS","value","pastDuration","display","DEFAULT_HEIGHT","TimeRangeControls","heightPx","showTimeRangeSelector","showRefreshButton","showRefreshInterval","showCustomTimeRange","showZoomButtons","timePresets","timeRange","setTimeRange","refresh","refreshInterval","setRefreshInterval","showCustomTimeRangeValue","showZoomInOutButtons","timePresetsValue","height","undefined","some","option","push","handleRefreshIntervalChange","duration","fromDurationToMillis","strDuration","millis","seconds","minutes","hours","days","weeks","months","years","doubleTimeRange","newStart","newEnd","extendEndsBy","now","Date","Object","hasOwn","absVal","end","getTime","start","relVal","setTime","halfTimeRange","shrinkEndsBy","endIsAbsolute","setHalfTimeRange","setDoubleTimeRange","direction","spacing","timeOptions","onChange","description","zoomOut","aria-label","onClick","sx","zoomIn"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"VariableEditorForm.d.ts","sourceRoot":"","sources":["../../../../src/components/Variables/VariableEditorForm/VariableEditorForm.tsx"],"names":[],"mappings":"AAaA,OAAc,EAAE,qBAAqB,EAAE,YAAY,EAAY,MAAM,OAAO,CAAC;AAa7E,OAAO,EAAE,kBAAkB,EAA0B,MAAM,EAAE,MAAM,kBAAkB,CAAC;AA4TtF,UAAU,uBAAuB;IAC/B,yBAAyB,EAAE,kBAAkB,CAAC;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,MAAM,EAAE,CAAC,GAAG,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAClC;AAED,wBAAgB,kBAAkB,CAAC,EACjC,yBAAyB,EACzB,MAAM,EACN,OAAO,EACP,UAAU,EACV,cAAc,EACd,MAAM,EACN,OAAO,EACP,QAAQ,GACT,EAAE,uBAAuB,GAAG,YAAY,CAoMxC"}
1
+ {"version":3,"file":"VariableEditorForm.d.ts","sourceRoot":"","sources":["../../../../src/components/Variables/VariableEditorForm/VariableEditorForm.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAY,MAAM,OAAO,CAAC;AAEtE,OAAO,EAAE,kBAAkB,EAA0B,MAAM,EAAE,MAAM,kBAAkB,CAAC;AA0TtF,UAAU,uBAAuB;IAC/B,yBAAyB,EAAE,kBAAkB,CAAC;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,MAAM,EAAE,CAAC,GAAG,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAClC;AAED,wBAAgB,kBAAkB,CAAC,EACjC,yBAAyB,EACzB,MAAM,EACN,OAAO,EACP,UAAU,EACV,cAAc,EACd,MAAM,EACN,OAAO,EACP,QAAQ,GACT,EAAE,uBAAuB,GAAG,YAAY,CAoMxC"}