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 7407db7e20..05eacb8aed 100644 --- a/lms/static/js/learner_dashboard/models/course_card_model.js +++ b/lms/static/js/learner_dashboard/models/course_card_model.js @@ -15,19 +15,46 @@ } }, + getUnselectedRunMode: function(runModes) { + if(runModes && runModes.length > 0){ + return { + course_image_url: runModes[0].course_image_url, + marketing_url: runModes[0].marketing_url, + is_enrollment_open: runModes[0].is_enrollment_open, + enrollment_open_date: runModes[0].enrollment_open_date + }; + } + return {}; + }, + getRunMode: function(runModes){ - //we should populate our model by looking at the run_modes - if (runModes.length > 0){ - if(runModes.length === 1){ - return runModes[0]; + var enrolled_mode = _.findWhere(runModes, {is_enrolled: true}), + openEnrollmentRunModes = this.getEnrollableRunModes(), + desiredRunMode; + //we populate our model by looking at the run_modes + if (enrolled_mode){ + // If we have a run_mode we are already enrolled in, + // return that one always + desiredRunMode = enrolled_mode; + } else if (openEnrollmentRunModes.length > 0){ + if(openEnrollmentRunModes.length === 1){ + desiredRunMode = openEnrollmentRunModes[0]; }else{ - //We need to implement logic here to select the - //most relevant run mode for the student to enroll - return runModes[0]; + desiredRunMode = this.getUnselectedRunMode(openEnrollmentRunModes); } }else{ - return null; - } + desiredRunMode = this.getUnselectedRunMode(runModes); + } + return desiredRunMode; + }, + + getEnrollableRunModes: function(){ + return _.where(this.context.run_modes, + { + is_enrollment_open: true, + is_enrolled: false, + is_course_ended: false + }); }, setActiveRunMode: function(runMode){ @@ -38,18 +65,29 @@ course_key: runMode.course_key, course_url: runMode.course_url || '', display_name: this.context.display_name, + start_date: runMode.start_date, end_date: runMode.end_date, is_enrolled: runMode.is_enrolled, is_enrollment_open: runMode.is_enrollment_open, key: this.context.key, marketing_url: runMode.marketing_url || '', + is_course_ended: runMode.is_course_ended, mode_slug: runMode.mode_slug, run_key: runMode.run_key, - start_date: runMode.start_date + enrollment_open_date: runMode.enrollment_open_date || '', + enrollable_run_modes: this.getEnrollableRunModes() }); } }, + setUnselected: function(){ + //This should be called to reset the model + //back to the unselected state + var unselectedMode = this.getUnselectedRunMode( + this.get('enrollable_run_modes')); + this.setActiveRunMode(unselectedMode); + }, + updateRun: function(runKey){ var selectedRun = _.findWhere(this.get('run_modes'), {run_key: runKey}); if (selectedRun){ diff --git a/lms/static/js/learner_dashboard/models/course_enroll_model.js b/lms/static/js/learner_dashboard/models/course_enroll_model.js index 5a2a26aecb..1977eb9767 100644 --- a/lms/static/js/learner_dashboard/models/course_enroll_model.js +++ b/lms/static/js/learner_dashboard/models/course_enroll_model.js @@ -11,7 +11,7 @@ return Backbone.Model.extend({ defaults: { course_id: '', - optIn: false, + optIn: false } }); } 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 f7d61e9e74..2e56ca6306 100644 --- a/lms/static/js/learner_dashboard/views/course_enroll_view.js +++ b/lms/static/js/learner_dashboard/views/course_enroll_view.js @@ -29,17 +29,14 @@ this.enrollModel = options.enrollModel; this.urlModel = options.urlModel; this.render(); - if(this.urlModel){ + if (this.urlModel){ this.trackSelectionUrl = this.urlModel.get('track_selection_url'); } }, render: function() { var filledTemplate; - if (this.$parentEl && - this.enrollModel && - this.model.get('course_key')){ - + if (this.$parentEl && this.enrollModel){ filledTemplate = this.tpl(this.model.toJSON()); HtmlUtils.setHtml(this.$el, filledTemplate); HtmlUtils.setHtml(this.$parentEl, HtmlUtils.HTML(this.$el)); @@ -48,7 +45,9 @@ handleEnroll: function(){ //Enrollment click event handled here - if (!this.model.get('is_enrolled')){ + if (!this.model.get('course_key')){ + this.$('.select-error').css('visibility','visible'); + } else if (!this.model.get('is_enrolled')){ // actually enroll this.enrollModel.save({ course_id: this.model.get('course_key') @@ -65,6 +64,9 @@ runKey = $(event.target).val(); if (runKey){ this.model.updateRun(runKey); + } else { + //Set back the unselected states + this.model.setUnselected(); } } }, @@ -74,7 +76,7 @@ if (this.trackSelectionUrl) { // Go to track selection page this.redirect( this.trackSelectionUrl + courseKey ); - }else{ + } else { this.model.set({ is_enrolled: true }); diff --git a/lms/static/js/spec/learner_dashboard/course_card_view_spec.js b/lms/static/js/spec/learner_dashboard/course_card_view_spec.js index 6869bbe266..8ddb8c5689 100644 --- a/lms/static/js/spec/learner_dashboard/course_card_view_spec.js +++ b/lms/static/js/spec/learner_dashboard/course_card_view_spec.js @@ -20,7 +20,7 @@ define([ }, run_modes: [{ start_date: 'Apr 25, 2016', - end_date: 'Jun 13, 2016', + end_date: 'Jun 13, 2019', course_key: 'course-v1:ANUx+ANU-ASTRO1x+3T2015', course_url: 'http://localhost:8000/courses/course-v1:edX+DemoX+Demo_Course/info', marketing_url: 'https://www.edx.org/course/astrophysics-exploring', @@ -29,12 +29,15 @@ define([ run_key: '2T2016', course_started: true, is_enrolled: true, - certificate_url: '' + is_course_ended: false, + is_enrollment_open: true, + certificate_url: '', + enrollment_open_date: 'Mar 03, 2016' }] }, setupView = function(data, isEnrolled){ - context.run_modes[0].is_enrolled = isEnrolled; + data.run_modes[0].is_enrolled = isEnrolled; setFixtures('
'); courseCardModel = new CourseCardModel(data); view = new CourseCardView({ @@ -94,6 +97,28 @@ define([ expect(view.$('.certificate-status').length).toEqual(1); expect(view.$('.certificate-status .cta-secondary').attr('href')).toEqual(certUrl); }); + + it('should render the course card with coming soon', function(){ + view.remove(); + context.run_modes[0].is_enrollment_open = false; + setupView(context, false); + expect(view.$('.header-img').attr('src')).toEqual(context.run_modes[0].course_image_url); + expect(view.$('.course-details .course-title').text().trim()).toEqual(context.display_name); + expect(view.$('.course-details .course-title-link').length).toBe(0); + expect(view.$('.course-details .course-text .course-key').html()).toEqual(context.key); + expect(view.$('.course-details .course-text .run-period').length).toBe(0); + expect(view.$('.no-action-message').text().trim()).toBe('Coming Soon'); + expect(view.$('.enroll-open-date').text().trim()) + .toBe(context.run_modes[0].enrollment_open_date); + }); + + it('should render if enrollment_open_date is not provided', function(){ + view.remove(); + context.run_modes[0].is_enrollment_open = true; + delete context.run_modes[0].enrollment_open_date; + setupView(context, false); + validateCourseInfoDisplay(); + }); }); } ); diff --git a/lms/static/js/spec/learner_dashboard/course_enroll_view_spec.js b/lms/static/js/spec/learner_dashboard/course_enroll_view_spec.js index a618e4b029..4ac1d58eb1 100644 --- a/lms/static/js/spec/learner_dashboard/course_enroll_view_spec.js +++ b/lms/static/js/spec/learner_dashboard/course_enroll_view_spec.js @@ -21,9 +21,11 @@ define([ course_url: 'http://localhost:8000/courses/course-v1:edX+DemoX+Demo_Course/info', course_image_url: 'http://test.com/image1', marketing_url: 'http://test.com/image2', + is_course_ended: false, mode_slug: 'audit', run_key: '2T2016', - is_enrolled: false + is_enrolled: false, + is_enrollment_open: true }], multiRunModeList = [{ start_date: 'May 21, 2015', @@ -33,8 +35,10 @@ define([ course_image_url: 'http://test.com/run_2_image_1', marketing_url: 'http://test.com/run_2_image_2', mode_slug: 'verified', + is_course_ended: false, run_key: '1T2015', - is_enrolled: false + is_enrolled: false, + is_enrollment_open: true, },{ start_date: 'Sep 22, 2015', end_date: 'Dec 28, 2015', @@ -42,9 +46,11 @@ define([ course_url: 'http://localhost:8000/courses/course-v1:edX+DemoX+Demo_Course/info', course_image_url: 'http://test.com/run_3_image_1', marketing_url: 'http://test.com/run_3_image_2', + is_course_ended: false, mode_slug: 'verified', run_key: '2T2015', - is_enrolled: false + is_enrolled: false, + is_enrollment_open: true }], context = { display_name: 'Edx Demo course', @@ -117,13 +123,14 @@ define([ it('should render run selection drop down if mulitple run available', function(){ setupView(multiRunModeList); expect(view.$('.run-select').length).toBe(1); - expect(view.$('.run-select').val()).toEqual(multiRunModeList[0].run_key); + expect(view.$('.run-select').val()).toEqual(''); + expect(view.$('.run-select option').length).toBe(3); }); it('should switch run context if dropdown selection changed', function(){ setupView(multiRunModeList); spyOn(courseCardModel, 'updateRun').and.callThrough(); - expect(view.$('.run-select').val()).toEqual(multiRunModeList[0].run_key); + expect(view.$('.run-select').val()).toEqual(''); view.$('.run-select').val(multiRunModeList[1].run_key); view.$('.run-select').trigger("change"); expect(view.$('.run-select').val()).toEqual(multiRunModeList[1].run_key); diff --git a/lms/static/sass/elements/_course-card.scss b/lms/static/sass/elements/_course-card.scss index c1f1ea249b..2c76983ba0 100644 --- a/lms/static/sass/elements/_course-card.scss +++ b/lms/static/sass/elements/_course-card.scss @@ -11,7 +11,7 @@ padding: $baseline/2 $baseline; } - .course-image-link { + .course-image-container{ @include float(left); .header-img { @@ -47,8 +47,26 @@ margin-bottom: $baseline/2; text-transform: uppercase; } - - .run-select-container { + .select-error{ + color: palette(error, base); + margin-bottom: $baseline/4; + font-size: font-size(small); + visibility: hidden; + } + .no-action-message{ + margin-bottom: $baseline/2; + color: palette(grayscale, black); + font-size: font-size(large); + text-align: center; + } + .enrollment-opens{ + text-align: center; + margin-bottom: $baseline/2; + } + .enroll-open-date{ + text-align: center; + } + .run-select-container{ margin-bottom: $baseline; .run-select { @@ -61,8 +79,8 @@ text-align: center; } - .view-course-link { - width: $baseline*10; + .view-course-link{ + min-width: $baseline*10; text-align: center; } } diff --git a/lms/templates/learner_dashboard/course_card.underscore b/lms/templates/learner_dashboard/course_card.underscore index c6e6edb40e..b0b794a23f 100644 --- a/lms/templates/learner_dashboard/course_card.underscore +++ b/lms/templates/learner_dashboard/course_card.underscore @@ -1,20 +1,36 @@