diff --git a/lms/djangoapps/teams/static/teams/js/spec/teams_factory_spec.js b/lms/djangoapps/teams/static/teams/js/spec/teams_factory_spec.js
index 628c00ba58..6a4c3b9115 100644
--- a/lms/djangoapps/teams/static/teams/js/spec/teams_factory_spec.js
+++ b/lms/djangoapps/teams/static/teams/js/spec/teams_factory_spec.js
@@ -6,7 +6,7 @@ define(["jquery", "teams/js/teams_tab_factory"],
var teamsTab;
beforeEach(function() {
- setFixtures("
");
+ setFixtures('');
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");
+ });
});
}
);
diff --git a/lms/djangoapps/teams/static/teams/js/teams_tab_factory.js b/lms/djangoapps/teams/static/teams/js/teams_tab_factory.js
index 9b735c651d..1575457033 100644
--- a/lms/djangoapps/teams/static/teams/js/teams_tab_factory.js
+++ b/lms/djangoapps/teams/static/teams/js/teams_tab_factory.js
@@ -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();
};
diff --git a/lms/djangoapps/teams/static/teams/js/views/teams_tab.js b/lms/djangoapps/teams/static/teams/js/views/teams_tab.js
index 5e60e84ecd..27c884d1e8 100644
--- a/lms/djangoapps/teams/static/teams/js/views/teams_tab.js
+++ b/lms/djangoapps/teams/static/teams/js/views/teams_tab.js
@@ -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);
diff --git a/lms/djangoapps/teams/templates/teams/teams.html b/lms/djangoapps/teams/templates/teams/teams.html
index e001a377fe..5bf68019d7 100644
--- a/lms/djangoapps/teams/templates/teams/teams.html
+++ b/lms/djangoapps/teams/templates/teams/teams.html
@@ -11,14 +11,18 @@
<%include file="/courseware/course_navigation.html" args="active_page='teams'" />
-
+
<%block name="js_extra">
diff --git a/lms/djangoapps/teams/views.py b/lms/djangoapps/teams/views.py
index 1d67ba498e..cb6bceef9a 100644
--- a/lms/djangoapps/teams/views.py
+++ b/lms/djangoapps/teams/views.py
@@ -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
diff --git a/lms/static/js/components/header/models/header.js b/lms/static/js/components/header/models/header.js
new file mode 100644
index 0000000000..55eb00c31d
--- /dev/null
+++ b/lms/static/js/components/header/models/header.js
@@ -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);
diff --git a/lms/static/js/components/header/views/header.js b/lms/static/js/components/header/views/header.js
new file mode 100644
index 0000000000..34a2da25d3
--- /dev/null
+++ b/lms/static/js/components/header/views/header.js
@@ -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);
diff --git a/lms/static/js/spec/components/header/header_spec.js b/lms/static/js/spec/components/header/header_spec.js
new file mode 100644
index 0000000000..a41d4d0fb5
--- /dev/null
+++ b/lms/static/js/spec/components/header/header_spec.js
@@ -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('