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 2015/02/23 15:38:01 UTC

fauxton commit: updated refs/heads/master to 8cbf95d

Repository: couchdb-fauxton
Updated Branches:
  refs/heads/master eb06a9431 -> 8cbf95d34


Reactify AllDocNumbers

Convert AllDocNumbers to the react flow


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

Branch: refs/heads/master
Commit: 8cbf95d34a191770cfaadf7df98e07b5652e7602
Parents: eb06a94
Author: Garren Smith <ga...@gmail.com>
Authored: Wed Feb 18 13:32:08 2015 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Feb 23 16:37:12 2015 +0200

----------------------------------------------------------------------
 app/addons/documents/docs-list/actions.js       |  44 +++++++
 app/addons/documents/docs-list/actiontypes.js   |  18 +++
 .../documents/docs-list/docs-list.react.jsx     | 119 +++++++++++++++++++
 app/addons/documents/docs-list/stores.js        |  94 +++++++++++++++
 app/addons/documents/routes-documents.js        |   9 --
 app/addons/documents/shared-routes.js           |   8 --
 .../documents/templates/all_docs_number.html    |  37 ------
 app/addons/documents/tests/actionsSpec.js       |   8 +-
 app/addons/documents/tests/doclistStoresSpec.js |  70 +++++++++++
 .../tests/docnumbers.componentSpec.react.jsx    |  58 +++++++++
 .../documents/tests/docsnumbers-actionsSpec.js  |  38 ++++++
 app/addons/documents/tests/headerSpec.react.jsx |   7 --
 app/addons/documents/views.js                   |  96 ++++-----------
 13 files changed, 470 insertions(+), 136 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/8cbf95d3/app/addons/documents/docs-list/actions.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/docs-list/actions.js b/app/addons/documents/docs-list/actions.js
