Standardization across Zabbix UI components (#2141)

## Summary

Throughout Zabbix we did not have a uniform UI - some drop-down were
using `Select` others `Combobox` others a custom one that we created.
Some had placeholders and others did not. This PR aims to standardize
our Zabbix UI across our query, variable and config editors

## Detailed summary 

- Migrate from `Select` to `Combobox` -> `Select` component is
deprecated
- Migrate from `HorizontalGroup` to `Stack` -> `HorizontalGroup` is also
deprecated
- Remove use of "custom" dropdown `MetricPickerMenu` in favor of
`Combobox` ensuring uniformity across our drop-down and removing
maintenance overhead for us down the line
- Standardize placeholders across all inputs

<img width="630" height="243" alt="Screenshot 2025-12-17 at 1 13 45 PM"
src="https://github.com/user-attachments/assets/9382057e-b443-4474-a9c8-850086d7f3d4"
/>

<img width="691" height="256" alt="Screenshot 2025-12-17 at 1 14 05 PM"
src="https://github.com/user-attachments/assets/a05ff2af-8603-4752-8d12-337dc381c0fd"
/>

## Why
To have a clean and standard UI and remove use of UI deprecated
packages.

## How to test
- Query Editor:
- By creating a new query in a dashboard or Explore and interacting with
all the different query types and drop-downs
     - All drop-downs should be searchable and have placeholders
- Config Editor:
- By going to a datasource and ensuring that the dropdown for Datasource
(when DB connection is enabled) and Auth type are responsive and working
as expected)


Fixes:
https://github.com/orgs/grafana/projects/457/views/40?pane=issue&itemId=3740545830&issue=grafana%7Coss-big-tent-squad%7C139
This commit is contained in:
Jocelyn Collado-Kuri
2025-12-18 06:28:29 -08:00
committed by GitHub
parent ce4a8d3e19
commit 127367464e
14 changed files with 152 additions and 356 deletions

View File

@@ -3,7 +3,7 @@ import React, { useEffect, FormEvent } from 'react';
import { useAsyncFn } from 'react-use';
import { SelectableValue } from '@grafana/data';
import { InlineField, Input, MultiSelect, Select } from '@grafana/ui';
import { Combobox, ComboboxOption, InlineField, Input, MultiSelect } from '@grafana/ui';
import { QueryEditorRow } from './QueryEditorRow';
import { MetricPicker } from '../../../components';
import { getVariableOptions } from './utils';
@@ -11,7 +11,7 @@ import { ZabbixDatasource } from '../../datasource';
import { ZabbixMetricsQuery, ZabbixTagEvalType } from '../../types/query';
import { useInterpolatedQuery } from '../../hooks/useInterpolatedQuery';
const showProblemsOptions: Array<SelectableValue<string>> = [
const showProblemsOptions: Array<ComboboxOption<string>> = [
{ label: 'Problems', value: 'problems' },
{ label: 'Recent problems', value: 'recent' },
{ label: 'History', value: 'history' },
@@ -26,7 +26,7 @@ const severityOptions: Array<SelectableValue<number>> = [
{ value: 5, label: 'Disaster' },
];
const evaltypeOptions: Array<SelectableValue<ZabbixTagEvalType>> = [
const evaltypeOptions: Array<ComboboxOption<ZabbixTagEvalType>> = [
{ label: 'AND/OR', value: ZabbixTagEvalType.AndOr },
{ label: 'OR', value: ZabbixTagEvalType.Or },
];
@@ -57,7 +57,7 @@ export const ProblemsQueryEditor = ({ query, datasource, onChange }: Props) => {
const loadHostOptions = async (group: string) => {
const hosts = await datasource.zabbix.getAllHosts(group);
let options: Array<SelectableValue<string>> = hosts?.map((host) => ({
let options: Array<ComboboxOption<string>> = hosts?.map((host) => ({
value: host.name,
label: host.name,
}));
@@ -74,7 +74,7 @@ export const ProblemsQueryEditor = ({ query, datasource, onChange }: Props) => {
const loadAppOptions = async (group: string, host: string) => {
const apps = await datasource.zabbix.getAllApps(group, host);
let options: Array<SelectableValue<string>> = apps?.map((app) => ({
let options: Array<ComboboxOption<string>> = apps?.map((app) => ({
value: app.name,
label: app.name,
}));
@@ -166,6 +166,7 @@ export const ProblemsQueryEditor = ({ query, datasource, onChange }: Props) => {
options={groupsOptions}
isLoading={groupsLoading}
onChange={onFilterChange('group')}
placeholder="Group name"
/>
</InlineField>
<InlineField label="Host" labelWidth={12}>
@@ -175,6 +176,7 @@ export const ProblemsQueryEditor = ({ query, datasource, onChange }: Props) => {
options={hostOptions}
isLoading={hostsLoading}
onChange={onFilterChange('host')}
placeholder="Host name"
/>
</InlineField>
<InlineField label="Proxy" labelWidth={12}>
@@ -184,6 +186,7 @@ export const ProblemsQueryEditor = ({ query, datasource, onChange }: Props) => {
options={proxiesOptions}
isLoading={proxiesLoading}
onChange={onFilterChange('proxy')}
placeholder="Proxy name"
/>
</InlineField>
</QueryEditorRow>
@@ -196,6 +199,7 @@ export const ProblemsQueryEditor = ({ query, datasource, onChange }: Props) => {
options={appOptions}
isLoading={appsLoading}
onChange={onFilterChange('application')}
placeholder="Application name"
/>
</InlineField>
)}
@@ -216,19 +220,12 @@ export const ProblemsQueryEditor = ({ query, datasource, onChange }: Props) => {
/>
</InlineField>
<InlineField>
<Select
isSearchable={false}
width={15}
value={query.evaltype}
options={evaltypeOptions}
onChange={onPropChange('evaltype')}
/>
<Combobox width={15} value={query.evaltype} options={evaltypeOptions} onChange={onPropChange('evaltype')} />
</InlineField>
</QueryEditorRow>
<QueryEditorRow>
<InlineField label="Show" labelWidth={12}>
<Select
isSearchable={false}
<Combobox
width={24}
value={query.showProblems}
options={showProblemsOptions}