diff --git a/package-lock.json b/package-lock.json
index 61ea891..ccd9fe5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "@edx/frontend-app-gradebook",
- "version": "1.4.22",
+ "version": "1.4.24",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index a1126e6..60805ac 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@edx/frontend-app-gradebook",
- "version": "1.4.23",
+ "version": "1.4.24",
"description": "edx editable gradebook-ui to manipulate grade overrides on subsections",
"repository": {
"type": "git",
diff --git a/src/components/Gradebook/GradebookTable.jsx b/src/components/Gradebook/GradebookTable.jsx
index d3e4b7e..bd2a764 100644
--- a/src/components/Gradebook/GradebookTable.jsx
+++ b/src/components/Gradebook/GradebookTable.jsx
@@ -2,12 +2,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
-
-import { Table } from '@edx/paragon';
-
+import {
+ Table, OverlayTrigger, Tooltip, Icon,
+} from '@edx/paragon';
import { formatDateForDisplay } from '../../data/actions/utils';
import { getHeadings } from '../../data/selectors/grades';
import { fetchGradeOverrideHistory } from '../../data/actions/grades';
+import { EMAIL_HEADING, TOTAL_COURSE_GRADE_HEADING, USERNAME_HEADING } from '../../data/constants/grades';
const DECIMAL_PRECISION = 2;
@@ -49,10 +50,10 @@ export class GradebookTable extends React.Component {
percent: (entries, areGradesFrozen) => entries.map((entry) => {
const learnerInformation = this.getLearnerInformation(entry);
const results = {
- Username: (
+ [USERNAME_HEADING]: (
{learnerInformation}
),
- Email: (
+ [EMAIL_HEADING]: (
{entry.email}
),
};
@@ -73,17 +74,17 @@ export class GradebookTable extends React.Component {
}
return acc;
}, {});
- const totals = { Total: `${this.roundGrade(entry.percent * 100)}%` };
+ const totals = { [TOTAL_COURSE_GRADE_HEADING]: `${this.roundGrade(entry.percent * 100)}%` };
return Object.assign(results, assignments, totals);
}),
absolute: (entries, areGradesFrozen) => entries.map((entry) => {
const learnerInformation = this.getLearnerInformation(entry);
const results = {
- Username: (
+ [USERNAME_HEADING]: (
{learnerInformation}
),
- Email: (
+ [EMAIL_HEADING]: (
{entry.email}
),
};
@@ -111,7 +112,10 @@ export class GradebookTable extends React.Component {
return acc;
}, {});
- const totals = { Total: `${this.roundGrade(entry.percent * 100)}/100` };
+ // Show this as a percent no matter what the other setting is. The data
+ // we're getting gives the final grade as a percentage so making it appear
+ // to be "out of" 100 is misleading.
+ const totals = { [TOTAL_COURSE_GRADE_HEADING]: `${this.roundGrade(entry.percent * 100)}%` };
return Object.assign(results, assignments, totals);
}),
};
@@ -120,22 +124,44 @@ export class GradebookTable extends React.Component {
let headings = [...this.props.headings];
if (headings.length > 0) {
- const userInformationHeadingLabel = (
+ const headerLabelReplacements = {};
+ headerLabelReplacements[USERNAME_HEADING] = (
);
- const emailHeadingLabel = 'Email*';
+ headerLabelReplacements[EMAIL_HEADING] = 'Email*';
- headings = headings.map(heading => ({
- label: heading,
- key: heading,
- }));
+ const totalGradePercentageMessage = 'Total Grade values are always displayed as a percentage.';
+ headerLabelReplacements[TOTAL_COURSE_GRADE_HEADING] = (
+
+
{totalGradePercentageMessage})}
+ >
+
+ {TOTAL_COURSE_GRADE_HEADING}
+
+
+
+
+
+
+ );
- // replace username heading label to include additional user data
- headings[0].label = userInformationHeadingLabel;
- headings[1].label = emailHeadingLabel;
+ headings = headings.map(heading => {
+ const result = {
+ label: heading,
+ key: heading,
+ };
+ if (headerLabelReplacements[heading] !== undefined) {
+ result.label = headerLabelReplacements[heading];
+ }
+ return result;
+ });
}
return headings;
diff --git a/src/components/Gradebook/gradebook.scss b/src/components/Gradebook/gradebook.scss
index b643840..ec23700 100644
--- a/src/components/Gradebook/gradebook.scss
+++ b/src/components/Gradebook/gradebook.scss
@@ -72,7 +72,10 @@
.student-key {
font-size: 14px;
}
-
+
+ #courseGradeTooltipIcon {
+ float: right;
+ }
.table thead tr {
min-height: 60px;
@@ -111,6 +114,9 @@
td:nth-child(2) {
width: 240px;
}
+ th:nth-last-of-type(1) {
+ width: 150px;
+ }
th, td {
width: 120px;
}
diff --git a/src/data/constants/grades.js b/src/data/constants/grades.js
new file mode 100644
index 0000000..1eb0680
--- /dev/null
+++ b/src/data/constants/grades.js
@@ -0,0 +1,5 @@
+const EMAIL_HEADING = 'Email';
+const TOTAL_COURSE_GRADE_HEADING = 'Total Grade (%)';
+const USERNAME_HEADING = 'Username';
+
+export { EMAIL_HEADING, TOTAL_COURSE_GRADE_HEADING, USERNAME_HEADING };
diff --git a/src/data/selectors/grades.js b/src/data/selectors/grades.js
index c6ab62d..d08378a 100644
--- a/src/data/selectors/grades.js
+++ b/src/data/selectors/grades.js
@@ -1,5 +1,6 @@
import { formatDateForDisplay } from '../actions/utils';
import { getFilters } from './filters';
+import { EMAIL_HEADING, TOTAL_COURSE_GRADE_HEADING, USERNAME_HEADING } from '../constants/grades';
const getRowsProcessed = (data) => {
const {
@@ -52,13 +53,13 @@ const headingMapper = (category, label = 'All') => {
return (entry) => {
if (entry) {
- const results = ['Username', 'Email'];
+ const results = [USERNAME_HEADING, EMAIL_HEADING];
const assignmentHeadings = entry
.filter(filters[filter])
.map(s => s.label);
- const totals = ['Total'];
+ const totals = [TOTAL_COURSE_GRADE_HEADING];
return results.concat(assignmentHeadings).concat(totals);
}