@perses-dev/tempo-plugin 0.57.0 → 0.57.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.
Files changed (54) hide show
  1. package/__mf/js/{Tempo.a15c7ca4.js → Tempo.6c9a48e0.js} +5 -5
  2. package/__mf/js/async/{1728.988e2b29.js → 1728.67c7a01e.js} +1 -1
  3. package/__mf/js/async/3.6db4a205.js +4 -0
  4. package/__mf/js/async/3208.47804c05.js +2 -0
  5. package/__mf/js/async/54.0f34f4f8.js +22 -0
  6. package/__mf/js/async/9811.b4b6d8ee.js +7 -0
  7. package/__mf/js/async/__federation_expose_TempoDatasource.a723b8ee.js +2 -0
  8. package/__mf/js/async/{__federation_expose_TempoExplorer.003c9970.js → __federation_expose_TempoExplorer.8d4424e2.js} +1 -1
  9. package/__mf/js/async/__federation_expose_TempoTraceQuery.629ec38d.js +1 -0
  10. package/__mf/js/{main.6a6654b6.js → main.019cca86.js} +3 -3
  11. package/lib/cjs/components/AttributeFilters.js +76 -51
  12. package/lib/cjs/components/complete.js +3 -3
  13. package/lib/cjs/components/filter/filter.js +2 -2
  14. package/lib/cjs/components/filter/filter_to_traceql.js +1 -1
  15. package/lib/cjs/components/filter/traceql_to_filter.js +5 -5
  16. package/lib/cjs/plugins/tempo-trace-query/TempoTraceQueryEditor.js +1 -1
  17. package/lib/cjs/plugins/tempo-trace-query/get-trace-data.js +6 -7
  18. package/lib/components/AttributeFilters.d.ts.map +1 -1
  19. package/lib/components/AttributeFilters.js +72 -47
  20. package/lib/components/AttributeFilters.js.map +1 -1
  21. package/lib/components/ClosableAlert.d.ts +2 -1
  22. package/lib/components/ClosableAlert.d.ts.map +1 -1
  23. package/lib/components/ClosableAlert.js.map +1 -1
  24. package/lib/components/complete.js +1 -1
  25. package/lib/components/complete.js.map +1 -1
  26. package/lib/components/filter/filter.d.ts.map +1 -1
  27. package/lib/components/filter/filter.js +2 -2
  28. package/lib/components/filter/filter.js.map +1 -1
  29. package/lib/components/filter/filter_to_traceql.d.ts.map +1 -1
  30. package/lib/components/filter/filter_to_traceql.js +1 -1
  31. package/lib/components/filter/filter_to_traceql.js.map +1 -1
  32. package/lib/components/filter/traceql_to_filter.js +5 -5
  33. package/lib/components/filter/traceql_to_filter.js.map +1 -1
  34. package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.d.ts +1 -1
  35. package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.d.ts.map +1 -1
  36. package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.js +1 -1
  37. package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.js.map +1 -1
  38. package/lib/plugins/tempo-trace-query/get-trace-data.d.ts.map +1 -1
  39. package/lib/plugins/tempo-trace-query/get-trace-data.js +6 -7
  40. package/lib/plugins/tempo-trace-query/get-trace-data.js.map +1 -1
  41. package/mf-manifest.json +24 -24
  42. package/mf-stats.json +26 -31
  43. package/package.json +6 -6
  44. package/__mf/js/async/1905.d3c01a20.js +0 -2
  45. package/__mf/js/async/2545.d42b194b.js +0 -2
  46. package/__mf/js/async/54.812deb71.js +0 -22
  47. package/__mf/js/async/7958.4ba5d596.js +0 -7
  48. package/__mf/js/async/__federation_expose_TempoDatasource.1f9ab43f.js +0 -2
  49. package/__mf/js/async/__federation_expose_TempoTraceQuery.eff34861.js +0 -1
  50. /package/__mf/js/async/{1905.d3c01a20.js.LICENSE.txt → 3.6db4a205.js.LICENSE.txt} +0 -0
  51. /package/__mf/js/async/{2545.d42b194b.js.LICENSE.txt → 3208.47804c05.js.LICENSE.txt} +0 -0
  52. /package/__mf/js/async/{54.812deb71.js.LICENSE.txt → 54.0f34f4f8.js.LICENSE.txt} +0 -0
  53. /package/__mf/js/async/{7958.4ba5d596.js.LICENSE.txt → 9811.b4b6d8ee.js.LICENSE.txt} +0 -0
  54. /package/__mf/js/async/{__federation_expose_TempoDatasource.1f9ab43f.js.LICENSE.txt → __federation_expose_TempoDatasource.a723b8ee.js.LICENSE.txt} +0 -0
@@ -25,10 +25,8 @@ const _react = require("react");
25
25
  const _material = require("@mui/material");
26
26
  const _pluginsystem = require("@perses-dev/plugin-system");
27
27
  const _reactquery = require("@tanstack/react-query");
