diff --git a/src/components/GradesView/GradebookTable/Fields.jsx b/src/components/GradesView/GradebookTable/Fields.jsx
index 867d661..c2e184b 100644
--- a/src/components/GradesView/GradebookTable/Fields.jsx
+++ b/src/components/GradesView/GradebookTable/Fields.jsx
@@ -29,16 +29,16 @@ Username.propTypes = {
};
/**
- * Fields.Email
- * Simple label field for email value.
- * @param {string} email - email for display
+ * Fields.Text
+ * Simple label field for text value.
+ * @param {string} value - value for display
*/
-const Email = ({ email }) => {email};
-Email.propTypes = {
- email: PropTypes.string.isRequired,
+const Text = ({ value }) => ({value});
+Text.propTypes = {
+ value: PropTypes.string.isRequired,
};
export default StrictDict({
- Email,
+ Text,
Username,
});
diff --git a/src/components/GradesView/GradebookTable/Fields.test.jsx b/src/components/GradesView/GradebookTable/Fields.test.jsx
index 53c02fc..dd34237 100644
--- a/src/components/GradesView/GradebookTable/Fields.test.jsx
+++ b/src/components/GradesView/GradebookTable/Fields.test.jsx
@@ -41,13 +41,13 @@ describe('Gradebook Table Fields', () => {
});
});
- describe('Email', () => {
- const email = 'myTag@place.com';
+ describe('Text', () => {
+ const value = 'myTag@place.com';
test('snapshot', () => {
- expect(shallow()).toMatchSnapshot();
+ expect(shallow()).toMatchSnapshot();
});
- test('wraps entry email', () => {
- expect(shallow().text()).toEqual(email);
+ test('wraps entry value', () => {
+ expect(shallow().text()).toEqual(value);
});
});
});
diff --git a/src/components/GradesView/GradebookTable/LabelReplacements.jsx b/src/components/GradesView/GradebookTable/LabelReplacements.jsx
index 959766a..86dd89c 100644
--- a/src/components/GradesView/GradebookTable/LabelReplacements.jsx
+++ b/src/components/GradesView/GradebookTable/LabelReplacements.jsx
@@ -45,6 +45,13 @@ const TotalGradeLabelReplacement = () => (
);
+/**
+ * Asterisk to display next to heading labels that are only used for masters students
+ */
+const mastersOnlyFieldAsterisk = (
+ *
+);
+
/**
*
* Username column header. Lists that Student Key is possibly available
@@ -56,11 +63,24 @@ const UsernameLabelReplacement = () => (
+ { mastersOnlyFieldAsterisk }
);
+/**
+ *
+ * Column header for fields that are only available for masters students
+ */
+const MastersOnlyLabelReplacement = (message) => (
+
+
+ { mastersOnlyFieldAsterisk }
+
+);
+
export default StrictDict({
TotalGradeLabelReplacement,
UsernameLabelReplacement,
+ MastersOnlyLabelReplacement,
});
diff --git a/src/components/GradesView/GradebookTable/LabelReplacements.test.jsx b/src/components/GradesView/GradebookTable/LabelReplacements.test.jsx
index fc2bbb1..a37729a 100644
--- a/src/components/GradesView/GradebookTable/LabelReplacements.test.jsx
+++ b/src/components/GradesView/GradebookTable/LabelReplacements.test.jsx
@@ -9,6 +9,7 @@ import LabelReplacements from './LabelReplacements';
const {
TotalGradeLabelReplacement,
UsernameLabelReplacement,
+ MastersOnlyLabelReplacement,
} = LabelReplacements;
jest.mock('@edx/paragon', () => ({
@@ -35,6 +36,16 @@ describe('LabelReplacements', () => {
expect(shallow()).toMatchSnapshot();
});
});
+ describe('MastersOnlyLabelReplacement', () => {
+ test('snapshot', () => {
+ const message = {
+ id: 'id',
+ defaultMessage: 'defaultMessAge',
+ description: 'desCripTion',
+ };
+ expect(shallow()).toMatchSnapshot();
+ });
+ });
});
describe('snapshot', () => {
diff --git a/src/components/GradesView/GradebookTable/__snapshots__/Fields.test.jsx.snap b/src/components/GradesView/GradebookTable/__snapshots__/Fields.test.jsx.snap
index cb1f257..7c0e555 100644
--- a/src/components/GradesView/GradebookTable/__snapshots__/Fields.test.jsx.snap
+++ b/src/components/GradesView/GradebookTable/__snapshots__/Fields.test.jsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Gradebook Table Fields Email snapshot 1`] = `
+exports[`Gradebook Table Fields Text snapshot 1`] = `
diff --git a/src/components/GradesView/GradebookTable/__snapshots__/LabelReplacements.test.jsx.snap b/src/components/GradesView/GradebookTable/__snapshots__/LabelReplacements.test.jsx.snap
index e0572bf..ed189e2 100644
--- a/src/components/GradesView/GradebookTable/__snapshots__/LabelReplacements.test.jsx.snap
+++ b/src/components/GradesView/GradebookTable/__snapshots__/LabelReplacements.test.jsx.snap
@@ -1,5 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`LabelReplacements MastersOnlyLabelReplacement snapshot 1`] = `
+
+
+
+ *
+
+
+`;
+
exports[`LabelReplacements TotalGradeLabelReplacement displays overlay tooltip 1`] = `
+
+ *
+
`;
diff --git a/src/components/GradesView/GradebookTable/__snapshots__/test.jsx.snap b/src/components/GradesView/GradebookTable/__snapshots__/test.jsx.snap
index 7bd40ff..228b171 100644
--- a/src/components/GradesView/GradebookTable/__snapshots__/test.jsx.snap
+++ b/src/components/GradesView/GradebookTable/__snapshots__/test.jsx.snap
@@ -13,8 +13,16 @@ exports[`GradebookTable component snapshot - fields1 and 2 between email and tot
"accessor": "Username",
},
Object {
- "Header": ,
+ "accessor": "Full Name",
+ },
+ Object {
+ "Header": ,
diff --git a/src/components/GradesView/GradebookTable/index.jsx b/src/components/GradesView/GradebookTable/index.jsx
index 902dd38..efdf04d 100644
--- a/src/components/GradesView/GradebookTable/index.jsx
+++ b/src/components/GradesView/GradebookTable/index.jsx
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { DataTable } from '@edx/paragon';
-import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
+import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import selectors from 'data/selectors';
import { Headings } from 'data/constants/grades';
@@ -38,7 +38,9 @@ export class GradebookTable extends React.Component {
} else if (heading === Headings.username) {
label = ;
} else if (heading === Headings.email) {
- label = ;
+ label = ;
+ } else if (heading === Headings.fullName) {
+ label = ;
} else {
label = heading;
}
@@ -49,7 +51,8 @@ export class GradebookTable extends React.Component {
[Headings.username]: (
),
- [Headings.email]: (),
+ [Headings.fullName]: (),
+ [Headings.email]: (),
[Headings.totalGrade]: `${roundGrade(entry.percent * 100)}${getLocalizedPercentSign()}`,
...entry.section_breakdown.reduce((acc, subsection) => ({
...acc,
diff --git a/src/components/GradesView/GradebookTable/messages.js b/src/components/GradesView/GradebookTable/messages.js
index 2caf521..9ebc629 100644
--- a/src/components/GradesView/GradebookTable/messages.js
+++ b/src/components/GradesView/GradebookTable/messages.js
@@ -1,9 +1,14 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
+ fullNameHeading: {
+ id: 'gradebook.GradesView.table.headings.fullName',
+ defaultMessage: 'Full Name',
+ description: 'Gradebook table full name column header',
+ },
emailHeading: {
id: 'gradebook.GradesView.table.headings.email',
- defaultMessage: 'Email*',
+ defaultMessage: 'Email',
description: 'Gradebook table email column header',
},
totalGradeHeading: {
@@ -18,7 +23,7 @@ const messages = defineMessages({
},
studentKeyLabel: {
id: 'gradebook.GradesView.table.labels.studentKey',
- defaultMessage: 'Student Key*',
+ defaultMessage: 'Student Key',
description: 'Gradebook table Student Key label',
},
usernameLabel: {
diff --git a/src/components/GradesView/GradebookTable/test.jsx b/src/components/GradesView/GradebookTable/test.jsx
index 6970e06..ed416a6 100644
--- a/src/components/GradesView/GradebookTable/test.jsx
+++ b/src/components/GradesView/GradebookTable/test.jsx
@@ -2,7 +2,6 @@ import React from 'react';
import { shallow } from 'enzyme';
import { DataTable } from '@edx/paragon';
-import { FormattedMessage } from '@edx/frontend-platform/i18n';
import selectors from 'data/selectors';
import { Headings } from 'data/constants/grades';
@@ -22,7 +21,7 @@ jest.mock('./Fields', () => ({
__esModule: true,
default: {
Username: () => 'Fields.Username',
- Email: () => 'Fields.Email',
+ Text: () => 'Fields.Text',
},
}));
jest.mock('./LabelReplacements', () => ({
@@ -30,6 +29,7 @@ jest.mock('./LabelReplacements', () => ({
default: {
TotalGradeLabelReplacement: () => 'TotalGradeLabelReplacement',
UsernameLabelReplacement: () => 'UsernameLabelReplacement',
+ MastersOnlyLabelReplacement: () => 'MastersOnlyLabelReplacement',
},
}));
jest.mock('./GradeButton', () => 'GradeButton');
@@ -75,6 +75,7 @@ describe('GradebookTable', () => {
],
headings: [
Headings.username,
+ Headings.fullName,
Headings.email,
fields.field1,
fields.field2,
@@ -104,17 +105,22 @@ describe('GradebookTable', () => {
expect(heading.accessor).toEqual(Headings.username);
expect(heading.Header.type).toEqual(LabelReplacements.UsernameLabelReplacement);
});
- test('email sets key and Header from header', () => {
+ test('full name sets key and Header from header', () => {
const heading = headings[1];
+ expect(heading.accessor).toEqual(Headings.fullName);
+ expect(heading.Header).toEqual();
+ });
+ test('email sets key and Header from header', () => {
+ const heading = headings[2];
expect(heading.accessor).toEqual(Headings.email);
- expect(heading.Header).toEqual();
+ expect(heading.Header).toEqual();
});
test('subsections set key and Header from header', () => {
- expect(headings[2]).toEqual({ accessor: fields.field1, Header: fields.field1 });
- expect(headings[3]).toEqual({ accessor: fields.field2, Header: fields.field2 });
+ expect(headings[3]).toEqual({ accessor: fields.field1, Header: fields.field1 });
+ expect(headings[4]).toEqual({ accessor: fields.field2, Header: fields.field2 });
});
test('totalGrade sets key and replaces Header with component', () => {
- const heading = headings[4];
+ const heading = headings[5];
expect(heading.accessor).toEqual(Headings.totalGrade);
expect(heading.Header.type).toEqual(LabelReplacements.TotalGradeLabelReplacement);
});
@@ -139,10 +145,15 @@ describe('GradebookTable', () => {
userKey: entry.external_user_key,
});
});
- test('email set to Email Field', () => {
+ test('fullName set to Text Field', () => {
+ const field = row[Headings.fullName];
+ expect(field.type).toEqual(Fields.Text);
+ expect(field.props).toEqual({ value: entry.full_name });
+ });
+ test('email set to Text Field', () => {
const field = row[Headings.email];
- expect(field.type).toEqual(Fields.Email);
- expect(field.props).toEqual({ email: entry.email });
+ expect(field.type).toEqual(Fields.Text);
+ expect(field.props).toEqual({ value: entry.email });
});
test('totalGrade set to rounded percent grade * 100', () => {
expect(
diff --git a/src/data/constants/grades.js b/src/data/constants/grades.js
index 5425308..2192158 100644
--- a/src/data/constants/grades.js
+++ b/src/data/constants/grades.js
@@ -3,6 +3,7 @@ import { StrictDict } from 'utils';
const EMAIL_HEADING = 'Email';
const TOTAL_COURSE_GRADE_HEADING = 'Total Grade (%)';
const USERNAME_HEADING = 'Username';
+const FULL_NAME_HEADING = 'Full Name';
const GradeFormats = StrictDict({
absolute: 'absolute',
@@ -10,15 +11,17 @@ const GradeFormats = StrictDict({
});
const Headings = StrictDict({
- email: 'Email',
- totalGrade: 'Total Grade (%)',
- username: 'Username',
+ email: EMAIL_HEADING,
+ totalGrade: TOTAL_COURSE_GRADE_HEADING,
+ username: USERNAME_HEADING,
+ fullName: FULL_NAME_HEADING,
});
export {
EMAIL_HEADING,
TOTAL_COURSE_GRADE_HEADING,
USERNAME_HEADING,
+ FULL_NAME_HEADING,
GradeFormats,
Headings,
};
diff --git a/src/data/selectors/grades.js b/src/data/selectors/grades.js
index 6182873..15abbbe 100644
--- a/src/data/selectors/grades.js
+++ b/src/data/selectors/grades.js
@@ -105,12 +105,17 @@ export const headingMapper = (category, label = 'All') => {
} else {
filter = filters.byLabel;
}
- const { username, email, totalGrade } = Headings;
+ const {
+ username,
+ fullName,
+ email,
+ totalGrade,
+ } = Headings;
const filteredLabels = (entry) => entry.filter(filter).map(s => s.label);
return (entry) => (
entry
- ? [username, email, ...filteredLabels(entry), totalGrade]
+ ? [username, fullName, email, ...filteredLabels(entry), totalGrade]
: []
);
};
diff --git a/src/data/selectors/grades.test.js b/src/data/selectors/grades.test.js
index e8a8830..bdd5f06 100644
--- a/src/data/selectors/grades.test.js
+++ b/src/data/selectors/grades.test.js
@@ -1,4 +1,9 @@
-import { EMAIL_HEADING, TOTAL_COURSE_GRADE_HEADING, USERNAME_HEADING } from '../constants/grades';
+import {
+ EMAIL_HEADING,
+ FULL_NAME_HEADING,
+ TOTAL_COURSE_GRADE_HEADING,
+ USERNAME_HEADING,
+} from '../constants/grades';
import { formatDateForDisplay } from '../actions/utils';
import * as selectors from './grades';
import exportedSelectors from './grades';
@@ -179,6 +184,7 @@ describe('grades selectors', () => {
describe('headingMapper', () => {
const expectedHeaders = (subsectionLabels) => ([
USERNAME_HEADING,
+ FULL_NAME_HEADING,
EMAIL_HEADING,
...subsectionLabels,
TOTAL_COURSE_GRADE_HEADING,