ModeratedColumnHeader.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Copyright (C) 2015 - 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 PropTypes from 'prop-types'
  20. import Constants from './constants'
  21. import I18n from 'i18n!moderated_grading'
  22. const ModeratedColumnHeader = React.createClass({
  23. displayName: 'ModeratedColumnHeader',
  24. propTypes: {
  25. markColumn: PropTypes.string.isRequired,
  26. sortDirection: PropTypes.string,
  27. includeModerationSetHeaders: PropTypes.bool.isRequired,
  28. handleSortMark1: PropTypes.func.isRequired,
  29. handleSortMark2: PropTypes.func.isRequired,
  30. handleSortMark3: PropTypes.func.isRequired,
  31. handleSelectAll: PropTypes.func.isRequired,
  32. permissions: PropTypes.shape({
  33. viewGrades: PropTypes.bool.isRequired
  34. }).isRequired
  35. },
  36. onSelectAllBlurred () {
  37. this.checkbox.setAttribute('aria-label', '');
  38. },
  39. onSelectAllFocused () {
  40. this.checkbox.setAttribute('aria-label', I18n.t('Select all students'));
  41. },
  42. labelSortOrder (mark) {
  43. if (mark !== this.props.markColumn) {
  44. return '';
  45. }
  46. switch (this.props.sortDirection) {
  47. case Constants.sortDirections.DESCENDING:
  48. return I18n.t('sorted descending');
  49. case Constants.sortDirections.ASCENDING:
  50. return I18n.t('sorted ascending');
  51. default:
  52. return '';
  53. }
  54. },
  55. renderLinkArrow (mark) {
  56. if (mark !== this.props.markColumn) {
  57. return null;
  58. }
  59. if (this.props.sortDirection === Constants.sortDirections.DESCENDING) {
  60. return (<i className="icon-mini-arrow-down" />);
  61. }
  62. return (<i className="icon-mini-arrow-up" />);
  63. },
  64. renderCheckbox () {
  65. if (!this.props.permissions.viewGrades) {
  66. return (
  67. <th scope="col" className="ColumnHeader__Selector">&nbsp;</th>
  68. );
  69. }
  70. return (
  71. <th
  72. scope="col"
  73. className="ColumnHeader__Selector"
  74. onBlur={this.onSelectAllBlurred}
  75. onFocus={this.onSelectAllFocused}
  76. >
  77. <input
  78. ref={(c) => { this.checkbox = c; }}
  79. type="checkbox"
  80. onChange={this.props.handleSelectAll}
  81. />
  82. </th>
  83. );
  84. },
  85. renderStudentColumnHeader () {
  86. return (
  87. <th scope="col" className="ModeratedColumnHeader__StudentName ColumnHeader__Item">
  88. <span>{I18n.t('Student')}</span>
  89. </th>
  90. );
  91. },
  92. renderFirstReviewerColumnHeader () {
  93. return (
  94. <th scope="col" className="ModeratedColumnHeader__Mark ColumnHeader__Item">
  95. <a
  96. href="#"
  97. onClick={this.props.handleSortMark1}
  98. >
  99. <span aria-label={I18n.t('First reviewer %{sortOrder}', { sortOrder: this.labelSortOrder(Constants.markColumnNames.MARK_ONE) })}>
  100. {I18n.t('1st Reviewer')}&nbsp;{this.renderLinkArrow(Constants.markColumnNames.MARK_ONE)}
  101. </span>
  102. </a>
  103. </th>
  104. );
  105. },
  106. render () {
  107. if (this.props.includeModerationSetHeaders) {
  108. return (
  109. <thead>
  110. <tr className="ModeratedColumnHeader">
  111. {this.renderCheckbox()}
  112. {this.renderStudentColumnHeader()}
  113. {this.renderFirstReviewerColumnHeader()}
  114. <th scope="col" className="ModeratedColumnHeader__Mark ColumnHeader__Item">
  115. <a
  116. href="#"
  117. onClick={this.props.handleSortMark2}
  118. >
  119. <span aria-label={`${I18n.t('Second reviewer')} ${this.labelSortOrder(Constants.markColumnNames.MARK_TWO)}`}>
  120. {I18n.t('2nd Reviewer')}&nbsp;{this.renderLinkArrow(Constants.markColumnNames.MARK_TWO)}
  121. </span>
  122. </a>
  123. </th>
  124. <th scope="col" className="ModeratedColumnHeader__Mark ColumnHeader__Item">
  125. <a
  126. href="#"
  127. onClick={this.props.handleSortMark3}
  128. >
  129. <span aria-label={I18n.t('Moderator %{sortOrder}', { sortOrder: this.labelSortOrder(Constants.markColumnNames.MARK_THREE) })}>
  130. {I18n.t('Moderator')}&nbsp;{this.renderLinkArrow(Constants.markColumnNames.MARK_THREE)}
  131. </span>
  132. </a>
  133. </th>
  134. <th scope="col" className="ColumnHeader__FinalGrade ColumnHeader__Item">
  135. {I18n.t('Grade')}
  136. </th>
  137. </tr>
  138. </thead>
  139. );
  140. }
  141. return (
  142. <thead>
  143. <tr className="ModeratedColumnHeader">
  144. {this.renderCheckbox()}
  145. {this.renderStudentColumnHeader()}
  146. {this.renderFirstReviewerColumnHeader()}
  147. </tr>
  148. </thead>
  149. );
  150. }
  151. });
  152. export default ModeratedColumnHeader