Browse Source

Merge pull request #14786 from grafana/14729-move-testrulebutton-to-toolbar

14729 move testrulebutton to toolbar
Torkel Ödegaard 7 years ago
parent
commit
b25214bfe1

+ 24 - 5
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<LoadingPlaceholderProps> = ({ text }) => (
+  <div className="gf-form-group">
+    {text} <i className="fa fa-spinner fa-spin" />
+  </div>
+);
+
 export class AlertTab extends PureComponent<Props> {
   element: any;
   component: AngularComponent;
@@ -65,9 +76,7 @@ export class AlertTab extends PureComponent<Props> {
     const loader = getAngularLoader();
     const template = '<alert-tab />';
 
-    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<Props> {
     };
   };
 
+  renderTestRuleButton = () => {
+    const { panel, dashboard } = this.props;
+    return <TestRuleButton panelId={panel.id} dashboard={dashboard} LoadingPlaceholder={LoadingPlaceholder} />;
+  };
+
+  testRule = (): EditorToolbarView => ({
+    title: 'Test Rule',
+    render: () => this.renderTestRuleButton(),
+  });
+
   onAddAlert = () => {
     this.panelCtrl._enableAlert();
     this.component.digest();
@@ -120,7 +139,7 @@ export class AlertTab extends PureComponent<Props> {
   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',

+ 0 - 17
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 */

+ 44 - 0
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(<TestRuleButton {...props} />);
+
+  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();
+    });
+  });
+});

+ 44 - 0
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<Props, State> {
+  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 <LoadingPlaceholder text="Evaluating rule" />;
+    }
+
+    return <JSONFormatter json={testRuleResponse} />;
+  }
+}

+ 13 - 0
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`] = `
+<JSONFormatter
+  config={
+    Object {
+      "animateOpen": true,
+    }
+  }
+  json={Object {}}
+  open={3}
+/>
+`;

+ 0 - 14
public/app/features/alerting/partials/alert_tab.html

@@ -121,20 +121,6 @@
             </div>
           </div>
         </div>
-
-        <div class="gf-form-button-row">
-          <button class="btn btn-inverse" ng-click="ctrl.test()">
-            Test Rule
-          </button>
-        </div>
-      </div>
-
-      <div class="gf-form-group" ng-if="ctrl.testing">
-        Evaluating rule <i class="fa fa-spinner fa-spin"></i>
-      </div>
-
-      <div class="gf-form-group" ng-if="ctrl.testResult">
-        <json-tree root-name="result" object="ctrl.testResult" start-expanded="true"></json-tree>
       </div>
     </div>
   </div>

+ 1 - 1
public/app/features/dashboard/dashgrid/EditorTabBody.tsx

@@ -52,7 +52,7 @@ export class EditorTabBody extends PureComponent<Props, State> {
   onToggleToolBarView = (item: EditorToolbarView) => {
     this.setState({
       openView: item,
-      isOpen: !this.state.isOpen,
+      isOpen: this.state.openView !== item || !this.state.isOpen,
     });
   };