customIgnoreDurationModal.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import {Component, createRef, Fragment} from 'react';
  2. import moment from 'moment';
  3. import {sprintf} from 'sprintf-js';
  4. import {ModalRenderProps} from 'sentry/actionCreators/modal';
  5. import Alert from 'sentry/components/alert';
  6. import Button from 'sentry/components/button';
  7. import ButtonBar from 'sentry/components/buttonBar';
  8. import {t} from 'sentry/locale';
  9. import {ResolutionStatusDetails} from 'sentry/types';
  10. const defaultProps = {
  11. label: t('Ignore this issue until \u2026'),
  12. };
  13. type Props = ModalRenderProps & {
  14. onSelected: (details: ResolutionStatusDetails) => void;
  15. } & typeof defaultProps;
  16. type State = {
  17. dateWarning: boolean;
  18. };
  19. export default class CustomIgnoreDurationModal extends Component<Props, State> {
  20. static defaultProps = defaultProps;
  21. state: State = {
  22. dateWarning: false,
  23. };
  24. snoozeDateInputRef = createRef<HTMLInputElement>();
  25. snoozeTimeInputRef = createRef<HTMLInputElement>();
  26. selectedIgnoreMinutes = () => {
  27. const dateStr = this.snoozeDateInputRef.current?.value; // YYYY-MM-DD
  28. const timeStr = this.snoozeTimeInputRef.current?.value; // HH:MM
  29. if (dateStr && timeStr) {
  30. const selectedDate = moment.utc(dateStr + ' ' + timeStr);
  31. if (selectedDate.isValid()) {
  32. const now = moment.utc();
  33. return selectedDate.diff(now, 'minutes');
  34. }
  35. }
  36. return 0;
  37. };
  38. snoozeClicked = () => {
  39. const minutes = this.selectedIgnoreMinutes();
  40. if (minutes <= 0) {
  41. this.setState({
  42. dateWarning: minutes <= 0,
  43. });
  44. return;
  45. }
  46. this.props.onSelected({ignoreDuration: minutes});
  47. this.props.closeModal();
  48. };
  49. render() {
  50. // Give the user a sane starting point to select a date
  51. // (prettier than the empty date/time inputs):
  52. const defaultDate = new Date();
  53. defaultDate.setDate(defaultDate.getDate() + 14);
  54. defaultDate.setSeconds(0);
  55. defaultDate.setMilliseconds(0);
  56. const defaultDateVal = sprintf(
  57. '%d-%02d-%02d',
  58. defaultDate.getUTCFullYear(),
  59. defaultDate.getUTCMonth() + 1,
  60. defaultDate.getUTCDate()
  61. );
  62. const defaultTimeVal = sprintf('%02d:00', defaultDate.getUTCHours());
  63. const {Header, Body, Footer, label} = this.props;
  64. return (
  65. <Fragment>
  66. <Header>{label}</Header>
  67. <Body>
  68. <form className="form-horizontal">
  69. <div className="control-group">
  70. <h6 className="nav-header">{t('Date')}</h6>
  71. <input
  72. className="form-control"
  73. type="date"
  74. id="snooze-until-date"
  75. defaultValue={defaultDateVal}
  76. ref={this.snoozeDateInputRef}
  77. required
  78. style={{padding: '0 10px'}}
  79. />
  80. </div>
  81. <div className="control-group m-b-1">
  82. <h6 className="nav-header">{t('Time (UTC)')}</h6>
  83. <input
  84. className="form-control"
  85. type="time"
  86. id="snooze-until-time"
  87. defaultValue={defaultTimeVal}
  88. ref={this.snoozeTimeInputRef}
  89. style={{padding: '0 10px'}}
  90. required
  91. />
  92. </div>
  93. </form>
  94. </Body>
  95. {this.state.dateWarning && (
  96. <Alert type="error" showIcon>
  97. {t('Please enter a valid date in the future')}
  98. </Alert>
  99. )}
  100. <Footer>
  101. <ButtonBar gap={1}>
  102. <Button type="button" priority="default" onClick={this.props.closeModal}>
  103. {t('Cancel')}
  104. </Button>
  105. <Button type="button" priority="primary" onClick={this.snoozeClicked}>
  106. {t('Ignore')}
  107. </Button>
  108. </ButtonBar>
  109. </Footer>
  110. </Fragment>
  111. );
  112. }
  113. }