You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2013/10/16 10:25:13 UTC

[1/3] git commit: updated refs/heads/master to 9710834

Updated Branches:
  refs/heads/master 1cf46213e -> 971083419


Fauxton: Add Verify Install module
Resolves #COUCHDB-1813


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

Branch: refs/heads/master
Commit: 9710834196c59f02ee5fb4df27df4a587cf6c1f1
Parents: bcb4fba
Author: Garren Smith <ga...@gmail.com>
Authored: Tue Oct 15 12:23:00 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Wed Oct 16 10:24:52 2013 +0200

----------------------------------------------------------------------
 .gitignore                                      |   1 +
 .../assets/less/verifyinstall.less              |   4 +
 src/fauxton/app/addons/verifyinstall/base.js    |  31 ++++
 .../app/addons/verifyinstall/resources.js       | 174 +++++++++++++++++++
 src/fauxton/app/addons/verifyinstall/routes.js  |  37 ++++
 .../addons/verifyinstall/templates/main.html    |  50 ++++++
 src/fauxton/app/addons/verifyinstall/views.js   | 126 ++++++++++++++
 src/fauxton/app/modules/documents/resources.js  |   1 -
 src/fauxton/settings.json.default               |   3 +-
 9 files changed, 425 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/97108341/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index cc2398b..95cf2f3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -100,6 +100,7 @@ src/fauxton/app/addons/*
 !src/fauxton/app/addons/auth
 !src/fauxton/app/addons/exampleAuth
 !src/fauxton/app/addons/permissions
+!src/fauxton/app/addons/verifyinstall
 src/fauxton/settings.json*
 !src/fauxton/settings.json.default
 src/ibrowse/ibrowse.app

http://git-wip-us.apache.org/repos/asf/couchdb/blob/97108341/src/fauxton/app/addons/verifyinstall/assets/less/verifyinstall.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/verifyinstall/assets/less/verifyinstall.less b/src/fauxton/app/addons/verifyinstall/assets/less/verifyinstall.less
new file mode 100644
index 0000000..508994b
--- /dev/null
+++ b/src/fauxton/app/addons/verifyinstall/assets/less/verifyinstall.less
@@ -0,0 +1,4 @@
+#start {
+  margin-bottom: 20px;
+}
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/97108341/src/fauxton/app/addons/verifyinstall/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/verifyinstall/base.js b/src/fauxton/app/addons/verifyinstall/base.js
new file mode 100644
index 0000000..d17c353
--- /dev/null
+++ b/src/fauxton/app/addons/verifyinstall/base.js
@@ -0,0 +1,31 @@
+// 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/verifyinstall/routes"
+],
+
+function(app, FauxtonAPI, VerifyInstall) {
+  VerifyInstall.initialize = function () {
+    FauxtonAPI.addHeaderLink({
+        title: "Verify", 
+        href: "#verifyinstall",
+        icon: "fonticon-circle-check",
+        bottomNav: true,
+      });
+  };
+
+
+  return VerifyInstall;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/97108341/src/fauxton/app/addons/verifyinstall/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/verifyinstall/resources.js b/src/fauxton/app/addons/verifyinstall/resources.js
new file mode 100644
index 0000000..f42c020
--- /dev/null
+++ b/src/fauxton/app/addons/verifyinstall/resources.js
@@ -0,0 +1,174 @@
+// 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",
+  "modules/databases/resources",
+  "modules/documents/resources"
+],
+
+function (app, FauxtonAPI, Databases, Documents) {
+  var Verifyinstall = FauxtonAPI.addon();
+
+  var db = new Databases.Model({
+    id: 'verifytestdb',
+    name: 'verifytestdb'
+  });
+
+  var dbReplicate = new Databases.Model({
+    id: 'verifytestdb_replicate',
+    name: 'verifytestdb_replicate'
+  });
+
+  var doc, viewDoc;
+
+  Verifyinstall.testProcess = {
+
+    saveDoc: function () {
+      doc = new Documents.Doc({_id: 'test_doc_1', a: 1}, {
+        database: db
+      });
+
+      return doc.save();
+    },
+
+    destroyDoc: function () {
+     return doc.destroy();
+    },
+
+    updateDoc: function () {
+      doc.set({b: "hello"});
+      return doc.save(); 
+    },
+
+    saveDB: function () {
+      return db.save();
+    },
+
+    setupDB: function (db) {
+      var deferred = FauxtonAPI.Deferred();
+      db.fetch()
+      .then(function () {
+        return db.destroy();
+      }, function (xhr) {
+        deferred.resolve();
+      })
+      .then(function () {
+        deferred.resolve();
+      }, function (xhr, error, reason) {
+        if (reason === "Unauthorized") {
+          deferred.reject(xhr, error, reason);
+        }
+      });
+
+      return deferred;
+    },
+
+    setup: function () {
+      return FauxtonAPI.when([
+        this.setupDB(db), 
+        this.setupDB(dbReplicate)
+      ]);
+    },
+
+    testView: function () {
+      var deferred = FauxtonAPI.Deferred();
+      var promise = $.get(viewDoc.url() + '/_view/testview');
+
+      promise.then(function (resp) { 
+        var row = JSON.parse(resp).rows[0];
+        if (row.value === 6) {
+          return deferred.resolve();
+        }
+        var reason = {
+            reason: 'Values expect 6, got ' + row.value
+          };
+
+        deferred.reject({responseText: JSON.stringify(reason)});
+      }, deferred.reject);
+
+      return deferred;
+    },
+
+    setupView: function () {
+      var doc1 = new Documents.Doc({_id: 'test_doc10', a: 1}, {
+        database: db
+      });
+
+      var doc2 = new Documents.Doc({_id: 'test_doc_20', a: 2}, {
+        database: db
+      });
+
+      var doc3 = new Documents.Doc({_id: 'test_doc_30', a: 3}, {
+        database: db
+      });
+
+      viewDoc = new Documents.Doc({
+        _id: '_design/view_check',
+        views: {
+          'testview': { 
+            map:'function (doc) { emit(doc._id, doc.a); }',
+            reduce: '_sum'
+          }
+        } 
+      },{
+        database: db,
+      });
+
+      return FauxtonAPI.when([doc1.save(),doc2.save(), doc3.save(), viewDoc.save()]);
+    },
+
+    setupReplicate: function () {
+      return $.ajax({
+        url: '/_replicate',
+        contentType: 'application/json',
+        type: 'POST',
+        dataType: 'json',
+        processData: false,
+        data: JSON.stringify({
+          create_target: true,
+          source: 'verifytestdb',
+          target: 'verifytestdb_replicate'
+        }),
+      });
+    },
+
+    testReplicate: function () {
+      var deferred = FauxtonAPI.Deferred();
+      /*var dbReplicate = new Databases.Model({
+          id: 'verifytestdb_replicate',
+          name: 'verifytestdb_replicate'
+        });*/
+
+      var promise = dbReplicate.fetch();
+
+      promise.then(function () {
+        var docCount = dbReplicate.get('doc_count');
+        if ( docCount === 4) {
+          deferred.resolve();
+          return;
+        }
+
+        var reason = {
+          reason: 'Replication Failed, expected 4 docs got ' + docCount
+        };
+
+        deferred.reject({responseText: JSON.stringify(reason)});
+      }, deferred.reject);
+
+      return deferred;
+    }
+  };
+
+  return Verifyinstall;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/97108341/src/fauxton/app/addons/verifyinstall/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/verifyinstall/routes.js b/src/fauxton/app/addons/verifyinstall/routes.js
new file mode 100644
index 0000000..e5024ba
--- /dev/null
+++ b/src/fauxton/app/addons/verifyinstall/routes.js
@@ -0,0 +1,37 @@
+// 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/verifyinstall/views"
+],
+function(app, FauxtonAPI, VerifyInstall) {
+
+  var VerifyRouteObject = FauxtonAPI.RouteObject.extend({
+    layout: 'one_pane',
+
+    routes: {
+      'verifyinstall': "verifyInstall"
+    },
+    selectedHeader: "Verify",
+
+    verifyInstall: function () {
+      this.setView('#dashboard-content', new VerifyInstall.Main({}));
+    },
+
+    crumbs: [{name: 'Verify Couchdb Installation', link: '#'}]
+  });
+
+  VerifyInstall.RouteObjects = [VerifyRouteObject];
+  return VerifyInstall;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/97108341/src/fauxton/app/addons/verifyinstall/templates/main.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/verifyinstall/templates/main.html b/src/fauxton/app/addons/verifyinstall/templates/main.html
new file mode 100644
index 0000000..fa41907
--- /dev/null
+++ b/src/fauxton/app/addons/verifyinstall/templates/main.html
@@ -0,0 +1,50 @@
+<!--
+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.
+-->
+<button id="start" class="btn btn-large btn-success"> Verify Installation </button>
+<div id="error"> </div>
+
+<table id="test-score" class="table table-striped table-bordered" >
+  <thead>
+    <tr>
+      <th> Test </th>
+      <th> Status </th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td> Create Database </td>
+      <td id="create-database" class="status">  </td>
+    </tr>
+    <tr>
+      <td> Create Document </td>
+      <td id="create-document" class="status">  </td>
+    </tr>
+    <tr>
+      <td> Update Document </td>
+      <td id="update-document" class="status">  </td>
+    </tr>
+    <tr>
+      <td> Delete Document </td>
+      <td id="delete-document" class="status">  </td>
+    </tr>
+    <tr>
+      <td> Create View </td>
+      <td id="create-view" class="status">  </td>
+    </tr>
+    <tr>
+      <td> Replication </td>
+      <td id="replicate" class="status">  </td>
+    </tr>
+  </tbody>
+</table>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/97108341/src/fauxton/app/addons/verifyinstall/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/verifyinstall/views.js b/src/fauxton/app/addons/verifyinstall/views.js
new file mode 100644
index 0000000..3ad3364
--- /dev/null
+++ b/src/fauxton/app/addons/verifyinstall/views.js
@@ -0,0 +1,126 @@
+// 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/verifyinstall/resources",
+],
+function(app, FauxtonAPI, VerifyInstall) {
+
+  VerifyInstall.Main = FauxtonAPI.View.extend({
+    template: 'addons/verifyinstall/templates/main',
+
+    events: {
+      "click #start": "startTest"
+    },
+
+    initialize: function (options) {
+      _.bindAll(this);
+    },
+
+    setPass: function (id) {
+      this.$('#' + id).html('&#10003;');
+    },
+
+    setError: function (id, msg) {
+      this.$('#' + id).html('&#x2717;');
+      FauxtonAPI.addNotification({
+        msg: 'Error: ' + msg,
+        type: 'error',
+        selector: '#error'
+      });
+    },
+
+    complete: function () {
+      FauxtonAPI.addNotification({
+        msg: 'Success! You Couchdb install is working. Time to Relax',
+        type: 'success',
+        selector: '#error'
+      });
+    },
+
+    enableButton: function () {
+      this.$('#start').removeAttr('disabled').text('Verify Installation');
+    },
+
+    disableButton: function () {
+      this.$('#start').attr('disabled','disabled').text('Verifying');
+    },
+
+    formatError: function (id) {
+      var enableButton = this.enableButton,
+          setError = this.setError;
+
+      return function (xhr, error, reason) {
+        enableButton();
+
+        if (!xhr) { return; }
+
+        setError(id, JSON.parse(xhr.responseText).reason);
+      };
+    },
+
+    
+    startTest: function () {
+      this.disableButton();
+      this.$('.status').text('');
+
+      var testProcess = VerifyInstall.testProcess,
+          setPass = this.setPass,
+          complete = this.complete,
+          setError = this.setError,
+          formatError = this.formatError;
+
+      testProcess.setup()
+      .then(function () {
+        return testProcess.saveDB();
+      }, formatError('create-database'))
+      .then(function () {
+        setPass('create-database');
+        return testProcess.saveDoc();
+      }, formatError('create-document'))
+      .then(function () {
+        setPass('create-document');
+        return testProcess.updateDoc();
+      }, formatError('update-document'))
+      .then(function () {
+        setPass('update-document');
+        return testProcess.destroyDoc();
+      }, formatError('delete-document'))
+      .then(function () {
+        setPass('delete-document');
+        return testProcess.setupView();
+      }, formatError('create-view'))
+      .then(function () {
+        return testProcess.testView();
+      }, formatError('create-view'))
+      .then(function () {
+        setPass('create-view');
+        return testProcess.setupReplicate();
+      }, formatError('create-view'))
+      .then(function () {
+        return testProcess.testReplicate();
+      }, formatError('replicate'))
+      .then(function () {
+          setPass('replicate');
+          complete();
+      }, formatError('replicate'));
+
+      this.enableButton();
+    }
+  });
+
+
+  return VerifyInstall;
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/97108341/src/fauxton/app/modules/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/resources.js b/src/fauxton/app/modules/documents/resources.js
index bad8b77..8df2e6f 100644
--- a/src/fauxton/app/modules/documents/resources.js
+++ b/src/fauxton/app/modules/documents/resources.js
@@ -12,7 +12,6 @@
 
 define([
   "app",
-
   "api"
 ],
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/97108341/src/fauxton/settings.json.default
----------------------------------------------------------------------
diff --git a/src/fauxton/settings.json.default b/src/fauxton/settings.json.default
index 4964135..ce45e26 100644
--- a/src/fauxton/settings.json.default
+++ b/src/fauxton/settings.json.default
@@ -8,7 +8,8 @@
   { "name": "plugins" },
   { "name": "contribute" },
   { "name": "permissions" },
-  { "name": "auth" }
+  { "name": "auth" },
+  { "name": "verifyinstall" }
   ],
     "template": {
       "development": {


[3/3] git commit: updated refs/heads/master to 9710834

Posted by ga...@apache.org.
Fauxton: Fix correct row number message
Fixes COUCHDB-1760


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

Branch: refs/heads/master
Commit: 807c4e32fa0e5aa4fd4a74a2338df215ffbe5ac7
Parents: 1cf4621
Author: Garren Smith <ga...@gmail.com>
Authored: Thu Oct 10 14:46:17 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Wed Oct 16 10:24:52 2013 +0200

----------------------------------------------------------------------
 src/fauxton/app/modules/documents/resources.js  | 17 +++-
 src/fauxton/app/modules/documents/views.js      | 90 ++++++++++++++------
 src/fauxton/app/modules/fauxton/components.js   |  7 +-
 .../app/templates/documents/all_docs_list.html  | 24 ++----
 .../templates/documents/all_docs_number.html    | 21 +++++
 5 files changed, 113 insertions(+), 46 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/807c4e32/src/fauxton/app/modules/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/resources.js b/src/fauxton/app/modules/documents/resources.js
index 901ba83..bad8b77 100644
--- a/src/fauxton/app/modules/documents/resources.js
+++ b/src/fauxton/app/modules/documents/resources.js
@@ -268,6 +268,8 @@ function(app, FauxtonAPI) {
       this.database = options.database;
       this.params = options.params;
       this.skipFirstItem = false;
+
+      this.on("remove",this.decrementTotalRows , this);
     },
 
     url: function(context) {
@@ -284,7 +286,13 @@ function(app, FauxtonAPI) {
 
     urlNextPage: function (num, lastId) {
       if (!lastId) {
-        lastId = this.last().id;
+        var doc = this.last();
+
+        if (doc) {
+          lastId = doc.id;
+        } else {
+          lastId = '';
+        }
       }
 
       this.params.startkey_docid = '"' + lastId + '"';
@@ -311,6 +319,13 @@ function(app, FauxtonAPI) {
       return this.viewMeta.total_rows || "unknown";
     },
 
+    decrementTotalRows: function () {
+      if (this.viewMeta.total_rows) {
+        this.viewMeta.total_rows = this.viewMeta.total_rows -1;
+        this.trigger('totalRows:decrement');
+      }
+    },
+
     updateSeq: function() {
       return this.viewMeta.update_seq || false;
     },

http://git-wip-us.apache.org/repos/asf/couchdb/blob/807c4e32/src/fauxton/app/modules/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js
index 3fd47d4..376a2ac 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -362,8 +362,11 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
         FauxtonAPI.addNotification({
           msg: "Succesfully destroyed your doc"
         });
-        that.$el.fadeOut();
-        that.model.collection.remove(that.id);
+        that.$el.fadeOut(function () {
+          that.remove();
+        });
+
+        that.model.collection.remove(that.model.id);
       }, function(resp) {
         FauxtonAPI.addNotification({
           msg: "Failed to destroy your doc!",
@@ -377,6 +380,16 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
     template: "templates/documents/index_row_docular",
     tagName: "tr",
 
+    events: {
+      "click button.delete": "destroy"
+    },
+
+    destroy: function (event) {
+      event.preventDefault(); 
+      
+      window.alert('Cannot delete a document generated from a view.');
+    },
+
     serialize: function() {
       return {
         doc: this.model
@@ -412,6 +425,38 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
     }
   });
 
+  Views.AllDocsNumber = FauxtonAPI.View.extend({
+    template: "templates/documents/all_docs_number",
+
+    initialize: function (options) {
+      this.newView = options.newView || false;
+      
+      this.listenTo(this.collection, 'totalRows:decrement', this.render);
+    },
+
+    serialize: function () {
+       var totalRows = 0,
+          recordStart = 0,
+          updateSeq = false;
+
+      if (!this.newView) {
+        totalRows = this.collection.totalRows();
+        updateSeq = this.collection.updateSeq();
+      }
+
+      recordStart = this.collection.recordStart();
+
+      return {
+        database: this.collection.database.id,
+        updateSeq: updateSeq,
+        offset: recordStart,
+        totalRows: totalRows,
+        numModels: this.collection.models.length + recordStart - 1,
+      };
+    }
+
+  });
+
   // TODO: Rename to reflect that this is a list of rows or documents
   Views.AllDocsList = FauxtonAPI.View.extend({
     template: "templates/documents/all_docs_list",
@@ -457,32 +502,16 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
     },
 
     serialize: function() {
-      var totalRows = 0,
-          recordStart = 0,
-          updateSeq = false;
+      var requestDuration = false;
 
-      if (!this.newView) {
-        totalRows = this.collection.totalRows();
-        updateSeq = this.collection.updateSeq();
+      if (this.collection.requestDurationInString) {
+        requestDuration = this.collection.requestDurationInString();
       }
 
-      recordStart = this.collection.recordStart();
-
-      var info = {
-        database: this.collection.database.id,
-        updateSeq: updateSeq,
-        offset: recordStart,
-        totalRows: totalRows,
-        numModels: this.collection.models.length + recordStart - 1,
+      return {
         viewList: this.viewList,
-        requestDuration: null
+        requestDuration: requestDuration
       };
-
-      if (this.collection.requestDurationInString) {
-        info.requestDuration = this.collection.requestDurationInString();
-      }
-
-      return info;
     },
 
     /*
@@ -497,7 +526,10 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
     bulkDelete: function() {
       var that = this;
       // yuck, data binding ftw?
-      var eles = this.$el.find("input.row-select:checked").parents("tr.all-docs-item").map(function(e) { return $(this).attr("data-id"); }).get();
+      var eles = this.$el.find("input.row-select:checked")
+                         .parents("tr.all-docs-item")
+                         .map(function(e) { return $(this).attr("data-id"); })
+                         .get();
 
       if (!window.confirm("Are you sure you want to delete these " + eles.length + " docs?")) {
         return false;
@@ -507,7 +539,9 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
         var model = this.collection.get(ele);
 
         model.destroy().then(function(resp) {
-          that.rows[ele].$el.fadeOut();
+          that.rows[ele].$el.fadeOut(function () {
+            $(this).remove();
+          });
 
           model.collection.remove(model.id);
           that.$('.bulk-delete').addClass('disabled');
@@ -551,6 +585,11 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
     },
 
     beforeRender: function() {
+      this.allDocsNumber = this.setView('#item-numbers', new Views.AllDocsNumber({
+        collection: this.collection,
+        newView: this.newView
+      }));
+
       this.insertView('#documents-pagination', this.pagination);
       this.collection.each(function(doc) {
         this.rows[doc.id] = this.insertView("table.all-docs tbody", new this.nestedView({
@@ -679,7 +718,6 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
         this.getDocFromEditor();
 
         notification = FauxtonAPI.addNotification({msg: "Saving document."});
-        console.log('save',this.model);
 
         this.model.save().then(function () {
           FauxtonAPI.navigate('/database/' + that.database.id + '/' + that.model.id);

http://git-wip-us.apache.org/repos/asf/couchdb/blob/807c4e32/src/fauxton/app/modules/fauxton/components.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/fauxton/components.js b/src/fauxton/app/modules/fauxton/components.js
index 09dcc51..03fea87 100644
--- a/src/fauxton/app/modules/fauxton/components.js
+++ b/src/fauxton/app/modules/fauxton/components.js
@@ -73,7 +73,12 @@ function(app, FauxtonAPI) {
 
     nextClicked: function (event) {
       event.preventDefault();
-      this.previousIds.push(this.collection.first().id);
+      var doc = this.collection.first();
+
+      if (doc) {
+        this.previousIds.push(doc.id);
+      }
+
       FauxtonAPI.navigate(this.nextUrlfn(), {trigger: false});
       FauxtonAPI.triggerRouteEvent('paginate', 'next');
     },

http://git-wip-us.apache.org/repos/asf/couchdb/blob/807c4e32/src/fauxton/app/templates/documents/all_docs_list.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/all_docs_list.html b/src/fauxton/app/templates/documents/all_docs_list.html
index 43a5532..dcb8dda 100644
--- a/src/fauxton/app/templates/documents/all_docs_list.html
+++ b/src/fauxton/app/templates/documents/all_docs_list.html
@@ -19,29 +19,17 @@ the License.
         <button type="button" class="btn all" data-toggle="button">✓ All</button>
         <button class="btn btn-small disabled bulk-delete"><i class="icon-trash"></i></button>
       </div>
-      <!-- TODO::REENABLE
-      <div class="btn-toolbar pull-right">
-        <a href="#new-view-index" class="btn btn-small toggle-edit disabled"><i class="icon-wrench"></i> Edit index</a>
-        <a href="#params" class="btn btn-small toggle-params"><i class="icon-plus"></i> API preview</a>
-      </div>
-      -->
     </div>
   <% } %>
   <p>
 
-  <% if (totalRows === "unknown"){ %>
-    Showing 0 documents. <a href="#/database/<%=database%>/new"> Create your first document.</a>
-  <% } else { %>
-    Showing <%=offset%> - <%= numModels %> of <%= totalRows %> rows
-  <%}%>
-    <% if (updateSeq) { %>
-      -- Update Sequence: <%= updateSeq %>
-    <% } %>
-    <% if (requestDuration) { %>
-  <span class="view-request-duration">
+  <div id="item-numbers"> </div>
+
+  <% if (requestDuration) { %>
+    <span class="view-request-duration">
     View request duration: <strong> <%= requestDuration %> </strong> 
-   </span>
-   <% } %>
+    </span>
+  <% } %>
   </p>
   <table class="all-docs table table-striped table-condensed">
     <tbody></tbody>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/807c4e32/src/fauxton/app/templates/documents/all_docs_number.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/all_docs_number.html b/src/fauxton/app/templates/documents/all_docs_number.html
new file mode 100644
index 0000000..c4ea8f6
--- /dev/null
+++ b/src/fauxton/app/templates/documents/all_docs_number.html
@@ -0,0 +1,21 @@
+<!--
+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.
+-->
+<% if (totalRows === "unknown"){ %>
+  Showing 0 documents. <a href="#/database/<%=database%>/new"> Create your first document.</a>
+<% } else { %>
+  Showing <%=offset%> - <%= numModels %> of <%= totalRows %> rows
+<%}%>
+<% if (updateSeq) { %>
+  -- Update Sequence: <%= updateSeq %>
+<% } %>


[2/3] git commit: updated refs/heads/master to 9710834

Posted by ga...@apache.org.
Fauxton: Add advanced options to Alldocs
Fixes COUCHDB-1694


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

Branch: refs/heads/master
Commit: bcb4fba312ba2ad74b9f19adcaf9eecbaf1bffe7
Parents: 807c4e3
Author: Garren Smith <ga...@gmail.com>
Authored: Fri Oct 11 11:27:45 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Wed Oct 16 10:24:52 2013 +0200

----------------------------------------------------------------------
 src/fauxton/app/modules/documents/routes.js     |  16 +-
 src/fauxton/app/modules/documents/views.js      | 433 ++++++++++++-------
 src/fauxton/app/modules/fauxton/base.js         |   4 +-
 .../templates/documents/advanced_options.html   |  94 ++++
 .../templates/documents/all_docs_layout.html    |  20 +
 .../app/templates/documents/jumpdoc.html        |   7 +-
 .../app/templates/documents/view_editor.html    | 123 +-----
 src/fauxton/assets/less/fauxton.less            |   6 +
 src/fauxton/test/core/routeObjectSpec.js        |   5 +-
 9 files changed, 445 insertions(+), 263 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/bcb4fba3/src/fauxton/app/modules/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/routes.js b/src/fauxton/app/modules/documents/routes.js
index 572bf1f..13b2bc9 100644
--- a/src/fauxton/app/modules/documents/routes.js
+++ b/src/fauxton/app/modules/documents/routes.js
@@ -204,12 +204,17 @@ function(app, FauxtonAPI, Documents, Databases) {
 
       if (this.viewEditor) { this.viewEditor.remove(); }
 
-
       this.toolsView = this.setView("#dashboard-upper-menu", new Documents.Views.JumpToDoc({
         database: this.data.database,
         collection: this.data.database.allDocs
       }));
 
+      this.setView("#dashboard-upper-content", new Documents.Views.AllDocsLayout({
+        database: this.data.database,
+        collection: this.data.database.allDocs,
+        params: docOptions
+      }));
+
       this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
         collection: this.data.database.allDocs
       }));
@@ -295,7 +300,14 @@ function(app, FauxtonAPI, Documents, Databases) {
 
     updateAllDocsFromView: function (event) {
       var view = event.view,
-      ddoc = event.ddoc;
+          docOptions = app.getParams(),
+          ddoc = event.ddoc;
+
+      if (event.allDocs) {
+        docOptions.include_docs = true;
+        this.data.database.buildAllDocs(docOptions);
+        return;
+      }
 
       this.data.indexedDocs = new Documents.IndexCollection(null, {
         database: this.data.database,

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bcb4fba3/src/fauxton/app/modules/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js
index 376a2ac..6c39044 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -457,6 +457,81 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
 
   });
 
+  Views.AllDocsLayout = FauxtonAPI.View.extend({
+    template: "templates/documents/all_docs_layout",
+    className: "row",
+
+    initialize: function (options) {
+      this.database = options.database;
+      this.params = options.params;
+    },
+
+    events: {
+      'click #toggle-query': "toggleQuery"
+    },
+
+    toggleQuery: function (event) {
+      this.$('#query').toggle('fast');
+    },
+
+    beforeRender: function () {
+      this.advancedOptions = this.insertView('#query', new Views.AdvancedOptions({
+        updateViewFn: this.updateView,
+        previewFn: this.previewView,
+        hasReduce: false,
+        showPreview: false
+      }));
+
+      this.$('#query').hide();
+    },
+
+    afterRender: function () {
+      if (this.params) {
+        this.advancedOptions.updateFromParams(this.params);
+      }
+
+    },
+
+    updateView: function (event, paramInfo) {
+      event.preventDefault();
+
+      var errorParams = paramInfo.errorParams,
+          params = paramInfo.params;
+
+      if (_.any(errorParams)) {
+        _.map(errorParams, function(param) {
+
+          // TODO: Where to add this error?
+          // bootstrap wants the error on a control-group div, but we're not using that
+          //$('form.view-query-update input[name='+param+'], form.view-query-update select[name='+param+']').addClass('error');
+          return FauxtonAPI.addNotification({
+            msg: "JSON Parse Error on field: "+param.name,
+            type: "error",
+            selector: ".advanced-options .errors-container"
+          });
+        });
+        FauxtonAPI.addNotification({
+          msg: "Make sure that strings are properly quoted and any other values are valid JSON structures",
+          type: "warning",
+          selector: ".advanced-options .errors-container"
+        });
+
+        return false;
+      }
+
+      var fragment = window.location.hash.replace(/\?.*$/, '');
+      fragment = fragment + '?' + $.param(params);
+      FauxtonAPI.navigate(fragment, {trigger: false});
+
+      FauxtonAPI.triggerRouteEvent('updateAllDocs', {allDocs: true});
+    },
+
+    previewView: function (event) {
+      event.preventDefault();
+    }
+
+  });
+
   // TODO: Rename to reflect that this is a list of rows or documents
   Views.AllDocsList = FauxtonAPI.View.extend({
     template: "templates/documents/all_docs_list",
@@ -886,6 +961,140 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
     }
   });
 
+  Views.AdvancedOptions = FauxtonAPI.View.extend({
+    template: "templates/documents/advanced_options",
+    className: "advanced-options well",
+
+    initialize: function (options) {
+      this.updateViewFn = options.updateViewFn;
+      this.previewFn = options.previewFn;
+      this.hadReduce = options.hasReduce || true;
+
+      if (typeof(options.hasReduce) === 'undefined') {
+        this.hasReduce = true;
+      } else {
+        this.hasReduce = options.hasReduce;
+      }
+
+      if (typeof(options.showPreview) === 'undefined') {
+        this.showPreview = true;
+      } else {
+        this.showPreview = options.showPreview;
+      }
+    },
+
+    events: {
+      "change form.view-query-update input": "updateFilters",
+      "change form.view-query-update select": "updateFilters",
+      "submit form.view-query-update": "updateView",
+      "click button.preview": "previewView"
+    },
+
+    queryParams: function () {
+      var $form = this.$(".view-query-update");
+      // Ignore params without a value
+      var params = _.filter($form.serializeArray(), function(param) {
+        return param.value;
+      });
+
+      // Validate *key* params to ensure they're valid JSON
+      var keyParams = ["key","keys","startkey","endkey"];
+      var errorParams = _.filter(params, function(param) {
+        if (_.contains(keyParams, param.name)) {
+          try {
+            JSON.parse(param.value);
+            return false;
+          } catch(e) {
+            return true;
+          }
+        } else {
+          return false;
+        }
+      });
+
+      return {params: params, errorParams: errorParams};
+    },
+
+    updateFilters: function(event) {
+      event.preventDefault();
+      var $ele = $(event.currentTarget);
+      var name = $ele.attr('name');
+      this.updateFiltersFor(name, $ele);
+    },
+
+    updateFiltersFor: function(name, $ele) {
+      var $form = $ele.parents("form.view-query-update:first");
+      switch (name) {
+        // Reduce constraints
+        //   - Can't include_docs for reduce=true
+        //   - can't include group_level for reduce=false
+        case "reduce":
+          if ($ele.prop('checked') === true) {
+          if ($form.find("input[name=include_docs]").prop("checked") === true) {
+            $form.find("input[name=include_docs]").prop("checked", false);
+            var notification = FauxtonAPI.addNotification({
+              msg: "include_docs has been disabled as you cannot include docs on a reduced view",
+              type: "warn",
+              selector: ".view.show .all-docs-list.errors-container"
+            });
+          }
+          $form.find("input[name=include_docs]").prop("disabled", true);
+          $form.find("select[name=group_level]").prop("disabled", false);
+        } else {
+          $form.find("select[name=group_level]").prop("disabled", true);
+          $form.find("input[name=include_docs]").prop("disabled", false);
+        }
+        break;
+        case "include_docs":
+          break;
+      }
+    },
+
+    updateFromParams: function (params) {
+      var $form = this.$el.find("form.view-query-update");
+      _.each(params, function(val, key) {
+        var $ele;
+        switch (key) {
+          case "limit":
+            case "group_level":
+            $form.find("select[name='"+key+"']").val(val);
+          break;
+          case "include_docs":
+            case "stale":
+            case "descending":
+            case "inclusive_end":
+            $form.find("input[name='"+key+"']").prop('checked', true);
+          break;
+          case "reduce":
+            $ele = $form.find("input[name='"+key+"']");
+          if (val == "true") {
+            $ele.prop('checked', true);
+          }
+          this.updateFiltersFor(key, $ele);
+          break;
+          default:
+            $form.find("input[name='"+key+"']").val(val);
+          break;
+        }
+      }, this);
+    },
+
+    updateView: function (event) {
+      this.updateViewFn(event, this.queryParams());
+    },
+
+    previewView: function (event) {
+      this.previewFn(event, this.queryParams());
+    },
+
+    serialize: function () {
+      return {
+        hasReduce: this.hasReduce,
+        showPreview: this.showPreview
+      };
+    }
+  });
+
   //TODO split this into two smaller views, one for advance query options and other for index editing
   Views.ViewEditor = FauxtonAPI.View.extend({
     template: "templates/documents/view_editor",
@@ -893,13 +1102,9 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
 
     events: {
       "click button.save": "saveView",
-      "click button.preview": "previewView",
       "click button.delete": "deleteView",
       "change select#reduce-function-selector": "updateReduce",
-      "change form.view-query-update input": "updateFilters",
-      "change form.view-query-update select": "updateFilters",
       "change select#ddoc": "updateDesignDoc",
-      "submit form.view-query-update": "updateView",
       "click #db-views-tabs-nav": 'toggleIndexNav'
     },
 
@@ -924,6 +1129,8 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
         this.viewName = options.viewName;
         this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
       } 
+
+      _.bindAll(this);
     },
 
     establish: function () {
@@ -965,31 +1172,6 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
       }
     },
 
-    queryParams: function () {
-      var $form = $(".view-query-update");
-      // Ignore params without a value
-      var params = _.filter($form.serializeArray(), function(param) {
-        return param.value;
-      });
-
-      // Validate *key* params to ensure they're valid JSON
-      var keyParams = ["key","keys","startkey","endkey"];
-      var errorParams = _.filter(params, function(param) {
-        if (_.contains(keyParams, param.name)) {
-          try {
-            JSON.parse(param.value);
-            return false;
-          } catch(e) {
-            return true;
-          }
-        } else {
-          return false;
-        }
-      });
-
-      return {params: params, errorParams: errorParams};
-    },
-
     deleteView: function (event) {
       event.preventDefault();
 
@@ -1016,14 +1198,70 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
       });
     },
 
-    updateView: function(event) {
+    saveView: function(event) {
+      var json, notification,
+      that = this;
+
+      if (event) { event.preventDefault();}
+
+      if (this.hasValidCode()) {
+        var mapVal = this.mapEditor.getValue(), 
+        reduceVal = this.reduceVal(),
+        viewName = this.$('#index-name').val(),
+        ddoc = this.getCurrentDesignDoc(),
+        ddocName = ddoc.id;
+
+        this.viewName = viewName;
+
+        notification = FauxtonAPI.addNotification({
+          msg: "Saving document.",
+          selector: "#define-view .errors-container"
+        });
+
+        ddoc.setDdocView(viewName, mapVal, reduceVal);
+
+        ddoc.save().then(function () {
+          FauxtonAPI.addNotification({
+            msg: "View has been saved.",
+            type: "success",
+            selector: "#define-view .errors-container"
+          });
+
+          if (that.newView) {
+            var fragment = '/database/' + that.database.id +'/' + ddocName + '/_view/' + viewName; 
+
+            FauxtonAPI.navigate(fragment, {trigger: false});
+            FauxtonAPI.triggerRouteEvent('reloadDesignDocs',{selectedTab: ddocName.replace('_design/','') + '_' + viewName});
+
+            that.newView = false;
+          }
+
+          FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: ddocName, view: viewName});
+
+        }, function(xhr) {
+          var responseText = JSON.parse(xhr.responseText).reason;
+          notification = FauxtonAPI.addNotification({
+            msg: "Save failed: " + responseText,
+            type: "error",
+            clear: true
+          });
+        });
+      } else {
+        notification = FauxtonAPI.addNotification({
+          msg: "Please fix the Javascript errors and try again.",
+          type: "error",
+          selector: "#define-view .errors-container"
+        });
+      }
+    },
+
+    updateView: function(event, paramInfo) {
       event.preventDefault();
 
       if (this.newView) { return alert('Please save this new view before querying it.'); }
 
-      var paramInfo = this.queryParams(),
-      errorParams = paramInfo.errorParams,
-      params = paramInfo.params;
+      var errorParams = paramInfo.errorParams,
+          params = paramInfo.params;
 
       if (_.any(errorParams)) {
         _.map(errorParams, function(param) {
@@ -1053,46 +1291,11 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
       FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
     },
 
-    updateFilters: function(event) {
-      event.preventDefault();
-      var $ele = $(event.currentTarget);
-      var name = $ele.attr('name');
-      this.updateFiltersFor(name, $ele);
-    },
-
-    updateFiltersFor: function(name, $ele) {
-      var $form = $ele.parents("form.view-query-update:first");
-      switch (name) {
-        // Reduce constraints
-        //   - Can't include_docs for reduce=true
-        //   - can't include group_level for reduce=false
-        case "reduce":
-          if ($ele.prop('checked') === true) {
-          if ($form.find("input[name=include_docs]").prop("checked") === true) {
-            $form.find("input[name=include_docs]").prop("checked", false);
-            var notification = FauxtonAPI.addNotification({
-              msg: "include_docs has been disabled as you cannot include docs on a reduced view",
-              type: "warn",
-              selector: ".view.show .all-docs-list.errors-container"
-            });
-          }
-          $form.find("input[name=include_docs]").prop("disabled", true);
-          $form.find("select[name=group_level]").prop("disabled", false);
-        } else {
-          $form.find("select[name=group_level]").prop("disabled", true);
-          $form.find("input[name=include_docs]").prop("disabled", false);
-        }
-        break;
-        case "include_docs":
-          break;
-      }
-    },
-
-    previewView: function(event) {
+    previewView: function(event, paramsInfo) {
       var that = this,
       mapVal = this.mapEditor.getValue(),
       reduceVal = this.reduceVal(),
-      paramsArr = this.queryParams().params;
+      paramsArr = paramsInfo.params;
 
       var params = _.reduce(paramsArr, function (params, param) {
         params[param.name] = param.value;
@@ -1127,63 +1330,6 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
       });
     },
 
-    saveView: function(event) {
-      var json, notification,
-      that = this;
-
-      if (event) { event.preventDefault();}
-
-      if (this.hasValidCode()) {
-        var mapVal = this.mapEditor.getValue(), 
-        reduceVal = this.reduceVal(),
-        viewName = this.$('#index-name').val(),
-        ddoc = this.getCurrentDesignDoc(),
-        ddocName = ddoc.id;
-
-        this.viewName = viewName;
-
-        notification = FauxtonAPI.addNotification({
-          msg: "Saving document.",
-          selector: "#define-view .errors-container"
-        });
-
-        ddoc.setDdocView(viewName, mapVal, reduceVal);
-
-        ddoc.save().then(function () {
-          FauxtonAPI.addNotification({
-            msg: "View has been saved.",
-            type: "success",
-            selector: "#define-view .errors-container"
-          });
-
-          if (that.newView) {
-            var fragment = '/database/' + that.database.id +'/' + ddocName + '/_view/' + viewName; 
-
-            FauxtonAPI.navigate(fragment, {trigger: false});
-            FauxtonAPI.triggerRouteEvent('reloadDesignDocs',{selectedTab: ddocName.replace('_design/','') + '_' + viewName});
-
-            that.newView = false;
-          }
-
-          FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: ddocName, view: viewName});
-
-        }, function(xhr) {
-          var responseText = JSON.parse(xhr.responseText).reason;
-          notification = FauxtonAPI.addNotification({
-            msg: "Save failed: " + responseText,
-            type: "error",
-            clear: true
-          });
-        });
-      } else {
-        notification = FauxtonAPI.addNotification({
-          msg: "Please fix the Javascript errors and try again.",
-          type: "error",
-          selector: "#define-view .errors-container"
-        });
-      }
-    },
-
     getCurrentDesignDoc: function () {
       if (this.newDesignDoc()) {
         var doc = {
@@ -1310,6 +1456,11 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
         this.reduceFunStr = this.model.viewHasReduce(this.viewName);
         this.setView('#ddoc-info', new Views.DdocInfo({model: this.ddocInfo }));
       }
+
+      this.advancedOptions = this.insertView('#query', new Views.AdvancedOptions({
+        updateViewFn: this.updateView,
+        previewFn: this.previewView
+      }));
     },
 
     afterRender: function() {
@@ -1375,32 +1526,7 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
       }
 
       if (this.params) {
-        var $form = this.$el.find("form.view-query-update");
-        _.each(this.params, function(val, key) {
-          var $ele;
-          switch (key) {
-            case "limit":
-              case "group_level":
-              $form.find("select[name='"+key+"']").val(val);
-            break;
-            case "include_docs":
-              case "stale":
-              case "descending":
-              case "inclusive_end":
-              $form.find("input[name='"+key+"']").prop('checked', true);
-            break;
-            case "reduce":
-              $ele = $form.find("input[name='"+key+"']");
-            if (val == "true") {
-              $ele.prop('checked', true);
-            }
-            this.updateFiltersFor(key, $ele);
-            break;
-            default:
-              $form.find("input[name='"+key+"']").val(val);
-            break;
-          }
-        }, this);
+        this.advancedOptions.updateFromParams(this.params);
       }
 
     }
@@ -1415,6 +1541,7 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re
 
     events: {
       "submit #jump-to-doc": "jumpToDoc",
+      "click #jump-to-doc-label": "jumpToDoc"
     },
 
     jumpToDoc: function (event) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bcb4fba3/src/fauxton/app/modules/fauxton/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/fauxton/base.js b/src/fauxton/app/modules/fauxton/base.js
index f1d2f70..01c2928 100644
--- a/src/fauxton/app/modules/fauxton/base.js
+++ b/src/fauxton/app/modules/fauxton/base.js
@@ -216,10 +216,10 @@ function(app, Backbone, resizeColumns) {
     },
 
     hide: function(){
-      $(this.el).addClass('hide');
+      this.$el.addClass('hide');
     },
     show: function(){
-      $(this.el).removeClass('hide');
+      this.$el.removeClass('hide');
     },
     update: function(endpoint) {
       this.show();

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bcb4fba3/src/fauxton/app/templates/documents/advanced_options.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/advanced_options.html b/src/fauxton/app/templates/documents/advanced_options.html
new file mode 100644
index 0000000..aee2f65
--- /dev/null
+++ b/src/fauxton/app/templates/documents/advanced_options.html
@@ -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.
+-->
+<div class="errors-container"></div>
+<form class="view-query-update custom-inputs">
+  <div class="controls-group">
+    <div class="row-fluid">
+      <div class="controls controls-row">
+        <input name="key" class="span6" type="text" placeholder="Key">
+        <input name="keys" class="span6" type="text" placeholder="Keys">
+      </div>
+    </div>
+    <div class="row-fluid">
+      <div class="controls controls-row">
+        <input name="startkey" class="span6" type="text" placeholder="Start Key">
+        <input name="endkey" class="span6" type="text" placeholder="End Key">
+      </div>
+    </div>
+  </div>
+  <div class="controls-group">
+    <div class="row-fluid">
+      <div class="controls controls-row">
+        <div class="checkbox inline">  
+          <input id="check1" type="checkbox" name="include_docs" value="true">  
+          <label name="include_docs" for="check1">Include Docs</label>  
+          <% if (hasReduce) { %>
+          <input id="check2" name="reduce" type="checkbox" value="true">
+          <label for="check2">Reduce</label>  
+        </div> 
+        <label id="select1" class="drop-down inline">
+          Group Level:
+          <select id="select1" disabled name="group_level" class="input-small">
+            <option value="0">None</option>
+            <option value="1">1</option>
+            <option value="2">2</option>
+            <option value="3">3</option>
+            <option value="4">4</option>
+            <option value="5">5</option>
+            <option value="6">6</option>
+            <option value="7">7</option>
+            <option value="8">8</option>
+            <option value="9">9</option>
+            <option value="999" selected="selected">exact</option>
+          </select>
+        </label>
+        <% } %>
+        <div class="checkbox inline">  
+          <input id="check3" name="stale" type="checkbox" value="ok">
+          <label for="check3">Stale</label>
+          <input id="check4" name="descending" type="checkbox" value="true">  
+          <label for="check4">Descending</label>  
+        </div> 
+        <label class="drop-down inline">
+          Limit:
+          <select name="limit" class="input-small">
+            <option>5</option>
+            <option selected="selected">10</option>
+            <option>25</option>
+            <option>50</option>
+            <option>100</option>
+          </select>
+        </label>
+        <div class="checkbox inline">  
+          <input id="check5" name="inclusive_end" type="checkbox" value="false">
+          <label for="check5">Disable Inclusive End</label>
+          <input id="check6" name="update_seq" type="checkbox" value="true">  
+          <label for="check6">Descending</label>  
+        </div>
+      </div>
+    </div>
+  </div>
+  <div class="controls-group">
+    <div class="row-fluid">
+      <div class="controls controls-row">
+        <button type="submit" class="btn btn-primary btn-large">Query</button>
+        <% if (showPreview) { %>
+        <button class="btn btn-info btn-large preview">Preview</button>
+        <% } %>
+      </div>
+    </div>
+  </div>
+</form>
+</div>
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bcb4fba3/src/fauxton/app/templates/documents/all_docs_layout.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/all_docs_layout.html b/src/fauxton/app/templates/documents/all_docs_layout.html
new file mode 100644
index 0000000..cdbd161
--- /dev/null
+++ b/src/fauxton/app/templates/documents/all_docs_layout.html
@@ -0,0 +1,20 @@
+<!--
+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.
+-->
+<ul class="nav nav-tabs window-resizeable" id="db-views-tabs-nav">
+  <li><a id="toggle-query" class="fonticon-plus fonticon" href="#query" data-toggle="tab">Advanced Options</a></li>
+</ul>
+<div class="tab-content">
+  <div class="tab-pane" id="query">
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bcb4fba3/src/fauxton/app/templates/documents/jumpdoc.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/jumpdoc.html b/src/fauxton/app/templates/documents/jumpdoc.html
index 2e83c52..c6f4652 100644
--- a/src/fauxton/app/templates/documents/jumpdoc.html
+++ b/src/fauxton/app/templates/documents/jumpdoc.html
@@ -12,9 +12,8 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 
-
-<form id="jump-to-doc" class="form-inline">
-	<label id="jump-to-doc-label" class="fonticon-search">
-    <input type="text" id="jump-to-doc-id" class="i1nput-large" placeholder="Document ID"></input>
+<form id="jump-to-doc" class="form-inline" >
+  <label id="jump-to-doc-label" class="fonticon-search">
+    <input type="text" id="jump-to-doc-id" class="input-large" placeholder="Document ID"></input>
   </label>
 </form>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bcb4fba3/src/fauxton/app/templates/documents/view_editor.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/view_editor.html b/src/fauxton/app/templates/documents/view_editor.html
index b1ca470..64f0f98 100644
--- a/src/fauxton/app/templates/documents/view_editor.html
+++ b/src/fauxton/app/templates/documents/view_editor.html
@@ -57,42 +57,42 @@ the License.
 
           <div class="control-group">
             <label for="map-function">Map function <a href="<%=getDocUrl('map_functions')%>" target="_blank"><i class="icon-question-sign"></i></a></label>
-              <% if (newView) { %>
-              <textarea class="js-editor" id="map-function"><%= langTemplates.map %></textarea>
-              <% } else { %>
-              <textarea class="js-editor" id="map-function"><%= ddoc.get('views')[viewName].map %></textarea>
-              <% } %>
+            <% if (newView) { %>
+            <textarea class="js-editor" id="map-function"><%= langTemplates.map %></textarea>
+            <% } else { %>
+            <textarea class="js-editor" id="map-function"><%= ddoc.get('views')[viewName].map %></textarea>
+            <% } %>
           </div>
 
 
           <div class="control-group">
             <label for="reduce-function-selector">Reduce function <a href="<%=getDocUrl('reduce_functions')%>" target="_blank"><i class="icon-question-sign"></i></a></label>
 
-              <select id="reduce-function-selector">
-                <option value="" <%= !reduceFunStr ? 'selected="selected"' : '' %>>None</option>
-                <% _.each(["_sum", "_count", "_stats"], function(reduce) { %>
-                <option value="<%= reduce %>" <% if (reduce == reduceFunStr) { %>selected<% } %>><%= reduce %></option>
-                <% }) %>
-                <option value="CUSTOM" <% if (isCustomReduce) { %>selected<% } %>>Custom reduce</option>
-              </select>
-              <span class="help-block">Reduce functions are optional.</span>
+            <select id="reduce-function-selector">
+              <option value="" <%= !reduceFunStr ? 'selected="selected"' : '' %>>None</option>
+              <% _.each(["_sum", "_count", "_stats"], function(reduce) { %>
+              <option value="<%= reduce %>" <% if (reduce == reduceFunStr) { %>selected<% } %>><%= reduce %></option>
+              <% }) %>
+              <option value="CUSTOM" <% if (isCustomReduce) { %>selected<% } %>>Custom reduce</option>
+            </select>
+            <span class="help-block">Reduce functions are optional.</span>
           </div>
 
 
           <div class="control-group reduce-function">
             <label for="reduce-function">Custom Reduce</label>
-              <% if (newView) { %>
-              <textarea class="js-editor" id="reduce-function"><%= langTemplates.reduce %></textarea>
-              <% } else { %>
-              <textarea class="js-editor" id="reduce-function"><%= ddoc.get('views')[viewName].reduce %></textarea>
-              <% } %>
+            <% if (newView) { %>
+            <textarea class="js-editor" id="reduce-function"><%= langTemplates.reduce %></textarea>
+            <% } else { %>
+            <textarea class="js-editor" id="reduce-function"><%= ddoc.get('views')[viewName].reduce %></textarea>
+            <% } %>
           </div>
 
           <div class="control-group">
-              <button class="button green save fonticon-circle-check">Save</button>
-              <% if (!this.newView) { %>
-              <button class="button cancel-button outlineGray fonticon-circle-x">Delete</button>
-              <% } %>
+            <button class="button green save fonticon-circle-check">Save</button>
+            <% if (!this.newView) { %>
+            <button class="button cancel-button outlineGray fonticon-circle-x">Delete</button>
+            <% } %>
           </div>
           <div class="clearfix"></div>
         </form>
@@ -102,85 +102,6 @@ the License.
       <div id="ddoc-info" class="well"> </div>
     </div>
     <div class="tab-pane" id="query">
-      <div class="advanced-options well">
-        <div class="errors-container"></div>
-        <form class="view-query-update custom-inputs">
-          <div class="controls-group">
-            <div class="row-fluid">
-              <div class="controls controls-row">
-                <input name="key" class="span6" type="text" placeholder="Key">
-                <input name="keys" class="span6" type="text" placeholder="Keys">
-              </div>
-            </div>
-            <div class="row-fluid">
-              <div class="controls controls-row">
-                <input name="startkey" class="span6" type="text" placeholder="Start Key">
-                <input name="endkey" class="span6" type="text" placeholder="End Key">
-              </div>
-            </div>
-          </div>
-          <div class="controls-group">
-            <div class="row-fluid">
-              <div class="controls controls-row">
-                <div class="checkbox inline">  
-                  <input id="check1" type="checkbox" name="include_docs" value="true">  
-                  <label name="include_docs" for="check1">Include Docs</label>  
-                  <% if (hasReduce) { %>
-                  <input id="check2" name="reduce" type="checkbox" value="true">
-                  <label for="check2">Reduce</label>  
-                </div> 
-                <label id="select1" class="drop-down inline">
-                  Group Level:
-                  <select id="select1" disabled name="group_level" class="input-small">
-                    <option value="0">None</option>
-                    <option value="1">1</option>
-                    <option value="2">2</option>
-                    <option value="3">3</option>
-                    <option value="4">4</option>
-                    <option value="5">5</option>
-                    <option value="6">6</option>
-                    <option value="7">7</option>
-                    <option value="8">8</option>
-                    <option value="9">9</option>
-                    <option value="999" selected="selected">exact</option>
-                  </select>
-                </label>
-                <% } %>
-                <div class="checkbox inline">  
-                  <input id="check3" name="stale" type="checkbox" value="ok">
-                  <label for="check3">Stale</label>
-                  <input id="check4" name="descending" type="checkbox" value="true">  
-                  <label for="check4">Descending</label>  
-                </div> 
-                <label class="drop-down inline">
-                  Limit:
-                  <select name="limit" class="input-small">
-                    <option>5</option>
-                    <option selected="selected">10</option>
-                    <option>25</option>
-                    <option>50</option>
-                    <option>100</option>
-                  </select>
-                </label>
-                <div class="checkbox inline">  
-                  <input id="check5" name="inclusive_end" type="checkbox" value="false">
-                  <label for="check5">Disable Inclusive End</label>
-                  <input id="check6" name="update_seq" type="checkbox" value="true">  
-                  <label for="check6">Descending</label>  
-                </div>
-              </div>
-            </div>
-          </div>
-          <div class="controls-group">
-            <div class="row-fluid">
-              <div class="controls controls-row">
-                <button type="submit" class="btn btn-primary btn-large">Query</button>
-                <button class="btn btn-info btn-large preview">Preview</button>
-              </div>
-            </div>
-          </div>
-        </form>
-      </div>
     </div>
   </div>
 </div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bcb4fba3/src/fauxton/assets/less/fauxton.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/fauxton.less b/src/fauxton/assets/less/fauxton.less
index 42b7836..56d1453 100644
--- a/src/fauxton/assets/less/fauxton.less
+++ b/src/fauxton/assets/less/fauxton.less
@@ -519,6 +519,10 @@ footer#mainFooter{
   padding: 0 20px;
 }
 
+.db-views-smaller {
+  max-width: 500px;
+}
+
 .nav-tabs > li{
   margin-right: 2px;
   > a {
@@ -969,6 +973,8 @@ div.spinner {
 #jump-to-doc {
   width: 88%;
   max-width: 600px;
+  float:right;
+  margin-right: 40px;
 
   #jump-to-doc-label {
     width: 100%;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/bcb4fba3/src/fauxton/test/core/routeObjectSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/test/core/routeObjectSpec.js b/src/fauxton/test/core/routeObjectSpec.js
index d043d63..987d5b7 100644
--- a/src/fauxton/test/core/routeObjectSpec.js
+++ b/src/fauxton/test/core/routeObjectSpec.js
@@ -27,6 +27,8 @@ define([
         });
 
         testRouteObject = new TestRouteObject();
+        var apiBar = {};
+        apiBar.hide = sinon.spy();
 
         // Need to find a better way of doing this
         mockLayout = {
@@ -35,7 +37,8 @@ define([
           setView: sinon.spy(),
           renderView: sinon.spy(),
           hooks: [],
-          setBreadcrumbs: sinon.spy()
+          setBreadcrumbs: sinon.spy(),
+          apiBar: apiBar
         };
 
       });