Bookmarks List Pagination
TNL-2490
This commit is contained in:
committed by
muzaffaryousaf
parent
4304c66c54
commit
fcbe595c8a
@@ -1,20 +1,24 @@
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
define(['backbone', 'js/bookmarks/models/bookmark'],
|
||||
function (Backbone, BookmarkModel) {
|
||||
define(['backbone', 'common/js/components/collections/paging_collection', 'js/bookmarks/models/bookmark'],
|
||||
function (Backbone, PagingCollection, BookmarkModel) {
|
||||
|
||||
return PagingCollection.extend({
|
||||
initialize: function(options) {
|
||||
PagingCollection.prototype.initialize.call(this);
|
||||
|
||||
return Backbone.Collection.extend({
|
||||
model: BookmarkModel,
|
||||
this.url = options.url;
|
||||
this.server_api.course_id = function () { return encodeURIComponent(options.course_id); };
|
||||
this.server_api.fields = function () { return encodeURIComponent('display_name,path'); };
|
||||
delete this.server_api.sort_order; // Sort order is not specified for the Bookmark API
|
||||
},
|
||||
|
||||
url: function() {
|
||||
return $(".courseware-bookmarks-button").data('bookmarksApiUrl');
|
||||
},
|
||||
model: BookmarkModel,
|
||||
|
||||
parse: function(response) {
|
||||
return response.results;
|
||||
}
|
||||
});
|
||||
url: function() {
|
||||
return this.url;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
})(define || RequireJS.define);
|
||||
})(define || RequireJS.define);
|
||||
@@ -1,7 +1,8 @@
|
||||
;(function (define, undefined) {
|
||||
'use strict';
|
||||
define(['gettext', 'jquery', 'underscore', 'backbone', 'logger', 'moment'],
|
||||
function (gettext, $, _, Backbone, Logger, _moment) {
|
||||
define(['gettext', 'jquery', 'underscore', 'backbone', 'logger', 'moment',
|
||||
'common/js/components/views/paging_header', 'common/js/components/views/paging_footer'],
|
||||
function (gettext, $, _, Backbone, Logger, _moment, PagingHeaderView, PagingFooterView) {
|
||||
|
||||
var moment = _moment || window.moment;
|
||||
|
||||
@@ -16,27 +17,31 @@
|
||||
errorMessage: gettext('An error has occurred. Please try again.'),
|
||||
loadingMessage: gettext('Loading'),
|
||||
|
||||
PAGE_SIZE: 500,
|
||||
defaultPage: 1,
|
||||
|
||||
events : {
|
||||
'click .bookmarks-results-list-item': 'visitBookmark'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
this.template = _.template($('#bookmarks_list-tpl').text());
|
||||
this.template = _.template($('#bookmarks-list-tpl').text());
|
||||
this.loadingMessageView = options.loadingMessageView;
|
||||
this.errorMessageView = options.errorMessageView;
|
||||
this.courseId = $(this.el).data('courseId');
|
||||
this.langCode = $(this.el).data('langCode');
|
||||
this.pagingHeaderView = new PagingHeaderView({collection: this.collection});
|
||||
this.pagingFooterView = new PagingFooterView({collection: this.collection});
|
||||
this.listenTo(this.collection, 'page_changed', this.render);
|
||||
_.bindAll(this, 'render', 'humanFriendlyDate');
|
||||
},
|
||||
|
||||
render: function () {
|
||||
var data = {
|
||||
bookmarks: this.collection.models,
|
||||
bookmarksCollection: this.collection,
|
||||
humanFriendlyDate: this.humanFriendlyDate
|
||||
};
|
||||
this.$el.html(this.template(data));
|
||||
this.pagingHeaderView.setElement(this.$('.paging-header')).render();
|
||||
this.pagingFooterView.setElement(this.$('.paging-footer')).render();
|
||||
this.delegateEvents();
|
||||
return this;
|
||||
},
|
||||
@@ -48,10 +53,7 @@
|
||||
this.showBookmarksContainer();
|
||||
this.showLoadingMessage();
|
||||
|
||||
this.collection.fetch({
|
||||
reset: true,
|
||||
data: {course_id: this.courseId, page_size: this.PAGE_SIZE, fields: 'display_name,path'}
|
||||
}).done(function () {
|
||||
this.collection.goTo(this.defaultPage).done(function () {
|
||||
view.hideLoadingMessage();
|
||||
view.render();
|
||||
view.focusBookmarksElement();
|
||||
|
||||
@@ -16,11 +16,20 @@
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
this.bookmarksListView = new BookmarksListView({
|
||||
collection: new BookmarksCollection(),
|
||||
loadingMessageView: new MessageView({el: $(this.loadingMessageElement)}),
|
||||
errorMessageView: new MessageView({el: $(this.errorMessageElement)})
|
||||
});
|
||||
var bookmarksCollection = new BookmarksCollection(
|
||||
{
|
||||
course_id: $('.courseware-results').data('courseId'),
|
||||
url: $(".courseware-bookmarks-button").data('bookmarksApiUrl')
|
||||
}
|
||||
);
|
||||
bookmarksCollection.bootstrap();
|
||||
this.bookmarksListView = new BookmarksListView(
|
||||
{
|
||||
collection: bookmarksCollection,
|
||||
loadingMessageView: new MessageView({el: $(this.loadingMessageElement)}),
|
||||
errorMessageView: new MessageView({el: $(this.errorMessageElement)})
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
toggleBookmarksListView: function () {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'js/common_helpers/template_helpers',
|
||||
'js/bookmarks/views/bookmark_button'
|
||||
define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers',
|
||||
'common/js/spec_helpers/template_helpers', 'js/bookmarks/views/bookmark_button'
|
||||
],
|
||||
function (Backbone, $, _, AjaxHelpers, TemplateHelpers, BookmarkButtonView) {
|
||||
'use strict';
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
define(['backbone', 'jquery', 'underscore', 'logger', 'js/common_helpers/ajax_helpers',
|
||||
'js/common_helpers/template_helpers', 'js/bookmarks/views/bookmarks_list_button'
|
||||
],
|
||||
function (Backbone, $, _, Logger, AjaxHelpers, TemplateHelpers, BookmarksListButtonView) {
|
||||
define(['backbone',
|
||||
'jquery',
|
||||
'underscore',
|
||||
'logger',
|
||||
'URI',
|
||||
'common/js/spec_helpers/ajax_helpers',
|
||||
'common/js/spec_helpers/template_helpers',
|
||||
'js/bookmarks/views/bookmarks_list_button',
|
||||
'js/bookmarks/views/bookmarks_list',
|
||||
'js/bookmarks/collections/bookmarks'],
|
||||
function (Backbone, $, _, Logger, URI, AjaxHelpers, TemplateHelpers, BookmarksListButtonView, BookmarksListView,
|
||||
BookmarksCollection) {
|
||||
'use strict';
|
||||
|
||||
describe("lms.courseware.bookmarks", function () {
|
||||
|
||||
var bookmarksButtonView;
|
||||
var BOOKMARKS_API_URL = '/api/bookmarks/v1/bookmarks/';
|
||||
|
||||
beforeEach(function () {
|
||||
loadFixtures('js/fixtures/bookmarks/bookmarks.html');
|
||||
TemplateHelpers.installTemplates(
|
||||
[
|
||||
'templates/message_view',
|
||||
'templates/bookmarks/bookmarks_list'
|
||||
'templates/bookmarks/bookmarks-list'
|
||||
]
|
||||
);
|
||||
spyOn(Logger, 'log').andReturn($.Deferred().resolve());
|
||||
@@ -27,12 +34,23 @@ define(['backbone', 'jquery', 'underscore', 'logger', 'js/common_helpers/ajax_he
|
||||
bookmarksButtonView = new BookmarksListButtonView();
|
||||
});
|
||||
|
||||
var createBookmarksData = function (count) {
|
||||
var verifyRequestParams = function (requests, params) {
|
||||
var urlParams = (new URI(requests[requests.length - 1].url)).query(true);
|
||||
_.each(params, function (value, key) {
|
||||
expect(urlParams[key]).toBe(value);
|
||||
});
|
||||
};
|
||||
|
||||
var createBookmarksData = function (options) {
|
||||
var data = {
|
||||
count: options.count || 0,
|
||||
num_pages: options.num_pages || 1,
|
||||
current_page: options.current_page || 1,
|
||||
start: options.start || 0,
|
||||
results: []
|
||||
};
|
||||
|
||||
for(var i = 0; i < count; i++) {
|
||||
for(var i = 0; i < options.numBookmarksToCreate; i++) {
|
||||
var bookmarkInfo = {
|
||||
id: i,
|
||||
display_name: 'UNIT_DISPLAY_NAME_' + i,
|
||||
@@ -87,6 +105,15 @@ define(['backbone', 'jquery', 'underscore', 'logger', 'js/common_helpers/ajax_he
|
||||
}
|
||||
};
|
||||
|
||||
var verifyPaginationInfo = function (requests, expectedData, currentPage, headerMessage) {
|
||||
AjaxHelpers.respondWithJson(requests, expectedData);
|
||||
verifyBookmarkedData(bookmarksButtonView.bookmarksListView, expectedData);
|
||||
expect(bookmarksButtonView.bookmarksListView.$('.paging-footer span.current-page').text().trim()).
|
||||
toBe(currentPage);
|
||||
expect(bookmarksButtonView.bookmarksListView.$('.paging-header span').text().trim()).
|
||||
toBe(headerMessage);
|
||||
};
|
||||
|
||||
it("has correct behavior for bookmarks button", function () {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
|
||||
@@ -101,16 +128,16 @@ define(['backbone', 'jquery', 'underscore', 'logger', 'js/common_helpers/ajax_he
|
||||
expect(bookmarksButtonView.toggleBookmarksListView).toHaveBeenCalled();
|
||||
expect(bookmarksButtonView.$('.bookmarks-list-button')).toHaveAttr('aria-pressed', 'true');
|
||||
expect(bookmarksButtonView.$('.bookmarks-list-button')).toHaveClass('is-active');
|
||||
AjaxHelpers.respondWithJson(requests, createBookmarksData(1));
|
||||
AjaxHelpers.respondWithJson(requests, createBookmarksData({numBookmarksToCreate: 1}));
|
||||
|
||||
bookmarksButtonView.$('.bookmarks-list-button').click();
|
||||
expect(bookmarksButtonView.$('.bookmarks-list-button')).toHaveAttr('aria-pressed', 'false');
|
||||
expect(bookmarksButtonView.$('.bookmarks-list-button')).toHaveClass('is-inactive');
|
||||
});
|
||||
|
||||
it("has rendered empty bookmarks list correctly", function () {
|
||||
it("can correctly render an empty bookmarks list", function () {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
var expectedData = createBookmarksData(0);
|
||||
var expectedData = createBookmarksData({numBookmarksToCreate: 0});
|
||||
|
||||
bookmarksButtonView.$('.bookmarks-list-button').click();
|
||||
AjaxHelpers.respondWithJson(requests, expectedData);
|
||||
@@ -125,25 +152,128 @@ define(['backbone', 'jquery', 'underscore', 'logger', 'js/common_helpers/ajax_he
|
||||
|
||||
expect(bookmarksButtonView.bookmarksListView.$('.bookmarks-empty-detail-title').text().trim()).
|
||||
toBe(emptyListText);
|
||||
|
||||
expect(bookmarksButtonView.bookmarksListView.$('.paging-header').length).toBe(0);
|
||||
expect(bookmarksButtonView.bookmarksListView.$('.paging-footer').length).toBe(0);
|
||||
});
|
||||
|
||||
it("has rendered bookmarked list correctly", function () {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
var url = BOOKMARKS_API_URL + '?course_id=COURSE_ID&page_size=500&fields=display_name%2Cpath';
|
||||
var expectedData = createBookmarksData(3);
|
||||
var expectedData = createBookmarksData({numBookmarksToCreate: 3});
|
||||
|
||||
spyOn(bookmarksButtonView.bookmarksListView, 'courseId').andReturn('COURSE_ID');
|
||||
bookmarksButtonView.$('.bookmarks-list-button').click();
|
||||
expect($('#loading-message').text().trim()).
|
||||
toBe(bookmarksButtonView.bookmarksListView.loadingMessage);
|
||||
|
||||
AjaxHelpers.expectRequest(requests, 'GET', url);
|
||||
verifyRequestParams(
|
||||
requests,
|
||||
{course_id: 'a/b/c', fields: 'display_name,path', page: '1', page_size: '10'}
|
||||
);
|
||||
AjaxHelpers.respondWithJson(requests, expectedData);
|
||||
|
||||
expect(bookmarksButtonView.bookmarksListView.$('.bookmarks-results-header').text().trim()).
|
||||
toBe('My Bookmarks');
|
||||
|
||||
verifyBookmarkedData(bookmarksButtonView.bookmarksListView, expectedData);
|
||||
|
||||
expect(bookmarksButtonView.bookmarksListView.$('.paging-header').length).toBe(1);
|
||||
expect(bookmarksButtonView.bookmarksListView.$('.paging-footer').length).toBe(1);
|
||||
});
|
||||
|
||||
it("calls bookmarks list render on page_changed event", function () {
|
||||
var renderSpy = spyOn(BookmarksListView.prototype, 'render');
|
||||
var listView = new BookmarksListView({collection: new BookmarksCollection({course_id: 'abc'})});
|
||||
listView.collection.trigger('page_changed');
|
||||
expect(renderSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("can go to a page number", function () {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
var expectedData = createBookmarksData(
|
||||
{
|
||||
numBookmarksToCreate: 10,
|
||||
count: 12,
|
||||
num_pages: 2,
|
||||
current_page: 1,
|
||||
start: 0
|
||||
}
|
||||
);
|
||||
|
||||
bookmarksButtonView.$('.bookmarks-list-button').click();
|
||||
AjaxHelpers.respondWithJson(requests, expectedData);
|
||||
verifyBookmarkedData(bookmarksButtonView.bookmarksListView, expectedData);
|
||||
|
||||
bookmarksButtonView.bookmarksListView.$('input#page-number-input').val('2');
|
||||
bookmarksButtonView.bookmarksListView.$('input#page-number-input').trigger('change');
|
||||
|
||||
expectedData = createBookmarksData(
|
||||
{
|
||||
numBookmarksToCreate: 2,
|
||||
count: 12,
|
||||
num_pages: 2,
|
||||
current_page: 2,
|
||||
start: 10
|
||||
}
|
||||
);
|
||||
AjaxHelpers.respondWithJson(requests, expectedData);
|
||||
verifyBookmarkedData(bookmarksButtonView.bookmarksListView, expectedData);
|
||||
|
||||
expect(bookmarksButtonView.bookmarksListView.$('.paging-footer span.current-page').text().trim()).
|
||||
toBe('2');
|
||||
expect(bookmarksButtonView.bookmarksListView.$('.paging-header span').text().trim()).
|
||||
toBe('Showing 11-12 out of 12 total');
|
||||
});
|
||||
|
||||
it("can navigate forward and backward", function () {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
var expectedData = createBookmarksData(
|
||||
{
|
||||
numBookmarksToCreate: 10,
|
||||
count: 15,
|
||||
num_pages: 2,
|
||||
current_page: 1,
|
||||
start: 0
|
||||
}
|
||||
);
|
||||
|
||||
bookmarksButtonView.$('.bookmarks-list-button').click();
|
||||
verifyPaginationInfo(requests, expectedData, '1', 'Showing 1-10 out of 15 total');
|
||||
verifyRequestParams(
|
||||
requests,
|
||||
{course_id: 'a/b/c', fields: 'display_name,path', page: '1', page_size: '10'}
|
||||
);
|
||||
|
||||
bookmarksButtonView.bookmarksListView.$('.paging-footer .next-page-link').click();
|
||||
expectedData = createBookmarksData(
|
||||
{
|
||||
numBookmarksToCreate: 5,
|
||||
count: 15,
|
||||
num_pages: 2,
|
||||
current_page: 2,
|
||||
start: 10
|
||||
}
|
||||
);
|
||||
verifyPaginationInfo(requests, expectedData, '2', 'Showing 11-15 out of 15 total');
|
||||
verifyRequestParams(
|
||||
requests,
|
||||
{course_id: 'a/b/c', fields: 'display_name,path', page: '2', page_size: '10'}
|
||||
);
|
||||
|
||||
expectedData = createBookmarksData(
|
||||
{
|
||||
numBookmarksToCreate: 10,
|
||||
count: 15,
|
||||
num_pages: 2,
|
||||
current_page: 1,
|
||||
start: 0
|
||||
}
|
||||
);
|
||||
bookmarksButtonView.bookmarksListView.$('.paging-footer .previous-page-link').click();
|
||||
verifyPaginationInfo(requests, expectedData, '1', 'Showing 1-10 out of 15 total');
|
||||
verifyRequestParams(
|
||||
requests,
|
||||
{course_id: 'a/b/c', fields: 'display_name,path', page: '1', page_size: '10'}
|
||||
);
|
||||
});
|
||||
|
||||
it("can navigate to correct url", function () {
|
||||
@@ -151,7 +281,7 @@ define(['backbone', 'jquery', 'underscore', 'logger', 'js/common_helpers/ajax_he
|
||||
spyOn(bookmarksButtonView.bookmarksListView, 'visitBookmark');
|
||||
|
||||
bookmarksButtonView.$('.bookmarks-list-button').click();
|
||||
AjaxHelpers.respondWithJson(requests, createBookmarksData(1));
|
||||
AjaxHelpers.respondWithJson(requests, createBookmarksData({numBookmarksToCreate: 1}));
|
||||
|
||||
bookmarksButtonView.bookmarksListView.$('.bookmarks-results-list-item').click();
|
||||
var url = bookmarksButtonView.bookmarksListView.$('.bookmarks-results-list-item').attr('href');
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
// Rules for Bookmarks Results
|
||||
.bookmarks-results-list {
|
||||
padding-top: $baseline;
|
||||
padding-top: ($baseline/2);
|
||||
|
||||
.bookmarks-results-list-item {
|
||||
@include padding(($baseline/4), $baseline, ($baseline/2), $baseline);
|
||||
@@ -181,3 +181,9 @@ i.bookmarked {
|
||||
@include icon-style("\f097", $black);
|
||||
@include hover-style($m-blue, $m-blue, "\f02e");
|
||||
}
|
||||
|
||||
.paging-header {
|
||||
.search-tools {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
<div id="my-bookmarks" class="sr-is-focusable" tabindex="-1"></div>
|
||||
<h2 class="bookmarks-results-header"><%= gettext("My Bookmarks") %></h2>
|
||||
|
||||
<% if (bookmarks.length) { %>
|
||||
<% if (bookmarksCollection.length) { %>
|
||||
|
||||
<div class="paging-header"></div>
|
||||
|
||||
<div class='bookmarks-results-list'>
|
||||
<% _.each(bookmarks, function(bookmark, index) { %>
|
||||
<% bookmarksCollection.each(function(bookmark, index) { %>
|
||||
<a class="bookmarks-results-list-item" href="<%= bookmark.blockUrl() %>" aria-labelledby="bookmark-link-<%= index %>" data-bookmark-id="<%= bookmark.get('id') %>" data-component-type="<%= bookmark.get('block_type') %>" data-usage-id="<%= bookmark.get('usage_id') %>" aria-describedby="bookmark-type-<%= index %> bookmark-date-<%= index %>">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-left-section">
|
||||
@@ -21,6 +23,8 @@
|
||||
<% }); %>
|
||||
</div>
|
||||
|
||||
<div class="paging-footer"></div>
|
||||
|
||||
<% } else {%>
|
||||
|
||||
<div class="bookmarks-empty" tabindex="0">
|
||||
@@ -53,7 +53,7 @@ ${page_title_breadcrumbs(course_name())}
|
||||
% endfor
|
||||
% endif
|
||||
|
||||
% for template_name in ["bookmarks_list"]:
|
||||
% for template_name in ["bookmarks-list"]:
|
||||
<script type="text/template" id="${template_name}-tpl">
|
||||
<%static:include path="bookmarks/${template_name}.underscore" />
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user