couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From robertkowal...@apache.org
Subject [3/4] fauxton commit: updated refs/heads/master to bfdbf11
Date Thu, 14 Jan 2016 08:38:41 GMT
add prioritized table view

 - offer a truncated and a filtered table view
 - filtered table viewis initially prioritized from the most
   occuring fields
 - offer dropdown / typeahead to select which field should be used
   for filtering
 - add small working improvements

PR: #580
PR-URL: https://github.com/apache/couchdb-fauxton/pull/580
Reviewed-By: Benjamin Keen <ben.keen@gmail.com>


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

Branch: refs/heads/master
Commit: bfdbf1121eb5e60c49f0f48e2b144a1da19bcdf9
Parents: 1f8f6ba
Author: Robert Kowalski <robertkowalski@apache.org>
Authored: Wed Nov 25 14:31:08 2015 +0100
Committer: Robert Kowalski <robertkowalski@apache.org>
Committed: Thu Jan 14 09:40:22 2016 +0100

----------------------------------------------------------------------
 .../assets/less/header-togglebutton.less        |   9 +-
 .../components/react-components.react.jsx       |  14 +-
 app/addons/components/tests/docSpec.react.jsx   |   2 +-
 app/addons/documents/assets/less/documents.less |  16 +
 app/addons/documents/assets/less/header.less    |  63 +-
 .../documents/assets/less/index-results.less    |  87 ++-
 app/addons/documents/base.js                    |  13 +-
 app/addons/documents/doc-editor/actions.js      |   4 +-
 .../documents/doc-editor/components.react.jsx   |   4 -
 app/addons/documents/header/header.actions.js   |  48 +-
 .../documents/header/header.actiontypes.js      |   7 +-
 app/addons/documents/header/header.react.jsx    | 123 ++--
 app/addons/documents/index-results/actions.js   |  83 +--
 .../documents/index-results/actiontypes.js      |   5 +-
 .../index-results.components.react.jsx          | 331 ++++++++--
 app/addons/documents/index-results/stores.js    | 662 ++++++++++++++-----
 .../tests/index-results.actionsSpec.js          | 153 +----
 .../index-results.componentsSpec.react.jsx      |  89 ++-
 .../tests/index-results.storesSpec.js           | 511 +++++++++++---
 app/addons/documents/mango/mango.actions.js     |   6 +-
 .../documents/mango/mango.components.react.jsx  |   3 +-
 app/addons/documents/pagination/actions.js      |  44 +-
 .../documents/pagination/pagination.react.jsx   | 135 ++--
 app/addons/documents/pagination/stores.js       | 197 ------
 .../pagination/tests/pagination.actionsSpec.js  | 104 ---
 .../pagination/tests/paginationStoreSpec.js     | 285 --------
 .../queryoptions/queryoptions.react.jsx         |   2 +-
 app/addons/documents/queryoptions/stores.js     |   4 +
 app/addons/documents/resources.js               |   8 +
 app/addons/documents/routes-documents.js        |  16 +-
 app/addons/documents/routes-index-editor.js     |  16 +-
 app/addons/documents/routes-mango.js            |  20 +-
 app/addons/documents/shared-resources.js        |   1 +
 app/addons/documents/shared-routes.js           |   6 +-
 .../documents/tests/nightwatch/changes.js       |   4 +-
 .../documents/tests/nightwatch/paginateView.js  |   1 -
 .../tests/nightwatch/selectDocViaTypeahead.js   |   2 +-
 .../documents/tests/nightwatch/tableView.js     |  42 +-
 .../documents/tests/nightwatch/viewCreate.js    |   2 +-
 app/addons/fauxton/components.react.jsx         |  11 +-
 app/config.js                                   |   3 +
 app/core/utils.js                               |  22 -
 assets/less/fauxton.less                        |  84 ++-
 assets/less/templates.less                      |   1 +
 .../custom-commands/createDocument.js           |  26 +-
 45 files changed, 1818 insertions(+), 1451 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/components/assets/less/header-togglebutton.less
----------------------------------------------------------------------
diff --git a/app/addons/components/assets/less/header-togglebutton.less b/app/addons/components/assets/less/header-togglebutton.less
index 78da3db..e804204 100644
--- a/app/addons/components/assets/less/header-togglebutton.less
+++ b/app/addons/components/assets/less/header-togglebutton.less
@@ -28,6 +28,11 @@
       margin: 10px 6px 0 0;
     }
   }
+  .icon.fontawesome {
+    &:before {
+      margin: 6px 6px 0 0;
+    }
+  }
 }
 
 .header-control-square {
@@ -48,10 +53,6 @@
   }
 }
 
