From 98406d6c429a51fc67484405e3325a6cfc8bb729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Thu, 21 Jan 2021 06:23:09 +0100 Subject: [PATCH] Alerting: Hides threshold handle for percentual thresholds (#30431) --- public/app/features/alerting/AlertTabCtrl.ts | 1 + .../alerting/state/ThresholdMapper.test.ts | 65 ++++++++++++++++++- .../alerting/state/ThresholdMapper.ts | 22 ++++--- .../plugins/panel/graph/threshold_manager.ts | 4 ++ 4 files changed, 80 insertions(+), 12 deletions(-) diff --git a/public/app/features/alerting/AlertTabCtrl.ts b/public/app/features/alerting/AlertTabCtrl.ts index 05b53431481..8745eeb7d56 100644 --- a/public/app/features/alerting/AlertTabCtrl.ts +++ b/public/app/features/alerting/AlertTabCtrl.ts @@ -390,6 +390,7 @@ export class AlertTabCtrl { case 'action': { conditionModel.source.reducer.type = evt.action.value; conditionModel.reducerPart = alertDef.createReducerPart(conditionModel.source.reducer); + this.evaluatorParamsChanged(); break; } case 'get-part-actions': { diff --git a/public/app/features/alerting/state/ThresholdMapper.test.ts b/public/app/features/alerting/state/ThresholdMapper.test.ts index 8491073ce4e..df70c654af5 100644 --- a/public/app/features/alerting/state/ThresholdMapper.test.ts +++ b/public/app/features/alerting/state/ThresholdMapper.test.ts @@ -1,6 +1,9 @@ -import { describe, it, expect } from 'test/lib/common'; +import { hiddenReducerTypes, ThresholdMapper } from './ThresholdMapper'; +import alertDef from './alertDef'; -import { ThresholdMapper } from './ThresholdMapper'; +const visibleReducerTypes = alertDef.reducerTypes + .filter(({ value }) => hiddenReducerTypes.indexOf(value) === -1) + .map(({ value }) => value); describe('ThresholdMapper', () => { describe('with greater than evaluator', () => { @@ -74,4 +77,62 @@ describe('ThresholdMapper', () => { expect(panel.thresholds[1].value).toBe(200); }); }); + + visibleReducerTypes.forEach((type) => { + describe(`with {${type}} reducer`, () => { + it('visible should be true', () => { + const panel = getPanel({ reducerType: type }); + + const updated = ThresholdMapper.alertToGraphThresholds(panel); + + expect(updated).toBe(true); + expect(panel.thresholds[0]).toEqual({ + value: 100, + op: 'gt', + fill: true, + line: true, + colorMode: 'critical', + visible: true, + }); + }); + }); + }); + + hiddenReducerTypes.forEach((type) => { + describe(`with {${type}} reducer`, () => { + it('visible should be false', () => { + const panel = getPanel({ reducerType: type }); + + const updated = ThresholdMapper.alertToGraphThresholds(panel); + + expect(updated).toBe(true); + expect(panel.thresholds[0]).toEqual({ + value: 100, + op: 'gt', + fill: true, + line: true, + colorMode: 'critical', + visible: false, + }); + }); + }); + }); }); + +function getPanel({ reducerType }: { reducerType?: string } = {}) { + const panel: any = { + type: 'graph', + options: { alertThreshold: true }, + alert: { + conditions: [ + { + type: 'query', + evaluator: { type: 'gt', params: [100] }, + reducer: { type: reducerType }, + }, + ], + }, + }; + + return panel; +} diff --git a/public/app/features/alerting/state/ThresholdMapper.ts b/public/app/features/alerting/state/ThresholdMapper.ts index c2b053056c4..e382919fe35 100644 --- a/public/app/features/alerting/state/ThresholdMapper.ts +++ b/public/app/features/alerting/state/ThresholdMapper.ts @@ -1,5 +1,6 @@ import { PanelModel } from 'app/features/dashboard/state'; +export const hiddenReducerTypes = ['percent_diff', 'percent_diff_abs']; export class ThresholdMapper { static alertToGraphThresholds(panel: PanelModel) { if (!panel.alert) { @@ -14,16 +15,17 @@ export class ThresholdMapper { const evaluator = condition.evaluator; const thresholds: any[] = (panel.thresholds = []); + const visible = hiddenReducerTypes.indexOf(condition.reducer?.type) === -1; switch (evaluator.type) { case 'gt': { const value = evaluator.params[0]; - thresholds.push({ value: value, op: 'gt' }); + thresholds.push({ value: value, op: 'gt', visible }); break; } case 'lt': { const value = evaluator.params[0]; - thresholds.push({ value: value, op: 'lt' }); + thresholds.push({ value: value, op: 'lt', visible }); break; } case 'outside_range': { @@ -31,11 +33,11 @@ export class ThresholdMapper { const value2 = evaluator.params[1]; if (value1 > value2) { - thresholds.push({ value: value1, op: 'gt' }); - thresholds.push({ value: value2, op: 'lt' }); + thresholds.push({ value: value1, op: 'gt', visible }); + thresholds.push({ value: value2, op: 'lt', visible }); } else { - thresholds.push({ value: value1, op: 'lt' }); - thresholds.push({ value: value2, op: 'gt' }); + thresholds.push({ value: value1, op: 'lt', visible }); + thresholds.push({ value: value2, op: 'gt', visible }); } break; @@ -45,11 +47,11 @@ export class ThresholdMapper { const value2 = evaluator.params[1]; if (value1 > value2) { - thresholds.push({ value: value1, op: 'lt' }); - thresholds.push({ value: value2, op: 'gt' }); + thresholds.push({ value: value1, op: 'lt', visible }); + thresholds.push({ value: value2, op: 'gt', visible }); } else { - thresholds.push({ value: value1, op: 'gt' }); - thresholds.push({ value: value2, op: 'lt' }); + thresholds.push({ value: value1, op: 'gt', visible }); + thresholds.push({ value: value2, op: 'lt', visible }); } break; } diff --git a/public/app/plugins/panel/graph/threshold_manager.ts b/public/app/plugins/panel/graph/threshold_manager.ts index d6e24a3db5c..eb75233e424 100644 --- a/public/app/plugins/panel/graph/threshold_manager.ts +++ b/public/app/plugins/panel/graph/threshold_manager.ts @@ -87,6 +87,10 @@ export class ThresholdManager { renderHandle(handleIndex: number, defaultHandleTopPos: number) { const model = this.thresholds[handleIndex]; + if (!model.visible) { + return; + } + const value = model.value; let valueStr = value; let handleTopPos = 0;