Displays the date, time, and username of the most recent save and publish

Conflicts:
	cms/djangoapps/contentstore/views/item.py
This commit is contained in:
Ben McMorran
2014-07-08 15:41:34 -04:00
committed by cahrens
parent 7cb5c4d7b8
commit 572b4fc030
10 changed files with 161 additions and 14 deletions

View File

@@ -32,14 +32,21 @@ define(["backbone", "js/utils/module"], function(Backbone, ModuleUtils) {
*/
"locked": null,
/**
* Date of last edit to this xblock. Will be the latest change to either the draft
* or the published version.
* Date of the last edit to this xblock or any of its descendants.
*/
"edited_on":null,
/**
* User who last edited the xblock.
* User who last edited the xblock or any of its descendants.
*/
"edited_by":null,
/**
* Date of the last publish of this xblock, or null if never published.
*/
"published_on": null,
/**
* User who last published the xblock, or null if never published.
*/
"published_by": null,
/**
* If the xblock is published, the date on which it will be released to students.
*/

View File

@@ -12,6 +12,7 @@ define(["jquery", "underscore", "underscore.string", "js/spec_helpers/create_sin
beforeEach(function () {
edit_helpers.installTemplate('xblock-string-field-editor');
edit_helpers.installTemplate('publish-xblock');
edit_helpers.installTemplate('publish-history');
appendSetFixtures(mockContainerPage);
model = new XBlockInfo({
@@ -130,6 +131,7 @@ define(["jquery", "underscore", "underscore.string", "js/spec_helpers/create_sin
draftBit = "draft",
publishButtonCss = ".action-publish",
discardChangesButtonCss = ".action-discard",
lastDraftCss = ".wrapper-last-draft",
request, lastRequest, promptSpies, sendDiscardChangesToServer;
lastRequest = function() { return requests[requests.length - 1]; };
@@ -280,6 +282,49 @@ define(["jquery", "underscore", "underscore.string", "js/spec_helpers/create_sin
expect(requests.length).toEqual(numRequests);
expect(containerPage.$(discardChangesButtonCss)).not.toHaveClass('is-disabled');
});
it('renders the last published date and user when there are no changes', function () {
renderContainerPage(mockContainerXBlockHtml, this);
fetch({ "id": "locator-container", "has_changes": false,
"edited_on": "Jun 30, 2014 at 14:20 UTC", "edited_by": "joe",
"published_on": "Jul 01, 2014 at 12:45 UTC", "published_by": "amako"});
expect(containerPage.$(lastDraftCss).text()).
toContain("Last published Jul 01, 2014 at 12:45 UTC by amako");
});
it('renders the last saved date and user when there are changes', function () {
renderContainerPage(mockContainerXBlockHtml, this);
fetch({ "id": "locator-container", "has_changes": true,
"edited_on": "Jul 02, 2014 at 14:20 UTC", "edited_by": "joe",
"published_on": "Jul 01, 2014 at 12:45 UTC", "published_by": "amako"});
expect(containerPage.$(lastDraftCss).text()).
toContain("Draft saved on Jul 02, 2014 at 14:20 UTC by joe");
});
});
describe("PublishHistory", function () {
var lastPublishCss = ".wrapper-last-publish";
it('renders the last published date and user when the block is published', function () {
renderContainerPage(mockContainerXBlockHtml, this);
fetch({ "id": "locator-container", "published": true,
"published_on": "Jul 01, 2014 at 12:45 UTC", "published_by": "amako" });
expect(containerPage.$(lastPublishCss).text()).
toContain("Last published Jul 01, 2014 at 12:45 UTC by amako");
});
it('renders never published when the block is unpublished', function () {
renderContainerPage(mockContainerXBlockHtml, this);
fetch({ "id": "locator-container", "published": false,
"published_on": "Jul 01, 2014 at 12:45 UTC", "published_by": "amako" });
expect(containerPage.$(lastPublishCss).text()).toContain("Never published");
});
it('renders correctly when the block is published without publish info', function () {
renderContainerPage(mockContainerXBlockHtml, this);
fetch({ "id": "locator-container", "published": true, "published_on": null, "published_by": null});
expect(containerPage.$(lastPublishCss).text()).toContain("Previously published");
});
});
});
});

View File

@@ -34,6 +34,12 @@ define(["jquery", "underscore", "gettext", "js/views/baseview", "js/views/contai
});
this.xblockPublisher.render();
this.publishHistory = new ContainerSubviews.PublishHistory({
el: this.$('#publish-history'),
model: this.model
});
this.publishHistory.render();
// No need to render initially. This is only used for updating state
// when the unit changes visibility.
this.visibilityState = new ContainerSubviews.VisibilityStateController({

View File

@@ -108,7 +108,9 @@ define(["jquery", "underscore", "gettext", "js/views/baseview", "js/views/feedba
has_changes: this.model.get('has_changes'),
published: this.model.get('published'),
edited_on: this.model.get('edited_on'),
edited_by: this.model.get('edited_by')
edited_by: this.model.get('edited_by'),
published_on: this.model.get('published_on'),
published_by: this.model.get('published_by')
}));
return this;
@@ -174,9 +176,40 @@ define(["jquery", "underscore", "gettext", "js/views/baseview", "js/views/feedba
}
});
/**
* 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(e) {
if (e.changedAttributes() && (('published' in e.changedAttributes()) ||
('published_on' in e.changedAttributes()) || ('published_by' in e.changedAttributes()))) {
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 {
'VisibilityStateController': VisibilityStateController,
'PreviewActionController': PreviewActionController,
'Publisher': Publisher
'Publisher': Publisher,
'PublishHistory': PublishHistory
};
}); // end define();