TNL-1900 Implement teams header component
This commit is contained in:
@@ -6,7 +6,7 @@ define(["jquery", "teams/js/teams_tab_factory"],
|
||||
var teamsTab;
|
||||
|
||||
beforeEach(function() {
|
||||
setFixtures("<div class='team-tab-content'></div>");
|
||||
setFixtures('<section class="teams-content"></section>');
|
||||
teamsTab = new TeamsTabFactory();
|
||||
});
|
||||
|
||||
@@ -14,6 +14,9 @@ define(["jquery", "teams/js/teams_tab_factory"],
|
||||
expect($("body").text()).toContain("This is the new Teams tab");
|
||||
});
|
||||
|
||||
it("displays a header", function() {
|
||||
expect($("body").html()).toContain("Course teams are organized");
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
|
||||
define(['jquery', 'teams/js/views/teams_tab'],
|
||||
define(['jquery','teams/js/views/teams_tab'],
|
||||
function ($, TeamsTabView) {
|
||||
return function () {
|
||||
var view = new TeamsTabView({
|
||||
el: $('.team-tab-content')
|
||||
el: $('.teams-content')
|
||||
});
|
||||
view.render();
|
||||
};
|
||||
|
||||
@@ -1,14 +1,31 @@
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
|
||||
define(['backbone', 'underscore', 'text!teams/templates/teams-tab.underscore'],
|
||||
function (Backbone, _, teamsTabTemplate) {
|
||||
var TeamTabView = Backbone.View.extend({
|
||||
render: function() {
|
||||
this.$el.html(_.template(teamsTabTemplate, {}));
|
||||
}
|
||||
});
|
||||
define(['backbone',
|
||||
'underscore',
|
||||
'gettext',
|
||||
'js/components/header/views/header',
|
||||
'js/components/header/models/header',
|
||||
'text!teams/templates/teams-tab.underscore'],
|
||||
function (Backbone, _, gettext, HeaderView, HeaderModel, teamsTabTemplate) {
|
||||
var TeamTabView = Backbone.View.extend({
|
||||
initialize: function() {
|
||||
this.headerModel = new HeaderModel({
|
||||
description: gettext("Course teams are organized into topics created by course instructors. Try to join others in an existing team before you decide to create a new team!"),
|
||||
title: gettext("Teams")
|
||||
});
|
||||
this.headerView = new HeaderView({
|
||||
model: this.headerModel
|
||||
});
|
||||
},
|
||||
|
||||
return TeamTabView;
|
||||
});
|
||||
render: function() {
|
||||
this.$el.html(_.template(teamsTabTemplate, {}));
|
||||
this.$el.prepend(this.headerView.$el);
|
||||
this.headerView.render();
|
||||
}
|
||||
});
|
||||
|
||||
return TeamTabView;
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
|
||||
@@ -11,14 +11,18 @@
|
||||
|
||||
<%include file="/courseware/course_navigation.html" args="active_page='teams'" />
|
||||
|
||||
<div class="team-tab-content"></div>
|
||||
<div class="container">
|
||||
<div class="teams-wrapper">
|
||||
<section class="teams-content">
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%block name="js_extra">
|
||||
<script type="text/javascript">
|
||||
(function (require) {
|
||||
require(['teams/js/teams_tab_factory'], function (TeamsTabFactory) {
|
||||
var pageView = new TeamsTabFactory({
|
||||
});
|
||||
var pageView = new TeamsTabFactory();
|
||||
});
|
||||
}).call(this, require || RequireJS.require);
|
||||
</script>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""HTTP endpoints for the Teams API."""
|
||||
|
||||
from django.shortcuts import render_to_response
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from courseware.courses import get_course_with_access, has_access
|
||||
from django.http import Http404
|
||||
from django.conf import settings
|
||||
|
||||
17
lms/static/js/components/header/models/header.js
Normal file
17
lms/static/js/components/header/models/header.js
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* A generic header model.
|
||||
*/
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(['backbone'], function (Backbone) {
|
||||
var HeaderModel = Backbone.Model.extend({
|
||||
defaults: {
|
||||
'title': '',
|
||||
'description': '',
|
||||
'breadcrumbs': null
|
||||
}
|
||||
});
|
||||
|
||||
return HeaderModel;
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
24
lms/static/js/components/header/views/header.js
Normal file
24
lms/static/js/components/header/views/header.js
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* A generic header view class.
|
||||
*/
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(['backbone', 'text!templates/components/header/header.underscore'],
|
||||
function (Backbone, headerTemplate) {
|
||||
var HeaderView = Backbone.View.extend({
|
||||
initialize: function (options) {
|
||||
this.template = _.template(headerTemplate);
|
||||
this.listenTo(this.model, 'change', this.render);
|
||||
this.render();
|
||||
},
|
||||
|
||||
render: function () {
|
||||
var json = this.model.attributes;
|
||||
this.$el.html(this.template(json));
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
return HeaderView;
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
58
lms/static/js/spec/components/header/header_spec.js
Normal file
58
lms/static/js/spec/components/header/header_spec.js
Normal file
@@ -0,0 +1,58 @@
|
||||
(function (define) {
|
||||
'use strict';
|
||||
|
||||
define(['jquery',
|
||||
'underscore',
|
||||
'js/components/header/views/header',
|
||||
'js/components/header/models/header'
|
||||
],
|
||||
function($, _, HeaderView, HeaderModel) {
|
||||
|
||||
describe('header component view', function () {
|
||||
var model, view;
|
||||
|
||||
var testBreadcrumbs = function (breadcrumbs) {
|
||||
model.set('breadcrumbs', breadcrumbs);
|
||||
expect(view.$el.html()).toContain('<nav class="breadcrumbs">');
|
||||
_.each(view.$('.nav-item'), function (el, index) {
|
||||
expect($(el).attr('href')).toEqual(breadcrumbs[index].url);
|
||||
expect($(el).text()).toEqual(breadcrumbs[index].title);
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
model = new HeaderModel({
|
||||
title: 'Test title',
|
||||
description: 'Test description'
|
||||
});
|
||||
view = new HeaderView({
|
||||
model: model
|
||||
});
|
||||
});
|
||||
|
||||
it('can render itself', function () {
|
||||
expect(view.$el.text()).toContain('Test title');
|
||||
expect(view.$el.text()).toContain('Test description');
|
||||
});
|
||||
|
||||
it('does not show breadcrumbs by default', function () {
|
||||
expect(view.$el.html()).not.toContain('<nav class="breadcrumbs">');
|
||||
});
|
||||
|
||||
it('shows breadcrumbs if they are supplied', function () {
|
||||
testBreadcrumbs([
|
||||
{url: 'url1', title: 'Crumb 1'},
|
||||
{url: 'url2', title: 'Crumb 2'}
|
||||
]);
|
||||
testBreadcrumbs([{url: 'url1', title: 'Crumb 1'}]);
|
||||
});
|
||||
|
||||
it('renders itself when its model changes', function () {
|
||||
expect(view.$el.text()).toContain('Test title');
|
||||
model.set('title', 'Changed title');
|
||||
expect(view.$el.text()).toContain('Changed title');
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}).call(this, define || RequireJS.define);
|
||||
@@ -578,6 +578,7 @@
|
||||
define([
|
||||
// Run the LMS tests
|
||||
'lms/include/teams/js/spec/teams_factory_spec.js',
|
||||
'lms/include/js/spec/components/header/header_spec.js',
|
||||
'lms/include/js/spec/photocapture_spec.js',
|
||||
'lms/include/js/spec/staff_debug_actions_spec.js',
|
||||
'lms/include/js/spec/views/notification_spec.js',
|
||||
|
||||
@@ -91,6 +91,7 @@ fixture_paths:
|
||||
- templates/student_profile
|
||||
- templates/verify_student
|
||||
- templates/file-upload.underscore
|
||||
- templates/components/header
|
||||
- js/fixtures/edxnotes
|
||||
- js/fixtures/search
|
||||
- templates/search
|
||||
|
||||
14
lms/templates/components/header/header.underscore
Normal file
14
lms/templates/components/header/header.underscore
Normal file
@@ -0,0 +1,14 @@
|
||||
<header class="page-header has-secondary">
|
||||
<div class="page-header-main">
|
||||
<% if (breadcrumbs !== null && breadcrumbs.length > 0) { %>
|
||||
<nav class="breadcrumbs">
|
||||
<% _.each(breadcrumbs, function (breadcrumb) { %>
|
||||
<a class="nav-item" href="<%= breadcrumb.url %>"><%- breadcrumb.title %></a>
|
||||
<span class="icon fa-angle-right" aria-hidden="true"></span>
|
||||
<% }) %>
|
||||
</nav>
|
||||
<% } %>
|
||||
<h2 class="page-title"><%- title %></h2>
|
||||
<p class="page-description"><%- description %></p>
|
||||
</div>
|
||||
</header>
|
||||
Reference in New Issue
Block a user