summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarren Smith <garren.smith@gmail.com>2014-01-07 14:30:30 +0200
committerGarren Smith <garren.smith@gmail.com>2014-01-08 16:19:36 +0200
commit1a3937022cc11fb0b5256165f4e4f2259fd9f468 (patch)
tree41873b64d6e028c4e798430266820a82914ec2cb
parent767b0582fd69c12a527cc2dc0e32ed3c4f54885e (diff)
downloadcouchdb-1a3937022cc11fb0b5256165f4e4f2259fd9f468.tar.gz
Fauxton: Improve UX for pagination
-rw-r--r--src/fauxton/app/modules/documents/resources.js46
-rw-r--r--src/fauxton/app/modules/documents/routes.js10
-rw-r--r--src/fauxton/app/modules/documents/views.js56
-rw-r--r--src/fauxton/app/modules/fauxton/components.js31
-rw-r--r--src/fauxton/app/templates/databases/item.html2
-rw-r--r--src/fauxton/app/templates/documents/advanced_options.html5
-rw-r--r--src/fauxton/app/templates/documents/all_docs_layout.html2
-rw-r--r--src/fauxton/app/templates/documents/all_docs_number.html4
-rw-r--r--src/fauxton/app/templates/documents/index_row_docular.html5
-rw-r--r--src/fauxton/app/templates/documents/sidebar.html2
10 files changed, 114 insertions, 49 deletions
diff --git a/src/fauxton/app/modules/documents/resources.js b/src/fauxton/app/modules/documents/resources.js
index 83589ca3a..43bb0fdc7 100644
--- a/src/fauxton/app/modules/documents/resources.js
+++ b/src/fauxton/app/modules/documents/resources.js
@@ -225,6 +225,10 @@ function(app, FauxtonAPI) {
});
Documents.ViewRow = Backbone.Model.extend({
+ // this is a hack so that backbone.collections doesn't group
+ // these by id and reduce the number of items returned.
+ idAttribute: "_id",
+
docType: function() {
if (!this.id) return "reduction";
@@ -329,16 +333,15 @@ function(app, FauxtonAPI) {
return this.url('app');
},
- urlPreviousPage: function (num, firstId) {
- this.params.limit = num;
- if (firstId) {
- this.params.startkey_docid = '"' + firstId + '"';
- this.params.startkey = '"' + firstId + '"';
+ urlPreviousPage: function (num, params) {
+ if (params) {
+ this.params = params;
} else {
- delete this.params.startkey;
- delete this.params.startkey_docid;
+ this.params = {reduce: false};
}
- return this.url('app');
+
+ this.params.limit = num;
+ return this.url('app');
},
totalRows: function() {
@@ -429,24 +432,27 @@ function(app, FauxtonAPI) {
urlNextPage: function (num, lastId) {
if (!lastId) {
- lastId = this.last().id;
+ lastDoc = this.last();
}
- this.params.startkey_docid = '"' + lastId + '"';
- this.params.startkey = '"' + lastId + '"';
- this.params.limit = num;
+ var id = lastDoc.get("id");
+ if (id) {
+ this.params.startkey_docid = id;
+ }
+
+ this.params.startkey = JSON.stringify(lastDoc.get('key'));
+ this.params.limit = num + 1;
return this.url('app');
},
- urlPreviousPage: function (num, firstId) {
- this.params.limit = num;
- if (firstId) {
- this.params.startkey_docid = '"' + firstId + '"';
- this.params.startkey = '"' + firstId + '"';
+ urlPreviousPage: function (num, params) {
+ if (params) {
+ this.params = params;
} else {
- delete this.params.startkey;
- delete this.params.startkey_docid;
+ this.params = {reduce: false};
}
+
+ this.params.limit = num;
return this.url('app');
},
@@ -463,6 +469,8 @@ function(app, FauxtonAPI) {
},
totalRows: function() {
+ if (this.params.reduce) { return "unknown_reduce";}
+
return this.viewMeta.total_rows || "unknown";
},
diff --git a/src/fauxton/app/modules/documents/routes.js b/src/fauxton/app/modules/documents/routes.js
index 538cd56eb..dbad6d067 100644
--- a/src/fauxton/app/modules/documents/routes.js
+++ b/src/fauxton/app/modules/documents/routes.js
@@ -188,7 +188,6 @@ function(app, FauxtonAPI, Documents, Databases) {
allDocs: function(databaseName, options) {
var docOptions = app.getParams(options);
- docOptions.include_docs = true;
this.data.database.buildAllDocs(docOptions);
if (docOptions.startkey && docOptions.startkey.indexOf('_design') > -1) {
@@ -234,8 +233,6 @@ function(app, FauxtonAPI, Documents, Databases) {
params: params
});
-
-
var ddocInfo = {
id: "_design/" + decodeDdoc,
currView: view,
@@ -301,9 +298,9 @@ function(app, FauxtonAPI, Documents, Databases) {
ddoc = event.ddoc;
if (event.allDocs) {
- docOptions.include_docs = true;
- this.data.database.buildAllDocs(docOptions);
- return;
+ this.documentsView.collection = this.data.database.buildAllDocs(docOptions);
+ this.documentsView.cleanup();
+ return this.documentsView.forceRender();
}
this.data.indexedDocs = new Documents.IndexCollection(null, {
@@ -313,6 +310,7 @@ function(app, FauxtonAPI, Documents, Databases) {
params: app.getParams()
});
+ this.documentsView && this.documentsView.remove();
this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
database: this.data.database,
collection: this.data.indexedDocs,
diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js
index e1554356a..0c75b8198 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -446,6 +446,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
initialize: function (options) {
this.newView = options.newView || false;
+ this.showNumbers = options.showNumbers;
+ this.pagination = options.pagination;
this.listenTo(this.collection, 'totalRows:decrement', this.render);
},
@@ -453,7 +455,9 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
serialize: function () {
var totalRows = 0,
recordStart = 0,
- updateSeq = false;
+ updateSeq = false,
+ pageStart = 0,
+ pageEnd = 20;
if (!this.newView) {
totalRows = this.collection.totalRows();
@@ -461,13 +465,20 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
}
recordStart = this.collection.recordStart();
+ if (this.pagination) {
+ pageStart = this.pagination.pageStart();
+ pageEnd = this.pagination.pageEnd();
+ }
return {
database: app.mixins.safeURLName(this.collection.database.id),
updateSeq: updateSeq,
offset: recordStart,
totalRows: totalRows,
+ showNumbers: this.showNumbers,
numModels: this.collection.models.length + recordStart - 1,
+ pageStart: pageStart,
+ pageEnd: pageEnd
};
}
@@ -492,7 +503,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
beforeRender: function () {
this.advancedOptions = this.insertView('#query', new Views.AdvancedOptions({
- updateViewFn: this.updateView,
+ updateViewFn: this.updateAllDocs,
previewFn: this.previewView,
hasReduce: false,
showPreview: false,
@@ -509,7 +520,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
},
- updateView: function (event, paramInfo) {
+ updateAllDocs: function (event, paramInfo) {
event.preventDefault();
var errorParams = paramInfo.errorParams,
@@ -578,7 +589,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
}
this.newView = options.newView || false;
this.expandDocs = true;
- this.addPagination();
},
establish: function() {
@@ -651,7 +661,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
});
model.collection.remove(model.id);
- console.log(model.id.match('_design'), !!model.id.match('_design'));
if (!!model.id.match('_design')) {
FauxtonAPI.triggerRouteEvent('reloadDesignDocs');
}
@@ -667,22 +676,31 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
addPagination: function () {
var collection = this.collection;
+ var perPage = function () {
+ if (collection.params.limit && collection.skipFirstItem) {
+ return parseInt(collection.params.limit, 10) - 1;
+ } else if (collection.params.limit) {
+ return parseInt(collection.params.limit, 10);
+ }
+
+ return 20;
+ };
this.pagination = new Components.IndexPagination({
collection: this.collection,
scrollToSelector: '#dashboard-content',
previousUrlfn: function () {
- return collection.urlPreviousPage(20, this.previousIds.pop());
+ return collection.urlPreviousPage(perPage(), this.previousParams.pop());
},
canShowPreviousfn: function () {
- if (collection.viewMeta.offset === 0) {
+ if (this.previousParams.length === 0) {
return false;
}
return true;
},
canShowNextfn: function () {
- if (collection.length === 0 || (collection.viewMeta.offset + collection.length + 2) >= collection.viewMeta.total_rows) {
+ if (collection.length < (perPage() -1)) {
return false;
}
@@ -690,18 +708,34 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
},
nextUrlfn: function () {
- return collection.urlNextPage(20);
+ return collection.urlNextPage(perPage());
}
});
},
+
+ cleanup: function () {
+ this.pagination.remove();
+ this.allDocsNumber.remove();
+ _.each(this.rows, function (row) {row.remove();});
+ },
beforeRender: function() {
+ var showNumbers = true;
+
+ this.addPagination();
+ this.insertView('#documents-pagination', this.pagination);
+
+ if (this.designDocs || this.collection.idxType === '_view' || this.collection.params.startkey === '"_design"') {
+ showNumbers = false;
+ }
+
this.allDocsNumber = this.setView('#item-numbers', new Views.AllDocsNumber({
collection: this.collection,
- newView: this.newView
+ newView: this.newView,
+ showNumbers: showNumbers,
+ pagination: this.pagination
}));
- this.insertView('#documents-pagination', this.pagination);
var docs = this.expandDocs ? this.collection : this.collection.simple();
docs.each(function(doc) {
diff --git a/src/fauxton/app/modules/fauxton/components.js b/src/fauxton/app/modules/fauxton/components.js
index 6afe0467c..a9f45addb 100644
--- a/src/fauxton/app/modules/fauxton/components.js
+++ b/src/fauxton/app/modules/fauxton/components.js
@@ -60,8 +60,6 @@ function(app, FauxtonAPI, ace) {
"click a#previous": 'previousClicked'
},
- previousIds: [],
-
scrollTo: function () {
if (!this.scrollToSelector) { return; }
$(this.scrollToSelector).animate({ scrollTop: 0 }, 'slow');
@@ -74,6 +72,7 @@ function(app, FauxtonAPI, ace) {
this.canShowNextfn = options.canShowNextfn;
this.scrollToSelector = options.scrollToSelector;
_.bindAll(this);
+ this.previousParams = [];
},
previousClicked: function (event) {
@@ -88,10 +87,11 @@ function(app, FauxtonAPI, ace) {
event.preventDefault();
event.stopPropagation();
if (!this.canShowNextfn()) { return; }
- var doc = this.collection.first();
- if (doc) {
- this.previousIds.push(doc.id);
+ var params = _.clone(this.collection.params);
+
+ if (params) {
+ this.previousParams.push(params);
}
FauxtonAPI.navigate(this.nextUrlfn(), {trigger: false});
@@ -103,6 +103,27 @@ function(app, FauxtonAPI, ace) {
canShowNextfn: this.canShowNextfn,
canShowPreviousfn: this.canShowPreviousfn,
};
+ },
+
+ pageLimit: function () {
+ var limit = 20;
+
+ if (this.collection.params.limit && this.collection.skipFirstItem) {
+ limit = parseInt(this.collection.params.limit, 10) - 1;
+ } else if (this.collection.params.limit) {
+ limit = parseInt(this.collection.params.limit, 10);
+ }
+
+ return limit;
+ },
+
+ pageStart: function () {
+ return (this.previousParams.length * this.pageLimit()) + 1;
+
+ },
+
+ pageEnd: function () {
+ return (this.previousParams.length * this.pageLimit()) + this.pageLimit();
}
});
diff --git a/src/fauxton/app/templates/databases/item.html b/src/fauxton/app/templates/databases/item.html
index e2f80712f..313dd961b 100644
--- a/src/fauxton/app/templates/databases/item.html
+++ b/src/fauxton/app/templates/databases/item.html
@@ -13,7 +13,7 @@ the License.
-->
<td>
- <a href="#/database/<%=encoded%>/_all_docs?limit=<%=docLimit%>"><%= database.get("name") %></a>
+ <a href="#/database/<%=encoded%>/_all_docs?limit=<%=docLimit%>&include_docs=true"><%= database.get("name") %></a>
</td>
<td><%= database.status.humanSize() %></td>
<td><%= database.status.numDocs() %></td>
diff --git a/src/fauxton/app/templates/documents/advanced_options.html b/src/fauxton/app/templates/documents/advanced_options.html
index 8e96574b1..e2563253f 100644
--- a/src/fauxton/app/templates/documents/advanced_options.html
+++ b/src/fauxton/app/templates/documents/advanced_options.html
@@ -67,8 +67,9 @@ the License.
Limit:
<select name="limit" class="input-small">
<option>5</option>
- <option selected="selected">10</option>
- <option>25</option>
+ <option>10</option>
+ <option selected="selected">20</option>
+ <option>30</option>
<option>50</option>
<option>100</option>
</select>
diff --git a/src/fauxton/app/templates/documents/all_docs_layout.html b/src/fauxton/app/templates/documents/all_docs_layout.html
index 526c200d1..6b4a31bc4 100644
--- a/src/fauxton/app/templates/documents/all_docs_layout.html
+++ b/src/fauxton/app/templates/documents/all_docs_layout.html
@@ -12,7 +12,7 @@ License for the specific language governing permissions and limitations under
the License.
-->
<ul class="nav nav-tabs window-resizeable" id="db-views-tabs-nav">
- <li><a id="toggle-query" class="fonticon-plus fonticon" href="#query" data-toggle="tab">Query Options</a></li>
+ <li><a id="toggle-query" class="fonticon-plus fonticon" href="#query" data-bypass="true" data-toggle="tab">Query Options</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane" id="query">
diff --git a/src/fauxton/app/templates/documents/all_docs_number.html b/src/fauxton/app/templates/documents/all_docs_number.html
index c4ea8f64a..df8fe07b6 100644
--- a/src/fauxton/app/templates/documents/all_docs_number.html
+++ b/src/fauxton/app/templates/documents/all_docs_number.html
@@ -13,8 +13,10 @@ the License.
-->
<% if (totalRows === "unknown"){ %>
Showing 0 documents. <a href="#/database/<%=database%>/new"> Create your first document.</a>
-<% } else { %>
+<% } else if (showNumbers) { %>
Showing <%=offset%> - <%= numModels %> of <%= totalRows %> rows
+<% } else { %>
+ Showing <%=pageStart%> - <%= pageEnd %>
<%}%>
<% if (updateSeq) { %>
-- Update Sequence: <%= updateSeq %>
diff --git a/src/fauxton/app/templates/documents/index_row_docular.html b/src/fauxton/app/templates/documents/index_row_docular.html
index 383545359..f1b221757 100644
--- a/src/fauxton/app/templates/documents/index_row_docular.html
+++ b/src/fauxton/app/templates/documents/index_row_docular.html
@@ -11,8 +11,9 @@ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
-->
-
-<td class="select"><input type="checkbox"></td>
+<% if (doc.isEditable()) { %>
+ <td class="select"><input type="checkbox"></td>
+<% } %>
<td>
<div>
<pre class="prettyprint"><%- doc.prettyJSON() %></pre>
diff --git a/src/fauxton/app/templates/documents/sidebar.html b/src/fauxton/app/templates/documents/sidebar.html
index 8a73ae9a3..362dd0cbc 100644
--- a/src/fauxton/app/templates/documents/sidebar.html
+++ b/src/fauxton/app/templates/documents/sidebar.html
@@ -55,7 +55,7 @@ the License.
<nav>
<ul class="nav nav-list">
- <li class="active"><a id="all-docs" href="#<%= database.url('index') %>?limit=<%= docLimit %>" class="toggle-view"> All documents</a></li>
+ <li class="active"><a id="all-docs" href="#<%= database.url('index') %>?limit=<%= docLimit %>&include_docs=true" class="toggle-view"> All documents</a></li>
<li><a id="design-docs" href='#<%= database.url("index") %>?limit=<%= docLimit %>&startkey="_design"&endkey="_e"' class="toggle-view"> All design docs</a></li>
</ul>
<ul class="nav nav-list views">