diff --git a/lms/static/js/learner_dashboard/program_details_factory.js b/lms/static/js/learner_dashboard/program_details_factory.js index af90d4ce6a..6073bfadac 100644 --- a/lms/static/js/learner_dashboard/program_details_factory.js +++ b/lms/static/js/learner_dashboard/program_details_factory.js @@ -6,7 +6,7 @@ ], function(ProgramDetailsView) { return function (options) { - var ProgramDetails = new ProgramDetailsView(options); + var ProgramDetails = new ProgramDetailsView(options.programData); return ProgramDetails; }; }); diff --git a/lms/static/js/learner_dashboard/program_list_factory.js b/lms/static/js/learner_dashboard/program_list_factory.js index 9b5cfcf414..06fd63cbdf 100644 --- a/lms/static/js/learner_dashboard/program_list_factory.js +++ b/lms/static/js/learner_dashboard/program_list_factory.js @@ -21,7 +21,11 @@ el: '.program-cards-container', childView: ProgramCardView, collection: new ProgramCollection(options.programsData), - context: options + context: options, + titleContext: { + el: 'h2', + title: 'Your Programs' + } }).render(); new SidebarView({ diff --git a/lms/static/js/learner_dashboard/views/collection_list_view.js b/lms/static/js/learner_dashboard/views/collection_list_view.js index 42812c1946..6ff7970e6b 100644 --- a/lms/static/js/learner_dashboard/views/collection_list_view.js +++ b/lms/static/js/learner_dashboard/views/collection_list_view.js @@ -5,31 +5,35 @@ 'jquery', 'underscore', 'gettext', + 'edx-ui-toolkit/js/utils/string-utils', + 'edx-ui-toolkit/js/utils/html-utils', 'text!../../../templates/learner_dashboard/empty_programs_list.underscore' ], function (Backbone, $, _, gettext, + StringUtils, + HtmlUtils, emptyProgramsListTpl) { return Backbone.View.extend({ initialize: function(data) { this.childView = data.childView; this.context = data.context; + this.titleContext = data.titleContext; }, render: function() { - var childList, tpl; + var childList; if (!this.collection.length) { if (this.context.xseriesUrl) { //Only show the xseries advertising panel if the link is passed in - tpl = _.template(emptyProgramsListTpl); - this.$el.html(tpl(this.context)); + HtmlUtils.setHtml(this.$el, HtmlUtils.template(emptyProgramsListTpl)(this.context)); } - } else { - childList = []; + } else { + childList = []; this.collection.each(function(model) { var child = new this.childView({ @@ -39,8 +43,23 @@ childList.push(child.el); }, this); + if (this.titleContext){ + this.$el.before(HtmlUtils.ensureHtml(this.getTitleHtml()).toString()); + } this.$el.html(childList); } + }, + + getTitleHtml: function(){ + var titleHtml = HtmlUtils.joinHtml( + HtmlUtils.HTML('<'), + this.titleContext.el, + HtmlUtils.HTML(' class="sr-only collection-title">'), + StringUtils.interpolate(this.titleContext.title), + HtmlUtils.HTML('')); + return titleHtml; } }); } diff --git a/lms/static/js/learner_dashboard/views/course_card_view.js b/lms/static/js/learner_dashboard/views/course_card_view.js new file mode 100644 index 0000000000..33ea0b0297 --- /dev/null +++ b/lms/static/js/learner_dashboard/views/course_card_view.js @@ -0,0 +1,35 @@ +;(function (define) { + 'use strict'; + + define(['backbone', + 'jquery', + 'underscore', + 'gettext', + 'edx-ui-toolkit/js/utils/html-utils', + 'text!../../../templates/learner_dashboard/course_card.underscore' + ], + function( + Backbone, + $, + _, + gettext, + HtmlUtils, + pageTpl + ) { + return Backbone.View.extend({ + className: 'course-card card', + + tpl: HtmlUtils.template(pageTpl), + + initialize: function() { + this.render(); + }, + + render: function() { + var filledTemplate = this.tpl(this.model.toJSON()); + HtmlUtils.setHtml(this.$el, filledTemplate); + } + }); + } + ); +}).call(this, define || RequireJS.define); diff --git a/lms/static/js/learner_dashboard/views/program_details_view.js b/lms/static/js/learner_dashboard/views/program_details_view.js index 5211af4853..98dd5cff81 100644 --- a/lms/static/js/learner_dashboard/views/program_details_view.js +++ b/lms/static/js/learner_dashboard/views/program_details_view.js @@ -7,9 +7,21 @@ 'gettext', 'edx-ui-toolkit/js/utils/html-utils', 'js/learner_dashboard/views/program_header_view', + 'js/learner_dashboard/views/collection_list_view', + 'js/learner_dashboard/views/course_card_view', 'text!../../../templates/learner_dashboard/program_details_view.underscore' ], - function(Backbone, $, _, gettext, HtmlUtils, HeaderView, pageTpl) { + function( + Backbone, + $, + _, + gettext, + HtmlUtils, + HeaderView, + CollectionListView, + CourseCardView, + pageTpl + ) { return Backbone.View.extend({ el: '.js-program-details-wrapper', @@ -17,6 +29,9 @@ initialize: function(options) { this.programModel = new Backbone.Model(options); + this.courseCardsCollection = new Backbone.Collection( + this.programModel.get('course_codes') + ); this.render(); }, @@ -29,6 +44,16 @@ this.headerView = new HeaderView({ model: this.programModel }); + new CollectionListView({ + el: '.js-course-list', + childView: CourseCardView, + collection: this.courseCardsCollection, + context: this.programModel.toJSON(), + titleContext: { + el: 'h2', + title: 'Course List' + } + }).render(); } }); } diff --git a/lms/static/js/spec/learner_dashboard/collection_list_view_spec.js b/lms/static/js/spec/learner_dashboard/collection_list_view_spec.js index 0cd6abd256..277b752509 100644 --- a/lms/static/js/spec/learner_dashboard/collection_list_view_spec.js +++ b/lms/static/js/spec/learner_dashboard/collection_list_view_spec.js @@ -124,6 +124,31 @@ define([ $cards = view.$el.find('.program-card'); expect($cards.length).toBe(0); }); + it('should have no title when title not provided', function(){ + var $title; + setFixtures('
'); + view.remove(); + view.render(); + expect(view).toBeDefined(); + $title = view.$el.parent().find('.collection-title'); + expect($title.html()).not.toBeDefined(); + }); + it('should display screen reader header when provided', function(){ + var $title, titleContext = {el:'h2', title:'list start'}; + view.remove(); + setFixtures('
'); + programCollection = new ProgramCollection(context.programsData); + view = new CollectionListView({ + el: '.program-cards-container', + childView: ProgramCardView, + context: {'xseriesUrl': '/programs'}, + collection: programCollection, + titleContext: titleContext + }); + view.render(); + $title = view.$el.parent().find('.collection-title'); + expect($title.html()).toBe(titleContext.title); + }); }); } ); 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 new file mode 100644 index 0000000000..db1fc69397 --- /dev/null +++ b/lms/static/js/spec/learner_dashboard/course_card_view_spec.js @@ -0,0 +1,78 @@ +define([ + 'backbone', + 'jquery', + 'js/learner_dashboard/views/course_card_view' + ], function (Backbone, $, CourseCardView) { + + 'use strict'; + + describe('Course Card View', function () { + var view = null, + courseCardModel, + setupView, + context = { + certificate_url: '', + course_end: 'Jun 13, 2016', + course_modes: [], + course_key: 'course-v1:ANUx+ANU-ASTRO1x+3T2015', + courseware_url: 'http://localhost:8000/courses/course-v1:edX+DemoX+Demo_Course/info', + course_start: 'Apr 25, 2016', + course_started: true, + display_name: 'Astrophysics: Exploring Exoplanets', + image_url: 'https://testimage.com/image', + key: 'ANU-ASTRO1x', + marketing_url: 'https://www.edx.org/course/astrophysics-exploring-exoplanets-anux-anu-astro2x-1', + organization: { + display_name: 'Australian National University', + key: 'ANUx' + }, + run_modes: [{ + course_key: '12313', + mode_slug: 'verified', + run_key: '2T2016', + start_date: '' + }] + }; + + setupView = function(enrollment_status){ + context.enrollment_status = enrollment_status; + setFixtures('
'); + courseCardModel = new Backbone.Model(context); + view = new CourseCardView({ + model: courseCardModel + }); + }; + + beforeEach(function() { + setupView(null); + }); + + afterEach(function() { + view.remove(); + }); + + it('should exist', function() { + expect(view).toBeDefined(); + }); + + it('should render the course card based on the data enrolled', function() { + view.remove(); + setupView('enrolled'); + expect(view.$('.header-img').attr('src')).toEqual(context.image_url); + expect(view.$('.course-details .course-title').html()).toEqual(context.display_name); + expect(view.$('.course-details .course-key').html()).toEqual(context.key); + expect(view.$('.course-details .enrollment-info').html()) + .toEqual(context.course_start + ' - ' + context.course_end); + expect(view.$('.course-details .course-link').attr('href')).toEqual(context.courseware_url); + }); + + it('should render the course card based on the data not enrolled', function() { + expect(view.$('.header-img').attr('src')).toEqual(context.image_url); + expect(view.$('.course-details .course-title').html()).toEqual(context.display_name); + expect(view.$('.course-details .course-key').html()).toEqual(context.key); + expect(view.$('.course-details .enrollment-info').html()).toEqual('Not Yet Enrolled'); + expect(view.$('.course-details .course-link').attr('href')).toEqual(context.marketing_url); + }); + }); + } +); diff --git a/lms/static/js/spec/main.js b/lms/static/js/spec/main.js index 1707029d3c..0bc05cb2fe 100644 --- a/lms/static/js/spec/main.js +++ b/lms/static/js/spec/main.js @@ -729,6 +729,7 @@ 'js/spec/learner_dashboard/program_card_view_spec.js', 'js/spec/learner_dashboard/sidebar_view_spec.js', 'js/spec/learner_dashboard/program_details_header_spec.js', + 'js/spec/learner_dashboard/course_card_view_spec.js', 'js/spec/markdown_editor_spec.js', 'js/spec/navigation_spec.js', 'js/spec/search/search_spec.js', diff --git a/lms/static/sass/_build-learner-dashboard.scss b/lms/static/sass/_build-learner-dashboard.scss index d77a710ebd..17ec0628d6 100644 --- a/lms/static/sass/_build-learner-dashboard.scss +++ b/lms/static/sass/_build-learner-dashboard.scss @@ -5,3 +5,4 @@ @import 'views/program-list'; @import 'views/program-details'; @import 'elements/program-card'; +@import 'elements/course-card'; diff --git a/lms/static/sass/elements/_course-card.scss b/lms/static/sass/elements/_course-card.scss new file mode 100644 index 0000000000..b3746b4b52 --- /dev/null +++ b/lms/static/sass/elements/_course-card.scss @@ -0,0 +1,8 @@ +.header-img{ + @include float(left); + margin-right:20px; +} +.course-card{ + height: 250px; + margin-top:20px; +} diff --git a/lms/templates/learner_dashboard/course_card.underscore b/lms/templates/learner_dashboard/course_card.underscore new file mode 100644 index 0000000000..2ea94e0602 --- /dev/null +++ b/lms/templates/learner_dashboard/course_card.underscore @@ -0,0 +1,13 @@ +<%- display_name %> +
+

<%- display_name %>

+

<%- key %>

+ <% if(enrollment_status){ %> + <%- course_start %> - <%-course_end %> + <%- gettext('View Course') %> + <% }else{ %> + <%- gettext('Not Yet Enrolled') %> + <%- gettext('Learn More') %> + <% } %> +
+
diff --git a/lms/templates/learner_dashboard/programs.html b/lms/templates/learner_dashboard/programs.html index 6603ca3cc4..df89f3e9a9 100644 --- a/lms/templates/learner_dashboard/programs.html +++ b/lms/templates/learner_dashboard/programs.html @@ -18,7 +18,7 @@ ProgramListFactory({ certificatesData: ${credentials | n, dump_js_escaped_json}, userProgress: ${progress | n, dump_js_escaped_json}, xseriesUrl: '${xseries_url | n, js_escaped_string}', - xseriesImage: '${static.url('images/xseries-certificate-visual.png')}' + xseriesImage: '${static.url('images/xseries-certificate-visual.png') | n, js_escaped_string}' }); @@ -27,7 +27,6 @@ ProgramListFactory({
-

${_("Your Programs")}