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 InputField from 'sentry/components/forms/inputField';
  6. import SelectField from 'sentry/components/forms/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. <InputField
  52. inline={false}
  53. flexibleControlStateSize
  54. stacked
  55. label={countLabel}
  56. name="count"
  57. type="number"
  58. value={count}
  59. onChange={val => this.handleChange('count' as 'count', Number(val))}
  60. required
  61. placeholder={t('e.g. 100')}
  62. />
  63. <SelectField
  64. inline={false}
  65. flexibleControlStateSize
  66. stacked
  67. label={t('Time window')}
  68. value={window}
  69. name="window"
  70. onChange={val => this.handleChange('window' as const, val)}
  71. options={windowOptions}
  72. placeholder={t('e.g. per hour')}
  73. allowClear
  74. help={t('(Optional) If supplied, this rule will apply as a rate of change.')}
  75. />
  76. </Body>
  77. <Footer>
  78. <ButtonBar gap={1}>
  79. <Button type="button" onClick={closeModal}>
  80. {t('Cancel')}
  81. </Button>
  82. <Button type="button" priority="primary" onClick={this.handleSubmit}>
  83. {t('Ignore')}
  84. </Button>
  85. </ButtonBar>
  86. </Footer>
  87. </Fragment>
  88. );
  89. }
  90. }
  91. export default CustomIgnoreCountModal;