diff --git a/jest-setup.js b/jest-setup.js index 9f926f5..0a9d778 100644 --- a/jest-setup.js +++ b/jest-setup.js @@ -16,3 +16,15 @@ class MockIntersectionObserver { } global.IntersectionObserver = MockIntersectionObserver; + +// jsdom does not implement HTMLCanvasElement.getContext; @grafana/ui's +// measureText helper (used by Combobox) calls ctx.measureText and crashes +// otherwise. Stub the 2D context with the bare minimum API used in tests. +if (typeof HTMLCanvasElement !== 'undefined') { + HTMLCanvasElement.prototype.getContext = function () { + return { + measureText: (text) => ({ width: (text?.length ?? 0) * 8 }), + font: '', + }; + }; +} diff --git a/src/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/TraceSearchSettingsEditor.tsx b/src/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/TraceSearchSettingsEditor.tsx index b84b44a..2d0600f 100644 --- a/src/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/TraceSearchSettingsEditor.tsx +++ b/src/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/TraceSearchSettingsEditor.tsx @@ -1,10 +1,9 @@ import React from 'react'; -import { MetricFindValue, SelectableValue } from '@grafana/data'; -import { InlineField, Input, SegmentAsync, Select } from '@grafana/ui'; +import { MetricFindValue } from '@grafana/data'; +import { Combobox, ComboboxOption, InlineField, Input } from '@grafana/ui'; import { useDatasource, useRange } from '@/components/QueryEditor/ElasticsearchQueryContext'; -import { segmentStyles } from '@/components/QueryEditor/styles'; import { useDispatch } from '@/hooks/useStatelessReducer'; import { MetricAggregation } from '@/types'; import { fuzzySearchSort } from '@/utils'; @@ -29,14 +28,14 @@ interface Props { metric: Extract; } -const statusOptions: Array> = [ +const statusOptions: Array> = [ { label: 'Any', value: '' }, { label: 'Error', value: 'error' }, { label: 'Ok', value: 'ok' }, { label: 'Unset', value: 'unset' }, ]; -function toFuzzyOptions(values: MetricFindValue[], query?: string): Array> { +function toFuzzyOptions(values: MetricFindValue[], query?: string): Array> { return fuzzySearchSort( values.map((value) => String(value.text)), (text) => text, @@ -54,7 +53,7 @@ export const TraceSearchSettingsEditor = ({ metric }: Props) => { dispatch(changeMetricSetting({ metric: typedMetric, settingName, newValue: newValue?.trim() || undefined })); }; - const loadFieldValues = (field: string) => async (query?: string): Promise>> => { + const loadFieldValues = (field: string) => async (query: string): Promise>> => { if (!datasource.getTagValues) { return []; } @@ -65,28 +64,28 @@ export const TraceSearchSettingsEditor = ({ metric }: Props) => { return ( <> - changeSetting('serviceName', e.value)} + changeSetting('serviceName', option?.value)} placeholder="All services" - value={typedMetric.settings?.serviceName} + value={typedMetric.settings?.serviceName ?? null} /> - changeSetting('spanName', e.value)} + changeSetting('spanName', option?.value)} placeholder="All spans" - value={typedMetric.settings?.spanName} + value={typedMetric.settings?.spanName ?? null} /> -