AssignmentGroupColumnHeader.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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 IconMoreSolid from 'instructure-icons/lib/Solid/IconMoreSolid';
  21. import { MenuItem, MenuItemFlyout, MenuItemGroup } from 'instructure-ui/lib/components/Menu';
  22. import PopoverMenu from 'instructure-ui/lib/components/PopoverMenu';
  23. import Typography from 'instructure-ui/lib/components/Typography';
  24. import I18n from 'i18n!gradebook';
  25. import ScreenReaderContent from 'instructure-ui/lib/components/ScreenReaderContent';
  26. import ColumnHeader from 'jsx/gradezilla/default_gradebook/components/ColumnHeader';
  27. function renderTrigger (assignmentGroup, menuShown, ref) {
  28. const classes = `Gradebook__ColumnHeaderAction ${menuShown ? 'menuShown' : ''}`;
  29. return (
  30. <span ref={ref} className={classes}>
  31. <Typography weight="bold" fontStyle="normal" size="large" color="brand">
  32. <IconMoreSolid
  33. className="rotated"
  34. title={I18n.t('%{name} Options', { name: assignmentGroup.name })}
  35. />
  36. </Typography>
  37. </span>
  38. );
  39. }
  40. function renderAssignmentGroupWeight (assignmentGroup, weightedGroups) {
  41. if (!weightedGroups) {
  42. return '';
  43. }
  44. const weightValue = assignmentGroup.groupWeight || 0;
  45. const weightStr = I18n.n(weightValue, { precision: 2, percentage: true });
  46. return (
  47. <Typography weight="normal" fontStyle="normal" size="x-small">
  48. { I18n.t('%{weight} of grade', { weight: weightStr }) }
  49. </Typography>
  50. );
  51. }
  52. class AssignmentGroupColumnHeader extends ColumnHeader {
  53. static propTypes = {
  54. assignmentGroup: shape({
  55. name: string.isRequired,
  56. groupWeight: number
  57. }).isRequired,
  58. sortBySetting: shape({
  59. direction: string.isRequired,
  60. disabled: bool.isRequired,
  61. isSortColumn: bool.isRequired,
  62. onSortByGradeAscending: func.isRequired,
  63. onSortByGradeDescending: func.isRequired,
  64. settingKey: string.isRequired
  65. }).isRequired,
  66. weightedGroups: bool.isRequired,
  67. onMenuClose: func.isRequired,
  68. ...ColumnHeader.propTypes
  69. };
  70. static defaultProps = {
  71. ...ColumnHeader.defaultProps
  72. };
  73. render () {
  74. const { assignmentGroup, sortBySetting, weightedGroups } = this.props;
  75. const selectedSortSetting = sortBySetting.isSortColumn && sortBySetting.settingKey;
  76. const menuShown = this.state.menuShown;
  77. return (
  78. <div className="Gradebook__ColumnHeaderContent">
  79. <span className="Gradebook__ColumnHeaderDetail">
  80. <span>{ this.props.assignmentGroup.name }</span>
  81. { renderAssignmentGroupWeight(assignmentGroup, weightedGroups) }
  82. </span>
  83. <PopoverMenu
  84. contentRef={this.bindOptionsMenuContent}
  85. shouldFocusTriggerOnClose={false}
  86. trigger={renderTrigger(this.props.assignmentGroup, menuShown, this.bindOptionsMenuTrigger)}
  87. onToggle={this.onToggle}
  88. onClose={this.props.onMenuClose}
  89. >
  90. <MenuItemFlyout label={I18n.t('Sort by')} contentRef={this.bindSortByMenuContent}>
  91. <MenuItemGroup label={<ScreenReaderContent>{I18n.t('Sort by')}</ScreenReaderContent>}>
  92. <MenuItem
  93. selected={selectedSortSetting === 'grade' && sortBySetting.direction === 'ascending'}
  94. disabled={sortBySetting.disabled}
  95. onSelect={sortBySetting.onSortByGradeAscending}
  96. >
  97. <span>{I18n.t('Grade - Low to High')}</span>
  98. </MenuItem>
  99. <MenuItem
  100. selected={selectedSortSetting === 'grade' && sortBySetting.direction === 'descending'}
  101. disabled={sortBySetting.disabled}
  102. onSelect={sortBySetting.onSortByGradeDescending}
  103. >
  104. <span>{I18n.t('Grade - High to Low')}</span>
  105. </MenuItem>
  106. </MenuItemGroup>
  107. </MenuItemFlyout>
  108. </PopoverMenu>
  109. </div>
  110. );
  111. }
  112. }
  113. export default AssignmentGroupColumnHeader;