The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/core/components/OptionsUI/registry.tsx

449 lines
13 KiB

import { BooleanFieldSettings } from '@react-awesome-query-builder/ui';
import React from 'react';
import {
FieldConfigPropertyItem,
FieldType,
standardEditorsRegistry,
StandardEditorsRegistryItem,
ThresholdsConfig,
ThresholdsFieldConfigSettings,
ThresholdsMode,
thresholdsOverrideProcessor,
ValueMapping,
ValueMappingFieldConfigSettings,
valueMappingsOverrideProcessor,
DataLink,
dataLinksOverrideProcessor,
NumberFieldConfigSettings,
numberOverrideProcessor,
StringFieldConfigSettings,
stringOverrideProcessor,
identityOverrideProcessor,
TimeZone,
FieldColor,
FieldColorConfigSettings,
StatsPickerConfigSettings,
displayNameOverrideProcessor,
FieldNamePickerConfigSettings,
booleanOverrideProcessor,
} from '@grafana/data';
import { FieldConfig } from '@grafana/schema';
import { RadioButtonGroup, TimeZonePicker, Switch } from '@grafana/ui';
import { FieldNamePicker } from '@grafana/ui/src/components/MatchersUI/FieldNamePicker';
import { ThresholdsValueEditor } from 'app/features/dimensions/editors/ThresholdsEditor/thresholds';
import { ValueMappingsEditor } from 'app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor';
import { DashboardPicker, DashboardPickerOptions } from './DashboardPicker';
import { ColorValueEditor, ColorValueEditorSettings } from './color';
import { FieldColorEditor } from './fieldColor';
import { DataLinksValueEditor } from './links';
import { MultiSelectValueEditor } from './multiSelect';
import { NumberValueEditor } from './number';
import { SelectValueEditor } from './select';
import { SliderValueEditor } from './slider';
import { StatsPickerEditor } from './stats';
import { StringValueEditor } from './string';
import { StringArrayEditor } from './strings';
import { UnitValueEditor } from './units';
/**
* Returns collection of standard option editors definitions
*/
export const getAllOptionEditors = () => {
const number: StandardEditorsRegistryItem<number> = {
id: 'number',
name: 'Number',
description: 'Allows numeric values input',
editor: NumberValueEditor,
};
const slider: StandardEditorsRegistryItem<number> = {
id: 'slider',
name: 'Slider',
description: 'Allows numeric values input',
editor: SliderValueEditor,
};
const text: StandardEditorsRegistryItem<string> = {
id: 'text',
name: 'Text',
description: 'Allows string values input',
editor: StringValueEditor,
};
const strings: StandardEditorsRegistryItem<string[]> = {
id: 'strings',
name: 'String array',
description: 'An array of strings',
editor: StringArrayEditor,
};
const boolean: StandardEditorsRegistryItem<boolean> = {
id: 'boolean',
name: 'Boolean',
description: 'Allows boolean values input',
editor(props) {
const { id, ...rest } = props; // Remove id from properties passed into switch
return <Switch {...rest} onChange={(e) => props.onChange(e.currentTarget.checked)} />;
},
};
const select: StandardEditorsRegistryItem = {
id: 'select',
name: 'Select',
description: 'Allows option selection',
editor: SelectValueEditor,
};
const multiSelect: StandardEditorsRegistryItem = {
id: 'multi-select',
name: 'Multi select',
description: 'Allows for multiple option selection',
editor: MultiSelectValueEditor,
};
const radio: StandardEditorsRegistryItem = {
id: 'radio',
name: 'Radio',
description: 'Allows option selection',
editor(props) {
return <RadioButtonGroup {...props} options={props.item.settings?.options} />;
},
};
const unit: StandardEditorsRegistryItem<string> = {
id: 'unit',
name: 'Unit',
description: 'Allows unit input',
editor: UnitValueEditor,
};
const color: StandardEditorsRegistryItem<string, ColorValueEditorSettings> = {
id: 'color',
name: 'Color',
description: 'Allows color selection',
editor(props) {
return (
<ColorValueEditor value={props.value} onChange={props.onChange} settings={props.item.settings} details={true} />
);
},
};
const fieldColor: StandardEditorsRegistryItem<FieldColor | undefined> = {
id: 'fieldColor',
name: 'Field Color',
description: 'Field color selection',
editor: FieldColorEditor,
};
const links: StandardEditorsRegistryItem<DataLink[]> = {
id: 'links',
name: 'Links',
description: 'Allows defining data links',
editor: DataLinksValueEditor,
};
const statsPicker: StandardEditorsRegistryItem<string[], StatsPickerConfigSettings> = {
id: 'stats-picker',
name: 'Stats Picker',
editor: StatsPickerEditor,
description: '',
};
const timeZone: StandardEditorsRegistryItem<TimeZone> = {
id: 'timezone',
name: 'Time zone',
description: 'Time zone selection',
editor: TimeZonePicker,
};
const fieldName: StandardEditorsRegistryItem<string, FieldNamePickerConfigSettings> = {
id: 'field-name',
name: 'Field name',
description: 'Allows selecting a field name from a data frame',
editor: FieldNamePicker,
};
const dashboardPicker: StandardEditorsRegistryItem<string, DashboardPickerOptions> = {
id: 'dashboard-uid',
name: 'Dashboard',
description: 'Select dashboard',
editor: DashboardPicker,
};
const mappings: StandardEditorsRegistryItem<ValueMapping[]> = {
id: 'mappings',
name: 'Mappings',
description: 'Allows defining value mappings',
editor: ValueMappingsEditor,
};
const thresholds: StandardEditorsRegistryItem<ThresholdsConfig> = {
id: 'thresholds',
name: 'Thresholds',
description: 'Allows defining thresholds',
editor: ThresholdsValueEditor,
};
return [
text,
number,
slider,
boolean,
radio,
select,
unit,
links,
statsPicker,
strings,
timeZone,
fieldColor,
color,
multiSelect,
fieldName,
dashboardPicker,
mappings,
thresholds,
];
};
/**
* Returns collection of common field config properties definitions
*/
export const getAllStandardFieldConfigs = () => {
const category = ['Standard options'];
const displayName: FieldConfigPropertyItem<any, string, StringFieldConfigSettings> = {
id: 'displayName',
path: 'displayName',
name: 'Display name',
description: 'Change the field or series name',
editor: standardEditorsRegistry.get('text').editor,
override: standardEditorsRegistry.get('text').editor,
process: displayNameOverrideProcessor,
settings: {
placeholder: 'none',
expandTemplateVars: true,
},
shouldApply: () => true,
category,
};
const unit: FieldConfigPropertyItem<any, string, StringFieldConfigSettings> = {
id: 'unit',
path: 'unit',
name: 'Unit',
description: '',
editor: standardEditorsRegistry.get('unit').editor,
override: standardEditorsRegistry.get('unit').editor,
process: stringOverrideProcessor,
settings: {
placeholder: 'none',
},
shouldApply: () => true,
category,
};
const unitScale: FieldConfigPropertyItem<unknown, boolean, BooleanFieldSettings> = {
id: 'unitScale',
path: 'unitScale',
name: 'Scale units',
description: 'Automatically scale units relative to magnitude of the value',
editor: standardEditorsRegistry.get('boolean').editor,
override: standardEditorsRegistry.get('boolean').editor,
process: booleanOverrideProcessor,
defaultValue: true,
shouldApply: () => true,
category,
};
const fieldMinMax: FieldConfigPropertyItem<{ min: number; max: number }, boolean, BooleanFieldSettings> = {
id: 'fieldMinMax',
path: 'fieldMinMax',
name: 'Field min/max',
description: 'Calculate min max per field',
editor: standardEditorsRegistry.get('boolean').editor,
override: standardEditorsRegistry.get('boolean').editor,
process: booleanOverrideProcessor,
shouldApply: (field) => field.type === FieldType.number,
showIf: (options: FieldConfig) => {
return options.min === undefined || options.max === undefined;
},
category,
};
const min: FieldConfigPropertyItem<any, number, NumberFieldConfigSettings> = {
id: 'min',
path: 'min',
name: 'Min',
description: 'Leave empty to calculate based on all values',
editor: standardEditorsRegistry.get('number').editor,
override: standardEditorsRegistry.get('number').editor,
process: numberOverrideProcessor,
settings: {
placeholder: 'auto',
},
shouldApply: (field) => field.type === FieldType.number,
category,
};
const max: FieldConfigPropertyItem<any, number, NumberFieldConfigSettings> = {
id: 'max',
path: 'max',
name: 'Max',
description: 'Leave empty to calculate based on all values',
editor: standardEditorsRegistry.get('number').editor,
override: standardEditorsRegistry.get('number').editor,
process: numberOverrideProcessor,
settings: {
placeholder: 'auto',
},
shouldApply: (field) => field.type === FieldType.number,
category,
};
const decimals: FieldConfigPropertyItem<any, number, NumberFieldConfigSettings> = {
id: 'decimals',
path: 'decimals',
name: 'Decimals',
editor: standardEditorsRegistry.get('number').editor,
override: standardEditorsRegistry.get('number').editor,
process: numberOverrideProcessor,
settings: {
placeholder: 'auto',
min: 0,
max: 15,
integer: true,
},
shouldApply: (field) => field.type === FieldType.number,
category,
};
const noValue: FieldConfigPropertyItem<any, string, StringFieldConfigSettings> = {
id: 'noValue',
path: 'noValue',
name: 'No value',
description: 'What to show when there is no value',
editor: standardEditorsRegistry.get('text').editor,
override: standardEditorsRegistry.get('text').editor,
process: stringOverrideProcessor,
settings: {
placeholder: '-',
},
// ??? any optionsUi with no value
shouldApply: () => true,
category,
};
const links: FieldConfigPropertyItem<any, DataLink[], StringFieldConfigSettings> = {
id: 'links',
path: 'links',
name: 'Data links',
editor: standardEditorsRegistry.get('links').editor,
override: standardEditorsRegistry.get('links').editor,
process: dataLinksOverrideProcessor,
settings: {
placeholder: '-',
},
shouldApply: () => true,
category: ['Data links'],
getItemsCount: (value) => (value ? value.length : 0),
};
const color: FieldConfigPropertyItem<any, FieldColor | undefined, FieldColorConfigSettings> = {
id: 'color',
path: 'color',
name: 'Color scheme',
editor: standardEditorsRegistry.get('fieldColor').editor,
override: standardEditorsRegistry.get('fieldColor').editor,
process: identityOverrideProcessor,
shouldApply: () => true,
settings: {
byValueSupport: true,
preferThresholdsMode: true,
},
category,
};
const mappings: FieldConfigPropertyItem<any, ValueMapping[], ValueMappingFieldConfigSettings> = {
id: 'mappings',
path: 'mappings',
name: 'Value mappings',
description: 'Modify the display text based on input value',
editor: standardEditorsRegistry.get('mappings').editor,
override: standardEditorsRegistry.get('mappings').editor,
process: valueMappingsOverrideProcessor,
settings: {},
defaultValue: [],
shouldApply: (x) => x.type !== FieldType.time,
category: ['Value mappings'],
getItemsCount: (value?) => (value ? value.length : 0),
};
const thresholds: FieldConfigPropertyItem<any, ThresholdsConfig, ThresholdsFieldConfigSettings> = {
id: 'thresholds',
path: 'thresholds',
name: 'Thresholds',
editor: standardEditorsRegistry.get('thresholds').editor,
override: standardEditorsRegistry.get('thresholds').editor,
process: thresholdsOverrideProcessor,
settings: {},
defaultValue: {
mode: ThresholdsMode.Absolute,
steps: [
{ value: -Infinity, color: 'green' },
{ value: 80, color: 'red' },
],
},
shouldApply: () => true,
category: ['Thresholds'],
getItemsCount: (value) => (value ? value.steps.length : 0),
};
const filterable: FieldConfigPropertyItem<{}, boolean | undefined, {}> = {
id: 'filterable',
path: 'filterable',
name: 'Ad-hoc filterable',
hideFromDefaults: true,
editor: standardEditorsRegistry.get('boolean').editor,
override: standardEditorsRegistry.get('boolean').editor,
process: booleanOverrideProcessor,
shouldApply: () => true,
settings: {},
category,
};
return [
unit,
unitScale,
min,
max,
fieldMinMax,
decimals,
displayName,
color,
noValue,
links,
mappings,
thresholds,
filterable,
];
};