AlertTab.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Libraries
  2. import React, { PureComponent, SFC } from 'react';
  3. // Services & Utils
  4. import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader';
  5. import appEvents from 'app/core/app_events';
  6. // Components
  7. import { EditorTabBody, EditorToolbarView } from '../dashboard/dashgrid/EditorTabBody';
  8. import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
  9. import StateHistory from './StateHistory';
  10. import 'app/features/alerting/AlertTabCtrl';
  11. // Types
  12. import { DashboardModel } from '../dashboard/dashboard_model';
  13. import { PanelModel } from '../dashboard/panel_model';
  14. import { TestRuleButton } from './TestRuleButton';
  15. interface Props {
  16. angularPanel?: AngularComponent;
  17. dashboard: DashboardModel;
  18. panel: PanelModel;
  19. }
  20. interface LoadingPlaceholderProps {
  21. text: string;
  22. }
  23. const LoadingPlaceholder: SFC<LoadingPlaceholderProps> = ({ text }) => (
  24. <div className="gf-form-group">
  25. {text} <i className="fa fa-spinner fa-spin" />
  26. </div>
  27. );
  28. export class AlertTab extends PureComponent<Props> {
  29. element: any;
  30. component: AngularComponent;
  31. panelCtrl: any;
  32. componentDidMount() {
  33. if (this.shouldLoadAlertTab()) {
  34. this.loadAlertTab();
  35. }
  36. }
  37. componentDidUpdate(prevProps: Props) {
  38. if (this.shouldLoadAlertTab()) {
  39. this.loadAlertTab();
  40. }
  41. }
  42. shouldLoadAlertTab() {
  43. return this.props.angularPanel && this.element && !this.component;
  44. }
  45. componentWillUnmount() {
  46. if (this.component) {
  47. this.component.destroy();
  48. }
  49. }
  50. loadAlertTab() {
  51. const { angularPanel } = this.props;
  52. const scope = angularPanel.getScope();
  53. // When full page reloading in edit mode the angular panel has on fully compiled & instantiated yet
  54. if (!scope.$$childHead) {
  55. setTimeout(() => {
  56. this.forceUpdate();
  57. });
  58. return;
  59. }
  60. this.panelCtrl = scope.$$childHead.ctrl;
  61. const loader = getAngularLoader();
  62. const template = '<alert-tab />';
  63. const scopeProps = { ctrl: this.panelCtrl };
  64. this.component = loader.load(this.element, scopeProps, template);
  65. }
  66. stateHistory = (): EditorToolbarView => {
  67. return {
  68. title: 'State history',
  69. render: () => {
  70. return (
  71. <StateHistory
  72. dashboard={this.props.dashboard}
  73. panelId={this.props.panel.id}
  74. onRefresh={this.panelCtrl.refresh}
  75. />
  76. );
  77. },
  78. };
  79. };
  80. deleteAlert = (): EditorToolbarView => {
  81. const { panel } = this.props;
  82. return {
  83. title: 'Delete',
  84. btnType: 'danger',
  85. onClick: () => {
  86. appEvents.emit('confirm-modal', {
  87. title: 'Delete Alert',
  88. text: 'Are you sure you want to delete this alert rule?',
  89. text2: 'You need to save dashboard for the delete to take effect',
  90. icon: 'fa-trash',
  91. yesText: 'Delete',
  92. onConfirm: () => {
  93. delete panel.alert;
  94. panel.thresholds = [];
  95. this.panelCtrl.alertState = null;
  96. this.panelCtrl.render();
  97. this.forceUpdate();
  98. },
  99. });
  100. },
  101. };
  102. };
  103. renderTestRuleButton = () => {
  104. const { panel, dashboard } = this.props;
  105. return <TestRuleButton panelId={panel.id} dashboard={dashboard} LoadingPlaceholder={LoadingPlaceholder} />;
  106. };
  107. testRule = (): EditorToolbarView => ({
  108. title: 'Test Rule',
  109. render: () => this.renderTestRuleButton(),
  110. });
  111. onAddAlert = () => {
  112. this.panelCtrl._enableAlert();
  113. this.component.digest();
  114. this.forceUpdate();
  115. };
  116. render() {
  117. const { alert } = this.props.panel;
  118. const toolbarItems = alert ? [this.stateHistory(), this.testRule(), this.deleteAlert()] : [];
  119. const model = {
  120. title: 'Panel has no alert rule defined',
  121. icon: 'icon-gf icon-gf-alert',
  122. onClick: this.onAddAlert,
  123. buttonTitle: 'Create Alert',
  124. };
  125. return (
  126. <EditorTabBody heading="Alert" toolbarItems={toolbarItems}>
  127. <>
  128. <div ref={element => (this.element = element)} />
  129. {!alert && <EmptyListCTA model={model} />}
  130. </>
  131. </EditorTabBody>
  132. );
  133. }
  134. }