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/05/23 17:42:28 UTC

[06/10] git commit: updated refs/heads/fauxton-view-improvements to 2171e16

update document list with route events from save and view query


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

Branch: refs/heads/fauxton-view-improvements
Commit: 642343c5ffa4c00521507a780535c42eb8c5c46d
Parents: 1e4949b
Author: Garren Smith <ga...@gmail.com>
Authored: Tue May 21 15:38:45 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Thu May 23 10:26:44 2013 +0200

----------------------------------------------------------------------
 src/fauxton/app/modules/documents/resources.js     |    2 +-
 src/fauxton/app/modules/documents/routes.js        |   43 ++-
 src/fauxton/app/modules/documents/views.js         |  360 ++++++---------
 .../app/templates/documents/all_docs_list.html     |   87 ----
 .../app/templates/documents/view_editor.html       |  229 +++++++---
 .../app/templates/layouts/with_tabs_sidebar.html   |    5 +-
 6 files changed, 345 insertions(+), 381 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/642343c5/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 2bd6ddf..4a2a280 100644
--- a/src/fauxton/app/modules/documents/resources.js
+++ b/src/fauxton/app/modules/documents/resources.js
@@ -242,7 +242,7 @@ function(app, FauxtonAPI) {
     initialize: function(_models, options) {
       this.database = options.database;
       this.view = options.view;
-      this.design = options.design;
+      this.design = options.design.replace('_design/','');
       this.params = _.extend({limit: 10, reduce: false}, options.params);
       this.idxType = "_view";
     },

http://git-wip-us.apache.org/repos/asf/couchdb/blob/642343c5/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 fc2a330..1facb3b 100644
--- a/src/fauxton/app/modules/documents/routes.js
+++ b/src/fauxton/app/modules/documents/routes.js
@@ -180,6 +180,10 @@ function(app, FauxtonAPI, Documents, Databases) {
       "database/:database/new_view": "newViewEditor"
     },
 
+    events: {
+      "route:updateAllDocs": "updateAllDocsFromView"
+    },
+
     initialize: function (route, masterLayout, options) {
       var docOptions = app.getParams();
       docOptions.include_docs = true;
@@ -207,6 +211,9 @@ function(app, FauxtonAPI, Documents, Databases) {
       }));
     },
 
+    establish: function () {
+      return this.data.designDocs.fetch();
+    },
 
     allDocs: function(databaseName, options) {
       var docOptions = app.getParams(options);
@@ -220,7 +227,10 @@ function(app, FauxtonAPI, Documents, Databases) {
         this.sidebar.setSelectedTab('all-docs');
       }
 
-      this.documentsView = this.setView("#dashboard-content", new Documents.Views.AllDocsList({
+      // TODO must be a better way
+      if (this.viewEditor) { this.viewEditor.remove(); }
+
+      this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
         collection: this.data.database.allDocs
       }));
 
@@ -250,13 +260,22 @@ function(app, FauxtonAPI, Documents, Databases) {
         designDocs: this.data.designDocs
       };
 
-      this.setView("#dashboard-content", new Documents.Views.AllDocsList({
+      this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.ViewEditor({
+        model: this.data.database,
+        ddocs: this.data.designDocs,
+        viewCollection: this.data.indexedDocs,
+        viewName: view,
+        params: params,
+        newView: false,
+        ddocInfo: ddocInfo
+      }));
+
+      this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
         database: this.data.database,
         collection: this.data.indexedDocs,
         nestedView: Documents.Views.Row,
         viewList: true,
-        ddocInfo: ddocInfo,
-        params: params
+        ddocInfo: ddocInfo
       }));
 
       this.sidebar.setSelectedTab(ddoc + '_' + view);
@@ -288,6 +307,22 @@ function(app, FauxtonAPI, Documents, Databases) {
       }));
 
       this.sidebar.setSelectedTab('new-view');
