mirror of
https://github.com/grafana/grafana.git
synced 2025-02-20 11:48:34 -06:00
Thresholds: Fixed issue with thresholds in overrides not working after save and reload (#27297)
* WIP: Fix null thresholds in overrides when loading * Fix thresholds on load instead of in apply field overrides * simplify expression * fixed ts issue * Updated test * Updated another test * Updated another test
This commit is contained in:
parent
d07755b624
commit
1f6c2dbcfb
@ -2,10 +2,8 @@ import merge from 'lodash/merge';
|
||||
import { getFieldDisplayValues, GetFieldDisplayValuesOptions } from './fieldDisplay';
|
||||
import { toDataFrame } from '../dataframe/processDataFrame';
|
||||
import { ReducerID } from '../transformations/fieldReducer';
|
||||
import { ThresholdsMode } from '../types/thresholds';
|
||||
import { GrafanaTheme } from '../types/theme';
|
||||
import { FieldConfig, MappingType } from '../types';
|
||||
import { validateFieldConfig } from './fieldOverrides';
|
||||
import { MappingType } from '../types';
|
||||
import { standardFieldConfigEditorRegistry } from './standardFieldConfigEditorRegistry';
|
||||
|
||||
describe('FieldDisplay', () => {
|
||||
@ -74,27 +72,6 @@ describe('FieldDisplay', () => {
|
||||
expect(display.map(v => v.display.numeric)).toEqual([1, 3]); // First 2 are from the first field
|
||||
});
|
||||
|
||||
it('should restore -Infinity value for base threshold', () => {
|
||||
const config: FieldConfig = {
|
||||
thresholds: {
|
||||
mode: ThresholdsMode.Absolute,
|
||||
steps: [
|
||||
{
|
||||
color: '#73BF69',
|
||||
value: (null as any) as number, // -Infinity becomes null in JSON
|
||||
},
|
||||
{
|
||||
color: '#F2495C',
|
||||
value: 50,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
validateFieldConfig(config);
|
||||
expect(config.thresholds!.steps.length).toEqual(2);
|
||||
expect(config.thresholds!.steps[0].value).toBe(-Infinity);
|
||||
});
|
||||
|
||||
it('Should return field thresholds when there is no data', () => {
|
||||
const options = createEmptyDisplayOptions({
|
||||
fieldConfig: {
|
||||
|
@ -4,7 +4,6 @@ import {
|
||||
DataFrame,
|
||||
Field,
|
||||
FieldType,
|
||||
ThresholdsMode,
|
||||
FieldColorMode,
|
||||
ColorScheme,
|
||||
FieldOverrideContext,
|
||||
@ -308,18 +307,6 @@ const processFieldConfigValue = (
|
||||
*/
|
||||
export function validateFieldConfig(config: FieldConfig) {
|
||||
const { thresholds } = config;
|
||||
if (thresholds) {
|
||||
if (!thresholds.mode) {
|
||||
thresholds.mode = ThresholdsMode.Absolute;
|
||||
}
|
||||
if (!thresholds.steps) {
|
||||
thresholds.steps = [];
|
||||
} else if (thresholds.steps.length) {
|
||||
// First value is always -Infinity
|
||||
// JSON saves it as null
|
||||
thresholds.steps[0].value = -Infinity;
|
||||
}
|
||||
}
|
||||
|
||||
if (!config.color) {
|
||||
if (thresholds) {
|
||||
|
@ -17,7 +17,7 @@ describe('sharedSingleStatMigrationHandler', () => {
|
||||
{
|
||||
color: 'green',
|
||||
index: 0,
|
||||
value: null,
|
||||
value: -Infinity,
|
||||
},
|
||||
{
|
||||
color: 'orange',
|
||||
|
@ -96,6 +96,13 @@ describe('PanelModel', () => {
|
||||
fieldConfig: {
|
||||
defaults: {
|
||||
unit: 'mpg',
|
||||
thresholds: {
|
||||
mode: 'absolute',
|
||||
steps: [
|
||||
{ color: 'green', value: null },
|
||||
{ color: 'red', value: 80 },
|
||||
],
|
||||
},
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
@ -103,7 +110,18 @@ describe('PanelModel', () => {
|
||||
id: '1',
|
||||
options: {},
|
||||
},
|
||||
properties: [],
|
||||
properties: [
|
||||
{
|
||||
id: 'thresholds',
|
||||
value: {
|
||||
mode: 'absolute',
|
||||
steps: [
|
||||
{ color: 'green', value: null },
|
||||
{ color: 'red', value: 80 },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -146,6 +164,11 @@ describe('PanelModel', () => {
|
||||
expect(model.getOptions().showThresholds).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should change null thresholds to negative infinity', () => {
|
||||
expect(model.fieldConfig.defaults.thresholds.steps[0].value).toBe(-Infinity);
|
||||
expect(model.fieldConfig.overrides[0].properties[0].value.steps[0].value).toBe(-Infinity);
|
||||
});
|
||||
|
||||
it('should apply option defaults but not override if array is changed', () => {
|
||||
expect(model.getOptions().arrayWith2Values.length).toBe(1);
|
||||
});
|
||||
|
@ -16,6 +16,8 @@ import {
|
||||
PanelEvents,
|
||||
PanelPlugin,
|
||||
ScopedVars,
|
||||
ThresholdsConfig,
|
||||
ThresholdsMode,
|
||||
} from '@grafana/data';
|
||||
import { EDIT_PANEL_ID } from 'app/core/constants';
|
||||
import config from 'app/core/config';
|
||||
@ -317,22 +319,7 @@ export class PanelModel implements DataConfigSource {
|
||||
}
|
||||
});
|
||||
|
||||
this.fieldConfig = {
|
||||
defaults: _.mergeWith(
|
||||
{},
|
||||
plugin.fieldConfigDefaults.defaults,
|
||||
this.fieldConfig ? this.fieldConfig.defaults : {},
|
||||
(objValue: any, srcValue: any): any => {
|
||||
if (_.isArray(srcValue)) {
|
||||
return srcValue;
|
||||
}
|
||||
}
|
||||
),
|
||||
overrides: [
|
||||
...plugin.fieldConfigDefaults.overrides,
|
||||
...(this.fieldConfig && this.fieldConfig.overrides ? this.fieldConfig.overrides : []),
|
||||
],
|
||||
};
|
||||
this.fieldConfig = applyFieldConfigDefaults(this.fieldConfig, this.plugin!.fieldConfigDefaults);
|
||||
}
|
||||
|
||||
pluginLoaded(plugin: PanelPlugin) {
|
||||
@ -503,6 +490,51 @@ export class PanelModel implements DataConfigSource {
|
||||
}
|
||||
}
|
||||
|
||||
function applyFieldConfigDefaults(fieldConfig: FieldConfigSource, defaults: FieldConfigSource): FieldConfigSource {
|
||||
const result: FieldConfigSource = {
|
||||
defaults: _.mergeWith(
|
||||
{},
|
||||
defaults.defaults,
|
||||
fieldConfig ? fieldConfig.defaults : {},
|
||||
(objValue: any, srcValue: any): any => {
|
||||
if (_.isArray(srcValue)) {
|
||||
return srcValue;
|
||||
}
|
||||
}
|
||||
),
|
||||
overrides: fieldConfig?.overrides ?? [],
|
||||
};
|
||||
|
||||
// Thresholds base values are null in JSON but need to be converted to -Infinity
|
||||
if (result.defaults.thresholds) {
|
||||
fixThresholds(result.defaults.thresholds);
|
||||
}
|
||||
|
||||
for (const override of result.overrides) {
|
||||
for (const property of override.properties) {
|
||||
if (property.id === 'thresholds') {
|
||||
fixThresholds(property.value as ThresholdsConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function fixThresholds(thresholds: ThresholdsConfig) {
|
||||
if (!thresholds.mode) {
|
||||
thresholds.mode = ThresholdsMode.Absolute;
|
||||
}
|
||||
|
||||
if (!thresholds.steps) {
|
||||
thresholds.steps = [];
|
||||
} else if (thresholds.steps.length) {
|
||||
// First value is always -Infinity
|
||||
// JSON saves it as null
|
||||
thresholds.steps[0].value = -Infinity;
|
||||
}
|
||||
}
|
||||
|
||||
function getPluginVersion(plugin: PanelPlugin): string {
|
||||
return plugin && plugin.meta.info.version ? plugin.meta.info.version : config.buildInfo.version;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ describe('BarGauge Panel Migrations', () => {
|
||||
{
|
||||
color: 'green',
|
||||
index: 0,
|
||||
value: null,
|
||||
value: -Infinity,
|
||||
},
|
||||
{
|
||||
color: 'orange',
|
||||
|
@ -22,7 +22,7 @@ describe('Gauge Panel Migrations', () => {
|
||||
{
|
||||
color: 'green',
|
||||
index: 0,
|
||||
value: null,
|
||||
value: -Infinity,
|
||||
},
|
||||
{
|
||||
color: '#EAB839',
|
||||
|
Loading…
Reference in New Issue
Block a user