SubmissionTrayRadioInputGroup.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * Copyright (C) 2017 - present Instructure, Inc.
  3. *
  4. * This file is part of Canvas.
  5. *
  6. * Canvas is free software: you can redistribute it and/or modify it under
  7. * the terms of the GNU Affero General Public License as published by the Free
  8. * Software Foundation, version 3 of the License.
  9. *
  10. * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
  11. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. * details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License along
  16. * with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. import React from 'react';
  19. import { bool, func, number, shape, string } from 'prop-types';
  20. import FormFieldGroup from 'instructure-ui/lib/components/FormFieldGroup';
  21. import ScreenReaderContent from 'instructure-ui/lib/components/ScreenReaderContent';
  22. import SubmissionTrayRadioInput from 'jsx/gradezilla/default_gradebook/components/SubmissionTrayRadioInput';
  23. import { statusesTitleMap } from 'jsx/gradezilla/default_gradebook/constants/statuses';
  24. import NumberHelper from 'jsx/shared/helpers/numberHelper';
  25. import I18n from 'i18n!gradebook';
  26. function checkedValue (submission) {
  27. if (submission.excused) {
  28. return 'excused';
  29. } else if (submission.missing) {
  30. return 'missing';
  31. } else if (submission.late) {
  32. return 'late';
  33. }
  34. return 'none';
  35. }
  36. function isNumeric (input) {
  37. return NumberHelper.validate(input);
  38. }
  39. export default class SubmissionTrayRadioInputGroup extends React.Component {
  40. handleNumberInputBlur = ({ target: { value } }) => {
  41. if (!isNumeric(value)) {
  42. return;
  43. }
  44. let secondsLateOverride = NumberHelper.parse(value) * 3600;
  45. if (this.props.latePolicy.lateSubmissionInterval === 'day') {
  46. secondsLateOverride *= 24;
  47. }
  48. this.props.updateSubmission({
  49. latePolicyStatus: 'late',
  50. secondsLateOverride: Math.trunc(secondsLateOverride)
  51. });
  52. }
  53. handleRadioInputChanged = ({ target: { value } }) => {
  54. const alreadyChecked = checkedValue(this.props.submission) === value;
  55. if (alreadyChecked || this.props.submissionUpdating) {
  56. return;
  57. }
  58. const data = value === 'excused' ? { excuse: true } : { latePolicyStatus: value };
  59. if (value === 'late') {
  60. data.secondsLateOverride = 0;
  61. }
  62. this.props.updateSubmission(data);
  63. }
  64. render () {
  65. const radioOptions = ['none', 'late', 'missing', 'excused'].map(status =>
  66. <SubmissionTrayRadioInput
  67. key={status}
  68. checked={checkedValue(this.props.submission) === status}
  69. color={this.props.colors[status]}
  70. latePolicy={this.props.latePolicy}
  71. locale={this.props.locale}
  72. onChange={this.handleRadioInputChanged}
  73. onNumberInputBlur={this.handleNumberInputBlur}
  74. submission={this.props.submission}
  75. text={statusesTitleMap[status] || I18n.t('None')}
  76. value={status}
  77. />
  78. );
  79. return (
  80. <FormFieldGroup description={I18n.t('Status')} layout="stacked" rowSpacing="none">
  81. {radioOptions}
  82. </FormFieldGroup>
  83. );
  84. }
  85. }
  86. SubmissionTrayRadioInputGroup.propTypes = {
  87. colors: shape({
  88. late: string.isRequired,
  89. missing: string.isRequired,
  90. excused: string.isRequired
  91. }).isRequired,
  92. latePolicy: shape({
  93. lateSubmissionInterval: string.isRequired
  94. }).isRequired,
  95. locale: string.isRequired,
  96. submission: shape({
  97. excused: bool.isRequired,
  98. late: bool.isRequired,
  99. missing: bool.isRequired,
  100. secondsLate: number.isRequired
  101. }).isRequired,
  102. submissionUpdating: bool.isRequired,
  103. updateSubmission: func.isRequired
  104. };