From 2046309de51fb85376ce50c9dc9c9da4f0cbfbee Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Wed, 19 Dec 2018 10:42:57 +0100 Subject: [PATCH 01/13] rewrite angular view --- .../features/alerting/partials/alert_tab.html | 336 ++++++++---------- 1 file changed, 155 insertions(+), 181 deletions(-) diff --git a/public/app/features/alerting/partials/alert_tab.html b/public/app/features/alerting/partials/alert_tab.html index 0e4e48a89a9..5fcc7ae5e44 100644 --- a/public/app/features/alerting/partials/alert_tab.html +++ b/public/app/features/alerting/partials/alert_tab.html @@ -1,191 +1,165 @@ -
-
- +
+
+ {{ctrl.error}} +
+
+
+
+
+
+ Name + +
+
+
+ Evaluate every + +
+
+ + + + If an alert rule has a configured For and the query violates the configured + threshold it + will first go from OK to Pending. + Going from OK to Pending Grafana will not send any notifications. Once the alert + rule + has + been firing for more than For duration, it will change to Alerting and send alert + notifications. + +
+
+
+
+
+
+
+
Conditions
+
+
+
+ + WHEN +
+
+ + + OF +
+
+ + +
+
+ + + + +
+
+ +
+
+
+ +
+
+
+ If no data or all values are null + SET STATE TO +
+ +
+
-
-
-
- {{ctrl.error}} -
+
+ If execution error or timeout + SET STATE TO +
+ +
+
-
-
Alert Config
-
- Name - -
-
-
- Evaluate every - -
-
- - - - If an alert rule has a configured For and the query violates the configured threshold it will first go from OK to Pending. - Going from OK to Pending Grafana will not send any notifications. Once the alert rule has been firing for more than For duration, it will change to Alerting and send alert notifications. - -
-
-
+
+ +
+
-
-
Conditions
-
-
- - WHEN -
-
- - - OF -
-
- - -
-
- - - - -
-
- -
-
+
+ Evaluating rule +
-
- -
-
- -
-
- If no data or all values are null - SET STATE TO -
- -
-
- -
- If execution error or timeout - SET STATE TO -
- -
-
- -
- -
-
- -
- Evaluating rule -
- -
- -
-
- -
-
Notifications
-
-
- Send to - +
+ +
+
+
+
+
Notifications
+
+
+
+ Send to +  {{nc.name}}  - + - -
-
-
- Message - -
-
- -
- -
- State history (last 50 state changes) -
- -
-
- No state changes recorded -
- -
    -
  1. -
    - -
    -
    -
    -
    - {{al.stateModel.text}} -
    -
    - {{al.info}} -
    -
    - {{al.time}} -
    -
  2. -
