You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2014/01/08 15:19:54 UTC

git commit: updated refs/heads/master to 1a39370

Updated Branches:
  refs/heads/master 767b0582f -> 1a3937022


Fauxton: Improve UX for pagination


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/1a393702
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/1a393702
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/1a393702

Branch: refs/heads/master
Commit: 1a3937022cc11fb0b5256165f4e4f2259fd9f468
Parents: 767b058
Author: Garren Smith <ga...@gmail.com>
Authored: Tue Jan 7 14:30:30 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Wed Jan 8 16:19:36 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/modules/documents/resources.js  | 46 +++++++++-------
 src/fauxton/app/modules/documents/routes.js     | 10 ++--
 src/fauxton/app/modules/documents/views.js      | 56 ++++++++++++++++----
 src/fauxton/app/modules/fauxton/components.js   | 31 +++++++++--
 src/fauxton/app/templates/databases/item.html   |  2 +-
 .../templates/documents/advanced_options.html   |  5 +-
 .../templates/documents/all_docs_layout.html    |  2 +-
 .../templates/documents/all_docs_number.html    |  4 +-
 .../templates/documents/index_row_docular.html  |  5 +-
 .../app/templates/documents/sidebar.html        |  2 +-
 10 files changed, 114 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/1a393702/src/fauxton/app/modules/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/resources.js b/src/fauxton/app/modules/documents/resources.js
index 83589ca..43bb0fd 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";
     },
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/1a393702/src/fauxton/app/modules/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/routes.js b/src/fauxton/app/modules/documents/routes.js
index 538cd56..dbad6d0 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,

http://git-wip-us.apache.org/repos/asf/couchdb/blob/1a393702/src/fauxton/app/modules/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js
index e155435..0c75b81 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) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/1a393702/src/fauxton/app/modules/fauxton/components.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/fauxton/components.js b/src/fauxton/app/modules/fauxton/components.js
index 6afe046..a9f45ad 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();
     }
 
   });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/1a393702/src/fauxton/app/templates/databases/item.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/databases/item.html b/src/fauxton/app/templates/databases/item.html
index e2f8071..313dd96 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>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/1a393702/src/fauxton/app/templates/documents/advanced_options.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/advanced_options.html b/src/fauxton/app/templates/documents/advanced_options.html
index 8e96574..e256325 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>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/1a393702/src/fauxton/app/templates/documents/all_docs_layout.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/all_docs_layout.html b/src/fauxton/app/templates/documents/all_docs_layout.html
index 526c200..6b4a31b 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">

http://git-wip-us.apache.org/repos/asf/couchdb/blob/1a393702/src/fauxton/app/templates/documents/all_docs_number.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/all_docs_number.html b/src/fauxton/app/templates/documents/all_docs_number.html
index c4ea8f6..df8fe07 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 %>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/1a393702/src/fauxton/app/templates/documents/index_row_docular.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/index_row_docular.html b/src/fauxton/app/templates/documents/index_row_docular.html
index 3835453..f1b2217 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>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/1a393702/src/fauxton/app/templates/documents/sidebar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/sidebar.html b/src/fauxton/app/templates/documents/sidebar.html
index 8a73ae9..362dd0c 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">