diff --git a/packages/grafana-data/src/utils/valueMappings.test.ts b/packages/grafana-data/src/utils/valueMappings.test.ts index 2b60616d850..90686b52895 100644 --- a/packages/grafana-data/src/utils/valueMappings.test.ts +++ b/packages/grafana-data/src/utils/valueMappings.test.ts @@ -185,6 +185,40 @@ describe('Format value with value mappings', () => { }); }); +describe('Range mapping with null From or null To', () => { + expect( + getValueMappingResult( + [ + { + type: MappingType.RangeToText, + options: { + from: 0, + to: null, + result: { text: 'pos' }, + }, + }, + ], + 100 + ) + ).toEqual({ text: 'pos' }); + + expect( + getValueMappingResult( + [ + { + type: MappingType.RangeToText, + options: { + from: null, + to: 0, + result: { text: 'neg' }, + }, + }, + ], + -100 + ) + ).toEqual({ text: 'neg' }); +}); + describe('Format value with regex mappings', () => { it('should return correct regular expression result', () => { const value = 'www.foo.com'; diff --git a/packages/grafana-data/src/utils/valueMappings.ts b/packages/grafana-data/src/utils/valueMappings.ts index d7ab2cf6a24..910cf55511f 100644 --- a/packages/grafana-data/src/utils/valueMappings.ts +++ b/packages/grafana-data/src/utils/valueMappings.ts @@ -35,13 +35,17 @@ export function getValueMappingResult(valueMappings: ValueMapping[], value: any) continue; } - const isNumFrom = !isNaN(vm.options.from!); - if (isNumFrom && valueAsNumber < vm.options.from!) { + const from = vm.options.from ?? -Infinity; + + const isNumFrom = !isNaN(from); + if (isNumFrom && valueAsNumber < from) { continue; } - const isNumTo = !isNaN(vm.options.to!); - if (isNumTo && valueAsNumber > vm.options.to!) { + const to = vm.options.to ?? Infinity; + + const isNumTo = !isNaN(to); + if (isNumTo && valueAsNumber > to) { continue; } diff --git a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingEditRow.tsx b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingEditRow.tsx index c26e5a26781..bb8215ffbe6 100644 --- a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingEditRow.tsx +++ b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingEditRow.tsx @@ -11,8 +11,8 @@ import { ResourcePicker } from '../ResourcePicker'; export interface ValueMappingEditRowModel { type: MappingType; - from?: number; - to?: number; + from?: number | null; + to?: number | null; pattern?: string; key?: string; isNew?: boolean; @@ -149,20 +149,8 @@ export function ValueMappingEditRow({ mapping, index, onChange, onRemove, onDupl )} {mapping.type === MappingType.RangeToText && (
- - + +
)} {mapping.type === MappingType.RegexToText && ( diff --git a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor.tsx b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor.tsx index 9bdb3ec96c8..3bbeff8882a 100644 --- a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor.tsx +++ b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor.tsx @@ -51,7 +51,7 @@ export const ValueMappingsEditor = memo((props: Props) => { {row.type === MappingType.ValueToText && row.key} {row.type === MappingType.RangeToText && ( - [{row.from} - {row.to}] + [{row.from ?? '-∞'} - {row.to ?? '∞'}] )} {row.type === MappingType.RegexToText && row.pattern} diff --git a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.test.tsx b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.test.tsx index 1090c942122..065f9d304fe 100644 --- a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.test.tsx +++ b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.test.tsx @@ -134,11 +134,11 @@ describe('ValueMappingsEditorModal', () => { ); await selectOptionInTest(selectComponent, 'Range'); - await userEvent.clear(screen.getByPlaceholderText('Range start')); - await userEvent.type(screen.getByPlaceholderText('Range start'), '10'); + await userEvent.clear(screen.getByPlaceholderText('From')); + await userEvent.type(screen.getByPlaceholderText('From'), '10'); - await userEvent.clear(screen.getByPlaceholderText('Range end')); - await userEvent.type(screen.getByPlaceholderText('Range end'), '20'); + await userEvent.clear(screen.getByPlaceholderText('To')); + await userEvent.type(screen.getByPlaceholderText('To'), '20'); await userEvent.clear(screen.getByPlaceholderText('Optional display text')); await userEvent.type(screen.getByPlaceholderText('Optional display text'), 'display'); diff --git a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.tsx b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.tsx index 9b970427143..199563a65fc 100644 --- a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.tsx +++ b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.tsx @@ -218,12 +218,12 @@ export function editModelToSaveModel(rows: ValueMappingEditRowModel[]) { } break; case MappingType.RangeToText: - if (item.from != null && item.to != null) { + if (item.from != null || item.to != null) { mappings.push({ type: item.type, options: { - from: item.from, - to: item.to, + from: item.from ?? null, + to: item.to ?? null, result, }, }); @@ -279,8 +279,8 @@ export function buildEditRowModels(value: ValueMapping[]) { createRow({ type: mapping.type, result: mapping.options.result, - from: mapping.options.from ?? 0, - to: mapping.options.to ?? 0, + from: mapping.options.from, + to: mapping.options.to, }) ); break;