From 402e7707b5745c21c4b9b47b12f5a23fa4b06f2e Mon Sep 17 00:00:00 2001 From: Ben Donnelly Date: Wed, 14 Feb 2024 12:11:19 +0000 Subject: [PATCH 1/3] feat(create): add support for creating tracepoints with span and metrics change fire count picker to be easier to understand --- docs/docs/styles/styles.css | 7 +- .../tracepoints/TracepointCreate.tsx | 745 +++++++++++------- src/deepql/DeepDataSource.ts | 22 +- src/types.ts | 18 +- yarn.lock | 86 +- 5 files changed, 580 insertions(+), 298 deletions(-) diff --git a/docs/docs/styles/styles.css b/docs/docs/styles/styles.css index 37fba7b..7a124b0 100644 --- a/docs/docs/styles/styles.css +++ b/docs/docs/styles/styles.css @@ -16,9 +16,10 @@ */ .md-header__button.md-logo { - padding: 0; + padding: 0; } -.md-header__button.md-logo img, .md-header__button.md-logo svg { - height: 45px; +.md-header__button.md-logo img, +.md-header__button.md-logo svg { + height: 45px; } diff --git a/src/components/tracepoints/TracepointCreate.tsx b/src/components/tracepoints/TracepointCreate.tsx index 4b5f652..e742e80 100644 --- a/src/components/tracepoints/TracepointCreate.tsx +++ b/src/components/tracepoints/TracepointCreate.tsx @@ -15,310 +15,491 @@ * along with this program. If not, see . */ -import {Props} from '../QueryEditor'; +import { Props } from '../QueryEditor'; import { - Button, - HorizontalGroup, - IconButton, - InlineField, - InlineFieldRow, - InlineLabel, - Input, - useStyles2, - VerticalGroup + Button, + HorizontalGroup, + InlineField, + InlineFieldRow, + InlineLabel, + Input, + Select, + useStyles2, } from '@grafana/ui'; -import React, {useEffect, useState} from 'react'; -import {firstValueFrom} from 'rxjs'; -import {TagsField} from '../TagsField/TagsField'; -import {DEFAULT_FIRE_COUNT} from '../../types'; -import {css, cx} from "@emotion/css"; +import React, { useEffect, useState } from 'react'; +import { firstValueFrom } from 'rxjs'; +import { TagsField } from '../TagsField/TagsField'; +import { DEFAULT_FIRE_COUNT } from '../../types'; +import { css } from '@emotion/css'; +import { AccessoryButton } from '@grafana/experimental'; +import { v4 as uuidv4 } from 'uuid'; +import { GrafanaTheme2 } from '@grafana/data'; -const getStyles = () => ({ - container: css` - display: flex; - flex-direction: row; - `, - containerColumn1: css` - display: flex; - flex-direction: column; - flex-basis: 79%; - margin-right:5px; - `, - containerColumn2: css` - display: flex; - flex-direction: column; - flex-basis: 19%; - `, - label: css` - width: inherit; - `, - watchGroup: css` - overflow-y: scroll; - height: 150px; - `, - watchLine: css` - width: 100%; - height: 30px; - `, - watchInput: css` - width: 100%; - `, - watchButton: css` - position: relative; - right: 5px; - z-index: 999; - float: right; - top: -23px; - `, -}) +const getStyles = (theme: GrafanaTheme2) => ({ + label: css` + width: inherit; + `, + watchGroup: css` + overflow-y: scroll; + height: 150px; + `, + watchLine: css` + width: 100%; + height: 30px; + `, + watchInput: css` + width: 100%; + `, + watchButton: css` + position: relative; + right: 5px; + z-index: 999; + float: right; + top: -23px; + `, + embedRow: css` + margin: -4px 0 0 0; + `, + embedValues: css` + max-width: 200px; + `, + addValue: css({ + marginLeft: theme.spacing(1), + }), +}); -export const TracepointCreate = ({datasource, query, onChange, onRunQuery, onBlur}: Props) => { - const styles = useStyles2(getStyles); - const [inputErrors, setInputErrors] = useState<{ [key: string]: boolean }>({ - path: !isValidPath(query.tpCreate?.path), - line: !isValidLine(`${query.tpCreate?.line_number}`), +export const TracepointCreate = ({ datasource, query, onChange, onRunQuery, onBlur }: Props) => { + const styles = useStyles2(getStyles); + const [inputErrors, setInputErrors] = useState<{ [key: string]: boolean }>({ + path: !isValidPath(query.tpCreate?.path), + line: !isValidLine(`${query.tpCreate?.line_number}`), + }); + const [customOptions, setCustomOptions] = useState>([]); + + const [targeting, setTargeting] = useState(); + + useEffect(() => { + onChange({ + ...query, + tpCreate: { + ...query.tpCreate, + targeting: targeting, + }, }); - const [newWatch, setNewWatch] = useState("") + }, [targeting]); // eslint-disable-line react-hooks/exhaustive-deps + + function anyError() { + return Object.values(inputErrors).some((v) => v); + } - const [targeting, setTargeting] = useState(); + let spanOptions = [ + { label: 'None', value: 'None' }, + { label: 'Line', value: 'Line' }, + { + label: 'Method/Function', + value: 'Method', + }, + ]; - useEffect(() => { - onChange({ - ...query, - tpCreate: { - ...query.tpCreate, - targeting: targeting, - }, - }); - }, [targeting]); // eslint-disable-line react-hooks/exhaustive-deps + const fireCountValues = [ + { label: 'Forever', value: -1 }, + { label: 'Once', value: 1 }, + { label: '5', value: 5 }, + { label: '10', value: 10 }, + ]; + + function spanFromOptions(spanOptions: { label: string; value: string }[], value: string) { + return spanOptions.filter((value1) => { + return value1.value == value; + })[0]; + } + + const randomId = () => uuidv4().slice(0, 12); + const addMetric = () => { + const metric = { + id: randomId(), + }; + onChange({ + ...query, + tpCreate: { + ...query.tpCreate, + metrics: [...query.tpCreate.metrics, metric], + }, + }); + }; - function anyError() { - return Object.values(inputErrors).some((v) => v); + const removeMetric = (id: string) => { + let metrics = query.tpCreate.metrics.filter((tag) => { + return tag.id !== id; + }); + if (metrics.length === 0) { + metrics = [ + { + id: randomId(), + }, + ]; } + onChange({ + ...query, + tpCreate: { + ...query.tpCreate, + metrics: [...metrics], + }, + }); + }; - return ( -
-
-
- - Enter a tracepoint details to create a new tracepoint - - Documentation - - - - - { - let value = v.currentTarget.value; - if (value && isValidPath(value)) { - setInputErrors({...inputErrors, path: false}); - } else { - setInputErrors({...inputErrors, path: true}); - } + function optionFromConfig(number: number) { + if (number === -1) { + return { label: 'Forever', value: -1 }; + } + return { label: `${number}`, value: number }; + } - onChange({ - ...query, - tpCreate: { - ...query.tpCreate, - path: value, - }, - }); - }} - /> - - - - - { - let value = v.currentTarget.value; - if (value && isValidLine(value)) { - setInputErrors({...inputErrors, line: false}); - } else { - setInputErrors({...inputErrors, line: true}); - } + return ( +
+ + Enter a tracepoint details to create a new tracepoint + + Documentation + + + + + { + let value = v.currentTarget.value; + if (value && isValidPath(value)) { + setInputErrors({ ...inputErrors, path: false }); + } else { + setInputErrors({ ...inputErrors, path: true }); + } - onChange({ - ...query, - tpCreate: { - ...query.tpCreate, - line_number: parseInt(value, 10), - }, - }); - }} - /> - - - { - let value = v.currentTarget.value; - if (value && isValidFireCount(value)) { - setInputErrors({...inputErrors, firecount: false}); - } else { - setInputErrors({...inputErrors, firecount: true}); - } + onChange({ + ...query, + tpCreate: { + ...query.tpCreate, + path: value, + }, + }); + }} + /> + + + + + { + let value = v.currentTarget.value; + if (value && isValidLine(value)) { + setInputErrors({ ...inputErrors, line: false }); + } else { + setInputErrors({ ...inputErrors, line: true }); + } + + onChange({ + ...query, + tpCreate: { + ...query.tpCreate, + line_number: parseInt(value, 10), + }, + }); + }} + /> + + + { + onChange({ + ...query, + tpCreate: { + ...query.tpCreate, + log_msg: v.currentTarget.value, + }, + }); + }} + /> + + + + + { + onChange({ + ...query, + tpCreate: { + ...query.tpCreate, + metrics: (query.tpCreate?.metrics ?? [tag]).map((metric) => { + if (metric.id == tag.id) { + metric.name = v.currentTarget.value; + } + return metric; + }), + }, + }); + }} + /> + + { + onChange({ + ...query, + tpCreate: { + ...query.tpCreate, + metrics: (query.tpCreate?.metrics ?? [tag]).map((metric) => { + if (metric.id == tag.id) { + metric.expression = v.currentTarget.value; + } + return metric; + }), + }, + }); + }} + /> + + {(tag.name || tag.expression || (query.tpCreate?.metrics ?? [tag]).length > 1) && ( + removeMetric(tag.id)} + tooltip="Remove metric" + /> + )} + {(tag.name || tag.expression) && i === (query.tpCreate?.metrics ?? [tag]).length - 1 && ( + + + + )} + +
+ ))} +
+ + + + +
+ {( + query.tpCreate?.watches ?? [ + { + id: randomId(), + }, + ] + ).map((watch, i) => ( +
+ + { + onChange({ + ...query, + tpCreate: { + ...query.tpCreate, + watches: (query.tpCreate?.watches ?? [watch]).map((value) => { + if (value.id === watch.id) { + value.expression = v.currentTarget.value; + } + return value; + }), + }, + }); + }} + /> - onChange({ - ...query, - tpCreate: { - ...query.tpCreate, - fire_count: parseInt(value, 10), - }, - }); - }} - /> - - - - - - - - - - { - onChange({ - ...query, - tpCreate: { - ...query.tpCreate, - log_msg: v.currentTarget.value - } - }) - }} - /> - - -
-
- - Watchers - - Documentation - - -
- - {(query.tpCreate?.watches ?? []).map((watch, index) => { - return
- { - query.tpCreate = { - ...query.tpCreate - } - query.tpCreate.watches = query.tpCreate?.watches ?? [] - query.tpCreate.watches[index] = event.currentTarget.value - onChange({ - ...query, - }) - }}/> - - { - query.tpCreate.watches.splice(index, 1); - onChange({ - ...query, - }) - }}/> - -
- })} -
-
-
- { - setNewWatch(event.currentTarget.value) - }}/> - - { - query.tpCreate = { - ...query.tpCreate - } - query.tpCreate.watches = query.tpCreate?.watches ?? [] - query.tpCreate.watches.push(newWatch) - onChange({ - ...query, - }) - }}/> - -
-
-
-
- - + tooltip="Add watch" + /> + + )} -
-
- ); +
+ ))} + + + + + + + + ); }; const isValidPath = (val: string): boolean => { - return !(!val || val === ''); + return !(!val || val === ''); }; const isValidLine = (val: string): boolean => { - const number = parseInt(val, 10); - return number >= 0; + const number = parseInt(val, 10); + return number >= 0; }; const isValidFireCount = (val: string): boolean => { - const number = parseInt(val, 10); - return number >= -1 && number !== 0; + const number = parseInt(val, 10); + return number >= -1 && number !== 0; }; diff --git a/src/deepql/DeepDataSource.ts b/src/deepql/DeepDataSource.ts index 93e03ea..b521231 100644 --- a/src/deepql/DeepDataSource.ts +++ b/src/deepql/DeepDataSource.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import {CoreApp, DataQueryRequest, DataQueryResponse, DataSourceInstanceSettings, ScopedVars} from '@grafana/data'; +import { CoreApp, DataQueryRequest, DataQueryResponse, DataSourceInstanceSettings, ScopedVars } from '@grafana/data'; import { BackendSrvRequest, config, @@ -26,11 +26,11 @@ import { TemplateSrv, } from '@grafana/runtime'; -import {DeepDatasourceOptions, DeepQuery, DEFAULT_FIRE_COUNT, DEFAULT_QUERY, SearchQueryParams} from '../types'; +import { DeepDatasourceOptions, DeepQuery, DEFAULT_FIRE_COUNT, DEFAULT_QUERY, SearchQueryParams } from '../types'; import DeepLanguageProvider from './DeepLanguageProvider'; -import {catchError, lastValueFrom, map, merge, Observable, of} from 'rxjs'; -import {serializeParams} from 'Utils'; -import {groupBy, identity, pick, pickBy} from 'lodash'; +import { catchError, lastValueFrom, map, merge, Observable, of } from 'rxjs'; +import { serializeParams } from 'Utils'; +import { groupBy, identity, pick, pickBy } from 'lodash'; import { createTableFrameFromDeepQlQuery, createTableFrameFromSearch, @@ -286,10 +286,18 @@ export class DeepDataSource extends DataSourceWithBackend watch.expression), targeting: this.parseTargeting(appliedQuery.tpCreate.targeting), + metrics: (appliedQuery.tpCreate?.metrics ?? []).map((metric) => { + return { + name: metric.name, + expression: metric.expression, + type: 'COUNTER', + }; + }), }, }, }); diff --git a/src/types.ts b/src/types.ts index 5484416..13b7cc6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -15,7 +15,8 @@ * along with this program. If not, see . */ -import { DataQuery, DataSourceJsonData } from '@grafana/data'; +import { DataSourceJsonData } from '@grafana/data'; +import { DataQuery } from '@grafana/schema'; export interface DeepQuery extends DataQuery { limit?: number; @@ -34,12 +35,25 @@ export interface DeepQuery extends DataQuery { export const DEFAULT_FIRE_COUNT = 1; export interface DeepTracepointCreateConfig { + metrics: Metric[]; log_msg?: string; targeting?: string; path: string; line_number: number; fire_count: number; - watches: string[]; + watches: Watch[]; + trace?: string; +} + +export interface Watch { + id: string; + expression?: string; +} + +export interface Metric { + id: string; + name?: string; + expression?: string; } export interface SearchQueryParams { diff --git a/yarn.lock b/yarn.lock index 1521123..952a69e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1592,6 +1592,20 @@ eslint-plugin-react-hooks "4.6.0" typescript "4.8.4" +"@grafana/experimental@^1.7.10": + version "1.7.10" + resolved "https://registry.yarnpkg.com/@grafana/experimental/-/experimental-1.7.10.tgz#e3903809c263b9e36caf27aa0a37865bcc17d772" + integrity sha512-kmTZ6YGCa7zDf7Vq/jvr9G9Z2Af0WGueTMrm9TQ9z17YcZ8/RtsTL2irNwcNdvsdRjpP49yanZ2QWZ00y8J+AA== + dependencies: + "@types/uuid" "^8.3.3" + lodash "^4.17.21" + prismjs "^1.29.0" + react-beautiful-dnd "^13.1.1" + react-popper-tooltip "^4.4.2" + react-use "^17.4.2" + semver "^7.5.4" + uuid "^8.3.2" + "@grafana/faro-core@^1.2.1": version "1.2.3" resolved "https://registry.yarnpkg.com/@grafana/faro-core/-/faro-core-1.2.3.tgz#03faae6ee93664cfda39dfd3059f42bbdb7aeae0" @@ -2041,7 +2055,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/sourcemap-codec@^1.4.10": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.15": version "1.4.15" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== @@ -3025,6 +3039,11 @@ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.2.tgz#6286b4c7228d58ab7866d19716f3696e03a09397" integrity sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw== +"@types/uuid@^8.3.3": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + "@types/yargs-parser@*": version "21.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" @@ -4296,6 +4315,11 @@ csstype@^3.0.2, csstype@^3.0.6: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== +csstype@^3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + cypress-file-upload@5.0.8: version "5.0.8" resolved "https://registry.yarnpkg.com/cypress-file-upload/-/cypress-file-upload-5.0.8.tgz#d8824cbeaab798e44be8009769f9a6c9daa1b4a1" @@ -6107,6 +6131,14 @@ inline-style-prefixer@^6.0.0: css-in-js-utils "^3.1.0" fast-loops "^1.1.3" +inline-style-prefixer@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-7.0.0.tgz#991d550735d42069f528ac1bcdacd378d1305442" + integrity sha512-I7GEdScunP1dQ6IM2mQWh6v0mOYdYmH3Bp31UecKdrcUgcURTcctSe1IECdUznSHKSmsHtjrT3CwCPI1pyxfUQ== + dependencies: + css-in-js-utils "^3.1.0" + fast-loops "^1.1.3" + internal-slot@^1.0.3, internal-slot@^1.0.4, internal-slot@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" @@ -7468,6 +7500,20 @@ nano-css@^5.3.1: stacktrace-js "^2.0.2" stylis "^4.0.6" +nano-css@^5.6.1: + version "5.6.1" + resolved "https://registry.yarnpkg.com/nano-css/-/nano-css-5.6.1.tgz#964120cb1af6cccaa6d0717a473ccd876b34c197" + integrity sha512-T2Mhc//CepkTa3X4pUhKgbEheJHYAxD0VptuqFhDbGMUWVV2m+lkNiW/Ieuj35wrfC8Zm0l7HvssQh7zcEttSw== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.15" + css-tree "^1.1.2" + csstype "^3.1.2" + fastest-stable-stringify "^2.0.2" + inline-style-prefixer "^7.0.0" + rtl-css-js "^1.16.1" + stacktrace-js "^2.0.2" + stylis "^4.3.0" + nanoid@3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" @@ -8352,7 +8398,7 @@ rc-virtual-list@^3.5.2: rc-resize-observer "^1.0.0" rc-util "^5.36.0" -react-beautiful-dnd@13.1.1: +react-beautiful-dnd@13.1.1, react-beautiful-dnd@^13.1.1: version "13.1.1" resolved "https://registry.yarnpkg.com/react-beautiful-dnd/-/react-beautiful-dnd-13.1.1.tgz#b0f3087a5840920abf8bb2325f1ffa46d8c4d0a2" integrity sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ== @@ -8480,7 +8526,7 @@ react-loading-skeleton@3.3.1: resolved "https://registry.yarnpkg.com/react-loading-skeleton/-/react-loading-skeleton-3.3.1.tgz#cd6e3a626ee86c76a46c14e2379243f2f8834e1b" integrity sha512-NilqqwMh2v9omN7LteiDloEVpFyMIa0VGqF+ukqp0ncVlYu1sKYbYGX9JEl+GtOT9TKsh04zCHAbavnQ2USldA== -react-popper-tooltip@4.4.2: +react-popper-tooltip@4.4.2, react-popper-tooltip@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-4.4.2.tgz#0dc4894b8e00ba731f89bd2d30584f6032ec6163" integrity sha512-y48r0mpzysRTZAIh8m2kpZ8S1YPNqGtQPDrlXYSGvDS1c1GpG/NUXbsbIdfbhXfmSaRJuTcaT6N1q3CKuHRVbg== @@ -8600,6 +8646,26 @@ react-use@17.4.0: ts-easing "^0.2.0" tslib "^2.1.0" +react-use@^17.4.2: + version "17.5.0" + resolved "https://registry.yarnpkg.com/react-use/-/react-use-17.5.0.tgz#1fae45638828a338291efa0f0c61862db7ee6442" + integrity sha512-PbfwSPMwp/hoL847rLnm/qkjg3sTRCvn6YhUZiHaUa3FA6/aNoFX79ul5Xt70O1rK+9GxSVqkY0eTwMdsR/bWg== + dependencies: + "@types/js-cookie" "^2.2.6" + "@xobotyi/scrollbar-width" "^1.9.5" + copy-to-clipboard "^3.3.1" + fast-deep-equal "^3.1.3" + fast-shallow-equal "^1.0.0" + js-cookie "^2.2.1" + nano-css "^5.6.1" + react-universal-interface "^0.6.2" + resize-observer-polyfill "^1.5.1" + screenfull "^5.1.0" + set-harmonic-interval "^1.0.1" + throttle-debounce "^3.0.1" + ts-easing "^0.2.0" + tslib "^2.1.0" + react-window@1.8.9: version "1.8.9" resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.9.tgz#24bc346be73d0468cdf91998aac94e32bc7fa6a8" @@ -8889,7 +8955,7 @@ robust-predicates@^3.0.0: resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.2.tgz#d5b28528c4824d20fc48df1928d41d9efa1ad771" integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg== -rtl-css-js@^1.14.0: +rtl-css-js@^1.14.0, rtl-css-js@^1.16.1: version "1.16.1" resolved "https://registry.yarnpkg.com/rtl-css-js/-/rtl-css-js-1.16.1.tgz#4b48b4354b0ff917a30488d95100fbf7219a3e80" integrity sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg== @@ -9034,6 +9100,13 @@ semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: dependencies: lru-cache "^6.0.0" +semver@^7.5.4: + version "7.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" + integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== + dependencies: + lru-cache "^6.0.0" + serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -9507,6 +9580,11 @@ stylis@4.2.0: resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== +stylis@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.1.tgz#ed8a9ebf9f76fe1e12d462f5cc3c4c980b23a7eb" + integrity sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ== + supports-color@8.1.1, supports-color@^8.0.0, supports-color@^8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" From c7031d44dfd1a900295146c241c093a83b72c094 Mon Sep 17 00:00:00 2001 From: Ben Donnelly Date: Wed, 14 Feb 2024 12:36:16 +0000 Subject: [PATCH 2/3] chore(deps): install missing deps --- package.json | 4 +++- yarn.lock | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 595f7f4..5e9231c 100644 --- a/package.json +++ b/package.json @@ -63,11 +63,13 @@ "dependencies": { "@emotion/css": "^11.11.2", "@grafana/data": "10.2.2", + "@grafana/experimental": "^1.7.10", "@grafana/runtime": "10.2.2", "@grafana/ui": "10.2.2", "prismjs": "^1.29.0", "react": "17.0.2", "react-dom": "17.0.2", - "slate": "0.47.9" + "slate": "0.47.9", + "uuid": "^9.0.1" } } diff --git a/yarn.lock b/yarn.lock index 952a69e..d022264 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10056,6 +10056,11 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +uuid@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" From c2aad26be23718045aecc1890bf848700f9dbf1b Mon Sep 17 00:00:00 2001 From: Ben Donnelly Date: Wed, 14 Feb 2024 12:43:45 +0000 Subject: [PATCH 3/3] chore(lint): fix lint issues --- .../tracepoints/TracepointCreate.tsx | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/components/tracepoints/TracepointCreate.tsx b/src/components/tracepoints/TracepointCreate.tsx index e742e80..ffd2960 100644 --- a/src/components/tracepoints/TracepointCreate.tsx +++ b/src/components/tracepoints/TracepointCreate.tsx @@ -108,9 +108,9 @@ export const TracepointCreate = ({ datasource, query, onChange, onRunQuery, onBl { label: '10', value: 10 }, ]; - function spanFromOptions(spanOptions: { label: string; value: string }[], value: string) { - return spanOptions.filter((value1) => { - return value1.value == value; + function spanFromOptions(spanOptions: Array<{ label: string; value: string }>, value: string) { + return spanOptions.filter((option) => { + return option.value === value; })[0]; } @@ -244,12 +244,13 @@ export const TracepointCreate = ({ datasource, query, onChange, onRunQuery, onBl onCreateOption={(v) => { if (isValidFireCount(v)) { setInputErrors({ ...inputErrors, firecount: false }); - setCustomOptions([...customOptions, { label: v, value: parseInt(v) }]); + const valueInt = parseInt(v, 10); + setCustomOptions([...customOptions, { label: v, value: valueInt }]); onChange({ ...query, tpCreate: { ...query.tpCreate, - fire_count: parseInt(v), + fire_count: valueInt, }, }); } else { @@ -324,21 +325,21 @@ export const TracepointCreate = ({ datasource, query, onChange, onRunQuery, onBl id: randomId(), }, ] - ).map((tag, i) => ( + ).map((metric, i) => (
{ onChange({ ...query, tpCreate: { ...query.tpCreate, - metrics: (query.tpCreate?.metrics ?? [tag]).map((metric) => { - if (metric.id == tag.id) { + metrics: (query.tpCreate?.metrics ?? [metric]).map((metric) => { + if (metric.id === metric.id) { metric.name = v.currentTarget.value; } return metric; @@ -351,15 +352,15 @@ export const TracepointCreate = ({ datasource, query, onChange, onRunQuery, onBl { onChange({ ...query, tpCreate: { ...query.tpCreate, - metrics: (query.tpCreate?.metrics ?? [tag]).map((metric) => { - if (metric.id == tag.id) { + metrics: (query.tpCreate?.metrics ?? [metric]).map((metric) => { + if (metric.id === metric.id) { metric.expression = v.currentTarget.value; } return metric; @@ -369,16 +370,16 @@ export const TracepointCreate = ({ datasource, query, onChange, onRunQuery, onBl }} /> - {(tag.name || tag.expression || (query.tpCreate?.metrics ?? [tag]).length > 1) && ( + {(metric.name || metric.expression || (query.tpCreate?.metrics ?? [metric]).length > 1) && ( removeMetric(tag.id)} + onClick={() => removeMetric(metric.id)} tooltip="Remove metric" /> )} - {(tag.name || tag.expression) && i === (query.tpCreate?.metrics ?? [tag]).length - 1 && ( + {(metric.name || metric.expression) && i === (query.tpCreate?.metrics ?? [metric]).length - 1 && (