customIgnoreCountModal.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import {Component, Fragment} from 'react';
  2. import {ModalRenderProps} from 'sentry/actionCreators/modal';
  3. import Button from 'sentry/components/button';
  4. import ButtonBar from 'sentry/components/buttonBar';
  5. import NumberField from 'sentry/components/forms/fields/numberField';
  6. import SelectField from 'sentry/components/forms/fields/selectField';
  7. import {t} from 'sentry/locale';
  8. import {ResolutionStatusDetails, SelectValue} from 'sentry/types';
  9. type CountNames = 'ignoreCount' | 'ignoreUserCount';
  10. type WindowNames = 'ignoreWindow' | 'ignoreUserWindow';
  11. type Props = ModalRenderProps & {
  12. countLabel: string;
  13. countName: CountNames;
  14. label: string;
  15. onSelected: (statusDetails: ResolutionStatusDetails) => void;
  16. windowName: WindowNames;
  17. windowOptions: SelectValue<number>[];
  18. };
  19. type State = {
  20. count: number;
  21. window: number | null;
  22. };
  23. class CustomIgnoreCountModal extends Component<Props, State> {
  24. state: State = {
  25. count: 100,
  26. window: null,
  27. };
  28. handleSubmit = () => {
  29. const {count, window} = this.state;
  30. const {countName, windowName} = this.props;
  31. const statusDetails: ResolutionStatusDetails = {[countName]: count};
  32. if (window) {
  33. statusDetails[windowName] = window;
  34. }
  35. this.props.onSelected(statusDetails);
  36. this.props.closeModal();
  37. };
  38. handleChange = (name: keyof State, value: number) => {
  39. this.setState({[name]: value} as State);
  40. };
  41. render() {
  42. const {Header, Footer, Body, countLabel, label, closeModal, windowOptions} =
  43. this.props;
  44. const {count, window} = this.state;
  45. return (
  46. <Fragment>
  47. <Header>
  48. <h4>{label}</h4>
  49. </Header>
  50. <Body>
  51. <NumberField
  52. inline={false}
  53. flexibleControlStateSize
  54. stacked
  55. label={countLabel}
  56. name="count"
  57. value={count}
  58. onChange={val => this.handleChange('count' as 'count', Number(val))}
  59. required
  60. placeholder={t('e.g. 100')}
  61. />
  62. <SelectField
  63. inline={false}
  64. flexibleControlStateSize
  65. stacked
  66. label={t('Time window')}
  67. value={window}
  68. name="window"
  69. onChange={val => this.handleChange('window' as const, val)}
  70. options={windowOptions}
  71. placeholder={t('e.g. per hour')}
  72. allowClear
  73. help={t('(Optional) If supplied, this rule will apply as a rate of change.')}
  74. />
  75. </Body>
  76. <Footer>
  77. <ButtonBar gap={1}>
  78. <Button type="button" onClick={closeModal}>
  79. {t('Cancel')}
  80. </Button>
  81. <Button type="button" priority="primary" onClick={this.handleSubmit}>
  82. {t('Ignore')}
  83. </Button>
  84. </ButtonBar>
  85. </Footer>
  86. </Fragment>
  87. );
  88. }
  89. }
  90. export default CustomIgnoreCountModal;