Show cohorts on the new instructor dashboard
TNL-161 Remove placeholder text
This commit is contained in:
@@ -253,6 +253,7 @@ def _section_membership(course_key, access):
|
||||
'modify_access_url': reverse('modify_access', kwargs={'course_id': course_key.to_deprecated_string()}),
|
||||
'list_forum_members_url': reverse('list_forum_members', kwargs={'course_id': course_key.to_deprecated_string()}),
|
||||
'update_forum_role_membership_url': reverse('update_forum_role_membership', kwargs={'course_id': course_key.to_deprecated_string()}),
|
||||
'cohorts_ajax_url': reverse('cohorts', kwargs={'course_key_string': course_key.to_deprecated_string()}),
|
||||
}
|
||||
return section_data
|
||||
|
||||
|
||||
11
lms/static/js/collections/cohort.js
Normal file
11
lms/static/js/collections/cohort.js
Normal file
@@ -0,0 +1,11 @@
|
||||
(function(Backbone) {
|
||||
var CohortCollection = Backbone.Collection.extend({
|
||||
model : this.CohortModel,
|
||||
comparator: "name",
|
||||
|
||||
parse: function(response) {
|
||||
return response.cohorts;
|
||||
}
|
||||
});
|
||||
this.CohortCollection = CohortCollection;
|
||||
}).call(this, Backbone);
|
||||
11
lms/static/js/models/cohort.js
Normal file
11
lms/static/js/models/cohort.js
Normal file
@@ -0,0 +1,11 @@
|
||||
(function(Backbone) {
|
||||
var CohortModel = Backbone.Model.extend({
|
||||
idAttribute: 'id',
|
||||
defaults: {
|
||||
name: '',
|
||||
user_count: 0
|
||||
}
|
||||
});
|
||||
|
||||
this.CohortModel = CohortModel;
|
||||
}).call(this, Backbone);
|
||||
64
lms/static/js/spec/views/cohorts_spec.js
Normal file
64
lms/static/js/spec/views/cohorts_spec.js
Normal file
@@ -0,0 +1,64 @@
|
||||
describe("Cohorts View", function() {
|
||||
var createMockCohorts, createCohortsView, installTemplateFixture;
|
||||
|
||||
createMockCohorts = function() {
|
||||
return {
|
||||
cohorts: [{
|
||||
id: 1,
|
||||
name: 'Cat Lovers',
|
||||
user_count: 123
|
||||
},{
|
||||
id: 2,
|
||||
name: 'Dog Lovers',
|
||||
user_count: 456
|
||||
}]
|
||||
};
|
||||
};
|
||||
|
||||
createCohortsView = function() {
|
||||
var cohorts, view;
|
||||
cohorts = new CohortCollection(createMockCohorts(), {parse: true});
|
||||
view = new CohortsView({
|
||||
model: cohorts
|
||||
});
|
||||
view.render();
|
||||
return view;
|
||||
};
|
||||
|
||||
installTemplateFixture = function(templateName, templateDirectory) {
|
||||
var templateFixture = readFixtures(templateDirectory + templateName + '.underscore');
|
||||
appendSetFixtures($('<script>', { id: templateName + '-tpl', type: 'text/template' })
|
||||
.text(templateFixture));
|
||||
};
|
||||
|
||||
beforeEach(function() {
|
||||
setFixtures("<div></div>");
|
||||
installTemplateFixture('cohort-editor', 'templates/instructor/instructor_dashboard_2/');
|
||||
installTemplateFixture('cohorts', 'templates/instructor/instructor_dashboard_2/');
|
||||
});
|
||||
|
||||
describe("Cohort Selector", function() {
|
||||
it('has no initial selection', function() {
|
||||
var view = createCohortsView();
|
||||
expect(view.$('.cohort-select').val()).toBe('');
|
||||
expect(view.$('.cohort-management-group-header .title-value').text()).toBe('');
|
||||
});
|
||||
|
||||
it('can select a cohort', function() {
|
||||
var view = createCohortsView();
|
||||
view.$('.cohort-select').val("1").change();
|
||||
expect(view.$('.cohort-select').val()).toBe('1');
|
||||
expect(view.$('.cohort-management-group-header .title-value').text()).toBe('Cat Lovers');
|
||||
expect(view.$('.cohort-management-group-header .group-count').text()).toBe('123');
|
||||
});
|
||||
|
||||
it('can switch cohort', function() {
|
||||
var view = createCohortsView();
|
||||
view.$('.cohort-select').val("1").change();
|
||||
view.$('.cohort-select').val("2").change();
|
||||
expect(view.$('.cohort-select').val()).toBe('2');
|
||||
expect(view.$('.cohort-management-group-header .title-value').text()).toBe('Dog Lovers');
|
||||
expect(view.$('.cohort-management-group-header .group-count').text()).toBe('456');
|
||||
});
|
||||
});
|
||||
});
|
||||
16
lms/static/js/views/cohort_editor.js
Normal file
16
lms/static/js/views/cohort_editor.js
Normal file
@@ -0,0 +1,16 @@
|
||||
(function(Backbone) {
|
||||
var CohortEditorView = Backbone.View.extend({
|
||||
initialize: function() {
|
||||
this.template = _.template($('#cohort-editor-tpl').text());
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.template({
|
||||
cohort: this.model
|
||||
}));
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
this.CohortEditorView = CohortEditorView;
|
||||
}).call(this, Backbone);
|
||||
35
lms/static/js/views/cohorts.js
Normal file
35
lms/static/js/views/cohorts.js
Normal file
@@ -0,0 +1,35 @@
|
||||
(function(Backbone, CohortEditorView) {
|
||||
var CohortsView = Backbone.View.extend({
|
||||
events : {
|
||||
"change .cohort-select": "showCohortEditor"
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
this.template = _.template($('#cohorts-tpl').text());
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.template({
|
||||
cohorts: this.model.models
|
||||
}));
|
||||
return this;
|
||||
},
|
||||
|
||||
getSelectedCohort: function() {
|
||||
var id = this.$('.cohort-select').val();
|
||||
return this.model.get(parseInt(id));
|
||||
},
|
||||
|
||||
showCohortEditor: function(event) {
|
||||
event.preventDefault();
|
||||
var selectedCohort = this.getSelectedCohort();
|
||||
this.editor = new CohortEditorView({
|
||||
el: this.$('.cohort-management-group'),
|
||||
model: selectedCohort
|
||||
});
|
||||
this.editor.render();
|
||||
}
|
||||
});
|
||||
|
||||
this.CohortsView = CohortsView;
|
||||
}).call(this, Backbone, CohortEditorView);
|
||||
@@ -46,11 +46,16 @@ lib_paths:
|
||||
- xmodule_js/src/capa/
|
||||
- xmodule_js/src/video/
|
||||
- xmodule_js/src/xmodule.js
|
||||
- xmodule_js/common_static/js/vendor/underscore-min.js
|
||||
- xmodule_js/common_static/js/vendor/backbone-min.js
|
||||
- js/models/cohort.js
|
||||
- js/collections/cohort.js
|
||||
- js/views/cohort_editor.js
|
||||
- js/views/cohorts.js
|
||||
|
||||
# Paths to source JavaScript files
|
||||
src_paths:
|
||||
- coffee/src
|
||||
- js/src
|
||||
- js
|
||||
|
||||
# Paths to spec (test) JavaScript files
|
||||
@@ -69,7 +74,7 @@ spec_paths:
|
||||
#
|
||||
fixture_paths:
|
||||
- coffee/fixtures
|
||||
- js/fixtures
|
||||
- templates/instructor/instructor_dashboard_2
|
||||
|
||||
# Regular expressions used to exclude *.js files from
|
||||
# appearing in the test runner page.
|
||||
|
||||
1
lms/static/templates
Symbolic link
1
lms/static/templates
Symbolic link
@@ -0,0 +1 @@
|
||||
../templates
|
||||
@@ -0,0 +1,6 @@
|
||||
<header class="cohort-management-group-header">
|
||||
<h3 class="group-header-title">
|
||||
<span class="title-value"><%- cohort.get('name') %></span>
|
||||
<span class="group-count"><%- cohort.get('user_count') %></span>
|
||||
</h3>
|
||||
</header>
|
||||
@@ -0,0 +1,35 @@
|
||||
<h2 class="section-title">
|
||||
<span class="value"><%- gettext('Cohort Management') %></span>
|
||||
<span class="description"></span>
|
||||
</h2>
|
||||
|
||||
<!-- nav -->
|
||||
<% if (cohorts.length > 0) { %>
|
||||
<div class="cohort-management-nav">
|
||||
<form action="" method="post" name="" id="cohort-management-nav-form" class="cohort-management-nav-form">
|
||||
|
||||
<div class="cohort-management-nav-form-select field field-select">
|
||||
<label for="cohort-select" class="label sr">${_("Select a cohort to manage")}</label>
|
||||
|
||||
<select class="input cohort-select" name="cohort-select" id="cohort-select">
|
||||
<option value=""><%- gettext('Select a cohort') %></option>
|
||||
<% _.each(cohorts, function(cohort) { %>
|
||||
<%
|
||||
var label = interpolate(
|
||||
gettext('%(cohort_name)s (%(user_count)s)'),
|
||||
{ cohort_name: cohort.get('name'), user_count: cohort.get('user_count') },
|
||||
true
|
||||
);
|
||||
%>
|
||||
<option value="<%- cohort.get('id') %>"><%- label %></option>
|
||||
<% }); %>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button class="form-submit button action-primary action-view sr"><%- gettext('View cohort group') %></button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- individual group -->
|
||||
<div class="cohort-management-group"></div>
|
||||
<% } %>
|
||||
@@ -33,12 +33,12 @@
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript" src="${static.url('js/vendor/underscore-min.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/vendor/backbone-min.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/vendor/mustache.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.axislabels.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/vendor/jquery-jvectormap-1.1.1/jquery-jvectormap-1.1.1.min.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/vendor/jquery-jvectormap-1.1.1/jquery-jvectormap-world-mill-en.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/course_groups/cohorts.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/vendor/jquery.event.drag-2.2.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/vendor/jquery.event.drop-2.2.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/vendor/slick.core.js')}"></script>
|
||||
@@ -50,6 +50,21 @@
|
||||
<script type="text/javascript" src="${static.url('js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js')}"></script>
|
||||
<%static:js group='module-descriptor-js'/>
|
||||
<%static:js group='instructor_dash'/>
|
||||
|
||||
## Backbone classes declared explicitly until RequireJS is supported
|
||||
<script type="text/javascript" src="${static.url('js/models/cohort.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/collections/cohort.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/views/cohort_editor.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/views/cohorts.js')}"></script>
|
||||
</%block>
|
||||
|
||||
## Include Underscore templates
|
||||
<%block name="header_extras">
|
||||
% for template_name in ["cohorts", "cohort-editor"]:
|
||||
<script type="text/template" id="${template_name}-tpl">
|
||||
<%static:include path="instructor/instructor_dashboard_2/${template_name}.underscore" />
|
||||
</script>
|
||||
% endfor
|
||||
</%block>
|
||||
|
||||
## NOTE that instructor is set as the active page so that the instructor button lights up, even though this is the instructor_2 page.
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<div class="vert-left">
|
||||
<div class="batch-enrollment">
|
||||
<h2> ${_("Batch Enrollment")} </h2>
|
||||
<p>
|
||||
@@ -112,9 +111,8 @@
|
||||
<div class="request-response-error"></div>
|
||||
</div>
|
||||
%endif
|
||||
</div>
|
||||
|
||||
<div class="vert-right member-lists-management">
|
||||
<div class="member-lists-management">
|
||||
## Translators: an "Administration List" is a list, such as Course Staff, that users can be added to.
|
||||
<h2> ${_("Administration List Management")} </h2>
|
||||
|
||||
@@ -216,3 +214,29 @@
|
||||
%endif
|
||||
|
||||
</div>
|
||||
|
||||
%if course.is_cohorted:
|
||||
<hr class="divider" />
|
||||
<div class="cohort-management membership-section" data-ajax_url="${section_data['cohorts_ajax_url']}">
|
||||
</div>
|
||||
% endif
|
||||
|
||||
<%block name="headextra">
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var cohortManagementElement = $('.cohort-management');
|
||||
if (cohortManagementElement.length > 0) {
|
||||
var cohorts = new CohortCollection();
|
||||
cohorts.url = cohortManagementElement.data('ajax_url');
|
||||
var cohortsView = new CohortsView({
|
||||
el: cohortManagementElement,
|
||||
model: cohorts
|
||||
});
|
||||
cohortsView.render();
|
||||
cohorts.fetch().done(function() {
|
||||
cohortsView.render();
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</%block>
|
||||
|
||||
Reference in New Issue
Block a user