28
- const _gettracedata = require("../plugins/tempo-trace-query/get-trace-data");
29
- const _filter_to_traceql = require("./filter/filter_to_traceql");
30
- const _traceql_to_filter = require("./filter/traceql_to_filter");
31
- const _filter = require("./filter/filter");
28
+ const _plugins = require("../plugins");
29
+ const _filter = require("./filter");
32
30
  const statusOptions = [
33
31
  'unset',
34
32
  'ok',
@@ -36,65 +34,92 @@ const statusOptions = [
36
34
  ];
37
35
  function AttributeFilters(props) {
38
36
  const { client, query, setQuery } = props;
39
- const filter = (0, _traceql_to_filter.traceQLToFilter)(query);
37
+ const filter = (0, _filter.traceQLToFilter)(query);
40
38
  const setFilter = (filter)=>{
41
- setQuery((0, _filter_to_traceql.filterToTraceQL)(filter));
39
+ setQuery((0, _filter.filterToTraceQL)(filter));
42
40
  };
43
41
  const { absoluteTimeRange } = (0, _pluginsystem.useTimeRange)();
44
- const { start, end } = (0, _gettracedata.getUnixTimeRange)(absoluteTimeRange);
45
- const { data: serviceNameOptions } = useTagValues(client, 'resource.service.name', (0, _filter_to_traceql.filterToTraceQL)({
42
+ const { start, end } = (0, _plugins.getUnixTimeRange)(absoluteTimeRange);
43
+ const { data: serviceNameOptions } = useTagValues(client, 'resource.service.name', (0, _filter.filterToTraceQL)({
46
44
  ...filter,
47
45
  serviceName: []
48
46
  }), start, end);
49
- const { data: spanNameOptions } = useTagValues(client, 'name', (0, _filter_to_traceql.filterToTraceQL)({
47
+ const { data: spanNameOptions } = useTagValues(client, 'name', (0, _filter.filterToTraceQL)({
50
48
  ...filter,
51
49
  spanName: []
52
50
  }), start, end);
53
- return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
51
+ return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Stack, {
52
+ direction: "column",
53
+ flex: 1,
54
+ gap: 1,
54
55
  children: [
55
- /*#__PURE__*/ (0, _jsxruntime.jsx)(StringAttributeFilter, {
56
- label: "Service Name",
57
- options: serviceNameOptions ?? [],
58
- value: filter.serviceName,
59
- setValue: (x)=>setFilter({
60
- ...filter,
61
- serviceName: x
62
- })
63
- }),
64
- /*#__PURE__*/ (0, _jsxruntime.jsx)(StringAttributeFilter, {
65
- label: "Span Name",
66
- options: spanNameOptions ?? [],
67
- value: filter.spanName,
68
- setValue: (x)=>setFilter({
69
- ...filter,
70
- spanName: x
71
- })
72
- }),
73
- /*#__PURE__*/ (0, _jsxruntime.jsx)(StringAttributeFilter, {
74
- label: "Status",
75
- width: 210,
76
- options: statusOptions ?? [],
77
- value: filter.status,
78
- setValue: (x)=>setFilter({
79
- ...filter,
80
- status: x
81
- })
82
- }),
83
- /*#__PURE__*/ (0, _jsxruntime.jsx)(DurationAttributeFilter, {
84
- label: "Trace Duration",
85
- value: filter.traceDuration,
86
- setValue: (value)=>setFilter({
87
- ...filter,
88
- traceDuration: value
56
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Stack, {
57
+ direction: "row",
58
+ flex: 1,
59
+ gap: 1,
60
+ sx: {
61
+ '& > *:nth-of-type(1)': {
62
+ flex: 2
63
+ },
64
+ '& > *:nth-of-type(2)': {
65
+ flex: 2
66
+ },
67
+ '& > *:nth-of-type(3)': {
68
+ flex: 1
69
+ }
70
+ },
71
+ children: [
72
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(StringAttributeFilter, {
73
+ label: "Service Name",
74
+ options: serviceNameOptions ?? [],
75
+ value: filter.serviceName,
76
+ setValue: (x)=>setFilter({
77
+ ...filter,
78
+ serviceName: x
79
+ })
80
+ }),
81
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(StringAttributeFilter, {
82
+ label: "Span Name",
83
+ options: spanNameOptions ?? [],
84
+ value: filter.spanName,
85
+ setValue: (x)=>setFilter({
86
+ ...filter,
87
+ spanName: x
88
+ })
89
+ }),
90
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(StringAttributeFilter, {
91
+ label: "Status",
92
+ options: statusOptions ?? [],
93
+ value: filter.status,
94
+ setValue: (x)=>setFilter({
95
+ ...filter,
96
+ status: x
97
+ })
89
98
  })
99
+ ]
90
100
  }),
91
- /*#__PURE__*/ (0, _jsxruntime.jsx)(CustomAttributesFilter, {
92
- label: "Custom Attributes",
93
- value: filter.customMatchers,
94
- setValue: (value)=>setFilter({
95
- ...filter,
96
- customMatchers: value
101
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Stack, {
102
+ direction: "row",
103
+ flex: 1,
104
+ gap: 1,
105
+ children: [
106
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(DurationAttributeFilter, {
107
+ label: "Trace Duration",
108
+ value: filter.traceDuration,
109
+ setValue: (value)=>setFilter({
110
+ ...filter,
111
+ traceDuration: value
112
+ })
113
+ }),
114
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(CustomAttributesFilter, {
115
+ label: "Custom Attributes",
116
+ value: filter.customMatchers,
117
+ setValue: (value)=>setFilter({
118
+ ...filter,
119
+ customMatchers: value
120
+ })
97
121
  })
122
+ ]
98
123
  })
99
124
  ]
100
125
  });
@@ -203,7 +228,7 @@ function CustomAttributesFilter(props) {
203
228
  /** A <TextField> which calls props.setValue when the input field is blurred and the validation passes. */ function LazyTextInput(props) {
204
229
  const { validationRegex, validationFailedMessage, value, setValue, ...otherProps } = props;
205
230
  const [draftValue, setDraftValue] = (0, _react.useState)(value);
206
- const isValidInput = draftValue == '' || validationRegex == undefined || validationRegex.test(draftValue);
231
+ const isValidInput = draftValue === '' || validationRegex === undefined || validationRegex.test(draftValue);
207
232
  (0, _react.useEffect)(()=>{
208
233
  setDraftValue(value);
209
234
  }, [
@@ -34,7 +34,7 @@ _export(exports, {
34
34
  const _autocomplete = require("@codemirror/autocomplete");
35
35
  const _language = require("@codemirror/language");
36
36
  const _lezertraceql = require("@grafana/lezer-traceql");
37
- const _tempotracequery = require("../plugins/tempo-trace-query");
37
+ const _plugins = require("../plugins");
38
38
  const quoteChars = [
39
39
  '"',
40
40
  '`'
@@ -294,7 +294,7 @@ async function completeTagName(completionCfg, scope) {
294
294
  if (!completionCfg.client) {
295
295
  return [];
296
296
  }
297
- const { start, end } = completionCfg.timeRange ? (0, _tempotracequery.getUnixTimeRange)(completionCfg.timeRange) : {};
297
+ const { start, end } = completionCfg.timeRange ? (0, _plugins.getUnixTimeRange)(completionCfg.timeRange) : {};
298
298
  const { limit, maxStaleValues } = completionCfg;
299
299
  const response = await completionCfg.client.searchTags({
300
300
  scope,
@@ -340,7 +340,7 @@ async function completeTagValue(completionCfg, tag) {
340
340
  if (!completionCfg.client) {
341
341
  return [];
342
342
  }
343
- const { start, end } = completionCfg.timeRange ? (0, _tempotracequery.getUnixTimeRange)(completionCfg.timeRange) : {};
343
+ const { start, end } = completionCfg.timeRange ? (0, _plugins.getUnixTimeRange)(completionCfg.timeRange) : {};
344
344
  const { limit, maxStaleValues } = completionCfg;
345
345
  const response = await completionCfg.client.searchTagValues({
346
346
  tag,
@@ -25,9 +25,9 @@ function splitByUnquotedWhitespace(x) {
25
25
  let from = 0;
26
26
  const chunks = [];
27
27
  for(let i = 0; i < x.length; i++){
28
- if (x[i] == '"' && x[i - 1] != '\\') {
28
+ if (x[i] === '"' && x[i - 1] !== '\\') {
29
29
  quote = !quote;
30
- } else if (x[i] == ' ' && !quote) {
30
+ } else if (x[i] === ' ' && !quote) {
31
31
  chunks.push(x.slice(from, i));
32
32
  from = i + 1;
33
33
  }
@@ -44,7 +44,7 @@ function stringMatcher(attribute, values) {
44
44
  return [
45
45
  `${attribute} =~ "${escapedValues.join('|')}"`
46
46
  ];
47
- } else if (escapedValues.length == 1) {
47
+ } else if (escapedValues.length === 1) {
48
48
  return [
49
49
  `${attribute} = "${escapedValues[0]}"`
50
50
  ];
@@ -83,9 +83,9 @@ function reverseStringMatcher(matches) {
83
83
  const values = [];
84
84
  for (const { operator, value } of matches ?? []){
85
85
  const unescaped = unescape(value.slice(1, -1));
86
- if (operator == '=') {
86
+ if (operator === '=') {
87
87
  values.push(unescaped);
88
- } else if (operator == '=~') {
88
+ } else if (operator === '=~') {
89
89
  values.push(...unescaped.split('|'));
90
90
  }
91
91
  }
@@ -94,7 +94,7 @@ function reverseStringMatcher(matches) {
94
94
  function reverseIntrinsicMatcher(matches) {
95
95
  const values = [];
96
96
  for (const { operator, value } of matches ?? []){
97
- if (operator == '=') {
97
+ if (operator === '=') {
98
98
  values.push(value);
99
99
  }
100
100
  }
@@ -103,9 +103,9 @@ function reverseIntrinsicMatcher(matches) {
103
103
  function reverseDurationMatcher(matches) {
104
104
  const duration = {};
105
105
  for (const { operator, value } of matches ?? []){
106
- if (operator == '>=') {
106
+ if (operator === '>=') {
107
107
  duration.min = value;
108
- } else if (operator == '<=') {
108
+ } else if (operator === '<=') {
109
109
  duration.max = value;
110
110
  }
111
111
  }
@@ -116,7 +116,7 @@ function TempoTraceQueryEditor(props) {
116
116
  }
117
117
  function isSimpleTraceQLQuery(query) {
118
118
  // if a query can be transformed to a filter and back to the original query, we can show the attribute filter toolbar
119
- return query == '' || (0, _components1.filterToTraceQL)((0, _components1.traceQLToFilter)(query)) === query;
119
+ return query === '' || (0, _components1.filterToTraceQL)((0, _components1.traceQLToFilter)(query)) === query;
120
120
  }
121
121
  const limitOptions = [
122
122
  20,
@@ -32,7 +32,6 @@ const _core = require("@perses-dev/core");
32
32
  const _pluginsystem = require("@perses-dev/plugin-system");
33
33
  const _datefns = require("date-fns");
34
34
  const _model = require("../../model");
35
- const _apitypes = require("../../model/api-types");
36
35
  function getUnixTimeRange(timeRange) {
37
36
  const { start, end } = timeRange;
38
37
  return {
@@ -80,7 +79,7 @@ const getTraceData = async (spec, context)=>{
80
79
  }
81
80
  // Fetch one more trace than requested.
82
81
  // This way we can check if there are more traces available matching the search request, and show a notice to the user.
83
- const limit = spec.limit ?? _apitypes.DEFAULT_SEARCH_LIMIT;
82
+ const limit = spec.limit ?? _model.DEFAULT_SEARCH_LIMIT;
84
83
  params.limit = limit + 1;
85
84
  const response = await client.searchWithFallback(params);
86
85
  const searchResult = parseSearchResponse(response);
@@ -115,20 +114,20 @@ function parseTraceResponse(response) {
115
114
  for (const resourceSpan of trace.resourceSpans){
116
115
  for (const scopeSpan of resourceSpan.scopeSpans){
117
116
  for (const span of scopeSpan.spans){
118
- if (span.traceId.length != 32) {
117
+ if (span.traceId.length !== 32) {
119
118
  span.traceId = base64ToHex(span.traceId);
120
119
  }
121
- if (span.spanId.length != 16) {
120
+ if (span.spanId.length !== 16) {
122
121
  span.spanId = base64ToHex(span.spanId);
123
122
  }
124
- if (span.parentSpanId && span.parentSpanId.length != 16) {
123
+ if (span.parentSpanId && span.parentSpanId.length !== 16) {
125
124
  span.parentSpanId = base64ToHex(span.parentSpanId);
126
125
  }
127
126
  for (const link of span.links ?? []){
128
- if (link.traceId.length != 32) {
127
+ if (link.traceId.length !== 32) {
129
128
  link.traceId = base64ToHex(link.traceId);
130
129
  }
131
- if (link.spanId.length != 16) {
130
+ if (link.spanId.length !== 16) {
132
131
  link.spanId = base64ToHex(link.spanId);
133
132
  }
134
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AttributeFilters.d.ts","sourceRoot":"","sources":["../../../src/components/AttributeFilters.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAoD,MAAM,OAAO,CAAC;AAIvF,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAQvC,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,CA2D3E"}
1
+ {"version":3,"file":"AttributeFilters.d.ts","sourceRoot":"","sources":["../../../src/components/AttributeFilters.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAoD,MAAM,OAAO,CAAC;AAIvF,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAMvC,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,CAuE3E"}
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // Copyright The Perses Authors
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -15,10 +15,8 @@ import { useCallback, useEffect, useState } from 'react';
15
15
  import { Autocomplete, Checkbox, Stack, TextField } from '@mui/material';
16
16
  import { useTimeRange } from '@perses-dev/plugin-system';
17
17
  import { useQuery } from '@tanstack/react-query';
18
- import { getUnixTimeRange } from '../plugins/tempo-trace-query/get-trace-data';
19
- import { filterToTraceQL } from './filter/filter_to_traceql';
20
- import { traceQLToFilter } from './filter/traceql_to_filter';
21
- import { splitByUnquotedWhitespace } from './filter/filter';
18
+ import { getUnixTimeRange } from '../plugins';
19
+ import { filterToTraceQL, traceQLToFilter, splitByUnquotedWhitespace } from './filter';
22
20
  const statusOptions = [
23
21
  'unset',
24
22
  'ok',
@@ -40,51 +38,78 @@ export function AttributeFilters(props) {
40
38
  ...filter,
41
39
  spanName: []
42
40
  }), start, end);
43
- return /*#__PURE__*/ _jsxs(_Fragment, {
41
+ return /*#__PURE__*/ _jsxs(Stack, {
42
+ direction: "column",
43
+ flex: 1,
44
+ gap: 1,
44
45
  children: [
45
- /*#__PURE__*/ _jsx(StringAttributeFilter, {
46
- label: "Service Name",
47
- options: serviceNameOptions ?? [],
48
- value: filter.serviceName,
49
- setValue: (x)=>setFilter({
50
- ...filter,
51
- serviceName: x
52
- })
53
- }),
54
- /*#__PURE__*/ _jsx(StringAttributeFilter, {
55
- label: "Span Name",
56
- options: spanNameOptions ?? [],
57
- value: filter.spanName,
58
- setValue: (x)=>setFilter({
59
- ...filter,
60
- spanName: x
61
- })
62
- }),
63
- /*#__PURE__*/ _jsx(StringAttributeFilter, {
64
- label: "Status",
65
- width: 210,
66
- options: statusOptions ?? [],
67
- value: filter.status,
68
- setValue: (x)=>setFilter({
69
- ...filter,
70
- status: x
71
- })
72
- }),
73
- /*#__PURE__*/ _jsx(DurationAttributeFilter, {
74
- label: "Trace Duration",
75
- value: filter.traceDuration,
76
- setValue: (value)=>setFilter({
77
- ...filter,
78
- traceDuration: value
46
+ /*#__PURE__*/ _jsxs(Stack, {
47
+ direction: "row",
48
+ flex: 1,
49
+ gap: 1,
50
+ sx: {
51
+ '& > *:nth-of-type(1)': {
52
+ flex: 2
53
+ },
54
+ '& > *:nth-of-type(2)': {
55
+ flex: 2
56
+ },
57
+ '& > *:nth-of-type(3)': {
58
+ flex: 1
59
+ }
60
+ },
61
+ children: [
62
+ /*#__PURE__*/ _jsx(StringAttributeFilter, {
63
+ label: "Service Name",
64
+ options: serviceNameOptions ?? [],
65
+ value: filter.serviceName,
66
+ setValue: (x)=>setFilter({
67
+ ...filter,
68
+ serviceName: x
69
+ })
70
+ }),
71
+ /*#__PURE__*/ _jsx(StringAttributeFilter, {
72
+ label: "Span Name",
73
+ options: spanNameOptions ?? [],
74
+ value: filter.spanName,
75
+ setValue: (x)=>setFilter({
76
+ ...filter,
77
+ spanName: x
78
+ })
79
+ }),
80
+ /*#__PURE__*/ _jsx(StringAttributeFilter, {
81
+ label: "Status",
82
+ options: statusOptions ?? [],
83
+ value: filter.status,
84
+ setValue: (x)=>setFilter({
85
+ ...filter,
86
+ status: x
87
+ })
79
88
  })
89
+ ]
80
90
  }),
81
- /*#__PURE__*/ _jsx(CustomAttributesFilter, {
82
- label: "Custom Attributes",
83
- value: filter.customMatchers,
84
- setValue: (value)=>setFilter({
85
- ...filter,
86
- customMatchers: value
91
+ /*#__PURE__*/ _jsxs(Stack, {
92
+ direction: "row",
93
+ flex: 1,
94
+ gap: 1,
95
+ children: [
96
+ /*#__PURE__*/ _jsx(DurationAttributeFilter, {
97
+ label: "Trace Duration",
98
+ value: filter.traceDuration,
99
+ setValue: (value)=>setFilter({
100
+ ...filter,
101
+ traceDuration: value
102
+ })
103
+ }),
104
+ /*#__PURE__*/ _jsx(CustomAttributesFilter, {
105
+ label: "Custom Attributes",
106
+ value: filter.customMatchers,
107
+ setValue: (value)=>setFilter({
108
+ ...filter,
109
+ customMatchers: value
110
+ })
87
111
  })
112
+ ]
88
113
  })
89
114
  ]
90
115
  });
@@ -193,7 +218,7 @@ function CustomAttributesFilter(props) {
193
218
  /** A <TextField> which calls props.setValue when the input field is blurred and the validation passes. */ function LazyTextInput(props) {
194
219
  const { validationRegex, validationFailedMessage, value, setValue, ...otherProps } = props;
195
220
  const [draftValue, setDraftValue] = useState(value);
196
- const isValidInput = draftValue == '' || validationRegex == undefined || validationRegex.test(draftValue);
221
+ const isValidInput = draftValue === '' || validationRegex === undefined || validationRegex.test(draftValue);
197
222
  useEffect(()=>{
198
223
  setDraftValue(value);
199
224
  }, [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/AttributeFilters.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ReactElement, SyntheticEvent, useCallback, useEffect, useState } from 'react';\nimport { Autocomplete, Checkbox, Stack, TextField, TextFieldProps } from '@mui/material';\nimport { useTimeRange } from '@perses-dev/plugin-system';\nimport { useQuery } from '@tanstack/react-query';\nimport { TempoClient } from '../model';\nimport { getUnixTimeRange } from '../plugins/tempo-trace-query/get-trace-data';\nimport { filterToTraceQL } from './filter/filter_to_traceql';\nimport { traceQLToFilter } from './filter/traceql_to_filter';\nimport { DurationField, Filter, splitByUnquotedWhitespace } from './filter/filter';\n\nconst statusOptions = ['unset', 'ok', 'error'];\n\nexport interface AttributeFiltersProps {\n client?: TempoClient;\n query: string;\n setQuery: (x: string) => void;\n}\n\nexport function AttributeFilters(props: AttributeFiltersProps): ReactElement {\n const { client, query, setQuery } = props;\n\n const filter = traceQLToFilter(query);\n const setFilter = (filter: Filter) => {\n setQuery(filterToTraceQL(filter));\n };\n\n const { absoluteTimeRange } = useTimeRange();\n const { start, end } = getUnixTimeRange(absoluteTimeRange);\n\n const { data: serviceNameOptions } = useTagValues(\n client,\n 'resource.service.name',\n filterToTraceQL({ ...filter, serviceName: [] }),\n start,\n end\n );\n const { data: spanNameOptions } = useTagValues(\n client,\n 'name',\n filterToTraceQL({ ...filter, spanName: [] }),\n start,\n end\n );\n\n return (\n <>\n <StringAttributeFilter\n label=\"Service Name\"\n options={serviceNameOptions ?? []}\n value={filter.serviceName}\n setValue={(x) => setFilter({ ...filter, serviceName: x })}\n />\n <StringAttributeFilter\n label=\"Span Name\"\n options={spanNameOptions ?? []}\n value={filter.spanName}\n setValue={(x) => setFilter({ ...filter, spanName: x })}\n />\n <StringAttributeFilter\n label=\"Status\"\n width={210}\n options={statusOptions ?? []}\n value={filter.status}\n setValue={(x) => setFilter({ ...filter, status: x })}\n />\n <DurationAttributeFilter\n label=\"Trace Duration\"\n value={filter.traceDuration}\n setValue={(value) => setFilter({ ...filter, traceDuration: value })}\n />\n <CustomAttributesFilter\n label=\"Custom Attributes\"\n value={filter.customMatchers}\n setValue={(value) => setFilter({ ...filter, customMatchers: value })}\n />\n </>\n );\n}\n\ninterface StringAttributeFilterProps {\n label: string;\n width?: number;\n options: string[];\n value: string[];\n setValue: (value: string[]) => void;\n}\n\nfunction StringAttributeFilter(props: StringAttributeFilterProps) {\n const { label, width, options, value, setValue } = props;\n\n return (\n <Autocomplete\n multiple\n size=\"small\"\n limitTags={1}\n disableCloseOnSelect\n value={value}\n onChange={(_event: SyntheticEvent, newValue: string[]) => setValue(newValue)}\n options={options}\n renderOption={(props, option, { selected }) => {\n const { key, ...optionProps } = props;\n return (\n <li key={key} {...optionProps}>\n <Checkbox style={{ marginRight: 8 }} checked={selected} />\n {option}\n </li>\n );\n }}\n renderInput={(params) => <TextField {...params} label={label} />}\n // Reduce the size of the chips to make space for the <input> element, the +X text and the X button to avoid a line break.\n // See https://github.com/mui/material-ui/issues/38835 for more details.\n slotProps={{ chip: { sx: { maxWidth: 'calc(100% - 45px) !important' } } }}\n // Reduce the size of the <input> field\n sx={{ width: width ?? 250, '& input': { minWidth: '5px !important' } }}\n />\n );\n}\n\ninterface DurationAttributeFilterProps {\n label: string;\n value: DurationField;\n setValue: (value: DurationField) => void;\n}\n\nfunction DurationAttributeFilter(props: DurationAttributeFilterProps) {\n const { label, value, setValue } = props;\n const { min, max } = value;\n\n return (\n <Stack direction=\"row\" gap={0.5}>\n <DurationTextInput label={`Min ${label}`} value={min ?? ''} setValue={(min) => setValue({ min, max })} />\n <DurationTextInput label={`Max ${label}`} value={max ?? ''} setValue={(max) => setValue({ min, max })} />\n </Stack>\n );\n}\n\nconst durationFormatRegex = /^([0-9]+\\.)?[0-9]+(ns|ms|s|m|h)$/;\n\ninterface DurationTextInputProps {\n label: string;\n value: string;\n setValue: (value: string) => void;\n}\n\nfunction DurationTextInput(props: DurationTextInputProps) {\n const { label, value, setValue } = props;\n\n return (\n <LazyTextInput\n label={label}\n size=\"small\"\n value={value}\n setValue={setValue}\n validationRegex={durationFormatRegex}\n validationFailedMessage=\"Invalid format. Accepted format e.g. 100ms, accepted units: ns, ms, s, m, h\"\n sx={{ width: 150 }}\n />\n );\n}\n\ninterface CustomAttributesFilterProps {\n label: string;\n value: string[];\n setValue: (value: string[]) => void;\n}\n\nfunction CustomAttributesFilter(props: CustomAttributesFilterProps) {\n const { label, value, setValue } = props;\n\n return (\n <LazyTextInput\n label={label}\n size=\"small\"\n placeholder='span.http.status_code=200 span.http.method=\"GET\"'\n value={value.join(' ')}\n setValue={(x) => setValue(splitByUnquotedWhitespace(x))}\n sx={{ flexGrow: 1 }}\n />\n );\n}\n\ninterface LazyTextInputProps extends Omit<TextFieldProps, 'variant'> {\n validationRegex?: RegExp;\n validationFailedMessage?: string;\n value: string;\n setValue: (value: string) => void;\n}\n\n/** A <TextField> which calls props.setValue when the input field is blurred and the validation passes. */\nfunction LazyTextInput(props: LazyTextInputProps) {\n const { validationRegex, validationFailedMessage, value, setValue, ...otherProps } = props;\n const [draftValue, setDraftValue] = useState(value);\n const isValidInput = draftValue == '' || validationRegex == undefined || validationRegex.test(draftValue);\n\n useEffect(() => {\n setDraftValue(value);\n }, [value, setDraftValue]);\n\n const handleChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n setDraftValue(event.target.value);\n }, []);\n\n const handleBlur = useCallback(() => {\n if (isValidInput) {\n setValue(draftValue);\n }\n }, [isValidInput, setValue, draftValue]);\n\n return (\n <TextField\n {...otherProps}\n error={!isValidInput}\n helperText={isValidInput ? undefined : validationFailedMessage}\n value={draftValue}\n onChange={handleChange}\n onBlur={handleBlur}\n />\n );\n}\n\nfunction useTagValues(client: TempoClient | undefined, tag: string, query: string, start?: number, end?: number) {\n return useQuery({\n queryKey: ['useTagValues', client, tag, query, start, end],\n enabled: !!client,\n queryFn: async function () {\n if (!client) return;\n const values = await client.searchTagValues({ tag, q: query, start, end });\n return values.tagValues.map((tagValue) => tagValue.value ?? '').sort();\n },\n staleTime: 60 * 1000, // cache tag value response for 1m\n });\n}\n"],"names":["useCallback","useEffect","useState","Autocomplete","Checkbox","Stack","TextField","useTimeRange","useQuery","getUnixTimeRange","filterToTraceQL","traceQLToFilter","splitByUnquotedWhitespace","statusOptions","AttributeFilters","props","client","query","setQuery","filter","setFilter","absoluteTimeRange","start","end","data","serviceNameOptions","useTagValues","serviceName","spanNameOptions","spanName","StringAttributeFilter","label","options","value","setValue","x","width","status","DurationAttributeFilter","traceDuration","CustomAttributesFilter","customMatchers","multiple","size","limitTags","disableCloseOnSelect","onChange","_event","newValue","renderOption","option","selected","key","optionProps","li","style","marginRight","checked","renderInput","params","slotProps","chip","sx","maxWidth","minWidth","min","max","direction","gap","DurationTextInput","durationFormatRegex","LazyTextInput","validationRegex","validationFailedMessage","placeholder","join","flexGrow","otherProps","draftValue","setDraftValue","isValidInput","undefined","test","handleChange","event","target","handleBlur","error","helperText","onBlur","tag","queryKey","enabled","queryFn","values","searchTagValues","q","tagValues","map","tagValue","sort","staleTime"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/AttributeFilters.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ReactElement, SyntheticEvent, useCallback, useEffect, useState } from 'react';\nimport { Autocomplete, Checkbox, Stack, TextField, TextFieldProps } from '@mui/material';\nimport { useTimeRange } from '@perses-dev/plugin-system';\nimport { useQuery, UseQueryResult } from '@tanstack/react-query';\nimport { TempoClient } from '../model';\nimport { getUnixTimeRange } from '../plugins';\nimport { filterToTraceQL, traceQLToFilter, DurationField, Filter, splitByUnquotedWhitespace } from './filter';\n\nconst statusOptions = ['unset', 'ok', 'error'];\n\nexport interface AttributeFiltersProps {\n client?: TempoClient;\n query: string;\n setQuery: (x: string) => void;\n}\n\nexport function AttributeFilters(props: AttributeFiltersProps): ReactElement {\n const { client, query, setQuery } = props;\n\n const filter = traceQLToFilter(query);\n const setFilter = (filter: Filter): void => {\n setQuery(filterToTraceQL(filter));\n };\n\n const { absoluteTimeRange } = useTimeRange();\n const { start, end } = getUnixTimeRange(absoluteTimeRange);\n\n const { data: serviceNameOptions } = useTagValues(\n client,\n 'resource.service.name',\n filterToTraceQL({ ...filter, serviceName: [] }),\n start,\n end\n );\n const { data: spanNameOptions } = useTagValues(\n client,\n 'name',\n filterToTraceQL({ ...filter, spanName: [] }),\n start,\n end\n );\n\n return (\n <Stack direction=\"column\" flex={1} gap={1}>\n <Stack\n direction=\"row\"\n flex={1}\n gap={1}\n sx={{\n '& > *:nth-of-type(1)': { flex: 2 }, // Service Name\n '& > *:nth-of-type(2)': { flex: 2 }, // Span Name\n '& > *:nth-of-type(3)': { flex: 1 }, // Status\n }}\n >\n <StringAttributeFilter\n label=\"Service Name\"\n options={serviceNameOptions ?? []}\n value={filter.serviceName}\n setValue={(x) => setFilter({ ...filter, serviceName: x })}\n />\n <StringAttributeFilter\n label=\"Span Name\"\n options={spanNameOptions ?? []}\n value={filter.spanName}\n setValue={(x) => setFilter({ ...filter, spanName: x })}\n />\n <StringAttributeFilter\n label=\"Status\"\n options={statusOptions ?? []}\n value={filter.status}\n setValue={(x) => setFilter({ ...filter, status: x })}\n />\n </Stack>\n <Stack direction=\"row\" flex={1} gap={1}>\n <DurationAttributeFilter\n label=\"Trace Duration\"\n value={filter.traceDuration}\n setValue={(value) => setFilter({ ...filter, traceDuration: value })}\n />\n <CustomAttributesFilter\n label=\"Custom Attributes\"\n value={filter.customMatchers}\n setValue={(value) => setFilter({ ...filter, customMatchers: value })}\n />\n </Stack>\n </Stack>\n );\n}\n\ninterface StringAttributeFilterProps {\n label: string;\n width?: number;\n options: string[];\n value: string[];\n setValue: (value: string[]) => void;\n}\n\nfunction StringAttributeFilter(props: StringAttributeFilterProps): ReactElement {\n const { label, width, options, value, setValue } = props;\n\n return (\n <Autocomplete\n multiple\n size=\"small\"\n limitTags={1}\n disableCloseOnSelect\n value={value}\n onChange={(_event: SyntheticEvent, newValue: string[]) => setValue(newValue)}\n options={options}\n renderOption={(props, option, { selected }) => {\n const { key, ...optionProps } = props;\n return (\n <li key={key} {...optionProps}>\n <Checkbox style={{ marginRight: 8 }} checked={selected} />\n {option}\n </li>\n );\n }}\n renderInput={(params) => <TextField {...params} label={label} />}\n // Reduce the size of the chips to make space for the <input> element, the +X text and the X button to avoid a line break.\n // See https://github.com/mui/material-ui/issues/38835 for more details.\n slotProps={{ chip: { sx: { maxWidth: 'calc(100% - 45px) !important' } } }}\n // Reduce the size of the <input> field\n sx={{ width: width ?? 250, '& input': { minWidth: '5px !important' } }}\n />\n );\n}\n\ninterface DurationAttributeFilterProps {\n label: string;\n value: DurationField;\n setValue: (value: DurationField) => void;\n}\n\nfunction DurationAttributeFilter(props: DurationAttributeFilterProps): ReactElement {\n const { label, value, setValue } = props;\n const { min, max } = value;\n\n return (\n <Stack direction=\"row\" gap={0.5}>\n <DurationTextInput label={`Min ${label}`} value={min ?? ''} setValue={(min) => setValue({ min, max })} />\n <DurationTextInput label={`Max ${label}`} value={max ?? ''} setValue={(max) => setValue({ min, max })} />\n </Stack>\n );\n}\n\nconst durationFormatRegex = /^([0-9]+\\.)?[0-9]+(ns|ms|s|m|h)$/;\n\ninterface DurationTextInputProps {\n label: string;\n value: string;\n setValue: (value: string) => void;\n}\n\nfunction DurationTextInput(props: DurationTextInputProps): ReactElement {\n const { label, value, setValue } = props;\n\n return (\n <LazyTextInput\n label={label}\n size=\"small\"\n value={value}\n setValue={setValue}\n validationRegex={durationFormatRegex}\n validationFailedMessage=\"Invalid format. Accepted format e.g. 100ms, accepted units: ns, ms, s, m, h\"\n sx={{ width: 150 }}\n />\n );\n}\n\ninterface CustomAttributesFilterProps {\n label: string;\n value: string[];\n setValue: (value: string[]) => void;\n}\n\nfunction CustomAttributesFilter(props: CustomAttributesFilterProps): ReactElement {\n const { label, value, setValue } = props;\n\n return (\n <LazyTextInput\n label={label}\n size=\"small\"\n placeholder='span.http.status_code=200 span.http.method=\"GET\"'\n value={value.join(' ')}\n setValue={(x) => setValue(splitByUnquotedWhitespace(x))}\n sx={{ flexGrow: 1 }}\n />\n );\n}\n\ninterface LazyTextInputProps extends Omit<TextFieldProps, 'variant'> {\n validationRegex?: RegExp;\n validationFailedMessage?: string;\n value: string;\n setValue: (value: string) => void;\n}\n\n/** A <TextField> which calls props.setValue when the input field is blurred and the validation passes. */\nfunction LazyTextInput(props: LazyTextInputProps): ReactElement {\n const { validationRegex, validationFailedMessage, value, setValue, ...otherProps } = props;\n const [draftValue, setDraftValue] = useState(value);\n const isValidInput = draftValue === '' || validationRegex === undefined || validationRegex.test(draftValue);\n\n useEffect(() => {\n setDraftValue(value);\n }, [value, setDraftValue]);\n\n const handleChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n setDraftValue(event.target.value);\n }, []);\n\n const handleBlur = useCallback(() => {\n if (isValidInput) {\n setValue(draftValue);\n }\n }, [isValidInput, setValue, draftValue]);\n\n return (\n <TextField\n {...otherProps}\n error={!isValidInput}\n helperText={isValidInput ? undefined : validationFailedMessage}\n value={draftValue}\n onChange={handleChange}\n onBlur={handleBlur}\n />\n );\n}\n\nfunction useTagValues(\n client: TempoClient | undefined,\n tag: string,\n query: string,\n start?: number,\n end?: number\n): UseQueryResult<string[] | undefined> {\n return useQuery({\n queryKey: ['useTagValues', client, tag, query, start, end],\n enabled: !!client,\n queryFn: async function () {\n if (!client) return;\n const values = await client.searchTagValues({ tag, q: query, start, end });\n return values.tagValues.map((tagValue) => tagValue.value ?? '').sort();\n },\n staleTime: 60 * 1000, // cache tag value response for 1m\n });\n}\n"],"names":["useCallback","useEffect","useState","Autocomplete","Checkbox","Stack","TextField","useTimeRange","useQuery","getUnixTimeRange","filterToTraceQL","traceQLToFilter","splitByUnquotedWhitespace","statusOptions","AttributeFilters","props","client","query","setQuery","filter","setFilter","absoluteTimeRange","start","end","data","serviceNameOptions","useTagValues","serviceName","spanNameOptions","spanName","direction","flex","gap","sx","StringAttributeFilter","label","options","value","setValue","x","status","DurationAttributeFilter","traceDuration","CustomAttributesFilter","customMatchers","width","multiple","size","limitTags","disableCloseOnSelect","onChange","_event","newValue","renderOption","option","selected","key","optionProps","li","style","marginRight","checked","renderInput","params","slotProps","chip","maxWidth","minWidth","min","max","DurationTextInput","durationFormatRegex","LazyTextInput","validationRegex","validationFailedMessage","placeholder","join","flexGrow","otherProps","draftValue","setDraftValue","isValidInput","undefined","test","handleChange","event","target","handleBlur","error","helperText","onBlur","tag","queryKey","enabled","queryFn","values","searchTagValues","q","tagValues","map","tagValue","sort","staleTime"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { ReactElement } from 'react';
1
2
  import { AlertProps } from '@mui/material';
2
- export declare function ClosableAlert(props: AlertProps): import("react/jsx-runtime").JSX.Element | null;
3
+ export declare function ClosableAlert(props: AlertProps): ReactElement | null;
3
4
  //# sourceMappingURL=ClosableAlert.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ClosableAlert.d.ts","sourceRoot":"","sources":["../../../src/components/ClosableAlert.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAS,UAAU,EAAE,MAAM,eAAe,CAAC;AAElD,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,kDAY9C"}
1
+ {"version":3,"file":"ClosableAlert.d.ts","sourceRoot":"","sources":["../../../src/components/ClosableAlert.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAyB,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAS,UAAU,EAAE,MAAM,eAAe,CAAC;AAElD,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI,CAYpE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ClosableAlert.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { useCallback, useState } from 'react';\nimport { Alert, AlertProps } from '@mui/material';\n\nexport function ClosableAlert(props: AlertProps) {\n const [isVisible, setVisible] = useState(true);\n\n const handleClose = useCallback(() => {\n setVisible(false);\n }, [setVisible]);\n\n if (!isVisible) {\n return null;\n }\n\n return <Alert {...props} onClose={handleClose} />;\n}\n"],"names":["useCallback","useState","Alert","ClosableAlert","props","isVisible","setVisible","handleClose","onClose"],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,WAAW,EAAEC,QAAQ,QAAQ,QAAQ;AAC9C,SAASC,KAAK,QAAoB,gBAAgB;AAElD,OAAO,SAASC,cAAcC,KAAiB;IAC7C,MAAM,CAACC,WAAWC,WAAW,GAAGL,SAAS;IAEzC,MAAMM,cAAcP,YAAY;QAC9BM,WAAW;IACb,GAAG;QAACA;KAAW;IAEf,IAAI,CAACD,WAAW;QACd,OAAO;IACT;IAEA,qBAAO,KAACH;QAAO,GAAGE,KAAK;QAAEI,SAASD;;AACpC"}
1
+ {"version":3,"sources":["../../../src/components/ClosableAlert.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ReactElement, useCallback, useState } from 'react';\nimport { Alert, AlertProps } from '@mui/material';\n\nexport function ClosableAlert(props: AlertProps): ReactElement | null {\n const [isVisible, setVisible] = useState(true);\n\n const handleClose = useCallback(() => {\n setVisible(false);\n }, [setVisible]);\n\n if (!isVisible) {\n return null;\n }\n\n return <Alert {...props} onClose={handleClose} />;\n}\n"],"names":["useCallback","useState","Alert","ClosableAlert","props","isVisible","setVisible","handleClose","onClose"],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAAuBA,WAAW,EAAEC,QAAQ,QAAQ,QAAQ;AAC5D,SAASC,KAAK,QAAoB,gBAAgB;AAElD,OAAO,SAASC,cAAcC,KAAiB;IAC7C,MAAM,CAACC,WAAWC,WAAW,GAAGL,SAAS;IAEzC,MAAMM,cAAcP,YAAY;QAC9BM,WAAW;IACb,GAAG;QAACA;KAAW;IAEf,IAAI,CAACD,WAAW;QACd,OAAO;IACT;IAEA,qBAAO,KAACH;QAAO,GAAGE,KAAK;QAAEI,SAASD;;AACpC"}
@@ -13,7 +13,7 @@
13
13
  import { insertCompletionText } from '@codemirror/autocomplete';
14
14
  import { syntaxTree } from '@codemirror/language';
15
15
  import { String as StringType, FieldExpression, AttributeField, Resource, Identifier, Span, SpansetFilter, FieldOp } from '@grafana/lezer-traceql';
16
- import { getUnixTimeRange } from '../plugins/tempo-trace-query';
16
+ import { getUnixTimeRange } from '../plugins';
17
17
  const quoteChars = [
18
18
  '"',
19
19
  '`'