Files
edx-platform/cms/static/js/views/pages/container_subviews.js
2014-08-07 12:27:14 -04:00

250 lines
9.9 KiB
JavaScript

/**
* Subviews (usually small side panels) for XBlockContainerPage.
*/
define(["jquery", "underscore", "gettext", "js/views/baseview", "js/views/utils/view_utils",
"js/views/utils/xblock_utils"],
function ($, _, gettext, BaseView, ViewUtils, XBlockViewUtils) {
var VisibilityState = XBlockViewUtils.VisibilityState,
disabledCss = "is-disabled";
/**
* A view that refreshes the view when certain values in the XBlockInfo have changed
* after a server sync operation.
*/
var ContainerStateListenerView = BaseView.extend({
// takes XBlockInfo as a model
initialize: function() {
this.model.on('sync', this.onSync, this);
},
onSync: function(model) {
if (this.shouldRefresh(model)) {
this.render();
}
},
shouldRefresh: function(model) {
return false;
},
render: function() {}
});
var MessageView = ContainerStateListenerView.extend({
initialize: function () {
ContainerStateListenerView.prototype.initialize.call(this);
this.template = this.loadTemplate('container-message');
},
shouldRefresh: function(model) {
return ViewUtils.hasChangedAttributes(model, ['currently_visible_to_students']);
},
render: function() {
this.$el.html(this.template({
currentlyVisibleToStudents: this.model.get('currently_visible_to_students')
}));
return this;
}
});
/**
* A controller for updating the "View Live" and "Preview" buttons.
*/
var PreviewActionController = ContainerStateListenerView.extend({
shouldRefresh: function(model) {
return ViewUtils.hasChangedAttributes(model, ['has_changes', 'published']);
},
render: function() {
var previewAction = this.$el.find('.button-preview'),
viewLiveAction = this.$el.find('.button-view');
if (this.model.get('published')) {
viewLiveAction.removeClass(disabledCss);
}
else {
viewLiveAction.addClass(disabledCss);
}
if (this.model.get('has_changes') || !this.model.get('published')) {
previewAction.removeClass(disabledCss);
}
else {
previewAction.addClass(disabledCss);
}
}
});
/**
* Publisher is a view that supports the following:
* 1) Publishing of a draft version of an xblock.
* 2) Discarding of edits in a draft version.
* 3) Display of who last edited the xblock, and when.
* 4) Display of publish status (published, published with changes, changes with no published version).
*/
var Publisher = BaseView.extend({
events: {
'click .action-publish': 'publish',
'click .action-discard': 'discardChanges',
'click .action-staff-lock': 'toggleStaffLock'
},
// takes XBlockInfo as a model
initialize: function () {
BaseView.prototype.initialize.call(this);
this.template = this.loadTemplate('publish-xblock');
this.model.on('sync', this.onSync, this);
this.renderPage = this.options.renderPage;
},
onSync: function(model) {
if (ViewUtils.hasChangedAttributes(model, [
'has_changes', 'published', 'edited_on', 'edited_by', 'visibility_state'
])) {
this.render();
}
},
render: function () {
this.$el.html(this.template({
visibilityState: this.model.get('visibility_state'),
visibilityClass: XBlockViewUtils.getXBlockVisibilityClass(this.model.get('visibility_state')),
hasChanges: this.model.get('has_changes'),
editedOn: this.model.get('edited_on'),
editedBy: this.model.get('edited_by'),
published: this.model.get('published'),
publishedOn: this.model.get('published_on'),
publishedBy: this.model.get('published_by'),
releaseDate: this.model.get('release_date'),
releaseDateFrom: this.model.get('release_date_from')
}));
return this;
},
publish: function (e) {
var xblockInfo = this.model;
if (e && e.preventDefault) {
e.preventDefault();
}
ViewUtils.runOperationShowingMessage(gettext('Publishing…'),
function () {
return xblockInfo.save({publish: 'make_public'}, {patch: true});
}).always(function() {
xblockInfo.set("publish", null);
}).done(function () {
xblockInfo.fetch();
});
},
discardChanges: function (e) {
var xblockInfo = this.model, renderPage = this.renderPage;
if (e && e.preventDefault) {
e.preventDefault();
}
ViewUtils.confirmThenRunOperation(gettext("Discard Changes"),
gettext("Are you sure you want to discard changes and revert to the last published version?"),
gettext("Discard Changes"),
function () {
ViewUtils.runOperationShowingMessage(gettext('Discarding Changes…'),
function () {
return xblockInfo.save({publish: 'discard_changes'}, {patch: true});
}).always(function() {
xblockInfo.set("publish", null);
}).done(function () {
renderPage();
});
}
);
},
toggleStaffLock: function (e) {
var xblockInfo = this.model, self=this, enableStaffLock,
saveAndPublishStaffLock, revertCheckBox;
if (e && e.preventDefault) {
e.preventDefault();
}
enableStaffLock = xblockInfo.get('visibility_state') !== VisibilityState.staffOnly;
revertCheckBox = function() {
self.checkStaffLock(!enableStaffLock);
};
saveAndPublishStaffLock = function() {
return xblockInfo.save({
publish: 'republish',
metadata: {visible_to_staff_only: enableStaffLock}},
{patch: true}
).always(function() {
xblockInfo.set("publish", null);
}).done(function () {
xblockInfo.fetch();
}).fail(function() {
revertCheckBox();
});
};
this.checkStaffLock(enableStaffLock);
if (enableStaffLock) {
ViewUtils.runOperationShowingMessage(gettext('Setting Staff Lock…'),
_.bind(saveAndPublishStaffLock, self));
} else {
ViewUtils.confirmThenRunOperation(gettext("Remove Staff Lock"),
gettext("Are you sure you want to remove the staff lock? Once you publish this unit, it will be released to students on the release date."),
gettext("Remove Staff Lock"),
function() {
ViewUtils.runOperationShowingMessage(gettext('Removing Staff Lock…'),
_.bind(saveAndPublishStaffLock, self));
},
function() {
// On cancel, revert the check in the check box
revertCheckBox();
}
);
}
},
checkStaffLock: function(check) {
this.$('.action-staff-lock i').removeClass('icon-check icon-check-empty');
this.$('.action-staff-lock i').addClass(check ? 'icon-check' : 'icon-check-empty');
}
});
/**
* PublishHistory displays when and by whom the xblock was last published, if it ever was.
*/
var PublishHistory = BaseView.extend({
// takes XBlockInfo as a model
initialize: function () {
BaseView.prototype.initialize.call(this);
this.template = this.loadTemplate('publish-history');
this.model.on('sync', this.onSync, this);
},
onSync: function(model) {
if (ViewUtils.hasChangedAttributes(model, ['published', 'published_on', 'published_by'])) {
this.render();
}
},
render: function () {
this.$el.html(this.template({
published: this.model.get('published'),
published_on: this.model.get('published_on'),
published_by: this.model.get('published_by')
}));
return this;
}
});
return {
'MessageView': MessageView,
'PreviewActionController': PreviewActionController,
'Publisher': Publisher,
'PublishHistory': PublishHistory
};
}); // end define();