new file mode 100644
index 0000000..5886cc6
--- /dev/null
+++ b/app/addons/documents/docs-list/actions.js
@@ -0,0 +1,44 @@
+// 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',
+  'api',
+  'addons/documents/docs-list/actiontypes',
+  'addons/documents/docs-list/stores'
+],
+function (app, FauxtonAPI, ActionTypes, Stores) {
+
+  return {
+    collectionChanged: function (collection, pagination, perPage) {
+      FauxtonAPI.dispatch({
+        type: ActionTypes.COLLECTION_CHANGED,
+        collection: collection,
+        pagination: pagination,
+        perPage: perPage
+      });
+    },
+
+    updatePerPage: function (perPage) {
+      var pagination = Stores.allDocsListStore.getPagination();
+      pagination.updatePerPage(perPage);
+
+      FauxtonAPI.dispatch({
+        type: ActionTypes.PER_PAGE_CHANGE,
+        perPage: pagination.documentsLeftToFetch()
+      });
+
+      FauxtonAPI.triggerRouteEvent('perPageChange', pagination.documentsLeftToFetch());
+    }
+
+  };
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/8cbf95d3/app/addons/documents/docs-list/actiontypes.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/docs-list/actiontypes.js b/app/addons/documents/docs-list/actiontypes.js
new file mode 100644
index 0000000..dd5dfd5
--- /dev/null
+++ b/app/addons/documents/docs-list/actiontypes.js
@@ -0,0 +1,18 @@
+// 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([], function () {
+  return {
+    COLLECTION_CHANGED: 'COLLECTION_CHANGED',
+    PER_PAGE_CHANGE: 'PER_PAGE_CHANGE'
+  };
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/8cbf95d3/app/addons/documents/docs-list/docs-list.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/documents/docs-list/docs-list.react.jsx b/app/addons/documents/docs-list/docs-list.react.jsx
new file mode 100644
index 0000000..bdd81ee
--- /dev/null
+++ b/app/addons/documents/docs-list/docs-list.react.jsx
@@ -0,0 +1,119 @@
+// 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",
+  "react",
+  'addons/documents/docs-list/stores',
+  'addons/documents/docs-list/actions'
+  ], function (FauxtonAPI, React, Stores, Actions) {
+    var allDocsListStore = Stores.allDocsListStore;
+
+    var PerPageSelector = React.createClass({
+
+      perPageChange: function (e) {
+        var perPage = parseInt(e.target.value, 10);
+        this.props.perPageChange(perPage);
+      },
+
+      render: function () {
+        return (
+          <div id="per-page">
+            <label htmlFor="select-per-page" className="drop-down inline">
+              Per page:
+              <select id="select-per-page" onChange={this.perPageChange} value={this.props.perPage.toString()} className="input-small">
+                <option value="5">5</option>
+                <option value="10">10</option>
+                <option value="20">20</option>
+                <option value="30">30</option>
+                <option value="50">50</option>
+                <option value="100">100</option>
+              </select>
+            </label>
+          </div>
+        );
+      }
+
+    });
+
+    var AllDocsNumber = React.createClass({
+
+      getStoreState: function () {
+        return {
+          totalRows: allDocsListStore.getTotalRows(),
+          pageStart: allDocsListStore.getPageStart(),
+          pageEnd: allDocsListStore.getPageEnd(),
+          updateSeq: allDocsListStore.getUpdateSeq(),
+          perPage: allDocsListStore.getPerPage()
+        };
+      },
+
+      getInitialState: function () {
+        return this.getStoreState();
+      },
+
+      componentDidMount: function() {
+        allDocsListStore.on('change', this.onChange, this);
+      },
+
+      componentWillUnmount: function() {
+        allDocsListStore.off('change', this.onChange);
+      },
+
+      onChange: function () {
+        this.setState(this.getStoreState());
+      },
+
+      pageNumber: function () {
+        if (this.state.totalRows === 0) {
+          return <p> Showing 0 documents. </p>;
+        }
+
+        return <p>Showing {this.state.pageStart} - {this.state.pageEnd}</p>;
+      },
+
+      updateSequence: function () {
+        if (this.state.updateSeq) {
+          return <span> Update Sequence: {this.state.updateSeq} </span>;
+        }
+      },
+
+      perPageChange: function (perPage) {
+        Actions.updatePerPage(perPage);
+      },
+
+      render: function () {
+        return (
+          <div>
+            <div className="index-indicator">
+              {this.pageNumber()}
+              {this.updateSequence()}
+            </div>
+            <PerPageSelector perPageChange={this.perPageChange} perPage={this.state.perPage} />
+          </div>
+        );
+      }
+
+    });
+
+    return {
+      AllDocsNumber: AllDocsNumber,
+      PerPageSelector: PerPageSelector,
+      renderAllDocsNumber: function (el) {
+        React.render(<AllDocsNumber/>, el);
+      },
+      removeAllDocsNumber: function (el) {
+        React.unmountComponentAtNode(el);
+      }
+    };
+
+  });

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/8cbf95d3/app/addons/documents/docs-list/stores.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/docs-list/stores.js b/app/addons/documents/docs-list/stores.js
new file mode 100644
index 0000000..bc7b3f2
--- /dev/null
+++ b/app/addons/documents/docs-list/stores.js
@@ -0,0 +1,94 @@
+// 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',
+  'addons/documents/docs-list/actiontypes'
+],function (FauxtonAPI, ActionTypes) {
+
+  var Stores = {};
+
+  Stores.AllDocsListStore = FauxtonAPI.Store.extend({
+    initialize: function () {
+      this._totalRows = 0;
+      this._updateSeq = false;
+      this._pageStart = 0;
+      this._pageEnd = 20;
+      this._newView = false;
+      this._perPage = FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE;
+    },
+
+    collectionChanged: function (collection, pagination, perPage) {
+     if (!this._newView) {
+       this._totalRows = collection.length;
+       this._updateSeq = collection.updateSeq();
+     }
+
+     this._pageStart = pagination.pageStart();
+     this._pageEnd =  pagination.pageEnd();
+     this._perPage = perPage;
+     this._pagination = pagination;
+    },
+
+    getPagination: function () {
+      return this._pagination;
+    },
+
+    getPerPage: function () {
+      return this._perPage;
+    },
+
+    setPerPage: function (perPage) {
+      this._perPage = perPage;
+    },
+
+    getTotalRows: function () {
+      return this._totalRows;
+    },
+
+    getPageStart: function () {
+      return this._pageStart;
+    },
+
+    getPageEnd: function () {
+      return this._pageEnd;
+    },
+
+    getUpdateSeq: function () {
+      return this._updateSeq;
+    },
+
+    dispatch: function (action) {
+      switch (action.type) {
+        case ActionTypes.COLLECTION_CHANGED:
+          this.collectionChanged(action.collection, action.pagination, action.perPage);
+          this.triggerChange();
+          break;
+        case ActionTypes.PER_PAGE_CHANGE:
+          this.setPerPage(action.perPage);
+          this.triggerChange();
+          break;
+        default:
+          return;
+      }
+
+    }
+
+  });
+
+  Stores.allDocsListStore = new Stores.AllDocsListStore();
+
+  Stores.AllDocsListStore.dispatchToken = FauxtonAPI.dispatcher.register(Stores.allDocsListStore.dispatch);
+
+  return Stores;
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/8cbf95d3/app/addons/documents/routes-documents.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/routes-documents.js b/app/addons/documents/routes-documents.js
index 488ff6b..1a72502 100644
--- a/app/addons/documents/routes-documents.js
+++ b/app/addons/documents/routes-documents.js
@@ -169,18 +169,9 @@ function(app, FauxtonAPI, BaseRoute, Documents, Changes, Index, DocEditor, Datab
       });
       this.setView('#documents-pagination', this.pagination);
 
