import _ from 'lodash'; import React, { useEffect } from 'react'; import { useAsyncFn } from 'react-use'; import { SelectableValue } from '@grafana/data'; import { InlineField } from '@grafana/ui'; import { QueryEditorRow } from './QueryEditorRow'; import { MetricPicker } from '../../../components'; import { getVariableOptions } from './utils'; import { ZabbixDatasource } from '../../datasource'; import { ZabbixMetricsQuery } from '../../types/query'; import { useInterpolatedQuery } from '../../hooks/useInterpolatedQuery'; export interface Props { query: ZabbixMetricsQuery; datasource: ZabbixDatasource; onChange: (query: ZabbixMetricsQuery) => void; } export const UserMacrosQueryEditor = ({ query, datasource, onChange }: Props) => { const interpolatedQuery = useInterpolatedQuery(datasource, query); const loadGroupOptions = async () => { const groups = await datasource.zabbix.getAllGroups(); const options = groups?.map((group) => ({ value: group.name, label: group.name, })); options.unshift(...getVariableOptions()); return options; }; const [{ loading: groupsLoading, value: groupsOptions }, fetchGroups] = useAsyncFn(async () => { const options = await loadGroupOptions(); return options; }, []); const loadHostOptions = async (group: string) => { const hosts = await datasource.zabbix.getAllHosts(group); let options: Array> = hosts?.map((host) => ({ value: host.name, label: host.name, })); options = _.uniqBy(options, (o) => o.value); options.unshift({ value: '/.*/' }); options.unshift(...getVariableOptions()); return options; }; const [{ loading: hostsLoading, value: hostOptions }, fetchHosts] = useAsyncFn(async () => { const options = await loadHostOptions(interpolatedQuery.group.filter); return options; }, [interpolatedQuery.group.filter]); const loadMacrosOptions = async (group: string, host: string) => { const macros = await datasource.zabbix.getAllMacros(group, host); let options: Array> = macros?.map((m) => ({ value: m.macro, label: m.macro, })); options = _.uniqBy(options, (o) => o.value); options.unshift({ value: '/.*/' }); options.unshift(...getVariableOptions()); return options; }; const [{ loading: macrosLoading, value: macrosOptions }, fetchmacros] = useAsyncFn(async () => { const options = await loadMacrosOptions(interpolatedQuery.group.filter, interpolatedQuery.host.filter); return options; }, [interpolatedQuery.group.filter, interpolatedQuery.host.filter]); // Update suggestions on every metric change const groupFilter = interpolatedQuery.group?.filter; const hostFilter = interpolatedQuery.host?.filter; useEffect(() => { fetchGroups(); }, []); useEffect(() => { fetchHosts(); }, [groupFilter]); useEffect(() => { fetchmacros(); }, [groupFilter, hostFilter]); const onFilterChange = (prop: string) => { return (value: string) => { if (value !== null) { onChange({ ...query, [prop]: { filter: value } }); } }; }; return ( <> ); };