couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gar...@apache.org
Subject [2/8] buncha editor stuff making the preview page look less butts. Styling the view form documents This stuff can't be tables. Boo. less for indexes resize stuff And more refactor stuff View editor updates, Splitting out less files An absolute abortion h
Date Tue, 26 Aug 2014 10:41:52 GMT
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/documents/views-index.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/views-index.js b/app/addons/documents/views-index.js
deleted file mode 100644
index d0ed8ed..0000000
--- a/app/addons/documents/views-index.js
+++ /dev/null
@@ -1,574 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-define([
-  "app",
-
-  "api",
-  "addons/fauxton/components",
-
-  "addons/documents/resources",
-  "addons/databases/resources",
-  "addons/pouchdb/base",
-  //views
-  "addons/documents/views-advancedopts",
-  // Libs
-  "addons/fauxton/resizeColumns",
-
-  // Plugins
-  "plugins/beautify",
-  "plugins/prettify"
-],
-
-function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
-         QueryOptions, resizeColumns, beautify, prettify) {
-
-  var Views = {};
-
-  Views.ViewEditor = FauxtonAPI.View.extend({
-    template: "addons/documents/templates/view_editor",
-    builtinReduces: ['_sum', '_count', '_stats'],
-
-    events: {
-      "click button.save": "saveView",
-      "click button.delete": "deleteView",
-      "change select#reduce-function-selector": "updateReduce",
-      "click button.preview": "previewView",
-      "click #db-views-tabs-nav": 'toggleIndexNav',
-      "click .beautify_map":  "beautifyCode",
-      "click .beautify_reduce":  "beautifyCode",
-      "click #query-options-wrapper": 'toggleIndexNav'
-    },
-
-    langTemplates: {
-      "javascript": {
-        map: "function(doc) {\n  emit(doc._id, 1);\n}",
-        reduce: "function(keys, values, rereduce){\n  if (rereduce){\n    return sum(values);\n  } else {\n    return values.length;\n  }\n}"
-      }
-    },
-
-    defaultLang: "javascript",
-
-    initialize: function(options) {
-      this.newView = options.newView || false;
-      this.ddocs = options.ddocs;
-      this.params = options.params;
-      this.database = options.database;
-      this.currentDdoc = options.currentddoc;
-      if (this.newView) {
-        this.viewName = 'newView';
-      } else {
-        this.ddocID = options.ddocInfo.id;
-        this.viewName = options.viewName;
-        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
-      }
-
-      this.showIndex = false;
-      _.bindAll(this);
-    },
-
-    establish: function () {
-      if (this.ddocInfo) {
-        return this.ddocInfo.fetch();
-      }
-    },
-
-    updateValues: function() {
-      var notification;
-      if (this.model.changedAttributes()) {
-        notification = FauxtonAPI.addNotification({
-          msg: "Document saved successfully.",
-          type: "success",
-          clear: true
-        });
-        this.editor.setValue(this.model.prettyJSON());
-      }
-    },
-
-    updateReduce: function(event) {
-      var $ele = $("#reduce-function-selector");
-      var $reduceContainer = $(".control-group.reduce-function");
-      if ($ele.val() == "CUSTOM") {
-        this.createReduceEditor();
-        this.reduceEditor.setValue(this.langTemplates.javascript.reduce);
-        $reduceContainer.show();
-      } else {
-        $reduceContainer.hide();
-      }
-    },
-
-    deleteView: function (event) {
-      event.preventDefault();
-
-      if (this.newView) { return alert('Cannot delete a new view.'); }
-      if (!confirm('Are you sure you want to delete this view?')) {return;}
-
-      var that = this,
-          promise,
-          viewName = this.$('#index-name').val(),
-          ddocName = this.$('#ddoc :selected').val(),
-          ddoc = this.getCurrentDesignDoc();
-
-      ddoc.removeDdocView(viewName);
-
-      if (ddoc.hasViews()) {
-        promise = ddoc.save();
-      } else {
-        promise = ddoc.destroy();
-      }
-
-      promise.then(function () {
-        FauxtonAPI.navigate('/database/' + that.database.safeID() + '/_all_docs?limit=' + Databases.DocLimit);
-        FauxtonAPI.triggerRouteEvent('reloadDesignDocs');
-      });
-    },
-
-    saveView: function(event) {
-      var json, notification,
-      that = this;
-
-      if (event) { event.preventDefault();}
-
-      $('#dashboard-content').scrollTop(0); //scroll up
-
-      if (this.hasValidCode() && this.$('#new-ddoc:visible').val() !=="") {
-        var mapVal = this.mapEditor.getValue(),
-        reduceVal = this.reduceVal(),
-        viewName = this.$('#index-name').val(),
-        ddoc = this.getCurrentDesignDoc(),
-        ddocName = ddoc.id,
-        viewNameChange = false;
-
-        if (this.viewName !== viewName) {
-          ddoc.removeDdocView(this.viewName);
-          this.viewName = viewName;
-          viewNameChange = true;
-        }
-
-        notification = FauxtonAPI.addNotification({
-          msg: "Saving document.",
-          selector: "#define-view .errors-container",
-          clear: true
-        });
-
-        ddoc.setDdocView(viewName, mapVal, reduceVal);
-
-        ddoc.save().then(function () {
-          that.ddocs.add(ddoc);
-
-          that.mapEditor.editSaved();
-          that.reduceEditor && that.reduceEditor.editSaved();
-
-
-          FauxtonAPI.addNotification({
-            msg: "View has been saved.",
-            type: "success",
-            selector: "#define-view .errors-container",
-            clear: true
-          });
-
-          if (that.newView || viewNameChange) {
-            var fragment = '/database/' + that.database.safeID() +'/' + ddoc.safeID() + '/_view/' + app.utils.safeURLName(viewName);
-
-            FauxtonAPI.navigate(fragment, {trigger: false});
-            that.newView = false;
-            that.ddocID = ddoc.safeID();
-            that.viewName = viewName;
-            that.ddocInfo = ddoc;
-            that.showIndex = true;
-            that.render();
-            FauxtonAPI.triggerRouteEvent('reloadDesignDocs', {
-              selectedTab: app.utils.removeSpecialCharacters(ddocName.replace(/_design\//,'')) + '_' + app.utils.removeSpecialCharacters(viewName)
-            });
-          }
-
-          if (that.reduceFunStr !== reduceVal) {
-            that.reduceFunStr = reduceVal;
-            that.advancedOptions.renderOnUpdatehasReduce(that.hasReduce());
-          }
-
-          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 {
-        var errormessage = (this.$('#new-ddoc:visible').val() ==="")?"Enter a design doc name":"Please fix the Javascript errors and try again.";
-        notification = FauxtonAPI.addNotification({
-          msg: errormessage,
-          type: "error",
-          selector: "#define-view .errors-container",
-          clear: true
-        });
-      }
-    },
-
-    updateView: function(event, paramInfo) {
-       event.preventDefault();
-
-       if (this.newView) { return alert('Please save this new view before querying it.'); }
-
-       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",
-             clear: true
-           });
-         });
-         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",
-           clear: true
-         });
-
-         return false;
-      }
-
-       var fragment = window.location.hash.replace(/\?.*$/, '');
-       if (!_.isEmpty(params)) {
-        fragment = fragment + '?' + $.param(params);
-       }
-
-       FauxtonAPI.navigate(fragment, {trigger: false});
-       FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
-    },
-
-
-    previewView: function(event, paramsInfo) {
-      event.preventDefault();
-      var that = this,
-      mapVal = this.mapVal(),
-      reduceVal = this.reduceVal(),
-      paramsArr = [];
-
-      if (paramsInfo && paramsInfo.params) {
-        paramsArr = paramsInfo.params;
-      }
-
-      var params = _.reduce(paramsArr, function (params, param) {
-        params[param.name] = param.value;
-        return params;
-      }, {reduce: false});
-
-      FauxtonAPI.addNotification({
-        msg: "<strong>Warning!</strong> Preview executes the Map/Reduce functions in your browser, and may behave differently from CouchDB.",
-        type: "warning",
-        selector: ".advanced-options .errors-container",
-        fade: true,
-        escape: false // beware of possible XSS when the message changes
-      });
-
-      var promise = FauxtonAPI.Deferred();
-
-      if (!this.database.allDocs || this.database.allDocs.params.include_docs !== true) {
-        this.database.buildAllDocs({limit: Databases.DocLimit.toString(), include_docs: true});
-        promise = this.database.allDocs.fetch();
-       } else {
-        promise.resolve();
-       }
-
-      promise.then(function () {
-        params.docs = that.database.allDocs.map(function (model) { return model.get('doc');});
-        var queryPromise = pouchdb.runViewQuery({map: mapVal, reduce: reduceVal}, params);
-        queryPromise.then(function (results) {
-          FauxtonAPI.triggerRouteEvent('updatePreviewDocs', {rows: results.rows, ddoc: that.getCurrentDesignDoc().id, view: that.viewName});
-        });
-      });
-    },
-
-    getCurrentDesignDoc: function () {
-      return this.designDocSelector.getCurrentDesignDoc();
-    },
-
-    isCustomReduceEnabled: function() {
-      return $("#reduce-function-selector").val() == "CUSTOM";
-    },
-
-    mapVal: function () {
-      if (this.mapEditor) {
-        return this.mapEditor.getValue();
-      }
-
-      return this.$('#map-function').text();
-    },
-
-    reduceVal: function() {
-      var reduceOption = this.$('#reduce-function-selector :selected').val(),
-      reduceVal = "";
-
-      if (reduceOption === 'CUSTOM') {
-        if (!this.reduceEditor) { this.createReduceEditor(); }
-        reduceVal = this.reduceEditor.getValue();
-      } else if ( reduceOption !== 'NONE') {
-        reduceVal = reduceOption;
-      }
-
-      return reduceVal;
-    },
-
-
-    hasValidCode: function() {
-      return _.every(["mapEditor", "reduceEditor"], function(editorName) {
-        var editor = this[editorName];
-        if (editorName === "reduceEditor" && ! this.isCustomReduceEnabled()) {
-          return true;
-        }
-        return editor.hadValidCode();
-      }, this);
-    },
-
-    toggleIndexNav: function (event) {
-      $('#dashboard-content').scrollTop(0); //scroll up
-
-      var $targetId = this.$(event.target).attr('id'),
-          $previousTab = this.$(this.$('li.active a').attr('href')),
-          $targetTab = this.$(this.$(event.target).attr('href'));
-
-      if ($targetTab.attr('id') !== $previousTab.attr('id')) {
-        $previousTab.removeAttr('style');
-      }
-
-      if ($targetId === 'index-nav') {
-        if (this.newView) { return; }
-        var that = this;
-        $('#dashboard-content').scrollTop(0); //scroll up
-        $targetTab.toggle('slow', function(){
-           that.showEditors();
-        });
-      } else {
-        $targetTab.toggle('slow');
-      }
-    },
-
-    serialize: function() {
-      return {
-        ddocs: this.ddocs,
-        ddoc: this.model,
-        ddocName: this.model.id,
-        viewName: this.viewName,
-        reduceFunStr: this.reduceFunStr,
-        isCustomReduce: this.hasCustomReduce(),
-        newView: this.newView,
-        langTemplates: this.langTemplates.javascript
-      };
-    },
-
-    hasCustomReduce: function() {
-      return this.reduceFunStr && ! _.contains(this.builtinReduces, this.reduceFunStr);
-    },
-
-    hasReduce: function () {
-      return this.reduceFunStr || false;
-    },
-
-    createReduceEditor: function () {
-      if (this.reduceEditor) {
-        this.reduceEditor.remove();
-      }
-
-      this.reduceEditor = new Components.Editor({
-        editorId: "reduce-function",
-        mode: "javascript",
-        couchJSHINT: true
-      });
-      this.reduceEditor.render();
-
-      if (this.reduceEditor.getLines() === 1){
-        this.$('.beautify_reduce').removeClass("hide");
-        $('.beautify-tooltip').tooltip();
-      }
-    },
-    beforeRender: function () {
-
-      if (this.newView) {
-        this.reduceFunStr = '';
-        if (this.ddocs.length === 0) {
-          this.model = new Documents.Doc(null, {database: this.database});
-        } else {
-          this.model = this.ddocs.first().dDocModel();
-        }
-        this.ddocID = this.model.id;
-      } else {
-        var ddocDecode = decodeURIComponent(this.ddocID);
-        this.model = this.ddocs.get(this.ddocID).dDocModel();
-        this.reduceFunStr = this.model.viewHasReduce(this.viewName);
-      }
-
-      var viewFilters = FauxtonAPI.getExtensions('sidebar:viewFilters'),
-          filteredModels = this.ddocs.models,
-          designDocs = this.ddocs.clone();
-
-      if (!_.isEmpty(viewFilters)) {
-        _.each(viewFilters, function (filter) {
-          filteredModels = _.filter(filteredModels, filter);
-        });
-        designDocs.reset(filteredModels, {silent: true});
-      }
-
-      this.designDocSelector = this.setView('.design-doc-group', new Views.DesignDocSelector({
-        collection: designDocs,
-        ddocName: this.currentDdoc || this.model.id,
-        database: this.database
-      }));
-
-      if (!this.newView) {
-        this.eventer = _.extend({}, Backbone.Events);
-
-        this.advancedOptions = this.insertView('#query', new QueryOptions.AdvancedOptions({
-          updateViewFn: this.updateView,
-          previewFn: this.previewView,
-          database: this.database,
-          viewName: this.viewName,
-          ddocName: this.model.id,
-          hasReduce: this.hasReduce(),
-          eventer: this.eventer,
-          showStale: true
-        }));
-      }
-
-    },
-
-    afterRender: function() {
-
-      if (this.params && !this.newView) {
-        this.advancedOptions.updateFromParams(this.params);
-      }
-
-      this.designDocSelector.updateDesignDoc();
-      if (this.newView || this.showIndex) {
-        this.showEditors();
-        this.showIndex = false;
-      } else {
-        this.$('#index').hide();
-        this.$('#index-nav').parent().removeClass('active');
-      }
-
-    },
-
-    showEditors: function () {
-      this.mapEditor = new Components.Editor({
-        editorId: "map-function",
-        mode: "javascript",
-        couchJSHINT: true
-      });
-      this.mapEditor.render();
-
-      if (this.hasCustomReduce()) {
-        this.createReduceEditor();
-      } else {
-        $(".control-group.reduce-function").hide();
-      }
-
-      if (this.newView) {
-        this.mapEditor.setValue(this.langTemplates[this.defaultLang].map);
-        //Use a built in view by default
-        //this.reduceEditor.setValue(this.langTemplates[this.defaultLang].reduce);
-      }
-
-      this.mapEditor.editSaved();
-      this.reduceEditor && this.reduceEditor.editSaved();
-
-      if (this.mapEditor.getLines() === 1){
-        this.$('.beautify_map').removeClass("hide");
-        $('.beautify-tooltip').tooltip();
-      }
-    },
-    beautifyCode: function(e){
-      e.preventDefault();
-      var targetEditor = $(e.currentTarget).hasClass('beautify_reduce')?this.reduceEditor:this.mapEditor;
-      var beautifiedCode = beautify(targetEditor.getValue());
-      targetEditor.setValue(beautifiedCode);
-    },
-    cleanup: function () {
-      this.mapEditor && this.mapEditor.remove();
-      this.reduceEditor && this.reduceEditor.remove();
-    }
-  });
-
-  Views.DesignDocSelector = FauxtonAPI.View.extend({
-    template: "addons/documents/templates/design_doc_selector",
-
-    events: {
-      "change select#ddoc": "updateDesignDoc"
-    },
-
-    initialize: function (options) {
-      this.ddocName = options.ddocName;
-      this.database = options.database;
-      this.listenTo(this.collection, 'add', this.ddocAdded);
-      this.DocModel = options.DocModel || Documents.Doc;
-    },
-
-    ddocAdded: function (ddoc) {
-      this.ddocName = ddoc.id;
-      this.render();
-    },
-
-    serialize: function () {
-      return {
-        ddocName: this.ddocName,
-        ddocs: this.collection
-      };
-    },
-
-    updateDesignDoc: function () {
-      if (this.newDesignDoc()) {
-        this.$('#new-ddoc-section').show();
-      } else {
-        this.$('#new-ddoc-section').hide();
-      }
-    },
-
-    newDesignDoc: function () {
-
-      return this.$('#ddoc').val() === 'new-doc';
-    },
-
-    newDocValidation: function(){
-      return this.newDesignDoc() && this.$('#new-ddoc').val()==="";
-    },
-    getCurrentDesignDoc: function () {
-      if (this.newDesignDoc()) {
-        var doc = {
-          _id: '_design/' + this.$('#new-ddoc').val(),
-          views: {},
-          language: "javascript"
-        };
-        var ddoc = new this.DocModel(doc, {database: this.database});
-        //this.collection.add(ddoc);
-        return ddoc;
-      } else if ( !this.newDesignDoc() ) {
-        var ddocName = this.$('#ddoc').val();
-        return this.collection.find(function (ddoc) {
-          return ddoc.id === ddocName;
-        }).dDocModel();
-      }
-    }
-  });
-
-  return Views;
-});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/documents/views-sidebar.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/views-sidebar.js b/app/addons/documents/views-sidebar.js
index 9f8c0ee..1d746ce 100644
--- a/app/addons/documents/views-sidebar.js
+++ b/app/addons/documents/views-sidebar.js
@@ -151,8 +151,13 @@ function(app, FauxtonAPI, Components, Documents, Databases) {
     toggleArrow:  function(e){
       this.$(e.currentTarget).toggleClass("down");
     },
+    buildIndexList: function(collection, selector, ddocType){
+    buildIndexList: function(collection, indexType){
     buildIndexList: function(collection, info){
       var design = this.model.id.replace(/^_design\//,"");
+      var selector = indexType.selector;
+      var ddocType = indexType.ddocType;
+      var icon = indexType.icon;
 
       this.insertView(".accordion-body", new Views.IndexItem({
         selector: info.selector,
@@ -176,14 +181,14 @@ function(app, FauxtonAPI, Components, Documents, Databases) {
 
     getSidebarLinks: function () {
       var ddocName = this.model.id.replace(/^_design\//,""),
-          docSafe = app.utils.safeURLName(ddocName), 
+          docSafe = app.utils.safeURLName(ddocName),
           database = this.collection.database;
 
       return _.reduce(FauxtonAPI.getExtensions('sidebar:links'), function (menuLinks, link) {
 
         menuLinks.push({
           title: link.title,
-          url: "#" + database.url('app') + "/" + link.url + "/" + docSafe,
+          url: "#" + database.url('app')+ "/" + link.url + "/" + docSafe,
           icon: 'fonticon-plus-circled'
         });
 
@@ -228,6 +233,7 @@ function(app, FauxtonAPI, Components, Documents, Databases) {
     }
   });
 
+  //Sidebar Index Item
   Views.IndexItem = FauxtonAPI.View.extend({
     template: "addons/documents/templates/index_menu_item",
     tagName: 'li',
@@ -248,7 +254,7 @@ function(app, FauxtonAPI, Components, Documents, Databases) {
 
     serialize: function() {
       return {
-        icon: this.icons[this.ddocType],
+        icon:  this.icons[this.ddocType],
         ddocType:  this.selector,
         name: this.name,
         index: this.index,
@@ -258,7 +264,6 @@ function(app, FauxtonAPI, Components, Documents, Databases) {
         collection: this.collection
       };
     },
-
     afterRender: function() {
       if (this.selected) {
         $(".sidenav ul.nav-list li").removeClass("active");
@@ -267,6 +272,8 @@ function(app, FauxtonAPI, Components, Documents, Databases) {
     }
   });
 
+
+
   return Views;
 });
 

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/views.js b/app/addons/documents/views.js
index 7085bd8..16a853a 100644
--- a/app/addons/documents/views.js
+++ b/app/addons/documents/views.js
@@ -38,6 +38,163 @@ function(app, FauxtonAPI, Components, Documents, Databases, Views, QueryOptions,
     });
   }
 
+  //Header for alldocs with search, Query options,& api bar
+  Views.RightAllDocsHeader = FauxtonAPI.View.extend({
+    className: "header-right",
+    template: "addons/documents/templates/header_alldocs",
+    events: {
+      'select .selectAllDocs': 'selectAllDocs'
+    },
+    initialize: function(options){
+      //adding the database to the object
+      this.database = options.database;
+    },
+    selectAllDocs: function(){
+      //trigger event to select all in other view
+    },
+    updateApiUrl: function(api){
+      //this will update the api bar when the route changes
+      //you can find the method that updates it in components.js Components.ApiBar()
+      this.apiBar && this.apiBar.update(api);
+    },
+    serialize: function() {
+      //basically if you want something in a template, You can define it here
+      return {
+        database: this.database.get('id')
+      };
+    },
+    beforeRender:function(){
+      //insert DB search dropdown
+
+      //insert top create level dropdown with gear icon
+
+      //search docs
+      this.setView("#header-search", new Views.JumpToDoc({
+        database: this.database,
+        collection: this.database.allDocs
+      }));
+
+      //insert queryoptions
+      //that file is included in require() above and the argument is QueryOptions
+      // and it wants all these params:
+      /* Sooooo I searched this file for where Advanced options was originally inserted to see what the hell
+         is happening.  and it's in AllDocsLayout.  So I'm going to move some of those functions over here
+
+        These are required:
+        this.database = options.database;
+        this.updateViewFn = options.updateViewFn;
+        this.previewFn = options.previewFn;
+
+        these are booleans:
+        this.showStale = _.isUndefined(options.showStale) ? false : options.showStale;
+        this.hasReduce = _.isUndefined(options.hasReduce) ? true : options.hasReduce;
+
+        these you only need for view indexes, not all docs because they are about
+        specific views and design docs (ddocs, also views live inside a ddoc):
+        this.viewName = options.viewName;
+        this.ddocName = options.ddocName;
+      */
+      this.setView("#query-options", new QueryOptions.AdvancedOptions({
+        updateViewFn: this.updateAllDocs,
+        previewFn: this.previewView,
+        database: this.database,
+        hasReduce: false,
+        showPreview: false,
+      }));
+
+      //Moved the apibar view into the components file so you can include it in your views
+      this.apiBar = this.insertView("#header-api-bar", new Components.ApiBar({}));
+
+    },
+    //moved from alldocs layout
+    updateAllDocs: 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",
+            clear:  true
+          });
+        });
+        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",
+          clear:  true
+        });
+
+        return false;
+      }
+
+      var fragment = window.location.hash.replace(/\?.*$/, '');
+
+      if (!_.isEmpty(params)) {
+        fragment = fragment + '?' + $.param(params);
+      }
+
+      FauxtonAPI.navigate(fragment, {trigger: false});
+      FauxtonAPI.triggerRouteEvent('updateAllDocs', {allDocs: true});
+    },
+    previewView: function (event) {
+      event.preventDefault();
+    }
+  });
+
+
+  //header that shows up when a doc is selected
+  // when a Doc is selected, trigger a routeEvent to render this
+  // the routeEvent will determine which header to show (??)
+  Views.DocEditHeader = FauxtonAPI.View.extend({
+    template: "addons/documents/templates/header_doc_edit",
+    events: {
+      'select .selectAllDocs': 'selectAllDocs'
+    },
+    initialize: function(options){
+
+    },
+    selectAllDocs: function(){
+      //trigger event to select all in other view
+    },
+    afterRender:function(){
+      //insert DB search dropdown
+
+      //insert top create level dropdown with gear icon
+    }
+  });
+
+  Views.DocsHeader = FauxtonAPI.View.extend({
+    template: "addons/documents/templates/header_selecteddoc",
+    events: {
+      'select .selectAllDocs': 'selectAllDocs'
+    },
+    initialize: function(options){
+
+    },
+    selectAllDocs: function(){
+      //trigger event to select all in other view
+    },
+    afterRender:function(){
+      //insert DB search dropdown
+
+      //insert top create level dropdown with gear icon
+
+      //search docs
+
+      //insert queryoptions
+
+    }
+  });
+
 
   Views.DeleteDBModal = Components.ModalView.extend({
     template: "addons/documents/templates/delete_database_modal",
@@ -83,11 +240,10 @@ function(app, FauxtonAPI, Components, Documents, Databases, Views, QueryOptions,
 
   Views.Document = FauxtonAPI.View.extend({
     template: "addons/documents/templates/all_docs_item",
-    tagName: "tr",
-    className: "all-docs-item",
-
+    className: "all-docs-item doc-row",
     initialize: function (options) {
       this.checked = options.checked;
+      this.expanded = options.expanded;
     },
 
     events: {
@@ -103,6 +259,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, Views, QueryOptions,
 
     serialize: function() {
       return {
+        expanded: this.expanded,
+        docID: this.model.get('_id'),
         doc: this.model,
         checked: this.checked
       };
@@ -148,27 +306,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, Views, QueryOptions,
     }
   });
 
-  Views.Row = FauxtonAPI.View.extend({
-    template: "addons/documents/templates/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,
-        url: this.model.url('app')
-      };
-    }
-  });
 
 
   Views.AllDocsNumber = FauxtonAPI.View.extend({
@@ -232,88 +369,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, Views, QueryOptions,
 
   });
 
-  Views.AllDocsLayout = FauxtonAPI.View.extend({
-    template: "addons/documents/templates/all_docs_layout",
-
-    initialize: function (options) {
-      this.database = options.database;
-      this.params = options.params;
-    },
-
-    events: {
-      'click #toggle-query': "toggleQuery"
-    },
-
-    toggleQuery: function (event) {
-      $('#dashboard-content').scrollTop(0);
-      this.$('#query').toggle('slow');
-    },
-
-    beforeRender: function () {
-      this.advancedOptions = this.insertView('#query', new QueryOptions.AdvancedOptions({
-        updateViewFn: this.updateAllDocs,
-        previewFn: this.previewView,
-        hasReduce: false,
-        showPreview: false,
-        database: this.database,
-      }));
-
-      this.toolsView = this.setView(".js-search", new Views.JumpToDoc({
-        database: this.database,
-        collection: this.database.allDocs
-      }));
-    },
-
-    afterRender: function () {
-      if (this.params) {
-        this.advancedOptions.updateFromParams(this.params);
-      }
-    },
-
-    updateAllDocs: 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",
-            clear:  true
-          });
-        });
-        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",
-          clear:  true
-        });
-
-        return false;
-      }
-
-      var fragment = window.location.hash.replace(/\?.*$/, '');
-
-      if (!_.isEmpty(params)) {
-        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({
@@ -378,12 +433,12 @@ function(app, FauxtonAPI, Components, Documents, Databases, Views, QueryOptions,
     },
 
     toggleDocument: function (event) {
-      var $row = this.$(event.target).closest('tr'),
+      var $row = this.$(event.target).closest('.doc-row'),
           docId = $row.attr('data-id'),
           rev = this.collection.get(docId).get('_rev'),
           data = {_id: docId, _rev: rev, _deleted: true};
 
-      if (!$row.hasClass('js-to-delete')) {
+      if (!$row.hasClass('js-to-delete')) {
         this.bulkDeleteDocsCollection.add(data);
       } else {
         this.bulkDeleteDocsCollection.remove(this.bulkDeleteDocsCollection.get(docId));
@@ -535,8 +590,9 @@ function(app, FauxtonAPI, Components, Documents, Databases, Views, QueryOptions,
         if (this.bulkDeleteDocsCollection) {
           isChecked = this.bulkDeleteDocsCollection.get(doc.id);
         }
-        this.rows[doc.id] = this.insertView("table.all-docs tbody", new this.nestedView({
+        this.rows[doc.id] = this.insertView("#doc-list", new this.nestedView({
           model: doc,
+          expanded: this.expandDocs,
           checked: isChecked
         }));
       }, this);
@@ -569,8 +625,11 @@ function(app, FauxtonAPI, Components, Documents, Databases, Views, QueryOptions,
       }
 
       this.toggleTrash();
+      this.setPaginationWidth();
+    },
+    setPaginationWidth: function(){
+      this.$('#documents-pagination').css('width', this.$el.outerWidth());
     },
-
     perPage: function () {
       return this.allDocsNumber.perPage();
     }

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/fauxton/base.js
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/base.js b/app/addons/fauxton/base.js
index 8b88d36..68ee7cd 100644
--- a/app/addons/fauxton/base.js
+++ b/app/addons/fauxton/base.js
@@ -14,11 +14,10 @@ define([
   "app",
   "api",
   "addons/fauxton/resizeColumns",
-  "addons/fauxton/components",
-  "plugins/zeroclipboard/ZeroClipboard"
+  "addons/fauxton/components"
 ],
 
-function(app, FauxtonAPI, resizeColumns, Components, ZeroClipboard) {
+function(app, FauxtonAPI, resizeColumns, Components) {
 
   var Fauxton = FauxtonAPI.addon();
   FauxtonAPI.addNotification = function (options) {
@@ -51,7 +50,7 @@ function(app, FauxtonAPI, resizeColumns, Components, ZeroClipboard) {
   Fauxton.initialize = function () {
     // app.footer = new Fauxton.Footer({el: "#footer-content"}),
     app.navBar = new Fauxton.NavBar();
-    app.apiBar = new Fauxton.ApiBar();
+    app.apiBar = new Components.ApiBar();
 
     FauxtonAPI.when.apply(null, app.navBar.establish()).done(function() {
       FauxtonAPI.masterLayout.setView("#primary-navbar", app.navBar, true);
@@ -77,7 +76,7 @@ function(app, FauxtonAPI, resizeColumns, Components, ZeroClipboard) {
       var crumbs = routeObject.get('crumbs');
 
       if (crumbs.length) {
-        FauxtonAPI.masterLayout.setView('#breadcrumbs', new Fauxton.Breadcrumbs({
+        FauxtonAPI.masterLayout.setView('#breadcrumbs', new Components.Breadcrumbs({
           crumbs: crumbs
         }), true).render();
       }
@@ -93,20 +92,7 @@ function(app, FauxtonAPI, resizeColumns, Components, ZeroClipboard) {
     });
   };
 
-  Fauxton.Breadcrumbs = FauxtonAPI.View.extend({
-    template: "addons/fauxton/templates/breadcrumbs",
 
-    serialize: function() {
-      var crumbs = _.clone(this.crumbs);
-      return {
-        crumbs: crumbs
-      };
-    },
-
-    initialize: function(options) {
-      this.crumbs = options.crumbs;
-    }
-  });
 
   Fauxton.VersionInfo = Backbone.Model.extend({
     url: function () {
@@ -259,64 +245,6 @@ function(app, FauxtonAPI, resizeColumns, Components, ZeroClipboard) {
     // TODO: ADD ACTIVE CLASS
   });
 
-  Fauxton.ApiBar = FauxtonAPI.View.extend({
-    template: "addons/fauxton/templates/api_bar",
-    endpoint: '_all_docs',
-
-    documentation: 'docs',
-
-    events:  {
-      "click .api-url-btn" : "toggleAPIbar"
-    },
-
-    toggleAPIbar: function(e){
-      var $currentTarget = $(e.currentTarget).find('span');
-      if ($currentTarget.hasClass("fonticon-plus")){
-        $currentTarget.removeClass("fonticon-plus").addClass("fonticon-minus");
-      }else{
-        $currentTarget.removeClass("fonticon-minus").addClass("fonticon-plus");
-      }
-      $('.api-navbar').toggle();
-    },
-
-    serialize: function() {
-      return {
-        endpoint: this.endpoint,
-        documentation: this.documentation
-      };
-    },
-
-    hide: function(){
-      this.$el.addClass('hide');
-    },
-    show: function(){
-      this.$el.removeClass('hide');
-    },
-    update: function(endpoint) {
-      this.show();
-      this.endpoint = endpoint[0];
-      this.documentation = endpoint[1];
-      this.render();
-    },
-    afterRender: function(){
-      var client = new Components.Clipboard({
-        $el: this.$('.copy-url')
-      });
-
-      client.on("load", function(e){
-        var $apiInput = $('#api-navbar input');
-        var copyURLTimer;
-        client.on("mouseup", function(e){
-          $apiInput.css("background-color","#aaa");
-          window.clearTimeout(copyURLTimer);
-          copyURLTimer = setInterval(function () {
-            $apiInput.css("background-color","#fff");
-          }, 200);
-        });
-      });
-    }
-
-  });
 
   Fauxton.Notification = FauxtonAPI.View.extend({
     fadeTimer: 5000,

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/fauxton/components.js
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/components.js b/app/addons/fauxton/components.js
index c863ba7..9540252 100644
--- a/app/addons/fauxton/components.js
+++ b/app/addons/fauxton/components.js
@@ -34,7 +34,124 @@ define([
 function(app, FauxtonAPI, ace, spin, ZeroClipboard) {
   var Components = FauxtonAPI.addon();
 
+
+  //setting up the left header with the backbutton used in Views and All docs
+  Components.LeftHeader = FauxtonAPI.View.extend({
+    className: "header-left",
+    template: "addons/fauxton/templates/header_left",
+    initialize:function(options){
+      this.dropdownMenuLinks = options.dropdownMenu;
+      this.crumbs = options.crumbs || [];
+    },
+    updateCrumbs: function(crumbs){
+      this.breadcrumbs && this.breadcrumbs.update(crumbs);
+    },
+    updateDropdown: function(menuLinks){
+      this.dropdown && this.dropdown.update(menuLinks);
+    },
+    beforeRender: function(){
+      this.setUpCrumbs();
+      this.setUpDropDownMenu();
+    },
+    setUpCrumbs: function(){
+      this.breadcrumbs = this.insertView("#header-breadcrumbs", new Components.Breadcrumbs({
+        crumbs: this.crumbs
+      }));
+    },
+    setUpDropDownMenu: function(){
+      if (this.dropdownMenuLinks){
+        this.dropdown = this.insertView("#header-dropdown-menu", new Components.MenuDropDown({
+          icon: 'fonticon-cog',
+          links: this.dropdownMenuLinks,
+        }));
+      }
+    }
+  });
+
+
+  Components.Breadcrumbs = FauxtonAPI.View.extend({
+    className: "breadcrumb pull-left",
+    tagName: "ul",
+    template: "addons/fauxton/templates/breadcrumbs",
+    serialize: function() {
+      var crumbs = _.clone(this.crumbs);
+      return {
+        crumbs: crumbs
+      };
+    },
+    update: function(crumbs) {
+      this.crumbs = crumbs;
+      this.render();
+    },
+    initialize: function(options) {
+      this.crumbs = options.crumbs;
+    }
+  });
+
+  Components.ApiBar = FauxtonAPI.View.extend({
+    template: "addons/fauxton/templates/api_bar",
+    events:  {
+      "click .api-url-btn" : "toggleAPIbar"
+    },
+
+    initialize: function(options){
+      var _options = options || {};
+      this.endpoint = _options.endpoint || '_all_docs';
+      this.documentation = _options.documentation || 'docs';
+    },
+
+    toggleAPIbar: function(e){
+      var $currentTarget = $(e.currentTarget).find('span');
+      if ($currentTarget.hasClass("fonticon-plus")){
+        $currentTarget.removeClass("fonticon-plus").addClass("fonticon-minus");
+      }else{
+        $currentTarget.removeClass("fonticon-minus").addClass("fonticon-plus");
+      }
+      $('.api-navbar').toggle();
+    },
+
+    serialize: function() {
+      return {
+        endpoint: this.endpoint,
+        documentation: this.documentation
+      };
+    },
+
+    hide: function(){
+      this.$el.addClass('hide');
+    },
+    show: function(){
+      this.$el.removeClass('hide');
+    },
+    update: function(endpoint) {
+      this.show();
+      this.endpoint = endpoint[0];
+      this.documentation = endpoint[1];
+      this.render();
+    },
+    afterRender: function(){
+      ZeroClipboard.config({ moviePath: "/assets/js/plugins/zeroclipboard/ZeroClipboard.swf" });
+      var client = new ZeroClipboard(this.$(".copy-url"));
+      client.on("load", function(e){
+        var $apiInput = $('#api-navbar input');
+        var copyURLTimer;
+        client.on("mouseup", function(e){
+          $apiInput.css("background-color","#aaa");
+          window.clearTimeout(copyURLTimer);
+          copyURLTimer = setInterval(function () {
+            $apiInput.css("background-color","#fff");
+          }, 200);
+        });
+      });
+    }
+
+  });
+
+
+
+
   Components.Pagination = FauxtonAPI.View.extend({
+    className: "pagination pagination-centered",
     template: "addons/fauxton/templates/pagination",
 
     initialize: function(options) {
@@ -57,6 +174,7 @@ function(app, FauxtonAPI, ace, spin, ZeroClipboard) {
   });
 
   Components.IndexPagination = FauxtonAPI.View.extend({
+    className: "pagination pagination-centered",
     template: "addons/fauxton/templates/index_pagination",
     events: {
       "click a": 'scrollTo',
@@ -453,7 +571,7 @@ function(app, FauxtonAPI, ace, spin, ZeroClipboard) {
       if (this.mode != "plain") {
         this.editor.getSession().setMode("ace/mode/" + this.mode);
       }
-      
+
       this.editor.setShowPrintMargin(false);
       this.addCommands();
 
@@ -624,11 +742,16 @@ function(app, FauxtonAPI, ace, spin, ZeroClipboard) {
     className: "dropdown",
     initialize: function(options){
       this.links = options.links;
+      this.icon = options.icon || "fonticon-plus-circled2";
+    },
+    update: function(links){
+      this.links = links;
+      this.render();
     },
     serialize: function(){
-      var sidebarItem = FauxtonAPI.getExtensions('sidebar:links');
       return {
-        links: this.links
+        links: this.links,
+        icon: this.icon
       };
     }
   });
@@ -656,7 +779,7 @@ function(app, FauxtonAPI, ace, spin, ZeroClipboard) {
   //need to make this into a backbone view...
   var routeObjectSpinner;
   FauxtonAPI.RouteObject.on('beforeEstablish', function (routeObject) {
-    if (!routeObject.disableLoader){ 
+    if (!routeObject.disableLoader){
       var opts = {
         lines: 16, // The number of lines to draw
         length: 8, // The length of each line
@@ -702,7 +825,7 @@ function(app, FauxtonAPI, ace, spin, ZeroClipboard) {
   FauxtonAPI.RouteObject.on('beforeRender', function (routeObject, view, selector) {
     removeRouteObjectSpinner();
 
-    if (!view.disableLoader){ 
+    if (!view.disableLoader){
       var opts = {
         lines: 16, // The number of lines to draw
         length: 8, // The length of each line

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/fauxton/resizeColumns.js
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/resizeColumns.js b/app/addons/fauxton/resizeColumns.js
index b3d8841..98555a9 100644
--- a/app/addons/fauxton/resizeColumns.js
+++ b/app/addons/fauxton/resizeColumns.js
@@ -32,7 +32,8 @@ function(FauxtonAPI) {
       var primaryNavWidth  = $('body').hasClass('closeMenu') ? 64 : 220;
       return primaryNavWidth;
     },
-    getPanelWidth: function(){
+
+    getSinglePanelWidth: function(){
       var sidebarWidth = $('#sidebar-content').length > 0 ? $('#sidebar-content').outerWidth() : 0,
           borders = parseInt($('#dashboard').css('border-left-width'), 10) +
                     parseInt($('#dashboard-content').css('border-left-width'), 10) +
@@ -40,6 +41,16 @@ function(FauxtonAPI) {
 
       return (this.getPrimaryNavWidth() + sidebarWidth + borders);
     },
+
+    getTwoPanelWidth: function(){
+      var borders = parseInt($('#dashboard').css('border-left-width'), 10) +
+          parseInt($('#right-content').css('border-left-width'), 10) +
+          parseInt($('#left-content').css('border-right-width'), 10)+
+          parseInt($('#left-content').css('border-left-width'), 10) +
+          parseInt($('#right-content').css('border-right-width'), 10);
+      return (this.getPrimaryNavWidth()+ borders);
+    },
+
     initialize: function(){
      // $(window).off('resize');
       var that = this;
@@ -49,33 +60,63 @@ function(FauxtonAPI) {
       FauxtonAPI.utils.initWindowResize();
       this.onResizeHandler();
     },
+
     updateOptions:function(options){
       this.options = {};
       this.options = options;
     },
+
     turnOff:function(){
       FauxtonAPI.utils.removeWindowResize("animation");
     },
+
     cleanupCallback: function(){
       this.callback = null;
     },
+
+    singlePanelResize: function(){
+      var combinedWidth = window.innerWidth - this.getSinglePanelWidth(),
+      smallWidthConstraint = ($('#sidebar-content').length > 0)? 470:800,
+      panelWidth;
+
+      if (combinedWidth > smallWidthConstraint) {
+        panelWidth = combinedWidth;
+      } else if (combinedWidth < smallWidthConstraint){
+        panelWidth = smallWidthConstraint;
+      }
+      return panelWidth;
+    },
+
+    getPanelWidth: function(){
+      var panelWidth;
+      if ($('#dashboard').hasClass('two-pane')){
+        panelWidth = (window.innerWidth - this.getTwoPanelWidth())/2;
+      } else {
+        panelWidth = this.singlePanelResize();
+      }
+      return panelWidth;
+    },
+
+    setPosition: function(panelWidth){
+      var primary = this.getPrimaryNavWidth();
+      $('#right-content').css('left',panelWidth+primary+4);
+    },
+
     onResizeHandler: function (){
       //if there is an override, do that instead
       if (this.options.onResizeHandler){
         this.options.onResizeHandler();
       } else {
-        var combinedWidth = window.innerWidth - this.getPanelWidth(),
-        smallWidthConstraint = ($('#sidebar-content').length > 0)? 470:800,
-        panelWidth;
-
-        if (combinedWidth > smallWidthConstraint) {
-          panelWidth = window.innerWidth - this.getPanelWidth();
-        } else if (combinedWidth < smallWidthConstraint){
-          panelWidth = smallWidthConstraint;
-        }
+        /*
+          Just so we all are aware:
+          This entire file and the html of the layouts is bonkers
+          crazy. I hate what horrible things happened in this file.
+          It will change soon with a layout overhaul.
+        */
 
+        var panelWidth = this.getPanelWidth();
+        this.setPosition(panelWidth);
         $('.window-resizeable').innerWidth(panelWidth);
-
       }
       //if there is a callback, run that
       if(this.options.callback) {

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/fauxton/templates/breadcrumbs.html
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/templates/breadcrumbs.html b/app/addons/fauxton/templates/breadcrumbs.html
index 52ea884..ca073c3 100644
--- a/app/addons/fauxton/templates/breadcrumbs.html
+++ b/app/addons/fauxton/templates/breadcrumbs.html
@@ -12,13 +12,10 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 
-<ul class="breadcrumb pull-left">
   <% _.each(_.initial(crumbs), function(crumb) { %>
     <li>
-      <a href="#<%- crumb.link %>"><%- crumb.name %></a>
-      <span class="divider fonticon fonticon-right-open"> </span>
+      <a href="#<%- crumb.link %>" class="fonticon <%- crumb.className %>"><%- crumb.name %></a>
     </li>
   <% }); %>
   <% var last = _.last(crumbs) || {name: ''} %>
   <li class="active"><%- last.name %></li>
-</ul>

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/fauxton/templates/header_left.html
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/templates/header_left.html b/app/addons/fauxton/templates/header_left.html
new file mode 100644
index 0000000..13bea60
--- /dev/null
+++ b/app/addons/fauxton/templates/header_left.html
@@ -0,0 +1,17 @@
+<!--
+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.
+-->
+<!--back arrow-->
+<div id="header-breadcrumbs"></div>
+  <!-- Menu gear-->
+<div id="header-dropdown-menu"></div>

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/fauxton/templates/index_pagination.html
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/templates/index_pagination.html b/app/addons/fauxton/templates/index_pagination.html
index f445377..594f6fc 100644
--- a/app/addons/fauxton/templates/index_pagination.html
+++ b/app/addons/fauxton/templates/index_pagination.html
@@ -12,13 +12,11 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 
-<div class="pagination pagination-centered">
-  <ul>
-    <li <% if (!canShowPreviousfn()) {%> class="disabled" <% } %>>
-       <a id="previous" href="#"> Previous </a>
-     </li>
-     <li <% if (!canShowNextfn()) {%> class="disabled" <% } %>>
-       <a id="next" href="#"> Next </a></li>
-  </ul>
-</div>
+<ul>
+  <li <% if (!canShowPreviousfn()) {%> class="disabled" <% } %>>
+     <a id="previous" href="#"> Previous </a>
+   </li>
+   <li <% if (!canShowNextfn()) {%> class="disabled" <% } %>>
+     <a id="next" href="#"> Next </a></li>
+</ul>
 

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/fauxton/templates/menu_dropdown.html
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/templates/menu_dropdown.html b/app/addons/fauxton/templates/menu_dropdown.html
index ddef343..d1e96af 100644
--- a/app/addons/fauxton/templates/menu_dropdown.html
+++ b/app/addons/fauxton/templates/menu_dropdown.html
@@ -12,7 +12,7 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 
-<a class="dropdown-toggle icon fonticon-plus-circled2" data-toggle="dropdown" href="#" data-bypass="true"></a>
+<a class="dropdown-toggle icon <%=icon%>" data-toggle="dropdown" href="#" data-bypass="true"></a>
 <ul class="dropdown-menu arrow" role="menu" aria-labelledby="dLabel">
   <% _.each(links, function (linkSection) { %>
     <% if (linkSection.title) { %>
@@ -20,9 +20,9 @@ the License.
     <% } %>
     <% _.each(linkSection.links, function (link) { %>
       <li>
-        <a 
+        <a
           <% if (link.icon) { %>
-          class="icon <%- link.icon %>" 
+          class="icon <%- link.icon %>"
           <% } %>
           href="<%- link.url %>">
           <%- link.title %>

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/fauxton/templates/pagination.html
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/templates/pagination.html b/app/addons/fauxton/templates/pagination.html
index 0674c22..614fd06 100644
--- a/app/addons/fauxton/templates/pagination.html
+++ b/app/addons/fauxton/templates/pagination.html
@@ -11,8 +11,6 @@ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 License for the specific language governing permissions and limitations under
 the License.
 -->
-
-<div class="pagination pagination-centered">
   <ul>
     <% if (page > 1) { %>
     <li> <a href="<%- urlFun(page-1) %>">&laquo;</a></li>
@@ -28,4 +26,3 @@ the License.
       <li class="disabled"> <a href="<%- urlFun(page) %>">&raquo;</a></li>
     <% } %>
   </ul>
-</div>

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/indexes/assets/less/doc-item.less
----------------------------------------------------------------------
diff --git a/app/addons/indexes/assets/less/doc-item.less b/app/addons/indexes/assets/less/doc-item.less
new file mode 100644
index 0000000..a04883a
--- /dev/null
+++ b/app/addons/indexes/assets/less/doc-item.less
@@ -0,0 +1,83 @@
+// 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.
+.view table td div.doc-menu-item div.dropdown{
+  display: block;
+}
+
+#doc-list{
+  margin-top: 30px;
+  div.doc-row {
+    margin-bottom:20px;
+    div.select {
+      width: 10%;
+      float: left;
+      vertical-align: top;
+    }
+    .doc-item {
+      float:left;
+      width:90%;
+      vertical-align: top;
+      position: relative;
+      .border-radius(5px 5px 5px 5px);
+      .box-shadow(3px 4px 0 rgba(0, 0, 0, 0.3));
+      border: 1px solid #000;
+      header {
+        font-weight: bold;
+        position: relative;
+        padding: 20px;
+        background-color: #777;
+        color: #3a2c2b;
+        border-bottom: 1px solid #000;
+        .header-id-number{
+          color: #fff;
+          margin-left: 10px;
+        }
+      }
+
+      .doc-data{
+        pre.prettyprint{
+        }
+      }
+
+      &:hover{
+        .btn-group{
+          display:block;
+        }
+      }
+      //temporary
+      .btn-group{
+        position:absolute;
+        top:10px;
+        right:10px;
+        display:none;
+      }
+
+      .doc-menu {
+        position:absolute;
+        right: 0px;
+        top: 0px;
+        .doc-menu-item{
+          a {
+            text-decoration: none;
+          }
+          .dropdown-menu {
+            left:auto;
+            right: 0px;
+          }
+          display: inline-block;
+          width: 30px;
+          height: 30px;
+        }
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/indexes/assets/less/index-form.less
----------------------------------------------------------------------
diff --git a/app/addons/indexes/assets/less/index-form.less b/app/addons/indexes/assets/less/index-form.less
new file mode 100644
index 0000000..c07163b
--- /dev/null
+++ b/app/addons/indexes/assets/less/index-form.less
@@ -0,0 +1,64 @@
+// 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.
+.index-form{
+  .control-group {
+    padding:15px 25px;
+    border-bottom: 1px solid #D9D9D9;
+    border-top: 1px solid #fff;
+    margin: 0 0 0 1px;
+    > input[type=text]{
+      width: 100%;
+      .border-radius(5px 5px 5px 5px);
+    }
+  }
+  .js-editor {
+    border: 1px solid #ccc;
+    .border-radius(5px 5px 5px 5px);
+  }
+}
+.input-prepend {
+  margin-left:0;
+}
+.new-ddoc {
+  .select-wrapper {
+    .border-radius(5px 0 0 5px);
+    margin-left:0;
+    overflow: hidden;
+    border: 1px solid #d0cdc6;
+    position: relative;
+    select {
+      border: 0;
+      color: #000;
+      background: transparent;
+      font-size: 14px;
+      padding: 5px 10px;
+      -webkit-appearance: none;
+      -moz-appearance: window;
+      height: 44px;
+    }
+    i {
+      position: absolute;
+      right: 20px;
+      top: 16px;
+      display: block;
+      color: #000;
+      width: 0;
+      height: 0;
+      border-style: solid;
+      border-width: 10px 7.5px 0 7.5px;
+      border-color: #000000 transparent transparent transparent;
+    }
+  }
+  input[type=text]{
+    .border-radius(0px 5px 5px 0);
+  }
+}

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/indexes/assets/less/indexes.less
----------------------------------------------------------------------
diff --git a/app/addons/indexes/assets/less/indexes.less b/app/addons/indexes/assets/less/indexes.less
new file mode 100644
index 0000000..5795cce
--- /dev/null
+++ b/app/addons/indexes/assets/less/indexes.less
@@ -0,0 +1,17 @@
+// 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.
+@import "../../../../../assets/less/variables.less";
+@import "../../../../../assets/less/bootstrap/variables.less";
+@import "../../../../../assets/less/bootstrap/mixins.less";
+@import "new-index-placeholder.less";
+@import "index-form.less";
+@import "doc-item.less";

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/indexes/assets/less/new-index-placeholder.less
----------------------------------------------------------------------
diff --git a/app/addons/indexes/assets/less/new-index-placeholder.less b/app/addons/indexes/assets/less/new-index-placeholder.less
new file mode 100644
index 0000000..ade1d3a
--- /dev/null
+++ b/app/addons/indexes/assets/less/new-index-placeholder.less
@@ -0,0 +1,25 @@
+// 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.
+.watermark-logo {
+  background: transparent url('../img/couchWatermark.png') no-repeat 50% 50%;
+  min-height: 400px;
+  padding-top: 60%;
+  text-align: center;
+  h3 {
+    border-bottom: 1px solid #ccc;
+    padding-bottom:10px;
+    margin-bottom:20px;
+  }
+  .preview {
+    margin: 0 10px;
+  }
+}

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/indexes/base.js
----------------------------------------------------------------------
diff --git a/app/addons/indexes/base.js b/app/addons/indexes/base.js
new file mode 100644
index 0000000..6365c61
--- /dev/null
+++ b/app/addons/indexes/base.js
@@ -0,0 +1,74 @@
+// 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.
+
+
+/*  View Indexes  */
+define([
+  "app",
+  "api",
+  "addons/indexes/routes"
+],
+function(app, FauxtonAPI, Routes) {
+  Routes.initialize = function() {
+
+    /*
+      Example of an extension:
+      An extension is just like an event that may or may not have listener in another view.
+      In this case the listener is in the documents addon in the sidebar.
+
+      If there are is a view that you want rendered in another route, this is the way to do it.
+
+      Each Secondary index is going to trigger this event with the views it's passing.
+      The views will be rendered and have links to the routes defined in this addon. Then it's just business as usual.
+
+      FauxtonAPI.registerExtension('sidebar:list', new Views.IndexMenu({}));
+      FauxtonAPI.registerExtension('sidebar:links',{
+        title: "New View",
+        url: "new_view"
+      });
+
+
+    */
+    //Show in the sidebar
+    FauxtonAPI.registerExtension('sidebar:list', {
+      selector:'views',
+      ddocType:'view',
+      icon: "fonticon-sidenav-map-reduce"
+    });
+    FauxtonAPI.registerExtension('sidebar:list', {
+      selector:'list',
+      icon: "fonticon-sidenav-list-function"
+    });
+    FauxtonAPI.registerExtension('sidebar:list', {
+      selector:'show',
+      icon: "fonticon-sidenav-show-function"
+    });
+
+
+    /* show in the add new menu dropdown */
+    FauxtonAPI.registerExtension('sidebar:links', {
+      title: "Secondary View",
+      url: "new_view"
+    });
+    FauxtonAPI.registerExtension('sidebar:links', {
+      title: "List Function",
+      url: "new_list"
+    });
+
+    FauxtonAPI.registerExtension('sidebar:links', {
+      url: 'new_show',
+      title: 'Show Index'
+    });
+
+  };
+  return Routes;
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/indexes/index-components.js
----------------------------------------------------------------------
diff --git a/app/addons/indexes/index-components.js b/app/addons/indexes/index-components.js
new file mode 100644
index 0000000..1ec34e2
--- /dev/null
+++ b/app/addons/indexes/index-components.js
@@ -0,0 +1,30 @@
+// 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.
+
+
+/*
+  Index components includes any common, generic, and reusable code for creating secondary indexes
+  View functions, List functions, Show Functions, and Filter functions, as well as anything created by
+  couchdb affiliates.
+*/
+
+define([
+  "app",
+  "api"
+],
+
+function(app, FauxtonAPI) {
+  var Components = {};
+
+
+  return Components;
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/indexes/resources.js
----------------------------------------------------------------------
diff --git a/app/addons/indexes/resources.js b/app/addons/indexes/resources.js
new file mode 100644
index 0000000..626d984
--- /dev/null
+++ b/app/addons/indexes/resources.js
@@ -0,0 +1,285 @@
+// 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",
+  "cloudant.pagingcollection"
+],
+
+function(app, FauxtonAPI, PagingCollection) {
+ var Resources = {};
+
+
+   Resources.QueryParams = (function () {
+    var _eachParams = function (params, action) {
+      // clone to avoid in-place modification
+      var result = _.clone(params);
+
+      _.each(['startkey', 'endkey', 'key'], function (key) {
+        if (_.has(result, key)) {
+          result[key] = action(result[key]);
+        }
+      });
+
+      return result;
+    };
+
+    return {
+      parse: function (params) {
+        return _eachParams(params, JSON.parse);
+      },
+
+      stringify: function (params) {
+        return _eachParams(params, JSON.stringify);
+      }
+    };
+  })();
+
+  Resources.ViewRow = FauxtonAPI.Model.extend({
+    // this is a hack so that backbone.collections doesn't group
+    // these by id and reduce the number of items returned.
+    idAttribute: "_id",
+
+    docType: function() {
+      if (!this.id) return "reduction";
+
+      return this.id.match(/^_design/) ? "design doc" : "doc";
+    },
+    documentation: function(){
+      return "docs";
+    },
+    url: function(context) {
+      return this.collection.database.url(context) + "/" + this.safeID();
+    },
+
+    isEditable: function() {
+      return this.docType() != "reduction";
+    },
+    safeID: function() {
+      var id = this.id || this.get("id");
+
+      return app.utils.safeURLName(id);
+    },
+
+    prettyJSON: function() {
+      //var data = this.get("doc") ? this.get("doc") : this;
+      return JSON.stringify(this, null, "  ");
+    }
+  });
+
+
+  Resources.PouchIndexCollection = PagingCollection.extend({
+    model: Resources.ViewRow,
+    documentation: function(){
+      return "docs";
+    },
+    initialize: function(_models, options) {
+      this.database = options.database;
+      this.rows = options.rows;
+      this.view = options.view;
+      this.design = options.design.replace('_design/','');
+      this.params = _.extend({limit: 20, reduce: false}, options.params);
+
+      this.idxType = "_view";
+    },
+
+    url: function () {
+      return '';
+    },
+
+    simple: function () {
+      var docs = this.map(function (item) {
+        return {
+          _id: item.id,
+          key: item.get('key'),
+          value: item.get('value')
+        };
+      });
+
+      return new Resources.PouchIndexCollection(docs, {
+        database: this.database,
+        params: this.params,
+        view: this.view,
+        design: this.design,
+        rows: this.rows
+      });
+
+    },
+
+    fetch: function() {
+      var deferred = FauxtonAPI.Deferred();
+      this.reset(this.rows, {silent: true});
+
+      this.viewMeta = {
+        total_rows: this.rows.length,
+        offset: 0,
+        update_seq: false
+      };
+
+      deferred.resolve();
+      return deferred;
+    },
+
+    totalRows: function() {
+      return this.viewMeta.total_rows || "unknown";
+    },
+
+    updateSeq: function() {
+      return this.viewMeta.update_seq || false;
+    },
+
+    buildAllDocs: function(){
+      this.fetch();
+    },
+
+    allDocs: function(){
+      return this.models;
+    }
+  });
+
+
+  Resources.IndexCollection = PagingCollection.extend({
+    model: Resources.ViewRow,
+    documentation: function(){
+      return "docs";
+    },
+    initialize: function(_models, options) {
+      this.database = options.database;
+      this.params = _.extend({limit: 20, reduce: false}, options.params);
+
+      this.idxType = "_view";
+      this.view = options.view;
+      this.design = options.design.replace('_design/','');
+      this.perPageLimit = options.perPageLimit || 20;
+
+      if (!this.params.limit) {
+        this.params.limit = this.perPageLimit;
+      }
+    },
+
+    urlRef: function(context, params) {
+      var query = "";
+
+      if (params) {
+        if (!_.isEmpty(params)) {
+          query = "?" + $.param(params);
+        } else {
+          query = '';
+        }
+      } else if (this.params) {
+        var parsedParam = Resources.QueryParams.stringify(this.params);
+        query = "?" + $.param(parsedParam);
+      }
+
+      var startOfUrl = app.host;
+      if (context === 'app') {
+        startOfUrl = 'database';
+      } else if (context === "apiurl"){
+        startOfUrl = window.location.origin;
+      }
+      var design = app.utils.safeURLName(this.design),
+          view = app.utils.safeURLName(this.view);
+
+      var url = [startOfUrl, this.database.safeID(), "_design", design, this.idxType, view];
+      return url.join("/") + query;
+    },
+
+    url: function () {
+      return this.urlRef.apply(this, arguments);
+    },
+
+    totalRows: function() {
+      if (this.params.reduce) { return "unknown_reduce";}
+
+      return this.viewMeta.total_rows || "unknown";
+    },
+
+    updateSeq: function() {
+      return this.viewMeta.update_seq || false;
+    },
+
+    simple: function () {
+      var docs = this.map(function (item) {
+        return {
+          _id: item.id,
+          key: item.get('key'),
+          value: item.get('value')
+        };
+      });
+
+      return new Resources.IndexCollection(docs, {
+        database: this.database,
+        params: this.params,
+        view: this.view,
+        design: this.design
+      });
+    },
+
+    parse: function(resp) {
+      var rows = resp.rows;
+      this.endTime = new Date().getTime();
+      this.requestDuration = (this.endTime - this.startTime);
+
+      return PagingCollection.prototype.parse.apply(this, arguments);
+    },
+
+    buildAllDocs: function(){
+      this.fetch();
+    },
+
+    // We implement our own fetch to store the starttime so we that
+    // we can get the request duration
+    fetch: function () {
+      this.startTime = new Date().getTime();
+      return PagingCollection.prototype.fetch.call(this);
+    },
+
+    allDocs: function(){
+      return this.models;
+    },
+
+    // This is taken from futon.browse.js $.timeString
+    requestDurationInString: function () {
+      var ms, sec, min, h, timeString, milliseconds = this.requestDuration;
+
+      sec = Math.floor(milliseconds / 1000.0);
+      min = Math.floor(sec / 60.0);
+      sec = (sec % 60.0).toString();
+      if (sec.length < 2) {
+         sec = "0" + sec;
+      }
+
+      h = (Math.floor(min / 60.0)).toString();
+      if (h.length < 2) {
+        h = "0" + h;
+      }
+
+      min = (min % 60.0).toString();
+      if (min.length < 2) {
+        min = "0" + min;
+      }
+
+      timeString = h + ":" + min + ":" + sec;
+
+      ms = (milliseconds % 1000.0).toString();
+      while (ms.length < 3) {
+        ms = "0" + ms;
+      }
+      timeString += "." + ms;
+
+      return timeString;
+    }
+
+  });
+
+  return Resources;
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/indexes/routes-core.js
----------------------------------------------------------------------
diff --git a/app/addons/indexes/routes-core.js b/app/addons/indexes/routes-core.js
new file mode 100644
index 0000000..354afb0
--- /dev/null
+++ b/app/addons/indexes/routes-core.js
@@ -0,0 +1,129 @@
+// 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/databases/base",
+  "addons/indexes/views",
+  "addons/documents/views",
+  "addons/indexes/resources"
+],
+
+function (app, FauxtonAPI, Databases, Views, Documents, Resources) {
+
+  var CoreIndexRouteObj =  FauxtonAPI.RouteObject.extend({
+    layout: "two_pane",
+
+    initialize: function (route, masterLayout, options) {
+      this.databaseName = options[0];
+
+      this.data = {
+        database: new Databases.Model({id:this.databaseName})
+      };
+
+      this.data.designDocs = new Documents.AllDocs(null, {
+        database: this.data.database,
+        paging: {
+          pageSize: 500
+        },
+        params: {
+          startkey: '_design',
+          endkey: '_design1',
+          include_docs: true,
+          limit: 500
+        }
+      });
+    },
+
+    events: {
+      "route:updatePreviewDocs": "updateAllDocsFromPreview"
+    },
+
+    ddocInfo: function (designDoc, designDocs, view) {
+      return {
+        id: "_design/" + designDoc,
+        currView: view,
+        designDocs: designDocs
+      };
+    },
+
+    createParams: function (options) {
+      var urlParams = app.getParams(options);
+      var params = Documents.QueryParams.parse(urlParams);
+
+      return {
+        urlParams: urlParams,
+        docParams: _.extend(params, {limit: this.getDocPerPageLimit(params, 20)})
+      };
+    },
+
+    getDocPerPageLimit: function (urlParams, perPage) {
+      var storedPerPage = perPage;
+
+      if (window.localStorage) {
+        storedPerPage = window.localStorage.getItem('fauxton:perpage');
+
+        if (!storedPerPage) {
+          this.setDocPerPageLimit(perPage);
+          storedPerPage = perPage;
+        } else {
+          storedPerPage = parseInt(storedPerPage, 10);
+        }
+      }
+
+      if (!urlParams.limit || urlParams.limit > storedPerPage) {
+        return parseInt(storedPerPage, 10);
+      } else {
+        return parseInt(urlParams.limit, 10);
+      }
+    },
+
+    establish: function () {
+      return this.data.designDocs.fetch({reset: true});
+    },
+
+    createViewDocumentsView: function (options) {
+      return this.setView("#right-content", new Documents.Views.AllDocsList({
+        database: options.database,
+        collection: options.indexedDocs,
+        nestedView: Views.Row,
+        viewList: true,
+        ddocInfo: this.ddocInfo(options.designDoc, options.designDocs, options.view),
+        docParams: options.docParams,
+        params: options.urlParams
+      }));
+    },
+
+    updateAllDocsFromPreview: function (event) {
+      var view = event.view,
+      rows = event.rows,
+      ddoc = event.ddoc;
+
+      this.data.indexedDocs = new Documents.PouchIndexCollection(null, {
+        database: this.data.database,
+        design: ddoc,
+        view: view,
+        rows: rows
+      });
+
+      this.documentsView = this.setView("#right-content", new Documents.Views.AllDocsList({
+        database: this.data.database,
+        collection: this.data.indexedDocs,
+        nestedView: Views.Row,
+        viewList: true
+      }));
+    }
+  });
+
+  return CoreIndexRouteObj;
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/indexes/routes-list.js
----------------------------------------------------------------------
diff --git a/app/addons/indexes/routes-list.js b/app/addons/indexes/routes-list.js
new file mode 100644
index 0000000..437cef6
--- /dev/null
+++ b/app/addons/indexes/routes-list.js
@@ -0,0 +1,108 @@
+// 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/databases/base",
+  "addons/indexes/views",
+  "addons/documents/views",
+  "addons/indexes/resources",
+  "addons/indexes/routes-core",
+  "addons/fauxton/components"
+],
+
+function (app, FauxtonAPI, Databases, Views, Documents, Resources, RouteCore, Components) {
+
+  var ListIndexes = RouteCore.extend({
+    routes: {
+      "database/:database/_design/:ddoc/_lists/:fn": {
+        route: "tempFn",
+        roles: ['_admin']
+      },
+      "database/:database/new_list": "newListsEditor",
+      "database/:database/new_list/:designDoc": "newListsEditor"
+    },
+
+    apiUrl: function() {
+      //TODO: Hook up proper API urls
+      return '';
+    },
+
+    newListsEditor: function (database, designDoc) {
+      var params = app.getParams();
+
+      /* --------------------------------------------------
+        Insert View Editor for new list
+      ----------------------------------------------------*/
+      this.setView("#left-content", new Views.ListEditor({
+        model: this.data.database,
+        currentddoc: designDoc ? "_design/"+designDoc : "",
+        ddocs: this.data.designDocs,
+        params: params,
+        database: this.data.database,
+        newView: true
+      }));
+      /* --------------------------------------------------
+        Insert Preview Screen View
+      ----------------------------------------------------*/
+      this.setView("#right-content", new Views.PreviewScreen({}));
+
+      /* --------------------------------------------------
+        Set up & Insert breadcrumb header
+      ----------------------------------------------------*/
+      var crumbs = [
+        {"name": "", "className": "fonticon-left-open", "link": Databases.databaseUrl(this.data.database)},
+        {"name": "Create a List Index", "link": Databases.databaseUrl(this.data.database)}
+      ];
+      this.leftheader = this.setView("#breadcrumbs", new Components.LeftHeader({
+        crumbs: crumbs
+      }));
+    },
+    tempFn:  function(databaseName, ddoc, view){
+      /* --------------------------------------------------
+        Set up breadcrumb header
+      ----------------------------------------------------*/
+      var crumbs = [
+        {"name": "", "className": "fonticon-left-open", "link": Databases.databaseUrl(this.data.database)},
+        {"name": view, "link": Databases.databaseUrl(this.data.database)}
+      ];
+
+      var dropdown = [{
+        links: [{
+          title: 'Duplicate Index',
+          icon: 'fonticon-documents'
+        },{
+          title: 'Delete',
+          icon: 'fonticon-trash'
+        }]
+      }];
+
+      this.leftheader = this.setView("#breadcrumbs", new Components.LeftHeader({
+        crumbs: crumbs,
+        dropdownMenu: dropdown
+      }));
+
+
+      /* --------------------------------------------------
+        Insert List Editor
+      ----------------------------------------------------*/
+      this.setView("#left-content", new Views.ListEditor({}));
+
+      /* --------------------------------------------------
+        Insert Preview Screen View
+      ----------------------------------------------------*/
+      this.setView("#right-content", new Views.PreviewScreen({}));
+    }
+  });
+
+  return ListIndexes;
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/indexes/routes-show.js
----------------------------------------------------------------------
diff --git a/app/addons/indexes/routes-show.js b/app/addons/indexes/routes-show.js
new file mode 100644
index 0000000..73f52d1
--- /dev/null
+++ b/app/addons/indexes/routes-show.js
@@ -0,0 +1,103 @@
+// 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/databases/base",
+  "addons/indexes/views",
+  "addons/documents/views",
+  "addons/indexes/resources",
+  "addons/indexes/routes-core",
+   "addons/fauxton/components"
+],
+
+function (app, FauxtonAPI, Databases, Views, Documents, Resources, RouteCore, Components) {
+
+  var ShowIndexes = RouteCore.extend({
+    routes: {
+      "database/:database/_design/:ddoc/_show/:fn": {
+        route: "tempFn",
+        roles: ['_admin']
+      },
+      "database/:database/new_show": "newShowEditor",
+      "database/:database/new_show/:designDoc": "newShowEditor"
+    },
+
+    newShowEditor: function (database, designDoc) {
+      var params = app.getParams();
+      /* --------------------------------------------------
+        Insert View Editor for new view
+      ----------------------------------------------------*/
+      this.setView("#left-content", new Views.ShowEditor({
+        model: this.data.database,
+        currentddoc: designDoc ? "_design/"+designDoc : "",
+        ddocs: this.data.designDocs,
+        params: params,
+        database: this.data.database,
+        newView: true
+      }));
+
+      /* --------------------------------------------------
+        Insert Preview Screen View
+      ----------------------------------------------------*/
+      this.setView("#right-content", new Views.PreviewScreen({}));
+
+      /* --------------------------------------------------
+        Set up & Insert breadcrumb header
+      ----------------------------------------------------*/
+      var crumbs = [
+        {"name": "", "className": "fonticon-left-open", "link": Databases.databaseUrl(this.data.database)},
+        {"name": "Create a Show Index", "link": Databases.databaseUrl(this.data.database)}
+      ];
+      this.leftheader = this.setView("#breadcrumbs", new Components.LeftHeader({
+        crumbs: crumbs
+      }));
+    },
+    tempFn:  function(databaseName, ddoc, view){
+      /* --------------------------------------------------
+        Set up breadcrumb header
+      ----------------------------------------------------*/
+      var crumbs = [
+        {"name": "", "className": "fonticon-left-open", "link": Databases.databaseUrl(this.data.database)},
+        {"name": view, "link": Databases.databaseUrl(this.data.database)}
+      ];
+
+      var dropdown = [{
+        links: [{
+          title: 'Duplicate Index',
+          icon: 'fonticon-documents'
+        },{
+          title: 'Delete',
+          icon: 'fonticon-trash'
+        }]
+      }];
+
+      this.leftheader = this.setView("#breadcrumbs", new Components.LeftHeader({
+        crumbs: crumbs,
+        dropdownMenu: dropdown
+      }));
+
+
+      /* --------------------------------------------------
+        Insert Show Editor
+      ----------------------------------------------------*/
+      this.setView("#left-content", new Views.ListEditor({}));
+
+      /* --------------------------------------------------
+        Insert Preview Screen View
+      ----------------------------------------------------*/
+      this.setView("#right-content", new Views.PreviewScreen({}));
+    }
+  });
+
+  return ShowIndexes;
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/113615ff/app/addons/indexes/routes-viewindexes.js
----------------------------------------------------------------------
diff --git a/app/addons/indexes/routes-viewindexes.js b/app/addons/indexes/routes-viewindexes.js
new file mode 100644
index 0000000..7330d04
--- /dev/null
+++ b/app/addons/indexes/routes-viewindexes.js
@@ -0,0 +1,156 @@
+// 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/databases/base",
+  "addons/indexes/views",
+  "addons/documents/views",
+  "addons/indexes/resources",
+  "addons/indexes/routes-core",
+  "addons/fauxton/components"
+],
+
+function (app, FauxtonAPI, Databases, Views, Documents, Resources, RouteCore, Components) {
+
+  var ViewIndexes = RouteCore.extend({
+    routes: {
+      "database/:database/_design/:ddoc/_view/:view": {
+        route: "viewFn",
+        roles: ['_admin']
+      },
+      "database/:database/new_view": "newViewEditor",
+      "database/:database/new_view/:designDoc": "newViewEditor"
+    },
+
+    newViewEditor: function (database, designDoc) {
+      var params = app.getParams();
+      /* --------------------------------------------------
+        remove right header
+      ----------------------------------------------------*/
+      this.rightheader && this.rightheader.remove();
+
+      /* --------------------------------------------------
+        Insert Preview Screen View
+      ----------------------------------------------------*/
+      this.setView("#right-content", new Views.PreviewScreen({}));
+
+      /* --------------------------------------------------
+        Insert View Editor for new view
+      ----------------------------------------------------*/
+      this.viewEditor = this.setView("#left-content", new Views.ViewEditor({
+        model: this.data.database,
+        currentddoc: designDoc ? "_design/"+designDoc : "",
+        ddocs: this.data.designDocs,
+        params: params,
+        database: this.data.database,
+        newView: true
+      }));
+
+      /* --------------------------------------------------
+        Set up & Insert breadcrumb header
+      ----------------------------------------------------*/
+      var crumbs = [
+        {"name": "", "className": "fonticon-left-open", "link": Databases.databaseUrl(this.data.database)},
+        {"name": "Create a View Index", "link": Databases.databaseUrl(this.data.database)}
+      ];
+      this.leftheader = this.setView("#breadcrumbs", new Components.LeftHeader({
+        crumbs: crumbs
+      }));
+
+    },
+
+    viewFn: function (databaseName, ddoc, view) {
+      var params = this.createParams(),
+          urlParams = params.urlParams,
+          docParams = params.docParams,
+          decodeDdoc = decodeURIComponent(ddoc);
+          view = view.replace(/\?.*$/,'');
+
+      /* --------------------------------------------------
+        Set up breadcrumb header
+      ----------------------------------------------------*/
+      var crumbs = [
+        {"name": "", "className": "fonticon-left-open", "link": Databases.databaseUrl(this.data.database)},
+        {"name": view, "link": Databases.databaseUrl(this.data.database)}
+      ];
+
+      var dropdown = [{
+        links: [{
+          title: 'Duplicate Index',
+          icon: 'fonticon-documents'
+        },{
+          title: 'Delete',
+          icon: 'fonticon-trash'
+        }]
+      }];
+
+      this.leftheader = this.setView("#breadcrumbs", new Components.LeftHeader({
+        crumbs: crumbs,
+        dropdownMenu: dropdown
+      }));
+
+      /* --------------------------------------------------
+        Set up Index Collection
+      ----------------------------------------------------*/
+      this.data.indexedDocs = new Resources.IndexCollection(null, {
+        database: this.data.database,
+        design: decodeDdoc,
+        view: view,
+        params: docParams,
+        paging: {
+          pageSize: this.getDocPerPageLimit(urlParams, parseInt(docParams.limit, 10))
+        }
+      });
+
+
+      /* --------------------------------------------------
+        Set up right header
+      ----------------------------------------------------*/
+
+      this.rightheader = this.setView("#api-navbar", new Views.RightHeader({
+        database: this.data.database,
+        model: this.data.database,
+        endpoint: this.data.indexedDocs.urlRef("apiurl", urlParams),
+        documentation: "docs"
+      }));
+
+      /* --------------------------------------------------
+        Insert View Editor
+      ----------------------------------------------------*/
+      this.viewEditor = this.setView("#left-content", new Views.ViewEditor({
+        model: this.data.database,
+        ddocs: this.data.designDocs,
+        viewName: view,
+        params: urlParams,
+        newView: false,
+        database: this.data.database,
+        ddocInfo: this.ddocInfo(decodeDdoc, this.data.designDocs, view)
+      }));
+
+      /* --------------------------------------------------
+        Insert Docs returned from view
+      ----------------------------------------------------*/
+      this.documentsView = this.createViewDocumentsView({
+        designDoc: decodeDdoc,
+        docParams: docParams,
+        urlParams: urlParams,
+        database: this.data.database,
+        indexedDocs: this.data.indexedDocs,
+        designDocs: this.data.designDocs,
+        view: view
+      });
+    }
+  });
+
+  return ViewIndexes;
+});


Mime
View raw message