diff --git a/public/app/features/alerting/AlertTab.tsx b/public/app/features/alerting/AlertTab.tsx index a5afbc198fc..5623fac95c1 100644 --- a/public/app/features/alerting/AlertTab.tsx +++ b/public/app/features/alerting/AlertTab.tsx @@ -1,5 +1,5 @@ // Libraries -import React, { PureComponent } from 'react'; +import React, { PureComponent, SFC } from 'react'; // Services & Utils import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader'; @@ -14,6 +14,7 @@ import 'app/features/alerting/AlertTabCtrl'; // Types import { DashboardModel } from '../dashboard/dashboard_model'; import { PanelModel } from '../dashboard/panel_model'; +import { TestRuleButton } from './TestRuleButton'; interface Props { angularPanel?: AngularComponent; @@ -21,6 +22,16 @@ interface Props { panel: PanelModel; } +interface LoadingPlaceholderProps { + text: string; +} + +const LoadingPlaceholder: SFC = ({ text }) => ( +
+ {text} +
+); + export class AlertTab extends PureComponent { element: any; component: AngularComponent; @@ -65,9 +76,7 @@ export class AlertTab extends PureComponent { const loader = getAngularLoader(); const template = ''; - const scopeProps = { - ctrl: this.panelCtrl, - }; + const scopeProps = { ctrl: this.panelCtrl }; this.component = loader.load(this.element, scopeProps, template); } @@ -111,6 +120,16 @@ export class AlertTab extends PureComponent { }; }; + renderTestRuleButton = () => { + const { panel, dashboard } = this.props; + return ; + }; + + testRule = (): EditorToolbarView => ({ + title: 'Test Rule', + render: () => this.renderTestRuleButton(), + }); + onAddAlert = () => { this.panelCtrl._enableAlert(); this.component.digest(); @@ -120,7 +139,7 @@ export class AlertTab extends PureComponent { render() { const { alert } = this.props.panel; - const toolbarItems = alert ? [this.stateHistory(), this.deleteAlert()] : []; + const toolbarItems = alert ? [this.stateHistory(), this.testRule(), this.deleteAlert()] : []; const model = { title: 'Panel has no alert rule defined', diff --git a/public/app/features/alerting/AlertTabCtrl.ts b/public/app/features/alerting/AlertTabCtrl.ts index 2be25e9df6a..af00e79b085 100644 --- a/public/app/features/alerting/AlertTabCtrl.ts +++ b/public/app/features/alerting/AlertTabCtrl.ts @@ -9,8 +9,6 @@ import appEvents from 'app/core/app_events'; export class AlertTabCtrl { panel: any; panelCtrl: any; - testing: boolean; - testResult: any; subTabIndex: number; conditionTypes: any; alert: any; @@ -406,21 +404,6 @@ export class AlertTabCtrl { }, }); } - - test() { - this.testing = true; - this.testResult = false; - - const payload = { - dashboard: this.dashboardSrv.getCurrent().getSaveModelClone(), - panelId: this.panelCtrl.panel.id, - }; - - return this.backendSrv.post('/api/alerts/test', payload).then(res => { - this.testResult = res; - this.testing = false; - }); - } } /** @ngInject */ diff --git a/public/app/features/alerting/TestRuleButton.test.tsx b/public/app/features/alerting/TestRuleButton.test.tsx new file mode 100644 index 00000000000..ae3b570cf43 --- /dev/null +++ b/public/app/features/alerting/TestRuleButton.test.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { DashboardModel } from '../dashboard/dashboard_model'; +import { Props, TestRuleButton } from './TestRuleButton'; + +jest.mock('app/core/services/backend_srv', () => ({ + getBackendSrv: () => ({ + post: jest.fn(), + }), +})); + +const setup = (propOverrides?: object) => { + const props: Props = { + panelId: 1, + dashboard: new DashboardModel({ panels: [{ id: 1 }] }), + LoadingPlaceholder: {}, + }; + + Object.assign(props, propOverrides); + + const wrapper = shallow(); + + return { wrapper, instance: wrapper.instance() as TestRuleButton }; +}; + +describe('Render', () => { + it('should render component', () => { + const { wrapper } = setup(); + + expect(wrapper).toMatchSnapshot(); + }); +}); + +describe('Life cycle', () => { + describe('component did mount', () => { + it('should call testRule', () => { + const { instance } = setup(); + instance.testRule = jest.fn(); + instance.componentDidMount(); + + expect(instance.testRule).toHaveBeenCalled(); + }); + }); +}); diff --git a/public/app/features/alerting/TestRuleButton.tsx b/public/app/features/alerting/TestRuleButton.tsx new file mode 100644 index 00000000000..f9927b1a182 --- /dev/null +++ b/public/app/features/alerting/TestRuleButton.tsx @@ -0,0 +1,44 @@ +import React, { PureComponent } from 'react'; +import { JSONFormatter } from 'app/core/components/JSONFormatter/JSONFormatter'; +import { getBackendSrv } from 'app/core/services/backend_srv'; +import { DashboardModel } from '../dashboard/dashboard_model'; + +export interface Props { + panelId: number; + dashboard: DashboardModel; + LoadingPlaceholder: any; +} + +interface State { + isLoading: boolean; + testRuleResponse: {}; +} + +export class TestRuleButton extends PureComponent { + readonly state: State = { + isLoading: false, + testRuleResponse: {}, + }; + + componentDidMount() { + this.testRule(); + } + + async testRule() { + const { panelId, dashboard } = this.props; + const payload = { dashboard: dashboard.getSaveModelClone(), panelId }; + const testRuleResponse = await getBackendSrv().post(`/api/alerts/test`, payload); + this.setState(prevState => ({ ...prevState, isLoading: false, testRuleResponse })); + } + + render() { + const { testRuleResponse, isLoading } = this.state; + const { LoadingPlaceholder } = this.props; + + if (isLoading === true) { + return ; + } + + return ; + } +} diff --git a/public/app/features/alerting/__snapshots__/TestRuleButton.test.tsx.snap b/public/app/features/alerting/__snapshots__/TestRuleButton.test.tsx.snap new file mode 100644 index 00000000000..d1ed3e64e99 --- /dev/null +++ b/public/app/features/alerting/__snapshots__/TestRuleButton.test.tsx.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Render should render component 1`] = ` + +`; diff --git a/public/app/features/alerting/partials/alert_tab.html b/public/app/features/alerting/partials/alert_tab.html index da862203da6..90e0c7bbac2 100644 --- a/public/app/features/alerting/partials/alert_tab.html +++ b/public/app/features/alerting/partials/alert_tab.html @@ -121,20 +121,6 @@ - -
- -
- - -
- Evaluating rule -
- -
-
diff --git a/public/app/features/dashboard/dashgrid/EditorTabBody.tsx b/public/app/features/dashboard/dashgrid/EditorTabBody.tsx index b159cb30a4b..e86baf0a80b 100644 --- a/public/app/features/dashboard/dashgrid/EditorTabBody.tsx +++ b/public/app/features/dashboard/dashgrid/EditorTabBody.tsx @@ -52,7 +52,7 @@ export class EditorTabBody extends PureComponent { onToggleToolBarView = (item: EditorToolbarView) => { this.setState({ openView: item, - isOpen: !this.state.isOpen, + isOpen: this.state.openView !== item || !this.state.isOpen, }); };