AlertRuleList.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import React from 'react';
  2. import classNames from 'classnames';
  3. import { inject, observer } from 'mobx-react';
  4. import PageHeader from 'app/core/components/PageHeader/PageHeader';
  5. import { IAlertRule } from 'app/stores/AlertListStore/AlertListStore';
  6. import appEvents from 'app/core/app_events';
  7. import IContainerProps from 'app/containers/IContainerProps';
  8. @inject('view', 'nav', 'alertList')
  9. @observer
  10. export class AlertRuleList extends React.Component<IContainerProps, any> {
  11. stateFilters = [
  12. { text: 'All', value: 'all' },
  13. { text: 'OK', value: 'ok' },
  14. { text: 'Not OK', value: 'not_ok' },
  15. { text: 'Alerting', value: 'alerting' },
  16. { text: 'No Data', value: 'no_data' },
  17. { text: 'Paused', value: 'paused' },
  18. ];
  19. constructor(props) {
  20. super(props);
  21. this.props.nav.load('alerting', 'alert-list');
  22. this.fetchRules();
  23. this.state = { search: '' };
  24. }
  25. onStateFilterChanged = evt => {
  26. this.props.view.updateQuery({ state: evt.target.value });
  27. this.fetchRules();
  28. };
  29. fetchRules() {
  30. this.props.alertList.loadRules({
  31. state: this.props.view.query.get('state') || 'all',
  32. });
  33. }
  34. onOpenHowTo = () => {
  35. appEvents.emit('show-modal', {
  36. src: 'public/app/features/alerting/partials/alert_howto.html',
  37. modalClass: 'confirm-modal',
  38. model: {},
  39. });
  40. };
  41. onSearchFilter(event) {
  42. this.setState({ search: event.target.value });
  43. }
  44. render() {
  45. const { nav, alertList } = this.props;
  46. let regex = new RegExp(this.state.search, 'ig');
  47. return (
  48. <div>
  49. <PageHeader model={nav as any} />
  50. <div className="page-container page-body">
  51. <div className="page-action-bar">
  52. <div className="gf-form">
  53. <label className="gf-form--has-input-icon">
  54. <input
  55. type="text"
  56. className="gf-form-input width-13"
  57. placeholder="Search alert"
  58. value={this.state.search}
  59. onChange={this.onSearchFilter.bind(this)}
  60. />
  61. <i className="gf-form-input-icon fa fa-search" />
  62. </label>
  63. </div>
  64. <div className="gf-form">
  65. <label className="gf-form-label">Filter by state</label>
  66. <div className="gf-form-select-wrapper width-13">
  67. <select className="gf-form-input" onChange={this.onStateFilterChanged} value={alertList.stateFilter}>
  68. {this.stateFilters.map(AlertStateFilterOption)}
  69. </select>
  70. </div>
  71. </div>
  72. <div className="page-action-bar__spacer" />
  73. <a className="btn btn-secondary" onClick={this.onOpenHowTo}>
  74. <i className="fa fa-info-circle" /> How to add an alert
  75. </a>
  76. </div>
  77. <section>
  78. <ol className="alert-rule-list">
  79. {alertList.searchFilter(regex).map(rule => <AlertRuleItem rule={rule} key={rule.id} />)}
  80. </ol>
  81. </section>
  82. </div>
  83. </div>
  84. );
  85. }
  86. }
  87. function AlertStateFilterOption({ text, value }) {
  88. return (
  89. <option key={value} value={value}>
  90. {text}
  91. </option>
  92. );
  93. }
  94. export interface AlertRuleItemProps {
  95. rule: IAlertRule;
  96. }
  97. @observer
  98. export class AlertRuleItem extends React.Component<AlertRuleItemProps, any> {
  99. toggleState = () => {
  100. this.props.rule.togglePaused();
  101. };
  102. render() {
  103. const { rule } = this.props;
  104. let stateClass = classNames({
  105. fa: true,
  106. 'fa-play': rule.isPaused,
  107. 'fa-pause': !rule.isPaused,
  108. });
  109. let ruleUrl = `dashboard/${rule.dashboardUri}?panelId=${rule.panelId}&fullscreen&edit&tab=alert`;
  110. return (
  111. <li className="alert-rule-item">
  112. <div className="alert-rule-item__body">
  113. <span className={`alert-rule-item__icon ${rule.stateClass}`}>
  114. <i className={rule.stateIcon} />
  115. </span>
  116. <div className="alert-rule-item__header">
  117. <div className="alert-rule-item__name">
  118. <a href={ruleUrl}>{rule.name}</a>
  119. </div>
  120. <div className="alert-rule-item__text">
  121. <span className={`${rule.stateClass}`}>{rule.stateText}</span>
  122. <span className="alert-rule-item__time"> for {rule.stateAge}</span>
  123. </div>
  124. </div>
  125. {rule.info && <div className="small muted alert-rule-item__info">{rule.info}</div>}
  126. </div>
  127. <div className="alert-rule-item__footer">
  128. <a
  129. className="btn btn-small btn-inverse alert-list__btn width-2"
  130. title="Pausing an alert rule prevents it from executing"
  131. onClick={this.toggleState}
  132. >
  133. <i className={stateClass} />
  134. </a>
  135. <a className="btn btn-small btn-inverse alert-list__btn width-2" href={ruleUrl} title="Edit alert rule">
  136. <i className="icon-gf icon-gf-settings" />
  137. </a>
  138. </div>
  139. </li>
  140. );
  141. }
  142. }