+    },
+
+    updateAllDocsFromView: function (event) {
+      var view = event.view,
+          ddoc = event.ddoc;
+
+       console.log('updae', event);
+      this.data.indexedDocs = new Documents.IndexCollection(null, {
+        database: this.data.database,
+        design: ddoc,
+        view: view,
+        params: app.getParams()
+      });
+
+      this.documentsView.collection = this.data.indexedDocs;
+      this.documentsView.forceRender();
     }
   });
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/642343c5/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 f5219e8..c267f31 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -279,17 +279,13 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
     template: "templates/documents/all_docs_list",
     events: {
       "click button.all": "selectAll",
-      "click button.bulk-delete": "bulkDelete",
-      "change form.view-query-update input": "updateFilters",
-      "change form.view-query-update select": "updateFilters",
-      "submit form.view-query-update": "updateView"
+      "click button.bulk-delete": "bulkDelete"
     },
 
     initialize: function(options){
       this.nestedView = options.nestedView || Views.Document;
       this.rows = {};
       this.viewList = !! options.viewList;
-      this.params = options.params;
       this.database = options.database;
       if (options.ddocInfo) {
         this.designDocs = options.ddocInfo.designDocs;
@@ -298,171 +294,22 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
     },
 
     establish: function() {
-      var deferreds = [
-        this.collection.fetch().error(function() {
-          // TODO: handle error requests that slip through
-          // This should just throw a notification, not break the page
-          console.log("ERROR: ", arguments);
-        })
-      ];
-      if (this.designDocs) {
-        deferreds.push(this.designDocs.fetch());
-      }
-      return deferreds;
+      return this.collection.fetch().error(function() {
+        // TODO: handle error requests that slip through
+        // This should just throw a notification, not break the page
+        console.log("ERROR: ", arguments);
+      });
     },
 
     selectAll: function(evt){
       $("input:checkbox").attr('checked', !$(evt.target).hasClass('active'));
     },
 
-    // TODO:: HACK::
-    // Hack to grab info about the ddoc and current view to determine whether
-    // or not the view has a reduce function so we can display the advanced
-    // options appropriately.
-    //
-    // NOTE: we have this here temporarily because we have to wait for the
-    // design docs to be present.
-    //
-    // NOTE: We should probably refactor this View out into a separate View
-    // dedicated to displaying view query results.
-    // If nothing else, we should at least switch to something along the lines
-    // of fetchOnce to ensure we're not reloading the ddocs here in addition to
-    // the sidebar.
-    setDdocInfo: function() {
-      if (!this.ddoc && this.designDocs) {
-        this.ddoc = this.designDocs.get(this.ddocID);
-      }
-    },
-
     serialize: function() {
-      this.setDdocInfo();
-      var data = {
+      return {
         database: this.collection,
-        viewList: this.viewList,
-        hasReduce: false,
-        params: this.params,
-        ddocs: this.designDocs
+        viewList: this.viewList
       };
-      if (this.ddoc) {
-        data.ddoc = this.ddoc;
-        data.hasReduce = this.ddoc.viewHasReduce(this.collection.view);
-        this.view = this.collection.view;
-      }
-      return data;
-    },
-
-    updateViewOnSave: function(ddoc, view) {
-      this.ddoc = ddoc;
-      this.view = view;
-      this.updateView();
-    },
-
-    updateView: function(event) {
-      var $form;
-
-      if (event && event.preventDefault) { 
-        event.preventDefault();
-        $form = $(event.currentTarget);
-      } else {
-        $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;
-        }
-      });
-
-      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: ".view.show .all-docs-list.errors-container"
-          });
-        });
-
-        FauxtonAPI.addNotification({
-          msg: "Make sure that strings are properly quoted and any other values are valid JSON structures",
-          type: "warning",
-          selector: ".view.show .all-docs-list.errors-container"
-        });
-
-        return false;
-      }
-
-      var fragment = window.location.hash.replace(/\?.*$/, '');
-      fragment = fragment + '?' + $.param(params);
-      FauxtonAPI.navigate(fragment, {trigger: false});
-
-      this.params = app.getParams();
-
-      this.collection = new Documents.IndexCollection(null, {
-        database: this.database,
-        design: this.ddoc.id.replace('_design/',''),
-        view: this.view,
-        params: this.params
-      });
-
-      var that = this;
-      FauxtonAPI.when(this.establish()).then(function () {
-        that.render();
-      });
-
-    },
-
-    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;
-      }
     },
 
     /*
@@ -500,16 +347,6 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
     },
 
     beforeRender: function() {
-      this.setDdocInfo();
-      if (this.viewList) {
-        this.viewEditorView = this.insertView("#edit-index-container", new Views.ViewEditor({
-          model: this.ddoc.dDocModel(),
-          ddocs: this.designDocs,
-          viewCollection: this.collection
-        }));
-
-        this.listenTo(this.viewEditorView, 'view_updated', this.updateViewOnSave);
-      }
       this.collection.each(function(doc) {
         this.rows[doc.id] = this.insertView("table.all-docs tbody", new this.nestedView({
           model: doc
@@ -519,34 +356,6 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
 
     afterRender: function(){
       prettyPrint();
-      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);
-      }
     }
   });
 
@@ -680,6 +489,7 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
     }
   });
 
+  //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",
     builtinReduces: ['_sum', '_count', '_stats'],
@@ -687,7 +497,10 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
     events: {
       "click button.save": "saveView",
       "click button.preview": "previewView",
-      "change select#reduce-function-selector": "updateReduce"
+      "change select#reduce-function-selector": "updateReduce",
+      "change form.view-query-update input": "updateFilters",
+      "change form.view-query-update select": "updateFilters",
+      "submit form.view-query-update": "updateView"
     },
 
     langTemplates: {
@@ -702,11 +515,13 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
     initialize: function(options) {
       this.newView = options.newView || false;
       this.ddocs = options.ddocs;
+      this.ddocID = options.ddocInfo.id;
       this.viewCollection = options.viewCollection;
+      this.viewName = options.viewName;
+      this.params = options.params;
       if (this.newView) {
         //TODO: CREATE NEW HERE
       } else {
-        this.reduceFunStr = this.model.viewHasReduce(this.viewCollection.view);
       } 
     },
 
@@ -732,9 +547,94 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
       }
     },
 
-    establish: function() {
-      //return [this.ddocs.fetch(), this.model.fetch()];
-      return [];
+    updateView: function(event) {
+      var $form = $(event.currentTarget);
+
+      event.preventDefault();
+
+      // 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;
+        }
+      });
+
+      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: ".view.show .all-docs-list.errors-container"
+          });
+        });
+
+        FauxtonAPI.addNotification({
+          msg: "Make sure that strings are properly quoted and any other values are valid JSON structures",
+          type: "warning",
+          selector: ".view.show .all-docs-list.errors-container"
+        });
+
+        return false;
+      }
+
+      var fragment = window.location.hash.replace(/\?.*$/, '');
+      fragment = fragment + '?' + $.param(params);
+      FauxtonAPI.navigate(fragment, {trigger: false});
+
+      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) {
@@ -761,10 +661,11 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
       if (this.hasValidCode()) {
         var mapVal = this.mapEditor.getValue(), 
             reduceVal = "",
-            viewName = this.$('#index-name').val(),
+            reduceOption = this.$('#reduce-function-selector :selected').val(),
+            viewName = this.$('#index-name').val();
             ddocName = this.$('#ddoc :selected').val();
 
-         var reduceOption = this.$('#reduce-function-selector :selected').val();
+         this.viewName = viewName;
 
          if (reduceOption === 'CUSTOM') {
             reduceVal = this.reduceEditor.getValue();
@@ -790,7 +691,8 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
             selector: "#define-view .errors-container"
           });
 
-          that.trigger('view_updated', ddoc, viewName);
+          FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: ddocName, view: viewName});
+
         }, function(xhr) {
           var responseText = JSON.parse(xhr.responseText).reason;
           notification = FauxtonAPI.addNotification({
@@ -865,6 +767,7 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
         ddoc: this.model,
         viewCollection: this.viewCollection,
         reduceFunStr: this.reduceFunStr,
+        hasReduce: this.reduceFunStr,
         isCustomReduce: this.hasCustomReduce(),
         newView: this.newView,
         langTemplates: this.langTemplates.javascript
@@ -875,6 +778,11 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
       return this.reduceFunStr && ! _.contains(this.builtinReduces, this.reduceFunStr);
     },
 
+    beforeRender: function () {
+      this.model = this.ddocs.get(this.ddocID).dDocModel();
+      this.reduceFunStr = this.model.viewHasReduce(this.viewCollection.view);
+    },
+
     afterRender: function() {
       var that = this;
       var mapFun = $("#map-function");
@@ -915,6 +823,36 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
       if ( ! this.hasCustomReduce()) {
         $(".control-group.reduce-function").hide();
       }
+
+       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);
+      }
+
     }
   });
 
@@ -931,14 +869,6 @@ function(app, FauxtonAPI, Documents, Codemirror, JSHint) {
       }
     },
 
-    establish: function() {
-      if (this.collection) {
-        return [this.collection.fetch()];
-      } else {
-        return null;
-      }
-    },
-
     serialize: function() {
       return {
         index: [1,2,3],

http://git-wip-us.apache.org/repos/asf/couchdb/blob/642343c5/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 2f63af0..e8f06af 100644
--- a/src/fauxton/app/templates/documents/all_docs_list.html
+++ b/src/fauxton/app/templates/documents/all_docs_list.html
@@ -28,93 +28,6 @@ the License.
     </div>
   <% } %>
 
-  <div class="row">
-    <div class="all-docs-list errors-container"></div>
-    <div id="edit-index-container"></div>
-    <% if (viewList) { %>
-      <div class="accordion" id="advanced-options-accordion">
-        <div class="accordion-group">
-          <div class="accordion-heading">
-            <a class="accordion-toggle" data-bypass="true" data-toggle="collapse" data-parent="#advanced-options-accordion" href="#collapse-advanced-options">
-              <i class="icon-plus"></i> Advanced Options
-            </a>
-          </div>
-          <div id="collapse-advanced-options" class="accordion-body collapse">
-            <div class="accordion-inner">
-              <form class="view-query-update">
-                <div class="controls controls-row">
-                  <label class="span3 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>
-                  <label class="span3 checkbox inline">
-                    <input name="include_docs" type="checkbox" value="true"> Include Docs
-                  </label>
-                  <% if (hasReduce) { %>
-                    <label class="span2 checkbox inline">
-                      <input name="reduce" type="checkbox" value="true"> Reduce
-                    </label>
-                    <label class="span4 inline">
-                      Group Level:
-                      <select 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>
-
-                <div class="controls controls-row">
-                  <input name="key" class="span4" type="text" placeholder="Key">
-                  <input name="keys" class="span8" type="text" placeholder="Keys">
-                </div>
-                <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 class="controls controls-row">
-                  <label class="span2 checkbox inline">
-                    <input name="stale" type="checkbox" value="ok"> Stale
-                  </label>
-                  <label class="span2 checkbox inline">
-                    <input name="descending" type="checkbox" value="true"> Descending
-                  </label>
-                  <label class="span4 checkbox inline">
-                    <input name="inclusive_end" type="checkbox" value="false"> Disable Inclusive End
-                  </label>
-                  <label class="span4 checkbox inline">
-                    <input name="update_seq" type="checkbox" value="true"> Include Update Sequence
-                  </label>
-                </div>
-                <div class="controls controls-row">
-                  <button type="submit" class="btn btn-primary">Query</button>
-                </div>
-              </form>
-
-            </div>
-          </div>
-
-        </div>
-      </div>
-    <% } %>
-  </div>
-
-
   <p>
     Showing 1-<%= database.models.length %> of <%= database.totalRows() %> rows
     <% if (database.updateSeq()) { %>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/642343c5/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 8ee3a4a..59e6551 100644
--- a/src/fauxton/app/templates/documents/view_editor.html
+++ b/src/fauxton/app/templates/documents/view_editor.html
@@ -11,89 +11,172 @@ 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="row">
+  <div class="all-docs-list errors-container"></div>
+  <div id="edit-index-container">
 
-<div class="accordion" id="edit-index-accordion">
-  <div class="accordion-group">
-    <div class="accordion-heading">
-      <a class="accordion-toggle" data-bypass="true" data-toggle="collapse" data-parent="#edit-index-accordion" href="#collapse-edit-index">
-        <i class="icon-wrench"></i> Edit Index
-      </a>
-    </div>
-    <div id="collapse-edit-index" class="accordion-body">
-      <div class="accordion-inner">
-        <div id="define-view" class="ddoc-alert well">
-          <div class="errors-container"></div>
-          <form class="form-horizontal">
-            <h3>Define your index</h3>
-            <div class="control-group">
-              <label class="control-label" for="ddoc">Design document <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs/#design-docs"><i class="icon-question-sign"></i></a></label>
-              <div class="controls">
-                <select id="ddoc">
-                  <optgroup label="Select a document">
-                    <option>New document</option>
-                    <% ddocs.each(function(ddoc) { %>
-                      <% if (ddoc.id == "_design/"+viewCollection.design) { %>
+    <div class="accordion" id="edit-index-accordion">
+      <div class="accordion-group">
+        <div class="accordion-heading">
+          <a class="accordion-toggle" data-bypass="true" data-toggle="collapse" data-parent="#edit-index-accordion" href="#collapse-edit-index">
+            <i class="icon-wrench"></i> Edit Index
+          </a>
+        </div>
+        <div id="collapse-edit-index" class="accordion-body collapse">
+          <div class="accordion-inner">
+            <div id="define-view" class="ddoc-alert well">
+              <div class="errors-container"></div>
+              <form class="form-horizontal">
+                <h3>Define your index</h3>
+                <div class="control-group">
+                  <label class="control-label" for="ddoc">Design document <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs/#design-docs"><i class="icon-question-sign"></i></a></label>
+                  <div class="controls">
+                    <select id="ddoc">
+                      <optgroup label="Select a document">
+                        <option>New document</option>
+                        <% ddocs.each(function(ddoc) { %>
+                        <% if (ddoc.id == "_design/"+viewCollection.design) { %>
                         <option selected="selected"><%= ddoc.id %></option>
-                      <% } else { %>
+                        <% } else { %>
                         <option><%= ddoc.id %></option>
-                      <% } %>
-                    <% }); %>
-                  </optgroup>
-                </select>
-              </div>
-            </div>
-            <div class="control-group">
-              <label class="control-label" for="index-name">Index name <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs/#view-functions"><i class="icon-question-sign"></i></a></label>
-              <div class="controls">
-                <input type="text" id="index-name" value="<%= viewCollection.view %>" placeholder="Index name" />
-              </div>
+                        <% } %>
+                        <% }); %>
+                      </optgroup>
+                    </select>
+                  </div>
+                </div>
+                <div class="control-group">
+                  <label class="control-label" for="index-name">Index name <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs/#view-functions"><i class="icon-question-sign"></i></a></label>
+                  <div class="controls">
+                    <input type="text" id="index-name" value="<%= viewCollection.view %>" placeholder="Index name" />
+                  </div>
+                </div>
+                <div class="control-group">
+                  <label class="control-label" for="map-function">Map function <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs/#map-functions"><i class="icon-question-sign"></i></a></label>
+                  <div class="controls">
+                    <% if (newView) { %>
+                    <textarea class="js-editor" id="map-function"><%= langTemplates.map %></textarea>
+                    <% } else { %>
+                    <textarea class="js-editor" id="map-function"><%= ddoc.get('views')[viewCollection.view].map %></textarea>
+                    <% } %>
+                  </div>
+                </div>
+                <div class="control-group">
+                  <label class="control-label" for="reduce-function-selector">Reduce function <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs.html#reduce-and-rereduce-functions"><i class="icon-question-sign"></i></a></label>
+                  <div class="controls">
+                    <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>
+                <div class="control-group reduce-function">
+                  <label class="control-label" for="reduce-function">Custom Reduce</label>
+                  <div class="controls">
+                    <% if (newView) { %>
+                    <textarea class="js-editor" id="reduce-function"><%= langTemplates.reduce %></textarea>
+                    <% } else { %>
+                    <textarea class="js-editor" id="reduce-function"><%= ddoc.get('views')[viewCollection.view].reduce %></textarea>
+                    <% } %>
+                  </div>
+                </div>
+                <div class="control-group">
+                  <hr />
+                  <div class="controls">
+                    <button class="btn btn-small btn-inverse cancel">Cancel</button>
+                    <button class="btn btn-small btn-info preview">Preview</button>
+                    <button class="btn btn-primary save">Save</button>
+                  </div>
+                </div>
+                <div class="clearfix"></div>
+              </form>
             </div>
-            <div class="control-group">
-              <label class="control-label" for="map-function">Map function <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs/#map-functions"><i class="icon-question-sign"></i></a></label>
-              <div class="controls">
-                <% if (newView) { %>
-                  <textarea class="js-editor" id="map-function"><%= langTemplates.map %></textarea>
-                <% } else { %>
-                  <textarea class="js-editor" id="map-function"><%= ddoc.get('views')[viewCollection.view].map %></textarea>
+          </div>
+        </div>
+
+      </div>
+    </div>
+    <div class="accordion" id="advanced-options-accordion">
+      <div class="accordion-group">
+        <div class="accordion-heading">
+          <a class="accordion-toggle" data-bypass="true" data-toggle="collapse" data-parent="#advanced-options-accordion" href="#collapse-advanced-options">
+            <i class="icon-plus"></i> Advanced Options
+          </a>
+        </div>
+        <div id="collapse-advanced-options" class="accordion-body collapse">
+          <div class="accordion-inner">
+            <form class="view-query-update">
+              <div class="controls controls-row">
+                <label class="span3 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>
+                <label class="span3 checkbox inline">
+                  <input name="include_docs" type="checkbox" value="true"> Include Docs
+                </label>
+                <% if (hasReduce) { %>
+                <label class="span2 checkbox inline">
+                  <input name="reduce" type="checkbox" value="true"> Reduce
+                </label>
+                <label class="span4 inline">
+                  Group Level:
+                  <select 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>
-            </div>
-            <div class="control-group">
-              <label class="control-label" for="reduce-function-selector">Reduce function <a target="_couch_docs" href="http://docs.couchdb.org/en/latest/ddocs.html#reduce-and-rereduce-functions"><i class="icon-question-sign"></i></a></label>
-              <div class="controls">
-                <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 class="controls controls-row">
+                <input name="key" class="span4" type="text" placeholder="Key">
+                <input name="keys" class="span8" type="text" placeholder="Keys">
               </div>
-            </div>
-            <div class="control-group reduce-function">
-              <label class="control-label" for="reduce-function">Custom Reduce</label>
-              <div class="controls">
-                <% if (newView) { %>
-                  <textarea class="js-editor" id="reduce-function"><%= langTemplates.reduce %></textarea>
-                <% } else { %>
-                  <textarea class="js-editor" id="reduce-function"><%= ddoc.get('views')[viewCollection.view].reduce %></textarea>
-                <% } %>
+              <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 class="control-group">
-              <hr />
-              <div class="controls">
-                <button class="btn btn-small btn-inverse cancel">Cancel</button>
-                <button class="btn btn-small btn-info preview">Preview</button>
-                <button class="btn btn-primary save">Save</button>
+              <div class="controls controls-row">
+                <label class="span2 checkbox inline">
+                  <input name="stale" type="checkbox" value="ok"> Stale
+                </label>
+                <label class="span2 checkbox inline">
+                  <input name="descending" type="checkbox" value="true"> Descending
+                </label>
+                <label class="span4 checkbox inline">
+                  <input name="inclusive_end" type="checkbox" value="false"> Disable Inclusive End
+                </label>
+                <label class="span4 checkbox inline">
+                  <input name="update_seq" type="checkbox" value="true"> Include Update Sequence
+                </label>
               </div>
-            </div>
-            <div class="clearfix"></div>
-          </form>
+              <div class="controls controls-row">
+                <button type="submit" class="btn btn-primary">Query</button>
+              </div>
+            </form>
+
+          </div>
         </div>
+
       </div>
     </div>
-
   </div>
-</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/642343c5/src/fauxton/app/templates/layouts/with_tabs_sidebar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/layouts/with_tabs_sidebar.html b/src/fauxton/app/templates/layouts/with_tabs_sidebar.html
index f78832f..0b5f2c7 100644
--- a/src/fauxton/app/templates/layouts/with_tabs_sidebar.html
+++ b/src/fauxton/app/templates/layouts/with_tabs_sidebar.html
@@ -21,7 +21,10 @@ the License.
 
   <div class="row-fluid">
     <div id="sidebar-content" class="sidebar span4"></div>
-    <div id="dashboard-content" class="list span8 pull-right"></div>
+    <div id="dashboard-content" class="list span8 pull-right">
+      <div id="dashboard-upper-content"></div>
+      <div id="dashboard-lower-content"></div>
+    </div>
   </div>
 </div>