Convert cohort JS to use RequireJS.
This commit is contained in:
@@ -1,16 +1,15 @@
|
||||
var edx = edx || {};
|
||||
|
||||
(function(Backbone, CohortModel) {
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(['backbone', 'js/groups/models/cohort'], function(Backbone, CohortModel) {
|
||||
|
||||
edx.groups = edx.groups || {};
|
||||
var CohortCollection = Backbone.Collection.extend({
|
||||
model : CohortModel,
|
||||
comparator: "name",
|
||||
|
||||
edx.groups.CohortCollection = Backbone.Collection.extend({
|
||||
model : CohortModel,
|
||||
comparator: "name",
|
||||
|
||||
parse: function(response) {
|
||||
return response.cohorts;
|
||||
}
|
||||
parse: function(response) {
|
||||
return response.cohorts;
|
||||
}
|
||||
});
|
||||
return CohortCollection;
|
||||
});
|
||||
}).call(this, Backbone, edx.groups.CohortModel);
|
||||
}).call(this, define || RequireJS.define);
|
||||
|
||||
@@ -1,29 +1,28 @@
|
||||
var edx = edx || {};
|
||||
|
||||
(function(Backbone) {
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(['backbone'], function(Backbone) {
|
||||
|
||||
edx.groups = edx.groups || {};
|
||||
|
||||
edx.groups.CohortModel = Backbone.Model.extend({
|
||||
idAttribute: 'id',
|
||||
defaults: {
|
||||
name: '',
|
||||
user_count: 0,
|
||||
/**
|
||||
* Indicates how students are added to the cohort. Will be "none" (signifying manual assignment) or
|
||||
* "random" (indicating students are randomly assigned).
|
||||
*/
|
||||
assignment_type: '',
|
||||
/**
|
||||
* If this cohort is associated with a user partition group, the ID of the user partition.
|
||||
*/
|
||||
user_partition_id: null,
|
||||
/**
|
||||
* If this cohort is associated with a user partition group, the ID of the group within the
|
||||
* partition associated with user_partition_id.
|
||||
*/
|
||||
group_id: null
|
||||
}
|
||||
var CohortModel = Backbone.Model.extend({
|
||||
idAttribute: 'id',
|
||||
defaults: {
|
||||
name: '',
|
||||
user_count: 0,
|
||||
/**
|
||||
* Indicates how students are added to the cohort. Will be "none" (signifying manual assignment) or
|
||||
* "random" (indicating students are randomly assigned).
|
||||
*/
|
||||
assignment_type: '',
|
||||
/**
|
||||
* If this cohort is associated with a user partition group, the ID of the user partition.
|
||||
*/
|
||||
user_partition_id: null,
|
||||
/**
|
||||
* If this cohort is associated with a user partition group, the ID of the group within the
|
||||
* partition associated with user_partition_id.
|
||||
*/
|
||||
group_id: null
|
||||
}
|
||||
});
|
||||
return CohortModel;
|
||||
});
|
||||
}).call(this, Backbone);
|
||||
}).call(this, define || RequireJS.define);
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
var edx = edx || {};
|
||||
|
||||
(function(Backbone) {
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
|
||||
edx.groups = edx.groups || {};
|
||||
|
||||
edx.groups.DiscussionTopicsSettingsModel = Backbone.Model.extend({
|
||||
defaults: {
|
||||
course_wide_discussions: {},
|
||||
inline_discussions: {}
|
||||
}
|
||||
define(['backbone'], function(Backbone) {
|
||||
var DiscussionTopicsSettingsModel = Backbone.Model.extend({
|
||||
defaults: {
|
||||
course_wide_discussions: {},
|
||||
inline_discussions: {}
|
||||
}
|
||||
});
|
||||
return DiscussionTopicsSettingsModel;
|
||||
});
|
||||
}).call(this, Backbone);
|
||||
}).call(this, define || RequireJS.define);
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
var edx = edx || {};
|
||||
|
||||
(function(Backbone) {
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
|
||||
edx.groups = edx.groups || {};
|
||||
|
||||
edx.groups.ContentGroupModel = Backbone.Model.extend({
|
||||
idAttribute: 'id',
|
||||
defaults: {
|
||||
name: '',
|
||||
user_partition_id: null
|
||||
}
|
||||
define(['backbone'], function(Backbone) {
|
||||
var ContentGroupModel = Backbone.Model.extend({
|
||||
idAttribute: 'id',
|
||||
defaults: {
|
||||
name: '',
|
||||
user_partition_id: null
|
||||
}
|
||||
});
|
||||
return ContentGroupModel;
|
||||
});
|
||||
}).call(this, Backbone);
|
||||
}).call(this, define || RequireJS.define);
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
var edx = edx || {};
|
||||
|
||||
(function(Backbone) {
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(['backbone'], function(Backbone) {
|
||||
|
||||
edx.groups = edx.groups || {};
|
||||
|
||||
edx.groups.CourseCohortSettingsModel = Backbone.Model.extend({
|
||||
idAttribute: 'id',
|
||||
defaults: {
|
||||
is_cohorted: false,
|
||||
cohorted_inline_discussions: [],
|
||||
cohorted_course_wide_discussions:[],
|
||||
always_cohort_inline_discussions: true
|
||||
}
|
||||
var CourseCohortSettingsModel = Backbone.Model.extend({
|
||||
idAttribute: 'id',
|
||||
defaults: {
|
||||
is_cohorted: false,
|
||||
cohorted_inline_discussions: [],
|
||||
cohorted_course_wide_discussions:[],
|
||||
always_cohort_inline_discussions: true
|
||||
}
|
||||
});
|
||||
return CourseCohortSettingsModel;
|
||||
});
|
||||
}).call(this, Backbone);
|
||||
}).call(this, define || RequireJS.define);
|
||||
|
||||
@@ -1,99 +1,98 @@
|
||||
var edx = edx || {};
|
||||
|
||||
(function ($, _, Backbone, gettext, interpolate_text, NotificationModel, NotificationView) {
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(['jquery', 'underscore', 'backbone', 'gettext', 'js/models/notification', 'js/views/notification'],
|
||||
function ($, _, Backbone) {
|
||||
|
||||
edx.groups = edx.groups || {};
|
||||
var CohortDiscussionConfigurationView = Backbone.View.extend({
|
||||
|
||||
edx.groups.CohortDiscussionConfigurationView = Backbone.View.extend({
|
||||
/**
|
||||
* Add/Remove the disabled attribute on given element.
|
||||
* @param {object} $element - The element to disable/enable.
|
||||
* @param {bool} disable - The flag to add/remove 'disabled' attribute.
|
||||
*/
|
||||
setDisabled: function($element, disable) {
|
||||
$element.prop('disabled', disable ? 'disabled' : false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add/Remove the disabled attribute on given element.
|
||||
* @param {object} $element - The element to disable/enable.
|
||||
* @param {bool} disable - The flag to add/remove 'disabled' attribute.
|
||||
*/
|
||||
setDisabled: function($element, disable) {
|
||||
$element.prop('disabled', disable ? 'disabled' : false);
|
||||
},
|
||||
/**
|
||||
* Returns the cohorted discussions list.
|
||||
* @param {string} selector - To select the discussion elements whose ids to return.
|
||||
* @returns {Array} - Cohorted discussions.
|
||||
*/
|
||||
getCohortedDiscussions: function(selector) {
|
||||
var self=this,
|
||||
cohortedDiscussions = [];
|
||||
|
||||
/**
|
||||
* Returns the cohorted discussions list.
|
||||
* @param {string} selector - To select the discussion elements whose ids to return.
|
||||
* @returns {Array} - Cohorted discussions.
|
||||
*/
|
||||
getCohortedDiscussions: function(selector) {
|
||||
var self=this,
|
||||
cohortedDiscussions = [];
|
||||
_.each(self.$(selector), function (topic) {
|
||||
cohortedDiscussions.push($(topic).data('id'))
|
||||
});
|
||||
return cohortedDiscussions;
|
||||
},
|
||||
|
||||
_.each(self.$(selector), function (topic) {
|
||||
cohortedDiscussions.push($(topic).data('id'))
|
||||
});
|
||||
return cohortedDiscussions;
|
||||
},
|
||||
/**
|
||||
* Save the cohortSettings' changed attributes to the server via PATCH method.
|
||||
* It shows the error message(s) if any.
|
||||
* @param {object} $element - Messages would be shown before this element.
|
||||
* @param {object} fieldData - Data to update on the server.
|
||||
*/
|
||||
saveForm: function ($element, fieldData) {
|
||||
var self = this,
|
||||
cohortSettingsModel = this.cohortSettings,
|
||||
saveOperation = $.Deferred(),
|
||||
showErrorMessage;
|
||||
|
||||
/**
|
||||
* Save the cohortSettings' changed attributes to the server via PATCH method.
|
||||
* It shows the error message(s) if any.
|
||||
* @param {object} $element - Messages would be shown before this element.
|
||||
* @param {object} fieldData - Data to update on the server.
|
||||
*/
|
||||
saveForm: function ($element, fieldData) {
|
||||
var self = this,
|
||||
cohortSettingsModel = this.cohortSettings,
|
||||
saveOperation = $.Deferred(),
|
||||
showErrorMessage;
|
||||
showErrorMessage = function (message, $element) {
|
||||
self.showMessage(message, $element, 'error');
|
||||
};
|
||||
this.removeNotification();
|
||||
|
||||
showErrorMessage = function (message, $element) {
|
||||
self.showMessage(message, $element, 'error');
|
||||
};
|
||||
this.removeNotification();
|
||||
cohortSettingsModel.save(
|
||||
fieldData, {patch: true, wait: true}
|
||||
).done(function () {
|
||||
saveOperation.resolve();
|
||||
}).fail(function (result) {
|
||||
var errorMessage = null;
|
||||
try {
|
||||
var jsonResponse = JSON.parse(result.responseText);
|
||||
errorMessage = jsonResponse.error;
|
||||
} catch (e) {
|
||||
// Ignore the exception and show the default error message instead.
|
||||
}
|
||||
if (!errorMessage) {
|
||||
errorMessage = gettext("We've encountered an error. Refresh your browser and then try again.");
|
||||
}
|
||||
showErrorMessage(errorMessage, $element);
|
||||
saveOperation.reject();
|
||||
});
|
||||
return saveOperation.promise();
|
||||
},
|
||||
|
||||
cohortSettingsModel.save(
|
||||
fieldData, {patch: true, wait: true}
|
||||
).done(function () {
|
||||
saveOperation.resolve();
|
||||
}).fail(function (result) {
|
||||
var errorMessage = null;
|
||||
try {
|
||||
var jsonResponse = JSON.parse(result.responseText);
|
||||
errorMessage = jsonResponse.error;
|
||||
} catch (e) {
|
||||
// Ignore the exception and show the default error message instead.
|
||||
/**
|
||||
* Shows the notification messages before given element using the NotificationModel.
|
||||
* @param {string} message - Text message to show.
|
||||
* @param {object} $element - Message would be shown before this element.
|
||||
* @param {string} type - Type of message to show e.g. confirmation or error.
|
||||
*/
|
||||
showMessage: function (message, $element, type) {
|
||||
var model = new NotificationModel({type: type || 'confirmation', title: message});
|
||||
this.removeNotification();
|
||||
this.notification = new NotificationView({
|
||||
model: model
|
||||
});
|
||||
$element.before(this.notification.$el);
|
||||
this.notification.render();
|
||||
},
|
||||
|
||||
/**
|
||||
*Removes the notification messages.
|
||||
*/
|
||||
removeNotification: function () {
|
||||
if (this.notification) {
|
||||
this.notification.remove();
|
||||
}
|
||||
}
|
||||
if (!errorMessage) {
|
||||
errorMessage = gettext("We've encountered an error. Refresh your browser and then try again.");
|
||||
}
|
||||
showErrorMessage(errorMessage, $element);
|
||||
saveOperation.reject();
|
||||
|
||||
});
|
||||
return saveOperation.promise();
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows the notification messages before given element using the NotificationModel.
|
||||
* @param {string} message - Text message to show.
|
||||
* @param {object} $element - Message would be shown before this element.
|
||||
* @param {string} type - Type of message to show e.g. confirmation or error.
|
||||
*/
|
||||
showMessage: function (message, $element, type) {
|
||||
var model = new NotificationModel({type: type || 'confirmation', title: message});
|
||||
this.removeNotification();
|
||||
this.notification = new NotificationView({
|
||||
model: model
|
||||
});
|
||||
$element.before(this.notification.$el);
|
||||
this.notification.render();
|
||||
},
|
||||
|
||||
/**
|
||||
*Removes the notification messages.
|
||||
*/
|
||||
removeNotification: function () {
|
||||
if (this.notification) {
|
||||
this.notification.remove();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}).call(this, $, _, Backbone, gettext, interpolate_text, NotificationModel, NotificationView
|
||||
);
|
||||
return CohortDiscussionConfigurationView;
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
|
||||
@@ -1,83 +1,82 @@
|
||||
var edx = edx || {};
|
||||
|
||||
(function ($, _, Backbone, gettext, interpolate_text, CohortDiscussionConfigurationView) {
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(['jquery', 'underscore', 'backbone', 'gettext', 'js/groups/views/cohort_discussions'],
|
||||
function ($, _, Backbone, gettext, CohortDiscussionConfigurationView) {
|
||||
var CourseWideDiscussionsView = CohortDiscussionConfigurationView.extend({
|
||||
events: {
|
||||
'change .check-discussion-subcategory-course-wide': 'discussionCategoryStateChanged',
|
||||
'click .cohort-course-wide-discussions-form .action-save': 'saveCourseWideDiscussionsForm'
|
||||
},
|
||||
|
||||
edx.groups = edx.groups || {};
|
||||
initialize: function (options) {
|
||||
this.template = _.template($('#cohort-discussions-course-wide-tpl').text());
|
||||
this.cohortSettings = options.cohortSettings;
|
||||
},
|
||||
|
||||
edx.groups.CourseWideDiscussionsView = CohortDiscussionConfigurationView.extend({
|
||||
events: {
|
||||
'change .check-discussion-subcategory-course-wide': 'discussionCategoryStateChanged',
|
||||
'click .cohort-course-wide-discussions-form .action-save': 'saveCourseWideDiscussionsForm'
|
||||
},
|
||||
render: function () {
|
||||
this.$('.cohort-course-wide-discussions-nav').html(this.template({
|
||||
courseWideTopics: this.getCourseWideDiscussionsHtml(
|
||||
this.model.get('course_wide_discussions')
|
||||
)
|
||||
}));
|
||||
this.setDisabled(this.$('.cohort-course-wide-discussions-form .action-save'), true);
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
this.template = _.template($('#cohort-discussions-course-wide-tpl').text());
|
||||
this.cohortSettings = options.cohortSettings;
|
||||
},
|
||||
/**
|
||||
* Returns the html list for course-wide discussion topics.
|
||||
* @param {object} courseWideDiscussions - course-wide discussions object from server.
|
||||
* @returns {Array} - HTML list for course-wide discussion topics.
|
||||
*/
|
||||
getCourseWideDiscussionsHtml: function (courseWideDiscussions) {
|
||||
var subCategoryTemplate = _.template($('#cohort-discussions-subcategory-tpl').html()),
|
||||
entries = courseWideDiscussions.entries,
|
||||
children = courseWideDiscussions.children;
|
||||
|
||||
render: function () {
|
||||
this.$('.cohort-course-wide-discussions-nav').html(this.template({
|
||||
courseWideTopics: this.getCourseWideDiscussionsHtml(
|
||||
this.model.get('course_wide_discussions')
|
||||
)
|
||||
}));
|
||||
this.setDisabled(this.$('.cohort-course-wide-discussions-form .action-save'), true);
|
||||
},
|
||||
return _.map(children, function (name) {
|
||||
var entry = entries[name];
|
||||
return subCategoryTemplate({
|
||||
name: name,
|
||||
id: entry.id,
|
||||
is_cohorted: entry.is_cohorted,
|
||||
type: 'course-wide'
|
||||
});
|
||||
}).join('');
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the html list for course-wide discussion topics.
|
||||
* @param {object} courseWideDiscussions - course-wide discussions object from server.
|
||||
* @returns {Array} - HTML list for course-wide discussion topics.
|
||||
*/
|
||||
getCourseWideDiscussionsHtml: function (courseWideDiscussions) {
|
||||
var subCategoryTemplate = _.template($('#cohort-discussions-subcategory-tpl').html()),
|
||||
entries = courseWideDiscussions.entries,
|
||||
children = courseWideDiscussions.children;
|
||||
/**
|
||||
* Enables the save button for course-wide discussions.
|
||||
*/
|
||||
discussionCategoryStateChanged: function(event) {
|
||||
event.preventDefault();
|
||||
this.setDisabled(this.$('.cohort-course-wide-discussions-form .action-save'), false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sends the cohorted_course_wide_discussions to the server and renders the view.
|
||||
*/
|
||||
saveCourseWideDiscussionsForm: function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
var self = this,
|
||||
courseWideCohortedDiscussions = self.getCohortedDiscussions(
|
||||
'.check-discussion-subcategory-course-wide:checked'
|
||||
),
|
||||
fieldData = { cohorted_course_wide_discussions: courseWideCohortedDiscussions };
|
||||
|
||||
self.saveForm(self.$('.course-wide-discussion-topics'),fieldData)
|
||||
.done(function () {
|
||||
self.model.fetch()
|
||||
.done(function () {
|
||||
self.render();
|
||||
self.showMessage(gettext('Your changes have been saved.'), self.$('.course-wide-discussion-topics'));
|
||||
}).fail(function() {
|
||||
var errorMessage = gettext("We've encountered an error. Refresh your browser and then try again.");
|
||||
self.showMessage(errorMessage, self.$('.course-wide-discussion-topics'), 'error')
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return _.map(children, function (name) {
|
||||
var entry = entries[name];
|
||||
return subCategoryTemplate({
|
||||
name: name,
|
||||
id: entry.id,
|
||||
is_cohorted: entry.is_cohorted,
|
||||
type: 'course-wide'
|
||||
});
|
||||
}).join('');
|
||||
},
|
||||
|
||||
/**
|
||||
* Enables the save button for course-wide discussions.
|
||||
*/
|
||||
discussionCategoryStateChanged: function(event) {
|
||||
event.preventDefault();
|
||||
this.setDisabled(this.$('.cohort-course-wide-discussions-form .action-save'), false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sends the cohorted_course_wide_discussions to the server and renders the view.
|
||||
*/
|
||||
saveCourseWideDiscussionsForm: function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
var self = this,
|
||||
courseWideCohortedDiscussions = self.getCohortedDiscussions(
|
||||
'.check-discussion-subcategory-course-wide:checked'
|
||||
),
|
||||
fieldData = { cohorted_course_wide_discussions: courseWideCohortedDiscussions };
|
||||
|
||||
self.saveForm(self.$('.course-wide-discussion-topics'),fieldData)
|
||||
.done(function () {
|
||||
self.model.fetch()
|
||||
.done(function () {
|
||||
self.render();
|
||||
self.showMessage(gettext('Your changes have been saved.'), self.$('.course-wide-discussion-topics'));
|
||||
}).fail(function() {
|
||||
var errorMessage = gettext("We've encountered an error. Refresh your browser and then try again.");
|
||||
self.showMessage(errorMessage, self.$('.course-wide-discussion-topics'), 'error')
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}).call(this, $, _, Backbone, gettext, interpolate_text, edx.groups.CohortDiscussionConfigurationView);
|
||||
return CourseWideDiscussionsView;
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
|
||||
@@ -1,145 +1,144 @@
|
||||
var edx = edx || {};
|
||||
|
||||
(function ($, _, Backbone, gettext, interpolate_text, CohortDiscussionConfigurationView) {
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(['jquery', 'underscore', 'backbone', 'gettext', 'js/groups/views/cohort_discussions', 'js/vendor/jquery.qubit'],
|
||||
function ($, _, Backbone, gettext, CohortDiscussionConfigurationView) {
|
||||
var InlineDiscussionsView = CohortDiscussionConfigurationView.extend({
|
||||
events: {
|
||||
'change .check-discussion-category': 'setSaveButton',
|
||||
'change .check-discussion-subcategory-inline': 'setSaveButton',
|
||||
'click .cohort-inline-discussions-form .action-save': 'saveInlineDiscussionsForm',
|
||||
'change .check-all-inline-discussions': 'setAllInlineDiscussions',
|
||||
'change .check-cohort-inline-discussions': 'setSomeInlineDiscussions'
|
||||
},
|
||||
|
||||
edx.groups = edx.groups || {};
|
||||
initialize: function (options) {
|
||||
this.template = _.template($('#cohort-discussions-inline-tpl').text());
|
||||
this.cohortSettings = options.cohortSettings;
|
||||
},
|
||||
|
||||
edx.groups.InlineDiscussionsView = CohortDiscussionConfigurationView.extend({
|
||||
events: {
|
||||
'change .check-discussion-category': 'setSaveButton',
|
||||
'change .check-discussion-subcategory-inline': 'setSaveButton',
|
||||
'click .cohort-inline-discussions-form .action-save': 'saveInlineDiscussionsForm',
|
||||
'change .check-all-inline-discussions': 'setAllInlineDiscussions',
|
||||
'change .check-cohort-inline-discussions': 'setSomeInlineDiscussions'
|
||||
},
|
||||
render: function () {
|
||||
var alwaysCohortInlineDiscussions = this.cohortSettings.get('always_cohort_inline_discussions');
|
||||
|
||||
initialize: function (options) {
|
||||
this.template = _.template($('#cohort-discussions-inline-tpl').text());
|
||||
this.cohortSettings = options.cohortSettings;
|
||||
},
|
||||
this.$('.cohort-inline-discussions-nav').html(this.template({
|
||||
inlineDiscussionTopics: this.getInlineDiscussionsHtml(this.model.get('inline_discussions')),
|
||||
alwaysCohortInlineDiscussions:alwaysCohortInlineDiscussions
|
||||
}));
|
||||
|
||||
render: function () {
|
||||
var alwaysCohortInlineDiscussions = this.cohortSettings.get('always_cohort_inline_discussions');
|
||||
// Provides the semantics for a nested list of tri-state checkboxes.
|
||||
// When attached to a jQuery element it listens for change events to
|
||||
// input[type=checkbox] elements, and updates the checked and indeterminate
|
||||
// based on the checked values of any checkboxes in child elements of the DOM.
|
||||
this.$('ul.inline-topics').qubit();
|
||||
|
||||
this.$('.cohort-inline-discussions-nav').html(this.template({
|
||||
inlineDiscussionTopics: this.getInlineDiscussionsHtml(this.model.get('inline_discussions')),
|
||||
alwaysCohortInlineDiscussions:alwaysCohortInlineDiscussions
|
||||
}));
|
||||
this.setElementsEnabled(alwaysCohortInlineDiscussions, true);
|
||||
},
|
||||
|
||||
// Provides the semantics for a nested list of tri-state checkboxes.
|
||||
// When attached to a jQuery element it listens for change events to
|
||||
// input[type=checkbox] elements, and updates the checked and indeterminate
|
||||
// based on the checked values of any checkboxes in child elements of the DOM.
|
||||
this.$('ul.inline-topics').qubit();
|
||||
/**
|
||||
* Generate html list for inline discussion topics.
|
||||
* @params {object} inlineDiscussions - inline discussions object from server.
|
||||
* @returns {Array} - HTML for inline discussion topics.
|
||||
*/
|
||||
getInlineDiscussionsHtml: function (inlineDiscussions) {
|
||||
var categoryTemplate = _.template($('#cohort-discussions-category-tpl').html()),
|
||||
entryTemplate = _.template($('#cohort-discussions-subcategory-tpl').html()),
|
||||
isCategoryCohorted = false,
|
||||
children = inlineDiscussions.children,
|
||||
entries = inlineDiscussions.entries,
|
||||
subcategories = inlineDiscussions.subcategories;
|
||||
|
||||
this.setElementsEnabled(alwaysCohortInlineDiscussions, true);
|
||||
},
|
||||
return _.map(children, function (name) {
|
||||
var html = '', entry;
|
||||
if (entries && _.has(entries, name)) {
|
||||
entry = entries[name];
|
||||
html = entryTemplate({
|
||||
name: name,
|
||||
id: entry.id,
|
||||
is_cohorted: entry.is_cohorted,
|
||||
type: 'inline'
|
||||
});
|
||||
} else { // subcategory
|
||||
html = categoryTemplate({
|
||||
name: name,
|
||||
entries: this.getInlineDiscussionsHtml(subcategories[name]),
|
||||
isCategoryCohorted: isCategoryCohorted
|
||||
});
|
||||
}
|
||||
return html;
|
||||
}, this).join('');
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate html list for inline discussion topics.
|
||||
* @params {object} inlineDiscussions - inline discussions object from server.
|
||||
* @returns {Array} - HTML for inline discussion topics.
|
||||
*/
|
||||
getInlineDiscussionsHtml: function (inlineDiscussions) {
|
||||
var categoryTemplate = _.template($('#cohort-discussions-category-tpl').html()),
|
||||
entryTemplate = _.template($('#cohort-discussions-subcategory-tpl').html()),
|
||||
isCategoryCohorted = false,
|
||||
children = inlineDiscussions.children,
|
||||
entries = inlineDiscussions.entries,
|
||||
subcategories = inlineDiscussions.subcategories;
|
||||
/**
|
||||
* Enable/Disable the inline discussion elements.
|
||||
*
|
||||
* Disables the category and sub-category checkboxes.
|
||||
* Enables the save button.
|
||||
*/
|
||||
setAllInlineDiscussions: function(event) {
|
||||
event.preventDefault();
|
||||
this.setElementsEnabled(($(event.currentTarget).prop('checked')), false);
|
||||
},
|
||||
|
||||
return _.map(children, function (name) {
|
||||
var html = '', entry;
|
||||
if (entries && _.has(entries, name)) {
|
||||
entry = entries[name];
|
||||
html = entryTemplate({
|
||||
name: name,
|
||||
id: entry.id,
|
||||
is_cohorted: entry.is_cohorted,
|
||||
type: 'inline'
|
||||
});
|
||||
} else { // subcategory
|
||||
html = categoryTemplate({
|
||||
name: name,
|
||||
entries: this.getInlineDiscussionsHtml(subcategories[name]),
|
||||
isCategoryCohorted: isCategoryCohorted
|
||||
});
|
||||
}
|
||||
return html;
|
||||
}, this).join('');
|
||||
},
|
||||
/**
|
||||
* Enables the inline discussion elements.
|
||||
*
|
||||
* Enables the category and sub-category checkboxes.
|
||||
* Enables the save button.
|
||||
*/
|
||||
setSomeInlineDiscussions: function(event) {
|
||||
event.preventDefault();
|
||||
this.setElementsEnabled(!($(event.currentTarget).prop('checked')), false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Enable/Disable the inline discussion elements.
|
||||
*
|
||||
* Disables the category and sub-category checkboxes.
|
||||
* Enables the save button.
|
||||
*/
|
||||
setAllInlineDiscussions: function(event) {
|
||||
event.preventDefault();
|
||||
this.setElementsEnabled(($(event.currentTarget).prop('checked')), false);
|
||||
},
|
||||
/**
|
||||
* Enable/Disable the inline discussion elements.
|
||||
*
|
||||
* Enable/Disable the category and sub-category checkboxes.
|
||||
* Enable/Disable the save button.
|
||||
* @param {bool} enable_checkboxes - The flag to enable/disable the checkboxes.
|
||||
* @param {bool} enable_save_button - The flag to enable/disable the save button.
|
||||
*/
|
||||
setElementsEnabled: function(enable_checkboxes, enable_save_button) {
|
||||
this.setDisabled(this.$('.check-discussion-category'), enable_checkboxes);
|
||||
this.setDisabled(this.$('.check-discussion-subcategory-inline'), enable_checkboxes);
|
||||
this.setDisabled(this.$('.cohort-inline-discussions-form .action-save'), enable_save_button);
|
||||
},
|
||||
|
||||
/**
|
||||
* Enables the inline discussion elements.
|
||||
*
|
||||
* Enables the category and sub-category checkboxes.
|
||||
* Enables the save button.
|
||||
*/
|
||||
setSomeInlineDiscussions: function(event) {
|
||||
event.preventDefault();
|
||||
this.setElementsEnabled(!($(event.currentTarget).prop('checked')), false);
|
||||
},
|
||||
/**
|
||||
* Enables the save button for inline discussions.
|
||||
*/
|
||||
setSaveButton: function(event) {
|
||||
this.setDisabled(this.$('.cohort-inline-discussions-form .action-save'), false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Enable/Disable the inline discussion elements.
|
||||
*
|
||||
* Enable/Disable the category and sub-category checkboxes.
|
||||
* Enable/Disable the save button.
|
||||
* @param {bool} enable_checkboxes - The flag to enable/disable the checkboxes.
|
||||
* @param {bool} enable_save_button - The flag to enable/disable the save button.
|
||||
*/
|
||||
setElementsEnabled: function(enable_checkboxes, enable_save_button) {
|
||||
this.setDisabled(this.$('.check-discussion-category'), enable_checkboxes);
|
||||
this.setDisabled(this.$('.check-discussion-subcategory-inline'), enable_checkboxes);
|
||||
this.setDisabled(this.$('.cohort-inline-discussions-form .action-save'), enable_save_button);
|
||||
},
|
||||
/**
|
||||
* Sends the cohorted_inline_discussions to the server and renders the view.
|
||||
*/
|
||||
saveInlineDiscussionsForm: function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
/**
|
||||
* Enables the save button for inline discussions.
|
||||
*/
|
||||
setSaveButton: function(event) {
|
||||
this.setDisabled(this.$('.cohort-inline-discussions-form .action-save'), false);
|
||||
},
|
||||
var self = this,
|
||||
cohortedInlineDiscussions = self.getCohortedDiscussions(
|
||||
'.check-discussion-subcategory-inline:checked'
|
||||
),
|
||||
fieldData= {
|
||||
cohorted_inline_discussions: cohortedInlineDiscussions,
|
||||
always_cohort_inline_discussions: self.$('.check-all-inline-discussions').prop('checked')
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends the cohorted_inline_discussions to the server and renders the view.
|
||||
*/
|
||||
saveInlineDiscussionsForm: function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
var self = this,
|
||||
cohortedInlineDiscussions = self.getCohortedDiscussions(
|
||||
'.check-discussion-subcategory-inline:checked'
|
||||
),
|
||||
fieldData= {
|
||||
cohorted_inline_discussions: cohortedInlineDiscussions,
|
||||
always_cohort_inline_discussions: self.$('.check-all-inline-discussions').prop('checked')
|
||||
};
|
||||
|
||||
self.saveForm(self.$('.inline-discussion-topics'), fieldData)
|
||||
.done(function () {
|
||||
self.model.fetch()
|
||||
.done(function () {
|
||||
self.render();
|
||||
self.showMessage(gettext('Your changes have been saved.'), self.$('.inline-discussion-topics'));
|
||||
}).fail(function() {
|
||||
var errorMessage = gettext("We've encountered an error. Refresh your browser and then try again.");
|
||||
self.showMessage(errorMessage, self.$('.inline-discussion-topics'), 'error')
|
||||
});
|
||||
});
|
||||
}
|
||||
self.saveForm(self.$('.inline-discussion-topics'), fieldData)
|
||||
.done(function () {
|
||||
self.model.fetch()
|
||||
.done(function () {
|
||||
self.render();
|
||||
self.showMessage(gettext('Your changes have been saved.'), self.$('.inline-discussion-topics'));
|
||||
}).fail(function() {
|
||||
var errorMessage = gettext("We've encountered an error. Refresh your browser and then try again.");
|
||||
self.showMessage(errorMessage, self.$('.inline-discussion-topics'), 'error')
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
return InlineDiscussionsView;
|
||||
});
|
||||
}).call(this, $, _, Backbone, gettext, interpolate_text, edx.groups.CohortDiscussionConfigurationView);
|
||||
}).call(this, define || RequireJS.define);
|
||||
|
||||
@@ -1,259 +1,258 @@
|
||||
var edx = edx || {};
|
||||
|
||||
(function(Backbone, _, $, gettext, ngettext, interpolate_text, CohortFormView, NotificationModel, NotificationView) {
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(['backbone', 'underscore', 'jquery', 'gettext', 'js/groups/views/cohort_form', 'string_utils',
|
||||
'js/models/notification', 'js/views/notification'],
|
||||
function(Backbone, _, $, gettext, CohortFormView) {
|
||||
var CohortEditorView = Backbone.View.extend({
|
||||
|
||||
edx.groups = edx.groups || {};
|
||||
events : {
|
||||
'click .wrapper-tabs .tab': 'selectTab',
|
||||
'click .tab-content-settings .action-save': 'saveSettings',
|
||||
'click .tab-content-settings .action-cancel': 'cancelSettings',
|
||||
'submit .cohort-management-group-add-form': 'addStudents'
|
||||
},
|
||||
|
||||
edx.groups.CohortEditorView = Backbone.View.extend({
|
||||
initialize: function(options) {
|
||||
this.template = _.template($('#cohort-editor-tpl').text());
|
||||
this.groupHeaderTemplate = _.template($('#cohort-group-header-tpl').text());
|
||||
this.cohorts = options.cohorts;
|
||||
this.contentGroups = options.contentGroups;
|
||||
this.context = options.context;
|
||||
},
|
||||
|
||||
events : {
|
||||
'click .wrapper-tabs .tab': 'selectTab',
|
||||
'click .tab-content-settings .action-save': 'saveSettings',
|
||||
'click .tab-content-settings .action-cancel': 'cancelSettings',
|
||||
'submit .cohort-management-group-add-form': 'addStudents'
|
||||
},
|
||||
// Any errors that are currently being displayed to the instructor (for example, unknown email addresses).
|
||||
errorNotifications: null,
|
||||
// Any confirmation messages that are currently being displayed (for example, number of students added).
|
||||
confirmationNotifications: null,
|
||||
|
||||
initialize: function(options) {
|
||||
this.template = _.template($('#cohort-editor-tpl').text());
|
||||
this.groupHeaderTemplate = _.template($('#cohort-group-header-tpl').text());
|
||||
this.cohorts = options.cohorts;
|
||||
this.contentGroups = options.contentGroups;
|
||||
this.context = options.context;
|
||||
},
|
||||
|
||||
// Any errors that are currently being displayed to the instructor (for example, unknown email addresses).
|
||||
errorNotifications: null,
|
||||
// Any confirmation messages that are currently being displayed (for example, number of students added).
|
||||
confirmationNotifications: null,
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.template({
|
||||
cohort: this.model
|
||||
}));
|
||||
this.renderGroupHeader();
|
||||
this.cohortFormView = new CohortFormView({
|
||||
model: this.model,
|
||||
contentGroups: this.contentGroups,
|
||||
context: this.context
|
||||
});
|
||||
this.cohortFormView.render();
|
||||
this.$('.tab-content-settings').append(this.cohortFormView.$el);
|
||||
return this;
|
||||
},
|
||||
|
||||
renderGroupHeader: function() {
|
||||
this.$('.cohort-management-group-header').html(this.groupHeaderTemplate({
|
||||
cohort: this.model
|
||||
}));
|
||||
},
|
||||
|
||||
selectTab: function(event) {
|
||||
var tabElement = $(event.currentTarget),
|
||||
tabName = tabElement.data('tab');
|
||||
event.preventDefault();
|
||||
this.$('.wrapper-tabs .tab').removeClass('is-selected');
|
||||
this.$('.wrapper-tabs .tab').find('span.sr').remove();
|
||||
tabElement.addClass('is-selected');
|
||||
tabElement.find('a').prepend('<span class="sr">' + gettext('Selected tab') + ' </span>');
|
||||
this.$('.tab-content').addClass('is-hidden');
|
||||
this.$('.tab-content-' + tabName).removeClass('is-hidden').focus();
|
||||
},
|
||||
|
||||
saveSettings: function(event) {
|
||||
var cohortFormView = this.cohortFormView;
|
||||
var self = this;
|
||||
event.preventDefault();
|
||||
cohortFormView.saveForm()
|
||||
.done(function() {
|
||||
self.renderGroupHeader();
|
||||
cohortFormView.showMessage(gettext('Saved cohort'));
|
||||
});
|
||||
},
|
||||
|
||||
cancelSettings: function(event) {
|
||||
event.preventDefault();
|
||||
this.render();
|
||||
},
|
||||
|
||||
setCohort: function(cohort) {
|
||||
this.model = cohort;
|
||||
this.render();
|
||||
},
|
||||
|
||||
addStudents: function(event) {
|
||||
event.preventDefault();
|
||||
var self = this,
|
||||
cohorts = this.cohorts,
|
||||
input = this.$('.cohort-management-group-add-students'),
|
||||
add_url = this.model.url() + '/add',
|
||||
students = input.val().trim(),
|
||||
cohortId = this.model.id;
|
||||
|
||||
if (students.length > 0) {
|
||||
$.post(
|
||||
add_url, {'users': students}
|
||||
).done(function(modifiedUsers) {
|
||||
self.refreshCohorts().done(function() {
|
||||
// Find the equivalent cohort in the new collection and select it
|
||||
var cohort = cohorts.get(cohortId);
|
||||
self.setCohort(cohort);
|
||||
|
||||
// Show the notifications
|
||||
self.addNotifications(modifiedUsers);
|
||||
|
||||
// If an unknown user was specified then update the new input to have
|
||||
// the original input's value. This is to allow the user to correct the
|
||||
// value in case it was a typo.
|
||||
if (modifiedUsers.unknown.length > 0) {
|
||||
self.$('.cohort-management-group-add-students').val(students);
|
||||
}
|
||||
render: function() {
|
||||
this.$el.html(this.template({
|
||||
cohort: this.model
|
||||
}));
|
||||
this.renderGroupHeader();
|
||||
this.cohortFormView = new CohortFormView({
|
||||
model: this.model,
|
||||
contentGroups: this.contentGroups,
|
||||
context: this.context
|
||||
});
|
||||
}).fail(function() {
|
||||
self.showErrorMessage(gettext('Error adding students.'), true);
|
||||
});
|
||||
} else {
|
||||
self.showErrorMessage(gettext('Enter a username or email.'), true);
|
||||
input.val('');
|
||||
}
|
||||
},
|
||||
this.cohortFormView.render();
|
||||
this.$('.tab-content-settings').append(this.cohortFormView.$el);
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Refresh the cohort collection to get the latest set as well as up-to-date counts.
|
||||
*/
|
||||
refreshCohorts: function() {
|
||||
return this.cohorts.fetch();
|
||||
},
|
||||
renderGroupHeader: function() {
|
||||
this.$('.cohort-management-group-header').html(this.groupHeaderTemplate({
|
||||
cohort: this.model
|
||||
}));
|
||||
},
|
||||
|
||||
undelegateViewEvents: function (view) {
|
||||
if (view) {
|
||||
view.undelegateEvents();
|
||||
}
|
||||
},
|
||||
selectTab: function(event) {
|
||||
var tabElement = $(event.currentTarget),
|
||||
tabName = tabElement.data('tab');
|
||||
event.preventDefault();
|
||||
this.$('.wrapper-tabs .tab').removeClass('is-selected');
|
||||
this.$('.wrapper-tabs .tab').find('span.sr').remove();
|
||||
tabElement.addClass('is-selected');
|
||||
tabElement.find('a').prepend('<span class="sr">' + gettext('Selected tab') + ' </span>');
|
||||
this.$('.tab-content').addClass('is-hidden');
|
||||
this.$('.tab-content-' + tabName).removeClass('is-hidden').focus();
|
||||
},
|
||||
|
||||
showErrorMessage: function(message, removeConfirmations, model) {
|
||||
if (removeConfirmations && this.confirmationNotifications) {
|
||||
this.undelegateViewEvents(this.confirmationNotifications);
|
||||
this.confirmationNotifications.$el.html('');
|
||||
this.confirmationNotifications = null;
|
||||
}
|
||||
if (model === undefined) {
|
||||
model = new NotificationModel();
|
||||
}
|
||||
model.set('type', 'error');
|
||||
model.set('title', message);
|
||||
saveSettings: function(event) {
|
||||
var cohortFormView = this.cohortFormView;
|
||||
var self = this;
|
||||
event.preventDefault();
|
||||
cohortFormView.saveForm()
|
||||
.done(function() {
|
||||
self.renderGroupHeader();
|
||||
cohortFormView.showMessage(gettext('Saved cohort'));
|
||||
});
|
||||
},
|
||||
|
||||
this.undelegateViewEvents(this.errorNotifications);
|
||||
cancelSettings: function(event) {
|
||||
event.preventDefault();
|
||||
this.render();
|
||||
},
|
||||
|
||||
this.errorNotifications = new NotificationView({
|
||||
el: this.$('.cohort-errors'),
|
||||
model: model
|
||||
setCohort: function(cohort) {
|
||||
this.model = cohort;
|
||||
this.render();
|
||||
},
|
||||
|
||||
addStudents: function(event) {
|
||||
event.preventDefault();
|
||||
var self = this,
|
||||
cohorts = this.cohorts,
|
||||
input = this.$('.cohort-management-group-add-students'),
|
||||
add_url = this.model.url() + '/add',
|
||||
students = input.val().trim(),
|
||||
cohortId = this.model.id;
|
||||
|
||||
if (students.length > 0) {
|
||||
$.post(
|
||||
add_url, {'users': students}
|
||||
).done(function(modifiedUsers) {
|
||||
self.refreshCohorts().done(function() {
|
||||
// Find the equivalent cohort in the new collection and select it
|
||||
var cohort = cohorts.get(cohortId);
|
||||
self.setCohort(cohort);
|
||||
|
||||
// Show the notifications
|
||||
self.addNotifications(modifiedUsers);
|
||||
|
||||
// If an unknown user was specified then update the new input to have
|
||||
// the original input's value. This is to allow the user to correct the
|
||||
// value in case it was a typo.
|
||||
if (modifiedUsers.unknown.length > 0) {
|
||||
self.$('.cohort-management-group-add-students').val(students);
|
||||
}
|
||||
});
|
||||
}).fail(function() {
|
||||
self.showErrorMessage(gettext('Error adding students.'), true);
|
||||
});
|
||||
} else {
|
||||
self.showErrorMessage(gettext('Enter a username or email.'), true);
|
||||
input.val('');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Refresh the cohort collection to get the latest set as well as up-to-date counts.
|
||||
*/
|
||||
refreshCohorts: function() {
|
||||
return this.cohorts.fetch();
|
||||
},
|
||||
|
||||
undelegateViewEvents: function (view) {
|
||||
if (view) {
|
||||
view.undelegateEvents();
|
||||
}
|
||||
},
|
||||
|
||||
showErrorMessage: function(message, removeConfirmations, model) {
|
||||
if (removeConfirmations && this.confirmationNotifications) {
|
||||
this.undelegateViewEvents(this.confirmationNotifications);
|
||||
this.confirmationNotifications.$el.html('');
|
||||
this.confirmationNotifications = null;
|
||||
}
|
||||
if (model === undefined) {
|
||||
model = new NotificationModel();
|
||||
}
|
||||
model.set('type', 'error');
|
||||
model.set('title', message);
|
||||
|
||||
this.undelegateViewEvents(this.errorNotifications);
|
||||
|
||||
this.errorNotifications = new NotificationView({
|
||||
el: this.$('.cohort-errors'),
|
||||
model: model
|
||||
});
|
||||
this.errorNotifications.render();
|
||||
},
|
||||
|
||||
addNotifications: function(modifiedUsers) {
|
||||
var oldCohort, title, details, numPresent, numUsersAdded, numErrors,
|
||||
createErrorDetails, errorActionCallback, errorModel,
|
||||
errorLimit = 5;
|
||||
|
||||
// Show confirmation messages.
|
||||
this.undelegateViewEvents(this.confirmationNotifications);
|
||||
numUsersAdded = modifiedUsers.added.length + modifiedUsers.changed.length;
|
||||
numPresent = modifiedUsers.present.length;
|
||||
if (numUsersAdded > 0 || numPresent > 0) {
|
||||
title = interpolate_text(
|
||||
ngettext("{numUsersAdded} student has been added to this cohort",
|
||||
"{numUsersAdded} students have been added to this cohort", numUsersAdded),
|
||||
{numUsersAdded: numUsersAdded}
|
||||
);
|
||||
|
||||
var movedByCohort = {};
|
||||
_.each(modifiedUsers.changed, function (changedInfo) {
|
||||
oldCohort = changedInfo.previous_cohort;
|
||||
if (oldCohort in movedByCohort) {
|
||||
movedByCohort[oldCohort] = movedByCohort[oldCohort] + 1;
|
||||
}
|
||||
else {
|
||||
movedByCohort[oldCohort] = 1;
|
||||
}
|
||||
});
|
||||
|
||||
details = [];
|
||||
for (oldCohort in movedByCohort) {
|
||||
details.push(
|
||||
interpolate_text(
|
||||
ngettext("{numMoved} student was removed from {oldCohort}",
|
||||
"{numMoved} students were removed from {oldCohort}", movedByCohort[oldCohort]),
|
||||
{numMoved: movedByCohort[oldCohort], oldCohort: oldCohort}
|
||||
)
|
||||
);
|
||||
}
|
||||
if (numPresent > 0) {
|
||||
details.push(
|
||||
interpolate_text(
|
||||
ngettext("{numPresent} student was already in the cohort",
|
||||
"{numPresent} students were already in the cohort", numPresent),
|
||||
{numPresent: numPresent}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
this.confirmationNotifications = new NotificationView({
|
||||
el: this.$('.cohort-confirmations'),
|
||||
model: new NotificationModel({
|
||||
type: "confirmation",
|
||||
title: title,
|
||||
details: details
|
||||
})
|
||||
});
|
||||
this.confirmationNotifications.render();
|
||||
}
|
||||
else if (this.confirmationNotifications) {
|
||||
this.confirmationNotifications.$el.html('');
|
||||
this.confirmationNotifications = null;
|
||||
}
|
||||
|
||||
// Show error messages.
|
||||
this.undelegateViewEvents(this.errorNotifications);
|
||||
numErrors = modifiedUsers.unknown.length;
|
||||
if (numErrors > 0) {
|
||||
createErrorDetails = function (unknownUsers, showAllErrors) {
|
||||
var numErrors = unknownUsers.length, details = [];
|
||||
|
||||
for (var i = 0; i < (showAllErrors ? numErrors : Math.min(errorLimit, numErrors)); i++) {
|
||||
details.push(interpolate_text(gettext("Unknown user: {user}"), {user: unknownUsers[i]}));
|
||||
}
|
||||
return details;
|
||||
};
|
||||
|
||||
title = interpolate_text(
|
||||
ngettext("There was an error when trying to add students:",
|
||||
"There were {numErrors} errors when trying to add students:", numErrors),
|
||||
{numErrors: numErrors}
|
||||
);
|
||||
details = createErrorDetails(modifiedUsers.unknown, false);
|
||||
|
||||
errorActionCallback = function (view) {
|
||||
view.model.set("actionText", null);
|
||||
view.model.set("details", createErrorDetails(modifiedUsers.unknown, true));
|
||||
view.render();
|
||||
};
|
||||
|
||||
errorModel = new NotificationModel({
|
||||
details: details,
|
||||
actionText: numErrors > errorLimit ? gettext("View all errors") : null,
|
||||
actionCallback: errorActionCallback,
|
||||
actionClass: 'action-expand'
|
||||
});
|
||||
|
||||
this.showErrorMessage(title, false, errorModel);
|
||||
}
|
||||
else if (this.errorNotifications) {
|
||||
this.errorNotifications.$el.html('');
|
||||
this.errorNotifications = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
this.errorNotifications.render();
|
||||
},
|
||||
|
||||
addNotifications: function(modifiedUsers) {
|
||||
var oldCohort, title, details, numPresent, numUsersAdded, numErrors,
|
||||
createErrorDetails, errorActionCallback, errorModel,
|
||||
errorLimit = 5;
|
||||
|
||||
// Show confirmation messages.
|
||||
this.undelegateViewEvents(this.confirmationNotifications);
|
||||
numUsersAdded = modifiedUsers.added.length + modifiedUsers.changed.length;
|
||||
numPresent = modifiedUsers.present.length;
|
||||
if (numUsersAdded > 0 || numPresent > 0) {
|
||||
title = interpolate_text(
|
||||
ngettext("{numUsersAdded} student has been added to this cohort",
|
||||
"{numUsersAdded} students have been added to this cohort", numUsersAdded),
|
||||
{numUsersAdded: numUsersAdded}
|
||||
);
|
||||
|
||||
var movedByCohort = {};
|
||||
_.each(modifiedUsers.changed, function (changedInfo) {
|
||||
oldCohort = changedInfo.previous_cohort;
|
||||
if (oldCohort in movedByCohort) {
|
||||
movedByCohort[oldCohort] = movedByCohort[oldCohort] + 1;
|
||||
}
|
||||
else {
|
||||
movedByCohort[oldCohort] = 1;
|
||||
}
|
||||
});
|
||||
|
||||
details = [];
|
||||
for (oldCohort in movedByCohort) {
|
||||
details.push(
|
||||
interpolate_text(
|
||||
ngettext("{numMoved} student was removed from {oldCohort}",
|
||||
"{numMoved} students were removed from {oldCohort}", movedByCohort[oldCohort]),
|
||||
{numMoved: movedByCohort[oldCohort], oldCohort: oldCohort}
|
||||
)
|
||||
);
|
||||
}
|
||||
if (numPresent > 0) {
|
||||
details.push(
|
||||
interpolate_text(
|
||||
ngettext("{numPresent} student was already in the cohort",
|
||||
"{numPresent} students were already in the cohort", numPresent),
|
||||
{numPresent: numPresent}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
this.confirmationNotifications = new NotificationView({
|
||||
el: this.$('.cohort-confirmations'),
|
||||
model: new NotificationModel({
|
||||
type: "confirmation",
|
||||
title: title,
|
||||
details: details
|
||||
})
|
||||
});
|
||||
this.confirmationNotifications.render();
|
||||
}
|
||||
else if (this.confirmationNotifications) {
|
||||
this.confirmationNotifications.$el.html('');
|
||||
this.confirmationNotifications = null;
|
||||
}
|
||||
|
||||
// Show error messages.
|
||||
this.undelegateViewEvents(this.errorNotifications);
|
||||
numErrors = modifiedUsers.unknown.length;
|
||||
if (numErrors > 0) {
|
||||
createErrorDetails = function (unknownUsers, showAllErrors) {
|
||||
var numErrors = unknownUsers.length, details = [];
|
||||
|
||||
for (var i = 0; i < (showAllErrors ? numErrors : Math.min(errorLimit, numErrors)); i++) {
|
||||
details.push(interpolate_text(gettext("Unknown user: {user}"), {user: unknownUsers[i]}));
|
||||
}
|
||||
return details;
|
||||
};
|
||||
|
||||
title = interpolate_text(
|
||||
ngettext("There was an error when trying to add students:",
|
||||
"There were {numErrors} errors when trying to add students:", numErrors),
|
||||
{numErrors: numErrors}
|
||||
);
|
||||
details = createErrorDetails(modifiedUsers.unknown, false);
|
||||
|
||||
errorActionCallback = function (view) {
|
||||
view.model.set("actionText", null);
|
||||
view.model.set("details", createErrorDetails(modifiedUsers.unknown, true));
|
||||
view.render();
|
||||
};
|
||||
|
||||
errorModel = new NotificationModel({
|
||||
details: details,
|
||||
actionText: numErrors > errorLimit ? gettext("View all errors") : null,
|
||||
actionCallback: errorActionCallback,
|
||||
actionClass: 'action-expand'
|
||||
});
|
||||
|
||||
this.showErrorMessage(title, false, errorModel);
|
||||
}
|
||||
else if (this.errorNotifications) {
|
||||
this.errorNotifications.$el.html('');
|
||||
this.errorNotifications = null;
|
||||
}
|
||||
}
|
||||
return CohortEditorView;
|
||||
});
|
||||
}).call(this, Backbone, _, $, gettext, ngettext, interpolate_text, edx.groups.CohortFormView,
|
||||
NotificationModel, NotificationView);
|
||||
}).call(this, define || RequireJS.define);
|
||||
|
||||
@@ -1,172 +1,173 @@
|
||||
var edx = edx || {};
|
||||
|
||||
(function($, _, Backbone, gettext, interpolate_text, CohortModel, NotificationModel, NotificationView) {
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(['jquery', 'underscore', 'backbone', 'gettext', 'js/groups/models/cohort',
|
||||
'js/models/notification', 'js/views/notification'],
|
||||
function($, _, Backbone, gettext, CohortModel) {
|
||||
|
||||
edx.groups = edx.groups || {};
|
||||
var CohortFormView = Backbone.View.extend({
|
||||
events : {
|
||||
'change .cohort-management-details-association-course input': 'onRadioButtonChange'
|
||||
},
|
||||
|
||||
edx.groups.CohortFormView = Backbone.View.extend({
|
||||
events : {
|
||||
'change .cohort-management-details-association-course input': 'onRadioButtonChange'
|
||||
},
|
||||
initialize: function(options) {
|
||||
this.template = _.template($('#cohort-form-tpl').text());
|
||||
this.contentGroups = options.contentGroups;
|
||||
this.context = options.context;
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
this.template = _.template($('#cohort-form-tpl').text());
|
||||
this.contentGroups = options.contentGroups;
|
||||
this.context = options.context;
|
||||
},
|
||||
showNotification: function(options, beforeElement) {
|
||||
var model = new NotificationModel(options);
|
||||
this.removeNotification();
|
||||
this.notification = new NotificationView({
|
||||
model: model
|
||||
});
|
||||
beforeElement.before(this.notification.$el);
|
||||
this.notification.render();
|
||||
},
|
||||
|
||||
showNotification: function(options, beforeElement) {
|
||||
var model = new NotificationModel(options);
|
||||
this.removeNotification();
|
||||
this.notification = new NotificationView({
|
||||
model: model
|
||||
removeNotification: function() {
|
||||
if (this.notification) {
|
||||
this.notification.remove();
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.template({
|
||||
cohort: this.model,
|
||||
isDefaultCohort: this.isDefault(this.model.get('name')),
|
||||
contentGroups: this.contentGroups,
|
||||
studioGroupConfigurationsUrl: this.context.studioGroupConfigurationsUrl
|
||||
}));
|
||||
return this;
|
||||
},
|
||||
|
||||
isDefault: function(name) {
|
||||
var cohorts = this.model.collection;
|
||||
if (_.isUndefined(cohorts)) {
|
||||
return false;
|
||||
}
|
||||
var randomModels = cohorts.where({assignment_type:'random'});
|
||||
return (randomModels.length === 1) && (randomModels[0].get('name') === name);
|
||||
},
|
||||
|
||||
onRadioButtonChange: function(event) {
|
||||
var target = $(event.currentTarget),
|
||||
groupsEnabled = target.val() === 'yes';
|
||||
if (!groupsEnabled) {
|
||||
// If the user has chosen 'no', then clear the selection by setting
|
||||
// it to the first option which represents no selection.
|
||||
this.$('.input-cohort-group-association').val('None');
|
||||
}
|
||||
// Enable the select if the user has chosen groups, else disable it
|
||||
this.$('.input-cohort-group-association').prop('disabled', !groupsEnabled);
|
||||
},
|
||||
|
||||
hasAssociatedContentGroup: function() {
|
||||
return this.$('.radio-yes').prop('checked');
|
||||
},
|
||||
|
||||
getSelectedContentGroup: function() {
|
||||
var selectValue = this.$('.input-cohort-group-association').val(),
|
||||
ids, groupId, userPartitionId, i, contentGroup;
|
||||
if (!this.hasAssociatedContentGroup() || selectValue === 'None') {
|
||||
return null;
|
||||
}
|
||||
ids = selectValue.split(':');
|
||||
groupId = parseInt(ids[0]);
|
||||
userPartitionId = parseInt(ids[1]);
|
||||
for (i=0; i < this.contentGroups.length; i++) {
|
||||
contentGroup = this.contentGroups[i];
|
||||
if (contentGroup.get('id') === groupId && contentGroup.get('user_partition_id') === userPartitionId) {
|
||||
return contentGroup;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
getUpdatedCohortName: function() {
|
||||
var cohortName = this.$('.cohort-name').val();
|
||||
return cohortName ? cohortName.trim() : '';
|
||||
},
|
||||
|
||||
getAssignmentType: function() {
|
||||
return this.$('input[name="cohort-assignment-type"]:checked').val();
|
||||
},
|
||||
|
||||
showMessage: function(message, type, details) {
|
||||
this.showNotification(
|
||||
{type: type || 'confirmation', title: message, details: details},
|
||||
this.$('.form-fields')
|
||||
);
|
||||
},
|
||||
|
||||
validate: function(fieldData) {
|
||||
var errorMessages;
|
||||
errorMessages = [];
|
||||
if (!fieldData.name) {
|
||||
errorMessages.push(gettext('You must specify a name for the cohort'));
|
||||
}
|
||||
if (this.hasAssociatedContentGroup() && fieldData.group_id === null) {
|
||||
if (this.$('.input-cohort-group-association').val() === 'None') {
|
||||
errorMessages.push(gettext('You did not select a content group'));
|
||||
} else {
|
||||
// If a value was selected, then it must be for a non-existent/deleted content group
|
||||
errorMessages.push(gettext('The selected content group does not exist'));
|
||||
}
|
||||
}
|
||||
return errorMessages;
|
||||
},
|
||||
|
||||
saveForm: function() {
|
||||
var self = this,
|
||||
cohort = this.model,
|
||||
saveOperation = $.Deferred(),
|
||||
isUpdate = !_.isUndefined(this.model.id),
|
||||
fieldData, selectedContentGroup, selectedAssignmentType, errorMessages, showErrorMessage;
|
||||
showErrorMessage = function(message, details) {
|
||||
self.showMessage(message, 'error', details);
|
||||
};
|
||||
this.removeNotification();
|
||||
selectedContentGroup = this.getSelectedContentGroup();
|
||||
selectedAssignmentType = this.getAssignmentType();
|
||||
fieldData = {
|
||||
name: this.getUpdatedCohortName(),
|
||||
group_id: selectedContentGroup ? selectedContentGroup.id : null,
|
||||
user_partition_id: selectedContentGroup ? selectedContentGroup.get('user_partition_id') : null,
|
||||
assignment_type: selectedAssignmentType
|
||||
};
|
||||
errorMessages = this.validate(fieldData);
|
||||
|
||||
if (errorMessages.length > 0) {
|
||||
showErrorMessage(
|
||||
isUpdate ? gettext("The cohort cannot be saved") : gettext("The cohort cannot be added"),
|
||||
errorMessages
|
||||
);
|
||||
saveOperation.reject();
|
||||
} else {
|
||||
cohort.save(
|
||||
fieldData, {patch: isUpdate, wait: true}
|
||||
).done(function(result) {
|
||||
cohort.id = result.id;
|
||||
self.render(); // re-render to remove any now invalid error messages
|
||||
saveOperation.resolve();
|
||||
}).fail(function(result) {
|
||||
var errorMessage = null;
|
||||
try {
|
||||
var jsonResponse = JSON.parse(result.responseText);
|
||||
errorMessage = jsonResponse.error;
|
||||
} catch(e) {
|
||||
// Ignore the exception and show the default error message instead.
|
||||
}
|
||||
if (!errorMessage) {
|
||||
errorMessage = gettext("We've encountered an error. Refresh your browser and then try again.");
|
||||
}
|
||||
showErrorMessage(errorMessage);
|
||||
saveOperation.reject();
|
||||
});
|
||||
}
|
||||
return saveOperation.promise();
|
||||
}
|
||||
});
|
||||
beforeElement.before(this.notification.$el);
|
||||
this.notification.render();
|
||||
},
|
||||
|
||||
removeNotification: function() {
|
||||
if (this.notification) {
|
||||
this.notification.remove();
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.template({
|
||||
cohort: this.model,
|
||||
isDefaultCohort: this.isDefault(this.model.get('name')),
|
||||
contentGroups: this.contentGroups,
|
||||
studioGroupConfigurationsUrl: this.context.studioGroupConfigurationsUrl
|
||||
}));
|
||||
return this;
|
||||
},
|
||||
|
||||
isDefault: function(name) {
|
||||
var cohorts = this.model.collection;
|
||||
if (_.isUndefined(cohorts)) {
|
||||
return false;
|
||||
}
|
||||
var randomModels = cohorts.where({assignment_type:'random'});
|
||||
return (randomModels.length === 1) && (randomModels[0].get('name') === name);
|
||||
},
|
||||
|
||||
onRadioButtonChange: function(event) {
|
||||
var target = $(event.currentTarget),
|
||||
groupsEnabled = target.val() === 'yes';
|
||||
if (!groupsEnabled) {
|
||||
// If the user has chosen 'no', then clear the selection by setting
|
||||
// it to the first option which represents no selection.
|
||||
this.$('.input-cohort-group-association').val('None');
|
||||
}
|
||||
// Enable the select if the user has chosen groups, else disable it
|
||||
this.$('.input-cohort-group-association').prop('disabled', !groupsEnabled);
|
||||
},
|
||||
|
||||
hasAssociatedContentGroup: function() {
|
||||
return this.$('.radio-yes').prop('checked');
|
||||
},
|
||||
|
||||
getSelectedContentGroup: function() {
|
||||
var selectValue = this.$('.input-cohort-group-association').val(),
|
||||
ids, groupId, userPartitionId, i, contentGroup;
|
||||
if (!this.hasAssociatedContentGroup() || selectValue === 'None') {
|
||||
return null;
|
||||
}
|
||||
ids = selectValue.split(':');
|
||||
groupId = parseInt(ids[0]);
|
||||
userPartitionId = parseInt(ids[1]);
|
||||
for (i=0; i < this.contentGroups.length; i++) {
|
||||
contentGroup = this.contentGroups[i];
|
||||
if (contentGroup.get('id') === groupId && contentGroup.get('user_partition_id') === userPartitionId) {
|
||||
return contentGroup;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
getUpdatedCohortName: function() {
|
||||
var cohortName = this.$('.cohort-name').val();
|
||||
return cohortName ? cohortName.trim() : '';
|
||||
},
|
||||
|
||||
getAssignmentType: function() {
|
||||
return this.$('input[name="cohort-assignment-type"]:checked').val();
|
||||
},
|
||||
|
||||
showMessage: function(message, type, details) {
|
||||
this.showNotification(
|
||||
{type: type || 'confirmation', title: message, details: details},
|
||||
this.$('.form-fields')
|
||||
);
|
||||
},
|
||||
|
||||
validate: function(fieldData) {
|
||||
var errorMessages;
|
||||
errorMessages = [];
|
||||
if (!fieldData.name) {
|
||||
errorMessages.push(gettext('You must specify a name for the cohort'));
|
||||
}
|
||||
if (this.hasAssociatedContentGroup() && fieldData.group_id === null) {
|
||||
if (this.$('.input-cohort-group-association').val() === 'None') {
|
||||
errorMessages.push(gettext('You did not select a content group'));
|
||||
} else {
|
||||
// If a value was selected, then it must be for a non-existent/deleted content group
|
||||
errorMessages.push(gettext('The selected content group does not exist'));
|
||||
}
|
||||
}
|
||||
return errorMessages;
|
||||
},
|
||||
|
||||
saveForm: function() {
|
||||
var self = this,
|
||||
cohort = this.model,
|
||||
saveOperation = $.Deferred(),
|
||||
isUpdate = !_.isUndefined(this.model.id),
|
||||
fieldData, selectedContentGroup, selectedAssignmentType, errorMessages, showErrorMessage;
|
||||
showErrorMessage = function(message, details) {
|
||||
self.showMessage(message, 'error', details);
|
||||
};
|
||||
this.removeNotification();
|
||||
selectedContentGroup = this.getSelectedContentGroup();
|
||||
selectedAssignmentType = this.getAssignmentType();
|
||||
fieldData = {
|
||||
name: this.getUpdatedCohortName(),
|
||||
group_id: selectedContentGroup ? selectedContentGroup.id : null,
|
||||
user_partition_id: selectedContentGroup ? selectedContentGroup.get('user_partition_id') : null,
|
||||
assignment_type: selectedAssignmentType
|
||||
};
|
||||
errorMessages = this.validate(fieldData);
|
||||
|
||||
if (errorMessages.length > 0) {
|
||||
showErrorMessage(
|
||||
isUpdate ? gettext("The cohort cannot be saved") : gettext("The cohort cannot be added"),
|
||||
errorMessages
|
||||
);
|
||||
saveOperation.reject();
|
||||
} else {
|
||||
cohort.save(
|
||||
fieldData, {patch: isUpdate, wait: true}
|
||||
).done(function(result) {
|
||||
cohort.id = result.id;
|
||||
self.render(); // re-render to remove any now invalid error messages
|
||||
saveOperation.resolve();
|
||||
}).fail(function(result) {
|
||||
var errorMessage = null;
|
||||
try {
|
||||
var jsonResponse = JSON.parse(result.responseText);
|
||||
errorMessage = jsonResponse.error;
|
||||
} catch(e) {
|
||||
// Ignore the exception and show the default error message instead.
|
||||
}
|
||||
if (!errorMessage) {
|
||||
errorMessage = gettext("We've encountered an error. Refresh your browser and then try again.");
|
||||
}
|
||||
showErrorMessage(errorMessage);
|
||||
saveOperation.reject();
|
||||
});
|
||||
}
|
||||
return saveOperation.promise();
|
||||
}
|
||||
});
|
||||
}).call(this, $, _, Backbone, gettext, interpolate_text, edx.groups.CohortModel, NotificationModel, NotificationView);
|
||||
return CohortFormView;
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
|
||||
@@ -1,310 +1,312 @@
|
||||
var edx = edx || {};
|
||||
|
||||
(function($, _, Backbone, gettext, interpolate_text, CohortModel, CohortEditorView, CohortFormView,
|
||||
CourseCohortSettingsNotificationView, NotificationModel, NotificationView, FileUploaderView,
|
||||
InlineDiscussionsView, CourseWideDiscussionsView) {
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(['jquery', 'underscore', 'backbone', 'gettext', 'js/groups/models/cohort',
|
||||
'js/groups/views/cohort_editor', 'js/groups/views/cohort_form',
|
||||
'js/groups/views/course_cohort_settings_notification',
|
||||
'js/groups/views/cohort_discussions_inline', 'js/groups/views/cohort_discussions_course_wide',
|
||||
'js/views/file_uploader', 'js/models/notification', 'js/views/notification', 'string_utils'],
|
||||
function($, _, Backbone, gettext, CohortModel, CohortEditorView, CohortFormView,
|
||||
CourseCohortSettingsNotificationView, InlineDiscussionsView, CourseWideDiscussionsView) {
|
||||
|
||||
var hiddenClass = 'is-hidden',
|
||||
disabledClass = 'is-disabled';
|
||||
var hiddenClass = 'is-hidden',
|
||||
disabledClass = 'is-disabled';
|
||||
|
||||
edx.groups = edx.groups || {};
|
||||
|
||||
edx.groups.CohortsView = Backbone.View.extend({
|
||||
events : {
|
||||
'change .cohort-select': 'onCohortSelected',
|
||||
'change .cohorts-state': 'onCohortsEnabledChanged',
|
||||
'click .action-create': 'showAddCohortForm',
|
||||
'click .cohort-management-add-form .action-save': 'saveAddCohortForm',
|
||||
'click .cohort-management-add-form .action-cancel': 'cancelAddCohortForm',
|
||||
'click .link-cross-reference': 'showSection',
|
||||
'click .toggle-cohort-management-secondary': 'showCsvUpload',
|
||||
'click .toggle-cohort-management-discussions': 'showDiscussionTopics'
|
||||
},
|
||||
var CohortsView = Backbone.View.extend({
|
||||
events : {
|
||||
'change .cohort-select': 'onCohortSelected',
|
||||
'change .cohorts-state': 'onCohortsEnabledChanged',
|
||||
'click .action-create': 'showAddCohortForm',
|
||||
'click .cohort-management-add-form .action-save': 'saveAddCohortForm',
|
||||
'click .cohort-management-add-form .action-cancel': 'cancelAddCohortForm',
|
||||
'click .link-cross-reference': 'showSection',
|
||||
'click .toggle-cohort-management-secondary': 'showCsvUpload',
|
||||
'click .toggle-cohort-management-discussions': 'showDiscussionTopics'
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
var model = this.model;
|
||||
initialize: function(options) {
|
||||
var model = this.model;
|
||||
|
||||
this.template = _.template($('#cohorts-tpl').text());
|
||||
this.selectorTemplate = _.template($('#cohort-selector-tpl').text());
|
||||
this.context = options.context;
|
||||
this.contentGroups = options.contentGroups;
|
||||
this.cohortSettings = options.cohortSettings;
|
||||
model.on('sync', this.onSync, this);
|
||||
this.template = _.template($('#cohorts-tpl').text());
|
||||
this.selectorTemplate = _.template($('#cohort-selector-tpl').text());
|
||||
this.context = options.context;
|
||||
this.contentGroups = options.contentGroups;
|
||||
this.cohortSettings = options.cohortSettings;
|
||||
model.on('sync', this.onSync, this);
|
||||
|
||||
// Update cohort counts when the user clicks back on the cohort management tab
|
||||
// (for example, after uploading a csv file of cohort assignments and then
|
||||
// checking results on data download tab).
|
||||
$(this.getSectionCss('cohort_management')).click(function () {
|
||||
model.fetch();
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.template({
|
||||
cohorts: this.model.models,
|
||||
cohortsEnabled: this.cohortSettings.get('is_cohorted')
|
||||
}));
|
||||
this.onSync();
|
||||
return this;
|
||||
},
|
||||
|
||||
renderSelector: function(selectedCohort) {
|
||||
this.$('.cohort-select').html(this.selectorTemplate({
|
||||
cohorts: this.model.models,
|
||||
selectedCohort: selectedCohort
|
||||
}));
|
||||
},
|
||||
|
||||
renderCourseCohortSettingsNotificationView: function() {
|
||||
var cohortStateMessageNotificationView = new CourseCohortSettingsNotificationView({
|
||||
el: $('.cohort-state-message'),
|
||||
cohortEnabled: this.getCohortsEnabled()
|
||||
});
|
||||
cohortStateMessageNotificationView.render();
|
||||
},
|
||||
|
||||
onSync: function(model, response, options) {
|
||||
var selectedCohort = this.lastSelectedCohortId && this.model.get(this.lastSelectedCohortId),
|
||||
hasCohorts = this.model.length > 0,
|
||||
cohortNavElement = this.$('.cohort-management-nav'),
|
||||
additionalCohortControlElement = this.$('.wrapper-cohort-supplemental'),
|
||||
isModelUpdate;
|
||||
isModelUpdate = function() {
|
||||
// Distinguish whether this is a sync event for just one model, or if it is for
|
||||
// an entire collection.
|
||||
return options && options.patch && response.hasOwnProperty('user_partition_id');
|
||||
};
|
||||
this.hideAddCohortForm();
|
||||
if (isModelUpdate()) {
|
||||
// Refresh the selector in case the model's name changed
|
||||
this.renderSelector(selectedCohort);
|
||||
} else if (hasCohorts) {
|
||||
cohortNavElement.removeClass(hiddenClass);
|
||||
additionalCohortControlElement.removeClass(hiddenClass);
|
||||
this.renderSelector(selectedCohort);
|
||||
if (selectedCohort) {
|
||||
this.showCohortEditor(selectedCohort);
|
||||
}
|
||||
} else {
|
||||
cohortNavElement.addClass(hiddenClass);
|
||||
additionalCohortControlElement.addClass(hiddenClass);
|
||||
this.showNotification({
|
||||
type: 'warning',
|
||||
title: gettext('You currently have no cohorts configured'),
|
||||
actionText: gettext('Add Cohort'),
|
||||
actionClass: 'action-create',
|
||||
actionIconClass: 'fa-plus'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
getSelectedCohort: function() {
|
||||
var id = this.$('.cohort-select').val();
|
||||
return id && this.model.get(parseInt(id));
|
||||
},
|
||||
|
||||
onCohortSelected: function(event) {
|
||||
event.preventDefault();
|
||||
var selectedCohort = this.getSelectedCohort();
|
||||
this.lastSelectedCohortId = selectedCohort.get('id');
|
||||
this.showCohortEditor(selectedCohort);
|
||||
},
|
||||
|
||||
onCohortsEnabledChanged: function(event) {
|
||||
event.preventDefault();
|
||||
this.saveCohortSettings();
|
||||
},
|
||||
|
||||
saveCohortSettings: function() {
|
||||
var self = this,
|
||||
cohortSettings,
|
||||
fieldData = {is_cohorted: this.getCohortsEnabled()};
|
||||
cohortSettings = this.cohortSettings;
|
||||
cohortSettings.save(
|
||||
fieldData, {patch: true, wait: true}
|
||||
).done(function() {
|
||||
self.render();
|
||||
self.renderCourseCohortSettingsNotificationView();
|
||||
}).fail(function(result) {
|
||||
self.showNotification({
|
||||
type: 'error',
|
||||
title: gettext("We've encountered an error. Refresh your browser and then try again.")},
|
||||
self.$('.cohorts-state-section')
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
getCohortsEnabled: function() {
|
||||
return this.$('.cohorts-state').prop('checked');
|
||||
},
|
||||
|
||||
showCohortEditor: function(cohort) {
|
||||
this.removeNotification();
|
||||
if (this.editor) {
|
||||
this.editor.setCohort(cohort);
|
||||
$('.cohort-management-group .group-header-title').focus();
|
||||
} else {
|
||||
this.editor = new CohortEditorView({
|
||||
el: this.$('.cohort-management-group'),
|
||||
model: cohort,
|
||||
cohorts: this.model,
|
||||
contentGroups: this.contentGroups,
|
||||
context: this.context
|
||||
});
|
||||
this.editor.render();
|
||||
$('.cohort-management-group .group-header-title').focus();
|
||||
}
|
||||
},
|
||||
|
||||
showNotification: function(options, beforeElement) {
|
||||
var model = new NotificationModel(options);
|
||||
this.removeNotification();
|
||||
this.notification = new NotificationView({
|
||||
model: model
|
||||
});
|
||||
|
||||
if (!beforeElement) {
|
||||
beforeElement = this.$('.cohort-management-group');
|
||||
}
|
||||
beforeElement.before(this.notification.$el);
|
||||
|
||||
this.notification.render();
|
||||
},
|
||||
|
||||
removeNotification: function() {
|
||||
if (this.notification) {
|
||||
this.notification.remove();
|
||||
}
|
||||
if (this.cohortFormView) {
|
||||
this.cohortFormView.removeNotification();
|
||||
}
|
||||
},
|
||||
|
||||
showAddCohortForm: function(event) {
|
||||
var newCohort;
|
||||
event.preventDefault();
|
||||
this.removeNotification();
|
||||
newCohort = new CohortModel();
|
||||
newCohort.url = this.model.url;
|
||||
this.cohortFormView = new CohortFormView({
|
||||
model: newCohort,
|
||||
contentGroups: this.contentGroups,
|
||||
context: this.context
|
||||
});
|
||||
this.cohortFormView.render();
|
||||
this.$('.cohort-management-add-form').append(this.cohortFormView.$el);
|
||||
this.cohortFormView.$('.cohort-name').focus();
|
||||
this.setCohortEditorVisibility(false);
|
||||
},
|
||||
|
||||
hideAddCohortForm: function() {
|
||||
this.setCohortEditorVisibility(true);
|
||||
if (this.cohortFormView) {
|
||||
this.cohortFormView.remove();
|
||||
this.cohortFormView = null;
|
||||
}
|
||||
},
|
||||
|
||||
setCohortEditorVisibility: function(showEditor) {
|
||||
if (showEditor) {
|
||||
this.$('.cohorts-state-section').removeClass(disabledClass).attr('aria-disabled', false);
|
||||
this.$('.cohort-management-group').removeClass(hiddenClass);
|
||||
this.$('.cohort-management-nav').removeClass(disabledClass).attr('aria-disabled', false);
|
||||
} else {
|
||||
this.$('.cohorts-state-section').addClass(disabledClass).attr('aria-disabled', true);
|
||||
this.$('.cohort-management-group').addClass(hiddenClass);
|
||||
this.$('.cohort-management-nav').addClass(disabledClass).attr('aria-disabled', true);
|
||||
}
|
||||
},
|
||||
|
||||
saveAddCohortForm: function(event) {
|
||||
var self = this,
|
||||
newCohort = this.cohortFormView.model;
|
||||
event.preventDefault();
|
||||
this.removeNotification();
|
||||
this.cohortFormView.saveForm()
|
||||
.done(function() {
|
||||
self.lastSelectedCohortId = newCohort.id;
|
||||
self.model.fetch().done(function() {
|
||||
self.showNotification({
|
||||
type: 'confirmation',
|
||||
title: interpolate_text(
|
||||
gettext('The {cohortGroupName} cohort has been created. You can manually add students to this cohort below.'),
|
||||
{cohortGroupName: newCohort.get('name')}
|
||||
)
|
||||
});
|
||||
// Update cohort counts when the user clicks back on the cohort management tab
|
||||
// (for example, after uploading a csv file of cohort assignments and then
|
||||
// checking results on data download tab).
|
||||
$(this.getSectionCss('cohort_management')).click(function () {
|
||||
model.fetch();
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
cancelAddCohortForm: function(event) {
|
||||
event.preventDefault();
|
||||
this.removeNotification();
|
||||
this.onSync();
|
||||
},
|
||||
render: function() {
|
||||
this.$el.html(this.template({
|
||||
cohorts: this.model.models,
|
||||
cohortsEnabled: this.cohortSettings.get('is_cohorted')
|
||||
}));
|
||||
this.onSync();
|
||||
return this;
|
||||
},
|
||||
|
||||
showSection: function(event) {
|
||||
event.preventDefault();
|
||||
var section = $(event.currentTarget).data("section");
|
||||
$(this.getSectionCss(section)).click();
|
||||
$(window).scrollTop(0);
|
||||
},
|
||||
renderSelector: function(selectedCohort) {
|
||||
this.$('.cohort-select').html(this.selectorTemplate({
|
||||
cohorts: this.model.models,
|
||||
selectedCohort: selectedCohort
|
||||
}));
|
||||
},
|
||||
|
||||
showCsvUpload: function(event) {
|
||||
event.preventDefault();
|
||||
renderCourseCohortSettingsNotificationView: function() {
|
||||
var cohortStateMessageNotificationView = new CourseCohortSettingsNotificationView({
|
||||
el: $('.cohort-state-message'),
|
||||
cohortEnabled: this.getCohortsEnabled()
|
||||
});
|
||||
cohortStateMessageNotificationView.render();
|
||||
},
|
||||
|
||||
$(event.currentTarget).addClass(hiddenClass);
|
||||
var uploadElement = this.$('.csv-upload').removeClass(hiddenClass);
|
||||
|
||||
if (!this.fileUploaderView) {
|
||||
this.fileUploaderView = new FileUploaderView({
|
||||
el: uploadElement,
|
||||
title: gettext("Assign students to cohorts by uploading a CSV file."),
|
||||
inputLabel: gettext("Choose a .csv file"),
|
||||
inputTip: gettext("Only properly formatted .csv files will be accepted."),
|
||||
submitButtonText: gettext("Upload File and Assign Students"),
|
||||
extensions: ".csv",
|
||||
url: this.context.uploadCohortsCsvUrl,
|
||||
successNotification: function (file, event, data) {
|
||||
var message = interpolate_text(gettext(
|
||||
"Your file '{file}' has been uploaded. Allow a few minutes for processing."
|
||||
), {file: file});
|
||||
return new NotificationModel({
|
||||
type: "confirmation",
|
||||
title: message
|
||||
onSync: function(model, response, options) {
|
||||
var selectedCohort = this.lastSelectedCohortId && this.model.get(this.lastSelectedCohortId),
|
||||
hasCohorts = this.model.length > 0,
|
||||
cohortNavElement = this.$('.cohort-management-nav'),
|
||||
additionalCohortControlElement = this.$('.wrapper-cohort-supplemental'),
|
||||
isModelUpdate;
|
||||
isModelUpdate = function() {
|
||||
// Distinguish whether this is a sync event for just one model, or if it is for
|
||||
// an entire collection.
|
||||
return options && options.patch && response.hasOwnProperty('user_partition_id');
|
||||
};
|
||||
this.hideAddCohortForm();
|
||||
if (isModelUpdate()) {
|
||||
// Refresh the selector in case the model's name changed
|
||||
this.renderSelector(selectedCohort);
|
||||
} else if (hasCohorts) {
|
||||
cohortNavElement.removeClass(hiddenClass);
|
||||
additionalCohortControlElement.removeClass(hiddenClass);
|
||||
this.renderSelector(selectedCohort);
|
||||
if (selectedCohort) {
|
||||
this.showCohortEditor(selectedCohort);
|
||||
}
|
||||
} else {
|
||||
cohortNavElement.addClass(hiddenClass);
|
||||
additionalCohortControlElement.addClass(hiddenClass);
|
||||
this.showNotification({
|
||||
type: 'warning',
|
||||
title: gettext('You currently have no cohorts configured'),
|
||||
actionText: gettext('Add Cohort'),
|
||||
actionClass: 'action-create',
|
||||
actionIconClass: 'fa-plus'
|
||||
});
|
||||
}
|
||||
}).render();
|
||||
this.$('#file-upload-form-file').focus();
|
||||
}
|
||||
},
|
||||
showDiscussionTopics: function(event) {
|
||||
event.preventDefault();
|
||||
},
|
||||
|
||||
$(event.currentTarget).addClass(hiddenClass);
|
||||
var cohortDiscussionsElement = this.$('.cohort-discussions-nav').removeClass(hiddenClass);
|
||||
getSelectedCohort: function() {
|
||||
var id = this.$('.cohort-select').val();
|
||||
return id && this.model.get(parseInt(id));
|
||||
},
|
||||
|
||||
if (!this.CourseWideDiscussionsView) {
|
||||
this.CourseWideDiscussionsView = new CourseWideDiscussionsView({
|
||||
el: cohortDiscussionsElement,
|
||||
model: this.context.discussionTopicsSettingsModel,
|
||||
cohortSettings: this.cohortSettings
|
||||
}).render();
|
||||
}
|
||||
if(!this.InlineDiscussionsView) {
|
||||
this.InlineDiscussionsView = new InlineDiscussionsView({
|
||||
el: cohortDiscussionsElement,
|
||||
model: this.context.discussionTopicsSettingsModel,
|
||||
cohortSettings: this.cohortSettings
|
||||
}).render();
|
||||
}
|
||||
},
|
||||
onCohortSelected: function(event) {
|
||||
event.preventDefault();
|
||||
var selectedCohort = this.getSelectedCohort();
|
||||
this.lastSelectedCohortId = selectedCohort.get('id');
|
||||
this.showCohortEditor(selectedCohort);
|
||||
},
|
||||
|
||||
getSectionCss: function (section) {
|
||||
return ".instructor-nav .nav-item a[data-section='" + section + "']";
|
||||
}
|
||||
onCohortsEnabledChanged: function(event) {
|
||||
event.preventDefault();
|
||||
this.saveCohortSettings();
|
||||
},
|
||||
|
||||
saveCohortSettings: function() {
|
||||
var self = this,
|
||||
cohortSettings,
|
||||
fieldData = {is_cohorted: this.getCohortsEnabled()};
|
||||
cohortSettings = this.cohortSettings;
|
||||
cohortSettings.save(
|
||||
fieldData, {patch: true, wait: true}
|
||||
).done(function() {
|
||||
self.render();
|
||||
self.renderCourseCohortSettingsNotificationView();
|
||||
}).fail(function(result) {
|
||||
self.showNotification({
|
||||
type: 'error',
|
||||
title: gettext("We've encountered an error. Refresh your browser and then try again.")},
|
||||
self.$('.cohorts-state-section')
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
getCohortsEnabled: function() {
|
||||
return this.$('.cohorts-state').prop('checked');
|
||||
},
|
||||
|
||||
showCohortEditor: function(cohort) {
|
||||
this.removeNotification();
|
||||
if (this.editor) {
|
||||
this.editor.setCohort(cohort);
|
||||
$('.cohort-management-group .group-header-title').focus();
|
||||
} else {
|
||||
this.editor = new CohortEditorView({
|
||||
el: this.$('.cohort-management-group'),
|
||||
model: cohort,
|
||||
cohorts: this.model,
|
||||
contentGroups: this.contentGroups,
|
||||
context: this.context
|
||||
});
|
||||
this.editor.render();
|
||||
$('.cohort-management-group .group-header-title').focus();
|
||||
}
|
||||
},
|
||||
|
||||
showNotification: function(options, beforeElement) {
|
||||
var model = new NotificationModel(options);
|
||||
this.removeNotification();
|
||||
this.notification = new NotificationView({
|
||||
model: model
|
||||
});
|
||||
|
||||
if (!beforeElement) {
|
||||
beforeElement = this.$('.cohort-management-group');
|
||||
}
|
||||
beforeElement.before(this.notification.$el);
|
||||
|
||||
this.notification.render();
|
||||
},
|
||||
|
||||
removeNotification: function() {
|
||||
if (this.notification) {
|
||||
this.notification.remove();
|
||||
}
|
||||
if (this.cohortFormView) {
|
||||
this.cohortFormView.removeNotification();
|
||||
}
|
||||
},
|
||||
|
||||
showAddCohortForm: function(event) {
|
||||
var newCohort;
|
||||
event.preventDefault();
|
||||
this.removeNotification();
|
||||
newCohort = new CohortModel();
|
||||
newCohort.url = this.model.url;
|
||||
this.cohortFormView = new CohortFormView({
|
||||
model: newCohort,
|
||||
contentGroups: this.contentGroups,
|
||||
context: this.context
|
||||
});
|
||||
this.cohortFormView.render();
|
||||
this.$('.cohort-management-add-form').append(this.cohortFormView.$el);
|
||||
this.cohortFormView.$('.cohort-name').focus();
|
||||
this.setCohortEditorVisibility(false);
|
||||
},
|
||||
|
||||
hideAddCohortForm: function() {
|
||||
this.setCohortEditorVisibility(true);
|
||||
if (this.cohortFormView) {
|
||||
this.cohortFormView.remove();
|
||||
this.cohortFormView = null;
|
||||
}
|
||||
},
|
||||
|
||||
setCohortEditorVisibility: function(showEditor) {
|
||||
if (showEditor) {
|
||||
this.$('.cohorts-state-section').removeClass(disabledClass).attr('aria-disabled', false);
|
||||
this.$('.cohort-management-group').removeClass(hiddenClass);
|
||||
this.$('.cohort-management-nav').removeClass(disabledClass).attr('aria-disabled', false);
|
||||
} else {
|
||||
this.$('.cohorts-state-section').addClass(disabledClass).attr('aria-disabled', true);
|
||||
this.$('.cohort-management-group').addClass(hiddenClass);
|
||||
this.$('.cohort-management-nav').addClass(disabledClass).attr('aria-disabled', true);
|
||||
}
|
||||
},
|
||||
|
||||
saveAddCohortForm: function(event) {
|
||||
var self = this,
|
||||
newCohort = this.cohortFormView.model;
|
||||
event.preventDefault();
|
||||
this.removeNotification();
|
||||
this.cohortFormView.saveForm()
|
||||
.done(function() {
|
||||
self.lastSelectedCohortId = newCohort.id;
|
||||
self.model.fetch().done(function() {
|
||||
self.showNotification({
|
||||
type: 'confirmation',
|
||||
title: interpolate_text(
|
||||
gettext('The {cohortGroupName} cohort has been created. You can manually add students to this cohort below.'),
|
||||
{cohortGroupName: newCohort.get('name')}
|
||||
)
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
cancelAddCohortForm: function(event) {
|
||||
event.preventDefault();
|
||||
this.removeNotification();
|
||||
this.onSync();
|
||||
},
|
||||
|
||||
showSection: function(event) {
|
||||
event.preventDefault();
|
||||
var section = $(event.currentTarget).data("section");
|
||||
$(this.getSectionCss(section)).click();
|
||||
$(window).scrollTop(0);
|
||||
},
|
||||
|
||||
showCsvUpload: function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
$(event.currentTarget).addClass(hiddenClass);
|
||||
var uploadElement = this.$('.csv-upload').removeClass(hiddenClass);
|
||||
|
||||
if (!this.fileUploaderView) {
|
||||
this.fileUploaderView = new FileUploaderView({
|
||||
el: uploadElement,
|
||||
title: gettext("Assign students to cohorts by uploading a CSV file."),
|
||||
inputLabel: gettext("Choose a .csv file"),
|
||||
inputTip: gettext("Only properly formatted .csv files will be accepted."),
|
||||
submitButtonText: gettext("Upload File and Assign Students"),
|
||||
extensions: ".csv",
|
||||
url: this.context.uploadCohortsCsvUrl,
|
||||
successNotification: function (file, event, data) {
|
||||
var message = interpolate_text(gettext(
|
||||
"Your file '{file}' has been uploaded. Allow a few minutes for processing."
|
||||
), {file: file});
|
||||
return new NotificationModel({
|
||||
type: "confirmation",
|
||||
title: message
|
||||
});
|
||||
}
|
||||
}).render();
|
||||
this.$('#file-upload-form-file').focus();
|
||||
}
|
||||
},
|
||||
showDiscussionTopics: function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
$(event.currentTarget).addClass(hiddenClass);
|
||||
var cohortDiscussionsElement = this.$('.cohort-discussions-nav').removeClass(hiddenClass);
|
||||
|
||||
if (!this.CourseWideDiscussionsView) {
|
||||
this.CourseWideDiscussionsView = new CourseWideDiscussionsView({
|
||||
el: cohortDiscussionsElement,
|
||||
model: this.context.discussionTopicsSettingsModel,
|
||||
cohortSettings: this.cohortSettings
|
||||
}).render();
|
||||
}
|
||||
if(!this.InlineDiscussionsView) {
|
||||
this.InlineDiscussionsView = new InlineDiscussionsView({
|
||||
el: cohortDiscussionsElement,
|
||||
model: this.context.discussionTopicsSettingsModel,
|
||||
cohortSettings: this.cohortSettings
|
||||
}).render();
|
||||
}
|
||||
},
|
||||
|
||||
getSectionCss: function (section) {
|
||||
return ".instructor-nav .nav-item a[data-section='" + section + "']";
|
||||
}
|
||||
});
|
||||
return CohortsView;
|
||||
});
|
||||
}).call(this, $, _, Backbone, gettext, interpolate_text, edx.groups.CohortModel, edx.groups.CohortEditorView,
|
||||
edx.groups.CohortFormView, edx.groups.CourseCohortSettingsNotificationView, NotificationModel, NotificationView,
|
||||
FileUploaderView, edx.groups.InlineDiscussionsView, edx.groups.CourseWideDiscussionsView);
|
||||
}).call(this, define || RequireJS.define);
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
;(function (define, undefined) {
|
||||
'use strict';
|
||||
define(['jquery', 'js/groups/views/cohorts', 'js/groups/collections/cohort', 'js/groups/models/course_cohort_settings',
|
||||
'js/groups/models/cohort_discussions'],
|
||||
function($) {
|
||||
'js/groups/models/cohort_discussions', 'js/groups/models/content_group'],
|
||||
function($, CohortsView, CohortCollection, CourseCohortSettingsModel, DiscussionTopicsSettingsModel, ContentGroupModel) {
|
||||
|
||||
return function(contentGroups, studioGroupConfigurationsUrl) {
|
||||
var contentGroupModels = $.map(contentGroups, function(group) {
|
||||
return new ContentGroupModel({
|
||||
id: group.id,
|
||||
name: group.name,
|
||||
user_partition_id: group.user_partition_id
|
||||
});
|
||||
});
|
||||
|
||||
var cohorts = new edx.groups.CohortCollection(),
|
||||
courseCohortSettings = new edx.groups.CourseCohortSettingsModel(),
|
||||
discussionTopicsSettings = new edx.groups.DiscussionTopicsSettingsModel();
|
||||
var cohorts = new CohortCollection(),
|
||||
courseCohortSettings = new CourseCohortSettingsModel(),
|
||||
discussionTopicsSettings = new DiscussionTopicsSettingsModel();
|
||||
|
||||
var cohortManagementElement = $('.cohort-management');
|
||||
|
||||
@@ -16,10 +23,10 @@
|
||||
courseCohortSettings.url = cohortManagementElement.data('course_cohort_settings_url');
|
||||
discussionTopicsSettings.url = cohortManagementElement.data('discussion-topics-url');
|
||||
|
||||
var cohortsView = new edx.groups.CohortsView({
|
||||
var cohortsView = new CohortsView({
|
||||
el: cohortManagementElement,
|
||||
model: cohorts,
|
||||
contentGroups: contentGroups,
|
||||
contentGroups: contentGroupModels,
|
||||
cohortSettings: courseCohortSettings,
|
||||
context: {
|
||||
discussionTopicsSettingsModel: discussionTopicsSettings,
|
||||
|
||||
@@ -1,31 +1,30 @@
|
||||
var edx = edx || {};
|
||||
|
||||
(function($, _, Backbone, gettext) {
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(['jquery', 'underscore', 'backbone', 'gettext'], function($, _, Backbone, gettext) {
|
||||
|
||||
edx.groups = edx.groups || {};
|
||||
var CourseCohortSettingsNotificationView = Backbone.View.extend({
|
||||
initialize: function(options) {
|
||||
this.template = _.template($('#cohort-state-tpl').text());
|
||||
this.cohortEnabled = options.cohortEnabled;
|
||||
},
|
||||
|
||||
edx.groups.CourseCohortSettingsNotificationView = Backbone.View.extend({
|
||||
initialize: function(options) {
|
||||
this.template = _.template($('#cohort-state-tpl').text());
|
||||
this.cohortEnabled = options.cohortEnabled;
|
||||
},
|
||||
render: function() {
|
||||
this.$el.html(this.template({}));
|
||||
this.showCohortStateMessage();
|
||||
return this;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.template({}));
|
||||
this.showCohortStateMessage();
|
||||
return this;
|
||||
},
|
||||
showCohortStateMessage: function () {
|
||||
var actionToggleMessage = this.$('.action-toggle-message');
|
||||
|
||||
showCohortStateMessage: function () {
|
||||
var actionToggleMessage = this.$('.action-toggle-message');
|
||||
|
||||
AnimationUtil.triggerAnimation(actionToggleMessage);
|
||||
if (this.cohortEnabled) {
|
||||
actionToggleMessage.text(gettext('Cohorts Enabled'));
|
||||
} else {
|
||||
actionToggleMessage.text(gettext('Cohorts Disabled'));
|
||||
AnimationUtil.triggerAnimation(actionToggleMessage);
|
||||
if (this.cohortEnabled) {
|
||||
actionToggleMessage.text(gettext('Cohorts Enabled'));
|
||||
} else {
|
||||
actionToggleMessage.text(gettext('Cohorts Disabled'));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return CourseCohortSettingsNotificationView;
|
||||
});
|
||||
}).call(this, $, _, Backbone, gettext);
|
||||
}).call(this, define || RequireJS.define);
|
||||
|
||||
@@ -67,18 +67,6 @@
|
||||
'js/models/notification': 'js/models/notification',
|
||||
'js/views/file_uploader': 'js/views/file_uploader',
|
||||
'js/views/notification': 'js/views/notification',
|
||||
'js/groups/models/cohort': 'js/groups/models/cohort',
|
||||
'js/groups/models/content_group': 'js/groups/models/content_group',
|
||||
'js/groups/models/course_cohort_settings': 'js/groups/models/course_cohort_settings',
|
||||
'js/groups/models/cohort_discussions': 'js/groups/models/cohort_discussions',
|
||||
'js/groups/views/cohort_discussions': 'js/groups/views/cohort_discussions',
|
||||
'js/groups/views/cohort_discussions_course_wide': 'js/groups/views/cohort_discussions_course_wide',
|
||||
'js/groups/views/cohort_discussions_inline': 'js/groups/views/cohort_discussions_inline',
|
||||
'js/groups/views/course_cohort_settings_notification': 'js/groups/views/course_cohort_settings_notification',
|
||||
'js/groups/collections/cohort': 'js/groups/collections/cohort',
|
||||
'js/groups/views/cohort_editor': 'js/groups/views/cohort_editor',
|
||||
'js/groups/views/cohort_form': 'js/groups/views/cohort_form',
|
||||
'js/groups/views/cohorts': 'js/groups/views/cohorts',
|
||||
'js/student_account/account': 'js/student_account/account',
|
||||
'js/student_account/views/FormView': 'js/student_account/views/FormView',
|
||||
'js/student_account/models/LoginModel': 'js/student_account/models/LoginModel',
|
||||
@@ -301,63 +289,6 @@
|
||||
exports: 'edx.instructor_dashboard.ecommerce.ExpiryCouponView',
|
||||
deps: ['backbone', 'jquery', 'underscore']
|
||||
},
|
||||
'js/groups/models/cohort': {
|
||||
exports: 'edx.groups.CohortModel',
|
||||
deps: ['backbone']
|
||||
},
|
||||
'js/groups/models/content_group': {
|
||||
exports: 'edx.groups.ContentGroupModel',
|
||||
deps: ['backbone']
|
||||
},
|
||||
'js/groups/models/course_cohort_settings': {
|
||||
exports: 'edx.groups.CourseCohortSettingsModel',
|
||||
deps: ['backbone']
|
||||
},
|
||||
'js/groups/models/cohort_discussions': {
|
||||
exports: 'edx.groups.DiscussionTopicsSettingsModel',
|
||||
deps: ['backbone']
|
||||
},
|
||||
'js/groups/views/cohort_discussions': {
|
||||
exports: 'edx.groups.CohortDiscussionConfigurationView',
|
||||
deps: ['backbone']
|
||||
},
|
||||
'js/groups/views/cohort_discussions_course_wide': {
|
||||
exports: 'edx.groups.CourseWideDiscussionsView',
|
||||
deps: ['backbone', 'js/groups/views/cohort_discussions']
|
||||
},
|
||||
'js/groups/views/cohort_discussions_inline': {
|
||||
exports: 'edx.groups.InlineDiscussionsView',
|
||||
deps: ['backbone', 'js/groups/views/cohort_discussions', 'js/vendor/jquery.qubit']
|
||||
},
|
||||
'js/groups/views/course_cohort_settings_notification': {
|
||||
exports: 'edx.groups.CourseCohortSettingsNotificationView',
|
||||
deps: ['backbone']
|
||||
},
|
||||
'js/groups/collections/cohort': {
|
||||
exports: 'edx.groups.CohortCollection',
|
||||
deps: ['backbone', 'js/groups/models/cohort']
|
||||
},
|
||||
'js/groups/views/cohort_form': {
|
||||
exports: 'edx.groups.CohortFormView',
|
||||
deps: [
|
||||
'backbone', 'jquery', 'underscore', 'js/views/notification', 'js/models/notification',
|
||||
'string_utils'
|
||||
]
|
||||
},
|
||||
'js/groups/views/cohort_editor': {
|
||||
exports: 'edx.groups.CohortEditorView',
|
||||
deps: [
|
||||
'backbone', 'jquery', 'underscore', 'js/views/notification', 'js/models/notification',
|
||||
'string_utils', 'js/groups/views/cohort_form'
|
||||
]
|
||||
},
|
||||
'js/groups/views/cohorts': {
|
||||
exports: 'edx.groups.CohortsView',
|
||||
deps: [
|
||||
'jquery', 'underscore', 'backbone', 'gettext', 'string_utils', 'js/groups/views/cohort_editor',
|
||||
'js/views/notification', 'js/models/notification', 'js/views/file_uploader'
|
||||
]
|
||||
},
|
||||
'js/models/notification': {
|
||||
exports: 'NotificationModel',
|
||||
deps: ['backbone']
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* done.
|
||||
*/
|
||||
modules: getModulesList([
|
||||
'js/groups/views/cohorts_dashboard_factory',
|
||||
'js/student_account/views/account_settings_factory',
|
||||
'js/student_account/views/finish_auth_factory',
|
||||
'js/student_profile/views/learner_profile_factory',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<%page args="section_data"/>
|
||||
<%namespace name='static' file='../../static_content.html'/>
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from courseware.courses import get_studio_url
|
||||
@@ -16,32 +17,23 @@ from openedx.core.djangoapps.course_groups.partition_scheme import get_cohorted_
|
||||
</div>
|
||||
|
||||
|
||||
<%block name="headextra">
|
||||
<%block name="js_extra">
|
||||
<%static:require_module module_name="js/groups/views/cohorts_dashboard_factory" class_name="CohortsFactory">
|
||||
<%
|
||||
cohorted_user_partition = get_cohorted_user_partition(course.id)
|
||||
content_groups = cohorted_user_partition.groups if cohorted_user_partition else []
|
||||
%>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
|
||||
var cohortUserPartitionId = ${cohorted_user_partition.id if cohorted_user_partition else 'null'},
|
||||
contentGroups = [
|
||||
% for content_group in content_groups:
|
||||
new edx.groups.ContentGroupModel({
|
||||
id: ${content_group.id},
|
||||
name: "${content_group.name | h}",
|
||||
user_partition_id: cohortUserPartitionId
|
||||
}),
|
||||
% endfor
|
||||
];
|
||||
|
||||
(function (require) {
|
||||
require(['js/groups/views/cohorts_dashboard_factory'], function (CohortsFactory) {
|
||||
CohortsFactory(contentGroups, '${get_studio_url(course, 'group_configurations') | h}');
|
||||
});
|
||||
}).call(this, require || RequireJS.require);
|
||||
});
|
||||
</script>
|
||||
|
||||
var cohortUserPartitionId = ${cohorted_user_partition.id if cohorted_user_partition else 'null'},
|
||||
contentGroups = [
|
||||
% for content_group in content_groups:
|
||||
{
|
||||
id: ${content_group.id},
|
||||
name: "${content_group.name | h}",
|
||||
user_partition_id: cohortUserPartitionId
|
||||
},
|
||||
% endfor
|
||||
];
|
||||
CohortsFactory(contentGroups, '${get_studio_url(course, 'group_configurations') | h}');
|
||||
</%static:require_module>
|
||||
</%block>
|
||||
<div class="cohort-state-message"></div>
|
||||
|
||||
@@ -56,22 +56,9 @@ from django.core.urlresolvers import reverse
|
||||
<%static:js group='application'/>
|
||||
|
||||
## Backbone classes declared explicitly until RequireJS is supported
|
||||
<script type="text/javascript" src="${static.url('js/instructor_dashboard/cohort_management.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/models/notification.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/views/notification.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/views/file_uploader.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/groups/models/cohort.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/groups/models/content_group.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/groups/models/course_cohort_settings.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/groups/collections/cohort.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/groups/views/course_cohort_settings_notification.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/groups/models/cohort_discussions.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/groups/views/cohort_discussions.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/groups/views/cohort_discussions_course_wide.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/groups/views/cohort_discussions_inline.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/groups/views/cohort_form.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/groups/views/cohort_editor.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/groups/views/cohorts.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/utils/animation.js')}"></script>
|
||||
</%block>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user