-
-
-
+ +
+
+
+ Message + +
+
+
-
-
Panel has no alert rule defined
- -
-
+
+
Panel has no alert rule defined
+ +
From f3ba3b4df0e4a71e32b0e70024a11ba9204665c5 Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Wed, 19 Dec 2018 13:09:53 +0100 Subject: [PATCH 02/13] render editor toolbar buttons --- .../features/dashboard/dashgrid/AlertTab.tsx | 22 ++++++++++++++++++- .../dashboard/dashgrid/PanelEditor.tsx | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/AlertTab.tsx b/public/app/features/dashboard/dashgrid/AlertTab.tsx index 7df7864c758..f9f565222d8 100644 --- a/public/app/features/dashboard/dashgrid/AlertTab.tsx +++ b/public/app/features/dashboard/dashgrid/AlertTab.tsx @@ -3,9 +3,11 @@ import React, { PureComponent } from 'react'; import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; import { EditorTabBody } from './EditorTabBody'; import 'app/features/alerting/AlertTabCtrl'; +import { PanelModel } from '../panel_model'; interface Props { angularPanel?: AngularComponent; + panel: PanelModel; } export class AlertTab extends PureComponent { @@ -63,8 +65,26 @@ export class AlertTab extends PureComponent { } render() { + const { alert } = this.props.panel; + + const stateHistory = { + title: 'State history', + render: () => { + return
State history
; + }, + }; + + const deleteAlert = { + title: 'Delete button', + render: () => { + return
Hello
; + }, + }; + + const toolbarItems = alert ? [deleteAlert, stateHistory] : []; + return ( - +
(this.element = element)} /> ); diff --git a/public/app/features/dashboard/dashgrid/PanelEditor.tsx b/public/app/features/dashboard/dashgrid/PanelEditor.tsx index a746d6c4b91..b3d94f43487 100644 --- a/public/app/features/dashboard/dashgrid/PanelEditor.tsx +++ b/public/app/features/dashboard/dashgrid/PanelEditor.tsx @@ -54,7 +54,7 @@ export class PanelEditor extends PureComponent { case 'queries': return ; case 'alert': - return ; + return ; case 'visualization': return ( Date: Fri, 21 Dec 2018 11:24:31 +0100 Subject: [PATCH 03/13] adding extra props From 6aacd0734b6c4ec99913c0772bd9329dee9a12da Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Fri, 21 Dec 2018 11:57:21 +0100 Subject: [PATCH 04/13] typings and renamings --- .../features/dashboard/dashgrid/AlertTab.tsx | 8 +++--- .../dashboard/dashgrid/EditorTabBody.tsx | 26 +++++++++++++------ .../dashboard/dashgrid/QueriesTab.tsx | 19 +++++++------- .../dashboard/dashgrid/VisualizationTab.tsx | 10 +++---- 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/AlertTab.tsx b/public/app/features/dashboard/dashgrid/AlertTab.tsx index f9f565222d8..ee7d320a85b 100644 --- a/public/app/features/dashboard/dashgrid/AlertTab.tsx +++ b/public/app/features/dashboard/dashgrid/AlertTab.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; -import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; -import { EditorTabBody } from './EditorTabBody'; +import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader'; +import { EditorTabBody, EditorToolbarView, ToolbarButtonType } from './EditorTabBody'; import 'app/features/alerting/AlertTabCtrl'; import { PanelModel } from '../panel_model'; @@ -67,11 +67,12 @@ export class AlertTab extends PureComponent { render() { const { alert } = this.props.panel; - const stateHistory = { + const stateHistory: EditorToolbarView = { title: 'State history', render: () => { return
State history
; }, + buttonType: ToolbarButtonType.View, }; const deleteAlert = { @@ -79,6 +80,7 @@ export class AlertTab extends PureComponent { render: () => { return
Hello
; }, + buttonType: ToolbarButtonType.Action, }; const toolbarItems = alert ? [deleteAlert, stateHistory] : []; diff --git a/public/app/features/dashboard/dashgrid/EditorTabBody.tsx b/public/app/features/dashboard/dashgrid/EditorTabBody.tsx index 7606d327405..2cd247ed704 100644 --- a/public/app/features/dashboard/dashgrid/EditorTabBody.tsx +++ b/public/app/features/dashboard/dashgrid/EditorTabBody.tsx @@ -10,21 +10,28 @@ interface Props { children: JSX.Element; heading: string; renderToolbar?: () => JSX.Element; - toolbarItems?: EditorToolBarView[]; + toolbarItems?: EditorToolbarView[]; } -export interface EditorToolBarView { +export enum ToolbarButtonType { + Action = 'action', + View = 'view', +} + +export interface EditorToolbarView { title?: string; heading?: string; imgSrc?: string; icon?: string; disabled?: boolean; onClick?: () => void; - render: (closeFunction?: any) => JSX.Element | JSX.Element[]; + render?: (closeFunction?: any) => JSX.Element | JSX.Element[]; + action?: () => void; + buttonType: ToolbarButtonType; } interface State { - openView?: EditorToolBarView; + openView?: EditorToolbarView; isOpen: boolean; fadeIn: boolean; } @@ -48,7 +55,7 @@ export class EditorTabBody extends PureComponent { this.setState({ fadeIn: true }); } - onToggleToolBarView = (item: EditorToolBarView) => { + onToggleToolBarView = (item: EditorToolbarView) => { this.setState({ openView: item, isOpen: !this.state.isOpen, @@ -74,12 +81,15 @@ export class EditorTabBody extends PureComponent { return state; } - renderButton(view: EditorToolBarView) { + renderButton(view: EditorToolbarView) { const onClick = () => { if (view.onClick) { view.onClick(); } - this.onToggleToolBarView(view); + + if (view.buttonType !== ToolbarButtonType.Action) { + this.onToggleToolBarView(view); + } }; return ( @@ -91,7 +101,7 @@ export class EditorTabBody extends PureComponent { ); } - renderOpenView(view: EditorToolBarView) { + renderOpenView(view: EditorToolbarView) { return ( {view.render()} diff --git a/public/app/features/dashboard/dashgrid/QueriesTab.tsx b/public/app/features/dashboard/dashgrid/QueriesTab.tsx index 9ad0bb3cadd..98287e4888e 100644 --- a/public/app/features/dashboard/dashgrid/QueriesTab.tsx +++ b/public/app/features/dashboard/dashgrid/QueriesTab.tsx @@ -1,26 +1,23 @@ // Libraries -import React, { SFC, PureComponent } from 'react'; +import React, { PureComponent, SFC } from 'react'; import _ from 'lodash'; - // Components import './../../panel/metrics_tab'; -import { EditorTabBody } from './EditorTabBody'; +import { EditorTabBody, EditorToolbarView, ToolbarButtonType } from './EditorTabBody'; import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker'; import { QueryInspector } from './QueryInspector'; import { QueryOptions } from './QueryOptions'; import { AngularQueryComponentScope } from 'app/features/panel/metrics_tab'; import { PanelOptionSection } from './PanelOptionSection'; - // Services import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; -import { getBackendSrv, BackendSrv } from 'app/core/services/backend_srv'; -import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; +import { BackendSrv, getBackendSrv } from 'app/core/services/backend_srv'; +import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader'; import config from 'app/core/config'; - // Types import { PanelModel } from '../panel_model'; import { DashboardModel } from '../dashboard_model'; -import { DataSourceSelectItem, DataQuery } from 'app/types'; +import { DataQuery, DataSourceSelectItem } from 'app/types'; import { PluginHelp } from 'app/core/components/PluginHelp/PluginHelp'; interface Props { @@ -204,15 +201,17 @@ export class QueriesTab extends PureComponent { const { panel } = this.props; const { currentDS, isAddingMixed } = this.state; - const queryInspector = { + const queryInspector: EditorToolbarView = { title: 'Query Inspector', render: this.renderQueryInspector, + buttonType: ToolbarButtonType.View, }; - const dsHelp = { + const dsHelp: EditorToolbarView = { heading: 'Help', icon: 'fa fa-question', render: this.renderHelp, + buttonType: ToolbarButtonType.View, }; return ( diff --git a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx index 42d9bf6a6eb..8a57dd17190 100644 --- a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx +++ b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx @@ -1,16 +1,13 @@ // Libraries import React, { PureComponent } from 'react'; - // Utils & Services -import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; - +import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader'; // Components -import { EditorTabBody } from './EditorTabBody'; +import { EditorTabBody, EditorToolbarView, ToolbarButtonType } from './EditorTabBody'; import { VizTypePicker } from './VizTypePicker'; import { PluginHelp } from 'app/core/components/PluginHelp/PluginHelp'; import { FadeIn } from 'app/core/components/Animations/FadeIn'; import { PanelOptionSection } from './PanelOptionSection'; - // Types import { PanelModel } from '../panel_model'; import { DashboardModel } from '../dashboard_model'; @@ -206,10 +203,11 @@ export class VisualizationTab extends PureComponent { const { plugin } = this.props; const { isVizPickerOpen, searchQuery } = this.state; - const pluginHelp = { + const pluginHelp: EditorToolbarView = { heading: 'Help', icon: 'fa fa-question', render: this.renderHelp, + buttonType: ToolbarButtonType.View, }; return ( From 4002f80ab880e34b60a855b03820f4b21d1f9814 Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Fri, 21 Dec 2018 14:56:49 +0100 Subject: [PATCH 05/13] delete works --- .../features/alerting/partials/alert_tab.html | 4 +- .../features/dashboard/dashgrid/AlertTab.tsx | 44 ++++++++++++++----- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/public/app/features/alerting/partials/alert_tab.html b/public/app/features/alerting/partials/alert_tab.html index 5fcc7ae5e44..cbddb93207a 100644 --- a/public/app/features/alerting/partials/alert_tab.html +++ b/public/app/features/alerting/partials/alert_tab.html @@ -1,4 +1,4 @@ -
+
{{ctrl.error}}
@@ -154,7 +154,7 @@
-
+
Panel has no alert rule defined
- -
-
-
Panel has no alert rule defined
- -
-
diff --git a/public/app/features/dashboard/dashgrid/AlertTab.tsx b/public/app/features/dashboard/dashgrid/AlertTab.tsx index 2a715536ca8..5ccfa791328 100644 --- a/public/app/features/dashboard/dashgrid/AlertTab.tsx +++ b/public/app/features/dashboard/dashgrid/AlertTab.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; - import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader'; import { EditorTabBody, EditorToolbarView, ToolbarButtonType } from './EditorTabBody'; +import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; import appEvents from 'app/core/app_events'; import { PanelModel } from '../panel_model'; import 'app/features/alerting/AlertTabCtrl'; @@ -33,7 +33,7 @@ export class AlertTab extends PureComponent { } shouldLoadAlertTab() { - return this.props.angularPanel && this.element; + return this.props.angularPanel && this.element && !this.component; } componentWillUnmount() { @@ -93,6 +93,7 @@ export class AlertTab extends PureComponent { panel.thresholds = []; this.panelCtrl.alertState = null; this.panelCtrl.render(); + this.forceUpdate(); }, }); }, @@ -100,15 +101,31 @@ export class AlertTab extends PureComponent { }; }; + onAddAlert = () => { + this.panelCtrl._enableAlert(); + this.component.digest(); + this.forceUpdate(); + }; + render() { const { alert } = this.props.panel; const toolbarItems = alert ? [this.stateHistory(), this.deleteAlert()] : []; + const model = { + title: 'Panel has no alert rule defined', + icon: 'icon-gf icon-gf-alert', + onClick: this.onAddAlert, + buttonTitle: 'Create Alert', + }; + //TODO move add button react from angular and add condition to render angular view return ( -
(this.element = element)} /> + <> +
(this.element = element)} /> + {!alert && } + ); } From e7d9bbf78138e91bbd940771f242e6659dca5285 Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Wed, 2 Jan 2019 15:22:22 +0100 Subject: [PATCH 09/13] state history tab --- .../features/dashboard/dashgrid/AlertTab.tsx | 6 +- .../dashboard/dashgrid/PanelEditor.tsx | 2 +- .../dashboard/dashgrid/StateHistory.tsx | 85 +++++++++++++++++++ 3 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 public/app/features/dashboard/dashgrid/StateHistory.tsx diff --git a/public/app/features/dashboard/dashgrid/AlertTab.tsx b/public/app/features/dashboard/dashgrid/AlertTab.tsx index 5ccfa791328..127e6cd0239 100644 --- a/public/app/features/dashboard/dashgrid/AlertTab.tsx +++ b/public/app/features/dashboard/dashgrid/AlertTab.tsx @@ -2,12 +2,15 @@ import React, { PureComponent } from 'react'; import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader'; import { EditorTabBody, EditorToolbarView, ToolbarButtonType } from './EditorTabBody'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; +import StateHistory from './StateHistory'; import appEvents from 'app/core/app_events'; import { PanelModel } from '../panel_model'; import 'app/features/alerting/AlertTabCtrl'; +import { DashboardModel } from '../dashboard_model'; interface Props { angularPanel?: AngularComponent; + dashboard: DashboardModel; panel: PanelModel; } @@ -70,7 +73,7 @@ export class AlertTab extends PureComponent { return { title: 'State history', render: () => { - return
State history
; + return ; }, buttonType: ToolbarButtonType.View, }; @@ -119,7 +122,6 @@ export class AlertTab extends PureComponent { buttonTitle: 'Create Alert', }; - //TODO move add button react from angular and add condition to render angular view return ( <> diff --git a/public/app/features/dashboard/dashgrid/PanelEditor.tsx b/public/app/features/dashboard/dashgrid/PanelEditor.tsx index b3d94f43487..fbc683c2eb3 100644 --- a/public/app/features/dashboard/dashgrid/PanelEditor.tsx +++ b/public/app/features/dashboard/dashgrid/PanelEditor.tsx @@ -54,7 +54,7 @@ export class PanelEditor extends PureComponent { case 'queries': return ; case 'alert': - return ; + return ; case 'visualization': return ( { + state = { + stateHistoryItems: [], + }; + + componentDidMount(): void { + const { dashboard, panelId } = this.props; + + getBackendSrv() + .get(`/api/annotations?dashboardId=${dashboard.id}&panelId=${panelId}&limit=50&type=alert`) + .then(res => { + console.log(res); + const items = []; + res.map(item => { + items.push({ + stateModel: alertDef.getStateDisplayModel(item.newState), + time: dashboard.formatDate(item.time, 'MMM D, YYYY HH:mm:ss'), + info: alertDef.getAlertAnnotationInfo(item), + }); + }); + + this.setState({ + stateHistoryItems: items, + }); + }); + } + + render() { + const { stateHistoryItems } = this.state; + + return ( +
+
+
+ Last 50 state changes + +
+
    + {stateHistoryItems ? ( + stateHistoryItems.map((item, index) => { + return ( +
  1. +
    + +
    +
    +
    +

    {item.alertName}

    +
    + {item.stateModel.text} +
    +
    + {item.info} +
    +
    {item.time}
    +
  2. + ); + }) + ) : ( + No state changes recorded + )} +
+
+
+ ); + } +} + +export default StateHistory; From 6b5f9d58217be26761675509ebfa02e0e5ff994f Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Wed, 2 Jan 2019 16:07:29 +0100 Subject: [PATCH 10/13] clear history --- .../features/dashboard/dashgrid/AlertTab.tsx | 12 +++-- .../dashboard/dashgrid/StateHistory.tsx | 53 ++++++++++++++----- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/AlertTab.tsx b/public/app/features/dashboard/dashgrid/AlertTab.tsx index 127e6cd0239..80706bf9b41 100644 --- a/public/app/features/dashboard/dashgrid/AlertTab.tsx +++ b/public/app/features/dashboard/dashgrid/AlertTab.tsx @@ -19,10 +19,6 @@ export class AlertTab extends PureComponent { component: AngularComponent; panelCtrl: any; - constructor(props) { - super(props); - } - componentDidMount() { if (this.shouldLoadAlertTab()) { this.loadAlertTab(); @@ -73,7 +69,13 @@ export class AlertTab extends PureComponent { return { title: 'State history', render: () => { - return ; + return ( + + ); }, buttonType: ToolbarButtonType.View, }; diff --git a/public/app/features/dashboard/dashgrid/StateHistory.tsx b/public/app/features/dashboard/dashgrid/StateHistory.tsx index d40afdd375a..c2998190841 100644 --- a/public/app/features/dashboard/dashgrid/StateHistory.tsx +++ b/public/app/features/dashboard/dashgrid/StateHistory.tsx @@ -1,11 +1,13 @@ import React, { PureComponent } from 'react'; import alertDef from '../../alerting/state/alertDef'; -import { getBackendSrv } from '../../../core/services/backend_srv'; +import { getBackendSrv } from 'app/core/services/backend_srv'; import { DashboardModel } from '../dashboard_model'; +import appEvents from '../../../core/app_events'; interface Props { dashboard: DashboardModel; panelId: number; + onRefresh: () => void; } interface State { @@ -23,14 +25,12 @@ class StateHistory extends PureComponent { getBackendSrv() .get(`/api/annotations?dashboardId=${dashboard.id}&panelId=${panelId}&limit=50&type=alert`) .then(res => { - console.log(res); - const items = []; - res.map(item => { - items.push({ + const items = res.map(item => { + return { stateModel: alertDef.getStateDisplayModel(item.newState), time: dashboard.formatDate(item.time, 'MMM D, YYYY HH:mm:ss'), info: alertDef.getAlertAnnotationInfo(item), - }); + }; }); this.setState({ @@ -39,20 +39,47 @@ class StateHistory extends PureComponent { }); } + clearHistory = () => { + const { dashboard, onRefresh, panelId } = this.props; + + appEvents.emit('confirm-modal', { + title: 'Delete Alert History', + text: 'Are you sure you want to remove all history & annotations for this alert?', + icon: 'fa-trash', + yesText: 'Yes', + onConfirm: () => { + getBackendSrv() + .post('/api/annotations/mass-delete', { + dashboardId: dashboard.id, + panelId: panelId, + }) + .then(() => { + onRefresh(); + }); + + this.setState({ + stateHistoryItems: [], + }); + }, + }); + }; + render() { const { stateHistoryItems } = this.state; return (
-
- Last 50 state changes - -
+ {stateHistoryItems.length > 0 && ( +
+ Last 50 state changes + +
+ )}
    - {stateHistoryItems ? ( + {stateHistoryItems.length > 0 ? ( stateHistoryItems.map((item, index) => { return (
  1. From 2eeba9dae186806ed5977d1e79815bfc5328169c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 4 Jan 2019 11:57:16 +0100 Subject: [PATCH 11/13] Updated alert tab layout & markup --- public/app/features/alerting/AlertTabCtrl.ts | 3 +- .../features/alerting/partials/alert_tab.html | 217 ++++++++++-------- 2 files changed, 117 insertions(+), 103 deletions(-) diff --git a/public/app/features/alerting/AlertTabCtrl.ts b/public/app/features/alerting/AlertTabCtrl.ts index ffcb20472ad..2be25e9df6a 100644 --- a/public/app/features/alerting/AlertTabCtrl.ts +++ b/public/app/features/alerting/AlertTabCtrl.ts @@ -115,7 +115,7 @@ export class AlertTabCtrl { } getNotifications() { - return Promise.resolve( + return this.$q.when( this.notifications.map(item => { return this.uiSegmentSrv.newSegment(item.name); }) @@ -148,6 +148,7 @@ export class AlertTabCtrl { // reset plus button this.addNotificationSegment.value = this.uiSegmentSrv.newPlusButton().value; this.addNotificationSegment.html = this.uiSegmentSrv.newPlusButton().html; + this.addNotificationSegment.fake = true; } removeNotification(index) { diff --git a/public/app/features/alerting/partials/alert_tab.html b/public/app/features/alerting/partials/alert_tab.html index 3a03b23a076..da862203da6 100644 --- a/public/app/features/alerting/partials/alert_tab.html +++ b/public/app/features/alerting/partials/alert_tab.html @@ -4,112 +4,121 @@
-
-
+
+

Rule

+
Name
-
-
- Evaluate every - -
-
- - - - If an alert rule has a configured For and the query violates the configured - threshold it - will first go from OK to Pending. - Going from OK to Pending Grafana will not send any notifications. Once the alert - rule - has - been firing for more than For duration, it will change to Alerting and send alert - notifications. - -
+
+ Evaluate every + +
+
+ + + + If an alert rule has a configured For and the query violates the configured + threshold it + will first go from OK to Pending. + Going from OK to Pending Grafana will not send any notifications. Once the alert + rule + has + been firing for more than For duration, it will change to Alerting and send alert + notifications. +
-
-
-
-
Conditions
-
-
-
- - WHEN -
-
- - - OF -
-
- - -
-
- - - - -
-
- -
-
-
- -
+
-
- If no data or all values are null - SET STATE TO -
- +

Conditions

+
+
+ + WHEN +
+
+ + + OF +
+
+ + +
+
+ + + + +
+
+
- If execution error or timeout - SET STATE TO -
- + +
+
+ +
+

No Data & Error Handling

+
+
+ If no data or all values are null +
+
+ SET STATE TO +
+ +
+
+
+ +
+
+ If execution error or timeout +
+
+ SET STATE TO +
+ +
@@ -129,19 +138,23 @@
+
Notifications
-
+
Send to - -  {{nc.name}}  - - - +
+ +  {{nc.name}}  + + +
+
+
From f749ced36e05956e02ed0574a24e8350b64e5b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 4 Jan 2019 12:18:49 +0100 Subject: [PATCH 12/13] AlertTab style fixes --- .../dashboard/dashgrid/EditorTabBody.tsx | 2 +- .../dashboard/dashgrid/StateHistory.tsx | 64 +++++++++---------- public/sass/pages/_alerting.scss | 1 + 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/EditorTabBody.tsx b/public/app/features/dashboard/dashgrid/EditorTabBody.tsx index 2cd247ed704..822507c5c11 100644 --- a/public/app/features/dashboard/dashgrid/EditorTabBody.tsx +++ b/public/app/features/dashboard/dashgrid/EditorTabBody.tsx @@ -25,7 +25,7 @@ export interface EditorToolbarView { icon?: string; disabled?: boolean; onClick?: () => void; - render?: (closeFunction?: any) => JSX.Element | JSX.Element[]; + render?: () => JSX.Element; action?: () => void; buttonType: ToolbarButtonType; } diff --git a/public/app/features/dashboard/dashgrid/StateHistory.tsx b/public/app/features/dashboard/dashgrid/StateHistory.tsx index c2998190841..99229b41848 100644 --- a/public/app/features/dashboard/dashgrid/StateHistory.tsx +++ b/public/app/features/dashboard/dashgrid/StateHistory.tsx @@ -69,41 +69,39 @@ class StateHistory extends PureComponent { return (
-
- {stateHistoryItems.length > 0 && ( -
- Last 50 state changes - -
- )} -
    - {stateHistoryItems.length > 0 ? ( - stateHistoryItems.map((item, index) => { - return ( -
  1. -
    - -
    -
    -
    -

    {item.alertName}

    -
    - {item.stateModel.text} -
    + {stateHistoryItems.length > 0 && ( +
    + Last 50 state changes + +
    + )} +
      + {stateHistoryItems.length > 0 ? ( + stateHistoryItems.map((item, index) => { + return ( +
    1. +
      + +
      +
      +
      +

      {item.alertName}

      +
      + {item.stateModel.text}
      - {item.info}
      -
      {item.time}
      -
    2. - ); - }) - ) : ( - No state changes recorded - )} -
    -
    + {item.info} +
    +
    {item.time}
    +
  2. + ); + }) + ) : ( + No state changes recorded + )} +
); } diff --git a/public/sass/pages/_alerting.scss b/public/sass/pages/_alerting.scss index 77752be11bc..f285ab753ff 100644 --- a/public/sass/pages/_alerting.scss +++ b/public/sass/pages/_alerting.scss @@ -107,6 +107,7 @@ display: flex; flex-direction: column; flex-grow: 1; + justify-content: center; overflow: hidden; } From e0c28ba7704246a70e4467f23109cadacb8f3fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 4 Jan 2019 12:38:50 +0100 Subject: [PATCH 13/13] Minor refactoring of EditorTabBody --- .../features/dashboard/dashgrid/AlertTab.tsx | 17 +++++++++++------ .../dashboard/dashgrid/EditorTabBody.tsx | 10 ++-------- .../features/dashboard/dashgrid/QueriesTab.tsx | 9 +++++---- .../dashboard/dashgrid/VisualizationTab.tsx | 6 ++++-- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/AlertTab.tsx b/public/app/features/dashboard/dashgrid/AlertTab.tsx index 80706bf9b41..20f7e90633e 100644 --- a/public/app/features/dashboard/dashgrid/AlertTab.tsx +++ b/public/app/features/dashboard/dashgrid/AlertTab.tsx @@ -1,12 +1,19 @@ +// Libraries import React, { PureComponent } from 'react'; + +// Services & Utils import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader'; -import { EditorTabBody, EditorToolbarView, ToolbarButtonType } from './EditorTabBody'; +import appEvents from 'app/core/app_events'; + +// Components +import { EditorTabBody, EditorToolbarView } from './EditorTabBody'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; import StateHistory from './StateHistory'; -import appEvents from 'app/core/app_events'; -import { PanelModel } from '../panel_model'; import 'app/features/alerting/AlertTabCtrl'; + +// Types import { DashboardModel } from '../dashboard_model'; +import { PanelModel } from '../panel_model'; interface Props { angularPanel?: AngularComponent; @@ -77,7 +84,6 @@ export class AlertTab extends PureComponent { /> ); }, - buttonType: ToolbarButtonType.View, }; }; @@ -85,7 +91,7 @@ export class AlertTab extends PureComponent { const { panel } = this.props; return { title: 'Delete', - icon: 'fa fa-trash', + btnType: 'danger', onClick: () => { appEvents.emit('confirm-modal', { title: 'Delete Alert', @@ -102,7 +108,6 @@ export class AlertTab extends PureComponent { }, }); }, - buttonType: ToolbarButtonType.Action, }; }; diff --git a/public/app/features/dashboard/dashgrid/EditorTabBody.tsx b/public/app/features/dashboard/dashgrid/EditorTabBody.tsx index 822507c5c11..b7da81a23f8 100644 --- a/public/app/features/dashboard/dashgrid/EditorTabBody.tsx +++ b/public/app/features/dashboard/dashgrid/EditorTabBody.tsx @@ -13,21 +13,15 @@ interface Props { toolbarItems?: EditorToolbarView[]; } -export enum ToolbarButtonType { - Action = 'action', - View = 'view', -} - export interface EditorToolbarView { title?: string; heading?: string; - imgSrc?: string; icon?: string; disabled?: boolean; onClick?: () => void; render?: () => JSX.Element; action?: () => void; - buttonType: ToolbarButtonType; + btnType?: 'danger'; } interface State { @@ -87,7 +81,7 @@ export class EditorTabBody extends PureComponent { view.onClick(); } - if (view.buttonType !== ToolbarButtonType.Action) { + if (view.render) { this.onToggleToolBarView(view); } }; diff --git a/public/app/features/dashboard/dashgrid/QueriesTab.tsx b/public/app/features/dashboard/dashgrid/QueriesTab.tsx index 98287e4888e..741e2cd9ac1 100644 --- a/public/app/features/dashboard/dashgrid/QueriesTab.tsx +++ b/public/app/features/dashboard/dashgrid/QueriesTab.tsx @@ -1,19 +1,22 @@ // Libraries import React, { PureComponent, SFC } from 'react'; import _ from 'lodash'; + // Components -import './../../panel/metrics_tab'; -import { EditorTabBody, EditorToolbarView, ToolbarButtonType } from './EditorTabBody'; +import 'app/features/panel/metrics_tab'; +import { EditorTabBody, EditorToolbarView} from './EditorTabBody'; import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker'; import { QueryInspector } from './QueryInspector'; import { QueryOptions } from './QueryOptions'; import { AngularQueryComponentScope } from 'app/features/panel/metrics_tab'; import { PanelOptionSection } from './PanelOptionSection'; + // Services import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { BackendSrv, getBackendSrv } from 'app/core/services/backend_srv'; import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader'; import config from 'app/core/config'; + // Types import { PanelModel } from '../panel_model'; import { DashboardModel } from '../dashboard_model'; @@ -204,14 +207,12 @@ export class QueriesTab extends PureComponent { const queryInspector: EditorToolbarView = { title: 'Query Inspector', render: this.renderQueryInspector, - buttonType: ToolbarButtonType.View, }; const dsHelp: EditorToolbarView = { heading: 'Help', icon: 'fa fa-question', render: this.renderHelp, - buttonType: ToolbarButtonType.View, }; return ( diff --git a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx index 8a57dd17190..bc7102f35dd 100644 --- a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx +++ b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx @@ -1,13 +1,16 @@ // Libraries import React, { PureComponent } from 'react'; + // Utils & Services import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader'; + // Components -import { EditorTabBody, EditorToolbarView, ToolbarButtonType } from './EditorTabBody'; +import { EditorTabBody, EditorToolbarView } from './EditorTabBody'; import { VizTypePicker } from './VizTypePicker'; import { PluginHelp } from 'app/core/components/PluginHelp/PluginHelp'; import { FadeIn } from 'app/core/components/Animations/FadeIn'; import { PanelOptionSection } from './PanelOptionSection'; + // Types import { PanelModel } from '../panel_model'; import { DashboardModel } from '../dashboard_model'; @@ -207,7 +210,6 @@ export class VisualizationTab extends PureComponent { heading: 'Help', icon: 'fa fa-question', render: this.renderHelp, - buttonType: ToolbarButtonType.View, }; return (