-      this.allDocsNumber = new Documents.Views.AllDocsNumber({
-        collection: collection,
-        pagination: this.pagination,
-        perPageDefault: this.perPageDefault
-      });
-
-      this.setView('#item-numbers', this.allDocsNumber);
-
       // documentsView will populate the collection
       this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
         pagination: this.pagination,
-        allDocsNumber: this.allDocsNumber,
         database: this.database,
         collection: collection,
         docParams: docParams,

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/8cbf95d3/app/addons/documents/shared-routes.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/shared-routes.js b/app/addons/documents/shared-routes.js
index 8c0db94..4d6fe37 100644
--- a/app/addons/documents/shared-routes.js
+++ b/app/addons/documents/shared-routes.js
@@ -105,14 +105,6 @@ define([
       });
       this.setView('#documents-pagination', this.pagination);
 
-      this.allDocsNumber = new Documents.Views.AllDocsNumber({
-        collection: options.indexedDocs,
-        pagination: this.pagination,
-        perPageDefault: this.perPageDefault
-      });
-
-      this.setView('#item-numbers', this.allDocsNumber);
-
       return this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
         pagination: this.pagination,
         allDocsNumber: this.allDocsNumber,

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/8cbf95d3/app/addons/documents/templates/all_docs_number.html
----------------------------------------------------------------------
diff --git a/app/addons/documents/templates/all_docs_number.html b/app/addons/documents/templates/all_docs_number.html
deleted file mode 100644
index 5148f96..0000000
--- a/app/addons/documents/templates/all_docs_number.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<%/*
-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="index-indicator">
-  <% if (totalRows === "unknown" || totalRows === 0) { %>
-  <p>Showing 0 documents.</p>
-  <% } else { %>
-  <p>Showing <%- pageStart %> - <%- pageEnd %></p>
-  <%}%>
-  <% if (updateSeq) { %>
-  -- Update Sequence: <%- updateSeq %>
-  <% } %>
-</div>
-<div id="per-page">
-  <label for="select-per-page" class="drop-down inline">
-    Per page:
-    <select id="select-per-page" name="per-page" class="input-small">
-      <option value="5">5</option>
-      <option value="10">10</option>
-      <option value="20">20</option>
-      <option value="30">30</option>
-      <option value="50">50</option>
-      <option value="100">100</option>
-    </select>
-  </label>
-</div>

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/8cbf95d3/app/addons/documents/tests/actionsSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/actionsSpec.js b/app/addons/documents/tests/actionsSpec.js
index 594e399..b49124c 100644
--- a/app/addons/documents/tests/actionsSpec.js
+++ b/app/addons/documents/tests/actionsSpec.js
@@ -139,7 +139,7 @@ define([
 
         designDoc.save = function () {
           var promise = $.Deferred();
-          promise.resolve(); 
+          promise.resolve();
           return promise;
         };
 
@@ -169,7 +169,7 @@ define([
 
         designDoc.save = function () {
           var promise = $.Deferred();
-          promise.resolve(); 
+          promise.resolve();
           return promise;
         };
 
@@ -257,7 +257,7 @@ define([
 
         designDoc.save = function () {
           var promise = $.Deferred();
-          promise.resolve(); 
+          promise.resolve();
           return promise;
         };
 
@@ -278,7 +278,7 @@ define([
 
         designDoc.save = function () {
           var promise = $.Deferred();
-          promise.resolve(); 
+          promise.resolve();
           return promise;
         };
 

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/8cbf95d3/app/addons/documents/tests/doclistStoresSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/doclistStoresSpec.js b/app/addons/documents/tests/doclistStoresSpec.js
new file mode 100644
index 0000000..6af1e00
--- /dev/null
+++ b/app/addons/documents/tests/doclistStoresSpec.js
@@ -0,0 +1,70 @@
+// 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',
+  'addons/documents/docs-list/stores',
+  'addons/documents/docs-list/actiontypes',
+  'testUtils'
+], function (FauxtonAPI, Stores, ActionTypes, testUtils) {
+  var assert = testUtils.assert;
+  var store;
+  var dispatchToken;
+
+
+  describe('AllDocsListStore', function () {
+
+    beforeEach(function () {
+      store = new Stores.AllDocsListStore();
+      dispatchToken = FauxtonAPI.dispatcher.register(store.dispatch);
+    });
+
+    afterEach(function () {
+      FauxtonAPI.dispatcher.unregister(dispatchToken);
+    });
+
+    describe('#collectionChanged', function () {
+      var collection, pagination;
+      beforeEach(function () {
+        collection = new Backbone.Collection([{id:1}, {id: 2}]);
+        collection.updateSeq = function () { return 'updateSeq';};
+        pagination = {
+          pageStart: function () { return 10; },
+          pageEnd: function () { return 30; }
+        };
+      });
+
+      it('sets total rows correctly', function () {
+        store.collectionChanged(collection, pagination);
+        assert.equal(store.getTotalRows(), 2);
+      });
+
+      it('sets updateSeq', function () {
+        store.collectionChanged(collection, pagination);
+        assert.equal(store.getUpdateSeq(), 'updateSeq');
+      });
+
+      it('sets pageStart', function () {
+        store.collectionChanged(collection, pagination);
+        assert.equal(store.getPageStart(), 10);
+      });
+
+      it('sets pageEnd', function () {
+        store.collectionChanged(collection, pagination);
+        assert.equal(store.getPageEnd(), 30);
+      });
+
+    });
+
+
+  });
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/8cbf95d3/app/addons/documents/tests/docnumbers.componentSpec.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/docnumbers.componentSpec.react.jsx b/app/addons/documents/tests/docnumbers.componentSpec.react.jsx
new file mode 100644
index 0000000..dffc3c7
--- /dev/null
+++ b/app/addons/documents/tests/docnumbers.componentSpec.react.jsx
@@ -0,0 +1,58 @@
+// 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',
+  'addons/documents/docs-list/docs-list.react',
+  'testUtils',
+  "react"
+], function (FauxtonAPI, Views, utils, React) {
+  FauxtonAPI.router = new FauxtonAPI.Router([]);
+
+  var assert = utils.assert;
+  var TestUtils = React.addons.TestUtils;
+
+  describe('All Docs Number', function () {
+
+    describe('PerPageSelector', function () {
+      var container, selectorEl, perPageChange;
+
+      beforeEach(function () {
+        perPageChange = sinon.spy();
+        container = document.createElement('div');
+        selectorEl = TestUtils.renderIntoDocument(
+          <Views.PerPageSelector
+            perPageChange={perPageChange}
+            perPage={10}
+          />,
+          container
+        );
+      });
+
+      afterEach(function () {
+        React.unmountComponentAtNode(container);
+      });
+
+      it('on new select calls callback with new page size', function () {
+        var selectEl = $(selectorEl.getDOMNode()).find('#select-per-page')[0];
+        var perPage = 5;
+        TestUtils.Simulate.change(selectEl, {
+          target: {
+            value: perPage
+          }
+        });
+
+        assert.ok(perPageChange.calledWith(perPage));
+      });
+
+    });
+  });
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/8cbf95d3/app/addons/documents/tests/docsnumbers-actionsSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/docsnumbers-actionsSpec.js b/app/addons/documents/tests/docsnumbers-actionsSpec.js
new file mode 100644
index 0000000..0646910
--- /dev/null
+++ b/app/addons/documents/tests/docsnumbers-actionsSpec.js
@@ -0,0 +1,38 @@
+define([
+  'api',
+  'addons/documents/docs-list/actions',
+  'addons/documents/docs-list/stores',
+  'testUtils',
+], function (FauxtonAPI, Actions, Stores, testUtils) {
+  var assert = testUtils.assert;
+
+  FauxtonAPI.router = new FauxtonAPI.Router([]);
+
+  describe('All Docs Numbers Actions', function () {
+
+    describe('updatePerPage', function () {
+      var pagination;
+
+      beforeEach(function () {
+        pagination = {
+          updatePerPage: function () {},
+          documentsLeftToFetch: function () { return 30; }
+        };
+      });
+
+      afterEach(function () {
+        Stores.allDocsListStore.getPagination.restore();
+        FauxtonAPI.triggerRouteEvent.restore();
+      });
+
+      it('triggers routeEvent', function () {
+        var stub = sinon.stub(Stores.allDocsListStore, 'getPagination');
+        stub.returns(pagination);
+        var spy = sinon.spy(FauxtonAPI, 'triggerRouteEvent');
+        Actions.updatePerPage(30);
+
+        assert.ok(spy.calledWith('perPageChange', 30));
+      });
+    });
+  });
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/8cbf95d3/app/addons/documents/tests/headerSpec.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/headerSpec.react.jsx b/app/addons/documents/tests/headerSpec.react.jsx
index 874cf84..83edada 100644
--- a/app/addons/documents/tests/headerSpec.react.jsx
+++ b/app/addons/documents/tests/headerSpec.react.jsx
@@ -101,18 +101,11 @@ define([
         perPage: 20
       });
 
-      var allDocsNumber = new Documents.Views.AllDocsNumber({
-        collection: database.allDocs,
-        pagination: pagination,
-        perPageDefault: 20
-      });
-
       var view = new Documents.Views.AllDocsList({
         viewList: false,
         bulkDeleteDocsCollection: bulkDeleteDocCollection,
         collection: database.allDocs,
         pagination: pagination,
-        allDocsNumber: allDocsNumber
       });
 
       viewSandbox = new ViewSandbox();

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/8cbf95d3/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/views.js b/app/addons/documents/views.js
index 15e7763..62cd8e2 100644
--- a/app/addons/documents/views.js
+++ b/app/addons/documents/views.js
@@ -24,13 +24,16 @@ define([
   // React
   'addons/documents/header/header.react',
   'addons/documents/header/header.actions',
+  'addons/documents/docs-list/docs-list.react',
+  'addons/documents/docs-list/actions',
 
   //plugins
   "plugins/prettify"
 ],
 
 function (app, FauxtonAPI, Components, Documents,
-  Databases, Views, QueryOptions, ReactHeader, ReactHeaderActions) {
+  Databases, Views, QueryOptions, ReactHeader, ReactHeaderActions,
+  ReactAllDocsList, AllDocsListActions) {
 
   function showError (msg) {
     FauxtonAPI.addNotification({
@@ -41,7 +44,26 @@ function (app, FauxtonAPI, Components, Documents,
   }
 
   Views.Footer = FauxtonAPI.View.extend({
-    template: "addons/documents/templates/all_docs_footer"
+    template: "addons/documents/templates/all_docs_footer",
+
+    beforeRender: function () {
+     this.allDocsNumber = new Views.ReactAllDocsNumber();
+     this.setView('#item-numbers', this.allDocsNumber);
+    },
+
+    cleanup: function () {
+      this.allDocsNumber.remove();
+    }
+  });
+
+  Views.ReactAllDocsNumber = FauxtonAPI.View.extend({
+    afterRender: function () {
+      ReactAllDocsList.renderAllDocsNumber(this.el);
+    },
+
+    cleanup: function () {
+      ReactAllDocsList.removeAllDocsNumber(this.el);
+    }
   });
 
   Views.ReactHeaderbar = FauxtonAPI.View.extend({
@@ -252,72 +274,6 @@ function (app, FauxtonAPI, Components, Documents,
     }
   });
 
-  Views.AllDocsNumber = FauxtonAPI.View.extend({
-    template: "addons/documents/templates/all_docs_number",
-
-    initialize: function (options) {
-      this.newView = options.newView || false;
-      this.pagination = options.pagination;
-      _.bindAll(this);
-
-      this._perPage = options.perPageDefault || FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE;
-      this.listenTo(this.collection, 'totalRows:decrement', this.render);
-    },
-
-    events: {
-      'change #select-per-page': 'updatePerPage'
-    },
-
-    establish: function () {
-      return this.collection.fetch({
-        reset: true
-      });
-    },
-
-    updatePerPage: function (event) {
-      this._perPage = parseInt(this.$('#select-per-page :selected').val(), 10);
-      this.pagination.updatePerPage(this.perPage());
-      FauxtonAPI.triggerRouteEvent('perPageChange', this.pagination.documentsLeftToFetch());
-    },
-
-    afterRender: function () {
-      this.$('option[value="' + this.perPage() + '"]').attr('selected', "selected");
-    },
-
-    serialize: function () {
-       var totalRows = 0,
-          updateSeq = false,
-          pageStart = 0,
-          pageEnd = 20;
-
-      if (!this.newView) {
-        totalRows = this.collection.length;
-        updateSeq = this.collection.updateSeq();
-      }
-
-      if (this.pagination) {
-        pageStart = this.pagination.pageStart();
-        pageEnd =  this.pagination.pageEnd();
-      }
-
-      return {
-        database: app.utils.safeURLName(this.collection.database.id),
-        updateSeq: updateSeq,
-        totalRows: totalRows,
-        pageStart: pageStart,
-        pageEnd: pageEnd
-      };
-    },
-
-    perPage: function () {
-      return this._perPage;
-    },
-
-    setCollection: function (collection) {
-      this.collection = collection;
-    }
-  });
-
   Views.AllDocsList = FauxtonAPI.View.extend({
     template: "addons/documents/templates/all_docs_list",
 
@@ -532,7 +488,7 @@ function (app, FauxtonAPI, Components, Documents,
       this.removeNestedViews();
 
       this.pagination.setCollection(this.collection);
-      this.allDocsNumber.setCollection(this.collection);
+      AllDocsListActions.collectionChanged(this.collection, this.pagination, this.perPageDefault);
 
       docs = this.expandDocs ? this.collection : this.collection.simple();
 
@@ -599,8 +555,6 @@ function (app, FauxtonAPI, Components, Documents,
     }
   });
 
-
-
   Views.JumpToDoc = FauxtonAPI.View.extend({
     template: "addons/documents/templates/jumpdoc",