import _ from 'lodash'; import React, { useEffect, FormEvent } from 'react'; import { useAsyncFn } from 'react-use'; import { SelectableValue } from '@grafana/data'; import { Combobox, ComboboxOption, InlineField, Input, MultiSelect } from '@grafana/ui'; import { QueryEditorRow } from './QueryEditorRow'; import { MetricPicker } from '../../../components'; import { getVariableOptions } from './utils'; import { ZabbixDatasource } from '../../datasource'; import { ZabbixMetricsQuery, ZabbixTagEvalType } from '../../types/query'; import { useInterpolatedQuery } from '../../hooks/useInterpolatedQuery'; const showProblemsOptions: Array> = [ { label: 'Problems', value: 'problems' }, { label: 'Recent problems', value: 'recent' }, { label: 'History', value: 'history' }, ]; const severityOptions: Array> = [ { value: 0, label: 'Not classified' }, { value: 1, label: 'Information' }, { value: 2, label: 'Warning' }, { value: 3, label: 'Average' }, { value: 4, label: 'High' }, { value: 5, label: 'Disaster' }, ]; const evaltypeOptions: Array> = [ { label: 'AND/OR', value: ZabbixTagEvalType.AndOr }, { label: 'OR', value: ZabbixTagEvalType.Or }, ]; export interface Props { query: ZabbixMetricsQuery; datasource: ZabbixDatasource; onChange: (query: ZabbixMetricsQuery) => void; } export const ProblemsQueryEditor = ({ 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 loadAppOptions = async (group: string, host: string) => { const apps = await datasource.zabbix.getAllApps(group, host); let options: Array> = apps?.map((app) => ({ value: app.name ?? '', label: app.name ?? '', })); options = _.uniqBy(options, (o) => o.value); options.unshift(...getVariableOptions()); return options; }; const [{ loading: appsLoading, value: appOptions }, fetchApps] = useAsyncFn(async () => { const options = await loadAppOptions(interpolatedQuery.group.filter, interpolatedQuery.host.filter); return options; }, [interpolatedQuery.group.filter, interpolatedQuery.host.filter]); const loadProxyOptions = async () => { const proxies = await datasource.zabbix.getProxies(); const options = proxies?.map((proxy) => ({ value: (!!proxy.host ? proxy.host : proxy.name) ?? '', label: (!!proxy.host ? proxy.host : proxy.name) ?? '', })); options.unshift(...getVariableOptions()); return options; }; const [{ loading: proxiesLoading, value: proxiesOptions }, fetchProxies] = useAsyncFn(async () => { const options = await loadProxyOptions(); return options; }, []); // Update suggestions on every metric change const groupFilter = interpolatedQuery.group?.filter; const hostFilter = interpolatedQuery.host?.filter; useEffect(() => { fetchGroups(); }, []); useEffect(() => { fetchHosts(); }, [groupFilter]); useEffect(() => { fetchApps(); }, [groupFilter, hostFilter]); useEffect(() => { fetchProxies(); }, []); const onTextFilterChange = (prop: string) => { return (v: FormEvent) => { const newValue = v?.currentTarget?.value; if (newValue !== null) { onChange({ ...query, [prop]: { filter: newValue } }); } }; }; const onFilterChange = (prop: string) => { return (value: string) => { if (value !== null) { onChange({ ...query, [prop]: { filter: value } }); } }; }; const onPropChange = (prop: string) => { return (option: SelectableValue) => { if (option.value !== null) { onChange({ ...query, [prop]: option.value }); } }; }; const onSeveritiesChange = (options: SelectableValue[]) => { if (options !== null) { onChange({ ...query, options: { ...query.options, severities: options.map((o) => o.value) } }); } }; const supportsApplications = datasource.zabbix.supportsApplications(); return ( <> {supportsApplications && ( )} ); };