diff --git a/src/components/editors/IconsEditor.tsx b/src/components/editors/IconsEditor.tsx index ac6b6ee..9aee9cd 100644 --- a/src/components/editors/IconsEditor.tsx +++ b/src/components/editors/IconsEditor.tsx @@ -121,7 +121,6 @@ export function IconsEditor({ onChange, value, context }: StandardEditorProps { - console.log(value); // @ts-ignore icons[iconIdx][field][conditionIdx] = value; @@ -138,52 +137,63 @@ export function IconsEditor({ onChange, value, context }: StandardEditorProps { return (
- removeIcon(iconIdx)}> - onIconFieldChange(iconIdx, 'url', (evt.target as any).value)} - /> + removeIcon(iconIdx)} + tooltip="Delete Icon" + > +
+ onIconFieldChange(iconIdx, 'url', (evt.target as any).value)} + /> +
onIconFieldChange(iconIdx, 'position', newVal)} /> - onIconFieldChange(iconIdx, 'size', newVal)} - /> +
+ onIconFieldChange(iconIdx, 'size', newVal)} + /> +
{icon.conditions.map((condition, conditionIdx) => { return ( - - onConditionChange(iconIdx, conditionIdx, 'metrics', newVal)} - item={fieldNamePickerSettings} - /> - onConditionChange(iconIdx, conditionIdx, 'conditions', newVal)} - /> - - onConditionChange(iconIdx, conditionIdx, 'values', (evt.target as any).value) - } - /> - removeCondition(iconIdx, conditionIdx)} - > - +
+ + onConditionChange(iconIdx, conditionIdx, 'metrics', newVal)} + item={fieldNamePickerSettings} + /> + onConditionChange(iconIdx, conditionIdx, 'conditions', newVal)} + /> + + onConditionChange(iconIdx, conditionIdx, 'values', (evt.target as any).value) + } + /> + removeCondition(iconIdx, conditionIdx)} + tooltip="Delete Condition" + > + +
); })}
- } - /> + + + onFieldChange('defaultColor', val)} + enableNamedColors={false} + /> + + + + + + onFieldChange('arcBackground', val)} + enableNamedColors={false} + /> + + {config.thresholds.map((threshold, thresholdIdx) => { return ( - - onThresholdFieldChange(thresholdIdx, 'color', newVal)} - enableNamedColors={true} - /> - - } - /> onThresholdFieldChange(thresholdIdx, 'useMetric', (evt.target as any).checked)} /> - {threshold.useMetric ? ( - onThresholdFieldChange(thresholdIdx, 'metricName', newVal)} - item={fieldNamePickerSettings} - /> - ) : ( - onThresholdFieldChange(thresholdIdx, 'value', (evt.target as any).value)} - /> - )} - removeThreshold(thresholdIdx)}> + + {threshold.useMetric ? ( + onThresholdFieldChange(thresholdIdx, 'metricName', newVal)} + item={fieldNamePickerSettings} + /> + ) : ( + onThresholdFieldChange(thresholdIdx, 'value', (evt.target as any).value)} + /> + )} + + + + onThresholdFieldChange(thresholdIdx, 'color', newVal)} + enableNamedColors={false} + /> + + + + + removeThreshold(thresholdIdx)} + tooltip="Delete Threshold" + > + + ); })} @@ -147,3 +147,15 @@ export function ThresholdsEditor({ onChange, value, context }: StandardEditorPro ); } + +interface ThresholdsEditorStyles { + deleteButton: string; +} + +const getStyles = stylesFactory((theme: GrafanaTheme): ThresholdsEditorStyles => { + return { + deleteButton: css` + margin-right: 0px!important; + `, + }; +}); diff --git a/src/components/editors/UseMetricEditor.tsx b/src/components/editors/UseMetricEditor.tsx new file mode 100644 index 0000000..37f7de0 --- /dev/null +++ b/src/components/editors/UseMetricEditor.tsx @@ -0,0 +1,62 @@ +import { FieldNamePicker } from '../../grafana/MatchersUI/FieldNamePicker'; + +import { StandardEditorProps } from '@grafana/data'; +import { + HorizontalGroup, + InlineField, + InlineSwitch, + Input, +} from '@grafana/ui'; + +import React from 'react'; + +import * as _ from 'lodash'; + + +type UseMetricConfig = { + useMetric: boolean; + value?: number; + metricName?: string; +}; + +const fieldNamePickerSettings = { + settings: { width: 24 }, +} as any; + +export function UseMetricEditor({ onChange, value, context }: StandardEditorProps) { + const config = value; + + const onFieldChange = (field: keyof UseMetricConfig, value: any) => { + // @ts-ignore + config[field] = value; + + onChange(config); + } + + return ( + + + onFieldChange('useMetric', (evt.target as any).checked)} + /> + + + {config.useMetric ? ( + onFieldChange('metricName', newVal)} + item={fieldNamePickerSettings} + /> + ) : ( + onFieldChange('value', (evt.target as any).value)} + /> + )} + + + ) +} diff --git a/src/module.ts b/src/module.ts index e366a4a..af79332 100644 --- a/src/module.ts +++ b/src/module.ts @@ -1,11 +1,15 @@ import { PanelOptions, Pod } from './types'; import { Panel } from './components/Panel'; + import { IconsEditor } from './components/editors/IconsEditor'; import { ThresholdsEditor } from './components/editors/ThresholdsEditor'; +import { NotSupportedText } from './components/editors/NotSupportedText'; +import { UseMetricEditor } from './components/editors/UseMetricEditor'; import { PanelPlugin } from '@grafana/data'; + export const plugin = new PanelPlugin(Panel).setPanelOptions((builder) => { return builder .addRadio({ @@ -18,21 +22,26 @@ export const plugin = new PanelPlugin(Panel).setPanelOptions((buil { label: 'Gauge', value: Pod.GAUGE, - description: 'Enable gauge pod', }, { label: 'Line', value: Pod.LINE, - description: 'Enable line pod', }, { label: 'Bar', value: Pod.BAR, - description: 'Enable bar pod', }, ], }, }) + .addCustomEditor({ + id: 'notSupportedText', + name: 'This visualization is not supported', + category: ['Visualization'], + path: '', + showIf: (config) => config.visualizationType !== Pod.GAUGE, + editor: NotSupportedText as any, + }) .addFieldNamePicker({ name: 'Value', @@ -40,46 +49,55 @@ export const plugin = new PanelPlugin(Panel).setPanelOptions((buil category: ['Extremum'], showIf: (config) => config.visualizationType === Pod.GAUGE, }) - - .addNumberInput({ - path: 'gauge.min.value', - name: 'Min', - category: ['Extremum'], - showIf: (config) => config.visualizationType === Pod.GAUGE && !config.gauge.min.useMetric, - }) - .addFieldNamePicker({ + // TODO: defaults? + .addCustomEditor({ + id: 'min', name: 'Min', - path: 'gauge.min.metricName', + path: 'gauge.min', category: ['Extremum'], - showIf: (config) => config.visualizationType === Pod.GAUGE && config.gauge.min.useMetric, - }) - .addBooleanSwitch({ - path: 'gauge.min.useMetric', - name: 'Use metric', - defaultValue: false, + showIf: (config) => config.visualizationType === Pod.GAUGE, + editor: UseMetricEditor as any, + }). + addCustomEditor({ + id: 'max', + name: 'Max', + path: 'gauge.max', category: ['Extremum'], showIf: (config) => config.visualizationType === Pod.GAUGE, + editor: UseMetricEditor as any, }) - .addNumberInput({ - path: 'gauge.max.value', - name: 'Max', - category: ['Extremum'], - showIf: (config) => config.visualizationType === Pod.GAUGE && !config.gauge.max.useMetric, + // note: `gauge.unit` will contain unit name, not it's string representation + // to format value with unit, use `getValueFormat` function from `@grafana/data` + .addUnitPicker({ + path: 'gauge.unit', + name: 'Unit', + category: ['Value Format'], + showIf: (config) => config.visualizationType === Pod.GAUGE, }) - .addFieldNamePicker({ - name: 'Max', - path: 'gauge.max.metricName', - category: ['Extremum'], - showIf: (config) => config.visualizationType === Pod.GAUGE && config.gauge.max.useMetric, + .addNumberInput({ + path: 'gauge.decimals', + name: 'Decimals', + settings: { + placeholder: 'auto', + min: 0, + max: 5, + }, + category: ['Value Format'], + showIf: (config) => config.visualizationType === Pod.GAUGE, }) - .addBooleanSwitch({ - path: 'gauge.max.useMetric', - name: 'Use metric', - defaultValue: false, - category: ['Extremum'], + .addSliderInput({ + path: 'gauge.size', + defaultValue: 20, + name: 'Size (px)', + settings: { + min: 1, + max: 50, + }, + category: ['Value Format'], showIf: (config) => config.visualizationType === Pod.GAUGE, }) + .addBooleanSwitch({ path: 'gauge.reversed', name: 'Reversed', @@ -87,6 +105,7 @@ export const plugin = new PanelPlugin(Panel).setPanelOptions((buil category: ['Direction'], showIf: (config) => config.visualizationType === Pod.GAUGE, }) + .addCustomEditor({ id: 'icons', path: 'gauge.icons',