Jaeger: Update operations dropdown (#49329)

* Fix issue where no values would load in operations dropdown

* Better naming

* Updated tests
This commit is contained in:
Joey Tawadrous 2022-05-22 10:29:25 +01:00 committed by GitHub
parent 4f46c2f75f
commit f06d9164a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 36 deletions

View File

@ -113,12 +113,10 @@ describe('SearchForm', () => {
expect(asyncServiceSelect).toBeInTheDocument();
await user.type(asyncServiceSelect, 'j');
jest.advanceTimersByTime(3000);
var option = await screen.findByText('jaeger-query');
expect(option).toBeDefined();
await user.type(asyncServiceSelect, 'c');
jest.advanceTimersByTime(3000);
option = await screen.findByText('No options found');
expect(option).toBeDefined();
});

View File

@ -1,9 +1,8 @@
import { css } from '@emotion/css';
import { debounce } from 'lodash';
import React, { useCallback, useEffect, useState } from 'react';
import { SelectableValue } from '@grafana/data';
import { AsyncSelect, fuzzyMatch, InlineField, InlineFieldRow, Input } from '@grafana/ui';
import { fuzzyMatch, InlineField, InlineFieldRow, Input, Select } from '@grafana/ui';
import { notifyApp } from 'app/core/actions';
import { createErrorNotification } from 'app/core/copy/appNotification';
import { dispatch } from 'app/store/store';
@ -37,7 +36,7 @@ export function SearchForm({ datasource, query, onChange }: Props) {
operations: false,
});
const loadServices = useCallback(
const loadOptions = useCallback(
async (url: string, loaderOfType: string, query = ''): Promise<Array<SelectableValue<string>>> => {
setIsLoading((prevValue) => ({ ...prevValue, [loaderOfType]: true }));
@ -47,14 +46,12 @@ export function SearchForm({ datasource, query, onChange }: Props) {
return [{ label: `No ${loaderOfType} found`, value: `No ${loaderOfType} found` }];
}
const serviceOptions: SelectableValue[] = values.sort().map((service) => ({
label: service,
value: service,
const options: SelectableValue[] = values.sort().map((option) => ({
label: option,
value: option,
}));
const filteredOptions = serviceOptions.filter((item) =>
item.value ? fuzzyMatch(item.value, query).found : false
);
const filteredOptions = options.filter((item) => (item.value ? fuzzyMatch(item.value, query).found : false));
return filteredOptions;
} catch (error) {
dispatch(notifyApp(createErrorNotification('Error', error)));
@ -66,28 +63,17 @@ export function SearchForm({ datasource, query, onChange }: Props) {
[datasource]
);
const getServiceOptions = (userQuery: string) => {
return loadServices('/api/services', 'services', userQuery);
};
const getOperationOptions = (userQuery: string) => {
return loadServices(`/api/services/${encodeURIComponent(query.service!)}/operations`, 'operations', userQuery);
};
const serviceSearch = debounce(getServiceOptions, 500, { leading: true, trailing: true });
const operationSearch = debounce(getOperationOptions, 500, { leading: true, trailing: true });
useEffect(() => {
const getServices = async () => {
const services = await loadServices('/api/services', 'services');
const services = await loadOptions('/api/services', 'services');
setServiceOptions(services);
};
getServices();
}, [datasource, loadServices]);
}, [datasource, loadOptions]);
useEffect(() => {
const getOperations = async () => {
const operations = await loadServices(
const operations = await loadOptions(
`/api/services/${encodeURIComponent(query.service!)}/operations`,
'operations'
);
@ -96,17 +82,16 @@ export function SearchForm({ datasource, query, onChange }: Props) {
if (query.service) {
getOperations();
}
}, [datasource, query.service, loadServices]);
}, [datasource, query.service, loadOptions]);
return (
<div className={css({ maxWidth: '500px' })}>
<InlineFieldRow>
<InlineField label="Service" labelWidth={14} grow>
<AsyncSelect
<Select
inputId="service"
cacheOptions={false}
loadOptions={serviceSearch}
onOpenMenu={() => loadServices('/api/services', 'services')}
options={serviceOptions}
onOpenMenu={() => loadOptions('/api/services', 'services')}
isLoading={isLoading.services}
value={serviceOptions?.find((v) => v?.value === query.service) || undefined}
onChange={(v) =>
@ -118,19 +103,17 @@ export function SearchForm({ datasource, query, onChange }: Props) {
}
menuPlacement="bottom"
isClearable
defaultOptions
aria-label={'select-service-name'}
/>
</InlineField>
</InlineFieldRow>
<InlineFieldRow>
<InlineField label="Operation" labelWidth={14} grow disabled={!query.service}>
<AsyncSelect
<Select
inputId="operation"
cacheOptions={false}
loadOptions={operationSearch}
options={operationOptions}
onOpenMenu={() =>
loadServices(`/api/services/${encodeURIComponent(query.service!)}/operations`, 'operations')
loadOptions(`/api/services/${encodeURIComponent(query.service!)}/operations`, 'operations')
}
isLoading={isLoading.operations}
value={operationOptions?.find((v) => v.value === query.operation) || null}
@ -142,7 +125,6 @@ export function SearchForm({ datasource, query, onChange }: Props) {
}
menuPlacement="bottom"
isClearable
defaultOptions
aria-label={'select-operation-name'}
/>
</InlineField>