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 2013/09/10 16:03:58 UTC

[12/14] git commit: updated refs/heads/index-pagination to db85b98

the basics working with tests


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

Branch: refs/heads/index-pagination
Commit: 7e0b1cea7aa1548b0815feb4177c3e4319b106dc
Parents: 4ac5314
Author: Garren Smith <ga...@gmail.com>
Authored: Fri Sep 6 14:49:36 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Tue Sep 10 09:41:13 2013 +0200

----------------------------------------------------------------------
 src/fauxton/app/modules/databases/views.js      |  10 +-
 src/fauxton/app/modules/documents/resources.js  |  64 +++++++++++-
 .../modules/documents/tests/resourcesSpec.js    |  84 ++++++++++++++++
 src/fauxton/app/modules/documents/views.js      |  36 ++++++-
 src/fauxton/app/modules/fauxton/base.js         |  23 +----
 src/fauxton/app/modules/fauxton/paginate.js     |  93 +++++++++++++++++
 .../app/templates/documents/all_docs_list.html  |  15 +--
 .../app/templates/fauxton/index_pagination.html |  24 +++++
 src/fauxton/test/core/paginateSpec.js           | 100 +++++++++++++++++++
 9 files changed, 403 insertions(+), 46 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/7e0b1cea/src/fauxton/app/modules/databases/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/databases/views.js b/src/fauxton/app/modules/databases/views.js
