Commit eff80bae by Diana Huang Committed by cahrens

Convert cohort JS to use RequireJS.

parent 1ceb8a0d
var edx = edx || {}; ;(function (define) {
(function(Backbone, CohortModel) {
'use strict'; 'use strict';
define(['backbone', 'js/groups/models/cohort'], function(Backbone, CohortModel) {
edx.groups = edx.groups || {}; var CohortCollection = Backbone.Collection.extend({
model : CohortModel,
edx.groups.CohortCollection = Backbone.Collection.extend({ comparator: "name",
model : CohortModel,
comparator: "name",
parse: function(response) { parse: function(response) {
return response.cohorts; return response.cohorts;
} }
});
return CohortCollection;
}); });
}).call(this, Backbone, edx.groups.CohortModel); }).call(this, define || RequireJS.define);
var edx = edx || {}; ;(function (define) {
(function(Backbone) {
'use strict'; 'use strict';
define(['backbone'], function(Backbone) {
edx.groups = edx.groups || {}; var CohortModel = Backbone.Model.extend({
idAttribute: 'id',
edx.groups.CohortModel = Backbone.Model.extend({ defaults: {
idAttribute: 'id', name: '',
defaults: { user_count: 0,
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).
* Indicates how students are added to the cohort. Will be "none" (signifying manual assignment) or */
* "random" (indicating students are randomly assigned). assignment_type: '',
*/ /**
assignment_type: '', * If this cohort is associated with a user partition group, the ID of the user partition.
/** */
* If this cohort is associated with a user partition group, the ID of the user partition. user_partition_id: null,
*/ /**
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.
* 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
*/ }
group_id: null });
} return CohortModel;
}); });
}).call(this, Backbone); }).call(this, define || RequireJS.define);
var edx = edx || {}; ;(function (define) {
(function(Backbone) {
'use strict'; 'use strict';
define(['backbone'], function(Backbone) {
edx.groups = edx.groups || {}; var DiscussionTopicsSettingsModel = Backbone.Model.extend({
defaults: {
edx.groups.DiscussionTopicsSettingsModel = Backbone.Model.extend({ course_wide_discussions: {},
defaults: { inline_discussions: {}
course_wide_discussions: {}, }
inline_discussions: {} });
} return DiscussionTopicsSettingsModel;
}); });
}).call(this, Backbone); }).call(this, define || RequireJS.define);
var edx = edx || {}; ;(function (define) {
(function(Backbone) {
'use strict'; 'use strict';
define(['backbone'], function(Backbone) {
edx.groups = edx.groups || {}; var ContentGroupModel = Backbone.Model.extend({
idAttribute: 'id',
edx.groups.ContentGroupModel = Backbone.Model.extend({ defaults: {
idAttribute: 'id', name: '',
defaults: { user_partition_id: null
name: '', }
user_partition_id: null });
} return ContentGroupModel;
}); });
}).call(this, Backbone); }).call(this, define || RequireJS.define);
var edx = edx || {}; ;(function (define) {
(function(Backbone) {
'use strict'; 'use strict';
define(['backbone'], function(Backbone) {
edx.groups = edx.groups || {}; var CourseCohortSettingsModel = Backbone.Model.extend({
idAttribute: 'id',
edx.groups.CourseCohortSettingsModel = Backbone.Model.extend({ defaults: {
idAttribute: 'id', is_cohorted: false,
defaults: { cohorted_inline_discussions: [],
is_cohorted: false, cohorted_course_wide_discussions:[],
cohorted_inline_discussions: [], always_cohort_inline_discussions: true
cohorted_course_wide_discussions:[], }
always_cohort_inline_discussions: true });
} return CourseCohortSettingsModel;
}); });
}).call(this, Backbone); }).call(this, define || RequireJS.define);
var edx = edx || {}; ;(function (define) {
(function ($, _, Backbone, gettext, interpolate_text, NotificationModel, NotificationView) {
'use strict'; '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. * Returns the cohorted discussions list.
* @param {object} $element - The element to disable/enable. * @param {string} selector - To select the discussion elements whose ids to return.
* @param {bool} disable - The flag to add/remove 'disabled' attribute. * @returns {Array} - Cohorted discussions.
*/ */
setDisabled: function($element, disable) { getCohortedDiscussions: function(selector) {
$element.prop('disabled', disable ? 'disabled' : false); var self=this,
}, cohortedDiscussions = [];
/** _.each(self.$(selector), function (topic) {
* Returns the cohorted discussions list. cohortedDiscussions.push($(topic).data('id'))
* @param {string} selector - To select the discussion elements whose ids to return. });
* @returns {Array} - Cohorted discussions. return cohortedDiscussions;
*/ },
getCohortedDiscussions: function(selector) {
var self=this,
cohortedDiscussions = [];
_.each(self.$(selector), function (topic) { /**
cohortedDiscussions.push($(topic).data('id')) * Save the cohortSettings' changed attributes to the server via PATCH method.
}); * It shows the error message(s) if any.
return cohortedDiscussions; * @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) {
* Save the cohortSettings' changed attributes to the server via PATCH method. self.showMessage(message, $element, 'error');
* It shows the error message(s) if any. };
* @param {object} $element - Messages would be shown before this element. this.removeNotification();
* @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) { cohortSettingsModel.save(
self.showMessage(message, $element, 'error'); fieldData, {patch: true, wait: true}
}; ).done(function () {
this.removeNotification(); 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} * Shows the notification messages before given element using the NotificationModel.
).done(function () { * @param {string} message - Text message to show.
saveOperation.resolve(); * @param {object} $element - Message would be shown before this element.
}).fail(function (result) { * @param {string} type - Type of message to show e.g. confirmation or error.
var errorMessage = null; */
try { showMessage: function (message, $element, type) {
var jsonResponse = JSON.parse(result.responseText); var model = new NotificationModel({type: type || 'confirmation', title: message});
errorMessage = jsonResponse.error; this.removeNotification();
} catch (e) { this.notification = new NotificationView({
// Ignore the exception and show the default error message instead. model: model
} });
if (!errorMessage) { $element.before(this.notification.$el);
errorMessage = gettext("We've encountered an error. Refresh your browser and then try again."); this.notification.render();
},
/**
*Removes the notification messages.
*/
removeNotification: function () {
if (this.notification) {
this.notification.remove();
}
} }
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); return CohortDiscussionConfigurationView;
this.notification.render(); });
}, }).call(this, define || RequireJS.define);
/**
*Removes the notification messages.
*/
removeNotification: function () {
if (this.notification) {
this.notification.remove();
}
}
});
}).call(this, $, _, Backbone, gettext, interpolate_text, NotificationModel, NotificationView
);
var edx = edx || {}; ;(function (define) {
(function ($, _, Backbone, gettext, interpolate_text, CohortDiscussionConfigurationView) {
'use strict'; '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());
edx.groups.CourseWideDiscussionsView = CohortDiscussionConfigurationView.extend({ this.cohortSettings = options.cohortSettings;
events: { },
'change .check-discussion-subcategory-course-wide': 'discussionCategoryStateChanged',
'click .cohort-course-wide-discussions-form .action-save': 'saveCourseWideDiscussionsForm'
},
initialize: function (options) { render: function () {
this.template = _.template($('#cohort-discussions-course-wide-tpl').text()); this.$('.cohort-course-wide-discussions-nav').html(this.template({
this.cohortSettings = options.cohortSettings; courseWideTopics: this.getCourseWideDiscussionsHtml(
}, this.model.get('course_wide_discussions')
)
}));
this.setDisabled(this.$('.cohort-course-wide-discussions-form .action-save'), true);
},
render: function () { /**
this.$('.cohort-course-wide-discussions-nav').html(this.template({ * Returns the html list for course-wide discussion topics.
courseWideTopics: this.getCourseWideDiscussionsHtml( * @param {object} courseWideDiscussions - course-wide discussions object from server.
this.model.get('course_wide_discussions') * @returns {Array} - HTML list for course-wide discussion topics.
) */
})); getCourseWideDiscussionsHtml: function (courseWideDiscussions) {
this.setDisabled(this.$('.cohort-course-wide-discussions-form .action-save'), true); var subCategoryTemplate = _.template($('#cohort-discussions-subcategory-tpl').html()),
}, entries = courseWideDiscussions.entries,
children = courseWideDiscussions.children;
/** return _.map(children, function (name) {
* Returns the html list for course-wide discussion topics. var entry = entries[name];
* @param {object} courseWideDiscussions - course-wide discussions object from server. return subCategoryTemplate({
* @returns {Array} - HTML list for course-wide discussion topics. name: name,
*/ id: entry.id,
getCourseWideDiscussionsHtml: function (courseWideDiscussions) { is_cohorted: entry.is_cohorted,
var subCategoryTemplate = _.template($('#cohort-discussions-subcategory-tpl').html()), type: 'course-wide'
entries = courseWideDiscussions.entries, });
children = courseWideDiscussions.children; }).join('');
},
return _.map(children, function (name) { /**
var entry = entries[name]; * Enables the save button for course-wide discussions.
return subCategoryTemplate({ */
name: name, discussionCategoryStateChanged: function(event) {
id: entry.id, event.preventDefault();
is_cohorted: entry.is_cohorted, this.setDisabled(this.$('.cohort-course-wide-discussions-form .action-save'), false);
type: 'course-wide' },
});
}).join('');
},
/** /**
* Enables the save button for course-wide discussions. * Sends the cohorted_course_wide_discussions to the server and renders the view.
*/ */
discussionCategoryStateChanged: function(event) { saveCourseWideDiscussionsForm: function (event) {
event.preventDefault(); event.preventDefault();
this.setDisabled(this.$('.cohort-course-wide-discussions-form .action-save'), false);
},
/** var self = this,
* Sends the cohorted_course_wide_discussions to the server and renders the view. courseWideCohortedDiscussions = self.getCohortedDiscussions(
*/ '.check-discussion-subcategory-course-wide:checked'
saveCourseWideDiscussionsForm: function (event) { ),
event.preventDefault(); fieldData = { cohorted_course_wide_discussions: courseWideCohortedDiscussions };
var self = this, self.saveForm(self.$('.course-wide-discussion-topics'),fieldData)
courseWideCohortedDiscussions = self.getCohortedDiscussions( .done(function () {
'.check-discussion-subcategory-course-wide:checked' self.model.fetch()
), .done(function () {
fieldData = { cohorted_course_wide_discussions: courseWideCohortedDiscussions }; 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')
});
});
}
self.saveForm(self.$('.course-wide-discussion-topics'),fieldData) });
.done(function () { return CourseWideDiscussionsView;
self.model.fetch() });
.done(function () { }).call(this, define || RequireJS.define);
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);
var edx = edx || {}; ;(function (define) {
(function ($, _, Backbone, gettext, interpolate_text, CohortDiscussionConfigurationView) {
'use strict'; 'use strict';
define(['jquery', 'underscore', 'backbone', 'gettext', 'js/groups/views/cohort_discussions', 'js/vendor/jquery.qubit'],
edx.groups = edx.groups || {}; function ($, _, Backbone, gettext, CohortDiscussionConfigurationView) {
var InlineDiscussionsView = CohortDiscussionConfigurationView.extend({
edx.groups.InlineDiscussionsView = CohortDiscussionConfigurationView.extend({ events: {
events: { 'change .check-discussion-category': 'setSaveButton',
'change .check-discussion-category': 'setSaveButton', 'change .check-discussion-subcategory-inline': 'setSaveButton',
'change .check-discussion-subcategory-inline': 'setSaveButton', 'click .cohort-inline-discussions-form .action-save': 'saveInlineDiscussionsForm',
'click .cohort-inline-discussions-form .action-save': 'saveInlineDiscussionsForm', 'change .check-all-inline-discussions': 'setAllInlineDiscussions',
'change .check-all-inline-discussions': 'setAllInlineDiscussions', 'change .check-cohort-inline-discussions': 'setSomeInlineDiscussions'
'change .check-cohort-inline-discussions': 'setSomeInlineDiscussions' },
},
initialize: function (options) {
initialize: function (options) { this.template = _.template($('#cohort-discussions-inline-tpl').text());
this.template = _.template($('#cohort-discussions-inline-tpl').text()); this.cohortSettings = options.cohortSettings;
this.cohortSettings = options.cohortSettings; },
},
render: function () {
render: function () { var alwaysCohortInlineDiscussions = this.cohortSettings.get('always_cohort_inline_discussions');
var alwaysCohortInlineDiscussions = this.cohortSettings.get('always_cohort_inline_discussions');
this.$('.cohort-inline-discussions-nav').html(this.template({
this.$('.cohort-inline-discussions-nav').html(this.template({ inlineDiscussionTopics: this.getInlineDiscussionsHtml(this.model.get('inline_discussions')),
inlineDiscussionTopics: this.getInlineDiscussionsHtml(this.model.get('inline_discussions')), alwaysCohortInlineDiscussions:alwaysCohortInlineDiscussions
alwaysCohortInlineDiscussions:alwaysCohortInlineDiscussions }));
}));
// Provides the semantics for a nested list of tri-state checkboxes.
// Provides the semantics for a nested list of tri-state checkboxes. // When attached to a jQuery element it listens for change events to
// When attached to a jQuery element it listens for change events to // input[type=checkbox] elements, and updates the checked and indeterminate
// input[type=checkbox] elements, and updates the checked and indeterminate // based on the checked values of any checkboxes in child elements of the DOM.
// based on the checked values of any checkboxes in child elements of the DOM. this.$('ul.inline-topics').qubit();
this.$('ul.inline-topics').qubit();
this.setElementsEnabled(alwaysCohortInlineDiscussions, true);
this.setElementsEnabled(alwaysCohortInlineDiscussions, true); },
},
/**
/** * Generate html list for inline discussion topics.
* Generate html list for inline discussion topics. * @params {object} inlineDiscussions - inline discussions object from server.
* @params {object} inlineDiscussions - inline discussions object from server. * @returns {Array} - HTML for inline discussion topics.
* @returns {Array} - HTML for inline discussion topics. */
*/ getInlineDiscussionsHtml: function (inlineDiscussions) {
getInlineDiscussionsHtml: function (inlineDiscussions) { var categoryTemplate = _.template($('#cohort-discussions-category-tpl').html()),
var categoryTemplate = _.template($('#cohort-discussions-category-tpl').html()), entryTemplate = _.template($('#cohort-discussions-subcategory-tpl').html()),
entryTemplate = _.template($('#cohort-discussions-subcategory-tpl').html()), isCategoryCohorted = false,
isCategoryCohorted = false, children = inlineDiscussions.children,
children = inlineDiscussions.children, entries = inlineDiscussions.entries,
entries = inlineDiscussions.entries, subcategories = inlineDiscussions.subcategories;
subcategories = inlineDiscussions.subcategories;
return _.map(children, function (name) {
return _.map(children, function (name) { var html = '', entry;
var html = '', entry; if (entries && _.has(entries, name)) {
if (entries && _.has(entries, name)) { entry = entries[name];
entry = entries[name]; html = entryTemplate({
html = entryTemplate({ name: name,
name: name, id: entry.id,
id: entry.id, is_cohorted: entry.is_cohorted,
is_cohorted: entry.is_cohorted, type: 'inline'
type: 'inline' });
}); } else { // subcategory
} else { // subcategory html = categoryTemplate({
html = categoryTemplate({ name: name,
name: name, entries: this.getInlineDiscussionsHtml(subcategories[name]),
entries: this.getInlineDiscussionsHtml(subcategories[name]), isCategoryCohorted: isCategoryCohorted
isCategoryCohorted: isCategoryCohorted });
}); }
} return html;
return html; }, this).join('');
}, this).join(''); },
},
/**
/** * Enable/Disable the inline discussion elements.
* Enable/Disable the inline discussion elements. *
* * Disables the category and sub-category checkboxes.
* Disables the category and sub-category checkboxes. * Enables the save button.
* Enables the save button. */
*/ setAllInlineDiscussions: function(event) {
setAllInlineDiscussions: function(event) { event.preventDefault();
event.preventDefault(); this.setElementsEnabled(($(event.currentTarget).prop('checked')), false);
this.setElementsEnabled(($(event.currentTarget).prop('checked')), false); },
},
/**
/** * Enables the inline discussion elements.
* Enables the inline discussion elements. *
* * Enables the category and sub-category checkboxes.
* Enables the category and sub-category checkboxes. * Enables the save button.
* Enables the save button. */
*/ setSomeInlineDiscussions: function(event) {
setSomeInlineDiscussions: function(event) { event.preventDefault();
event.preventDefault(); this.setElementsEnabled(!($(event.currentTarget).prop('checked')), false);
this.setElementsEnabled(!($(event.currentTarget).prop('checked')), false); },
},
/**
/** * Enable/Disable the inline discussion elements.
* Enable/Disable the inline discussion elements. *
* * Enable/Disable the category and sub-category checkboxes.
* Enable/Disable the category and sub-category checkboxes. * Enable/Disable the save button.
* Enable/Disable the save button. * @param {bool} enable_checkboxes - The flag to enable/disable the checkboxes.
* @param {bool} enable_checkboxes - The flag to enable/disable the checkboxes. * @param {bool} enable_save_button - The flag to enable/disable the save button.
* @param {bool} enable_save_button - The flag to enable/disable the save button. */
*/ setElementsEnabled: function(enable_checkboxes, enable_save_button) {
setElementsEnabled: function(enable_checkboxes, enable_save_button) { this.setDisabled(this.$('.check-discussion-category'), enable_checkboxes);
this.setDisabled(this.$('.check-discussion-category'), enable_checkboxes); this.setDisabled(this.$('.check-discussion-subcategory-inline'), enable_checkboxes);
this.setDisabled(this.$('.check-discussion-subcategory-inline'), enable_checkboxes); this.setDisabled(this.$('.cohort-inline-discussions-form .action-save'), enable_save_button);
this.setDisabled(this.$('.cohort-inline-discussions-form .action-save'), enable_save_button); },
},
/**
/** * Enables the save button for inline discussions.
* Enables the save button for inline discussions. */
*/ setSaveButton: function(event) {
setSaveButton: function(event) { this.setDisabled(this.$('.cohort-inline-discussions-form .action-save'), false);
this.setDisabled(this.$('.cohort-inline-discussions-form .action-save'), false); },
},
/**
/** * Sends the cohorted_inline_discussions to the server and renders the view.
* Sends the cohorted_inline_discussions to the server and renders the view. */
*/ saveInlineDiscussionsForm: function (event) {
saveInlineDiscussionsForm: function (event) { event.preventDefault();
event.preventDefault();
var self = this,
var self = this, cohortedInlineDiscussions = self.getCohortedDiscussions(
cohortedInlineDiscussions = self.getCohortedDiscussions( '.check-discussion-subcategory-inline:checked'
'.check-discussion-subcategory-inline:checked' ),
), fieldData= {
fieldData= { cohorted_inline_discussions: cohortedInlineDiscussions,
cohorted_inline_discussions: cohortedInlineDiscussions, always_cohort_inline_discussions: self.$('.check-all-inline-discussions').prop('checked')
always_cohort_inline_discussions: self.$('.check-all-inline-discussions').prop('checked') };
};
self.saveForm(self.$('.inline-discussion-topics'), fieldData)
self.saveForm(self.$('.inline-discussion-topics'), fieldData) .done(function () {
.done(function () { self.model.fetch()
self.model.fetch() .done(function () {
.done(function () { self.render();
self.render(); self.showMessage(gettext('Your changes have been saved.'), self.$('.inline-discussion-topics'));
self.showMessage(gettext('Your changes have been saved.'), self.$('.inline-discussion-topics')); }).fail(function() {
}).fail(function() { var errorMessage = gettext("We've encountered an error. Refresh your browser and then try again.");
var errorMessage = gettext("We've encountered an error. Refresh your browser and then try again."); self.showMessage(errorMessage, self.$('.inline-discussion-topics'), 'error')
self.showMessage(errorMessage, self.$('.inline-discussion-topics'), 'error') });
}); });
}); }
}
});
return InlineDiscussionsView;
}); });
}).call(this, $, _, Backbone, gettext, interpolate_text, edx.groups.CohortDiscussionConfigurationView); }).call(this, define || RequireJS.define);
var edx = edx || {}; ;(function (define) {
(function(Backbone, _, $, gettext, ngettext, interpolate_text, CohortFormView, NotificationModel, NotificationView) {
'use strict'; 'use strict';
define(['backbone', 'underscore', 'jquery', 'gettext', 'js/groups/views/cohort_form', 'string_utils',
edx.groups = edx.groups || {}; 'js/models/notification', 'js/views/notification'],
function(Backbone, _, $, gettext, CohortFormView) {
edx.groups.CohortEditorView = Backbone.View.extend({ var CohortEditorView = Backbone.View.extend({
events : { events : {
'click .wrapper-tabs .tab': 'selectTab', 'click .wrapper-tabs .tab': 'selectTab',
'click .tab-content-settings .action-save': 'saveSettings', 'click .tab-content-settings .action-save': 'saveSettings',
'click .tab-content-settings .action-cancel': 'cancelSettings', 'click .tab-content-settings .action-cancel': 'cancelSettings',
'submit .cohort-management-group-add-form': 'addStudents' 'submit .cohort-management-group-add-form': 'addStudents'
}, },
initialize: function(options) { initialize: function(options) {
this.template = _.template($('#cohort-editor-tpl').text()); this.template = _.template($('#cohort-editor-tpl').text());
this.groupHeaderTemplate = _.template($('#cohort-group-header-tpl').text()); this.groupHeaderTemplate = _.template($('#cohort-group-header-tpl').text());
this.cohorts = options.cohorts; this.cohorts = options.cohorts;
this.contentGroups = options.contentGroups; this.contentGroups = options.contentGroups;
this.context = options.context; this.context = options.context;
}, },
// Any errors that are currently being displayed to the instructor (for example, unknown email addresses). // Any errors that are currently being displayed to the instructor (for example, unknown email addresses).
errorNotifications: null, errorNotifications: null,
// Any confirmation messages that are currently being displayed (for example, number of students added). // Any confirmation messages that are currently being displayed (for example, number of students added).
confirmationNotifications: null, confirmationNotifications: null,
render: function() { render: function() {
this.$el.html(this.template({ this.$el.html(this.template({
cohort: this.model cohort: this.model
})); }));
this.renderGroupHeader(); this.renderGroupHeader();
this.cohortFormView = new CohortFormView({ this.cohortFormView = new CohortFormView({
model: this.model, model: this.model,
contentGroups: this.contentGroups, contentGroups: this.contentGroups,
context: this.context 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);
}
}); });
}).fail(function() { this.cohortFormView.render();
self.showErrorMessage(gettext('Error adding students.'), true); this.$('.tab-content-settings').append(this.cohortFormView.$el);
}); return this;
} else { },
self.showErrorMessage(gettext('Enter a username or email.'), true);
input.val(''); renderGroupHeader: function() {
} this.$('.cohort-management-group-header').html(this.groupHeaderTemplate({
}, cohort: this.model
}));
/** },
* Refresh the cohort collection to get the latest set as well as up-to-date counts.
*/ selectTab: function(event) {
refreshCohorts: function() { var tabElement = $(event.currentTarget),
return this.cohorts.fetch(); tabName = tabElement.data('tab');
}, event.preventDefault();
this.$('.wrapper-tabs .tab').removeClass('is-selected');
undelegateViewEvents: function (view) { this.$('.wrapper-tabs .tab').find('span.sr').remove();
if (view) { tabElement.addClass('is-selected');
view.undelegateEvents(); 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) { saveSettings: function(event) {
this.undelegateViewEvents(this.confirmationNotifications); var cohortFormView = this.cohortFormView;
this.confirmationNotifications.$el.html(''); var self = this;
this.confirmationNotifications = null; event.preventDefault();
} cohortFormView.saveForm()
if (model === undefined) { .done(function() {
model = new NotificationModel(); self.renderGroupHeader();
} cohortFormView.showMessage(gettext('Saved cohort'));
model.set('type', 'error'); });
model.set('title', message); },
this.undelegateViewEvents(this.errorNotifications); cancelSettings: function(event) {
event.preventDefault();
this.errorNotifications = new NotificationView({ this.render();
el: this.$('.cohort-errors'), },
model: model
}); setCohort: function(cohort) {
this.errorNotifications.render(); this.model = cohort;
}, this.render();
},
addNotifications: function(modifiedUsers) {
var oldCohort, title, details, numPresent, numUsersAdded, numErrors, addStudents: function(event) {
createErrorDetails, errorActionCallback, errorModel, event.preventDefault();
errorLimit = 5; var self = this,
cohorts = this.cohorts,
// Show confirmation messages. input = this.$('.cohort-management-group-add-students'),
this.undelegateViewEvents(this.confirmationNotifications); add_url = this.model.url() + '/add',
numUsersAdded = modifiedUsers.added.length + modifiedUsers.changed.length; students = input.val().trim(),
numPresent = modifiedUsers.present.length; cohortId = this.model.id;
if (numUsersAdded > 0 || numPresent > 0) {
title = interpolate_text( if (students.length > 0) {
ngettext("{numUsersAdded} student has been added to this cohort", $.post(
"{numUsersAdded} students have been added to this cohort", numUsersAdded), add_url, {'users': students}
{numUsersAdded: numUsersAdded} ).done(function(modifiedUsers) {
); self.refreshCohorts().done(function() {
// Find the equivalent cohort in the new collection and select it
var movedByCohort = {}; var cohort = cohorts.get(cohortId);
_.each(modifiedUsers.changed, function (changedInfo) { self.setCohort(cohort);
oldCohort = changedInfo.previous_cohort;
if (oldCohort in movedByCohort) { // Show the notifications
movedByCohort[oldCohort] = movedByCohort[oldCohort] + 1; 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('');
} }
else { },
movedByCohort[oldCohort] = 1;
/**
* 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();
} }
}); },
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++) { showErrorMessage: function(message, removeConfirmations, model) {
details.push(interpolate_text(gettext("Unknown user: {user}"), {user: unknownUsers[i]})); if (removeConfirmations && this.confirmationNotifications) {
this.undelegateViewEvents(this.confirmationNotifications);
this.confirmationNotifications.$el.html('');
this.confirmationNotifications = null;
} }
return details; if (model === undefined) {
}; model = new NotificationModel();
}
model.set('type', 'error');
model.set('title', message);
title = interpolate_text( this.undelegateViewEvents(this.errorNotifications);
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) { this.errorNotifications = new NotificationView({
view.model.set("actionText", null); el: this.$('.cohort-errors'),
view.model.set("details", createErrorDetails(modifiedUsers.unknown, true)); model: model
view.render(); });
}; 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}
)
);
}
errorModel = new NotificationModel({ this.confirmationNotifications = new NotificationView({
details: details, el: this.$('.cohort-confirmations'),
actionText: numErrors > errorLimit ? gettext("View all errors") : null, model: new NotificationModel({
actionCallback: errorActionCallback, type: "confirmation",
actionClass: 'action-expand' title: title,
}); details: details
})
});
this.confirmationNotifications.render();
}
else if (this.confirmationNotifications) {
this.confirmationNotifications.$el.html('');
this.confirmationNotifications = null;
}
this.showErrorMessage(title, false, errorModel); // Show error messages.
} this.undelegateViewEvents(this.errorNotifications);
else if (this.errorNotifications) { numErrors = modifiedUsers.unknown.length;
this.errorNotifications.$el.html(''); if (numErrors > 0) {
this.errorNotifications = null; 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, }).call(this, define || RequireJS.define);
NotificationModel, NotificationView);
var edx = edx || {}; ;(function (define) {
(function($, _, Backbone, gettext, interpolate_text, CohortModel, NotificationModel, NotificationView) {
'use strict'; 'use strict';
define(['jquery', 'underscore', 'backbone', 'gettext', 'js/groups/models/cohort',
edx.groups = edx.groups || {}; 'js/models/notification', 'js/views/notification'],
function($, _, Backbone, gettext, CohortModel) {
edx.groups.CohortFormView = Backbone.View.extend({
events : { var CohortFormView = Backbone.View.extend({
'change .cohort-management-details-association-course input': 'onRadioButtonChange' events : {
}, 'change .cohort-management-details-association-course input': 'onRadioButtonChange'
},
initialize: function(options) {
this.template = _.template($('#cohort-form-tpl').text()); initialize: function(options) {
this.contentGroups = options.contentGroups; this.template = _.template($('#cohort-form-tpl').text());
this.context = options.context; this.contentGroups = options.contentGroups;
}, this.context = options.context;
},
showNotification: function(options, beforeElement) {
var model = new NotificationModel(options); showNotification: function(options, beforeElement) {
this.removeNotification(); var model = new NotificationModel(options);
this.notification = new NotificationView({ this.removeNotification();
model: model this.notification = new NotificationView({
}); model: model
beforeElement.before(this.notification.$el); });
this.notification.render(); beforeElement.before(this.notification.$el);
}, this.notification.render();
},
removeNotification: function() {
if (this.notification) { removeNotification: function() {
this.notification.remove(); if (this.notification) {
} this.notification.remove();
}, }
},
render: function() {
this.$el.html(this.template({ render: function() {
cohort: this.model, this.$el.html(this.template({
isDefaultCohort: this.isDefault(this.model.get('name')), cohort: this.model,
contentGroups: this.contentGroups, isDefaultCohort: this.isDefault(this.model.get('name')),
studioGroupConfigurationsUrl: this.context.studioGroupConfigurationsUrl contentGroups: this.contentGroups,
})); studioGroupConfigurationsUrl: this.context.studioGroupConfigurationsUrl
return this; }));
}, return this;
},
isDefault: function(name) {
var cohorts = this.model.collection; isDefault: function(name) {
if (_.isUndefined(cohorts)) { var cohorts = this.model.collection;
return false; 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) { var randomModels = cohorts.where({assignment_type:'random'});
errorMessage = gettext("We've encountered an error. Refresh your browser and then try again."); 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');
} }
showErrorMessage(errorMessage); // Enable the select if the user has chosen groups, else disable it
saveOperation.reject(); this.$('.input-cohort-group-association').prop('disabled', !groupsEnabled);
}); },
}
return saveOperation.promise(); hasAssociatedContentGroup: function() {
} return this.$('.radio-yes').prop('checked');
}); },
}).call(this, $, _, Backbone, gettext, interpolate_text, edx.groups.CohortModel, NotificationModel, NotificationView);
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();
}
});
return CohortFormView;
});
}).call(this, define || RequireJS.define);
var edx = edx || {}; ;(function (define) {
(function($, _, Backbone, gettext, interpolate_text, CohortModel, CohortEditorView, CohortFormView,
CourseCohortSettingsNotificationView, NotificationModel, NotificationView, FileUploaderView,
InlineDiscussionsView, CourseWideDiscussionsView) {
'use strict'; '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 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;
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'
});
}
},
var hiddenClass = 'is-hidden', getSelectedCohort: function() {
disabledClass = 'is-disabled'; var id = this.$('.cohort-select').val();
return id && this.model.get(parseInt(id));
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'
},
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);
// 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) { onCohortSelected: function(event) {
beforeElement = this.$('.cohort-management-group'); event.preventDefault();
} var selectedCohort = this.getSelectedCohort();
beforeElement.before(this.notification.$el); this.lastSelectedCohortId = selectedCohort.get('id');
this.showCohortEditor(selectedCohort);
this.notification.render(); },
},
onCohortsEnabledChanged: function(event) {
removeNotification: function() { event.preventDefault();
if (this.notification) { this.saveCohortSettings();
this.notification.remove(); },
}
if (this.cohortFormView) { saveCohortSettings: function() {
this.cohortFormView.removeNotification(); var self = this,
} cohortSettings,
}, fieldData = {is_cohorted: this.getCohortsEnabled()};
cohortSettings = this.cohortSettings;
showAddCohortForm: function(event) { cohortSettings.save(
var newCohort; fieldData, {patch: true, wait: true}
event.preventDefault(); ).done(function() {
this.removeNotification(); self.render();
newCohort = new CohortModel(); self.renderCourseCohortSettingsNotificationView();
newCohort.url = this.model.url; }).fail(function(result) {
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({ self.showNotification({
type: 'confirmation', type: 'error',
title: interpolate_text( title: gettext("We've encountered an error. Refresh your browser and then try again.")},
gettext('The {cohortGroupName} cohort has been created. You can manually add students to this cohort below.'), self.$('.cohorts-state-section')
{cohortGroupName: newCohort.get('name')} );
) });
},
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();
cancelAddCohortForm: function(event) { this.setCohortEditorVisibility(false);
event.preventDefault(); },
this.removeNotification();
this.onSync(); hideAddCohortForm: function() {
}, this.setCohortEditorVisibility(true);
if (this.cohortFormView) {
showSection: function(event) { this.cohortFormView.remove();
event.preventDefault(); this.cohortFormView = null;
var section = $(event.currentTarget).data("section"); }
$(this.getSectionCss(section)).click(); },
$(window).scrollTop(0);
}, setCohortEditorVisibility: function(showEditor) {
if (showEditor) {
showCsvUpload: function(event) { this.$('.cohorts-state-section').removeClass(disabledClass).attr('aria-disabled', false);
event.preventDefault(); this.$('.cohort-management-group').removeClass(hiddenClass);
this.$('.cohort-management-nav').removeClass(disabledClass).attr('aria-disabled', false);
$(event.currentTarget).addClass(hiddenClass); } else {
var uploadElement = this.$('.csv-upload').removeClass(hiddenClass); this.$('.cohorts-state-section').addClass(disabledClass).attr('aria-disabled', true);
this.$('.cohort-management-group').addClass(hiddenClass);
if (!this.fileUploaderView) { this.$('.cohort-management-nav').addClass(disabledClass).attr('aria-disabled', true);
this.fileUploaderView = new FileUploaderView({ }
el: uploadElement, },
title: gettext("Assign students to cohorts by uploading a CSV file."),
inputLabel: gettext("Choose a .csv file"), saveAddCohortForm: function(event) {
inputTip: gettext("Only properly formatted .csv files will be accepted."), var self = this,
submitButtonText: gettext("Upload File and Assign Students"), newCohort = this.cohortFormView.model;
extensions: ".csv", event.preventDefault();
url: this.context.uploadCohortsCsvUrl, this.removeNotification();
successNotification: function (file, event, data) { this.cohortFormView.saveForm()
var message = interpolate_text(gettext( .done(function() {
"Your file '{file}' has been uploaded. Allow a few minutes for processing." self.lastSelectedCohortId = newCohort.id;
), {file: file}); self.model.fetch().done(function() {
return new NotificationModel({ self.showNotification({
type: "confirmation", type: 'confirmation',
title: message 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();
} }
}).render(); },
this.$('#file-upload-form-file').focus();
} getSectionCss: function (section) {
}, return ".instructor-nav .nav-item a[data-section='" + section + "']";
showDiscussionTopics: function(event) { }
event.preventDefault(); });
return CohortsView;
$(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 + "']";
}
}); });
}).call(this, $, _, Backbone, gettext, interpolate_text, edx.groups.CohortModel, edx.groups.CohortEditorView, }).call(this, define || RequireJS.define);
edx.groups.CohortFormView, edx.groups.CourseCohortSettingsNotificationView, NotificationModel, NotificationView,
FileUploaderView, edx.groups.InlineDiscussionsView, edx.groups.CourseWideDiscussionsView);
;(function (define, undefined) { ;(function (define, undefined) {
'use strict'; 'use strict';
define(['jquery', 'js/groups/views/cohorts', 'js/groups/collections/cohort', 'js/groups/models/course_cohort_settings', define(['jquery', 'js/groups/views/cohorts', 'js/groups/collections/cohort', 'js/groups/models/course_cohort_settings',
'js/groups/models/cohort_discussions'], 'js/groups/models/cohort_discussions', 'js/groups/models/content_group'],
function($) { function($, CohortsView, CohortCollection, CourseCohortSettingsModel, DiscussionTopicsSettingsModel, ContentGroupModel) {
return function(contentGroups, studioGroupConfigurationsUrl) { 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(), var cohorts = new CohortCollection(),
courseCohortSettings = new edx.groups.CourseCohortSettingsModel(), courseCohortSettings = new CourseCohortSettingsModel(),
discussionTopicsSettings = new edx.groups.DiscussionTopicsSettingsModel(); discussionTopicsSettings = new DiscussionTopicsSettingsModel();
var cohortManagementElement = $('.cohort-management'); var cohortManagementElement = $('.cohort-management');
...@@ -16,10 +23,10 @@ ...@@ -16,10 +23,10 @@
courseCohortSettings.url = cohortManagementElement.data('course_cohort_settings_url'); courseCohortSettings.url = cohortManagementElement.data('course_cohort_settings_url');
discussionTopicsSettings.url = cohortManagementElement.data('discussion-topics-url'); discussionTopicsSettings.url = cohortManagementElement.data('discussion-topics-url');
var cohortsView = new edx.groups.CohortsView({ var cohortsView = new CohortsView({
el: cohortManagementElement, el: cohortManagementElement,
model: cohorts, model: cohorts,
contentGroups: contentGroups, contentGroups: contentGroupModels,
cohortSettings: courseCohortSettings, cohortSettings: courseCohortSettings,
context: { context: {
discussionTopicsSettingsModel: discussionTopicsSettings, discussionTopicsSettingsModel: discussionTopicsSettings,
......
var edx = edx || {}; ;(function (define) {
(function($, _, Backbone, gettext) {
'use strict'; 'use strict';
define(['jquery', 'underscore', 'backbone', 'gettext'], function($, _, Backbone, gettext) {
edx.groups = edx.groups || {}; var CourseCohortSettingsNotificationView = Backbone.View.extend({
initialize: function(options) {
edx.groups.CourseCohortSettingsNotificationView = Backbone.View.extend({ this.template = _.template($('#cohort-state-tpl').text());
initialize: function(options) { this.cohortEnabled = options.cohortEnabled;
this.template = _.template($('#cohort-state-tpl').text()); },
this.cohortEnabled = options.cohortEnabled;
},
render: function() { render: function() {
this.$el.html(this.template({})); this.$el.html(this.template({}));
this.showCohortStateMessage(); this.showCohortStateMessage();
return this; return this;
}, },
showCohortStateMessage: function () { showCohortStateMessage: function () {
var actionToggleMessage = this.$('.action-toggle-message'); var actionToggleMessage = this.$('.action-toggle-message');
AnimationUtil.triggerAnimation(actionToggleMessage); AnimationUtil.triggerAnimation(actionToggleMessage);
if (this.cohortEnabled) { if (this.cohortEnabled) {
actionToggleMessage.text(gettext('Cohorts Enabled')); actionToggleMessage.text(gettext('Cohorts Enabled'));
} else { } else {
actionToggleMessage.text(gettext('Cohorts Disabled')); actionToggleMessage.text(gettext('Cohorts Disabled'));
}
} }
} });
return CourseCohortSettingsNotificationView;
}); });
}).call(this, $, _, Backbone, gettext); }).call(this, define || RequireJS.define);
...@@ -67,18 +67,6 @@ ...@@ -67,18 +67,6 @@
'js/models/notification': 'js/models/notification', 'js/models/notification': 'js/models/notification',
'js/views/file_uploader': 'js/views/file_uploader', 'js/views/file_uploader': 'js/views/file_uploader',
'js/views/notification': 'js/views/notification', '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/account': 'js/student_account/account',
'js/student_account/views/FormView': 'js/student_account/views/FormView', 'js/student_account/views/FormView': 'js/student_account/views/FormView',
'js/student_account/models/LoginModel': 'js/student_account/models/LoginModel', 'js/student_account/models/LoginModel': 'js/student_account/models/LoginModel',
...@@ -301,63 +289,6 @@ ...@@ -301,63 +289,6 @@
exports: 'edx.instructor_dashboard.ecommerce.ExpiryCouponView', exports: 'edx.instructor_dashboard.ecommerce.ExpiryCouponView',
deps: ['backbone', 'jquery', 'underscore'] 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': { 'js/models/notification': {
exports: 'NotificationModel', exports: 'NotificationModel',
deps: ['backbone'] deps: ['backbone']
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
* done. * done.
*/ */
modules: getModulesList([ modules: getModulesList([
'js/groups/views/cohorts_dashboard_factory',
'js/student_account/views/account_settings_factory', 'js/student_account/views/account_settings_factory',
'js/student_account/views/finish_auth_factory', 'js/student_account/views/finish_auth_factory',
'js/student_profile/views/learner_profile_factory', 'js/student_profile/views/learner_profile_factory',
......
<%page args="section_data"/> <%page args="section_data"/>
<%namespace name='static' file='../../static_content.html'/>
<%! <%!
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from courseware.courses import get_studio_url from courseware.courses import get_studio_url
...@@ -16,32 +17,23 @@ from openedx.core.djangoapps.course_groups.partition_scheme import get_cohorted_ ...@@ -16,32 +17,23 @@ from openedx.core.djangoapps.course_groups.partition_scheme import get_cohorted_
</div> </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) cohorted_user_partition = get_cohorted_user_partition(course.id)
content_groups = cohorted_user_partition.groups if cohorted_user_partition else [] content_groups = cohorted_user_partition.groups if cohorted_user_partition else []
%> %>
<script type="text/javascript"> var cohortUserPartitionId = ${cohorted_user_partition.id if cohorted_user_partition else 'null'},
$(document).ready(function() { contentGroups = [
% for content_group in content_groups:
var cohortUserPartitionId = ${cohorted_user_partition.id if cohorted_user_partition else 'null'}, {
contentGroups = [ id: ${content_group.id},
% for content_group in content_groups: name: "${content_group.name | h}",
new edx.groups.ContentGroupModel({ user_partition_id: cohortUserPartitionId
id: ${content_group.id}, },
name: "${content_group.name | h}", % endfor
user_partition_id: cohortUserPartitionId ];
}), CohortsFactory(contentGroups, '${get_studio_url(course, 'group_configurations') | h}');
% endfor </%static:require_module>
];
(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>
</%block> </%block>
<div class="cohort-state-message"></div> <div class="cohort-state-message"></div>
...@@ -56,22 +56,9 @@ from django.core.urlresolvers import reverse ...@@ -56,22 +56,9 @@ from django.core.urlresolvers import reverse
<%static:js group='application'/> <%static:js group='application'/>
## Backbone classes declared explicitly until RequireJS is supported ## 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/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/notification.js')}"></script>
<script type="text/javascript" src="${static.url('js/views/file_uploader.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> <script type="text/javascript" src="${static.url('js/utils/animation.js')}"></script>
</%block> </%block>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment