import { css } from '@emotion/css'; import { SelectableValue } from '@grafana/data'; import { AsyncSelect, InlineField, InlineFieldRow, Input } from '@grafana/ui'; import React, { useCallback, useEffect, useState } from 'react'; import { JaegerDatasource } from '../datasource'; import { JaegerQuery } from '../types'; import { transformToLogfmt } from '../util'; import { AdvancedOptions } from './AdvancedOptions'; import { dispatch } from 'app/store/store'; import { notifyApp } from 'app/core/actions'; import { createErrorNotification } from 'app/core/copy/appNotification'; type Props = { datasource: JaegerDatasource; query: JaegerQuery; onChange: (value: JaegerQuery) => void; }; export const ALL_OPERATIONS_KEY = 'All'; const allOperationsOption: SelectableValue = { label: ALL_OPERATIONS_KEY, value: undefined, }; export function SearchForm({ datasource, query, onChange }: Props) { const [serviceOptions, setServiceOptions] = useState>>(); const [operationOptions, setOperationOptions] = useState>>(); const [isLoading, setIsLoading] = useState<{ services: boolean; operations: boolean; }>({ services: false, operations: false, }); const loadServices = useCallback( async (url: string, loaderOfType: string): Promise>> => { setIsLoading((prevValue) => ({ ...prevValue, [loaderOfType]: true })); try { const values: string[] | null = await datasource.metadataRequest(url); if (!values) { return [{ label: `No ${loaderOfType} found`, value: `No ${loaderOfType} found` }]; } const serviceOptions: SelectableValue[] = values.sort().map((service) => ({ label: service, value: service, })); return serviceOptions; } catch (error) { dispatch(notifyApp(createErrorNotification('Error', error))); return []; } finally { setIsLoading((prevValue) => ({ ...prevValue, [loaderOfType]: false })); } }, [datasource] ); useEffect(() => { const getServices = async () => { const services = await loadServices('/api/services', 'services'); setServiceOptions(services); }; getServices(); }, [datasource, loadServices]); useEffect(() => { const getOperations = async () => { const operations = await loadServices( `/api/services/${encodeURIComponent(query.service!)}/operations`, 'operations' ); setOperationOptions([allOperationsOption, ...operations]); }; if (query.service) { getOperations(); } }, [datasource, query.service, loadServices]); return (
loadServices('/api/services', 'services')} onOpenMenu={() => loadServices('/api/services', 'services')} isLoading={isLoading.services} value={serviceOptions?.find((v) => v?.value === query.service) || undefined} onChange={(v) => onChange({ ...query, service: v?.value!, operation: query.service !== v?.value ? undefined : query.operation, }) } menuPlacement="bottom" isClearable defaultOptions aria-label={'select-service-name'} /> loadServices(`/api/services/${encodeURIComponent(query.service!)}/operations`, 'operations') } onOpenMenu={() => loadServices(`/api/services/${encodeURIComponent(query.service!)}/operations`, 'operations') } isLoading={isLoading.operations} value={operationOptions?.find((v) => v.value === query.operation) || null} onChange={(v) => onChange({ ...query, operation: v?.value! || undefined, }) } menuPlacement="bottom" isClearable defaultOptions aria-label={'select-operation-name'} /> onChange({ ...query, tags: v.currentTarget.value, }) } />
); } export default SearchForm;