diff --git a/lms/static/js/learner_dashboard/models/course_card_model.js b/lms/static/js/learner_dashboard/models/course_card_model.js index 1c328eacf9ea..59eff0747083 100644 --- a/lms/static/js/learner_dashboard/models/course_card_model.js +++ b/lms/static/js/learner_dashboard/models/course_card_model.js @@ -1,6 +1,5 @@ /* globals gettext */ -import _ from 'underscore'; import Backbone from 'backbone'; import DateUtils from 'edx-ui-toolkit/js/utils/date-utils'; @@ -18,7 +17,7 @@ class CourseCardModel extends Backbone.Model { } getCourseRun(course) { - const enrolledCourseRun = _.findWhere(course.course_runs, { is_enrolled: true }); + const enrolledCourseRun = course.course_runs.find(run => run.is_enrolled); const openEnrollmentCourseRuns = this.getEnrollableCourseRuns(); let desiredCourseRun; @@ -41,7 +40,7 @@ class CourseCardModel extends Backbone.Model { isEnrolledInSession() { // Returns true if the user is currently enrolled in a session of the course - return _.findWhere(this.context.course_runs, { is_enrolled: true }) !== undefined; + return this.context.course_runs.find(run => run.is_enrolled) !== undefined; } static getUnselectedCourseRun(courseRuns) { @@ -62,12 +61,12 @@ class CourseCardModel extends Backbone.Model { } getEnrollableCourseRuns() { - const rawCourseRuns = _.where(this.context.course_runs, { - is_enrollment_open: true, - is_enrolled: false, - is_course_ended: false, - status: 'published', - }); + const rawCourseRuns = this.context.course_runs.filter(run => ( + run.is_enrollment_open && + !run.is_enrolled && + !run.is_course_ended && + run.status === 'published' + )); // Deep copy to avoid mutating this.context. const enrollableCourseRuns = $.extend(true, [], rawCourseRuns); @@ -75,27 +74,25 @@ class CourseCardModel extends Backbone.Model { // These are raw course runs from the server. The start // dates are ISO-8601 formatted strings that need to be // prepped for display. - _.each(enrollableCourseRuns, (courseRun) => { - // eslint-disable-next-line no-param-reassign - courseRun.start_date = CourseCardModel.formatDate(courseRun.start); - // eslint-disable-next-line no-param-reassign - courseRun.end_date = CourseCardModel.formatDate(courseRun.end); - - // This is used to render the date when selecting a course run to enroll in - // eslint-disable-next-line no-param-reassign - courseRun.dateString = this.formatDateString(courseRun); + enrollableCourseRuns.forEach((courseRun) => { + Object.assign(courseRun, { + start_date: CourseCardModel.formatDate(courseRun.start), + end_date: CourseCardModel.formatDate(courseRun.end), + // This is used to render the date when selecting a course run to enroll in + dateString: this.formatDateString(courseRun), + }); }); return enrollableCourseRuns; } getUpcomingCourseRuns() { - return _.where(this.context.course_runs, { - is_enrollment_open: false, - is_enrolled: false, - is_course_ended: false, - status: 'published', - }); + return this.context.course_runs.filter(run => ( + !run.is_enrollment_open && + !run.is_enrolled && + !run.is_course_ended && + run.status === 'published' + )); } static formatDate(date, userPreferences) { @@ -117,11 +114,9 @@ class CourseCardModel extends Backbone.Model { static getCertificatePriceString(run) { if ('seats' in run && run.seats.length) { // eslint-disable-next-line consistent-return - const upgradeableSeats = _.filter(run.seats, (seat) => { + const upgradeableSeats = run.seats.filter((seat) => { const upgradeableSeatTypes = ['verified', 'professional', 'no-id-professional', 'credit']; - if (upgradeableSeatTypes.indexOf(seat.type) >= 0) { - return seat; - } + return upgradeableSeatTypes.indexOf(seat.type) >= 0; }); if (upgradeableSeats.length > 0) { const upgradeableSeat = upgradeableSeats[0]; @@ -224,12 +219,13 @@ class CourseCardModel extends Backbone.Model { } updateCourseRun(courseRunKey) { - const selectedCourseRun = _.findWhere(this.get('course_runs'), { key: courseRunKey }); + const selectedCourseRun = this.get('course_runs').find(run => run.key === courseRunKey); if (selectedCourseRun) { // Update the current context to set the course run to the enrolled state - _.each(this.context.course_runs, (run) => { - // eslint-disable-next-line no-param-reassign - if (run.key === selectedCourseRun.key) run.is_enrolled = true; + this.context.course_runs.forEach((run) => { + Object.assign(run, { + is_enrolled: run.is_enrolled || run.key === selectedCourseRun.key, + }); }); this.setActiveCourseRun(selectedCourseRun); } diff --git a/lms/static/js/learner_dashboard/spec/course_entitlement_view_spec.js b/lms/static/js/learner_dashboard/spec/course_entitlement_view_spec.js index 253a6acfaa96..7a65058a9dd3 100644 --- a/lms/static/js/learner_dashboard/spec/course_entitlement_view_spec.js +++ b/lms/static/js/learner_dashboard/spec/course_entitlement_view_spec.js @@ -1,7 +1,5 @@ /* globals setFixtures */ -import _ from 'underscore'; - import CourseEntitlementView from '../views/course_entitlement_view'; describe('Course Entitlement View', () => { @@ -78,13 +76,13 @@ describe('Course Entitlement View', () => { }); it('Self paced courses should have visual indication in the selection option.', () => { - const selfPacedOptionIndex = _.findIndex(entitlementAvailableSessions, session => session.pacing_type === 'self_paced'); + const selfPacedOptionIndex = entitlementAvailableSessions.findIndex(session => session.pacing_type === 'self_paced'); const selfPacedOption = selectOptions[selfPacedOptionIndex]; expect(selfPacedOption && selfPacedOption.text.includes('(Self-paced)')).toBe(true); }); it('Courses with an an enroll by date should indicate so on the selection option.', () => { - const enrollEndSetOptionIndex = _.findIndex(entitlementAvailableSessions, + const enrollEndSetOptionIndex = entitlementAvailableSessions.findIndex( session => session.enrollment_end !== null); const enrollEndSetOption = selectOptions[enrollEndSetOptionIndex]; expect(enrollEndSetOption && enrollEndSetOption.text.includes('Open until')).toBe(true); @@ -123,7 +121,7 @@ describe('Course Entitlement View', () => { }); it('Currently selected session should be specified in the dropdown options.', () => { - const selectedSessionIndex = _.findIndex(entitlementAvailableSessions, + const selectedSessionIndex = entitlementAvailableSessions.findIndex( session => initialSessionId === session.session_id); expect(selectOptions[selectedSessionIndex].text.includes('Currently Selected')).toBe(true); }); diff --git a/lms/static/js/learner_dashboard/views/certificate_list_view.js b/lms/static/js/learner_dashboard/views/certificate_list_view.js index 3951315aae2e..ea754eb445c5 100644 --- a/lms/static/js/learner_dashboard/views/certificate_list_view.js +++ b/lms/static/js/learner_dashboard/views/certificate_list_view.js @@ -1,11 +1,12 @@ -import _ from 'underscore'; import Backbone from 'backbone'; +import HtmlUtils from 'edx-ui-toolkit/js/utils/html-utils'; + import certificateTpl from '../../../templates/learner_dashboard/certificate_list.underscore'; class CertificateListView extends Backbone.View { initialize(options) { - this.tpl = _.template(certificateTpl); + this.tpl = HtmlUtils.template(certificateTpl); this.title = options.title || false; this.render(); } @@ -16,7 +17,7 @@ class CertificateListView extends Backbone.View { certificateList: this.collection.toJSON(), }; - this.$el.html(this.tpl(data)); + HtmlUtils.setHtml(this.$el, this.tpl(data)); } } diff --git a/lms/static/js/learner_dashboard/views/course_enroll_view.js b/lms/static/js/learner_dashboard/views/course_enroll_view.js index b3906e0cfd9e..30be3cb03c19 100644 --- a/lms/static/js/learner_dashboard/views/course_enroll_view.js +++ b/lms/static/js/learner_dashboard/views/course_enroll_view.js @@ -1,4 +1,3 @@ -import _ from 'underscore'; import Backbone from 'backbone'; import HtmlUtils from 'edx-ui-toolkit/js/utils/html-utils'; @@ -56,8 +55,8 @@ class CourseEnrollView extends Backbone.View { this.enrollModel.save({ course_id: courseRunKey, }, { - success: _.bind(this.enrollSuccess, this), - error: _.bind(this.enrollError, this), + success: this.enrollSuccess.bind(this), + error: this.enrollError.bind(this), }); } } diff --git a/lms/static/js/learner_dashboard/views/course_entitlement_view.js b/lms/static/js/learner_dashboard/views/course_entitlement_view.js index 272be27dc442..d1889209b2b6 100644 --- a/lms/static/js/learner_dashboard/views/course_entitlement_view.js +++ b/lms/static/js/learner_dashboard/views/course_entitlement_view.js @@ -2,7 +2,6 @@ import 'bootstrap'; -import _ from 'underscore'; import Backbone from 'backbone'; import moment from 'moment'; @@ -118,10 +117,10 @@ class CourseEntitlementView extends Backbone.View { course_run_id: this.currentSessionSelection, }), statusCode: { - 201: _.bind(this.enrollSuccess, this), - 204: _.bind(this.unenrollSuccess, this), + 201: this.enrollSuccess.bind(this), + 204: this.unenrollSuccess.bind(this), }, - error: _.bind(this.enrollError, this), + error: this.enrollError.bind(this), }); } @@ -371,29 +370,24 @@ class CourseEntitlementView extends Backbone.View { the object with a session_dates attribute representing a formatted date string that highlights the start and end dates of the particular session. */ - const formattedSessionData = sessionData; - let startDate; - let endDate; // Set the date format string to the user's selected language moment.locale(document.documentElement.lang); const dateFormat = moment.localeData().longDateFormat('L').indexOf('DD') > moment.localeData().longDateFormat('L').indexOf('MM') ? 'MMMM D, YYYY' : 'D MMMM, YYYY'; - return _.map(formattedSessionData, (session) => { - const formattedSession = session; - startDate = CourseEntitlementView.formatDate(formattedSession.start, dateFormat); - endDate = CourseEntitlementView.formatDate(formattedSession.end, dateFormat); - formattedSession.enrollment_end = CourseEntitlementView.formatDate( - formattedSession.enrollment_end, - dateFormat); - formattedSession.session_dates = this.courseCardModel.formatDateString({ - start_date: startDate, - advertised_start: session.advertised_start, - end_date: endDate, - pacing_type: formattedSession.pacing_type, + sessionData.forEach((session) => { + Object.assign(session, { + enrollment_end: CourseEntitlementView.formatDate(session.enrollment_end, dateFormat), + session_dates: this.courseCardModel.formatDateString({ + start_date: CourseEntitlementView.formatDate(session.start, dateFormat), + advertised_start: session.advertised_start, + end_date: CourseEntitlementView.formatDate(session.end, dateFormat), + pacing_type: session.pacing_type, + }), }); - return formattedSession; - }, this); + }); + + return sessionData; } static formatDate(date, dateFormat) { diff --git a/lms/static/js/learner_dashboard/views/explore_new_programs_view.js b/lms/static/js/learner_dashboard/views/explore_new_programs_view.js index 436fb89b0c0a..fb8338421217 100644 --- a/lms/static/js/learner_dashboard/views/explore_new_programs_view.js +++ b/lms/static/js/learner_dashboard/views/explore_new_programs_view.js @@ -1,6 +1,7 @@ -import _ from 'underscore'; import Backbone from 'backbone'; +import HtmlUtils from 'edx-ui-toolkit/js/utils/html-utils'; + import exploreTpl from '../../../templates/learner_dashboard/explore_new_programs.underscore'; class ExploreNewProgramsView extends Backbone.View { @@ -12,7 +13,7 @@ class ExploreNewProgramsView extends Backbone.View { } initialize(data) { - this.tpl = _.template(exploreTpl); + this.tpl = HtmlUtils.template(exploreTpl); this.context = data.context; this.$parentEl = $(this.parentEl); @@ -26,7 +27,7 @@ class ExploreNewProgramsView extends Backbone.View { } render() { - this.$el.html(this.tpl(this.context)); + HtmlUtils.setHtml(this.$el, this.tpl(this.context)); } } diff --git a/lms/static/js/learner_dashboard/views/program_card_view.js b/lms/static/js/learner_dashboard/views/program_card_view.js index d3571b2878d4..8e35f4bb878d 100644 --- a/lms/static/js/learner_dashboard/views/program_card_view.js +++ b/lms/static/js/learner_dashboard/views/program_card_view.js @@ -1,9 +1,10 @@ /* globals gettext */ -import _ from 'underscore'; import Backbone from 'backbone'; import picturefill from 'picturefill'; +import HtmlUtils from 'edx-ui-toolkit/js/utils/html-utils'; + import programCardTpl from '../../../templates/learner_dashboard/program_card.underscore'; class ProgramCardView extends Backbone.View { @@ -21,7 +22,7 @@ class ProgramCardView extends Backbone.View { } initialize(data) { - this.tpl = _.template(programCardTpl); + this.tpl = HtmlUtils.template(programCardTpl); this.progressCollection = data.context.progressCollection; if (this.progressCollection) { this.progressModel = this.progressCollection.findWhere({ @@ -32,14 +33,14 @@ class ProgramCardView extends Backbone.View { } render() { - const orgList = _.map(this.model.get('authoring_organizations'), org => gettext(org.key)); + const orgList = this.model.get('authoring_organizations').map(org => gettext(org.key)); const data = $.extend( this.model.toJSON(), this.getProgramProgress(), { orgList: orgList.join(' ') }, ); - this.$el.html(this.tpl(data)); + HtmlUtils.setHtml(this.$el, this.tpl(data)); this.postRender(); } diff --git a/lms/static/js/learner_dashboard/views/progress_circle_view.js b/lms/static/js/learner_dashboard/views/progress_circle_view.js index 3ec35859ac34..cffd0f97d23c 100644 --- a/lms/static/js/learner_dashboard/views/progress_circle_view.js +++ b/lms/static/js/learner_dashboard/views/progress_circle_view.js @@ -1,6 +1,7 @@ -import _ from 'underscore'; import Backbone from 'backbone'; +import HtmlUtils from 'edx-ui-toolkit/js/utils/html-utils'; + import progressViewTpl from '../../../templates/learner_dashboard//progress_circle_view.underscore'; import progressSegmentTpl from '../../../templates/learner_dashboard/progress_circle_segment.underscore'; @@ -12,8 +13,8 @@ class ProgressCircleView extends Backbone.View { this.degrees = 180; this.strokeWidth = 1.2; - this.viewTpl = _.template(progressViewTpl); - this.segmentTpl = _.template(progressSegmentTpl); + this.viewTpl = HtmlUtils.template(progressViewTpl); + this.segmentTpl = HtmlUtils.template(progressSegmentTpl); const progress = this.model.get('progress'); @@ -33,7 +34,7 @@ class ProgressCircleView extends Backbone.View { strokeWidth: this.strokeWidth, }); - this.$el.html(this.viewTpl(data)); + HtmlUtils.setHtml(this.$el, this.viewTpl(data)); } static getDegreeIncrement(total) { diff --git a/lms/static/js/learner_dashboard/views/sidebar_view.js b/lms/static/js/learner_dashboard/views/sidebar_view.js index 0af9b2a394a7..b8b5cb31c936 100644 --- a/lms/static/js/learner_dashboard/views/sidebar_view.js +++ b/lms/static/js/learner_dashboard/views/sidebar_view.js @@ -1,6 +1,7 @@ -import _ from 'underscore'; import Backbone from 'backbone'; +import HtmlUtils from 'edx-ui-toolkit/js/utils/html-utils'; + import NewProgramsView from './explore_new_programs_view'; import sidebarTpl from '../../../templates/learner_dashboard/sidebar.underscore'; @@ -14,12 +15,12 @@ class SidebarView extends Backbone.View { } initialize(data) { - this.tpl = _.template(sidebarTpl); + this.tpl = HtmlUtils.template(sidebarTpl); this.context = data.context; } render() { - this.$el.html(this.tpl(this.context)); + HtmlUtils.setHtml(this.$el, this.tpl(this.context)); this.postRender(); }