-button.header-control-box:focus {
-  outline: 0;
-}
-
 .js-headerbar-togglebutton-selected {
   .icon, span {
     color: @linkColor;

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/components/react-components.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/components/react-components.react.jsx b/app/addons/components/react-components.react.jsx
index c501396..ee52ae2 100644
--- a/app/addons/components/react-components.react.jsx
+++ b/app/addons/components/react-components.react.jsx
@@ -38,12 +38,13 @@ function (app, FauxtonAPI, React, Stores, FauxtonComponents, ace, beautifyHelper
         title: '',
         disabled: false,
         toggleCallback: null,
-        text: ''
+        text: '',
+        iconDefaultClass: 'icon'
       };
     },
 
     render: function () {
-      var iconClasses = 'icon ' + this.props.fonticon + ' ' + this.props.innerClasses,
+      var iconClasses = this.props.iconDefaultClass + ' ' + this.props.fonticon + ' ' + this.props.innerClasses,
           containerClasses = 'button ' + this.props.containerClasses;
 
       if (this.props.selected) {
@@ -69,9 +70,10 @@ function (app, FauxtonAPI, React, Stores, FauxtonComponents, ace, beautifyHelper
     propTypes: {
       hasSelectedItem: React.PropTypes.bool.isRequired,
       removeItem: React.PropTypes.func.isRequired,
-      selectAll: React.PropTypes.func.isRequired,
+      selectAll: React.PropTypes.func,
       toggleSelect: React.PropTypes.func.isRequired,
-      isChecked: React.PropTypes.bool.isRequired
+      isChecked: React.PropTypes.bool.isRequired,
+      disabled: React.PropTypes.bool
     },
 
     getDefaultProps: function () {
@@ -916,7 +918,7 @@ function (app, FauxtonAPI, React, Stores, FauxtonComponents, ace, beautifyHelper
 
     onChange: function (e) {
       e.preventDefault();
-      this.props.docChecked(this.props.docIdentifier, this.props.doc, e);
+      this.props.docChecked(this.props.doc.id, this.props.doc._rev);
     },
 
     getUrlFragment: function () {
@@ -1225,7 +1227,7 @@ function (app, FauxtonAPI, React, Stores, FauxtonComponents, ace, beautifyHelper
             containerClasses="header-control-box control-toggle-api-url"
             title="API URL"
             fonticon="fonticon-link"
-            text="API URL" />
+            text="API" />
 
           <TrayContents
             className="api-bar-tray">

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/components/tests/docSpec.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/components/tests/docSpec.react.jsx b/app/addons/components/tests/docSpec.react.jsx
index c7d9d9d..a931019 100644
--- a/app/addons/components/tests/docSpec.react.jsx
+++ b/app/addons/components/tests/docSpec.react.jsx
@@ -69,7 +69,7 @@ define([
       var spy = sinon.spy();
 
       el = TestUtils.renderIntoDocument(
-        <ReactComponents.Document isDeletable={true} docChecked={spy} docIdentifier="foo" />,
+        <ReactComponents.Document doc={{id: "foo"}} isDeletable={true} docChecked={spy} docIdentifier="foo" />,
         container
       );
       var testEl = $(el.getDOMNode()).find('input[type="checkbox"]')[0];

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/documents/assets/less/documents.less
----------------------------------------------------------------------
diff --git a/app/addons/documents/assets/less/documents.less b/app/addons/documents/assets/less/documents.less
index 8868da9..91355ae 100644
--- a/app/addons/documents/assets/less/documents.less
+++ b/app/addons/documents/assets/less/documents.less
@@ -36,6 +36,7 @@ button.beautify {
 
   #select-per-page {
     margin-top: 10px;
+    width: 60px;
   }
 }
 
@@ -165,3 +166,18 @@ button.string-edit[disabled] {
 .doc-editor-extension-icons {
   display: inline-block;
 }
+
+.pagination-footer {
+  .footer-table-control label {
+    margin: 0;
+    padding: 0;
+
+  }
+  .footer-table-control {
+    float: right;
+    display: inline-block;
+    input {
+      margin: 0 5px 0 15px;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/documents/assets/less/header.less
----------------------------------------------------------------------
diff --git a/app/addons/documents/assets/less/header.less b/app/addons/documents/assets/less/header.less
index 1ffc162..5c733a7 100644
--- a/app/addons/documents/assets/less/header.less
+++ b/app/addons/documents/assets/less/header.less
@@ -11,44 +11,37 @@
 // the License.
 
 
-button.control-view {
-  border-right: 1px solid @btnBorder;
-  border-left: none;
-}
-
-#react-headerbar .dropdown {
-  a {
-    text-decoration: none;
-    div {
-      margin-left: 30px;
+#react-headerbar {
+  .control-toggle-include-docs {
+    border-right: 1px solid @btnBorder;
+    .icon-check {
+      &:before {
+        margin: 6px 6px 0 0;
+      }
     }
-  }
-  li {
-    cursor: pointer;
-    i {
-      font-size: 17px;
-      position: absolute;
+    .icon-check-empty {
+      &:before {
+        margin: 6px 9px 0 0;
+      }
     }
   }
-  .icon {
-    position: relative;
-  }
-  .dropdown-toggle.fonticon-json:before {
-    margin-top: 9px;
-  }
-  .dropdown-menu {
-    left: -101px;
-    top: 55px;
-  }
-}
 
-#react-headerbar {
-  // dropdown needs position absolute
-  .add-dropdown {
-    right: initial;
-    top: initial;
-  }
-  .control-select-all {
-    margin-left: 95px;
+  .header-toggle-button {
+    font-size: 15px;
+    padding: 11px;
+
+    button.btn {
+      padding: 10px 15px;
+      &:hover {
+        background-color: @brandPrimary;
+        color: white;
+      }
+      &.active {
+        color: @brandPrimary;
+        &:hover {
+          background-color: white;
+        }
+      }
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/documents/assets/less/index-results.less
----------------------------------------------------------------------
diff --git a/app/addons/documents/assets/less/index-results.less b/app/addons/documents/assets/less/index-results.less
index 4bfa77f..591c520 100644
--- a/app/addons/documents/assets/less/index-results.less
+++ b/app/addons/documents/assets/less/index-results.less
@@ -12,11 +12,20 @@
 
 @import "../../../../../assets/less/variables.less";
 
-
 .document-result-screen {
   .bulk-action-component {
     padding-bottom: 15px;
   }
+
+  .loading-lines-wrapper {
+    margin-left: auto;
+    margin-right: auto;
+    width:  80px;
+  }
+
+  .loading-lines {
+    position: absolute;
+  }
 }
 
 .watermark-logo {
@@ -36,35 +45,97 @@
 }
 
 .table-view-docs {
+  position: absolute;
+  margin-top: 30px;
+
+
+  .bulk-action-component {
+    padding-bottom: 0;
+    min-height: 0px;
+  }
+  .bulk-action-component-panel input {
+    width: auto;
+  }
+
+
   .tableview-data-cell-id {
-    font-weight: 700;
     a {
       color: @linkColor;
     }
-  }
-  .tableview-header-el-checkbox {
-    border: none;
+    div:first-of-type {
+      font-weight: 700;
+    }
+    div {
+      text-overflow: ellipsis;
+      overflow: hidden;
+    }
   }
 
   td, th, td a {
     vertical-align: middle;
     line-height: 20px;
     font-size: 14px;
-    color: @defaultHTag;
   }
   td {
     height: 49px;
   }
   td, th {
+    color: @defaultHTag;
     max-width: 160px;
     overflow: hidden;
     text-overflow: ellipsis;
     white-space: nowrap;
   }
   td.tableview-checkbox-cell, th.tableview-header-el-checkbox {
-    width: 28px;
+    width: 68px;
   }
   .tableview-checkbox-cell input {
-    margin: 0px;
+    margin: 0 0 0 8px;
+  }
+  .tableview-el-last {
+    width: 50px;
+  }
+  .tableview-el-copy {
+    width: 35px;
+  }
+
+  thead input {
+    max-width: 138px;
+    width: 100%;
+  }
+
+  .table-dropdown-item {
+    padding: 2px 6px;
+    cursor: pointer;
+    background: #2b2f33;
+    color: white;
+    margin: 0 2px;
+  }
+  .table-dropdown-item-highlight {
+    background: #e23632;
+  }
+
+  .icon.icon-filter {
+    position: absolute;
+    right: 6px;
+    top: 6px;
+    pointer-events: none;
+    color: #999;
+  }
+
+  .table-container-autocomplete {
+    position: relative;
+    width: 128px;
+  }
+
+}
+
+.document-result-screen {
+
+  .table-bulkselector-section {
+    .bulk-action-component {
+      float: left;
+    }
+    width: 300px;
   }
 }

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/documents/base.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/base.js b/app/addons/documents/base.js
index c0eaa91..cb9b9d1 100644
--- a/app/addons/documents/base.js
+++ b/app/addons/documents/base.js
@@ -21,15 +21,22 @@ define([
 
 function (app, FauxtonAPI, Documents) {
 
+  function getQueryParam (query) {
+    if (!query) {
+      query = '';
+    }
+    return query;
+  }
+
   FauxtonAPI.registerUrls( 'allDocs', {
     server: function (id, query) {
-      return app.host + '/' + id + '/_all_docs' + query;
+      return app.host + '/' + id + '/_all_docs' + getQueryParam(query);
     },
     app: function (id, query) {
-      return 'database/' + id + '/_all_docs' + query;
+      return 'database/' + id + '/_all_docs' + getQueryParam(query);
     },
     apiurl: function (id, query) {
-      return window.location.origin + '/' + id + '/_all_docs' + query;
+      return window.location.origin + '/' + id + '/_all_docs' + getQueryParam(query);
     }
   });
 

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/documents/doc-editor/actions.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/doc-editor/actions.js b/app/addons/documents/doc-editor/actions.js
index 259cfc4..98095bf 100644
--- a/app/addons/documents/doc-editor/actions.js
+++ b/app/addons/documents/doc-editor/actions.js
@@ -45,8 +45,6 @@ function (app, FauxtonAPI, ActionTypes) {
   }
 
   function saveDoc (doc, isValidDoc, onSave) {
-    var databaseLink = doc.database.safeID();
-
     if (isValidDoc) {
       FauxtonAPI.addNotification({
         msg: 'Saving document.',
@@ -55,7 +53,7 @@ function (app, FauxtonAPI, ActionTypes) {
 
       doc.save().then(function () {
         onSave(doc.prettyJSON());
-        FauxtonAPI.navigate(FauxtonAPI.urls('document', 'app', databaseLink, doc.id));
+        FauxtonAPI.navigate('#' + FauxtonAPI.urls('allDocs', 'app', doc.database.id), {trigger: true});
       }).fail(function (xhr) {
         FauxtonAPI.addNotification({
           msg: 'Save failed: ' + JSON.parse(xhr.responseText).reason,

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/documents/doc-editor/components.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/documents/doc-editor/components.react.jsx b/app/addons/documents/doc-editor/components.react.jsx
index 462915a..6e1e051 100644
--- a/app/addons/documents/doc-editor/components.react.jsx
+++ b/app/addons/documents/doc-editor/components.react.jsx
@@ -89,11 +89,7 @@ define([
     },
 
     onSaveComplete: function (json) {
-      this.getEditor().setValue(json);
       this.getEditor().clearChanges();
-
-      // the save action updates the doc. This ensures the button row then shows the appropriate buttons
-      this.forceUpdate();
     },
 
     hideDeleteDocModal: function () {

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/documents/header/header.actions.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/header/header.actions.js b/app/addons/documents/header/header.actions.js
index 3e7cc04..6db2229 100644
--- a/app/addons/documents/header/header.actions.js
+++ b/app/addons/documents/header/header.actions.js
@@ -13,46 +13,36 @@
 define([
   'app',
   'api',
-  'addons/documents/header/header.actiontypes'
+  'addons/documents/header/header.actiontypes',
+  'addons/documents/queryoptions/actions',
+
 ],
-function (app, FauxtonAPI, ActionTypes) {
+function (app, FauxtonAPI, ActionTypes, ActionsQueryOptions) {
 
   return {
-    collapseDocuments: function () {
-      FauxtonAPI.dispatch({
-        type: ActionTypes.COLLAPSE_DOCUMENTS
-      });
-    },
 
-    unCollapseDocuments: function () {
-      FauxtonAPI.dispatch({
-        type: ActionTypes.EXPAND_DOCUMENTS
-      });
-    },
+    toggleIncludeDocs: function (state, bulkDocsCollection) {
+      var params = app.getParams();
 
-    collapseAllDocuments: function () {
-      FauxtonAPI.dispatch({
-        type: ActionTypes.COLLAPSE_ALL_DOCUMENTS
-      });
-    },
+      if (state) {
+        delete params.include_docs;
+      } else {
+        params.include_docs = true;
+      }
 
-    unCollapseAllDocuments: function () {
-      FauxtonAPI.dispatch({
-        type: ActionTypes.EXPAND_ALL_DOCUMENTS
-      });
-    },
+      app.utils.localStorageSet('include_docs_bulkdocs', bulkDocsCollection.toJSON());
 
-    enableTableView: function () {
-      FauxtonAPI.dispatch({
-        type: ActionTypes.ENABLE_TABLE_VIEW
-      });
+      ActionsQueryOptions.runQuery(params);
     },
 
-    disableTableView: function () {
+    toggleTableView: function (state) {
       FauxtonAPI.dispatch({
-        type: ActionTypes.DISABLE_TABLE_VIEW
+        type: ActionTypes.TOGGLE_TABLEVIEW,
+        options: {
+          enable: state
+        }
       });
-    },
+    }
 
   };
 });

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/documents/header/header.actiontypes.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/header/header.actiontypes.js b/app/addons/documents/header/header.actiontypes.js
index ee5039f..f4de5fc 100644
--- a/app/addons/documents/header/header.actiontypes.js
+++ b/app/addons/documents/header/header.actiontypes.js
@@ -12,11 +12,6 @@
 
 define([], function () {
   return {
-    COLLAPSE_DOCUMENTS: 'COLLAPSE_DOCUMENTS',
-    EXPAND_DOCUMENTS: 'UNCOLLAPSE_DOCUMENTS',
-    COLLAPSE_ALL_DOCUMENTS: 'COLLAPSE_ALL_DOCUMENTS',
-    EXPAND_ALL_DOCUMENTS: 'EXPAND_ALL_DOCUMENTS',
-    DISABLE_TABLE_VIEW: 'DISABLE_TABLE_VIEW',
-    ENABLE_TABLE_VIEW: 'ENABLE_TABLE_VIEW'
+    TOGGLE_TABLEVIEW: 'TOGGLE_TABLEVIEW',
   };
 });

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/documents/header/header.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/documents/header/header.react.jsx b/app/addons/documents/header/header.react.jsx
index 03246bd..74b680f 100644
--- a/app/addons/documents/header/header.react.jsx
+++ b/app/addons/documents/header/header.react.jsx
@@ -16,22 +16,34 @@ define([
   'react',
   'addons/documents/header/header.actions',
   'addons/components/react-components.react',
+
   'addons/documents/index-results/stores',
   'addons/documents/index-results/actions',
+  'libs/react-bootstrap',
+  'addons/documents/queryoptions/stores',
 ],
 
-function (app, FauxtonAPI, React, Actions, ReactComponents, IndexResultsStore, IndexResultsActions) {
+function (app, FauxtonAPI, React, Actions, ReactComponents,
+  IndexResultsStore, IndexResultsActions, ReactBootstrap, QueryOptionsStore) {
   var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
 
   var indexResultsStore = IndexResultsStore.indexResultsStore;
+  var queryOptionsStore = QueryOptionsStore.queryOptionsStore;
+
+
   var ToggleHeaderButton = ReactComponents.ToggleHeaderButton;
-  var MenuDropDown = ReactComponents.MenuDropDown;
+
+  var ButtonGroup = ReactBootstrap.ButtonGroup;
+  var Button = ReactBootstrap.Button;
 
 
   var BulkDocumentHeaderController = React.createClass({
     getStoreState: function () {
       return {
-        selectedView: indexResultsStore.getCurrentViewType()
+        selectedView: indexResultsStore.getCurrentViewType(),
+        isTableView: indexResultsStore.getIsTableView(),
+        includeDocs: queryOptionsStore.getIncludeDocsEnabled(),
+        bulkDocCollection: indexResultsStore.getBulkDocCollection(),
       };
     },
 
@@ -41,101 +53,60 @@ function (app, FauxtonAPI, React, Actions, ReactComponents, IndexResultsStore, I
 
     componentDidMount: function () {
       indexResultsStore.on('change', this.onChange, this);
+      queryOptionsStore.on('change', this.onChange, this);
+
     },
 
     componentWillUnmount: function () {
       indexResultsStore.off('change', this.onChange);
+      queryOptionsStore.off('change', this.onChange);
     },
 
     onChange: function () {
       this.setState(this.getStoreState());
     },
 
-    getIcon: function () {
-      if (this.state.selectedView === 'table') {
-        return 'fonticon-table';
-      }
-
-      if (this.state.selectedView === 'collapsed') {
-        return 'fonticon-list-alt';
-      }
-
-      return 'fonticon-json';
-    },
-
-    getCollapseDocsButton: function () {
-      var icon = this.getIcon();
-
-      return (
-        <div className="add-dropdown">
-          <div className="dropdown">
-            <button data-toggle="dropdown" className="button header-control-box control-view">
-              <i className={"dropdown-toggle icon " + icon}></i> View
-            </button>
-            <ul className="dropdown-menu arrow" role="menu" aria-labelledby="dLabel">
-              <li>
-                <a onClick={this.collapseAllDocuments}>
-                  <i className="fonticon-list-alt" />
-                  <div>
-                    Collapsed View
-                  </div>
-                </a>
-              </li>
-              <li>
-                <a onClick={this.toggleToNormalJson}>
-                  <i className="fonticon-json" />
-                  <div>
-                    Expanded View
-                  </div>
-                </a>
-              </li>
-              <li>
-                <a onClick={this.tablelizeView}>
-                  <i className="fonticon-table" />
-                  <div>
-                    Table View
-                  </div>
-                </a>
-              </li>
-            </ul>
-
-          </div>
-        </div>
-      );
-    },
-
     render: function () {
+      var isTableViewSelected = this.state.isTableView;
+
       return (
-        <div className='alternative-header'>
-          {this.getCollapseDocsButton()}
+        <div className="alternative-header">
+          <ButtonGroup className="header-toggle-button">
+            <Button
+              className={isTableViewSelected ? '' : 'active'}
+              onClick={this.toggleTableView.bind(this, false)}
+            >
+              <i className="fonticon-json" /> JSON
+            </Button>
+            <Button
+              className={isTableViewSelected ? 'active' : ''}
+              onClick={this.toggleTableView.bind(this, true)}
+            >
+              <i className="fonticon-table" /> Table
+            </Button>
+          </ButtonGroup>
+          {this.props.showIncludeAllDocs ? <ToggleHeaderButton
+            toggleCallback={this.toggleIncludeDocs}
+            containerClasses="header-control-box control-toggle-include-docs"
+            title="Enable/Disable include_docs"
+            fonticon={this.state.includeDocs ? 'icon-check' : 'icon-check-empty'}
+            iconDefaultClass="icon fontawesome"
+            text="Include Docs" /> : null}
         </div>
       );
     },
 
-    collapseDocuments: function () {
-      Actions.collapseDocuments();
-    },
-
-    unCollapseDocuments: function () {
-      Actions.unCollapseDocuments();
-    },
-
-    toggleToNormalJson: function () {
-      Actions.unCollapseAllDocuments();
-    },
-
-    collapseAllDocuments: function () {
-      Actions.collapseAllDocuments();
+    toggleIncludeDocs: function () {
+      Actions.toggleIncludeDocs(this.state.includeDocs, this.state.bulkDocCollection);
     },
 
-    tablelizeView: function () {
-      Actions.enableTableView();
+    toggleTableView: function (enable) {
+      Actions.toggleTableView(enable);
     }
   });
 
   var Views = {
-    BulkDocumentHeaderController: BulkDocumentHeaderController,
-    ToggleHeaderButton: ToggleHeaderButton
+    BulkDocumentHeaderController: BulkDocumentHeaderController
   };
 
   return Views;

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/documents/index-results/actions.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/index-results/actions.js b/app/addons/documents/index-results/actions.js
index 4fab529..e999140 100644
--- a/app/addons/documents/index-results/actions.js
+++ b/app/addons/documents/index-results/actions.js
@@ -37,6 +37,12 @@ function (app, FauxtonAPI, ActionTypes, Stores, Documents, SidebarActions) {
 
   return {
 
+    togglePrioritizedTableView: function () {
+      FauxtonAPI.dispatch({
+        type: ActionTypes.INDEX_RESULTS_TOGGLE_PRIORITIZED_TABLE_VIEW
+      });
+    },
+
     sendMessageNewResultList: function (options) {
       FauxtonAPI.dispatch({
         type: ActionTypes.INDEX_RESULTS_NEW_RESULTS,
@@ -45,13 +51,14 @@ function (app, FauxtonAPI, ActionTypes, Stores, Documents, SidebarActions) {
     },
 
     newResultsList: function (options) {
-      this.sendMessageNewResultList(options);
+      this.clearResults();
 
       if (!options.collection.fetch) { return; }
-      this.clearResults();
 
       return options.collection.fetch({reset: true}).then(function () {
         this.resultsListReset();
+        this.sendMessageNewResultList(options);
+
       }.bind(this), function (collection, _xhr) {
         //Make this more robust as sometimes the colection is passed through here.
         var xhr = collection.responseText ? collection : _xhr;
@@ -83,7 +90,8 @@ function (app, FauxtonAPI, ActionTypes, Stores, Documents, SidebarActions) {
 
     runMangoFindQuery: function (options) {
       var query = JSON.parse(options.queryCode),
-          collection = indexResultsStore.getCollection();
+          collection = indexResultsStore.getCollection(),
+          bulkCollection = indexResultsStore.getBulkDocCollection();
 
       this.clearResults();
 
@@ -96,7 +104,7 @@ function (app, FauxtonAPI, ActionTypes, Stores, Documents, SidebarActions) {
             collection: collection,
             query: options.queryCode,
             textEmptyIndex: 'No Results Found!',
-            bulkCollection: Documents.BulkDeleteDocCollection
+            bulkCollection: bulkCollection
           });
         }.bind(this), function (res) {
           FauxtonAPI.addNotification({
@@ -113,14 +121,14 @@ function (app, FauxtonAPI, ActionTypes, Stores, Documents, SidebarActions) {
       if (indexResultsStore.getTypeOfIndex() === 'mango') {
         return this.newResultsList({
           collection: indexResultsStore.getCollection(),
-          bulkCollection: Documents.MangoBulkDeleteDocCollection,
+          bulkCollection: indexResultsStore.getBulkDocCollection(),
           typeOfIndex: 'mango'
         });
       }
 
       return this.newResultsList({
         collection: indexResultsStore.getCollection(),
-        bulkCollection: Documents.BulkDeleteDocCollection
+        bulkCollection: indexResultsStore.getBulkDocCollection()
       });
     },
 
@@ -130,16 +138,21 @@ function (app, FauxtonAPI, ActionTypes, Stores, Documents, SidebarActions) {
       });
     },
 
-    selectDoc: function (id) {
+    selectDoc: function (options) {
       FauxtonAPI.dispatch({
         type: ActionTypes.INDEX_RESULTS_SELECT_DOC,
-        id: id
+        options: {
+          _id: options._id,
+          _rev: options._rev,
+          _deleted: true
+        }
       });
     },
 
-    selectAllDocuments: function () {
+    changeField: function (options) {
       FauxtonAPI.dispatch({
-        type: ActionTypes.INDEX_RESULTS_SELECT_ALL_DOCUMENTS
+        type: ActionTypes.INDEX_RESULTS_SELECT_NEW_FIELD_IN_TABLE,
+        options: options
       });
     },
 
@@ -149,21 +162,13 @@ function (app, FauxtonAPI, ActionTypes, Stores, Documents, SidebarActions) {
       });
     },
 
-    selectListOfDocs: function (ids) {
-      FauxtonAPI.dispatch({
-        type: ActionTypes.INDEX_RESULTS_SELECT_LIST_OF_DOCS,
-        ids: ids
-      });
-    },
-
     clearResults: function () {
       FauxtonAPI.dispatch({
         type: ActionTypes.INDEX_RESULTS_CLEAR_RESULTS
       });
     },
 
-    deleteSelected: function () {
-      var itemsLength = indexResultsStore.getSelectedItemsLength();
+    deleteSelected: function (bulkDeleteCollection, itemsLength) {
       var msg = (itemsLength === 1) ? 'Are you sure you want to delete this doc?' :
         'Are you sure you want to delete these ' + itemsLength + ' docs?';
 
@@ -177,30 +182,30 @@ function (app, FauxtonAPI, ActionTypes, Stores, Documents, SidebarActions) {
       }
 
       var reloadResultsList = _.bind(this.reloadResultsList, this);
-      var selectListOfDocs = _.bind(this.selectListOfDocs, this);
       var selectedIds = [];
 
-      indexResultsStore.createBulkDeleteFromSelected().bulkDelete()
-      .then(function (ids) {
-        FauxtonAPI.addNotification({
-          msg: 'Successfully deleted your docs',
-          clear:  true
-        });
+      bulkDeleteCollection
+        .bulkDelete()
+        .then(function (ids) {
+          FauxtonAPI.addNotification({
+            msg: 'Successfully deleted your docs',
+            clear:  true
+          });
 
-        if (!_.isEmpty(ids.errorIds)) {
-          errorMessage(ids.errorIds);
-          selectedIds = ids.errorIds;
-        }
-      }, function (ids) {
-        errorMessage(ids);
-        selectedIds = ids;
-      })
-      .always(function () {
-        reloadResultsList().then(function () {
-          selectListOfDocs(selectedIds);
-          SidebarActions.refresh();
+          if (!_.isEmpty(ids.errorIds)) {
+            errorMessage(ids.errorIds);
+            selectedIds = ids.errorIds;
+          }
+        }, function (ids) {
+          errorMessage(ids);
+          selectedIds = ids;
+        })
+        .always(function (id) {
+          reloadResultsList().then(function () {
+            bulkDeleteCollection.reset(selectedIds);
+            SidebarActions.refresh();
+          });
         });
-      });
     }
   };
 });

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/documents/index-results/actiontypes.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/index-results/actiontypes.js b/app/addons/documents/index-results/actiontypes.js
index 4794610..d98ae40 100644
--- a/app/addons/documents/index-results/actiontypes.js
+++ b/app/addons/documents/index-results/actiontypes.js
@@ -15,10 +15,11 @@ define([], function () {
     INDEX_RESULTS_NEW_RESULTS: 'INDEX_RESULTS_NEW_RESULTS',
     INDEX_RESULTS_RESET: 'INDEX_RESULTS_RESET',
     INDEX_RESULTS_SELECT_DOC: 'INDEX_RESULTS_SELECT_DOC',
-    INDEX_RESULTS_SELECT_LIST_OF_DOCS: 'INDEX_RESULTS_SELECT_LIST_OF_DOCS',
     INDEX_RESULTS_CLEAR_RESULTS: 'INDEX_RESULTS_CLEAR_RESULTS',
-    INDEX_RESULTS_SELECT_ALL_DOCUMENTS: 'INDEX_RESULTS_SELECT_ALL_DOCUMENTS',
     INDEX_RESULTS_TOOGLE_SELECT_ALL_DOCUMENTS: 'INDEX_RESULTS_TOOGLE_SELECT_ALL_DOCUMENTS',
+    INDEX_RESULTS_SELECT_NEW_FIELD_IN_TABLE: 'INDEX_RESULTS_SELECT_NEW_FIELD_IN_TABLE',
+    INDEX_RESULTS_CLEAR_SELECTED_ITEMS: 'INDEX_RESULTS_CLEAR_SELECTED_ITEMS',
+    INDEX_RESULTS_TOGGLE_PRIORITIZED_TABLE_VIEW: 'INDEX_RESULTS_TOGGLE_PRIORITIZED_TABLE_VIEW',
 
   };
 });

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/documents/index-results/index-results.components.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/documents/index-results/index-results.components.react.jsx b/app/addons/documents/index-results/index-results.components.react.jsx
index 089b83d..dcbec93 100644
--- a/app/addons/documents/index-results/index-results.components.react.jsx
+++ b/app/addons/documents/index-results/index-results.components.react.jsx
@@ -18,14 +18,24 @@ define([
   'addons/documents/index-results/actions',
   'addons/components/react-components.react',
   'addons/documents/resources',
+  'addons/fauxton/components.react',
+
+  'libs/react-bootstrap',
+  'react-autocomplete',
+
+  'plugins/prettify',
 
-  'plugins/prettify'
 ],
 
-function (app, FauxtonAPI, React, Stores, Actions, Components, Documents) {
+
+function (app, FauxtonAPI, React, Stores, Actions, Components, Documents, FauxtonComponents, ReactBootstrap, Autocomplete) {
   var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
   var store = Stores.indexResultsStore;
   var BulkActionComponent = Components.BulkActionComponent;
+  var Clipboard = FauxtonComponents.Clipboard;
+
+  var SplitButton = ReactBootstrap.SplitButton;
+  var MenuItem = ReactBootstrap.MenuItem;
 
   var NoResultScreen = React.createClass({
     render: function () {
@@ -47,7 +57,7 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, Documents) {
     },
 
     onChange: function (e) {
-      this.props.docChecked(this.props.docIdentifier, this.props.data, e);
+      this.props.docChecked(this.props.el.id, this.props.el._rev);
     },
 
     getInitialState: function () {
@@ -56,16 +66,17 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, Documents) {
       };
     },
 
-    getRowContents: function (element, rownumber) {
-      var row = this.props.schema.map(function (k, i) {
-        var el = element.content.doc || element.content;
-        var key = 'tableview-data-cell-' + rownumber + k + i + el[k];
+    getRowContents: function (element, rowNumber) {
+      var el = element.content;
+
+      var row = this.props.data.selectedFields.map(function (k, i) {
+
+        var key = 'tableview-data-cell-' + rowNumber + k + i + el[k];
         var stringified = typeof el[k] === 'object' ? JSON.stringify(el[k]) : el[k];
-        var className = k === '_id' ? 'tableview-data-cell-id' : null;
 
         return (
-          <td className={className} key={key} title={stringified}>
-            {k === '_id' ? this.maybeGetUrl(element.url, stringified) : stringified}
+          <td key={key} title={stringified}>
+            {stringified}
           </td>
         );
       }.bind(this));
@@ -73,85 +84,255 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, Documents) {
       return row;
     },
 
+    maybeGetSpecialField: function (element, i) {
+      if (!this.props.data.hasMetadata) {
+        return null;
+      }
+
+      var el = element.content;
+
+      return (
+        <td className="tableview-data-cell-id" key={'tableview-data-cell-id' + i}>
+          <div>{this.maybeGetUrl(element.url, el._id || el.id)}</div>
+          <div>{el._rev}</div>
+        </td>
+      );
+    },
+
     maybeGetUrl: function (url, stringified) {
       if (!url) {
         return stringified;
       }
 
       return (
-        <a href={url}>
+        <a href={'#' + url}>
           {stringified}
         </a>
       );
     },
 
-    maybeGetCheckboxCell: function (i) {
-      if (!this.props.data.isDeletable) {
-        return <td className="tableview-checkbox-cell" key={"tableview-checkbox-cell-" + i}></td>;
-      }
-
+    maybeGetCheckboxCell: function (el, i) {
       return (
         <td className="tableview-checkbox-cell" key={"tableview-checkbox-cell-" + i}>
-          <input
+          {el.isDeletable ? <input
             id={"checkbox-" + this.props.docIdentifier}
             checked={this.props.isSelected}
             type="checkbox"
-            onChange={this.onChange} />
+            onChange={this.onChange} /> : null}
+        </td>
+      );
+    },
+
+    getAttachmentRow: function (el) {
+      var attachmentCount = Object.keys(el._attachments || {}).length;
+      var paperClip = null;
+      var text = null;
+
+      if (attachmentCount) {
+        text = attachmentCount === 1 ? attachmentCount + ' Attachment' : attachmentCount + ' Attachments';
+        paperClip = (
+          <div><i className="icon fonticon-paperclip"></i> {attachmentCount}</div>
+        );
+      }
+
+      return (
+        <td title={text} className="tableview-el-last">
+          {paperClip}
         </td>
       );
     },
 
+    getCopyButton: function (el) {
+      var text = JSON.stringify(el, null, '  ');
+      return (
+        <td title={text} className="tableview-el-copy">
+          <Clipboard onClipboardClick={this.showCopiedMessage} title={text} text={text}/>
+        </td>
+      );
+    },
+
+    showCopiedMessage: function () {
+      FauxtonAPI.addNotification({
+        msg: 'The document content has been copied to the clipboard.',
+        type: 'success',
+        clear: true
+      });
+    },
+
     render: function () {
       var i = this.props.index;
+      var docContent = this.props.el.content;
+      var el = this.props.el;
 
       return (
         <tr key={"tableview-content-row-" + i}>
-          {this.maybeGetCheckboxCell(i)}
-          {this.getRowContents(this.props.data, i)}
+          {this.maybeGetCheckboxCell(el, i)}
+          {this.getCopyButton(docContent)}
+          {this.maybeGetSpecialField(el, i)}
+          {this.getRowContents(el, i)}
+          {this.getAttachmentRow(docContent)}
         </tr>
       );
     }
   });
 
+  var WrappedAutocomplete = React.createClass({
+
+    getInitialState: function () {
+      return {
+        showFilters: false
+      };
+    },
+
+    showFilters: function (state) {
+      this.setState({
+        showFilters: state
+      });
+    },
+
+    render: function () {
+
+      function matchItem (item, value) {
+        return (
+          item.indexOf(value) !== -1
+        );
+      }
+
+      function renderItems (items) {
+        return items.map(function (item) {
+          return item;
+        });
+      }
+
+      var menuStyle = {
+        borderRadius: '3px',
+        boxShadow: '0 2px 12px rgba(0, 0, 0, 0.1)',
+        background: 'rgba(255, 255, 255, 0.9)',
+        padding: '0',
+        fontSize: '90%',
+        position: 'fixed',
+        overflow: 'auto',
+        maxHeight: '50%'
+      };
+
+      return (
+        <div className="table-container-autocomplete">
+          <Autocomplete
+            shouldItemRender={matchItem}
+            initialValue={this.props.selectedField}
+            items={this.props.notSelectedFields}
+            menuStyle={menuStyle}
+            onSelect={function (item) {
+              Actions.changeField({
+                newSelectedRow: item,
+                index: this.props.index
+              });
+
+              this.showFilters(false);
+            }.bind(this)}
+            onChange={function (e, text) {
+              if (!text) {
+                this.showFilters(true);
+                return;
+              }
+              this.showFilters(false);
+            }.bind(this)}
+            getItemValue={function (item) { return item; }}
+            renderItem={function (item, isHighlighted) {
+              var highlight = isHighlighted ? 'table-dropdown-item-highlight ' : '';
+              return (
+                <div
+                  className={highlight + 'table-dropdown-item'}
+                  key={item}>
+                  {item}
+                </div>
+              );
+            }} />
+            {this.state.showFilters ? <i className="icon icon-filter"></i> : null}
+        </div>
+      );
+    }
+  });
+
+
   var TableView = React.createClass({
+
     getContentRows: function () {
       var data = this.props.data.results;
-      var schema = this.props.data.schema;
 
-      var res = data.map(function (el, i) {
+      return data.map(function (el, i) {
 
         return (
           <TableRow
             key={"tableview-row-component-" + i}
-            isListDeletable={this.props.isListDeletable}
             index={i}
-            data={el}
-            docId={el.id}
+            el={el}
             docIdentifier={el.id || "tableview-row-component-" + i}
             docChecked={this.props.docChecked}
             isSelected={this.props.isSelected(el.id)}
-            schema={schema} />
+            data={this.props.data} />
         );
       }.bind(this));
+    },
+
+    getOptionFieldRows: function (filtered) {
+      var notSelectedFields = this.props.data.notSelectedFields;
 
-      return res;
+      if (!notSelectedFields) {
+        return filtered.map(function (el, i) {
+          return <th key={'header-el-' + i}>{el}</th>;
+        });
+      }
+
+      return filtered.map(function (el, i) {
+        return (
+          <th key={'header-el-' + i}>
+            {this.getDropdown(el, this.props.data.schema, i)}
+          </th>
+        );
+      }.bind(this));
     },
 
-    getHeader: function () {
-      var row = this.props.data.schema.map(function (el, i) {
-        return <th key={"header-el-" + i} title={el}>{el}</th>;
-      });
+    getDropdown: function (selectedField, notSelectedFields, i) {
 
-      var box = null;
+      return (
+        <WrappedAutocomplete
+          selectedField={selectedField}
+          notSelectedFields={notSelectedFields}
+          index={i} />
+      );
+    },
 
-      if (this.props.isListDeletable) {
-        box = (<th className="tableview-header-el-checkbox" key="tableview-header-el-checkbox"></th>);
+    getHeader: function () {
+      var selectedFields = this.props.data.selectedFields;
+
+      var specialField = null;
+      if (this.props.data.hasMetadata) {
+        specialField = (<th key="header-el-metadata" title="Metadata">Metadata</th>);
       }
 
+      var row = this.getOptionFieldRows(selectedFields);
+
+      var box = (
+        <th className="tableview-header-el-checkbox" key="tableview-header-el-checkbox">
+          {this.props.isListDeletable ? <BulkActionComponent
+            disabled={this.props.isLoading}
+            removeItem={this.props.removeItem}
+            isChecked={this.props.isChecked}
+            hasSelectedItem={this.props.hasSelectedItem}
+            toggleSelect={this.props.toggleSelect}
+            title="Select all docs that can be..." /> : null}
+        </th>
+      );
+
+
       return (
         <tr key="tableview-content-row-header">
           {box}
+          <th className="tableview-el-copy"></th>
+          {specialField}
           {row}
+          <th className="tableview-el-last"></th>
         </tr>
       );
     },
@@ -161,14 +342,16 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, Documents) {
       var contentRows = this.getContentRows();
 
       return (
-        <table className="table table-striped table-view-docs">
-          <thead>
-            {header}
-          </thead>
-          <tbody>
-            {contentRows}
-          </tbody>
-        </table>
+        <div className="table-view-docs">
+          <table className="table table-striped">
+            <thead>
+              {header}
+            </thead>
+            <tbody>
+              {contentRows}
+            </tbody>
+          </table>
+        </div>
       );
     }
   });
@@ -216,6 +399,7 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, Documents) {
 
     getDocumentStyleView: function (loadLines) {
       var classNames = 'view';
+      var isDeletable = this.props.isListDeletable;
 
       if (this.props.isListDeletable) {
         classNames += ' show-select';
@@ -223,10 +407,19 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, Documents) {
 
       return (
         <div className={classNames}>
-          {loadLines}
-
+          <div className="loading-lines-wrapper">
+            {loadLines}
+          </div>
 
           <div id="doc-list">
+            {isDeletable ? <BulkActionComponent
+              removeItem={this.props.removeItem}
+              isChecked={this.props.allDocumentsSelected}
+              hasSelectedItem={this.props.hasSelectedItem}
+              toggleSelect={this.toggleSelectAll}
+              disabled={this.props.isLoading}
+              title="Select all docs that can be..." /> : null}
+
             <ReactCSSTransitionGroup transitionName="slow-fade">
               {this.getDocumentList()}
             </ReactCSSTransitionGroup>
@@ -238,11 +431,22 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, Documents) {
     getTableStyleView: function (loadLines) {
       return (
         <div>
+          <div className="loading-lines-wrapper">
+            {loadLines}
+          </div>
+
           <TableView
             docChecked={this.props.docChecked}
             isSelected={this.props.isSelected}
             isListDeletable={this.props.isListDeletable}
-            data={this.props.results} />
+            data={this.props.results}
+            isLoading={this.props.isLoading}
+
+            removeItem={this.props.removeItem}
+            isChecked={this.props.allDocumentsSelected}
+            hasSelectedItem={this.props.hasSelectedItem}
+            toggleSelect={this.toggleSelectAll}
+            title="Select all docs that can be..." />
         </div>
       );
     },
@@ -259,22 +463,11 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, Documents) {
       var mainView = isTableView ? this.getTableStyleView(loadLines) : this.getDocumentStyleView(loadLines);
       return (
         <div className="document-result-screen">
-          {this.props.isListDeletable ? <BulkActionComponent
-            removeItem={this.props.removeItem}
-            isChecked={this.props.allDocumentsSelected}
-            hasSelectedItem={this.props.hasSelectedItem}
-            selectAll={this.selectAllDocs}
-            toggleSelect={this.toggleSelectAll}
-            title="Select all docs that can be..." /> : null}
           {mainView}
         </div>
       );
     },
 
-    selectAllDocs: function () {
-      Actions.selectAllDocuments();
-    },
-
     toggleSelectAll: function () {
       Actions.toggleAllDocuments();
     },
@@ -293,28 +486,27 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, Documents) {
 
   var ViewResultListController = React.createClass({
     getStoreState: function () {
+      var selectedItemsLength = store.getSelectedItemsLength();
       return {
         hasResults: store.hasResults(),
         results: store.getResults(),
-        selectedItems: store.getSelectedItems(),
         isLoading: store.isLoading(),
         isEditable: store.isEditable(),
         textEmptyIndex: store.getTextEmptyIndex(),
         isTableView: store.getIsTableView(),
-
-        canDeselectAll: store.canDeselectAll(),
-        canSelectAll: store.canSelectAll(),
         allDocumentsSelected: store.areAllDocumentsSelected(),
-        hasSelectedItem: !!store.getSelectedItemsLength()
+        hasSelectedItem: !!selectedItemsLength,
+        selectedItemsLength: selectedItemsLength,
+        bulkDeleteCollection: store.getBulkDocCollection()
       };
     },
 
     isSelected: function (id) {
-      return !!this.state.selectedItems[id];
+      return !!this.state.bulkDeleteCollection.get(id);
     },
 
     removeItem: function () {
-      Actions.deleteSelected();
+      Actions.deleteSelected(this.state.bulkDeleteCollection, this.state.selectedItemsLength);
     },
 
     getInitialState: function () {
@@ -333,8 +525,11 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, Documents) {
       this.setState(this.getStoreState());
     },
 
-    docChecked: function (id) {
-      Actions.selectDoc(id);
+    docChecked: function (_id, _rev) {
+      Actions.selectDoc({
+        _id: _id,
+        _rev: _rev
+      });
     },
 
     render: function () {
@@ -345,10 +540,9 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, Documents) {
           removeItem={this.removeItem}
           hasSelectedItem={this.state.hasSelectedItem}
           allDocumentsSelected={this.state.allDocumentsSelected}
-          canSelectAll={this.state.canSelectAll}
           isSelected={this.isSelected}
           isEditable={this.state.isEditable}
-          isListDeletable={this.state.results.hasDeletableDoc}
+          isListDeletable={this.state.results.hasBulkDeletableDoc}
           docChecked={this.docChecked}
           isLoading={this.state.isLoading}
           results={this.state.results}
@@ -363,7 +557,8 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, Documents) {
 
   var Views = {
     List: ViewResultListController,
-    ResultsScreen: ResultsScreen
+    ResultsScreen: ResultsScreen,
+    WrappedAutocomplete: WrappedAutocomplete
   };
 
   return Views;

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/documents/index-results/stores.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/index-results/stores.js b/app/addons/documents/index-results/stores.js
index 5a4766e..384f457 100644
--- a/app/addons/documents/index-results/stores.js
+++ b/app/addons/documents/index-results/stores.js
@@ -15,16 +15,19 @@ define([
   'api',
   'addons/documents/index-results/actiontypes',
   'addons/documents/header/header.actiontypes',
+  'addons/documents/pagination/actiontypes',
+
+  'addons/documents/resources',
+  'addons/documents/mango/mango.helper',
   'addons/documents/resources',
-  'addons/documents/mango/mango.helper'
 ],
 
-function (app, FauxtonAPI, ActionTypes, HeaderActionTypes, Documents, MangoHelper) {
+function (app, FauxtonAPI, ActionTypes, HeaderActionTypes, PaginationActionTypes,
+  Documents, MangoHelper, Resources) {
+
   var Stores = {};
 
-  /*TODO:
-    remove header code, add delete, clean up pagination tests
-    */
+  var maxDocLimit = 10000;
 
   Stores.IndexResultsStore = FauxtonAPI.Store.extend({
 
@@ -34,21 +37,159 @@ function (app, FauxtonAPI, ActionTypes, HeaderActionTypes, Documents, MangoHelpe
 
     reset: function () {
       this._collection = [];
+      this._filteredCollection = [];
+      this._bulkDeleteDocCollection = new Resources.BulkDeleteDocCollection([], {}),
+
       this.clearSelectedItems();
       this._isLoading = false;
       this._textEmptyIndex = 'No Index Created Yet!';
       this._typeOfIndex = 'view';
-      this._lastQuery = null;
-      this._bulkDeleteDocCollection = null;
+
+      this._tableViewSelectedFields = [];
+      this._isPrioritizedEnabled = false;
+
+      this._tableSchema = [];
+      this._tableView = false;
+
+      this.resetPagination();
+    },
+
+    resetPagination: function () {
+      this._pageStart = 1;
+      this._currentPage = 1;
+      this._enabled = true;
+      this._newView = false;
+      this._docLimit = _.isUndefined(this._docLimit) ? maxDocLimit : this._docLimit;
+
+      this.initPerPage();
+    },
+
+    setDocumentLimit: function (docLimit) {
+      if (docLimit) {
+        this._docLimit = docLimit;
+      } else {
+        this._docLimit = maxDocLimit;
+      }
+
+      this.initPerPage();
+    },
+
+    getCollection: function () {
+      return this._collection;
+    },
+
+    canShowPrevious: function () {
+      if (!this._enabled) { return false; }
+      if (!this._collection || !this._collection.hasPrevious) { return false; }
+
+      return this._collection.hasPrevious();
+    },
+
+    canShowNext: function () {
+      if (!this._enabled) { return this._enabled; }
+
+      if ((this._pageStart + this._perPage) >= this._docLimit) {
+        return false;
+      }
+
+      if (!this._collection || !this._collection.hasNext) { return false; }
+
+      return this._collection.hasNext();
+    },
+
+    paginateNext: function () {
+      this._currentPage += 1;
+      this._pageStart += this.getPerPage();
+      this._collection.paging.pageSize = this.documentsLeftToFetch();
+    },
+
+    paginatePrevious: function () {
+      this._currentPage -= 1;
+
+      this._pageStart = this._pageStart - this.getPerPage();
+      if (this._pageStart < 1) {
+        this._pageStart = 1;
+      }
+
+      this._collection.paging.pageSize = this.getPerPage();
+    },
+
+    getCurrentPage: function () {
+      return this._currentPage;
+    },
+
+    totalDocsViewed: function () {
+      return this._perPage * this._currentPage;
+    },
+
+    documentsLeftToFetch: function () {
+      var documentsLeftToFetch = this._docLimit - this.totalDocsViewed();
+
+      if (documentsLeftToFetch < this.getPerPage() ) {
+        return documentsLeftToFetch;
+      }
+
+      return this._perPage;
+    },
+
+    getPerPage: function () {
+      return this._perPage;
+    },
+
+    initPerPage: function () {
+      var perPage = FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE;
+
+      if (window.localStorage) {
+        var storedPerPage = app.utils.localStorageGet('fauxton:perpage');
+
+        if (storedPerPage) {
+          perPage = parseInt(storedPerPage, 10);
+        }
+      }
+
+      if (this._docLimit < perPage) {
+        perPage = this._docLimit;
+      }
+
+      this.setPerPage(perPage);
+    },
+
+    setPerPage: function (perPage) {
+      this._perPage = perPage;
+      app.utils.localStorageSet('fauxton:perpage', perPage);
+
+      if (this._collection && this._collection.pageSizeReset) {
+        this._collection.pageSizeReset(perPage, {fetch: false});
+      }
+    },
+
+    getTotalRows: function () {
+      if (!this._collection) { return false; }
+
+      return this._collection.length;
+    },
+
+    getPageStart: function () {
+      return this._pageStart;
+    },
+
+    getPageEnd: function () {
+      if (!this._collection) { return false; }
+      return this._pageStart + this._collection.length - 1;
+    },
+
+    getUpdateSeq: function () {
+      if (!this._collection) { return false; }
+      if (!this._collection.updateSeq) { return false; }
+      return this._collection.updateSeq();
     },
 
     clearSelectedItems: function () {
-      this._selectedItems = {};
+      this._bulkDeleteDocCollection.reset([]);
     },
 
     newResults: function (options) {
       this._collection = options.collection;
-      this.clearSelectedItems();
 
       this._bulkDeleteDocCollection = options.bulkCollection;
 
@@ -60,8 +201,16 @@ function (app, FauxtonAPI, ActionTypes, HeaderActionTypes, Documents, MangoHelpe
         this._typeOfIndex = options.typeOfIndex;
       }
 
-      if (options.query) {
-        this._lastQuery = options.query;
+      this._cachedSelected = [];
+
+      this._filteredCollection = this._collection.filter(filterOutGeneratedMangoDocs);
+
+      function filterOutGeneratedMangoDocs (doc) {
+        if (doc.get && typeof doc.get === 'function') {
+          return doc.get('language') !== 'query';
+        }
+
+        return doc.language !== 'query';
       }
     },
 
@@ -69,10 +218,6 @@ function (app, FauxtonAPI, ActionTypes, HeaderActionTypes, Documents, MangoHelpe
       return this._typeOfIndex;
     },
 
-    getLastQuery: function () {
-      return this._lastQuery;
-    },
-
     isEditable: function (doc) {
       if (!this._collection) {
         return false;
@@ -104,20 +249,20 @@ function (app, FauxtonAPI, ActionTypes, HeaderActionTypes, Documents, MangoHelpe
         return false;
       }
 
-      return doc.isBulkDeletable();
+      return doc.isDeletable();
     },
 
     getCollection: function () {
       return this._collection;
     },
 
+    getBulkDocCollection: function () {
+      return this._bulkDeleteDocCollection;
+    },
+
     getDocContent: function (originalDoc) {
       var doc = originalDoc.toJSON();
 
-      if (this._allCollapsed) {
-        return JSON.stringify({id: doc.id, rev: doc._rev}, null, ' ');
-      }
-
       return JSON.stringify(doc, null, ' ');
     },
 
@@ -140,10 +285,6 @@ function (app, FauxtonAPI, ActionTypes, HeaderActionTypes, Documents, MangoHelpe
       delete doc.ddoc;
       delete doc.name;
 
-      if (this._allCollapsed) {
-        return '';
-      }
-
       return JSON.stringify(doc, null, ' ');
     },
 
@@ -176,33 +317,19 @@ function (app, FauxtonAPI, ActionTypes, HeaderActionTypes, Documents, MangoHelpe
         isDeletable: this.isDeletable(doc),
         isEditable: this.isEditable(doc)
       };
-
-    },
-
-    filterOutGeneratedMangoDocs: function (doc) {
-      if (doc.get && typeof doc.get === 'function') {
-        return doc.get('language') !== 'query';
-      }
-
-      return doc.language !== 'query';
     },
 
     getResults: function () {
-      var hasDeletableDoc;
+      var hasBulkDeletableDoc;
       var res;
-      var collection;
-
-      var filteredCollection = this._collection.filter(this.filterOutGeneratedMangoDocs);
 
       // Table sytle view
       if (this.getIsTableView()) {
-        collection = this._collection.toJSON().filter(this.filterOutGeneratedMangoDocs);
-        return this.getTableViewData(collection);
+        return this.getTableViewData();
       }
 
       // JSON style views
-      res = this._collection
-        .filter(this.filterOutGeneratedMangoDocs)
+      res = this._filteredCollection
         .map(function (doc, i) {
           if (doc.get('def') || this.isGhostDoc(doc)) {
             return this.getMangoDoc(doc, i);
@@ -210,6 +337,7 @@ function (app, FauxtonAPI, ActionTypes, HeaderActionTypes, Documents, MangoHelpe
           return {
             content: this.getDocContent(doc),
             id: this.getDocId(doc),
+            _rev: doc.get('_rev'),
             header: this.getDocId(doc),
             keylabel: doc.isFromView() ? 'key' : 'id',
             url: this.getDocId(doc) ? doc.url('app') : null,
@@ -218,10 +346,11 @@ function (app, FauxtonAPI, ActionTypes, HeaderActionTypes, Documents, MangoHelpe
           };
         }, this);
 
-      hasDeletableDoc = this.getHasDeletableDoc(res);
+      hasBulkDeletableDoc = this.hasBulkDeletableDoc(this._filteredCollection);
 
       return {
-        hasDeletableDoc: hasDeletableDoc,
+        displayedFields: this.getDisplayCountForTableView(),
+        hasBulkDeletableDoc: hasBulkDeletableDoc,
         results: res
       };
     },
@@ -247,58 +376,262 @@ function (app, FauxtonAPI, ActionTypes, HeaderActionTypes, Documents, MangoHelpe
       return cache;
     },
 
-    // filter out cruft and JSONify strings
-    normalizeTableData: function (data) {
-      // include_docs enabled
-      if (data[0] && data[0].doc && data[0].doc._rev) {
-        return data.map(function (el) {
-          el = el.doc;
-          return el;
-        });
+    normalizeTableData: function (data, isView) {
+      // filter out cruft
+      if (isView) {
+        return data;
       }
 
-      return data;
+      return data.map(function (el) {
+        return el.doc || el;
+      });
+    },
+
+    isIncludeDocsEnabled: function () {
+      var params = app.getParams();
+
+      return !!params.include_docs;
     },
 
-    getTableViewData: function (data) {
+    getPrioritizedFields: function (data, max) {
+      var res = data.reduce(function (acc, el) {
+        acc = acc.concat(Object.keys(el));
+        return acc;
+      }, []);
+
+      res = _.countBy(res, function (el) {
+        return el;
+      });
+
+      delete res._id;
+      delete res.id;
+      delete res._rev;
+
+      res = Object.keys(res).reduce(function (acc, el) {
+        acc.push([res[el], el]);
+        return acc;
+      }, []);
+
+      res = this.sortByTwoFields(res);
+      res = res.slice(0, max);
+
+      return res.reduce(function (acc, el) {
+        acc.push(el[1]);
+        return acc;
+      }, []);
+    },
+
+     sortByTwoFields: function (elements) {
+      // given:
+      // var a = [[2, "b"], [3, "z"], [1, "a"], [3, "a"]]
+      // it sorts to:
+      // [[3, "a"], [3, "z"], [2, "b"], [1, "a"]]
+      // note that the arrays with 3 got the first two arrays
+      // _and_ that the second values in the array with 3 are also sorted
+
+      function _recursiveSort (a, b, index) {
+        if (a[index] === b[index]) {
+          return index < 2 ? _recursiveSort(a, b, index + 1) : 0;
+        }
+
+        // second elements asc
+        if (index === 1) {
+          return (a[index] < b[index]) ? -1 : 1;
+        }
+
+        // first elements desc
+        return (a[index] < b[index]) ? 1 : -1;
+      }
+
+      return elements.sort(function (a, b) {
+        return _recursiveSort(a, b, 0);
+      });
+    },
+
+    hasIdOrRev: function (schema) {
+
+      return schema.indexOf('_id') !== -1 ||
+        schema.indexOf('id') !== -1 ||
+        schema.indexOf('_rev') !== -1;
+    },
+
+    getNotSelectedFields: function (selectedFields, allFields) {
+      var without = _.without.bind(this, allFields);
+      return without.apply(this, selectedFields);
+    },
+
+    getDisplayCountForTableView: function () {
+      var allFieldCount;
+      var shownCount;
+
+      if (!this.getIsTableView()) {
+        return null;
+      }
+
+      if (!this.isIncludeDocsEnabled()) {
+        return null;
+      }
+
+      shownCount = _.uniq(this._tableViewSelectedFields).length;
+
+      allFieldCount = this._tableSchema.length;
+      if (_.contains(this._tableSchema, '_id', '_rev')) {
+        allFieldCount = allFieldCount - 1;
+      }
+
+      if (_.contains(this._tableSchema, '_id', '_rev')) {
+        shownCount = shownCount + 1;
+      }
+
+      return {shown: shownCount, allFieldCount: allFieldCount};
+    },
+
+    getTableViewData: function () {
       var res;
       var schema;
       var database;
+      var hasIdOrRev;
+      var hasIdOrRev;
+      var prioritizedFields;
+      var hasBulkDeletableDoc;
+      var isView = !!this._collection.view;
+
+      // softmigration remove backbone
+      var data;
+      var collectionType = this._collection.collectionType;
+      data = this._filteredCollection.map(function (el) {
+        return fixDocIdForMango(el.toJSON(), collectionType);
+      });
+
+      function fixDocIdForMango (doc, docType) {
+        if (docType !== 'MangoIndex') {
+          return doc;
+        }
+
+        doc.id = doc.ddoc;
+        return doc;
+      }
+
+      function isJSONDocEditable (doc, docType) {
+
+        if (!doc) {
+          return;
+        }
+
+        if (docType === 'MangoIndex') {
+          return false;
+        }
+
+        if (!Object.keys(doc).length) {
+          return false;
+        }
+
+        if (!doc._id) {
+          return false;
+        }
+
+        return true;
+      }
+
+      function isJSONDocBulkDeletable (doc, docType) {
+        if (docType === 'MangoIndex') {
+          return doc.type !== 'special';
+        }
+
+        return !!doc._id && !!doc._rev;
+      }
+
+      // softmigration end
+
+      var isIncludeDocsEnabled = this.isIncludeDocsEnabled();
+      var notSelectedFields = null;
+      if (isIncludeDocsEnabled) {
+
+        data = this.normalizeTableData(data, isView);
+        schema = this.getPseudoSchema(data);
+        hasIdOrRev = this.hasIdOrRev(schema);
+
+        if (!this._isPrioritizedEnabled) {
+          this._tableViewSelectedFields = this._cachedSelected || [];
+        }
+
+        if (this._tableViewSelectedFields.length === 0) {
+          prioritizedFields = this.getPrioritizedFields(data, hasIdOrRev ? 4 : 5);
+          this._tableViewSelectedFields = prioritizedFields;
+          this._cachedSelected = this._tableViewSelectedFields;
+        }
+
+        var schemaWithoutMetaDataFields = _.without(schema, '_id', '_rev', '_attachment');
+        notSelectedFields = this.getNotSelectedFields(this._tableViewSelectedFields, schemaWithoutMetaDataFields);
+
+        if (this._isPrioritizedEnabled) {
+          notSelectedFields = null;
+          this._tableViewSelectedFields = schemaWithoutMetaDataFields;
+        }
+
+
+      } else {
+        schema = this.getPseudoSchema(data);
+        this._tableViewSelectedFields = _.without(schema, '_id', '_rev', '_attachment');
+      }
+
+      this._notSelectedFields = notSelectedFields;
+      this._tableSchema = schema;
 
-      data = this.normalizeTableData(data);
-      schema = this.getPseudoSchema(data);
       database = this.getDatabase().safeID();
 
-      res = this._collection
-        .filter(this.filterOutGeneratedMangoDocs)
-        .map(function (doc) {
+      res = data.map(function (doc) {
+        var safeId = app.utils.getSafeIdForDoc(doc._id || doc.id); // inconsistent apis for GET between mango and views
+        var url;
 
-          return {
-            content: doc.toJSON(),
-            id: this.getDocId(doc),
-            header: '',
-            keylabel: '',
-            url: this.getDocId(doc) ? doc.url('app') : null,
-            isDeletable: this.isDeletable(doc),
-            isEditable: this.isEditable(doc)
-          };
-        }, this);
+        if (safeId) {
+          url = FauxtonAPI.urls('document', 'app', database, safeId);
+        }
+
+        return {
+          content: doc,
+          id: doc._id || doc.id, // inconsistent apis for GET between mango and views
+          _rev: doc._rev,
+          header: '',
+          keylabel: '',
+          url: url,
+          isDeletable: isJSONDocBulkDeletable(doc, collectionType),
+          isEditable: isJSONDocEditable(doc, collectionType)
+        };
+      }.bind(this));
+
+      hasBulkDeletableDoc = this.hasBulkDeletableDoc(this._filteredCollection);
 
       return {
-        hasDeletableDoc: this.getHasDeletableDoc(res),
+        notSelectedFields: notSelectedFields,
+        hasMetadata: this.getHasMetadata(schema),
+        selectedFields: this._tableViewSelectedFields,
+        hasBulkDeletableDoc: hasBulkDeletableDoc,
         schema: schema,
-        results: res
+        results: res,
+        displayedFields: this.getDisplayCountForTableView(),
       };
     },
 
-    getHasDeletableDoc: function (data) {
+    changeTableViewFields: function (options) {
+      var newSelectedRow = options.newSelectedRow;
+      var i = options.index;
+
+      this._tableViewSelectedFields[i] = newSelectedRow;
+    },
+
+    getHasMetadata: function (schema) {
+      return _.contains(schema, '_id', '_rev');
+    },
+
+    hasBulkDeletableDoc: function (docs) {
       var found = false;
-      var length = data.length;
+      var length = docs.length;
       var i;
+
       // use a for loop here as we can end it once we found the first id
       for (i = 0; i < length; i++) {
-
-        if (data[i].isDeletable) {
+        if (docs[i].isBulkDeletable()) {
           found = true;
           break;
         }
@@ -316,59 +649,85 @@ function (app, FauxtonAPI, ActionTypes, HeaderActionTypes, Documents, MangoHelpe
       return this._isLoading;
     },
 
-    selectDoc: function (id) {
-      if (!id || id === '_all_docs') {
+    selectDoc: function (doc, noReset) {
+
+      if (!doc._id || doc._id === '_all_docs') {
         return;
       }
 
-      if (!this._selectedItems[id]) {
-        this._selectedItems[id] = true;
-      } else {
-        delete this._selectedItems[id];
+      if (!this._bulkDeleteDocCollection.get(doc._id)) {
+        this._bulkDeleteDocCollection.add(doc);
+        return;
       }
+
+      this._bulkDeleteDocCollection.remove(doc._id);
     },
 
-    selectListOfDocs: function (ids) {
-      this.clearSelectedItems();
-      _.each(ids, function (id) {
-        this.selectDoc(id);
+    selectAllDocuments: function () {
+      this.deSelectCurrentCollection();
+
+      this._collection.each(function (doc) {
+
+        if (!doc.isBulkDeletable()) {
+          return;
+        }
+
+        this.selectDoc({
+          _id: doc.id,
+          _rev: doc.get('_rev'),
+          _deleted: true
+        });
       }, this);
+
     },
 
-    selectAllDocuments: function () {
-      this.clearSelectedItems();
+    deSelectCurrentCollection: function () {
       this._collection.each(function (doc) {
+
         if (!doc.isBulkDeletable()) {
           return;
         }
-        this.selectDoc(doc.id);
+
+        this._bulkDeleteDocCollection.remove(doc.id);
       }, this);
     },
 
     toggleSelectAllDocuments: function () {
       if (this.areAllDocumentsSelected()) {
-        return this.clearSelectedItems();
+        return this.deSelectCurrentCollection();
       }
 
       return this.selectAllDocuments();
     },
 
-    areAllDocumentsSelected: function () {
-      var filtered;
+    togglePrioritizedTableView: function () {
+      this._isPrioritizedEnabled = !this._isPrioritizedEnabled;
+    },
 
+    areAllDocumentsSelected: function () {
       if (this._collection.length === 0) {
         return false;
       }
 
-      filtered = this._collection.filter(function (doc) {
-        return doc.isBulkDeletable();
-      });
+      var foundAllOnThisPage = true;
 
-      return Object.keys(this._selectedItems).length === filtered.length;
+      var selected = this._bulkDeleteDocCollection.pluck('_id');
+
+      this._collection.forEach(function (doc) {
+        if (!doc.isBulkDeletable()) {
+          return;
+        }
+
+        if (!_.contains(selected, doc.id)) {
+          foundAllOnThisPage = false;
+        }
+      }.bind(this));
+
+      return foundAllOnThisPage;
     },
 
     getSelectedItemsLength: function () {
-      return Object.keys(this._selectedItems).length;
+      return this._bulkDeleteDocCollection.length;
     },
 
     getDatabase: function () {
@@ -379,69 +738,18 @@ function (app, FauxtonAPI, ActionTypes, HeaderActionTypes, Documents, MangoHelpe
       return this._textEmptyIndex;
     },
 
-    setbulkDeleteDocCollection: function (bulkDeleteDocCollection) {
-      this._bulkDeleteDocCollection = bulkDeleteDocCollection;
-    },
-
-    createBulkDeleteFromSelected: function () {
-      var items = _.map(_.keys(this._selectedItems), function (id) {
-        var doc = this._collection.get(id);
-
-        return {
-          _id: doc.id,
-          _rev: doc.get('_rev'),
-          _deleted: true
-        };
-      }, this);
-
-      var bulkDelete = new this._bulkDeleteDocCollection(items, {
-        databaseId: this.getDatabase().safeID()
-      });
-
-      return bulkDelete;
-    },
-
-    canSelectAll: function () {
-      var length = this._collection.length;
-
-      if (this._collection.get && this._collection.get('_all_docs')) {
-        length = length - 1;
-      }
-
-      return length > this.getSelectedItemsLength();
-    },
-
-    canDeselectAll: function () {
-      return this.getSelectedItemsLength() > 0;
-    },
-
-    getSelectedItems: function () {
-      return this._selectedItems;
-    },
-
     hasSelectedItem: function () {
       return this.getSelectedItemsLength() > 0;
     },
 
-    collapseAllDocs: function () {
-      this.disableTableView();
-
-      this._allCollapsed = true;
-    },
-
-    unCollapseAllDocs: function () {
-      this.disableTableView();
+    toggleTableView: function (options) {
+      var enableTableView = options.enable;
 
-      this._allCollapsed = false;
-    },
-
-    enableTableView: function () {
-      this._allCollapsed = false;
-      this._tableView = true;
-    },
+      if (enableTableView) {
+        this._tableView = true;
+        return;
+      }
 
-    disableTableView: function () {
-      this._allCollapsed = false;
       this._tableView = false;
     },
 
@@ -449,19 +757,23 @@ function (app, FauxtonAPI, ActionTypes, HeaderActionTypes, Documents, MangoHelpe
       return this._tableView;
     },
 
+    getIsPrioritizedEnabled: function () {
+      return this._isPrioritizedEnabled;
+    },
+
     getCurrentViewType: function () {
 
       if (this._tableView) {
         return 'table';
       }
 
-      if (this._allCollapsed) {
-        return 'collapsed';
-      }
-
       return 'expanded';
     },
 
+    getShowPrioritizedFieldToggler: function () {
+      return this.isIncludeDocsEnabled() && this.getIsTableView();
+    },
+
     clearResultsBeforeFetch: function () {
       if (this._collection && this._collection.reset) {
         this._collection.reset();
@@ -482,37 +794,37 @@ function (app, FauxtonAPI, ActionTypes, HeaderActionTypes, Documents, MangoHelpe
           this.resultsResetFromFetch();
         break;
         case ActionTypes.INDEX_RESULTS_SELECT_DOC:
-          this.selectDoc(action.id);
-        break;
-        case ActionTypes.INDEX_RESULTS_SELECT_LIST_OF_DOCS:
-          this.selectListOfDocs(action.ids);
+          this.selectDoc(action.options);
         break;
         case ActionTypes.INDEX_RESULTS_CLEAR_RESULTS:
           this.clearResultsBeforeFetch();
         break;
-        case ActionTypes.INDEX_RESULTS_SELECT_ALL_DOCUMENTS:
-          this.selectAllDocuments();
-        break;
         case ActionTypes.INDEX_RESULTS_TOOGLE_SELECT_ALL_DOCUMENTS:
           this.toggleSelectAllDocuments();
         break;
-        case HeaderActionTypes.COLLAPSE_DOCUMENTS:
-          this.collapseSelectedDocs();
+        case ActionTypes.INDEX_RESULTS_SELECT_NEW_FIELD_IN_TABLE:
+          this.changeTableViewFields(action.options);
+        break;
+        case ActionTypes.INDEX_RESULTS_TOGGLE_PRIORITIZED_TABLE_VIEW:
+          this.togglePrioritizedTableView();
         break;
-        case HeaderActionTypes.EXPAND_DOCUMENTS:
-          this.unCollapseSelectedDocs();
+
+        case HeaderActionTypes.TOGGLE_TABLEVIEW:
+          this.toggleTableView(action.options);
         break;
-        case HeaderActionTypes.COLLAPSE_ALL_DOCUMENTS:
-          this.collapseAllDocs();
+
+        case PaginationActionTypes.SET_PAGINATION_DOCUMENT_LIMIT:
+          this.setDocumentLimit(action.docLimit);
         break;
-        case HeaderActionTypes.EXPAND_ALL_DOCUMENTS:
-          this.unCollapseAllDocs();
+        case PaginationActionTypes.PAGINATE_NEXT:
+          this.paginateNext();
         break;
-        case HeaderActionTypes.DISABLE_TABLE_VIEW:
-          this.disableTableView();
+        case PaginationActionTypes.PAGINATE_PREVIOUS:
+          this.paginatePrevious();
         break;
-        case HeaderActionTypes.ENABLE_TABLE_VIEW:
-          this.enableTableView();
+        case PaginationActionTypes.PER_PAGE_CHANGE:
+          this.resetPagination();
+          this.setPerPage(action.perPage);
         break;
 
         default:

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/bfdbf112/app/addons/documents/index-results/tests/index-results.actionsSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/index-results/tests/index-results.actionsSpec.js b/app/addons/documents/index-results/tests/index-results.actionsSpec.js
index 719cfb9..b1135ca 100644
--- a/app/addons/documents/index-results/tests/index-results.actionsSpec.js
+++ b/app/addons/documents/index-results/tests/index-results.actionsSpec.js
@@ -16,49 +16,29 @@ define([
   'addons/documents/index-results/stores',
   'addons/documents/resources',
   'addons/documents/sidebar/actions',
-  'testUtils'
-], function (FauxtonAPI, Actions, Stores, Documents, SidebarActions, testUtils) {
+  'testUtils',
+  'addons/documents/tests/document-test-helper',
+
+], function (FauxtonAPI, Actions, Stores, Documents, SidebarActions, testUtils, documentTestHelper) {
   var assert = testUtils.assert;
   var restore = testUtils.restore;
-  var store = Stores.indexResultsStore;
-
-  FauxtonAPI.router = new FauxtonAPI.Router([]);
-
-  describe('Index Results Actions', function () {
-
-    describe('#newResultsList', function () {
-
-      it('sends results list reset', function () {
-        var collection = {
-          fetch: function () {
-            var promise = $.Deferred();
-            promise.resolve();
-            return promise;
-          }
-        };
-
-        var spy = sinon.spy(Actions, 'resultsListReset');
-
-        Actions.newResultsList({collection: collection});
-        assert.ok(spy.calledOnce);
-      });
-
-    });
-
-  });
+  var store;
 
+  var createDocColumn = documentTestHelper.createDocColumn;
 
   describe('#deleteSelected', function () {
     var confirmStub;
+    var bulkDeleteCollection;
 
     beforeEach(function () {
-      store._collection = new Documents.AllDocs([{_id: 'testId1'}, {_id: 'testId2'}], {
-        params: {},
-        database: {
-          safeID: function () { return '1';}
-        }
-      });
-      store._bulkDeleteDocCollection = Documents.BulkDeleteDocCollection;
+      Stores.indexResultsStore = new Stores.IndexResultsStore();
+      Stores.indexResultsStore.dispatchToken = FauxtonAPI.dispatcher.register(Stores.indexResultsStore.dispatch);
+      store = Stores.indexResultsStore;
+      store.reset();
+
+      bulkDeleteCollection = new Documents.BulkDeleteDocCollection([], {databaseId: '1'});
+      store._bulkDeleteDocCollection = bulkDeleteCollection;
+      store._collection = createDocColumn([{_id: 'testId1'}, {_id: 'testId2'}]);
 
       store._selectedItems = {
         'testId1': true,
@@ -72,11 +52,10 @@ define([
 
     afterEach(function () {
       restore(window.confirm);
-      restore(store.createBulkDeleteFromSelected);
       restore(FauxtonAPI.addNotification);
       restore(Actions.reloadResultsList);
-      restore(Actions.selectListOfDocs);
       restore(SidebarActions.refresh);
+      restore(Actions.newResultsList);
     });
 
     it('doesn\'t delete if user denies confirmation', function () {
@@ -85,121 +64,39 @@ define([
       var stub = sinon.stub(window, 'confirm');
       stub.returns(false);
 
-      var spy = sinon.spy(store, 'createBulkDeleteFromSelected');
+      var spy = sinon.spy(bulkDeleteCollection, 'bulkDelete');
 
-      Actions.deleteSelected();
+      Actions.deleteSelected(bulkDeleteCollection, 1);
 
       assert.notOk(spy.calledOnce);
     });
 
-    it('creates bulk delete', function () {
-      var spy = sinon.spy(store, 'createBulkDeleteFromSelected');
-
-      Actions.deleteSelected();
-
-      assert.ok(spy.calledOnce);
-    });
-
-    it('on success notifies all deleted', function () {
+    it('on success notifies all deleted', function (done) {
       var spy = sinon.spy(FauxtonAPI, 'addNotification');
       var sidebarSpy = sinon.spy(SidebarActions, 'refresh');
       var promise = FauxtonAPI.Deferred();
       var ids = {
-          errorIds: []
+        errorIds: []
       };
       var bulkDelete = {
         bulkDelete: function () {
           promise.resolve(ids);
           return promise;
+        },
+        reset: function () {
+          done();
         }
       };
-      var stub = sinon.stub(store, 'createBulkDeleteFromSelected');
-      stub.returns(bulkDelete);
-      var reloadResultsListStub = sinon.stub(Actions, 'reloadResultsList');
-      var stubPromise = FauxtonAPI.Deferred();
-      stubPromise.resolve();
-      reloadResultsListStub.returns(stubPromise);
-
-      Actions.deleteSelected();
-
-      assert.ok(spy.calledOnce);
-      assert.ok(sidebarSpy.calledOnce);
-    });
-
-    it('on success with some failed ids, re-selects failed', function () {
-      var spy = sinon.spy(Actions, 'selectListOfDocs');
-      var sidebarSpy = sinon.spy(SidebarActions, 'refresh');
 
       var reloadResultsListStub = sinon.stub(Actions, 'reloadResultsList');
       var stubPromise = FauxtonAPI.Deferred();
       stubPromise.resolve();
       reloadResultsListStub.returns(stubPromise);
 
-      var promise = FauxtonAPI.Deferred();
-      var ids = {
-          errorIds: ['1']
-      };
-      var bulkDelete = {
-        bulkDelete: function () {
-          promise.resolve(ids);
-          return promise;
-        }
-      };
-
-      var stub = sinon.stub(store, 'createBulkDeleteFromSelected');
-      stub.returns(bulkDelete);
-
-      Actions.deleteSelected();
-      assert.ok(spy.calledWith(ids.errorIds));
-      assert.ok(sidebarSpy.calledOnce);
-    });
-
-    it('on failure notifies failed', function () {
-      var spy = sinon.spy(FauxtonAPI, 'addNotification');
-      var promise = FauxtonAPI.Deferred();
-      var bulkDelete = {
-        bulkDelete: function () {
-          promise.reject();
-          return promise;
-        }
-      };
-      var stub = sinon.stub(store, 'createBulkDeleteFromSelected');
-      stub.returns(bulkDelete);
-      var reloadResultsListStub = sinon.stub(Actions, 'reloadResultsList');
-      var stubPromise = FauxtonAPI.Deferred();
-      stubPromise.resolve();
-      reloadResultsListStub.returns(stubPromise);
-
-      Actions.deleteSelected();
+      Actions.deleteSelected(bulkDelete, 1);
 
       assert.ok(spy.calledOnce);
+      assert.ok(sidebarSpy.calledOnce);
     });
-
-    it('on failure re-selects docs', function () {
-      var spy = sinon.spy(Actions, 'selectListOfDocs');
-
-      var reloadResultsListStub = sinon.stub(Actions, 'reloadResultsList');
-      var stubPromise = FauxtonAPI.Deferred();
-      stubPromise.resolve();
-      reloadResultsListStub.returns(stubPromise);
-
-      var promise = FauxtonAPI.Deferred();
-      var errorIds = ['1'];
-
-      var bulkDelete = {
-        bulkDelete: function () {
-          promise.reject(errorIds);
-          return promise;
-        }
-      };
-
-      var stub = sinon.stub(store, 'createBulkDeleteFromSelected');
-      stub.returns(bulkDelete);
-
-      Actions.deleteSelected();
-      assert.ok(spy.calledWith(errorIds));
-    });
-
   });
-
 });


Mime
View raw message