Skip to content

Commit c9d1ede

Browse files
committed
fix: allow edit of trace search fields
Signed-off-by: Patrik Cyvoct <patrik@ptrk.io>
1 parent 00f9f19 commit c9d1ede

2 files changed

Lines changed: 31 additions & 20 deletions

File tree

jest-setup.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,15 @@ class MockIntersectionObserver {
1616
}
1717

1818
global.IntersectionObserver = MockIntersectionObserver;
19+
20+
// jsdom does not implement HTMLCanvasElement.getContext; @grafana/ui's
21+
// measureText helper (used by Combobox) calls ctx.measureText and crashes
22+
// otherwise. Stub the 2D context with the bare minimum API used in tests.
23+
if (typeof HTMLCanvasElement !== 'undefined') {
24+
HTMLCanvasElement.prototype.getContext = function () {
25+
return {
26+
measureText: (text) => ({ width: (text?.length ?? 0) * 8 }),
27+
font: '',
28+
};
29+
};
30+
}

src/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/TraceSearchSettingsEditor.tsx

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import React from 'react';
22

3-
import { MetricFindValue, SelectableValue } from '@grafana/data';
4-
import { InlineField, Input, SegmentAsync, Select } from '@grafana/ui';
3+
import { MetricFindValue } from '@grafana/data';
4+
import { Combobox, ComboboxOption, InlineField, Input } from '@grafana/ui';
55

66
import { useDatasource, useRange } from '@/components/QueryEditor/ElasticsearchQueryContext';
7-
import { segmentStyles } from '@/components/QueryEditor/styles';
87
import { useDispatch } from '@/hooks/useStatelessReducer';
98
import { MetricAggregation } from '@/types';
109
import { fuzzySearchSort } from '@/utils';
@@ -29,14 +28,14 @@ interface Props {
2928
metric: Extract<MetricAggregation, { type: 'trace_search' }>;
3029
}
3130

32-
const statusOptions: Array<SelectableValue<TraceSearchStatus>> = [
31+
const statusOptions: Array<ComboboxOption<TraceSearchStatus>> = [
3332
{ label: 'Any', value: '' },
3433
{ label: 'Error', value: 'error' },
3534
{ label: 'Ok', value: 'ok' },
3635
{ label: 'Unset', value: 'unset' },
3736
];
3837

39-
function toFuzzyOptions(values: MetricFindValue[], query?: string): Array<SelectableValue<string>> {
38+
function toFuzzyOptions(values: MetricFindValue[], query?: string): Array<ComboboxOption<string>> {
4039
return fuzzySearchSort(
4140
values.map((value) => String(value.text)),
4241
(text) => text,
@@ -54,7 +53,7 @@ export const TraceSearchSettingsEditor = ({ metric }: Props) => {
5453
dispatch(changeMetricSetting({ metric: typedMetric, settingName, newValue: newValue?.trim() || undefined }));
5554
};
5655

57-
const loadFieldValues = (field: string) => async (query?: string): Promise<Array<SelectableValue<string>>> => {
56+
const loadFieldValues = (field: string) => async (query: string): Promise<Array<ComboboxOption<string>>> => {
5857
if (!datasource.getTagValues) {
5958
return [];
6059
}
@@ -65,28 +64,28 @@ export const TraceSearchSettingsEditor = ({ metric }: Props) => {
6564
return (
6665
<>
6766
<InlineField label="Service name" labelWidth={16}>
68-
<SegmentAsync
69-
allowCustomValue={true}
70-
className={segmentStyles}
71-
loadOptions={loadFieldValues('service_name')}
72-
onChange={(e) => changeSetting('serviceName', e.value)}
67+
<Combobox
68+
isClearable
69+
createCustomValue
70+
options={loadFieldValues('service_name')}
71+
onChange={(option) => changeSetting('serviceName', option?.value)}
7372
placeholder="All services"
74-
value={typedMetric.settings?.serviceName}
73+
value={typedMetric.settings?.serviceName ?? null}
7574
/>
7675
</InlineField>
7776
<InlineField label="Span name" labelWidth={16}>
78-
<SegmentAsync
79-
allowCustomValue={true}
80-
className={segmentStyles}
81-
loadOptions={loadFieldValues('span_name')}
82-
onChange={(e) => changeSetting('spanName', e.value)}
77+
<Combobox
78+
isClearable
79+
createCustomValue
80+
options={loadFieldValues('span_name')}
81+
onChange={(option) => changeSetting('spanName', option?.value)}
8382
placeholder="All spans"
84-
value={typedMetric.settings?.spanName}
83+
value={typedMetric.settings?.spanName ?? null}
8584
/>
8685
</InlineField>
8786
<InlineField label="Status" labelWidth={16}>
88-
<Select
89-
onChange={(e) => changeSetting('status', e.value)}
87+
<Combobox
88+
onChange={(option) => changeSetting('status', option.value)}
9089
options={statusOptions}
9190
value={typedMetric.settings?.status || ''}
9291
/>

0 commit comments

Comments
 (0)