index c177264..ef75841 100644
--- a/src/fauxton/app/modules/databases/views.js
+++ b/src/fauxton/app/modules/databases/views.js
@@ -13,11 +13,11 @@
 define([
   "app",
 
-  "modules/fauxton/base",
+  "modules/fauxton/paginate",
   "api"
 ],
 
-function(app, Fauxton, FauxtonAPI) {
+function(app, Paginate, FauxtonAPI) {
   var Views = {};
 
   Views.Item = FauxtonAPI.View.extend({
@@ -32,8 +32,8 @@ function(app, Fauxton, FauxtonAPI) {
   });
 
   Views.List = FauxtonAPI.View.extend({
-    dbLimit: 10,
-    perPage: 10,
+    dbLimit: 20,
+    perPage: 20,
     template: "templates/databases/list",
     events: {
       "click button.all": "selectAll",
@@ -83,7 +83,7 @@ function(app, Fauxton, FauxtonAPI) {
         }));
       }, this);
 
-      this.insertView("#database-pagination", new Fauxton.Pagination({
+      this.insertView("#database-pagination", new Paginate.Pagination({
         page: this.page,
         perPage: this.perPage,
         total: this.collection.length,

http://git-wip-us.apache.org/repos/asf/couchdb/blob/7e0b1cea/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 0a80ad8..a9e9836 100644
--- a/src/fauxton/app/modules/documents/resources.js
+++ b/src/fauxton/app/modules/documents/resources.js
@@ -255,14 +255,41 @@ function(app, FauxtonAPI) {
       this.params = options.params;
     },
 
-    url: function() {
+    url: function(context) {
       var query = "";
       if (this.params) {
         query = "?" + $.param(this.params);
       }
+
+      if (context === 'app') {
+        return 'database/' + this.database.id + "/_all_docs" + query;
+      }
       return app.host + "/" + this.database.id + "/_all_docs" + query;
     },
 
+    urlNextPage: function (num, lastId) {
+      if (!lastId) {
+        lastId = this.last().id;
+      }
+
+      this.params.startkey_docid = '"' + lastId + '"';
+      this.params.startkey = '"' + lastId + '"';
+      this.params.limit = num;
+      return this.url('app');
+    },
+
+    urlPreviousPage: function (num, firstId) {
+      this.params.limit = num;
+      if (firstId) { 
+        this.params.startkey_docid = '"' + firstId + '"';
+        this.params.startkey = '"' + firstId + '"';
+      } else {
+        delete this.params.startkey;
+        delete this.params.startkey_docid;
+      }
+      return this.url('app');
+    },
+
     totalRows: function() {
       return this.viewMeta.total_rows || "unknown";
     },
@@ -301,15 +328,44 @@ function(app, FauxtonAPI) {
       this.design = options.design.replace('_design/','');
     },
 
-    url: function() {
+    url: function(context) {
       var query = "";
       if (this.params) {
         query = "?" + $.param(this.params);
       }
-      var url = [app.host, this.database.id, "_design", this.design, this.idxType, this.view];
+      
+      var startOfUrl = app.host;
+      if (context === 'app') {
+        startOfUrl = 'database';
+      }
+
+      var url = [startOfUrl, this.database.id, "_design", this.design, this.idxType, this.view];
       return url.join("/") + query;
     },
 
+    urlNextPage: function (num, lastId) {
+      if (!lastId) {
+        lastId = this.last().id;
+      }
+
+      this.params.startkey_docid = '"' + lastId + '"';
+      this.params.startkey = '"' + lastId + '"';
+      this.params.limit = num;
+      return this.url('app');
+    },
+
+     urlPreviousPage: function (num, firstId) {
+      this.params.limit = num;
+      if (firstId) { 
+        this.params.startkey_docid = '"' + firstId + '"';
+        this.params.startkey = '"' + firstId + '"';
+      } else {
+        delete this.params.startkey;
+        delete this.params.startkey_docid;
+      }
+      return this.url('app');
+    },
+
     totalRows: function() {
       return this.viewMeta.total_rows || "unknown";
     },
@@ -324,7 +380,7 @@ function(app, FauxtonAPI) {
 
       this.viewMeta = {
         total_rows: resp.total_rows,
-        offest: resp.offest,
+        offset: resp.offset,
         update_seq: resp.update_seq
       };
       return _.map(resp.rows, function(row) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/7e0b1cea/src/fauxton/app/modules/documents/tests/resourcesSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/tests/resourcesSpec.js b/src/fauxton/app/modules/documents/tests/resourcesSpec.js
new file mode 100644
index 0000000..35bbdb3
--- /dev/null
+++ b/src/fauxton/app/modules/documents/tests/resourcesSpec.js
@@ -0,0 +1,84 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+define([
+       'modules/documents/resources',
+      'testUtils'
+], function (Models, testUtils) {
+  var assert = testUtils.assert;
+
+  describe('IndexCollection', function () {
+    var collection;
+    beforeEach(function () {
+      collection = new Models.IndexCollection([{
+        id:'myId1',
+        doc: 'num1'
+      },
+      {
+        id:'myId2',
+        doc: 'num2'
+      }], {
+        database: {id: 'databaseId'},
+        design: '_design/myDoc'
+      });
+
+    });
+
+    it('Should return urlNext', function () {
+      var url = collection.urlNextPage(20);
+
+      assert.equal(url, 'database/databaseId/_design/myDoc/_view/?limit=20&reduce=false&startkey_docid=%22myId2%22&startkey=%22myId2%22');
+
+    });
+
+    it('Should return urlPrevious', function () {
+      var url = collection.urlPreviousPage(20, 'myId1');
+
+      assert.equal(url, 'database/databaseId/_design/myDoc/_view/?limit=20&reduce=false&startkey_docid=%22myId1%22&startkey=%22myId1%22');
+
+    });
+
+  });
+
+  describe('AllDocs', function () {
+    var collection;
+    beforeEach(function () {
+      collection = new Models.AllDocs([{
+        _id:'myId1',
+        doc: 'num1'
+      },
+      {
+        _id:'myId2',
+        doc: 'num2'
+      }], {
+        database: {id: 'databaseId'},
+        params: {limit: 20}
+      });
+
+    });
+
+    it('Should return urlNext', function () {
+      var url = collection.urlNextPage(20);
+
+      assert.equal(url, 'database/databaseId/_all_docs?limit=20&startkey_docid=%22myId2%22&startkey=%22myId2%22');
+
+    });
+
+     it('Should return urlPrevious', function () {
+      var url = collection.urlPreviousPage(20, 'myId1');
+      assert.equal(url, 'database/databaseId/_all_docs?limit=20&startkey_docid=%22myId1%22&startkey=%22myId1%22');
+    });
+
+
+  });
+
+});
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/7e0b1cea/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 83e1e8f..c345c9c 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -14,6 +14,7 @@ define([
        "app",
 
        "api",
+       "modules/fauxton/paginate",
 
        "modules/documents/resources",
        "modules/pouchdb/base",
@@ -29,7 +30,7 @@ define([
 
 ],
 
-function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint, resizeColumns) {
+function(app, FauxtonAPI, Paginate, Documents, pouchdb, Codemirror, JSHint, resizeColumns) {
   var Views = {};
 
   Views.Tabs = FauxtonAPI.View.extend({
@@ -435,6 +436,7 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint, resizeColumns)
         this.ddocID = options.ddocInfo.id;
       }
       this.newView = options.newView || false;
+      this.addPagination();
     },
 
     establish: function() {
@@ -510,7 +512,39 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, JSHint, resizeColumns)
       }, this);
     },
 
+    addPagination: function () {
+      var collection = this.collection;
+
+      this.pagination = new Paginate.IndexPagination({
+        collection: this.collection,
+        scrollToSelector: '#dashboard-lower-content',
+        previousUrlfn: function () {
+          return collection.urlPreviousPage(20, this.previousIds.pop());
+        },
+        canShowPreviousfn: function () {
+          if (collection.viewMeta.offset === 0) {
+            return false;
+          }
+
+          return true;
+        },
+        canShowNextfn: function () {
+          
+          if ((collection.viewMeta.offset + 1) === collection.viewMeta.total_rows) {
+            return false;
+          }
+
+          return true;
+        },
+        
+        nextUrlfn: function () {
+          return collection.urlNextPage(20);
+        }
+      });
+    },
+
     beforeRender: function() {
+      this.insertView('#documents-pagination', this.pagination);
       this.collection.each(function(doc) {
         this.rows[doc.id] = this.insertView("table.all-docs tbody", new this.nestedView({
           model: doc

http://git-wip-us.apache.org/repos/asf/couchdb/blob/7e0b1cea/src/fauxton/app/modules/fauxton/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/fauxton/base.js b/src/fauxton/app/modules/fauxton/base.js
index 8fa40fa..a4b3a5e 100644
--- a/src/fauxton/app/modules/fauxton/base.js
+++ b/src/fauxton/app/modules/fauxton/base.js
@@ -260,27 +260,6 @@ function(app, Backbone, resizeColumns) {
     }
   });
 
-  Fauxton.Pagination = Backbone.View.extend({
-    template: "templates/fauxton/pagination",
-
-    initialize: function(options) {
-      this.page = parseInt(options.page, 10);
-      this.perPage = options.perPage;
-      this.total = options.total;
-      this.totalPages = Math.ceil(this.total / this.perPage);
-      this.urlFun = options.urlFun;
-    },
-
-    serialize: function() {
-      return {
-        page: this.page,
-        perPage: this.perPage,
-        total: this.total,
-        totalPages: this.totalPages,
-        urlFun: this.urlFun
-      };
-    }
-  });
-
+  
   return Fauxton;
 });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/7e0b1cea/src/fauxton/app/modules/fauxton/paginate.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/fauxton/paginate.js b/src/fauxton/app/modules/fauxton/paginate.js
new file mode 100644
index 0000000..a32bbbe
--- /dev/null
+++ b/src/fauxton/app/modules/fauxton/paginate.js
@@ -0,0 +1,93 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+define([
+       "app",
+       // Libs
+      "api"
+],
+
+function(app, FauxtonAPI) {
+  var Paginate = app.module();
+   
+  Paginate.Pagination = FauxtonAPI.View.extend({
+    template: "templates/fauxton/pagination",
+
+    initialize: function(options) {
+      this.page = parseInt(options.page, 10);
+      this.perPage = options.perPage;
+      this.total = options.total;
+      this.totalPages = Math.ceil(this.total / this.perPage);
+      this.urlFun = options.urlFun;
+    },
+
+    serialize: function() {
+      return {
+        page: this.page,
+        perPage: this.perPage,
+        total: this.total,
+        totalPages: this.totalPages,
+        urlFun: this.urlFun
+      };
+    }
+  });
+
+  Paginate.IndexPagination = FauxtonAPI.View.extend({
+    template: "templates/fauxton/index_pagination",
+    events: {
+      "click a": 'scrollTo',
+      "click a#next": 'nextClicked',
+      "click a#previous": 'previousClicked'
+    },
+
+    currentDirection: 'next',
+    previousIds: [],
+
+    scrollTo: function () {
+      if (!this.scrollToSelector) { return; }
+      $(this.scrollToSelector).animate({ scrollTop: 0 }, 'slow');
+    },
+
+    initialize: function (options) {
+      this.previousUrlfn = options.previousUrlfn;
+      this.nextUrlfn = options.nextUrlfn;
+      this.canShowPreviousfn = options.canShowPreviousfn;
+      this.canShowNextfn = options.canShowNextfn;
+      this.scrollToSelector = options.scrollToSelector;
+      _.bindAll(this);
+    },
+
+    previousClicked: function (event) {
+      event.preventDefault();
+      this.currentDirection = 'previous';
+      FauxtonAPI.navigate(this.previousUrlfn());
+    },
+
+    nextClicked: function (event) {
+      event.preventDefault();
+      this.currentDirection = 'next';
+      this.previousIds.push(this.collection.first().id);
+      FauxtonAPI.navigate(this.nextUrlfn());
+    },
+
+    serialize: function () {
+      return {
+        canShowNextfn: this.canShowNextfn,
+        canShowPreviousfn: this.canShowPreviousfn,
+      };
+    }
+
+  });
+
+  return Paginate;
+});
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/7e0b1cea/src/fauxton/app/templates/documents/all_docs_list.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/all_docs_list.html b/src/fauxton/app/templates/documents/all_docs_list.html
index fd1a5b0..f602575 100644
--- a/src/fauxton/app/templates/documents/all_docs_list.html
+++ b/src/fauxton/app/templates/documents/all_docs_list.html
@@ -41,18 +41,5 @@ the License.
   <table class="all-docs table table-striped table-condensed">
     <tbody></tbody>
   </table>
-  <!--
-  <div class="pagination pagination-centered">
-    <ul>
-      <li class="disabled"><a href="#">&laquo;</a></li>
-      <li class="active"><a href="#">1</a></li>
-      <li><a href="#">2</a></li>
-      <li><a href="#">3</a></li>
-      <li><a href="#">4</a></li>
-      <li><a href="#">5</a></li>
-      <li><a href="#">&raquo;</a></li>
-    </ul>
-  </div>
-  -->
-
+  <div id="documents-pagination"></div>
 </div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/7e0b1cea/src/fauxton/app/templates/fauxton/index_pagination.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/fauxton/index_pagination.html b/src/fauxton/app/templates/fauxton/index_pagination.html
new file mode 100644
index 0000000..f445377
--- /dev/null
+++ b/src/fauxton/app/templates/fauxton/index_pagination.html
@@ -0,0 +1,24 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<div class="pagination pagination-centered">
+  <ul>
+    <li <% if (!canShowPreviousfn()) {%> class="disabled" <% } %>>
+       <a id="previous" href="#"> Previous </a>
+     </li>
+     <li <% if (!canShowNextfn()) {%> class="disabled" <% } %>>
+       <a id="next" href="#"> Next </a></li>
+  </ul>
+</div>
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/7e0b1cea/src/fauxton/test/core/paginateSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/test/core/paginateSpec.js b/src/fauxton/test/core/paginateSpec.js
new file mode 100644
index 0000000..6b7bfb6
--- /dev/null
+++ b/src/fauxton/test/core/paginateSpec.js
@@ -0,0 +1,100 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+define([
+       'api',
+       'modules/fauxton/paginate',
+       'modules/documents/resources',
+       'testUtils',
+       'app'
+], function (FauxtonAPI, Views, Models, testUtils, app) {
+  var assert = testUtils.assert,
+  ViewSandbox = testUtils.ViewSandbox;
+
+
+  describe('IndexPaginate', function () {
+    var viewSandbox, paginate, collection, navigateMock;
+    beforeEach(function () {
+      app.router = {
+        navigate: function () {}
+      };
+
+      collection = new Models.IndexCollection([{
+        id:'myId1',
+        doc: 'num1'
+      },
+      {
+        id:'myId2',
+        doc: 'num2'
+      }], {
+        database: {id: 'databaseId'},
+        design: '_design/myDoc'
+      });
+
+      paginate = new Views.IndexPagination({
+        collection: collection,
+        previousUrlfn: function () {},
+        nextUrlfn: function () {},
+        canShowPreviousfn: function () {},
+        canShowNextfn: function () {}
+      });
+      viewSandbox = new ViewSandbox();
+      viewSandbox.renderView(paginate); 
+    });
+
+    afterEach(function () {
+      viewSandbox.remove();
+    });
+
+    describe('#next', function () {
+
+      it('should set direction as next', function () {
+        paginate.$('a#next').click();
+
+        assert.equal(paginate.currentDirection, 'next');
+
+      });
+
+      it('Should navigate', function () {
+        var navigateMock = sinon.spy(FauxtonAPI, 'navigate');
+
+        paginate.$('a#next').click();
+
+        assert.ok(navigateMock.calledOnce);
+        FauxtonAPI.navigate.restore();
+      });
+
+    });
+
+
+    describe('#previous', function () {
+
+      it('should set direction as next', function () {
+        paginate.$('a#previous').click();
+
+        assert.equal(paginate.currentDirection, 'previous');
+
+      });
+
+      it('Should navigate', function () {
+        var navigateMock = sinon.spy(FauxtonAPI, 'navigate');
+
+        paginate.$('a#previous').click();
+
+        assert.ok(navigateMock.calledOnce);
+        FauxtonAPI.navigate.restore();
+      });
+
+
+    });
+
+  });
+});