index.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import {Component, Fragment} from 'react';
  2. import {Panel, PanelBody} from 'sentry/components/panels';
  3. import {Organization, Project} from 'sentry/types';
  4. import {removeAtArrayIndex} from 'sentry/utils/removeAtArrayIndex';
  5. import {replaceAtArrayIndex} from 'sentry/utils/replaceAtArrayIndex';
  6. import ActionsPanel from 'sentry/views/alerts/rules/metric/triggers/actionsPanel';
  7. import TriggerForm from 'sentry/views/alerts/rules/metric/triggers/form';
  8. import {
  9. Action,
  10. AlertRuleComparisonType,
  11. AlertRuleThresholdType,
  12. MetricActionTemplate,
  13. Trigger,
  14. UnsavedMetricRule,
  15. } from '../types';
  16. type Props = {
  17. aggregate: UnsavedMetricRule['aggregate'];
  18. availableActions: MetricActionTemplate[] | null;
  19. comparisonType: AlertRuleComparisonType;
  20. currentProject: string;
  21. disabled: boolean;
  22. errors: Map<number, {[fieldName: string]: string}>;
  23. onChange: (
  24. triggers: Trigger[],
  25. triggerIndex?: number,
  26. changeObj?: Partial<Trigger>
  27. ) => void;
  28. onResolveThresholdChange: (
  29. resolveThreshold: UnsavedMetricRule['resolveThreshold']
  30. ) => void;
  31. onThresholdPeriodChange: (value: number) => void;
  32. onThresholdTypeChange: (thresholdType: AlertRuleThresholdType) => void;
  33. organization: Organization;
  34. projects: Project[];
  35. resolveThreshold: UnsavedMetricRule['resolveThreshold'];
  36. thresholdPeriod: UnsavedMetricRule['thresholdPeriod'];
  37. thresholdType: UnsavedMetricRule['thresholdType'];
  38. triggers: Trigger[];
  39. };
  40. /**
  41. * A list of forms to add, edit, and delete triggers.
  42. */
  43. class Triggers extends Component<Props> {
  44. handleDeleteTrigger = (index: number) => {
  45. const {triggers, onChange} = this.props;
  46. const updatedTriggers = removeAtArrayIndex(triggers, index);
  47. onChange(updatedTriggers);
  48. };
  49. handleChangeTrigger = (
  50. triggerIndex: number,
  51. trigger: Trigger,
  52. changeObj: Partial<Trigger>
  53. ) => {
  54. const {triggers, onChange} = this.props;
  55. const updatedTriggers = replaceAtArrayIndex(triggers, triggerIndex, trigger);
  56. onChange(updatedTriggers, triggerIndex, changeObj);
  57. };
  58. handleAddAction = (triggerIndex: number, action: Action) => {
  59. const {onChange, triggers} = this.props;
  60. const trigger = triggers[triggerIndex];
  61. const actions = [...trigger.actions, action];
  62. const updatedTriggers = replaceAtArrayIndex(triggers, triggerIndex, {
  63. ...trigger,
  64. actions,
  65. });
  66. onChange(updatedTriggers, triggerIndex, {actions});
  67. };
  68. handleChangeActions = (
  69. triggerIndex: number,
  70. triggers: Trigger[],
  71. actions: Action[]
  72. ): void => {
  73. const {onChange} = this.props;
  74. const trigger = triggers[triggerIndex];
  75. const updatedTriggers = replaceAtArrayIndex(triggers, triggerIndex, {
  76. ...trigger,
  77. actions,
  78. });
  79. onChange(updatedTriggers, triggerIndex, {actions});
  80. };
  81. render() {
  82. const {
  83. availableActions,
  84. currentProject,
  85. errors,
  86. organization,
  87. projects,
  88. triggers,
  89. disabled,
  90. aggregate,
  91. thresholdType,
  92. thresholdPeriod,
  93. comparisonType,
  94. resolveThreshold,
  95. onThresholdTypeChange,
  96. onResolveThresholdChange,
  97. onThresholdPeriodChange,
  98. } = this.props;
  99. // Note we only support 2 triggers max
  100. return (
  101. <Fragment>
  102. <Panel>
  103. <PanelBody>
  104. <TriggerForm
  105. disabled={disabled}
  106. errors={errors}
  107. organization={organization}
  108. projects={projects}
  109. triggers={triggers}
  110. aggregate={aggregate}
  111. resolveThreshold={resolveThreshold}
  112. thresholdType={thresholdType}
  113. thresholdPeriod={thresholdPeriod}
  114. comparisonType={comparisonType}
  115. onChange={this.handleChangeTrigger}
  116. onThresholdTypeChange={onThresholdTypeChange}
  117. onResolveThresholdChange={onResolveThresholdChange}
  118. onThresholdPeriodChange={onThresholdPeriodChange}
  119. />
  120. </PanelBody>
  121. </Panel>
  122. <ActionsPanel
  123. disabled={disabled}
  124. loading={availableActions === null}
  125. error={false}
  126. availableActions={availableActions}
  127. currentProject={currentProject}
  128. organization={organization}
  129. projects={projects}
  130. triggers={triggers}
  131. onChange={this.handleChangeActions}
  132. onAdd={this.handleAddAction}
  133. />
  134. </Fragment>
  135. );
  136. }
  137. }
  138. export default Triggers;