fix: eslint autofixable issues (#32181)
* fix: eslint operator-linebreak issue * fix: eslint quotes issue * fix: react jsx indent and props issues * fix: eslint trailing spaces issues * fix: eslint line around directives issue * fix: eslint semi rule * fix: eslint newline per chain rule * fix: eslint space infix ops rule * fix: eslint space-in-parens issue * fix: eslint space before function paren issue * fix: eslint space before blocks issue * fix: eslint arrow body style issue * fix: eslint dot-location issue * fix: eslint quotes issue * fix: eslint quote props issue * fix: eslint operator assignment issue * fix: eslint new line after import issue * fix: indent issues * fix: operator assignment issue * fix: all autofixable eslint issues * fix: all react related fixable issues * fix: autofixable eslint issues * chore: remove all template literals * fix: remaining autofixable issues * fix: failing js test
This commit is contained in:
committed by
GitHub
parent
f2daf37d4a
commit
d7053a6783
@@ -49,7 +49,6 @@
|
|||||||
"import/no-dynamic-require": "off",
|
"import/no-dynamic-require": "off",
|
||||||
"import/no-unresolved": "off",
|
"import/no-unresolved": "off",
|
||||||
"max-len": "off",
|
"max-len": "off",
|
||||||
"newline-per-chained-call": "off",
|
|
||||||
"no-console": "off",
|
"no-console": "off",
|
||||||
"no-lonely-if": "off",
|
"no-lonely-if": "off",
|
||||||
"no-param-reassign": "off",
|
"no-param-reassign": "off",
|
||||||
@@ -73,7 +72,6 @@
|
|||||||
"radix": "off",
|
"radix": "off",
|
||||||
"react/jsx-indent-props": ["error", 4],
|
"react/jsx-indent-props": ["error", 4],
|
||||||
"react/prop-types": "off",
|
"react/prop-types": "off",
|
||||||
"semi": "off",
|
|
||||||
"vars-on-top": "off"
|
"vars-on-top": "off"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
jasmine.getFixtures().fixturesPath = '/base/templates';
|
|
||||||
|
|
||||||
import 'common/js/spec_helpers/jasmine-extensions';
|
import 'common/js/spec_helpers/jasmine-extensions';
|
||||||
import 'common/js/spec_helpers/jasmine-stealth';
|
import 'common/js/spec_helpers/jasmine-stealth';
|
||||||
import 'common/js/spec_helpers/jasmine-waituntil';
|
import 'common/js/spec_helpers/jasmine-waituntil';
|
||||||
@@ -12,11 +10,6 @@ import _ from 'underscore';
|
|||||||
import str from 'underscore.string';
|
import str from 'underscore.string';
|
||||||
import HtmlUtils from 'edx-ui-toolkit/js/utils/html-utils';
|
import HtmlUtils from 'edx-ui-toolkit/js/utils/html-utils';
|
||||||
import StringUtils from 'edx-ui-toolkit/js/utils/string-utils';
|
import StringUtils from 'edx-ui-toolkit/js/utils/string-utils';
|
||||||
window._ = _;
|
|
||||||
window._.str = str;
|
|
||||||
window.edx = window.edx || {};
|
|
||||||
window.edx.HtmlUtils = HtmlUtils;
|
|
||||||
window.edx.StringUtils = StringUtils;
|
|
||||||
|
|
||||||
// These are the tests that will be run
|
// These are the tests that will be run
|
||||||
import './xblock/cms.runtime.v1_spec.js';
|
import './xblock/cms.runtime.v1_spec.js';
|
||||||
@@ -31,4 +24,12 @@ import '../../../js/spec/views/pages/course_outline_spec.js';
|
|||||||
import '../../../js/spec/views/xblock_editor_spec.js';
|
import '../../../js/spec/views/xblock_editor_spec.js';
|
||||||
import '../../../js/spec/views/xblock_string_field_editor_spec.js';
|
import '../../../js/spec/views/xblock_string_field_editor_spec.js';
|
||||||
|
|
||||||
|
jasmine.getFixtures().fixturesPath = '/base/templates';
|
||||||
|
|
||||||
|
window._ = _;
|
||||||
|
window._.str = str;
|
||||||
|
window.edx = window.edx || {};
|
||||||
|
window.edx.HtmlUtils = HtmlUtils;
|
||||||
|
window.edx.StringUtils = StringUtils;
|
||||||
|
|
||||||
window.__karma__.start(); // eslint-disable-line no-underscore-dangle
|
window.__karma__.start(); // eslint-disable-line no-underscore-dangle
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
// http://tobyho.com/2012/01/30/write-a-jasmine-matcher/
|
// http://tobyho.com/2012/01/30/write-a-jasmine-matcher/
|
||||||
|
|
||||||
define(['jquery'], function($) { // eslint-disable-line no-unused-vars
|
define(['jquery'], function($) { // eslint-disable-line no-unused-vars
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
return function() {
|
return function() {
|
||||||
jasmine.addMatchers({
|
jasmine.addMatchers({
|
||||||
|
|||||||
@@ -64,16 +64,16 @@ function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHel
|
|||||||
|
|
||||||
it('course mode selection updating the link successfully', function() {
|
it('course mode selection updating the link successfully', function() {
|
||||||
selectDropDownByText(this.view.$(SELECTORS.course_modes), 'test1');
|
selectDropDownByText(this.view.$(SELECTORS.course_modes), 'test1');
|
||||||
expect(this.view.$(SELECTORS.preview_certificate).attr('href')).
|
expect(this.view.$(SELECTORS.preview_certificate).attr('href'))
|
||||||
toEqual('/users/1/courses/orgX/009/2016?preview=test1');
|
.toEqual('/users/1/courses/orgX/009/2016?preview=test1');
|
||||||
|
|
||||||
selectDropDownByText(this.view.$(SELECTORS.course_modes), 'test2');
|
selectDropDownByText(this.view.$(SELECTORS.course_modes), 'test2');
|
||||||
expect(this.view.$(SELECTORS.preview_certificate).attr('href')).
|
expect(this.view.$(SELECTORS.preview_certificate).attr('href'))
|
||||||
toEqual('/users/1/courses/orgX/009/2016?preview=test2');
|
.toEqual('/users/1/courses/orgX/009/2016?preview=test2');
|
||||||
|
|
||||||
selectDropDownByText(this.view.$(SELECTORS.course_modes), 'test3');
|
selectDropDownByText(this.view.$(SELECTORS.course_modes), 'test3');
|
||||||
expect(this.view.$(SELECTORS.preview_certificate).attr('href')).
|
expect(this.view.$(SELECTORS.preview_certificate).attr('href'))
|
||||||
toEqual('/users/1/courses/orgX/009/2016?preview=test3');
|
.toEqual('/users/1/courses/orgX/009/2016?preview=test3');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('toggle certificate activation event works fine', function() {
|
it('toggle certificate activation event works fine', function() {
|
||||||
|
|||||||
@@ -21,6 +21,6 @@ export default function ContainerFactory(componentTemplates, XBlockInfoJson, act
|
|||||||
var view = new ContainerPage(_.extend(main_options, options));
|
var view = new ContainerPage(_.extend(main_options, options));
|
||||||
view.render();
|
view.render();
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
export {ContainerFactory}
|
export {ContainerFactory};
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import * as ContextCourse from 'js/models/course';
|
import * as ContextCourse from 'js/models/course';
|
||||||
|
|
||||||
export {ContextCourse}
|
export {ContextCourse};
|
||||||
|
|||||||
@@ -21,6 +21,6 @@ export default function EditTabsFactory(courseLocation, explicitUrl) {
|
|||||||
mast: $('.wrapper-mast')
|
mast: $('.wrapper-mast')
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
export {EditTabsFactory}
|
export {EditTabsFactory};
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ export default function LibraryFactory(componentTemplates, XBlockInfoJson, optio
|
|||||||
var view = new PagedContainerPage(_.extend(main_options, options));
|
var view = new PagedContainerPage(_.extend(main_options, options));
|
||||||
view.render();
|
view.render();
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
export {LibraryFactory}
|
export {LibraryFactory};
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ define([
|
|||||||
|
|
||||||
// Toggle collapsibles when trigger is clicked
|
// Toggle collapsibles when trigger is clicked
|
||||||
$('.collapsible .collapsible-trigger').click(function() {
|
$('.collapsible .collapsible-trigger').click(function() {
|
||||||
const contentId = this.id.replace('-trigger', '-content')
|
const contentId = this.id.replace('-trigger', '-content');
|
||||||
$(`#${contentId}`).toggleClass('collapsed')
|
$(`#${contentId}`).toggleClass('collapsed');
|
||||||
})
|
});
|
||||||
|
|
||||||
model = new CourseDetailsModel();
|
model = new CourseDetailsModel();
|
||||||
model.urlRoot = detailsUrl;
|
model.urlRoot = detailsUrl;
|
||||||
|
|||||||
@@ -19,6 +19,6 @@ export default function TextbooksFactory(textbooksJson) {
|
|||||||
return gettext('You have unsaved changes. Do you really want to leave this page?');
|
return gettext('You have unsaved changes. Do you really want to leave this page?');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
export {TextbooksFactory}
|
export {TextbooksFactory};
|
||||||
|
|||||||
@@ -16,6 +16,6 @@ export default function XBlockValidationFactory(validationMessages, hasEditingUr
|
|||||||
if (!model.get('empty')) {
|
if (!model.get('empty')) {
|
||||||
new XBlockValidationView({el: validationEle, model: model, root: isRoot}).render();
|
new XBlockValidationView({el: validationEle, model: model, root: isRoot}).render();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
export {XBlockValidationFactory}
|
export {XBlockValidationFactory};
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ define(['backbone', 'js/models/location', 'js/collections/course_grader', 'edx-u
|
|||||||
grace_period: null, // either null or { hours: n, minutes: m, ...}
|
grace_period: null, // either null or { hours: n, minutes: m, ...}
|
||||||
minimum_grade_credit: null, // either null or percentage
|
minimum_grade_credit: null, // either null or percentage
|
||||||
assignment_count_info: [], // Object with keys mapping assignment type names to a list of
|
assignment_count_info: [], // Object with keys mapping assignment type names to a list of
|
||||||
//assignment display names
|
// assignment display names
|
||||||
},
|
},
|
||||||
parse: function(attributes) {
|
parse: function(attributes) {
|
||||||
if (attributes.graders) {
|
if (attributes.graders) {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import 'jquery.smoothScroll';
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var toggleSock = function (e) {
|
var toggleSock = function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
var $btnShowSockLabel = $(this).find('.copy-show');
|
var $btnShowSockLabel = $(this).find('.copy-show');
|
||||||
@@ -33,9 +33,9 @@ var toggleSock = function (e) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
domReady(function () {
|
domReady(function() {
|
||||||
// toggling footer additional support
|
// toggling footer additional support
|
||||||
$('.cta-show-sock').bind('click', toggleSock);
|
$('.cta-show-sock').bind('click', toggleSock);
|
||||||
});
|
});
|
||||||
|
|
||||||
export {toggleSock}
|
export {toggleSock};
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ define(['js/views/license', 'js/models/license', 'common/js/spec_helpers/templat
|
|||||||
this.view = new LicenseView({model: this.model, showPreview: true});
|
this.view = new LicenseView({model: this.model, showPreview: true});
|
||||||
this.view.render();
|
this.view.render();
|
||||||
expect(this.view.$('.license-preview').length).toEqual(1);
|
expect(this.view.$('.license-preview').length).toEqual(1);
|
||||||
// Expect default text to be "All Rights Reserved"
|
// Expect default text to be "All Rights Reserved"
|
||||||
expect(this.view.$('.license-preview')).toContainText('All Rights Reserved');
|
expect(this.view.$('.license-preview')).toContainText('All Rights Reserved');
|
||||||
this.view.$('li[data-license=creative-commons] button').click();
|
this.view.$('li[data-license=creative-commons] button').click();
|
||||||
expect(this.view.$('.license-preview').length).toEqual(1);
|
expect(this.view.$('.license-preview').length).toEqual(1);
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ describe('ModuleEdit', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('render', function() {
|
describe('render', function() {
|
||||||
beforeEach(function () {
|
beforeEach(function() {
|
||||||
edit_helpers.installEditTemplates(true);
|
edit_helpers.installEditTemplates(true);
|
||||||
spyOn(this.moduleEdit, 'loadDisplay');
|
spyOn(this.moduleEdit, 'loadDisplay');
|
||||||
spyOn(this.moduleEdit, 'delegateEvents');
|
spyOn(this.moduleEdit, 'delegateEvents');
|
||||||
|
|||||||
@@ -343,15 +343,15 @@ describe('Container Subviews', function() {
|
|||||||
it('renders the last published date and user when there are no changes', function() {
|
it('renders the last published date and user when there are no changes', function() {
|
||||||
renderContainerPage(this, mockContainerXBlockHtml);
|
renderContainerPage(this, mockContainerXBlockHtml);
|
||||||
fetch({published_on: 'Jul 01, 2014 at 12:45 UTC', published_by: 'amako'});
|
fetch({published_on: 'Jul 01, 2014 at 12:45 UTC', published_by: 'amako'});
|
||||||
expect(containerPage.$(lastDraftCss).text()).
|
expect(containerPage.$(lastDraftCss).text())
|
||||||
toContain('Last published Jul 01, 2014 at 12:45 UTC by amako');
|
.toContain('Last published Jul 01, 2014 at 12:45 UTC by amako');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders the last saved date and user when there are changes', function() {
|
it('renders the last saved date and user when there are changes', function() {
|
||||||
renderContainerPage(this, mockContainerXBlockHtml);
|
renderContainerPage(this, mockContainerXBlockHtml);
|
||||||
fetch({has_changes: true, edited_on: 'Jul 02, 2014 at 14:20 UTC', edited_by: 'joe'});
|
fetch({has_changes: true, edited_on: 'Jul 02, 2014 at 14:20 UTC', edited_by: 'joe'});
|
||||||
expect(containerPage.$(lastDraftCss).text()).
|
expect(containerPage.$(lastDraftCss).text())
|
||||||
toContain('Draft saved on Jul 02, 2014 at 14:20 UTC by joe');
|
.toContain('Draft saved on Jul 02, 2014 at 14:20 UTC by joe');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Release Date', function() {
|
describe('Release Date', function() {
|
||||||
@@ -596,8 +596,8 @@ describe('Container Subviews', function() {
|
|||||||
fetch({
|
fetch({
|
||||||
published: true, published_on: 'Jul 01, 2014 at 12:45 UTC', published_by: 'amako'
|
published: true, published_on: 'Jul 01, 2014 at 12:45 UTC', published_by: 'amako'
|
||||||
});
|
});
|
||||||
expect(containerPage.$(lastPublishCss).text()).
|
expect(containerPage.$(lastPublishCss).text())
|
||||||
toContain('Last published Jul 01, 2014 at 12:45 UTC by amako');
|
.toContain('Last published Jul 01, 2014 at 12:45 UTC by amako');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders correctly when the block is published without publish info', function() {
|
it('renders correctly when the block is published without publish info', function() {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ describe('CourseOutlinePage', function() {
|
|||||||
selectVisibilitySettings, selectDiscussionSettings, selectAdvancedSettings, createMockCourseJSON, createMockSectionJSON,
|
selectVisibilitySettings, selectDiscussionSettings, selectAdvancedSettings, createMockCourseJSON, createMockSectionJSON,
|
||||||
createMockSubsectionJSON, verifyTypePublishable, mockCourseJSON, mockEmptyCourseJSON, setSelfPaced, setSelfPacedCustomPLS,
|
createMockSubsectionJSON, verifyTypePublishable, mockCourseJSON, mockEmptyCourseJSON, setSelfPaced, setSelfPacedCustomPLS,
|
||||||
mockSingleSectionCourseJSON, createMockVerticalJSON, createMockIndexJSON, mockCourseEntranceExamJSON,
|
mockSingleSectionCourseJSON, createMockVerticalJSON, createMockIndexJSON, mockCourseEntranceExamJSON,
|
||||||
selectOnboardingExam, createMockCourseJSONWithReviewRules,mockCourseJSONWithReviewRules,
|
selectOnboardingExam, createMockCourseJSONWithReviewRules, mockCourseJSONWithReviewRules,
|
||||||
mockOutlinePage = readFixtures('templates/mock/mock-course-outline-page.underscore'),
|
mockOutlinePage = readFixtures('templates/mock/mock-course-outline-page.underscore'),
|
||||||
mockRerunNotification = readFixtures('templates/mock/mock-course-rerun-notification.underscore');
|
mockRerunNotification = readFixtures('templates/mock/mock-course-rerun-notification.underscore');
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ describe('CourseOutlinePage', function() {
|
|||||||
setSelfPacedCustomPLS = function() {
|
setSelfPacedCustomPLS = function() {
|
||||||
setSelfPaced();
|
setSelfPaced();
|
||||||
course.set('is_custom_relative_dates_active', true);
|
course.set('is_custom_relative_dates_active', true);
|
||||||
}
|
};
|
||||||
|
|
||||||
createCourseOutlinePage = function(test, courseJSON, createOnly) {
|
createCourseOutlinePage = function(test, courseJSON, createOnly) {
|
||||||
requests = AjaxHelpers.requests(test);
|
requests = AjaxHelpers.requests(test);
|
||||||
@@ -1458,7 +1458,7 @@ describe('CourseOutlinePage', function() {
|
|||||||
$('.wrapper-modal-window .action-save').click();
|
$('.wrapper-modal-window .action-save').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can select the onboarding exam when a course supports onboarding', function () {
|
it('can select the onboarding exam when a course supports onboarding', function() {
|
||||||
var mockCourseWithSpecialExamJSON = createMockCourseJSON({}, [
|
var mockCourseWithSpecialExamJSON = createMockCourseJSON({}, [
|
||||||
createMockSectionJSON({
|
createMockSectionJSON({
|
||||||
has_changes: true,
|
has_changes: true,
|
||||||
@@ -2191,7 +2191,7 @@ describe('CourseOutlinePage', function() {
|
|||||||
expect($modalWindow.find('.outline-subsection')).not.toExist();
|
expect($modalWindow.find('.outline-subsection')).not.toExist();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Self Paced with Custom Personalized Learner Schedules (PLS)', function () {
|
describe('Self Paced with Custom Personalized Learner Schedules (PLS)', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
var mockCourseJSON = createMockCourseJSON({}, [
|
var mockCourseJSON = createMockCourseJSON({}, [
|
||||||
createMockSectionJSON({}, [
|
createMockSectionJSON({}, [
|
||||||
@@ -2210,7 +2210,7 @@ describe('CourseOutlinePage', function() {
|
|||||||
|
|
||||||
selectRelativeWeeksSubsection = function(weeks) {
|
selectRelativeWeeksSubsection = function(weeks) {
|
||||||
$('#due_in').val(weeks).trigger('keyup');
|
$('#due_in').val(weeks).trigger('keyup');
|
||||||
}
|
};
|
||||||
|
|
||||||
mockCustomPacingServerValuesJson = createMockSectionJSON({
|
mockCustomPacingServerValuesJson = createMockSectionJSON({
|
||||||
release_date: 'Jan 01, 2970 at 05:00 UTC'
|
release_date: 'Jan 01, 2970 at 05:00 UTC'
|
||||||
@@ -2235,7 +2235,7 @@ describe('CourseOutlinePage', function() {
|
|||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
it('can show correct editors for self_paced course with custom pacing', function (){
|
it('can show correct editors for self_paced course with custom pacing', function() {
|
||||||
outlinePage.$('.outline-subsection .configure-button').click();
|
outlinePage.$('.outline-subsection .configure-button').click();
|
||||||
expect($('.edit-settings-release').length).toBe(0);
|
expect($('.edit-settings-release').length).toBe(0);
|
||||||
// Due date input exists for custom pacing self paced courses
|
// Due date input exists for custom pacing self paced courses
|
||||||
@@ -2295,7 +2295,7 @@ describe('CourseOutlinePage', function() {
|
|||||||
expectShowCorrectness('never');
|
expectShowCorrectness('never');
|
||||||
});
|
});
|
||||||
|
|
||||||
it ('does not show relative date input when assignment is not graded', function() {
|
it('does not show relative date input when assignment is not graded', function() {
|
||||||
outlinePage.$('.outline-subsection .configure-button').click();
|
outlinePage.$('.outline-subsection .configure-button').click();
|
||||||
$('#grading_type').val('Lab').trigger('change');
|
$('#grading_type').val('Lab').trigger('change');
|
||||||
$('#due_in').val('').trigger('change');
|
$('#due_in').val('').trigger('change');
|
||||||
@@ -2304,7 +2304,7 @@ describe('CourseOutlinePage', function() {
|
|||||||
$('#grading_type').val('notgraded').trigger('change');
|
$('#grading_type').val('notgraded').trigger('change');
|
||||||
$('#due_in').val('').trigger('change');
|
$('#due_in').val('').trigger('change');
|
||||||
expect($('#relative_date_input').css('display')).toBe('none');
|
expect($('#relative_date_input').css('display')).toBe('none');
|
||||||
})
|
});
|
||||||
|
|
||||||
it('shows validation error on relative date', function() {
|
it('shows validation error on relative date', function() {
|
||||||
outlinePage.$('.outline-subsection .configure-button').click();
|
outlinePage.$('.outline-subsection .configure-button').click();
|
||||||
@@ -2371,7 +2371,7 @@ describe('CourseOutlinePage', function() {
|
|||||||
'Contains staff only content'
|
'Contains staff only content'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Note: most tests for units can be found in Bok Choy
|
// Note: most tests for units can be found in Bok Choy
|
||||||
@@ -2470,13 +2470,12 @@ describe('CourseOutlinePage', function() {
|
|||||||
expect(messages).toContainText('Contains staff only content');
|
expect(messages).toContainText('Contains staff only content');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('discussion settings', function () {
|
describe('discussion settings', function() {
|
||||||
it('hides discussion settings if unit level discussions are disabled', function() {
|
it('hides discussion settings if unit level discussions are disabled', function() {
|
||||||
getUnitStatus({}, {unit_level_discussions: false});
|
getUnitStatus({}, {unit_level_discussions: false});
|
||||||
outlinePage.$('.outline-unit .configure-button').click();
|
outlinePage.$('.outline-unit .configure-button').click();
|
||||||
expect($('.modal-section .edit-discussion')).not.toExist();
|
expect($('.modal-section .edit-discussion')).not.toExist();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
verifyTypePublishable('unit', function(options) {
|
verifyTypePublishable('unit', function(options) {
|
||||||
|
|||||||
@@ -110,8 +110,8 @@ define(['jquery', 'js/models/xblock_validation', 'js/views/xblock_validation', '
|
|||||||
it('renders action info', function() {
|
it('renders action info', function() {
|
||||||
expect(view.$('a.edit-button .action-button-text').text()).toContain('Summary Action');
|
expect(view.$('a.edit-button .action-button-text').text()).toContain('Summary Action');
|
||||||
|
|
||||||
expect(view.$('a.notification-action-button .action-button-text').text()).
|
expect(view.$('a.notification-action-button .action-button-text').text())
|
||||||
toContain('First Message Action');
|
.toContain('First Message Action');
|
||||||
expect(view.$('a.notification-action-button').data('notification-action')).toBe('fix-up');
|
expect(view.$('a.notification-action-button').data('notification-action')).toBe('fix-up');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -138,4 +138,4 @@ export {
|
|||||||
installEditTemplates,
|
installEditTemplates,
|
||||||
showEditModal,
|
showEditModal,
|
||||||
verifyXBlockRequest,
|
verifyXBlockRequest,
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,66 +1,67 @@
|
|||||||
define([
|
define([
|
||||||
"jquery",
|
'jquery',
|
||||||
"underscore",
|
'underscore',
|
||||||
"backbone",
|
'backbone',
|
||||||
"js/views/utils/xblock_utils",
|
'js/views/utils/xblock_utils',
|
||||||
"js/utils/templates",
|
'js/utils/templates',
|
||||||
"js/views/modals/course_outline_modals",
|
'js/views/modals/course_outline_modals',
|
||||||
"edx-ui-toolkit/js/utils/html-utils",
|
'edx-ui-toolkit/js/utils/html-utils',
|
||||||
], function ($, _, Backbone, XBlockViewUtils, TemplateUtils, CourseOutlineModalsFactory, HtmlUtils) {
|
], function($, _, Backbone, XBlockViewUtils, TemplateUtils, CourseOutlineModalsFactory, HtmlUtils) {
|
||||||
"use strict";
|
'use strict';
|
||||||
var CourseVideoSharingEnableView = Backbone.View.extend({
|
|
||||||
events: {
|
|
||||||
"change #video-sharing-configuration-options": "handleVideoSharingConfigurationChange",
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize: function () {
|
var CourseVideoSharingEnableView = Backbone.View.extend({
|
||||||
this.template = TemplateUtils.loadTemplate("course-video-sharing-enable");
|
events: {
|
||||||
},
|
'change #video-sharing-configuration-options': 'handleVideoSharingConfigurationChange',
|
||||||
|
|
||||||
getRequestData: function (value) {
|
|
||||||
return {
|
|
||||||
metadata: {
|
|
||||||
'video_sharing_options': value,
|
|
||||||
},
|
},
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
handleVideoSharingConfigurationChange: function (event) {
|
initialize: function() {
|
||||||
if (event.type === "change") {
|
this.template = TemplateUtils.loadTemplate('course-video-sharing-enable');
|
||||||
event.preventDefault();
|
},
|
||||||
this.updateVideoSharingConfiguration(event.target.value);
|
|
||||||
this.trackVideoSharingConfigurationChange(event.target.value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
updateVideoSharingConfiguration: function (value) {
|
getRequestData: function(value) {
|
||||||
XBlockViewUtils.updateXBlockFields(this.model, this.getRequestData(value), {
|
return {
|
||||||
success: this.refresh.bind(this)
|
metadata: {
|
||||||
});
|
video_sharing_options: value,
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
trackVideoSharingConfigurationChange: function (value) {
|
handleVideoSharingConfigurationChange: function(event) {
|
||||||
window.analytics.track(
|
if (event.type === 'change') {
|
||||||
'edx.social.video_sharing_options.changed',
|
event.preventDefault();
|
||||||
{
|
this.updateVideoSharingConfiguration(event.target.value);
|
||||||
course_id: this.model.id,
|
this.trackVideoSharingConfigurationChange(event.target.value);
|
||||||
video_sharing_options: value
|
}
|
||||||
}
|
},
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
refresh: function () {
|
updateVideoSharingConfiguration: function(value) {
|
||||||
this.model.fetch({
|
XBlockViewUtils.updateXBlockFields(this.model, this.getRequestData(value), {
|
||||||
success: this.render.bind(this),
|
success: this.refresh.bind(this)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function () {
|
trackVideoSharingConfigurationChange: function(value) {
|
||||||
var html = this.template(this.model.attributes);
|
window.analytics.track(
|
||||||
HtmlUtils.setHtml(this.$el, HtmlUtils.HTML(html));
|
'edx.social.video_sharing_options.changed',
|
||||||
return this;
|
{
|
||||||
},
|
course_id: this.model.id,
|
||||||
});
|
video_sharing_options: value
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
return CourseVideoSharingEnableView;
|
refresh: function() {
|
||||||
|
this.model.fetch({
|
||||||
|
success: this.render.bind(this),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
var html = this.template(this.model.attributes);
|
||||||
|
HtmlUtils.setHtml(this.$el, HtmlUtils.HTML(html));
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return CourseVideoSharingEnableView;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ define(
|
|||||||
updateUrlFieldVisibility: function() {
|
updateUrlFieldVisibility: function() {
|
||||||
const urlContainer = this.$el.find('.public-access-block-url-container');
|
const urlContainer = this.$el.find('.public-access-block-url-container');
|
||||||
|
|
||||||
if(this.getValueFromEditor()) {
|
if (this.getValueFromEditor()) {
|
||||||
urlContainer.removeClass('is-hidden');
|
urlContainer.removeClass('is-hidden');
|
||||||
} else {
|
} else {
|
||||||
urlContainer.addClass('is-hidden');
|
urlContainer.addClass('is-hidden');
|
||||||
|
|||||||
@@ -408,11 +408,11 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
|
|||||||
if (!this.getValue() || !course.get('start')) { return; }
|
if (!this.getValue() || !course.get('start')) { return; }
|
||||||
var startDate = new Date(course.get('start'));
|
var startDate = new Date(course.get('start'));
|
||||||
// The value returned by toUTCString() is a string in the form Www, dd Mmm yyyy hh:mm:ss GMT
|
// The value returned by toUTCString() is a string in the form Www, dd Mmm yyyy hh:mm:ss GMT
|
||||||
var startDateList = startDate.toUTCString().split(' ')
|
var startDateList = startDate.toUTCString().split(' ');
|
||||||
// This text will look like Mmm dd, yyyy (i.e. Jul 26, 2021)
|
// This text will look like Mmm dd, yyyy (i.e. Jul 26, 2021)
|
||||||
this.$('#relative_weeks_due_start_date').text(startDateList[2] + ' ' + startDateList[1] + ', ' + startDateList[3]);
|
this.$('#relative_weeks_due_start_date').text(startDateList[2] + ' ' + startDateList[1] + ', ' + startDateList[3]);
|
||||||
var projectedDate = new Date(startDate)
|
var projectedDate = new Date(startDate);
|
||||||
projectedDate.setDate(projectedDate.getDate() + this.getValue()*7);
|
projectedDate.setDate(projectedDate.getDate() + this.getValue() * 7);
|
||||||
var projectedDateList = projectedDate.toUTCString().split(' ');
|
var projectedDateList = projectedDate.toUTCString().split(' ');
|
||||||
this.$('#relative_weeks_due_projected_due_in').text(projectedDateList[2] + ' ' + projectedDateList[1] + ', ' + projectedDateList[3]);
|
this.$('#relative_weeks_due_projected_due_in').text(projectedDateList[2] + ' ' + projectedDateList[1] + ', ' + projectedDateList[3]);
|
||||||
this.$('#relative_weeks_due_projected').show();
|
this.$('#relative_weeks_due_projected').show();
|
||||||
@@ -433,9 +433,9 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
|
|||||||
afterRender: function() {
|
afterRender: function() {
|
||||||
AbstractEditor.prototype.afterRender.call(this);
|
AbstractEditor.prototype.afterRender.call(this);
|
||||||
if (this.model.get('graded')) {
|
if (this.model.get('graded')) {
|
||||||
this.$('#relative_date_input').show()
|
this.$('#relative_date_input').show();
|
||||||
} else {
|
} else {
|
||||||
this.$('#relative_date_input').hide()
|
this.$('#relative_date_input').hide();
|
||||||
}
|
}
|
||||||
this.$('.field-due-in input').val(this.model.get('relative_weeks_due'));
|
this.$('.field-due-in input').val(this.model.get('relative_weeks_due'));
|
||||||
this.$('#relative_weeks_due_projected').hide();
|
this.$('#relative_weeks_due_projected').hide();
|
||||||
@@ -444,12 +444,12 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
|
|||||||
|
|
||||||
getRequestData: function() {
|
getRequestData: function() {
|
||||||
// Grab all the sections, map them to their block_ids, then return as an Array
|
// Grab all the sections, map them to their block_ids, then return as an Array
|
||||||
var sectionIds = $('.outline-section').map(function(){ return this.id; }).get()
|
var sectionIds = $('.outline-section').map(function() { return this.id; }).get();
|
||||||
// Grab all the subsections, map them to their block_ids, then return as an Array
|
// Grab all the subsections, map them to their block_ids, then return as an Array
|
||||||
var subsectionIds = $('.outline-subsection').map(function(){ return this.id; }).get()
|
var subsectionIds = $('.outline-subsection').map(function() { return this.id; }).get();
|
||||||
var relative_weeks_due = null;
|
var relative_weeks_due = null;
|
||||||
if (this.getValue() > 0 && $('#grading_type').val() !== 'notgraded') {
|
if (this.getValue() > 0 && $('#grading_type').val() !== 'notgraded') {
|
||||||
relative_weeks_due = this.getValue()
|
relative_weeks_due = this.getValue();
|
||||||
}
|
}
|
||||||
window.analytics.track('edx.bi.studio.relative_date.saved', {
|
window.analytics.track('edx.bi.studio.relative_date.saved', {
|
||||||
block_id: this.model.get('id'),
|
block_id: this.model.get('id'),
|
||||||
@@ -944,16 +944,16 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
|
|||||||
|
|
||||||
showTipText: function() {
|
showTipText: function() {
|
||||||
if (this.model.get('published')) {
|
if (this.model.get('published')) {
|
||||||
$('.un-published-tip').hide()
|
$('.un-published-tip').hide();
|
||||||
} else {
|
} else {
|
||||||
$('.un-published-tip').show()
|
$('.un-published-tip').show();
|
||||||
}
|
}
|
||||||
let enabledForGraded = course.get('discussions_settings').enable_graded_units
|
let enabledForGraded = course.get('discussions_settings').enable_graded_units;
|
||||||
if (this.model.get('graded') && !enabledForGraded) {
|
if (this.model.get('graded') && !enabledForGraded) {
|
||||||
$('#discussion_enabled').prop('disabled', true);
|
$('#discussion_enabled').prop('disabled', true);
|
||||||
$('.graded-tip').show()
|
$('.graded-tip').show();
|
||||||
} else {
|
} else {
|
||||||
$('.graded-tip').hide()
|
$('.graded-tip').hide();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ function($, _, ViewUtils, ContainerView, ModuleUtils, gettext, NotificationView,
|
|||||||
if (originalDone) {
|
if (originalDone) {
|
||||||
originalDone();
|
originalDone();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
self.handleXBlockFragment(fragment, options);
|
self.handleXBlockFragment(fragment, options);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -265,15 +265,15 @@ function($, _, Backbone, gettext, BasePage, ViewUtils, ContainerView, XBlockView
|
|||||||
editXBlock: function(event, options) {
|
editXBlock: function(event, options) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
if(!options || options.view !== 'visibility_view' ){
|
if (!options || options.view !== 'visibility_view') {
|
||||||
const primaryHeader = $(event.target).closest('.xblock-header-primary')
|
const primaryHeader = $(event.target).closest('.xblock-header-primary');
|
||||||
|
|
||||||
var useNewTextEditor = primaryHeader.attr('use-new-editor-text'),
|
var useNewTextEditor = primaryHeader.attr('use-new-editor-text'),
|
||||||
useNewVideoEditor = primaryHeader.attr('use-new-editor-video'),
|
useNewVideoEditor = primaryHeader.attr('use-new-editor-video'),
|
||||||
useNewProblemEditor = primaryHeader.attr('use-new-editor-problem'),
|
useNewProblemEditor = primaryHeader.attr('use-new-editor-problem'),
|
||||||
blockType = primaryHeader.attr('data-block-type');
|
blockType = primaryHeader.attr('data-block-type');
|
||||||
|
|
||||||
if( (useNewTextEditor === 'True' && blockType === 'html')
|
if((useNewTextEditor === 'True' && blockType === 'html')
|
||||||
|| (useNewVideoEditor === 'True' && blockType === 'video')
|
|| (useNewVideoEditor === 'True' && blockType === 'video')
|
||||||
|| (useNewProblemEditor === 'True' && blockType === 'problem')
|
|| (useNewProblemEditor === 'True' && blockType === 'problem')
|
||||||
) {
|
) {
|
||||||
@@ -476,13 +476,13 @@ function($, _, Backbone, gettext, BasePage, ViewUtils, ContainerView, XBlockView
|
|||||||
useNewProblemEditor = this.$('.xblock-header-primary').attr('use-new-editor-problem');
|
useNewProblemEditor = this.$('.xblock-header-primary').attr('use-new-editor-problem');
|
||||||
|
|
||||||
// find the block type in the locator if availible
|
// find the block type in the locator if availible
|
||||||
if(data.hasOwnProperty('locator')){
|
if(data.hasOwnProperty('locator')) {
|
||||||
var matchBlockTypeFromLocator = /\@(.*?)\+/;
|
var matchBlockTypeFromLocator = /\@(.*?)\+/;
|
||||||
var blockType = data.locator.match(matchBlockTypeFromLocator);
|
var blockType = data.locator.match(matchBlockTypeFromLocator);
|
||||||
}
|
}
|
||||||
if((useNewTextEditor === 'True' && blockType.includes('html'))
|
if((useNewTextEditor === 'True' && blockType.includes('html'))
|
||||||
|| (useNewVideoEditor === 'True' && blockType.includes('video'))
|
|| (useNewVideoEditor === 'True' && blockType.includes('video'))
|
||||||
||(useNewProblemEditor === 'True' && blockType.includes('problem'))
|
|| (useNewProblemEditor === 'True' && blockType.includes('problem'))
|
||||||
){
|
){
|
||||||
var destinationUrl = this.$('.xblock-header-primary').attr('authoring_MFE_base_url') + '/' + blockType[1] + '/' + encodeURI(data.locator);
|
var destinationUrl = this.$('.xblock-header-primary').attr('authoring_MFE_base_url') + '/' + blockType[1] + '/' + encodeURI(data.locator);
|
||||||
window.location.href = destinationUrl;
|
window.location.href = destinationUrl;
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ function($, _, gettext, BasePage, XBlockViewUtils, CourseOutlineView, ViewUtils,
|
|||||||
* at 100 millisecond intervals until element is found or
|
* at 100 millisecond intervals until element is found or
|
||||||
* Polling is reached
|
* Polling is reached
|
||||||
*/
|
*/
|
||||||
scrollToElement: function () {
|
scrollToElement: function() {
|
||||||
this.findElementPollingTimeout -= this.pollingDelay;
|
this.findElementPollingTimeout -= this.pollingDelay;
|
||||||
|
|
||||||
const elementID = window.location.hash.replace('#', '');
|
const elementID = window.location.hash.replace('#', '');
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ function(ValidatingView, _, $, ui, GraderView, StringUtils, HtmlUtils) {
|
|||||||
this);
|
this);
|
||||||
gradeCollection.each(function(gradeModel) {
|
gradeCollection.each(function(gradeModel) {
|
||||||
var graderType = gradeModel.get('type');
|
var graderType = gradeModel.get('type');
|
||||||
var graderTypeAssignmentList = self.courseAssignmentLists[graderType]
|
var graderTypeAssignmentList = self.courseAssignmentLists[graderType];
|
||||||
if (graderTypeAssignmentList === undefined) {
|
if (graderTypeAssignmentList === undefined) {
|
||||||
graderTypeAssignmentList = [];
|
graderTypeAssignmentList = [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -388,7 +388,7 @@ function(ValidatingView, CodeMirror, _, $, ui, DateUtils, FileUploadModel,
|
|||||||
Hides and clears the certificate available date field if a display behavior that doesn't use it is
|
Hides and clears the certificate available date field if a display behavior that doesn't use it is
|
||||||
chosen. Because we are clearing it, toggling back to "end_with_date" will require re-entering the date
|
chosen. Because we are clearing it, toggling back to "end_with_date" will require re-entering the date
|
||||||
*/
|
*/
|
||||||
if (!this.useV2CertDisplaySettings){
|
if (!this.useV2CertDisplaySettings) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let showDatepicker = this.model.get('certificates_display_behavior') == 'end_with_date';
|
let showDatepicker = this.model.get('certificates_display_behavior') == 'end_with_date';
|
||||||
@@ -402,7 +402,7 @@ function(ValidatingView, CodeMirror, _, $, ui, DateUtils, FileUploadModel,
|
|||||||
datepicker.prop('disabled', true);
|
datepicker.prop('disabled', true);
|
||||||
datepicker.val(null);
|
datepicker.val(null);
|
||||||
this.clearValidationErrors();
|
this.clearValidationErrors();
|
||||||
this.setAndValidate('certificate_available_date', null)
|
this.setAndValidate('certificate_available_date', null);
|
||||||
certificateAvailableDateField.addClass('hidden');
|
certificateAvailableDateField.addClass('hidden');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js'));
|
var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js'));
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js'));
|
var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js'));
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js'));
|
var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js'));
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const BlockType = PropTypes.shape({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const BlockList = ({
|
export const BlockList = ({
|
||||||
blocks, selectedBlock, onSelectBlock, onChangeRoot
|
blocks, selectedBlock, onSelectBlock, onChangeRoot,
|
||||||
}) => (
|
}) => (
|
||||||
<ul className="block-list">
|
<ul className="block-list">
|
||||||
{blocks.map(block => (
|
{blocks.map(block => (
|
||||||
@@ -48,11 +48,12 @@ export const BlockList = ({
|
|||||||
label={block.display_name}
|
label={block.display_name}
|
||||||
/>
|
/>
|
||||||
{block.children
|
{block.children
|
||||||
&& <Button
|
&& (
|
||||||
onClick={() => onChangeRoot(block.id)}
|
<Button
|
||||||
label={RightIcon}
|
onClick={() => onChangeRoot(block.id)}
|
||||||
/>
|
label={RightIcon}
|
||||||
}
|
/>
|
||||||
|
)}
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
@@ -71,7 +72,7 @@ BlockList.defaultProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const BlockBrowser = ({
|
export const BlockBrowser = ({
|
||||||
blocks, selectedBlock, onSelectBlock, onChangeRoot, className
|
blocks, selectedBlock, onSelectBlock, onChangeRoot, className,
|
||||||
}) => !!blocks && (
|
}) => !!blocks && (
|
||||||
<div className={classNames('block-browser', className)}>
|
<div className={classNames('block-browser', className)}>
|
||||||
<div className="header">
|
<div className="header">
|
||||||
|
|||||||
@@ -29,4 +29,4 @@ export const getCourseBlocks = courseId => fetch(`${COURSE_BLOCKS_API}?${buildQu
|
|||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: HEADERS,
|
headers: HEADERS,
|
||||||
},);
|
});
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ function NextArrow(props) {
|
|||||||
} = props;
|
} = props;
|
||||||
const showArrow = slideCount - currentSlide > displayedSlides;
|
const showArrow = slideCount - currentSlide > displayedSlides;
|
||||||
const opts = {
|
const opts = {
|
||||||
className: classNames('js-carousel-nav', 'carousel-arrow', 'next', 'btn btn-secondary', {'active': showArrow}),
|
className: classNames('js-carousel-nav', 'carousel-arrow', 'next', 'btn btn-secondary', {active: showArrow}),
|
||||||
onClick
|
onClick
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -22,8 +22,8 @@ function NextArrow(props) {
|
|||||||
return (
|
return (
|
||||||
<button {...opts}>
|
<button {...opts}>
|
||||||
<span>Next </span>
|
<span>Next </span>
|
||||||
<span className="icon fa fa-chevron-right" aria-hidden="true"></span>
|
<span className="icon fa fa-chevron-right" aria-hidden="true" />
|
||||||
<span className="sr">{ 'Scroll carousel forwards' }</span>
|
<span className="sr">Scroll carousel forwards</span>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@ function PrevArrow(props) {
|
|||||||
const {currentSlide, onClick} = props;
|
const {currentSlide, onClick} = props;
|
||||||
const showArrow = currentSlide > 0;
|
const showArrow = currentSlide > 0;
|
||||||
const opts = {
|
const opts = {
|
||||||
className: classNames('js-carousel-nav', 'carousel-arrow', 'prev', 'btn btn-secondary', {'active': showArrow}),
|
className: classNames('js-carousel-nav', 'carousel-arrow', 'prev', 'btn btn-secondary', {active: showArrow}),
|
||||||
onClick
|
onClick
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -41,10 +41,10 @@ function PrevArrow(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button {...opts} >
|
<button {...opts}>
|
||||||
<span className="icon fa fa-chevron-left" aria-hidden="true"></span>
|
<span className="icon fa fa-chevron-left" aria-hidden="true" />
|
||||||
<span> Prev</span>
|
<span> Prev</span>
|
||||||
<span className="sr">{ 'Scroll carousel backwards' }</span>
|
<span className="sr">Scroll carousel backwards</span>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ export default class ExperimentalCarousel extends React.Component {
|
|||||||
},
|
},
|
||||||
tabIndex: tabIndex,
|
tabIndex: tabIndex,
|
||||||
className: 'carousel-item'
|
className: 'carousel-item'
|
||||||
}
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div {...carouselLinkProps}>
|
<div {...carouselLinkProps}>
|
||||||
@@ -113,7 +113,7 @@ export default class ExperimentalCarousel extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Slider {...carouselSettings} >
|
<Slider {...carouselSettings}>
|
||||||
{this.getCarouselContent()}
|
{this.getCarouselContent()}
|
||||||
</Slider>
|
</Slider>
|
||||||
);
|
);
|
||||||
@@ -122,4 +122,4 @@ export default class ExperimentalCarousel extends React.Component {
|
|||||||
|
|
||||||
ExperimentalCarousel.propTypes = {
|
ExperimentalCarousel.propTypes = {
|
||||||
slides: PropTypes.array.isRequired
|
slides: PropTypes.array.isRequired
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -208,7 +208,7 @@
|
|||||||
Content.prototype.incrementVote = function(increment) {
|
Content.prototype.incrementVote = function(increment) {
|
||||||
var newVotes;
|
var newVotes;
|
||||||
newVotes = _.clone(this.get('votes'));
|
newVotes = _.clone(this.get('votes'));
|
||||||
newVotes.up_count = newVotes.up_count + increment;
|
newVotes.up_count += increment;
|
||||||
return this.set('votes', newVotes);
|
return this.set('votes', newVotes);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,8 @@
|
|||||||
if (_.isUndefined(userId)) {
|
if (_.isUndefined(userId)) {
|
||||||
userId = this.user ? this.user.id : void 0;
|
userId = this.user ? this.user.id : void 0;
|
||||||
}
|
}
|
||||||
if(_.isUndefined(this.roleIds)) {
|
if (_.isUndefined(this.roleIds)) {
|
||||||
this.roleIds = {}
|
this.roleIds = {};
|
||||||
}
|
}
|
||||||
staff = _.union(this.roleIds.Moderator, this.roleIds.Administrator);
|
staff = _.union(this.roleIds.Moderator, this.roleIds.Administrator);
|
||||||
return _.include(staff, parseInt(userId));
|
return _.include(staff, parseInt(userId));
|
||||||
@@ -77,7 +77,9 @@
|
|||||||
DiscussionUtil.generateDiscussionLink = function(cls, txt, handler) {
|
DiscussionUtil.generateDiscussionLink = function(cls, txt, handler) {
|
||||||
return $('<a>')
|
return $('<a>')
|
||||||
.addClass('discussion-link').attr('href', '#')
|
.addClass('discussion-link').attr('href', '#')
|
||||||
.addClass(cls).text(txt).click(function() { return handler(this); });
|
.addClass(cls)
|
||||||
|
.text(txt)
|
||||||
|
.click(function() { return handler(this); });
|
||||||
};
|
};
|
||||||
|
|
||||||
DiscussionUtil.urlFor = function(name, param, param1, param2) {
|
DiscussionUtil.urlFor = function(name, param, param1, param2) {
|
||||||
@@ -484,7 +486,6 @@
|
|||||||
element,
|
element,
|
||||||
this.postMathJaxProcessor(this.markdownWithHighlight(element.text()))
|
this.postMathJaxProcessor(this.markdownWithHighlight(element.text()))
|
||||||
);
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DiscussionUtil.typesetMathJax = function(element) {
|
DiscussionUtil.typesetMathJax = function(element) {
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ jasmine.getFixtures().fixturesPath = '/base/';
|
|||||||
// Stub out modal dialog alerts, which will prevent
|
// Stub out modal dialog alerts, which will prevent
|
||||||
// us from accessing the test results in the DOM
|
// us from accessing the test results in the DOM
|
||||||
window.confirm = function() { return true; };
|
window.confirm = function() { return true; };
|
||||||
window.alert = function() { return; };
|
window.alert = function() { };
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
initialized we can't override the ExceptionFormatter as Jasmine then uses the stored reference to the function */
|
initialized we can't override the ExceptionFormatter as Jasmine then uses the stored reference to the function */
|
||||||
(function() {
|
(function() {
|
||||||
/* globals jasmineRequire */
|
/* globals jasmineRequire */
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var OldExceptionFormatter = jasmineRequire.ExceptionFormatter(),
|
var OldExceptionFormatter = jasmineRequire.ExceptionFormatter(),
|
||||||
oldExceptionFormatter = new OldExceptionFormatter(),
|
oldExceptionFormatter = new OldExceptionFormatter(),
|
||||||
|
|||||||
@@ -40,9 +40,11 @@
|
|||||||
|
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var _ = require('underscore');
|
var _ = require('underscore');
|
||||||
|
|
||||||
var appRoot = path.join(__dirname, '../../../../');
|
var appRoot = path.join(__dirname, '../../../../');
|
||||||
var webdriver = require('selenium-webdriver');
|
var webdriver = require('selenium-webdriver');
|
||||||
var firefox = require('selenium-webdriver/firefox');
|
var firefox = require('selenium-webdriver/firefox');
|
||||||
|
|
||||||
var webpackConfig = require(path.join(appRoot, 'webpack.dev.config.js'));
|
var webpackConfig = require(path.join(appRoot, 'webpack.dev.config.js'));
|
||||||
|
|
||||||
// The following crazy bit is to work around the webpack.optimize.CommonsChunkPlugin
|
// The following crazy bit is to work around the webpack.optimize.CommonsChunkPlugin
|
||||||
|
|||||||
@@ -57,11 +57,11 @@
|
|||||||
_ref >= 0 ? _i <= _ref : _i >= _ref;
|
_ref >= 0 ? _i <= _ref : _i >= _ref;
|
||||||
i = _ref >= 0 ? ++_i : --_i
|
i = _ref >= 0 ? ++_i : --_i
|
||||||
) {
|
) {
|
||||||
threadData.body = threadData.body + imageTag;
|
threadData.body += imageTag;
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
expectedHtml = expectedHtml + imageTag;
|
expectedHtml += imageTag;
|
||||||
} else {
|
} else {
|
||||||
expectedHtml = expectedHtml + '<em>image omitted</em>';
|
expectedHtml += '<em>image omitted</em>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,8 +80,6 @@
|
|||||||
callbackFunc(draggableObj);
|
callbackFunc(draggableObj);
|
||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
if (draggableObj.originalConfigObj.label.length > 0) {
|
if (draggableObj.originalConfigObj.label.length > 0) {
|
||||||
draggableObj.iconEl = $(HtmlUtils.joinHtml(
|
draggableObj.iconEl = $(HtmlUtils.joinHtml(
|
||||||
@@ -101,8 +99,6 @@
|
|||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
callbackFunc(draggableObj);
|
callbackFunc(draggableObj);
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
describe('interpolate_ntext', function() {
|
describe('interpolate_ntext', function() {
|
||||||
it('replaces placeholder values', function() {
|
it('replaces placeholder values', function() {
|
||||||
expect(interpolate_ntext('contains {count} student', 'contains {count} students', 1, {count: 1})).
|
expect(interpolate_ntext('contains {count} student', 'contains {count} students', 1, {count: 1}))
|
||||||
toBe('contains 1 student');
|
.toBe('contains 1 student');
|
||||||
expect(interpolate_ntext('contains {count} student', 'contains {count} students', 5, {count: 2})).
|
expect(interpolate_ntext('contains {count} student', 'contains {count} students', 5, {count: 2}))
|
||||||
toBe('contains 2 students');
|
.toBe('contains 2 students');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('interpolate_text', function() {
|
describe('interpolate_text', function() {
|
||||||
it('replaces placeholder values', function() {
|
it('replaces placeholder values', function() {
|
||||||
expect(interpolate_text('contains {adjective} students', {adjective: 'awesome'})).
|
expect(interpolate_text('contains {adjective} students', {adjective: 'awesome'}))
|
||||||
toBe('contains awesome students');
|
.toBe('contains awesome students');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import CookieBanner from '@edx/frontend-component-cookie-policy-banner';
|
import CookieBanner from '@edx/frontend-component-cookie-policy-banner';
|
||||||
|
|
||||||
export function CookiePolicyBanner() { return <CookieBanner />; };
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
|
export function CookiePolicyBanner() { return <CookieBanner />; }
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ var accessible_modal = function(trigger, closeButtonId, modalId, mainPageId) {
|
|||||||
// see http://accessibility.oit.ncsu.edu/blog/2013/09/13/the-incredible-accessible-modal-dialog/
|
// see http://accessibility.oit.ncsu.edu/blog/2013/09/13/the-incredible-accessible-modal-dialog/
|
||||||
// for more information on managing modals
|
// for more information on managing modals
|
||||||
//
|
//
|
||||||
var initialFocus
|
var initialFocus;
|
||||||
$(trigger).click(function() {
|
$(trigger).click(function() {
|
||||||
$focusedElementBeforeModal = $(trigger);
|
$focusedElementBeforeModal = $(trigger);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js'));
|
var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js'));
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js'));
|
var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js'));
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
'globals': {
|
globals: {
|
||||||
'gettext': (t) => { return t; },
|
gettext: (t) => t,
|
||||||
},
|
},
|
||||||
'modulePaths': [
|
modulePaths: [
|
||||||
'common/static/common/js/components',
|
'common/static/common/js/components',
|
||||||
],
|
],
|
||||||
'setupFilesAfterEnv': ['<rootDir>/setupTests.js'],
|
setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
|
||||||
'testMatch': [
|
testMatch: [
|
||||||
'/**/*.test.jsx',
|
'/**/*.test.jsx',
|
||||||
'common/static/common/js/components/**/?(*.)+(spec|test).js?(x)',
|
'common/static/common/js/components/**/?(*.)+(spec|test).js?(x)',
|
||||||
],
|
],
|
||||||
'testEnvironment': 'jsdom',
|
testEnvironment: 'jsdom',
|
||||||
'transform': {
|
transform: {
|
||||||
'^.+\\.jsx$': 'babel-jest',
|
'^.+\\.jsx$': 'babel-jest',
|
||||||
'^.+\\.js$': 'babel-jest',
|
'^.+\\.js$': 'babel-jest',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export default class Main extends React.Component {
|
|||||||
this.props.problemResponsesEndpoint,
|
this.props.problemResponsesEndpoint,
|
||||||
this.props.taskStatusEndpoint,
|
this.props.taskStatusEndpoint,
|
||||||
this.props.reportDownloadEndpoint,
|
this.props.reportDownloadEndpoint,
|
||||||
this.props.selectedBlock
|
this.props.selectedBlock,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ describe('ProblemBrowser Main component', () => {
|
|||||||
fetchCourseBlocks={jest.fn()}
|
fetchCourseBlocks={jest.fn()}
|
||||||
problemResponsesEndpoint={problemResponsesEndpoint}
|
problemResponsesEndpoint={problemResponsesEndpoint}
|
||||||
onSelectBlock={jest.fn()}
|
onSelectBlock={jest.fn()}
|
||||||
selectedBlock={'some-selected-block'}
|
selectedBlock="some-selected-block"
|
||||||
taskStatusEndpoint={taskStatusEndpoint}
|
taskStatusEndpoint={taskStatusEndpoint}
|
||||||
/>
|
/>
|
||||||
</Provider>,
|
</Provider>,
|
||||||
@@ -64,7 +64,7 @@ describe('ProblemBrowser Main component', () => {
|
|||||||
fetchCourseBlocks={fetchCourseBlocksMock}
|
fetchCourseBlocks={fetchCourseBlocksMock}
|
||||||
problemResponsesEndpoint={problemResponsesEndpoint}
|
problemResponsesEndpoint={problemResponsesEndpoint}
|
||||||
onSelectBlock={jest.fn()}
|
onSelectBlock={jest.fn()}
|
||||||
selectedBlock={'some-selected-block'}
|
selectedBlock="some-selected-block"
|
||||||
taskStatusEndpoint={taskStatusEndpoint}
|
taskStatusEndpoint={taskStatusEndpoint}
|
||||||
/>
|
/>
|
||||||
</Provider>,
|
</Provider>,
|
||||||
@@ -83,7 +83,7 @@ describe('ProblemBrowser Main component', () => {
|
|||||||
fetchCourseBlocks={jest.fn()}
|
fetchCourseBlocks={jest.fn()}
|
||||||
problemResponsesEndpoint={problemResponsesEndpoint}
|
problemResponsesEndpoint={problemResponsesEndpoint}
|
||||||
onSelectBlock={jest.fn()}
|
onSelectBlock={jest.fn()}
|
||||||
selectedBlock={'some-selected-block'}
|
selectedBlock="some-selected-block"
|
||||||
taskStatusEndpoint={taskStatusEndpoint}
|
taskStatusEndpoint={taskStatusEndpoint}
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const mapDispatchToProps = dispatch => ({
|
|||||||
(courseId, excludeBlockTypes) => dispatch(fetchCourseBlocks(courseId, excludeBlockTypes)),
|
(courseId, excludeBlockTypes) => dispatch(fetchCourseBlocks(courseId, excludeBlockTypes)),
|
||||||
createProblemResponsesReportTask:
|
createProblemResponsesReportTask:
|
||||||
(problemResponsesEndpoint, taskStatusEndpoint, reportDownloadEndpoint, problemLocation) => dispatch(
|
(problemResponsesEndpoint, taskStatusEndpoint, reportDownloadEndpoint, problemLocation) => dispatch(
|
||||||
createProblemResponsesReportTask(problemResponsesEndpoint, taskStatusEndpoint, reportDownloadEndpoint, problemLocation,),
|
createProblemResponsesReportTask(problemResponsesEndpoint, taskStatusEndpoint, reportDownloadEndpoint, problemLocation),
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import * as PropTypes from 'prop-types';
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
const ReportStatus = ({
|
const ReportStatus = ({
|
||||||
error, succeeded, inProgress, reportPath
|
error, succeeded, inProgress, reportPath,
|
||||||
}) => {
|
}) => {
|
||||||
const progressMessage = (
|
const progressMessage = (
|
||||||
<div className="msg progress">
|
<div className="msg progress">
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ describe('ReportStatus component', () => {
|
|||||||
<ReportStatus
|
<ReportStatus
|
||||||
error={null}
|
error={null}
|
||||||
inProgress={false}
|
inProgress={false}
|
||||||
reportName={'some-report-name'}
|
reportName="some-report-name"
|
||||||
reportPath={'/some/report/path.csv'}
|
reportPath="/some/report/path.csv"
|
||||||
succeeded
|
succeeded
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
@@ -35,7 +35,7 @@ describe('ReportStatus component', () => {
|
|||||||
test('render error status', () => {
|
test('render error status', () => {
|
||||||
const component = renderer.create(
|
const component = renderer.create(
|
||||||
<ReportStatus
|
<ReportStatus
|
||||||
error={'some error status'}
|
error="some error status"
|
||||||
inProgress={false}
|
inProgress={false}
|
||||||
reportName={null}
|
reportName={null}
|
||||||
reportPath={null}
|
reportPath={null}
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ function initiateProblemResponsesRequest(endpoint, blockId) {
|
|||||||
method: 'post',
|
method: 'post',
|
||||||
headers: HEADERS,
|
headers: HEADERS,
|
||||||
body: formData,
|
body: formData,
|
||||||
},);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchTaskStatus = (endpoint, taskId) => fetch(`${endpoint}/?task_id=${taskId}`, {
|
const fetchTaskStatus = (endpoint, taskId) => fetch(`${endpoint}/?task_id=${taskId}`, {
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: HEADERS,
|
headers: HEADERS,
|
||||||
},);
|
});
|
||||||
|
|
||||||
const fetchDownloadsList = (endpoint, reportName) => {
|
const fetchDownloadsList = (endpoint, reportName) => {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
@@ -33,7 +33,7 @@ const fetchDownloadsList = (endpoint, reportName) => {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: HEADERS,
|
headers: HEADERS,
|
||||||
body: formData,
|
body: formData,
|
||||||
},);
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ const mapStateToProps = state => ({
|
|||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
createEntitlement: ({
|
createEntitlement: ({
|
||||||
username, courseUuid, mode, comments
|
username, courseUuid, mode, comments,
|
||||||
}) => dispatch(createEntitlement({
|
}) => dispatch(createEntitlement({
|
||||||
username, courseUuid, mode, comments
|
username, courseUuid, mode, comments,
|
||||||
})),
|
})),
|
||||||
reissueEntitlement: ({ entitlement, comments }) => dispatch(reissueEntitlement({ entitlement, comments })),
|
reissueEntitlement: ({ entitlement, comments }) => dispatch(reissueEntitlement({ entitlement, comments })),
|
||||||
closeForm: () => dispatch(closeForm()),
|
closeForm: () => dispatch(closeForm()),
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Button, InputSelect, InputText, TextArea
|
Button, InputSelect, InputText, TextArea,
|
||||||
} from '@edx/paragon';
|
} from '@edx/paragon';
|
||||||
import { formTypes } from '../../data/constants/formTypes';
|
import { formTypes } from '../../data/constants/formTypes';
|
||||||
|
|
||||||
@@ -57,21 +57,21 @@ class EntitlementForm extends React.Component {
|
|||||||
|
|
||||||
submitForm() {
|
submitForm() {
|
||||||
const {
|
const {
|
||||||
courseUuid, username, mode, comments
|
courseUuid, username, mode, comments,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
const { formType, entitlement } = this.props;
|
const { formType, entitlement } = this.props;
|
||||||
if (formType === formTypes.REISSUE) { // if there is an active entitlement we are updating an entitlement
|
if (formType === formTypes.REISSUE) { // if there is an active entitlement we are updating an entitlement
|
||||||
this.props.reissueEntitlement({ entitlement, comments });
|
this.props.reissueEntitlement({ entitlement, comments });
|
||||||
} else { // if there is no active entitlement we are creating a new entitlement
|
} else { // if there is no active entitlement we are creating a new entitlement
|
||||||
this.props.createEntitlement({
|
this.props.createEntitlement({
|
||||||
courseUuid, username, mode, comments
|
courseUuid, username, mode, comments,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
courseUuid, username, mode, comments
|
courseUuid, username, mode, comments,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
const isReissue = this.props.formType === formTypes.REISSUE;
|
const isReissue = this.props.formType === formTypes.REISSUE;
|
||||||
const title = isReissue ? 'Re-issue Entitlement' : 'Create Entitlement';
|
const title = isReissue ? 'Re-issue Entitlement' : 'Create Entitlement';
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ const entitlementColumns = [
|
|||||||
|
|
||||||
const parseEntitlementData = (entitlements, ecommerceUrl, openReissueForm) => entitlements.map((entitlement) => {
|
const parseEntitlementData = (entitlements, ecommerceUrl, openReissueForm) => entitlements.map((entitlement) => {
|
||||||
const {
|
const {
|
||||||
expiredAt, created, modified, orderNumber, enrollmentCourseRun
|
expiredAt, created, modified, orderNumber, enrollmentCourseRun,
|
||||||
} = entitlement;
|
} = entitlement;
|
||||||
return Object.assign({}, entitlement, {
|
return Object.assign({}, entitlement, {
|
||||||
expiredAt: expiredAt ? moment(expiredAt).format('lll') : '',
|
expiredAt: expiredAt ? moment(expiredAt).format('lll') : '',
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ const createEntitlementSuccess = entitlement => ({
|
|||||||
const createEntitlementFailure = error => dispatch => dispatch(displayError('Error Creating Entitlement', error));
|
const createEntitlementFailure = error => dispatch => dispatch(displayError('Error Creating Entitlement', error));
|
||||||
|
|
||||||
const createEntitlement = ({
|
const createEntitlement = ({
|
||||||
username, courseUuid, mode, comments
|
username, courseUuid, mode, comments,
|
||||||
}) => (dispatch) => {
|
}) => (dispatch) => {
|
||||||
postEntitlement({
|
postEntitlement({
|
||||||
username,
|
username,
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ const HEADERS = {
|
|||||||
const getEntitlements = username => fetch(`${entitlementApi}?user=${username}`, {
|
const getEntitlements = username => fetch(`${entitlementApi}?user=${username}`, {
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
},);
|
});
|
||||||
|
|
||||||
const postEntitlement = ({
|
const postEntitlement = ({
|
||||||
username, courseUuid, mode, action, comments = null
|
username, courseUuid, mode, action, comments = null,
|
||||||
}) => fetch(`${entitlementApi}`, {
|
}) => fetch(`${entitlementApi}`, {
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@@ -30,10 +30,10 @@ const postEntitlement = ({
|
|||||||
comments,
|
comments,
|
||||||
}],
|
}],
|
||||||
}),
|
}),
|
||||||
},);
|
});
|
||||||
|
|
||||||
const patchEntitlement = ({
|
const patchEntitlement = ({
|
||||||
uuid, action, unenrolledRun = null, comments = null
|
uuid, action, unenrolledRun = null, comments = null,
|
||||||
}) => fetch(`${entitlementApi}${uuid}`, {
|
}) => fetch(`${entitlementApi}${uuid}`, {
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
method: 'patch',
|
method: 'patch',
|
||||||
@@ -46,7 +46,7 @@ const patchEntitlement = ({
|
|||||||
comments,
|
comments,
|
||||||
}],
|
}],
|
||||||
}),
|
}),
|
||||||
},);
|
});
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getEntitlements,
|
getEntitlements,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { formActions, entitlementActions } from '../constants/actionTypes';
|
import { formActions, entitlementActions } from '../constants/actionTypes';
|
||||||
import { formTypes } from '../constants/formTypes';
|
import { formTypes } from '../constants/formTypes';
|
||||||
|
|
||||||
const clearFormState = {
|
const clearFormState = {
|
||||||
formType: '',
|
formType: '',
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
@@ -10,11 +11,11 @@ const form = (state = {}, action) => {
|
|||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case formActions.OPEN_REISSUE_FORM:
|
case formActions.OPEN_REISSUE_FORM:
|
||||||
return {
|
return {
|
||||||
...state, formType: formTypes.REISSUE, isOpen: true, activeEntitlement: action.entitlement
|
...state, formType: formTypes.REISSUE, isOpen: true, activeEntitlement: action.entitlement,
|
||||||
};
|
};
|
||||||
case formActions.OPEN_CREATION_FORM:
|
case formActions.OPEN_CREATION_FORM:
|
||||||
return {
|
return {
|
||||||
...state, formType: formTypes.CREATE, isOpen: true, activeEntitlement: null
|
...state, formType: formTypes.CREATE, isOpen: true, activeEntitlement: null,
|
||||||
};
|
};
|
||||||
case formActions.CLOSE_FORM:
|
case formActions.CLOSE_FORM:
|
||||||
case entitlementActions.reissue.SUCCESS:
|
case entitlementActions.reissue.SUCCESS:
|
||||||
|
|||||||
@@ -141,8 +141,7 @@ class FileUpload extends React.Component {
|
|||||||
fileName={this.state.fileInProgress}
|
fileName={this.state.fileInProgress}
|
||||||
request={this.state.currentRequest}
|
request={this.state.currentRequest}
|
||||||
/>
|
/>
|
||||||
)
|
)}
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="uploaded-files">
|
<div className="uploaded-files">
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
import {
|
import {
|
||||||
Button, InputText, TextArea, StatusAlert
|
Button, InputText, TextArea, StatusAlert,
|
||||||
} from '@edx/paragon';
|
} from '@edx/paragon';
|
||||||
|
|
||||||
export const LinkProgramEnrollmentsSupportPage = props => (
|
export const LinkProgramEnrollmentsSupportPage = props => (
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {
|
import {
|
||||||
Button, InputText, StatusAlert, InputSelect
|
Button, InputText, StatusAlert, InputSelect,
|
||||||
} from '@edx/paragon';
|
} from '@edx/paragon';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -112,7 +112,7 @@ const renderEnrollmentsSection = enrollments => (
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
),
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
@@ -152,7 +152,7 @@ export const ProgramEnrollmentsInspectorPage = props => (
|
|||||||
dialog={props.error}
|
dialog={props.error}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div id="input_alert" className={'alert alert-danger'} hidden>
|
<div id="input_alert" className="alert alert-danger" hidden>
|
||||||
Search either by edx username or email, or Institution user key, but not both
|
Search either by edx username or email, or Institution user key, but not both
|
||||||
</div>
|
</div>
|
||||||
<div key="edX_accounts">
|
<div key="edX_accounts">
|
||||||
@@ -228,7 +228,7 @@ ProgramEnrollmentsInspectorPage.propTypes = {
|
|||||||
is_active: PropTypes.bool,
|
is_active: PropTypes.bool,
|
||||||
mode: PropTypes.string,
|
mode: PropTypes.string,
|
||||||
}),
|
}),
|
||||||
})
|
}),
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ class RenderForm extends React.Component {
|
|||||||
{
|
{
|
||||||
id: this.props.context.customFields.referrer,
|
id: this.props.context.customFields.referrer,
|
||||||
value: document.referrer ? document.referrer : 'Direct Contact Us Page Request',
|
value: document.referrer ? document.referrer : 'Direct Contact Us Page Request',
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
tags: this.props.context.tags,
|
tags: this.props.context.tags,
|
||||||
};
|
};
|
||||||
@@ -175,6 +175,7 @@ class RenderForm extends React.Component {
|
|||||||
this.scrollToTop();
|
this.scrollToTop();
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
validateFormData(formData) {
|
validateFormData(formData) {
|
||||||
const { course, subject, message } = formData;
|
const { course, subject, message } = formData;
|
||||||
|
|
||||||
@@ -273,21 +274,25 @@ class RenderForm extends React.Component {
|
|||||||
let userElement,
|
let userElement,
|
||||||
suggestionsListComponent = null;
|
suggestionsListComponent = null;
|
||||||
if (this.userInformation) {
|
if (this.userInformation) {
|
||||||
userElement = (<LoggedInUser
|
userElement = (
|
||||||
userInformation={this.userInformation}
|
<LoggedInUser
|
||||||
onChangeCallback={this.formOnChangeCallback}
|
userInformation={this.userInformation}
|
||||||
handleClick={this.handleClick}
|
onChangeCallback={this.formOnChangeCallback}
|
||||||
showWarning={this.showWarningMessage()}
|
handleClick={this.handleClick}
|
||||||
showDiscussionButton={this.showDiscussionButton()}
|
showWarning={this.showWarningMessage()}
|
||||||
reDirectUser={this.reDirectUser}
|
showDiscussionButton={this.showDiscussionButton()}
|
||||||
errorList={this.getFormErrorsFromState()}
|
reDirectUser={this.reDirectUser}
|
||||||
/>);
|
errorList={this.getFormErrorsFromState()}
|
||||||
|
/>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
userElement = (<LoggedOutUser
|
userElement = (
|
||||||
platformName={this.props.context.platformName}
|
<LoggedOutUser
|
||||||
loginQuery={this.props.context.loginQuery}
|
platformName={this.props.context.platformName}
|
||||||
supportEmail={this.props.context.supportEmail}
|
loginQuery={this.props.context.loginQuery}
|
||||||
/>);
|
supportEmail={this.props.context.supportEmail}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (suggestions !== null && suggestions.length) {
|
if (suggestions !== null && suggestions.length) {
|
||||||
suggestionsListComponent = (
|
suggestionsListComponent = (
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import PropTypes from 'prop-types';
|
|||||||
import StringUtils from 'edx-ui-toolkit/js/utils/string-utils';
|
import StringUtils from 'edx-ui-toolkit/js/utils/string-utils';
|
||||||
|
|
||||||
function Success({
|
function Success({
|
||||||
platformName, homepageUrl, dashboardUrl, isLoggedIn
|
platformName, homepageUrl, dashboardUrl, isLoggedIn,
|
||||||
}) {
|
}) {
|
||||||
let btnText,
|
let btnText,
|
||||||
btnUrl;
|
btnUrl;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export function markBlocksCompletedOnViewIfNeeded(runtime, containerElement) {
|
|||||||
const tracker = new ViewedEventTracker();
|
const tracker = new ViewedEventTracker();
|
||||||
|
|
||||||
blockElements.forEach((blockElement) => {
|
blockElements.forEach((blockElement) => {
|
||||||
const markCompletedOnViewAfterDelay = parseInt(blockElement.dataset.markCompletedOnViewAfterDelay, 10,);
|
const markCompletedOnViewAfterDelay = parseInt(blockElement.dataset.markCompletedOnViewAfterDelay, 10);
|
||||||
if (markCompletedOnViewAfterDelay >= 0) {
|
if (markCompletedOnViewAfterDelay >= 0) {
|
||||||
tracker.addElement(blockElement, markCompletedOnViewAfterDelay);
|
tracker.addElement(blockElement, markCompletedOnViewAfterDelay);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,7 +123,7 @@
|
|||||||
|
|
||||||
this.before = this.before.replace(regex,
|
this.before = this.before.replace(regex,
|
||||||
function(match) {
|
function(match) {
|
||||||
chunkObj.startTag = chunkObj.startTag + match;
|
chunkObj.startTag += match;
|
||||||
return '';
|
return '';
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@
|
|||||||
|
|
||||||
this.selection = this.selection.replace(regex,
|
this.selection = this.selection.replace(regex,
|
||||||
function(match) {
|
function(match) {
|
||||||
chunkObj.startTag = chunkObj.startTag + match;
|
chunkObj.startTag += match;
|
||||||
return '';
|
return '';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -194,14 +194,14 @@
|
|||||||
|
|
||||||
this.selection = this.selection.replace(/(^\n*)/, '');
|
this.selection = this.selection.replace(/(^\n*)/, '');
|
||||||
|
|
||||||
this.startTag = this.startTag + re.$1;
|
this.startTag += re.$1;
|
||||||
|
|
||||||
this.selection = this.selection.replace(/(\n*$)/, '');
|
this.selection = this.selection.replace(/(\n*$)/, '');
|
||||||
this.endTag = this.endTag + re.$1;
|
this.endTag += re.$1;
|
||||||
this.startTag = this.startTag.replace(/(^\n*)/, '');
|
this.startTag = this.startTag.replace(/(^\n*)/, '');
|
||||||
this.before = this.before + re.$1;
|
this.before += re.$1;
|
||||||
this.endTag = this.endTag.replace(/(\n*$)/, '');
|
this.endTag = this.endTag.replace(/(\n*$)/, '');
|
||||||
this.after = this.after + re.$1;
|
this.after += re.$1;
|
||||||
|
|
||||||
if (this.before) {
|
if (this.before) {
|
||||||
regexText = replacementText = '';
|
regexText = replacementText = '';
|
||||||
@@ -236,7 +236,7 @@
|
|||||||
|
|
||||||
function findAnEmptyToolbar(toolbarClassName) {
|
function findAnEmptyToolbar(toolbarClassName) {
|
||||||
var toolbars = doc.getElementsByClassName(toolbarClassName);
|
var toolbars = doc.getElementsByClassName(toolbarClassName);
|
||||||
for (var i=0; i < toolbars.length; ++i) {
|
for (var i = 0; i < toolbars.length; ++i) {
|
||||||
var aToolbar = toolbars[i];
|
var aToolbar = toolbars[i];
|
||||||
if (aToolbar.children.length == 0) {
|
if (aToolbar.children.length == 0) {
|
||||||
var anEmptyToolbar = aToolbar;
|
var anEmptyToolbar = aToolbar;
|
||||||
@@ -524,7 +524,6 @@
|
|||||||
var keyCodeChar = String.fromCharCode(keyCode);
|
var keyCodeChar = String.fromCharCode(keyCode);
|
||||||
|
|
||||||
switch (keyCodeChar) {
|
switch (keyCodeChar) {
|
||||||
|
|
||||||
case 'y':
|
case 'y':
|
||||||
undoObj.redo();
|
undoObj.redo();
|
||||||
handled = true;
|
handled = true;
|
||||||
@@ -548,7 +547,6 @@
|
|||||||
if (window.event) {
|
if (window.event) {
|
||||||
window.event.returnValue = false;
|
window.event.returnValue = false;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -737,7 +735,7 @@
|
|||||||
|
|
||||||
// Sets the TextareaState properties given a chunk of markdown.
|
// Sets the TextareaState properties given a chunk of markdown.
|
||||||
this.setChunks = function(chunk) {
|
this.setChunks = function(chunk) {
|
||||||
chunk.before = chunk.before + chunk.startTag;
|
chunk.before += chunk.startTag;
|
||||||
chunk.after = chunk.endTag + chunk.after;
|
chunk.after = chunk.endTag + chunk.after;
|
||||||
|
|
||||||
this.start = chunk.before.length;
|
this.start = chunk.before.length;
|
||||||
@@ -1572,11 +1570,9 @@
|
|||||||
|
|
||||||
// Add the true markup.
|
// Add the true markup.
|
||||||
var markup = nStars <= 1 ? '*' : '**'; // shouldn't the test be = ?
|
var markup = nStars <= 1 ? '*' : '**'; // shouldn't the test be = ?
|
||||||
chunk.before = chunk.before + markup;
|
chunk.before += markup;
|
||||||
chunk.after = markup + chunk.after;
|
chunk.after = markup + chunk.after;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
commandProto.stripLinkDefs = function(text, defsToAdd) {
|
commandProto.stripLinkDefs = function(text, defsToAdd) {
|
||||||
@@ -1663,7 +1659,9 @@
|
|||||||
});
|
});
|
||||||
if (title) {
|
if (title) {
|
||||||
title = title.trim ? title.trim() : title.replace(/^\s*/, '').replace(/\s*$/, '');
|
title = title.trim ? title.trim() : title.replace(/^\s*/, '').replace(/\s*$/, '');
|
||||||
title = $.trim(title).replace(/"/g, 'quot;').replace(/\(/g, '(').replace(/\)/g, ')').replace(/</g, '<').replace(/>/g, '>');
|
title = $.trim(title).replace(/"/g, 'quot;').replace(/\(/g, '(').replace(/\)/g, ')')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>');
|
||||||
}
|
}
|
||||||
return title ? link + ' "' + title + '"' : link;
|
return title ? link + ' "' + title + '"' : link;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ export class StatusAlertRenderer {
|
|||||||
*/
|
*/
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<StatusAlert
|
<StatusAlert
|
||||||
alertType='warning'
|
alertType="warning"
|
||||||
dismissible={true}
|
dismissible
|
||||||
open={true}
|
open
|
||||||
dialog={message}
|
dialog={message}
|
||||||
dismissable={true}
|
dismissable
|
||||||
onClose={() => this.shiftFocus(afterselector)}
|
onClose={() => this.shiftFocus(afterselector)}
|
||||||
/>,
|
/>,
|
||||||
document.querySelector(selector)
|
document.querySelector(selector)
|
||||||
|
|||||||
@@ -49,9 +49,9 @@ $(function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (cancel_submit) {
|
if (cancel_submit) {
|
||||||
$('.status.message.submission-error').
|
$('.status.message.submission-error')
|
||||||
removeClass('is-hidden').
|
.removeClass('is-hidden')
|
||||||
focus();
|
.focus();
|
||||||
$('html, body').animate({scrollTop: 0}, 'fast');
|
$('html, body').animate({scrollTop: 0}, 'fast');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -72,10 +72,10 @@ $(function() {
|
|||||||
toggleSubmitButton(true);
|
toggleSubmitButton(true);
|
||||||
json = $.parseJSON(jqXHR.responseText);
|
json = $.parseJSON(jqXHR.responseText);
|
||||||
$('.status.message.submission-error').addClass('is-shown').focus();
|
$('.status.message.submission-error').addClass('is-shown').focus();
|
||||||
$('.status.message.submission-error .message-copy').
|
$('.status.message.submission-error .message-copy')
|
||||||
text(gettext('There has been an error processing your survey.')).
|
.text(gettext('There has been an error processing your survey.'))
|
||||||
stop().
|
.stop()
|
||||||
css('display', 'block');
|
.css('display', 'block');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -83,14 +83,14 @@ function toggleSubmitButton(enable) {
|
|||||||
var $submitButton = $('form .form-actions #submit');
|
var $submitButton = $('form .form-actions #submit');
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
$submitButton.
|
$submitButton
|
||||||
removeClass('is-disabled').
|
.removeClass('is-disabled')
|
||||||
attr('aria-disabled', false).
|
.attr('aria-disabled', false)
|
||||||
removeProp('disabled');
|
.removeProp('disabled');
|
||||||
} else {
|
} else {
|
||||||
$submitButton.
|
$submitButton
|
||||||
addClass('is-disabled').
|
.addClass('is-disabled')
|
||||||
attr('aria-disabled', true).
|
.attr('aria-disabled', true)
|
||||||
prop('disabled', true);
|
.prop('disabled', true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ var edx = edx || {};
|
|||||||
display: 'block',
|
display: 'block',
|
||||||
'z-index': 0
|
'z-index': 0
|
||||||
});
|
});
|
||||||
$('#activate-account-modal').focus()
|
$('#activate-account-modal').focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.action-email-settings').each(function(index) {
|
$('.action-email-settings').each(function(index) {
|
||||||
|
|||||||
@@ -4,13 +4,12 @@ import Cookies from 'js-cookie';
|
|||||||
import {DemographicsCollectionModal} from './DemographicsCollectionModal';
|
import {DemographicsCollectionModal} from './DemographicsCollectionModal';
|
||||||
|
|
||||||
export class DemographicsCollectionBanner extends React.Component {
|
export class DemographicsCollectionBanner extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
modalOpen: false,
|
modalOpen: false,
|
||||||
hideBanner: false
|
hideBanner: false
|
||||||
}
|
};
|
||||||
|
|
||||||
this.dismissBanner = this.dismissBanner.bind(this);
|
this.dismissBanner = this.dismissBanner.bind(this);
|
||||||
}
|
}
|
||||||
@@ -65,30 +64,31 @@ export class DemographicsCollectionBanner extends React.Component {
|
|||||||
{gettext('Want to make edX better for everyone?')}
|
{gettext('Want to make edX better for everyone?')}
|
||||||
</div>
|
</div>
|
||||||
<button className="demographics-banner-btn d-flex align-items-center bg-white font-weight-bold border-0 py-2 px-3 mx-2 mb-3 m-lg-0 shadow justify-content-center">
|
<button className="demographics-banner-btn d-flex align-items-center bg-white font-weight-bold border-0 py-2 px-3 mx-2 mb-3 m-lg-0 shadow justify-content-center">
|
||||||
<span className="fa fa-thumbs-up px-2" aria-hidden="true"></span>
|
<span className="fa fa-thumbs-up px-2" aria-hidden="true" />
|
||||||
{gettext('Get started')}
|
{gettext('Get started')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="demographics-dismiss-container md-flex justify-content-right align-self-start align-self-lg-center ml-lg-auto">
|
<div className="demographics-dismiss-container md-flex justify-content-right align-self-start align-self-lg-center ml-lg-auto">
|
||||||
<button type="button" className="demographics-dismiss-btn btn btn-default px-0" id="demographics-dismiss" aria-label="close">
|
<button type="button" className="demographics-dismiss-btn btn btn-default px-0" id="demographics-dismiss" aria-label="close">
|
||||||
<i className="fa fa-times-circle text-white px-2" aria-hidden="true" onClick={this.dismissBanner}></i>
|
<i className="fa fa-times-circle text-white px-2" aria-hidden="true" onClick={this.dismissBanner} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<div>
|
<div>
|
||||||
{this.state.modalOpen
|
{this.state.modalOpen
|
||||||
&& <DemographicsCollectionModal
|
&& (
|
||||||
{...this.props}
|
<DemographicsCollectionModal
|
||||||
user={this.props.user}
|
{...this.props}
|
||||||
open={this.state.modalOpen}
|
user={this.props.user}
|
||||||
closeModal={() => this.setState({modalOpen: false})}
|
open={this.state.modalOpen}
|
||||||
dismissBanner={this.dismissBanner}
|
closeModal={() => this.setState({modalOpen: false})}
|
||||||
/>
|
dismissBanner={this.dismissBanner}
|
||||||
}
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
/* global gettext */
|
/* global gettext */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import Wizard from './Wizard';
|
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
import {SelectWithInput} from './SelectWithInput'
|
import StringUtils from 'edx-ui-toolkit/js/utils/string-utils';
|
||||||
|
import FocusLock from 'react-focus-lock';
|
||||||
|
import Wizard from './Wizard';
|
||||||
|
import {SelectWithInput} from './SelectWithInput';
|
||||||
import {MultiselectDropdown} from './MultiselectDropdown';
|
import {MultiselectDropdown} from './MultiselectDropdown';
|
||||||
import AxiosJwtTokenService from '../jwt_auth/AxiosJwtTokenService';
|
import AxiosJwtTokenService from '../jwt_auth/AxiosJwtTokenService';
|
||||||
import StringUtils from 'edx-ui-toolkit/js/utils/string-utils';
|
|
||||||
import AxiosCsrfTokenService from '../jwt_auth/AxiosCsrfTokenService';
|
import AxiosCsrfTokenService from '../jwt_auth/AxiosCsrfTokenService';
|
||||||
import FocusLock from 'react-focus-lock';
|
|
||||||
|
|
||||||
const FIELD_NAMES = {
|
const FIELD_NAMES = {
|
||||||
CURRENT_WORK: 'current_work_sector',
|
CURRENT_WORK: 'current_work_sector',
|
||||||
@@ -66,7 +66,7 @@ class DemographicsCollectionModal extends React.Component {
|
|||||||
accessToken,
|
accessToken,
|
||||||
refreshUrl,
|
refreshUrl,
|
||||||
);
|
);
|
||||||
this.csrfTokenService = new AxiosCsrfTokenService(this.props.csrfTokenPath)
|
this.csrfTokenService = new AxiosCsrfTokenService(this.props.csrfTokenPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
@@ -108,7 +108,7 @@ class DemographicsCollectionModal extends React.Component {
|
|||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
await this.jwtTokenService.getJwtToken();
|
await this.jwtTokenService.getJwtToken();
|
||||||
await fetch(url, options)
|
await fetch(url, options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.setState({loading: false, fieldError: true, errorMessage: error});
|
this.setState({loading: false, fieldError: true, errorMessage: error});
|
||||||
}
|
}
|
||||||
@@ -129,13 +129,13 @@ class DemographicsCollectionModal extends React.Component {
|
|||||||
this.setState(({selected}) => {
|
this.setState(({selected}) => {
|
||||||
// decline was previously selected
|
// decline was previously selected
|
||||||
if (selected[FIELD_NAMES.ETHNICITY].find(i => i === 'declined')) {
|
if (selected[FIELD_NAMES.ETHNICITY].find(i => i === 'declined')) {
|
||||||
return {selected: {...selected, [FIELD_NAMES.ETHNICITY]: values.filter(value => value !== 'declined')}}
|
return {selected: {...selected, [FIELD_NAMES.ETHNICITY]: values.filter(value => value !== 'declined')}};
|
||||||
// decline was just selected
|
// decline was just selected
|
||||||
} else if (decline) {
|
} else if (decline) {
|
||||||
return {selected: {...selected, [FIELD_NAMES.ETHNICITY]: [decline]}}
|
return {selected: {...selected, [FIELD_NAMES.ETHNICITY]: [decline]}};
|
||||||
// anything else was selected
|
// anything else was selected
|
||||||
} else {
|
} else {
|
||||||
return {selected: {...selected, [FIELD_NAMES.ETHNICITY]: values}}
|
return {selected: {...selected, [FIELD_NAMES.ETHNICITY]: values}};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -174,7 +174,7 @@ class DemographicsCollectionModal extends React.Component {
|
|||||||
// We gather the possible answers to any demographics questions from the OPTIONS of the api
|
// We gather the possible answers to any demographics questions from the OPTIONS of the api
|
||||||
async getDemographicsQuestionOptions() {
|
async getDemographicsQuestionOptions() {
|
||||||
try {
|
try {
|
||||||
const optionsResponse = await fetch(`${this.props.demographicsBaseUrl}/demographics/api/v1/demographics/`, {method: 'OPTIONS'})
|
const optionsResponse = await fetch(`${this.props.demographicsBaseUrl}/demographics/api/v1/demographics/`, {method: 'OPTIONS'});
|
||||||
const demographicsOptions = await optionsResponse.json();
|
const demographicsOptions = await optionsResponse.json();
|
||||||
return demographicsOptions;
|
return demographicsOptions;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -240,7 +240,7 @@ class DemographicsCollectionModal extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.state.loading) {
|
if (this.state.loading) {
|
||||||
return <div className="demographics-collection-modal d-flex justify-content-center align-items-start" />
|
return <div className="demographics-collection-modal d-flex justify-content-center align-items-start" />;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<FocusLock>
|
<FocusLock>
|
||||||
@@ -261,8 +261,7 @@ class DemographicsCollectionModal extends React.Component {
|
|||||||
currentPage: currentPage,
|
currentPage: currentPage,
|
||||||
totalPages: totalPages
|
totalPages: totalPages
|
||||||
}
|
}
|
||||||
)
|
)}
|
||||||
}
|
|
||||||
</p>
|
</p>
|
||||||
<h2 className="mb-1 mt-4 font-weight-bold text-secondary">
|
<h2 className="mb-1 mt-4 font-weight-bold text-secondary">
|
||||||
{gettext('Help make edX better for everyone!')}
|
{gettext('Help make edX better for everyone!')}
|
||||||
@@ -282,204 +281,209 @@ class DemographicsCollectionModal extends React.Component {
|
|||||||
)}
|
)}
|
||||||
</Wizard.Header>
|
</Wizard.Header>
|
||||||
<Wizard.Page>
|
<Wizard.Page>
|
||||||
{({wizardConsumer}) => <div className="demographics-form-container" data-hj-suppress>
|
{({wizardConsumer}) => (
|
||||||
{/* Gender Identity */}
|
<div className="demographics-form-container" data-hj-suppress>
|
||||||
<SelectWithInput
|
{/* Gender Identity */}
|
||||||
selectName={FIELD_NAMES.GENDER}
|
<SelectWithInput
|
||||||
selectId={FIELD_NAMES.GENDER}
|
selectName={FIELD_NAMES.GENDER}
|
||||||
selectValue={wizardConsumer[FIELD_NAMES.GENDER]}
|
selectId={FIELD_NAMES.GENDER}
|
||||||
selectOnChange={this.handleSelectChange}
|
selectValue={wizardConsumer[FIELD_NAMES.GENDER]}
|
||||||
labelText={gettext('What is your gender identity?')}
|
selectOnChange={this.handleSelectChange}
|
||||||
options={[
|
labelText={gettext('What is your gender identity?')}
|
||||||
<option value="default" key="default">{gettext('Select gender')}</option>,
|
options={[
|
||||||
this.loadOptions(FIELD_NAMES.GENDER)
|
<option value="default" key="default">{gettext('Select gender')}</option>,
|
||||||
]}
|
this.loadOptions(FIELD_NAMES.GENDER)
|
||||||
showInput={wizardConsumer[FIELD_NAMES.GENDER] == 'self-describe'}
|
]}
|
||||||
inputName={FIELD_NAMES.GENDER_DESCRIPTION}
|
showInput={wizardConsumer[FIELD_NAMES.GENDER] == 'self-describe'}
|
||||||
inputId={FIELD_NAMES.GENDER_DESCRIPTION}
|
inputName={FIELD_NAMES.GENDER_DESCRIPTION}
|
||||||
inputType="text"
|
inputId={FIELD_NAMES.GENDER_DESCRIPTION}
|
||||||
inputValue={wizardConsumer[FIELD_NAMES.GENDER_DESCRIPTION]}
|
inputType="text"
|
||||||
inputOnChange={this.handleInputChange}
|
inputValue={wizardConsumer[FIELD_NAMES.GENDER_DESCRIPTION]}
|
||||||
inputOnBlur={this.handleSelectChange}
|
inputOnChange={this.handleInputChange}
|
||||||
disabled={this.state.fieldError}
|
inputOnBlur={this.handleSelectChange}
|
||||||
/>
|
disabled={this.state.fieldError}
|
||||||
{/* Ethnicity */}
|
/>
|
||||||
<MultiselectDropdown
|
{/* Ethnicity */}
|
||||||
label={gettext('Which of the following describes you best?')}
|
<MultiselectDropdown
|
||||||
emptyLabel={gettext('Check all that apply')}
|
label={gettext('Which of the following describes you best?')}
|
||||||
options={get(this.state.options, FIELD_NAMES.ETHNICITY_OPTIONS, {choices: []}).choices}
|
emptyLabel={gettext('Check all that apply')}
|
||||||
selected={wizardConsumer[FIELD_NAMES.ETHNICITY]}
|
options={get(this.state.options, FIELD_NAMES.ETHNICITY_OPTIONS, {choices: []}).choices}
|
||||||
onChange={this.handleMultiselectChange}
|
selected={wizardConsumer[FIELD_NAMES.ETHNICITY]}
|
||||||
disabled={this.state.fieldError}
|
onChange={this.handleMultiselectChange}
|
||||||
onBlur={() => {
|
disabled={this.state.fieldError}
|
||||||
|
onBlur={() => {
|
||||||
// we create a fake "event", and then use it to call our normal selection handler function that
|
// we create a fake "event", and then use it to call our normal selection handler function that
|
||||||
// is used by the other dropdowns.
|
// is used by the other dropdowns.
|
||||||
const e = {
|
const e = {
|
||||||
target: {
|
target: {
|
||||||
name: FIELD_NAMES.ETHNICITY,
|
name: FIELD_NAMES.ETHNICITY,
|
||||||
value: wizardConsumer[FIELD_NAMES.ETHNICITY].map(ethnicity => ({ethnicity, value: ethnicity})),
|
value: wizardConsumer[FIELD_NAMES.ETHNICITY].map(ethnicity => ({ethnicity, value: ethnicity})),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.handleSelectChange(e);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/* Family Income */}
|
||||||
|
<div className="d-flex flex-column pb-3">
|
||||||
|
<label htmlFor={FIELD_NAMES.INCOME}>
|
||||||
|
{gettext('What was the total combined income, during the last 12 months, of all members of your family? ')}
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
onChange={this.handleSelectChange}
|
||||||
|
className="form-control"
|
||||||
|
name={FIELD_NAMES.INCOME}
|
||||||
|
id={FIELD_NAMES.INCOME}
|
||||||
|
value={wizardConsumer[FIELD_NAMES.INCOME]}
|
||||||
|
disabled={this.state.fieldError}
|
||||||
|
>
|
||||||
|
<option value="default">{gettext('Select income')}</option>
|
||||||
|
{
|
||||||
|
this.loadOptions(FIELD_NAMES.INCOME)
|
||||||
}
|
}
|
||||||
}
|
</select>
|
||||||
this.handleSelectChange(e);
|
</div>
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{/* Family Income */}
|
|
||||||
<div className="d-flex flex-column pb-3">
|
|
||||||
<label htmlFor={FIELD_NAMES.INCOME}>
|
|
||||||
{gettext('What was the total combined income, during the last 12 months, of all members of your family? ')}
|
|
||||||
</label>
|
|
||||||
<select
|
|
||||||
onChange={this.handleSelectChange}
|
|
||||||
className="form-control"
|
|
||||||
name={FIELD_NAMES.INCOME} id={FIELD_NAMES.INCOME}
|
|
||||||
value={wizardConsumer[FIELD_NAMES.INCOME]}
|
|
||||||
disabled={this.state.fieldError}
|
|
||||||
>
|
|
||||||
<option value="default">{gettext('Select income')}</option>
|
|
||||||
{
|
|
||||||
this.loadOptions(FIELD_NAMES.INCOME)
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
}
|
|
||||||
</Wizard.Page>
|
</Wizard.Page>
|
||||||
<Wizard.Page>
|
<Wizard.Page>
|
||||||
{({wizardConsumer}) => <div className="demographics-form-container" data-hj-suppress>
|
{({wizardConsumer}) => (
|
||||||
{/* Military History */}
|
<div className="demographics-form-container" data-hj-suppress>
|
||||||
<div className="d-flex flex-column pb-3">
|
{/* Military History */}
|
||||||
<label htmlFor={FIELD_NAMES.MILITARY}>
|
<div className="d-flex flex-column pb-3">
|
||||||
{gettext('Have you ever served on active duty in the U.S. Armed Forces, Reserves, or National Guard?')}
|
<label htmlFor={FIELD_NAMES.MILITARY}>
|
||||||
</label>
|
{gettext('Have you ever served on active duty in the U.S. Armed Forces, Reserves, or National Guard?')}
|
||||||
<select
|
</label>
|
||||||
autoFocus
|
<select
|
||||||
className="form-control"
|
autoFocus
|
||||||
onChange={this.handleSelectChange}
|
className="form-control"
|
||||||
name={FIELD_NAMES.MILITARY}
|
onChange={this.handleSelectChange}
|
||||||
id={FIELD_NAMES.MILITARY}
|
name={FIELD_NAMES.MILITARY}
|
||||||
value={wizardConsumer[FIELD_NAMES.MILITARY]}
|
id={FIELD_NAMES.MILITARY}
|
||||||
disabled={this.state.fieldError}
|
value={wizardConsumer[FIELD_NAMES.MILITARY]}
|
||||||
>
|
disabled={this.state.fieldError}
|
||||||
<option value="default">{gettext('Select military status')}</option>
|
>
|
||||||
{
|
<option value="default">{gettext('Select military status')}</option>
|
||||||
this.loadOptions(FIELD_NAMES.MILITARY)
|
{
|
||||||
}
|
this.loadOptions(FIELD_NAMES.MILITARY)
|
||||||
</select>
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
}
|
|
||||||
</Wizard.Page>
|
</Wizard.Page>
|
||||||
<Wizard.Page>
|
<Wizard.Page>
|
||||||
{({wizardConsumer}) => <div className="demographics-form-container" data-hj-suppress>
|
{({wizardConsumer}) => (
|
||||||
{/* Learner Education Level */}
|
<div className="demographics-form-container" data-hj-suppress>
|
||||||
<div className="d-flex flex-column pb-3">
|
{/* Learner Education Level */}
|
||||||
<label htmlFor={FIELD_NAMES.EDUCATION_LEVEL}>
|
<div className="d-flex flex-column pb-3">
|
||||||
{gettext('What is the highest level of education that you have achieved so far?')}
|
<label htmlFor={FIELD_NAMES.EDUCATION_LEVEL}>
|
||||||
</label>
|
{gettext('What is the highest level of education that you have achieved so far?')}
|
||||||
<select
|
</label>
|
||||||
className="form-control"
|
<select
|
||||||
autoFocus
|
className="form-control"
|
||||||
onChange={this.handleSelectChange}
|
autoFocus
|
||||||
key="self-education"
|
onChange={this.handleSelectChange}
|
||||||
name={FIELD_NAMES.EDUCATION_LEVEL}
|
key="self-education"
|
||||||
id={FIELD_NAMES.EDUCATION_LEVEL}
|
name={FIELD_NAMES.EDUCATION_LEVEL}
|
||||||
value={wizardConsumer[FIELD_NAMES.EDUCATION_LEVEL]}
|
id={FIELD_NAMES.EDUCATION_LEVEL}
|
||||||
disabled={this.state.fieldError}
|
value={wizardConsumer[FIELD_NAMES.EDUCATION_LEVEL]}
|
||||||
>
|
disabled={this.state.fieldError}
|
||||||
<option value="default">{gettext('Select level of education')}</option>
|
>
|
||||||
{
|
<option value="default">{gettext('Select level of education')}</option>
|
||||||
this.loadOptions(FIELD_NAMES.EDUCATION_LEVEL)
|
{
|
||||||
}
|
this.loadOptions(FIELD_NAMES.EDUCATION_LEVEL)
|
||||||
</select>
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{/* Parent/Guardian Education Level */}
|
||||||
|
<div className="d-flex flex-column pb-3">
|
||||||
|
<label htmlFor={FIELD_NAMES.PARENT_EDUCATION}>
|
||||||
|
{gettext('What is the highest level of education that any of your parents or guardians have achieved?')}
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
className="form-control"
|
||||||
|
onChange={this.handleSelectChange}
|
||||||
|
name={FIELD_NAMES.PARENT_EDUCATION}
|
||||||
|
id={FIELD_NAMES.PARENT_EDUCATION}
|
||||||
|
value={wizardConsumer[FIELD_NAMES.PARENT_EDUCATION]}
|
||||||
|
disabled={this.state.fieldError}
|
||||||
|
>
|
||||||
|
<option value="default">{gettext('Select guardian education')}</option>
|
||||||
|
{
|
||||||
|
this.loadOptions(FIELD_NAMES.PARENT_EDUCATION)
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Parent/Guardian Education Level */}
|
)}
|
||||||
<div className="d-flex flex-column pb-3">
|
|
||||||
<label htmlFor={FIELD_NAMES.PARENT_EDUCATION}>
|
|
||||||
{gettext('What is the highest level of education that any of your parents or guardians have achieved?')}
|
|
||||||
</label>
|
|
||||||
<select
|
|
||||||
className="form-control"
|
|
||||||
onChange={this.handleSelectChange}
|
|
||||||
name={FIELD_NAMES.PARENT_EDUCATION}
|
|
||||||
id={FIELD_NAMES.PARENT_EDUCATION}
|
|
||||||
value={wizardConsumer[FIELD_NAMES.PARENT_EDUCATION]}
|
|
||||||
disabled={this.state.fieldError}
|
|
||||||
>
|
|
||||||
<option value="default">{gettext('Select guardian education')}</option>
|
|
||||||
{
|
|
||||||
this.loadOptions(FIELD_NAMES.PARENT_EDUCATION)
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</Wizard.Page>
|
</Wizard.Page>
|
||||||
<Wizard.Page>
|
<Wizard.Page>
|
||||||
{({wizardConsumer}) => <div className="demographics-form-container" data-hj-suppress>
|
{({wizardConsumer}) => (
|
||||||
{/* Employment Status */}
|
<div className="demographics-form-container" data-hj-suppress>
|
||||||
<SelectWithInput
|
{/* Employment Status */}
|
||||||
selectName={FIELD_NAMES.WORK_STATUS}
|
<SelectWithInput
|
||||||
selectId={FIELD_NAMES.WORK_STATUS}
|
selectName={FIELD_NAMES.WORK_STATUS}
|
||||||
selectValue={wizardConsumer[FIELD_NAMES.WORK_STATUS]}
|
selectId={FIELD_NAMES.WORK_STATUS}
|
||||||
selectOnChange={this.handleSelectChange}
|
selectValue={wizardConsumer[FIELD_NAMES.WORK_STATUS]}
|
||||||
labelText={'What is your current employment status?'}
|
selectOnChange={this.handleSelectChange}
|
||||||
options={[
|
labelText="What is your current employment status?"
|
||||||
<option value="default" key="default">{gettext('Select employment status')}</option>,
|
options={[
|
||||||
this.loadOptions(FIELD_NAMES.WORK_STATUS)
|
<option value="default" key="default">{gettext('Select employment status')}</option>,
|
||||||
]}
|
this.loadOptions(FIELD_NAMES.WORK_STATUS)
|
||||||
showInput={wizardConsumer[FIELD_NAMES.WORK_STATUS] == 'other'}
|
]}
|
||||||
inputName={FIELD_NAMES.WORK_STATUS_DESCRIPTION}
|
showInput={wizardConsumer[FIELD_NAMES.WORK_STATUS] == 'other'}
|
||||||
inputId={FIELD_NAMES.WORK_STATUS_DESCRIPTION}
|
inputName={FIELD_NAMES.WORK_STATUS_DESCRIPTION}
|
||||||
inputType="text"
|
inputId={FIELD_NAMES.WORK_STATUS_DESCRIPTION}
|
||||||
inputValue={wizardConsumer[FIELD_NAMES.WORK_STATUS_DESCRIPTION]}
|
inputType="text"
|
||||||
inputOnChange={this.handleInputChange}
|
inputValue={wizardConsumer[FIELD_NAMES.WORK_STATUS_DESCRIPTION]}
|
||||||
inputOnBlur={this.handleSelectChange}
|
inputOnChange={this.handleInputChange}
|
||||||
disabled={this.state.fieldError}
|
inputOnBlur={this.handleSelectChange}
|
||||||
/>
|
|
||||||
{/* Current Work Industry */}
|
|
||||||
<div className="d-flex flex-column pb-3">
|
|
||||||
<label htmlFor={FIELD_NAMES.CURRENT_WORK}>
|
|
||||||
{gettext('What industry do you currently work in?')}
|
|
||||||
</label>
|
|
||||||
<select
|
|
||||||
className="form-control"
|
|
||||||
onChange={this.handleSelectChange}
|
|
||||||
name={FIELD_NAMES.CURRENT_WORK}
|
|
||||||
id={FIELD_NAMES.CURRENT_WORK}
|
|
||||||
value={wizardConsumer[FIELD_NAMES.CURRENT_WORK]}
|
|
||||||
disabled={this.state.fieldError}
|
disabled={this.state.fieldError}
|
||||||
>
|
/>
|
||||||
<option value="default">{gettext('Select current industry')}</option>
|
{/* Current Work Industry */}
|
||||||
{
|
<div className="d-flex flex-column pb-3">
|
||||||
this.loadOptions(FIELD_NAMES.CURRENT_WORK)
|
<label htmlFor={FIELD_NAMES.CURRENT_WORK}>
|
||||||
}
|
{gettext('What industry do you currently work in?')}
|
||||||
</select>
|
</label>
|
||||||
|
<select
|
||||||
|
className="form-control"
|
||||||
|
onChange={this.handleSelectChange}
|
||||||
|
name={FIELD_NAMES.CURRENT_WORK}
|
||||||
|
id={FIELD_NAMES.CURRENT_WORK}
|
||||||
|
value={wizardConsumer[FIELD_NAMES.CURRENT_WORK]}
|
||||||
|
disabled={this.state.fieldError}
|
||||||
|
>
|
||||||
|
<option value="default">{gettext('Select current industry')}</option>
|
||||||
|
{
|
||||||
|
this.loadOptions(FIELD_NAMES.CURRENT_WORK)
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{/* Future Work Industry */}
|
||||||
|
<div className="d-flex flex-column pb-3">
|
||||||
|
<label htmlFor={FIELD_NAMES.FUTURE_WORK}>
|
||||||
|
{gettext('What industry do you want to work in?')}
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
className="form-control"
|
||||||
|
onChange={this.handleSelectChange}
|
||||||
|
name={FIELD_NAMES.FUTURE_WORK}
|
||||||
|
id={FIELD_NAMES.FUTURE_WORK}
|
||||||
|
value={wizardConsumer[FIELD_NAMES.FUTURE_WORK]}
|
||||||
|
disabled={this.state.fieldError}
|
||||||
|
>
|
||||||
|
<option value="default">{gettext('Select prospective industry')}</option>
|
||||||
|
{
|
||||||
|
this.loadOptions(FIELD_NAMES.FUTURE_WORK)
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Future Work Industry */}
|
)}
|
||||||
<div className="d-flex flex-column pb-3">
|
|
||||||
<label htmlFor={FIELD_NAMES.FUTURE_WORK}>
|
|
||||||
{gettext('What industry do you want to work in?')}
|
|
||||||
</label>
|
|
||||||
<select
|
|
||||||
className="form-control"
|
|
||||||
onChange={this.handleSelectChange}
|
|
||||||
name={FIELD_NAMES.FUTURE_WORK}
|
|
||||||
id={FIELD_NAMES.FUTURE_WORK}
|
|
||||||
value={wizardConsumer[FIELD_NAMES.FUTURE_WORK]}
|
|
||||||
disabled={this.state.fieldError}
|
|
||||||
>
|
|
||||||
<option value="default">{gettext('Select prospective industry')}</option>
|
|
||||||
{
|
|
||||||
this.loadOptions(FIELD_NAMES.FUTURE_WORK)
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</Wizard.Page>
|
</Wizard.Page>
|
||||||
<Wizard.Closer>
|
<Wizard.Closer>
|
||||||
<div className="demographics-modal-closer m-sm-0">
|
<div className="demographics-modal-closer m-sm-0">
|
||||||
<i className="fa fa-check" aria-hidden="true"></i>
|
<i className="fa fa-check" aria-hidden="true" />
|
||||||
<h3>
|
<h3>
|
||||||
{gettext('Thank you! You’re helping make edX better for everyone.')}
|
{gettext('Thank you! You’re helping make edX better for everyone.')}
|
||||||
</h3>
|
</h3>
|
||||||
@@ -493,7 +497,7 @@ class DemographicsCollectionModal extends React.Component {
|
|||||||
</Wizard>
|
</Wizard>
|
||||||
</div>
|
</div>
|
||||||
</FocusLock>
|
</FocusLock>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class MultiselectDropdown extends React.Component {
|
|||||||
this.buttonRef = null;
|
this.buttonRef = null;
|
||||||
this.setButtonRef = (element) => {
|
this.setButtonRef = (element) => {
|
||||||
this.buttonRef = element;
|
this.buttonRef = element;
|
||||||
}
|
};
|
||||||
|
|
||||||
this.focusButton = this.focusButton.bind(this);
|
this.focusButton = this.focusButton.bind(this);
|
||||||
this.handleKeydown = this.handleKeydown.bind(this);
|
this.handleKeydown = this.handleKeydown.bind(this);
|
||||||
@@ -27,7 +27,6 @@ class MultiselectDropdown extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
|
||||||
document.removeEventListener('keydown', this.handleKeydown, false);
|
document.removeEventListener('keydown', this.handleKeydown, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +86,7 @@ class MultiselectDropdown extends React.Component {
|
|||||||
.map(selected => this.findOption(selected).display_name)
|
.map(selected => this.findOption(selected).display_name)
|
||||||
.join(', ');
|
.join(', ');
|
||||||
if (selectedList.length > 60) {
|
if (selectedList.length > 60) {
|
||||||
return selectedList.substring(0, 55) + '...'
|
return selectedList.substring(0, 55) + '...';
|
||||||
}
|
}
|
||||||
return selectedList;
|
return selectedList;
|
||||||
}
|
}
|
||||||
@@ -95,7 +94,7 @@ class MultiselectDropdown extends React.Component {
|
|||||||
renderUnselect() {
|
renderUnselect() {
|
||||||
return this.props.selected.length > 0 && (
|
return this.props.selected.length > 0 && (
|
||||||
<button id="unselect-button" disabled={this.props.disabled} aria-label="Clear all selected" onClick={this.handleRemoveAllClick}>{gettext('Clear all')}</button>
|
<button id="unselect-button" disabled={this.props.disabled} aria-label="Clear all selected" onClick={this.handleRemoveAllClick}>{gettext('Clear all')}</button>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderMenu() {
|
renderMenu() {
|
||||||
@@ -112,15 +111,15 @@ class MultiselectDropdown extends React.Component {
|
|||||||
<span className="pl-2">{option.display_name}</span>
|
<span className="pl-2">{option.display_name}</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
})
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<fieldset id="multiselect-dropdown-fieldset" disabled={this.props.disabled}>
|
<fieldset id="multiselect-dropdown-fieldset" disabled={this.props.disabled}>
|
||||||
<legend className="sr-only">{this.props.label}</legend>
|
<legend className="sr-only">{this.props.label}</legend>
|
||||||
{options}
|
{options}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -136,7 +135,7 @@ class MultiselectDropdown extends React.Component {
|
|||||||
// and close the dropdown.
|
// and close the dropdown.
|
||||||
if (!e.currentTarget.contains(e.relatedTarget)) {
|
if (!e.currentTarget.contains(e.relatedTarget)) {
|
||||||
this.props.onBlur(e);
|
this.props.onBlur(e);
|
||||||
this.setState({open: false})
|
this.setState({open: false});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -151,7 +150,7 @@ class MultiselectDropdown extends React.Component {
|
|||||||
{this.renderMenu()}
|
{this.renderMenu()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,19 +32,20 @@ export const SelectWithInput = (props) => {
|
|||||||
{options}
|
{options}
|
||||||
</select>
|
</select>
|
||||||
{showInput
|
{showInput
|
||||||
&& <input
|
&& (
|
||||||
className="form-control"
|
<input
|
||||||
aria-label={`${selectName} description field`}
|
className="form-control"
|
||||||
type={inputType}
|
aria-label={`${selectName} description field`}
|
||||||
name={inputName}
|
type={inputType}
|
||||||
id={inputId}
|
name={inputName}
|
||||||
onChange={inputOnChange}
|
id={inputId}
|
||||||
onBlur={inputOnBlur}
|
onChange={inputOnChange}
|
||||||
value={inputValue}
|
onBlur={inputOnBlur}
|
||||||
disabled={disabled}
|
value={inputValue}
|
||||||
maxLength={255}
|
disabled={disabled}
|
||||||
/>
|
maxLength={255}
|
||||||
}
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export default class Wizard extends React.Component {
|
|||||||
totalPages: 0,
|
totalPages: 0,
|
||||||
pages: [],
|
pages: [],
|
||||||
wizardContext: {},
|
wizardContext: {},
|
||||||
}
|
};
|
||||||
|
|
||||||
this.wizardComplete = this.wizardComplete.bind(this);
|
this.wizardComplete = this.wizardComplete.bind(this);
|
||||||
}
|
}
|
||||||
@@ -32,18 +32,18 @@ export default class Wizard extends React.Component {
|
|||||||
|
|
||||||
handleNext() {
|
handleNext() {
|
||||||
if (this.state.currentPage < this.props.children.length) {
|
if (this.state.currentPage < this.props.children.length) {
|
||||||
this.setState(prevState => ({currentPage: prevState.currentPage + 1}))
|
this.setState(prevState => ({currentPage: prevState.currentPage + 1}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
findSubComponentByType(type) {
|
findSubComponentByType(type) {
|
||||||
return React.Children.toArray(this.props.children).filter(child => child.type.name === type)
|
return React.Children.toArray(this.props.children).filter(child => child.type.name === type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this needs to handle the case of no provided header
|
// this needs to handle the case of no provided header
|
||||||
renderHeader() {
|
renderHeader() {
|
||||||
const header = this.findSubComponentByType(Wizard.Header.name)[0];
|
const header = this.findSubComponentByType(Wizard.Header.name)[0];
|
||||||
return header.props.children({currentPage: this.state.currentPage, totalPages: this.state.totalPages})
|
return header.props.children({currentPage: this.state.currentPage, totalPages: this.state.totalPages});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPage() {
|
renderPage() {
|
||||||
@@ -74,7 +74,7 @@ export default class Wizard extends React.Component {
|
|||||||
<button className="wizard-button colored" arial-label={gettext('close questionnaire')} onClick={this.props.onWizardComplete}>{gettext('Close')}</button>
|
<button className="wizard-button colored" arial-label={gettext('close questionnaire')} onClick={this.props.onWizardComplete}>{gettext('Close')}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -181,7 +181,7 @@
|
|||||||
_.each(modifiedUsers.changed, function(changedInfo) {
|
_.each(modifiedUsers.changed, function(changedInfo) {
|
||||||
oldCohort = changedInfo.previous_cohort;
|
oldCohort = changedInfo.previous_cohort;
|
||||||
if (oldCohort in movedByCohort) {
|
if (oldCohort in movedByCohort) {
|
||||||
movedByCohort[oldCohort] = movedByCohort[oldCohort] + 1;
|
movedByCohort[oldCohort] += 1;
|
||||||
} else {
|
} else {
|
||||||
movedByCohort[oldCohort] = 1;
|
movedByCohort[oldCohort] = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ function createMobileMenu() {
|
|||||||
* Dynamically create a mobile menu from all specified mobile links
|
* Dynamically create a mobile menu from all specified mobile links
|
||||||
* on the page.
|
* on the page.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
$('.mobile-nav-item').each(function() {
|
$('.mobile-nav-item').each(function() {
|
||||||
var mobileNavItem = $(this).clone().addClass('mobile-nav-link');
|
var mobileNavItem = $(this).clone().addClass('mobile-nav-link');
|
||||||
|
|||||||
@@ -91,9 +91,9 @@ var onCertificatesReady = null;
|
|||||||
var response = JSON.parse(jqXHR.responseText);
|
var response = JSON.parse(jqXHR.responseText);
|
||||||
$certificate_regeneration_status.text(gettext(response.message)).addClass('message');
|
$certificate_regeneration_status.text(gettext(response.message)).addClass('message');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
$certificate_regeneration_status.
|
$certificate_regeneration_status
|
||||||
text(gettext('Error while regenerating certificates. Please try again.')).
|
.text(gettext('Error while regenerating certificates. Please try again.'))
|
||||||
addClass('message');
|
.addClass('message');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
(function($) { // eslint-disable-line wrap-iife
|
(function($) { // eslint-disable-line wrap-iife
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
$.fn.extend({
|
$.fn.extend({
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -81,13 +81,15 @@ class CircleChart extends React.Component {
|
|||||||
lastY = nextY;
|
lastY = nextY;
|
||||||
|
|
||||||
// eslint-disable-next-line react/jsx-indent
|
// eslint-disable-next-line react/jsx-indent
|
||||||
return <path
|
return (
|
||||||
d={d}
|
<path
|
||||||
className={`slice-${sliceIndex}`}
|
d={d}
|
||||||
key={index}
|
className={`slice-${sliceIndex}`}
|
||||||
stroke={strokeColor}
|
key={index}
|
||||||
strokeWidth={strokeWidth}
|
stroke={strokeColor}
|
||||||
/>;
|
strokeWidth={strokeWidth}
|
||||||
|
/>
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,6 @@ class CircleChartLegend extends React.Component {
|
|||||||
|
|
||||||
CircleChartLegend.propTypes = {
|
CircleChartLegend.propTypes = {
|
||||||
data: PropTypes.array.isRequired
|
data: PropTypes.array.isRequired
|
||||||
}
|
};
|
||||||
|
|
||||||
export default CircleChartLegend;
|
export default CircleChartLegend;
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class Discussions extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div className="post-counts">
|
<div className="post-counts">
|
||||||
<div className="votes-wrapper">
|
<div className="votes-wrapper">
|
||||||
<span className="fa fa-plus-square-o count-icon" aria-hidden="true"></span>
|
<span className="fa fa-plus-square-o count-icon" aria-hidden="true" />
|
||||||
<span className="user-count">{thread_votes}</span>
|
<span className="user-count">{thread_votes}</span>
|
||||||
<p className="label">Votes on your posts, comments, and replies</p>
|
<p className="label">Votes on your posts, comments, and replies</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -85,6 +85,6 @@ class Discussions extends React.Component {
|
|||||||
Discussions.propTypes = {
|
Discussions.propTypes = {
|
||||||
content_authored: PropTypes.number.isRequired,
|
content_authored: PropTypes.number.isRequired,
|
||||||
thread_votes: PropTypes.number.isRequired
|
thread_votes: PropTypes.number.isRequired
|
||||||
}
|
};
|
||||||
|
|
||||||
export default Discussions;
|
export default Discussions;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class DueDates extends React.Component {
|
|||||||
|
|
||||||
getLabel(type) {
|
getLabel(type) {
|
||||||
const {assignmentCounts} = this.props;
|
const {assignmentCounts} = this.props;
|
||||||
if (assignmentCounts[type] < 2 ) {
|
if (assignmentCounts[type] < 2) {
|
||||||
return type;
|
return type;
|
||||||
} else {
|
} else {
|
||||||
this.renderLabels[type] += 1;
|
this.renderLabels[type] += 1;
|
||||||
@@ -35,14 +35,12 @@ class DueDates extends React.Component {
|
|||||||
this.renderLabels = this.initLabelTracker(assignmentCounts);
|
this.renderLabels = this.initLabelTracker(assignmentCounts);
|
||||||
|
|
||||||
return dates.sort((a, b) => new Date(a.due) > new Date(b.due))
|
return dates.sort((a, b) => new Date(a.due) > new Date(b.due))
|
||||||
.map(({format, due}, index) => {
|
.map(({format, due}, index) => (
|
||||||
return (
|
<li className="date-item" key={index}>
|
||||||
<li className="date-item" key={index}>
|
<div className="label">{this.getLabel(format)}</div>
|
||||||
<div className="label">{this.getLabel(format)}</div>
|
<div className="data">{this.getDate(due)}</div>
|
||||||
<div className="data">{this.getDate(due)}</div>
|
</li>
|
||||||
</li>
|
));
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initLabelTracker(list) {
|
initLabelTracker(list) {
|
||||||
@@ -51,7 +49,7 @@ class DueDates extends React.Component {
|
|||||||
return labels.reduce((accumulator, key) => {
|
return labels.reduce((accumulator, key) => {
|
||||||
accumulator[key] = 0;
|
accumulator[key] = 0;
|
||||||
return accumulator;
|
return accumulator;
|
||||||
}, {})
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderList() {
|
renderList() {
|
||||||
@@ -73,6 +71,6 @@ class DueDates extends React.Component {
|
|||||||
|
|
||||||
DueDates.propTypes = {
|
DueDates.propTypes = {
|
||||||
dates: PropTypes.array.isRequired
|
dates: PropTypes.array.isRequired
|
||||||
}
|
};
|
||||||
|
|
||||||
export default DueDates;
|
export default DueDates;
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
const exGrades = [
|
const exGrades = [
|
||||||
{
|
{
|
||||||
'assignment_type':'Exam',
|
assignment_type: 'Exam',
|
||||||
'total_possible':6.0,
|
total_possible: 6.0,
|
||||||
'total_earned':3.0
|
total_earned: 3.0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'assignment_type':'Homework',
|
assignment_type: 'Homework',
|
||||||
'total_possible':5.0,
|
total_possible: 5.0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'assignment_type':'Homework',
|
assignment_type: 'Homework',
|
||||||
'total_possible':11.0,
|
total_possible: 11.0,
|
||||||
'total_earned':0.0
|
total_earned: 0.0
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -26,7 +27,7 @@ class GradeTable extends React.Component {
|
|||||||
getTableGroup(type, groupIndex) {
|
getTableGroup(type, groupIndex) {
|
||||||
const {grades} = this.props;
|
const {grades} = this.props;
|
||||||
const groupData = grades.filter(value => {
|
const groupData = grades.filter(value => {
|
||||||
if (value['assignment_type'] === type) {
|
if (value.assignment_type === type) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -68,15 +69,15 @@ class GradeTable extends React.Component {
|
|||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
GradeTable.propTypes = {
|
GradeTable.propTypes = {
|
||||||
assignmentTypes: PropTypes.array.isRequired,
|
assignmentTypes: PropTypes.array.isRequired,
|
||||||
grades: PropTypes.array.isRequired,
|
grades: PropTypes.array.isRequired,
|
||||||
passingGrade: PropTypes.number.isRequired,
|
passingGrade: PropTypes.number.isRequired,
|
||||||
percentGrade: PropTypes.number.isRequired
|
percentGrade: PropTypes.number.isRequired
|
||||||
}
|
};
|
||||||
|
|
||||||
export default GradeTable;
|
export default GradeTable;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ function arrayToObject(array) {
|
|||||||
const key = Object.keys(obj)[0];
|
const key = Object.keys(obj)[0];
|
||||||
accumulator[key] = obj[key];
|
accumulator[key] = obj[key];
|
||||||
return accumulator;
|
return accumulator;
|
||||||
}, {})
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
function countByType(type, assignments) {
|
function countByType(type, assignments) {
|
||||||
@@ -24,7 +24,7 @@ function countByType(type, assignments) {
|
|||||||
if (format === type) {
|
if (format === type) {
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,18 +34,16 @@ function getActiveUserString(count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getAssignmentCounts(types, assignments) {
|
function getAssignmentCounts(types, assignments) {
|
||||||
const countsArray = types.map((type) => {
|
const countsArray = types.map((type) => ({
|
||||||
return {
|
[type]: countByType(type, assignments)
|
||||||
[type]: countByType(type, assignments)
|
}));
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return arrayToObject(countsArray);
|
return arrayToObject(countsArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStreakIcons(count) {
|
function getStreakIcons(count) {
|
||||||
return Array.apply(null, {length: count}).map((e, i) => (
|
return Array.apply(null, {length: count}).map((e, i) => (
|
||||||
<span className="fa fa-trophy" aria-hidden="true" key={i}></span>
|
<span className="fa fa-trophy" aria-hidden="true" key={i} />
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +54,7 @@ function getStreakEncouragement(count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getStreakString(count) {
|
function getStreakString(count) {
|
||||||
const unit = (count ===1) ? 'week' : 'weeks';
|
const unit = (count === 1) ? 'week' : 'weeks';
|
||||||
return (count > 0) ? `Active ${count} ${unit} in a row` : false;
|
return (count > 0) ? `Active ${count} ${unit} in a row` : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,16 +62,14 @@ export function LearnerAnalyticsDashboard(props) {
|
|||||||
const {
|
const {
|
||||||
grading_policy, grades, schedule, schedule_raw, week_streak, weekly_active_users, discussion_info, profile_images, passing_grade, percent_grade
|
grading_policy, grades, schedule, schedule_raw, week_streak, weekly_active_users, discussion_info, profile_images, passing_grade, percent_grade
|
||||||
} = props;
|
} = props;
|
||||||
const gradeBreakdown = grading_policy.GRADER.map(({type, weight}, index) => {
|
const gradeBreakdown = grading_policy.GRADER.map(({type, weight}, index) => ({
|
||||||
return {
|
value: weight,
|
||||||
value: weight,
|
label: type,
|
||||||
label: type,
|
sliceIndex: index + 1
|
||||||
sliceIndex: index + 1
|
}));
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get a list of assignment types minus duplicates
|
// Get a list of assignment types minus duplicates
|
||||||
const assignments = gradeBreakdown.map(value => value['label']);
|
const assignments = gradeBreakdown.map(value => value.label);
|
||||||
const assignmentTypes = [...new Set(assignments)];
|
const assignmentTypes = [...new Set(assignments)];
|
||||||
const assignmentCounts = getAssignmentCounts(assignmentTypes, schedule);
|
const assignmentCounts = getAssignmentCounts(assignmentTypes, schedule);
|
||||||
|
|
||||||
@@ -86,23 +82,23 @@ export function LearnerAnalyticsDashboard(props) {
|
|||||||
<div className="analytics-group">
|
<div className="analytics-group">
|
||||||
<h2 className="group-heading">Grading</h2>
|
<h2 className="group-heading">Grading</h2>
|
||||||
{gradeBreakdown
|
{gradeBreakdown
|
||||||
&& <h3 className="section-heading">Weight</h3>
|
&& <h3 className="section-heading">Weight</h3>}
|
||||||
}
|
|
||||||
{gradeBreakdown
|
{gradeBreakdown
|
||||||
&& <div className="grading-weight-wrapper">
|
&& (
|
||||||
<div className="chart-wrapper">
|
<div className="grading-weight-wrapper">
|
||||||
<CircleChart
|
<div className="chart-wrapper">
|
||||||
slices={gradeBreakdown}
|
<CircleChart
|
||||||
centerHole={true}
|
slices={gradeBreakdown}
|
||||||
sliceBorder={{
|
centerHole
|
||||||
strokeColor: '#f5f5f5',
|
sliceBorder={{
|
||||||
strokeWidth: 2
|
strokeColor: '#f5f5f5',
|
||||||
}}
|
strokeWidth: 2
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<CircleChartLegend data={gradeBreakdown} />
|
||||||
</div>
|
</div>
|
||||||
<CircleChartLegend data={gradeBreakdown} />
|
)}
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
<h3 className="section-heading">Graded Assignments</h3>
|
<h3 className="section-heading">Graded Assignments</h3>
|
||||||
{/* TODO: LEARNER-3854: If implementing Learner Analytics, rename to graded-assignments-wrapper. */}
|
{/* TODO: LEARNER-3854: If implementing Learner Analytics, rename to graded-assignments-wrapper. */}
|
||||||
@@ -125,8 +121,7 @@ export function LearnerAnalyticsDashboard(props) {
|
|||||||
<div className="week-streak-wrapper">
|
<div className="week-streak-wrapper">
|
||||||
<h3 className="section-heading">Week streak</h3>
|
<h3 className="section-heading">Week streak</h3>
|
||||||
{week_streak > 0
|
{week_streak > 0
|
||||||
&& <div className="streak-icon-wrapper" aria-hidden="true">{getStreakIcons(week_streak)}</div>
|
&& <div className="streak-icon-wrapper" aria-hidden="true">{getStreakIcons(week_streak)}</div>}
|
||||||
}
|
|
||||||
<p>{getStreakString(week_streak)}</p>
|
<p>{getStreakString(week_streak)}</p>
|
||||||
<p className="streak-encouragement">{getStreakEncouragement(week_streak)}</p>
|
<p className="streak-encouragement">{getStreakEncouragement(week_streak)}</p>
|
||||||
<ul className="streak-criteria">
|
<ul className="streak-criteria">
|
||||||
@@ -136,8 +131,8 @@ export function LearnerAnalyticsDashboard(props) {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className="active-users-wrapper">
|
<div className="active-users-wrapper">
|
||||||
<span className="fa fa-user count-icon" aria-hidden="true"></span>
|
<span className="fa fa-user count-icon" aria-hidden="true" />
|
||||||
<span className="user-count">{weekly_active_users.toLocaleString('en', {useGrouping:true})}</span>
|
<span className="user-count">{weekly_active_users.toLocaleString('en', {useGrouping: true})}</span>
|
||||||
<p className="label">{getActiveUserString(weekly_active_users)}</p>
|
<p className="label">{getActiveUserString(weekly_active_users)}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ class EnterpriseLearnerPortalModal extends React.Component {
|
|||||||
gettext('You have access to the {enterpriseName} dashboard'),
|
gettext('You have access to the {enterpriseName} dashboard'),
|
||||||
{
|
{
|
||||||
enterpriseName: this.props.enterpriseCustomerName,
|
enterpriseName: this.props.enterpriseCustomerName,
|
||||||
}
|
},
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
@@ -125,7 +125,7 @@ class EnterpriseLearnerPortalModal extends React.Component {
|
|||||||
gettext('To access the courses available to you through {enterpriseName}, visit the {enterpriseName} dashboard.'),
|
gettext('To access the courses available to you through {enterpriseName}, visit the {enterpriseName} dashboard.'),
|
||||||
{
|
{
|
||||||
enterpriseName: this.props.enterpriseCustomerName,
|
enterpriseName: this.props.enterpriseCustomerName,
|
||||||
}
|
},
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-4 d-flex align-content-center justify-content-end">
|
<div className="mt-4 d-flex align-content-center justify-content-end">
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ describe('Course Enroll View', () => {
|
|||||||
view.enrollSuccess();
|
view.enrollSuccess();
|
||||||
|
|
||||||
expect(CourseEnrollView.redirect).toHaveBeenCalledWith(
|
expect(CourseEnrollView.redirect).toHaveBeenCalledWith(
|
||||||
view.trackSelectionUrl + courseCardModel.get('course_run_key')
|
view.trackSelectionUrl + courseCardModel.get('course_run_key'),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ describe('Course Entitlement View', () => {
|
|||||||
|
|
||||||
it('Courses with an an enroll by date should indicate so on the selection option.', () => {
|
it('Courses with an an enroll by date should indicate so on the selection option.', () => {
|
||||||
const enrollEndSetOptionIndex = entitlementAvailableSessions.findIndex(
|
const enrollEndSetOptionIndex = entitlementAvailableSessions.findIndex(
|
||||||
session => session.enrollment_end !== null
|
session => session.enrollment_end !== null,
|
||||||
);
|
);
|
||||||
const enrollEndSetOption = selectOptions[enrollEndSetOptionIndex];
|
const enrollEndSetOption = selectOptions[enrollEndSetOptionIndex];
|
||||||
expect(enrollEndSetOption && enrollEndSetOption.text.includes('Open until')).toBe(true);
|
expect(enrollEndSetOption && enrollEndSetOption.text.includes('Open until')).toBe(true);
|
||||||
@@ -123,7 +123,7 @@ describe('Course Entitlement View', () => {
|
|||||||
|
|
||||||
it('Currently selected session should be specified in the dropdown options.', () => {
|
it('Currently selected session should be specified in the dropdown options.', () => {
|
||||||
const selectedSessionIndex = entitlementAvailableSessions.findIndex(
|
const selectedSessionIndex = entitlementAvailableSessions.findIndex(
|
||||||
session => initialSessionId === session.session_id
|
session => initialSessionId === session.session_id,
|
||||||
);
|
);
|
||||||
expect(selectOptions[selectedSessionIndex].text.includes('Currently Selected')).toBe(true);
|
expect(selectOptions[selectedSessionIndex].text.includes('Currently Selected')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -61,18 +61,18 @@ describe('Program Progress View', () => {
|
|||||||
|
|
||||||
expect(view.$('.js-subscription-info')[0]).toBeInDOM();
|
expect(view.$('.js-subscription-info')[0]).toBeInDOM();
|
||||||
expect(
|
expect(
|
||||||
view.$('.js-subscription-info .divider-heading').text().trim()
|
view.$('.js-subscription-info .divider-heading').text().trim(),
|
||||||
).toEqual(heading);
|
).toEqual(heading);
|
||||||
expect(
|
expect(
|
||||||
view.$('.js-subscription-info .subscription-section p:nth-child(1)')
|
view.$('.js-subscription-info .subscription-section p:nth-child(1)'),
|
||||||
).toContainHtml(body);
|
).toContainHtml(body);
|
||||||
expect(
|
expect(
|
||||||
view.$('.js-subscription-info .subscription-section p:nth-child(2)')
|
view.$('.js-subscription-info .subscription-section p:nth-child(2)'),
|
||||||
).toContainText(
|
).toContainText(
|
||||||
/Need help\? Check out the.*Learner Help Center.*to troubleshoot issues or contact support/
|
/Need help\? Check out the.*Learner Help Center.*to troubleshoot issues or contact support/,
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
view.$('.js-subscription-info .subscription-section p:nth-child(2) .subscription-link').attr('href')
|
view.$('.js-subscription-info .subscription-section p:nth-child(2) .subscription-link').attr('href'),
|
||||||
).toEqual('/learner');
|
).toEqual('/learner');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -235,18 +235,18 @@ describe('Program Progress View', () => {
|
|||||||
testSubscriptionState(
|
testSubscriptionState(
|
||||||
'pre',
|
'pre',
|
||||||
'Inactive subscription',
|
'Inactive subscription',
|
||||||
'If you had a subscription previously, your payment history is still available'
|
'If you had a subscription previously, your payment history is still available',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render active trial subscription info if subscription is active with trial', () => {
|
it('should render active trial subscription info if subscription is active with trial', () => {
|
||||||
subscriptionData.trial_end = moment().add(3, 'days').utc().format(
|
subscriptionData.trial_end = moment().add(3, 'days').utc().format(
|
||||||
'YYYY-MM-DDTHH:mm:ss[Z]'
|
'YYYY-MM-DDTHH:mm:ss[Z]',
|
||||||
);
|
);
|
||||||
testSubscriptionState(
|
testSubscriptionState(
|
||||||
'active',
|
'active',
|
||||||
'Trial subscription',
|
'Trial subscription',
|
||||||
'View your receipts or modify your subscription'
|
'View your receipts or modify your subscription',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ describe('Program Progress View', () => {
|
|||||||
testSubscriptionState(
|
testSubscriptionState(
|
||||||
'active',
|
'active',
|
||||||
'Active subscription',
|
'Active subscription',
|
||||||
'View your receipts or modify your subscription'
|
'View your receipts or modify your subscription',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -262,7 +262,7 @@ describe('Program Progress View', () => {
|
|||||||
testSubscriptionState(
|
testSubscriptionState(
|
||||||
'inactive',
|
'inactive',
|
||||||
'Inactive subscription',
|
'Inactive subscription',
|
||||||
'Restart your subscription for $100/month. Your payment history is still available'
|
'Restart your subscription for $100/month. Your payment history is still available',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -524,7 +524,7 @@ describe('Program Details View', () => {
|
|||||||
};
|
};
|
||||||
if (trial) {
|
if (trial) {
|
||||||
subscriptionData.trial_end = moment().add(3, 'days').utc().format(
|
subscriptionData.trial_end = moment().add(3, 'days').utc().format(
|
||||||
'YYYY-MM-DDTHH:mm:ss[Z]'
|
'YYYY-MM-DDTHH:mm:ss[Z]',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
view = initView({
|
view = initView({
|
||||||
@@ -580,9 +580,9 @@ describe('Program Details View', () => {
|
|||||||
expect(view.$('.program-heading-title').text()).toEqual('Your Program Journey');
|
expect(view.$('.program-heading-title').text()).toEqual('Your Program Journey');
|
||||||
expect(view.$('.program-heading-message').text().trim()
|
expect(view.$('.program-heading-message').text().trim()
|
||||||
.replace(/\s+/g, ' ')).toEqual(
|
.replace(/\s+/g, ' ')).toEqual(
|
||||||
'Track and plan your progress through the 3 courses in this program. '
|
'Track and plan your progress through the 3 courses in this program. '
|
||||||
+ 'To complete the program, you must earn a verified certificate for each course.',
|
+ 'To complete the program, you must earn a verified certificate for each course.',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render the program heading congratulations message if all courses completed', () => {
|
it('should render the program heading congratulations message if all courses completed', () => {
|
||||||
@@ -598,8 +598,8 @@ describe('Program Details View', () => {
|
|||||||
expect(view.$('.program-heading-title').text()).toEqual('Congratulations!');
|
expect(view.$('.program-heading-title').text()).toEqual('Congratulations!');
|
||||||
expect(view.$('.program-heading-message').text().trim()
|
expect(view.$('.program-heading-message').text().trim()
|
||||||
.replace(/\s+/g, ' ')).toEqual(
|
.replace(/\s+/g, ' ')).toEqual(
|
||||||
'You have successfully completed all the requirements for the Test Course Title Test.',
|
'You have successfully completed all the requirements for the Test Course Title Test.',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render the course list headings', () => {
|
it('should render the course list headings', () => {
|
||||||
@@ -695,7 +695,7 @@ describe('Program Details View', () => {
|
|||||||
testSubscriptionState(
|
testSubscriptionState(
|
||||||
'pre',
|
'pre',
|
||||||
'Start 7-day free trial',
|
'Start 7-day free trial',
|
||||||
'$100/month subscription after trial ends. Cancel anytime.'
|
'$100/month subscription after trial ends. Cancel anytime.',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -704,7 +704,7 @@ describe('Program Details View', () => {
|
|||||||
'active',
|
'active',
|
||||||
'Manage my subscription',
|
'Manage my subscription',
|
||||||
'Active trial ends',
|
'Active trial ends',
|
||||||
true
|
true,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -712,7 +712,7 @@ describe('Program Details View', () => {
|
|||||||
testSubscriptionState(
|
testSubscriptionState(
|
||||||
'active',
|
'active',
|
||||||
'Manage my subscription',
|
'Manage my subscription',
|
||||||
'Your next billing date is'
|
'Your next billing date is',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -720,7 +720,7 @@ describe('Program Details View', () => {
|
|||||||
testSubscriptionState(
|
testSubscriptionState(
|
||||||
'inactive',
|
'inactive',
|
||||||
'Restart my subscription',
|
'Restart my subscription',
|
||||||
'Unlock verified access to all courses for $100/month. Cancel anytime.'
|
'Unlock verified access to all courses for $100/month. Cancel anytime.',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class CollectionListView extends Backbone.View {
|
|||||||
StringUtils.interpolate(this.titleContext.title),
|
StringUtils.interpolate(this.titleContext.title),
|
||||||
HtmlUtils.HTML('</'),
|
HtmlUtils.HTML('</'),
|
||||||
this.titleContext.el,
|
this.titleContext.el,
|
||||||
HtmlUtils.HTML('>')
|
HtmlUtils.HTML('>'),
|
||||||
);
|
);
|
||||||
return titleHtml;
|
return titleHtml;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class ProgramDetailsView extends Backbone.View {
|
|||||||
this.programModel = new Backbone.Model(this.options.programData);
|
this.programModel = new Backbone.Model(this.options.programData);
|
||||||
this.courseData = new Backbone.Model(this.options.courseData);
|
this.courseData = new Backbone.Model(this.options.courseData);
|
||||||
this.certificateCollection = new Backbone.Collection(
|
this.certificateCollection = new Backbone.Collection(
|
||||||
this.options.certificateData
|
this.options.certificateData,
|
||||||
);
|
);
|
||||||
this.subscriptionModel = new SubscriptionModel({
|
this.subscriptionModel = new SubscriptionModel({
|
||||||
context: this.options,
|
context: this.options,
|
||||||
@@ -92,7 +92,7 @@ class ProgramDetailsView extends Backbone.View {
|
|||||||
const totalCount = completedCount + inProgressCount + remainingCount;
|
const totalCount = completedCount + inProgressCount + remainingCount;
|
||||||
const buyButtonUrl = ProgramDetailsView.getUrl(
|
const buyButtonUrl = ProgramDetailsView.getUrl(
|
||||||
this.options.urls.buy_button_url,
|
this.options.urls.buy_button_url,
|
||||||
this.options.programData
|
this.options.programData,
|
||||||
);
|
);
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import Backbone from 'backbone';
|
|||||||
|
|
||||||
import HtmlUtils from 'edx-ui-toolkit/js/utils/html-utils';
|
import HtmlUtils from 'edx-ui-toolkit/js/utils/html-utils';
|
||||||
|
|
||||||
import progressViewTpl from '../../../templates/learner_dashboard//progress_circle_view.underscore';
|
import progressViewTpl from '../../../templates/learner_dashboard/progress_circle_view.underscore';
|
||||||
import progressSegmentTpl from '../../../templates/learner_dashboard/progress_circle_segment.underscore';
|
import progressSegmentTpl from '../../../templates/learner_dashboard/progress_circle_segment.underscore';
|
||||||
|
|
||||||
class ProgressCircleView extends Backbone.View {
|
class ProgressCircleView extends Backbone.View {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
import Backbone from 'backbone';
|
import Backbone from 'backbone';
|
||||||
|
|
||||||
class UnenrollView extends Backbone.View {
|
class UnenrollView extends Backbone.View {
|
||||||
|
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
const defaults = {
|
const defaults = {
|
||||||
el: '.unenroll-modal',
|
el: '.unenroll-modal',
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ function(Backbone, $, AjaxHelpers, TemplateHelpers, CohortsView, CohortCollectio
|
|||||||
if (options && options.selectCohort) {
|
if (options && options.selectCohort) {
|
||||||
cohortsView.$('.cohort-select').val(options.selectCohort.toString()).change();
|
cohortsView.$('.cohort-select').val(options.selectCohort.toString()).change();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
respondToRefresh = function(catCount, dogCount) {
|
respondToRefresh = function(catCount, dogCount) {
|
||||||
@@ -262,8 +261,8 @@ function(Backbone, $, AjaxHelpers, TemplateHelpers, CohortsView, CohortCollectio
|
|||||||
// But upload form should not be visible until toggle is clicked.
|
// But upload form should not be visible until toggle is clicked.
|
||||||
expect(cohortsView.$(fileUploadFormCss).length).toBe(0);
|
expect(cohortsView.$(fileUploadFormCss).length).toBe(0);
|
||||||
uploadCsvToggle = cohortsView.$('.toggle-cohort-management-secondary');
|
uploadCsvToggle = cohortsView.$('.toggle-cohort-management-secondary');
|
||||||
expect(uploadCsvToggle.text()).
|
expect(uploadCsvToggle.text())
|
||||||
toContain('Assign learners to cohorts by uploading a CSV file');
|
.toContain('Assign learners to cohorts by uploading a CSV file');
|
||||||
uploadCsvToggle.click();
|
uploadCsvToggle.click();
|
||||||
// After toggle is clicked, it should be hidden.
|
// After toggle is clicked, it should be hidden.
|
||||||
expect(uploadCsvToggle).toHaveClass('hidden');
|
expect(uploadCsvToggle).toHaveClass('hidden');
|
||||||
|
|||||||
@@ -133,17 +133,17 @@ function(Backbone, $, AjaxHelpers, TemplateHelpers, DiscussionsView, CourseDiscu
|
|||||||
expect($inlineDiscussionsForm.length).toBe(1);
|
expect($inlineDiscussionsForm.length).toBe(1);
|
||||||
expect($courseWideDiscussionsForm.length).toBe(1);
|
expect($courseWideDiscussionsForm.length).toBe(1);
|
||||||
|
|
||||||
expect($courseWideDiscussionsForm.text()).
|
expect($courseWideDiscussionsForm.text())
|
||||||
toContain('Course-Wide Discussion Topics');
|
.toContain('Course-Wide Discussion Topics');
|
||||||
expect($courseWideDiscussionsForm.text()).
|
expect($courseWideDiscussionsForm.text())
|
||||||
toContain('Select the course-wide discussion topics that you want to divide.');
|
.toContain('Select the course-wide discussion topics that you want to divide.');
|
||||||
|
|
||||||
// Should see the inline discussions form and its content
|
// Should see the inline discussions form and its content
|
||||||
expect($inlineDiscussionsForm.length).toBe(1);
|
expect($inlineDiscussionsForm.length).toBe(1);
|
||||||
expect($inlineDiscussionsForm.text()).
|
expect($inlineDiscussionsForm.text())
|
||||||
toContain('Content-Specific Discussion Topics');
|
.toContain('Content-Specific Discussion Topics');
|
||||||
expect($inlineDiscussionsForm.text()).
|
expect($inlineDiscussionsForm.text())
|
||||||
toContain('Specify whether content-specific discussion topics are divided.');
|
.toContain('Specify whether content-specific discussion topics are divided.');
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
|
|||||||
@@ -182,10 +182,10 @@ function($, AjaxHelpers, CertificateInvalidationModel, CertificateInvalidationVi
|
|||||||
view.collection.add(model);
|
view.collection.add(model);
|
||||||
expect(view.$el.find('table tbody tr').length).toBe(3);
|
expect(view.$el.find('table tbody tr').length).toBe(3);
|
||||||
|
|
||||||
expect(view.$el.find('table tbody tr td:contains("' + user + '")').parent().html()).
|
expect(view.$el.find('table tbody tr td:contains("' + user + '")').parent().html())
|
||||||
toMatch(notes);
|
.toMatch(notes);
|
||||||
expect(view.$el.find('table tbody tr td:contains("' + user + '")').parent().html()).
|
expect(view.$el.find('table tbody tr td:contains("' + user + '")').parent().html())
|
||||||
toMatch(user);
|
.toMatch(user);
|
||||||
|
|
||||||
// Remove a model from collection
|
// Remove a model from collection
|
||||||
var collection_model = view.collection.get({id: 2});
|
var collection_model = view.collection.get({id: 2});
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ function($, id, AjaxHelper) {
|
|||||||
dataDownload = window.InstructorDashboard.sections;
|
dataDownload = window.InstructorDashboard.sections;
|
||||||
dataDownload.DataDownloadV2($('#data_download_2'));
|
dataDownload.DataDownloadV2($('#data_download_2'));
|
||||||
window.InstructorDashboard.util.PendingInstructorTasks = function() {
|
window.InstructorDashboard.util.PendingInstructorTasks = function() {
|
||||||
return;
|
|
||||||
};
|
};
|
||||||
requests = AjaxHelper.requests(this);
|
requests = AjaxHelper.requests(this);
|
||||||
$selected = $('<option data-endpoint="api/url/fake"></option>');
|
$selected = $('<option data-endpoint="api/url/fake"></option>');
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
define(['jquery', 'js/instructor_dashboard/student_admin', 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers'],
|
define(['jquery', 'js/instructor_dashboard/student_admin', 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers'],
|
||||||
function($, StudentAdmin, AjaxHelpers) {
|
function($, StudentAdmin, AjaxHelpers) {
|
||||||
// 'js/instructor_dashboard/student_admin'
|
// 'js/instructor_dashboard/student_admin'
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
describe('edx.instructor_dashboard.student_admin.StudentAdmin', function() {
|
describe('edx.instructor_dashboard.student_admin.StudentAdmin', function() {
|
||||||
var studentadmin, dashboardApiUrl, uniqStudentIdentifier, alertMsg;
|
var studentadmin, dashboardApiUrl, uniqStudentIdentifier, alertMsg;
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ function(Backbone, $, _, AjaxHelpers, TemplateHelpers, FieldViewsSpecHelpers, He
|
|||||||
Helpers.expectLoadingErrorIsVisible(accountSettingsView, true);
|
Helpers.expectLoadingErrorIsVisible(accountSettingsView, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('shows loading error when UserPreferencesModel fails to load', function() {
|
it('shows loading error when UserPreferencesModel fails to load', function() {
|
||||||
requests = AjaxHelpers.requests(this);
|
requests = AjaxHelpers.requests(this);
|
||||||
|
|
||||||
@@ -108,7 +107,7 @@ function(Backbone, $, _, AjaxHelpers, TemplateHelpers, FieldViewsSpecHelpers, He
|
|||||||
AjaxHelpers.respondWithJson(requests, Helpers.createAccountSettingsData());
|
AjaxHelpers.respondWithJson(requests, Helpers.createAccountSettingsData());
|
||||||
AjaxHelpers.respondWithJson(requests, Helpers.TIME_ZONE_RESPONSE);
|
AjaxHelpers.respondWithJson(requests, Helpers.TIME_ZONE_RESPONSE);
|
||||||
AjaxHelpers.respondWithJson(requests, Helpers.createUserPreferencesData());
|
AjaxHelpers.respondWithJson(requests, Helpers.createUserPreferencesData());
|
||||||
AjaxHelpers.respondWithJson(requests, {}); // Page viewed analytics event
|
AjaxHelpers.respondWithJson(requests, {}); // Page viewed analytics event
|
||||||
|
|
||||||
var sectionsData = accountSettingsView.options.tabSections.aboutTabSections;
|
var sectionsData = accountSettingsView.options.tabSections.aboutTabSections;
|
||||||
|
|
||||||
@@ -272,7 +271,7 @@ function(Backbone, $, _, AjaxHelpers, TemplateHelpers, FieldViewsSpecHelpers, He
|
|||||||
AjaxHelpers.respondWithJson(requests, Helpers.createAccountSettingsData());
|
AjaxHelpers.respondWithJson(requests, Helpers.createAccountSettingsData());
|
||||||
AjaxHelpers.respondWithJson(requests, Helpers.TIME_ZONE_RESPONSE);
|
AjaxHelpers.respondWithJson(requests, Helpers.TIME_ZONE_RESPONSE);
|
||||||
AjaxHelpers.respondWithJson(requests, Helpers.createUserPreferencesData());
|
AjaxHelpers.respondWithJson(requests, Helpers.createUserPreferencesData());
|
||||||
AjaxHelpers.respondWithJson(requests, {}); // Page viewed analytics event
|
AjaxHelpers.respondWithJson(requests, {}); // Page viewed analytics event
|
||||||
|
|
||||||
sectionsData = accountSettingsView.options.tabSections.aboutTabSections;
|
sectionsData = accountSettingsView.options.tabSections.aboutTabSections;
|
||||||
|
|
||||||
@@ -322,7 +321,7 @@ function(Backbone, $, _, AjaxHelpers, TemplateHelpers, FieldViewsSpecHelpers, He
|
|||||||
title: view.options.title,
|
title: view.options.title,
|
||||||
valueAttribute: view.options.valueAttribute,
|
valueAttribute: view.options.valueAttribute,
|
||||||
helpMessage: '',
|
helpMessage: '',
|
||||||
validValue: Helpers.FIELD_OPTIONS[1][0], // dummy option for dropdown field
|
validValue: Helpers.FIELD_OPTIONS[1][0], // dummy option for dropdown field
|
||||||
invalidValue1: Helpers.FIELD_OPTIONS[2][0], // dummy option for dropdown field
|
invalidValue1: Helpers.FIELD_OPTIONS[2][0], // dummy option for dropdown field
|
||||||
invalidValue2: Helpers.FIELD_OPTIONS[3][0], // dummy option for dropdown field
|
invalidValue2: Helpers.FIELD_OPTIONS[3][0], // dummy option for dropdown field
|
||||||
validationError: 'Nope, this will not do!',
|
validationError: 'Nope, this will not do!',
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ function(Backbone, $, _, AjaxHelpers, TemplateHelpers, UserAccountModel, FieldVi
|
|||||||
AjaxHelpers.respondWithJson(requests, {success: 'true'});
|
AjaxHelpers.respondWithJson(requests, {success: 'true'});
|
||||||
FieldViewsSpecHelpers.expectMessageContains(
|
FieldViewsSpecHelpers.expectMessageContains(
|
||||||
view,
|
view,
|
||||||
"We've sent a message to legolas@woodland.middlearth. " +
|
"We've sent a message to legolas@woodland.middlearth. "
|
||||||
'Click the link in the message to reset your password.'
|
+ 'Click the link in the message to reset your password.'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ function(Backbone, $, _, AjaxHelpers, TemplateHelpers, Helpers, FieldViews, User
|
|||||||
{
|
{
|
||||||
title: 'Basic Account Information',
|
title: 'Basic Account Information',
|
||||||
messageType: 'info',
|
messageType: 'info',
|
||||||
message: 'Your profile settings are managed by Test Enterprise. ' +
|
message: 'Your profile settings are managed by Test Enterprise. '
|
||||||
'Contact your administrator or <a href="https://support.edx.org/">edX Support</a> for help.',
|
+ 'Contact your administrator or <a href="https://support.edx.org/">edX Support</a> for help.',
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
view: new FieldViews.ReadonlyFieldView({
|
view: new FieldViews.ReadonlyFieldView({
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user