AlertTab.tsx 3.8 KB

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