Merge pull request #12558 from edx/schen/ECOM-4218
ECOM-4218 Draft 1 for Course Cards on program details page
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
],
|
||||
function(ProgramDetailsView) {
|
||||
return function (options) {
|
||||
var ProgramDetails = new ProgramDetailsView(options);
|
||||
var ProgramDetails = new ProgramDetailsView(options.programData);
|
||||
return ProgramDetails;
|
||||
};
|
||||
});
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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('</'),
|
||||
this.titleContext.el,
|
||||
HtmlUtils.HTML('>'));
|
||||
return titleHtml;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
35
lms/static/js/learner_dashboard/views/course_card_view.js
Normal file
35
lms/static/js/learner_dashboard/views/course_card_view.js
Normal file
@@ -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);
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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('<div class="test-container"><div class="program-cards-container"></div></div>');
|
||||
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('<div class="test-container"><div class="program-cards-container"></div></div>');
|
||||
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);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -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('<div class="course-card card"></div>');
|
||||
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);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -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',
|
||||
|
||||
@@ -5,3 +5,4 @@
|
||||
@import 'views/program-list';
|
||||
@import 'views/program-details';
|
||||
@import 'elements/program-card';
|
||||
@import 'elements/course-card';
|
||||
|
||||
8
lms/static/sass/elements/_course-card.scss
Normal file
8
lms/static/sass/elements/_course-card.scss
Normal file
@@ -0,0 +1,8 @@
|
||||
.header-img{
|
||||
@include float(left);
|
||||
margin-right:20px;
|
||||
}
|
||||
.course-card{
|
||||
height: 250px;
|
||||
margin-top:20px;
|
||||
}
|
||||
13
lms/templates/learner_dashboard/course_card.underscore
Normal file
13
lms/templates/learner_dashboard/course_card.underscore
Normal file
@@ -0,0 +1,13 @@
|
||||
<img class="header-img" src="<%- image_url %>" alt="<%- display_name %>"/>
|
||||
<div class="course-details">
|
||||
<h3 class="course-title"><%- display_name %></h3>
|
||||
<p class="course-key"><%- key %></p>
|
||||
<% if(enrollment_status){ %>
|
||||
<span class="enrollment-info"><%- course_start %> - <%-course_end %></span>
|
||||
<a href="<%- courseware_url %>" class="course-link cta"><%- gettext('View Course') %></a>
|
||||
<% }else{ %>
|
||||
<span class="enrollment-info"><%- gettext('Not Yet Enrolled') %></span>
|
||||
<a href="<%- marketing_url %>" class="course-link cta"><%- gettext('Learn More') %></a>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="action-msg-view"></div>
|
||||
@@ -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}'
|
||||
});
|
||||
</%static:require_module>
|
||||
</%block>
|
||||
@@ -27,7 +27,6 @@ ProgramListFactory({
|
||||
|
||||
<main id="main" aria-label="Content" tabindex="-1">
|
||||
<div class="program-list-wrapper grid-container">
|
||||
<h2 class="sr-only">${_("Your Programs")}</h2>
|
||||
<div class="program-cards-container col"></div>
|
||||
<div class="sidebar col col-last"></div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user