couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gar...@apache.org
Subject fauxton commit: updated refs/heads/master to 1e0f4de
Date Tue, 02 Sep 2014 12:56:58 GMT
Repository: couchdb-fauxton
Updated Branches:
  refs/heads/master 64e3b0862 -> 1e0f4de0c


New Documents header

This is the start of the new documents header. Initial work by
<deathbearbrown@gmail.com> and Jenn Schiffer <jenn@pancaketheorem.com>.


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

Branch: refs/heads/master
Commit: 1e0f4de0ccfca5c6ccfba7572f56c53586bab4af
Parents: 64e3b08
Author: Garren Smith <garren.smith@gmail.com>
Authored: Thu Aug 28 11:17:47 2014 +0200
Committer: Garren Smith <garren.smith@gmail.com>
Committed: Tue Sep 2 14:55:57 2014 +0200

----------------------------------------------------------------------
 app/addons/documents/routes-doc-editor.js       | 128 +++++
 app/addons/documents/routes-documents.js        | 495 +++++++++++++++++
 app/addons/documents/routes.js                  | 542 +------------------
 .../documents/templates/header_alldocs.html     |  31 ++
 app/addons/documents/tests/routeSpec.js         |   8 -
 app/addons/documents/views-doceditor.js         | 106 ++--
 app/addons/documents/views.js                   | 114 ++++
 app/addons/fauxton/components.js                |  61 ++-
 app/addons/fauxton/templates/header_left.html   |  17 +
 app/addons/fauxton/templates/menu_dropdown.html |   8 +-
 app/core/api.js                                 |   2 +
 app/templates/layouts/with_tabs_sidebar.html    |  15 +-
 assets/less/fauxton.less                        |   6 +-
 13 files changed, 921 insertions(+), 612 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/1e0f4de0/app/addons/documents/routes-doc-editor.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/routes-doc-editor.js b/app/addons/documents/routes-doc-editor.js
new file mode 100644
index 0000000..57f61c4
--- /dev/null
+++ b/app/addons/documents/routes-doc-editor.js
@@ -0,0 +1,128 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+define([
+  "app",
+
+  "api",
+
+  // Modules
+  //views
+  "addons/documents/views",
+  "addons/documents/views-doceditor",
+  "addons/databases/base",
+],
+
+function(app, FauxtonAPI, Documents, DocEditor, Databases) {
+
+  var DocEditorRouteObject = FauxtonAPI.RouteObject.extend({
+    layout: "one_pane",
+    disableLoader: true,
+    selectedHeader: "Databases",
+    initialize: function(route, masterLayout, options) {
+      var databaseName = options[0];
+      this.docID = options[1]||'new';
+
+      this.database = this.database || new Databases.Model({id: databaseName});
+      this.doc = new Documents.Doc({
+        _id: this.docID
+      }, {
+        database: this.database
+      });
+    },
+
+    routes: {
+      "database/:database/:doc/code_editor": "code_editor",
+      "database/:database/:doc": "code_editor"
+    },
+
+    events: {
+      "route:reRenderDoc": "reRenderDoc",
+      "route:duplicateDoc": "duplicateDoc"
+    },
+
+    crumbs: function() {
+      return [
+        {"name": this.database.id, "link": Databases.databaseUrl(this.database)}
+        //{"name": this.docID, "link": "#"}
+      ];
+    },
+
+    code_editor: function (database, doc) {
+      this.docView = this.setView("#dashboard-content", new DocEditor.CodeEditor({
+        model: this.doc,
+        database: this.database
+      }));
+    },
+
+    reRenderDoc: function () {
+      this.docView.forceRender();
+    },
+
+    duplicateDoc: function (newId) {
+      var doc = this.doc,
+      docView = this.docView,
+      database = this.database;
+      this.docID = newId;
+
+      doc.copy(newId).then(function () {
+        doc.set({_id: newId});
+        docView.forceRender();
+        FauxtonAPI.navigate('/database/' + database.safeID() + '/' + app.utils.safeURLName(newId), {trigger: true});
+        FauxtonAPI.addNotification({
+          msg: "Document has been duplicated."
+        });
+
+      }, function (error) {
+        var errorMsg = "Could not duplicate document, reason: " + error.responseText + ".";
+        FauxtonAPI.addNotification({
+          msg: errorMsg,
+          type: "error"
+        });
+      });
+    },
+
+    apiUrl: function() {
+      return [this.doc.url("apiurl"), this.doc.documentation()];
+    }
+  });
+
+  var NewDocEditorRouteObject = DocEditorRouteObject.extend({
+    initialize: function (route, masterLayout, options) {
+      var databaseName = options[0];
+
+      this.database = this.database || new Databases.Model({id: databaseName});
+      this.doc = new Documents.NewDoc(null,{
+        database: this.database
+      });
+
+    },
+    crumbs: function() {
+      return [
+        {"name": this.database.id, "link": Databases.databaseUrl(this.database)},
+        {"name": "New", "link": "#"}
+      ];
+    },
+    routes: {
+      "database/:database/new": "code_editor"
+    },
+    selectedHeader: "Databases",
+
+  });
+
+  
+  return {
+    NewDocEditorRouteObject: NewDocEditorRouteObject,
+    DocEditorRouteObject: DocEditorRouteObject
+  };
+});
+

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/1e0f4de0/app/addons/documents/routes-documents.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/routes-documents.js b/app/addons/documents/routes-documents.js
new file mode 100644
index 0000000..9ab69b3
--- /dev/null
+++ b/app/addons/documents/routes-documents.js
@@ -0,0 +1,495 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+define([
+  "app",
+
+  "api",
+
+  // Modules
+  //views
+  "addons/documents/views",
+  "addons/documents/views-changes",
+  "addons/documents/views-index",
+  "addons/documents/views-doceditor",
+
+  "addons/databases/base",
+  "addons/documents/resources",
+  "addons/fauxton/components"
+],
+
+function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resources, Components) {
+
+  var crumbs = {
+    allDocs: function (database) {
+      return [
+        {"name": "", "className": "fonticon-left-open", "link": "/_all_dbs"},
+        {"name": database.id, "link": Databases.databaseUrl(database)}
+      ];
+    },
+
+    changes: function (database) {
+      return [
+        {"name": "", "className": "fonticon-left-open", "link": "/_all_dbs"},
+        {"name": database.id, "link": Databases.databaseUrl(database)},
+        {"name": "_changes", "link": "/_changes"}
+      ];
+    }
+
+  };
+
+  var DocumentsRouteObject = FauxtonAPI.RouteObject.extend({
+    layout: "with_tabs_sidebar",
+    selectedHeader: "Databases",
+    routes: {
+
+      "database/:database/_all_docs(:extra)": {
+        route: "allDocs",
+        roles: ["_reader","_writer","_admin"]
+      },
+      "database/:database/_design/:ddoc/_views/:view": {
+        route: "viewFn",
+        roles: ['_admin']
+      },
+      "database/:database/_design/:ddoc/_lists/:fn": {
+        route: "tempFn",
+        roles: ['_admin']
+      },
+      "database/:database/_design/:ddoc/_filters/:fn": {
+        route: "tempFn",
+        roles: ['_admin']
+      },
+      "database/:database/_design/:ddoc/_show/:fn": {
+        route: "tempFn",
+        roles: ['_admin']
+      },
+      "database/:database/_design/:ddoc/metadata": {
+        route: "designDocMetadata",
+        roles: ['_admin']
+      },
+      "database/:database/new_view": "newViewEditor",
+      "database/:database/new_view/:designDoc": "newViewEditor",
+      "database/:database/_changes(:params)": "changes"
+    },
+
+    events: {
+      "route:updateAllDocs": "updateAllDocsFromView",
+      "route:reloadDesignDocs": "reloadDesignDocs",
+      "route:paginate": "paginate",
+      "route:perPageChange": "perPageChange",
+      "route:changesFilterAdd": "addFilter",
+      "route:changesFilterRemove": "removeFilter"
+    },
+
+    initialize: function (route, masterLayout, options) {
+      this.databaseName = options[0];
+
+      this.database = new Databases.Model({id:this.databaseName});
+
+      this.designDocs = new Documents.AllDocs(null, {
+        database: this.database,
+        paging: {
+          pageSize: 500
+        },
+        params: {
+          startkey: '_design/',
+          endkey: '_design0',
+          include_docs: true,
+          limit: 500
+        }
+      });
+
+      this.rightHeader = this.setView("#api-navbar", new Documents.Views.RightAllDocsHeader({
+         database: this.database
+      }));
+
+      this.leftheader = this.setView("#breadcrumbs", new Components.LeftHeader({
+        crumbs: crumbs.allDocs(this.database),
+        dropdownMenu: this.setUpDropdown()
+      }));
+
+      this.sidebar = this.setView("#sidebar-content", new Documents.Views.Sidebar({
+        collection: this.designDocs,
+        database: this.database
+      }));
+
+    },
+
+    setUpDropdown: function(){
+      var defaultMenuLinks = [{
+        links: [{
+          title: 'Replicate Database',
+          icon: 'fonticon-replicate',
+          url: '#/replication/'+this.databaseName
+        },{
+          title: 'Delete',
+          icon: 'fonticon-trash',
+          trigger: 'database:delete'
+        }]
+      }];
+
+      defaultMenuLinks.push({
+        title: 'Add new',
+        links: this.getExtensionLinks()
+      });
+
+      return defaultMenuLinks;
+    },
+
+    getExtensionLinks: function () {
+      var database = this.database,
+          newurlPrefix = "#" + database.url('app');
+
+      var menuLinks = [{
+          title: 'New Doc',
+          url: newurlPrefix + '/new',
+          icon: 'fonticon-plus-circled'
+        },{
+          title: 'New View',
+          url: newurlPrefix + '/new_view',
+          icon: 'fonticon-plus-circled'
+      }];
+
+      return _.reduce(FauxtonAPI.getExtensions('sidebar:links'), function (menuLinks, link) {
+
+        menuLinks.push({
+          title: link.title,
+          url: newurlPrefix + "/" + link.url,
+          icon: 'fonticon-plus-circled'
+        });
+
+        return menuLinks;
+     }, menuLinks);
+
+    },
+
+    designDocMetadata:  function(database, ddoc){
+      this.toolsView && this.toolsView.remove();
+      this.viewEditor && this.viewEditor.remove();
+
+      var designDocInfo = new Resources.DdocInfo({_id: "_design/"+ddoc},{database: this.database });
+
+      this.setView("#dashboard-lower-content", new Documents.Views.DdocInfo({
+        ddocName: ddoc,
+        model: designDocInfo
+      }));
+
+      this.sidebar.setSelectedTab(app.utils.removeSpecialCharacters(ddoc)+"_metadata");
+
+
+      this.leftheader.updateCrumbs(crumbs.allDocs(this.database)); 
+      this.leftheader.forceRender();
+
+      this.apiUrl = [designDocInfo.url('apiurl'), designDocInfo.documentation() ];
+
+    },
+    tempFn:  function(databaseName, ddoc, fn){
+      this.setView("#dashboard-upper-content", new Documents.Views.temp({}));
+      this.crumbs = function () {
+        return [
+          {"name": this.database.id, "link": Databases.databaseUrl(this.database)},
+        ];
+      };
+
+    },
+
+    establish: function () {
+      return this.designDocs.fetch({reset: true});
+    },
+
+    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)})
+      };
+    },
+
+    /*
+    * docParams are the options collection uses to fetch from the server
+    * urlParams are what are shown in the url and to the user
+    * They are not the same when paginating
+    */
+    allDocs: function(databaseName, options) {
+      var params = this.createParams(options),
+          urlParams = params.urlParams,
+          docParams = params.docParams;
+
+      if (this.eventAllDocs) {
+        this.eventAllDocs = false;
+        return;
+      }
+
+      this.leftheader.updateCrumbs(crumbs.allDocs(this.database)); 
+      this.leftheader.forceRender();
+      this.database.buildAllDocs(docParams);
+
+      if (docParams.startkey && docParams.startkey.indexOf('_design') > -1) {
+        this.sidebar.setSelectedTab('design-docs');
+      } else {
+        this.sidebar.setSelectedTab('all-docs');
+      }
+
+      this.viewEditor && this.viewEditor.remove();
+
+      this.database.allDocs.paging.pageSize = this.getDocPerPageLimit(urlParams, parseInt(docParams.limit, 10));
+
+      this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.AllDocsLayout({
+        database: this.database,
+        collection: this.database.allDocs,
+        params: urlParams,
+        docParams: docParams
+      }));
+
+      this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
+        database: this.database,
+        collection: this.database.allDocs,
+        docParams: docParams,
+        params: urlParams,
+        bulkDeleteDocsCollection: new Documents.BulkDeleteDocCollection([], {databaseId: this.database.get('id')})
+      }));
+
+      this.rightHeader.updateApiUrl([this.database.allDocs.urlRef("apiurl", urlParams), this.database.allDocs.documentation()]);
+    },
+
+    viewFn: function (databaseName, ddoc, view) {
+      var params = this.createParams(),
+          urlParams = params.urlParams,
+          docParams = params.docParams,
+          decodeDdoc = decodeURIComponent(ddoc);
+
+      view = view.replace(/\?.*$/,'');
+
+      this.indexedDocs = new Documents.IndexCollection(null, {
+        database: this.database,
+        design: decodeDdoc,
+        view: view,
+        params: docParams,
+        paging: {
+          pageSize: this.getDocPerPageLimit(urlParams, parseInt(docParams.limit, 10))
+        }
+      });
+
+      this.viewEditor = this.setView("#dashboard-upper-content", new Index.ViewEditor({
+        model: this.database,
+        ddocs: this.designDocs,
+        viewName: view,
+        params: urlParams,
+        newView: false,
+        database: this.database,
+        ddocInfo: this.ddocInfo(decodeDdoc, this.designDocs, view)
+      }));
+
+      this.toolsView && this.toolsView.remove();
+
+      this.documentsView = this.createViewDocumentsView({
+        designDoc: decodeDdoc,
+        docParams: docParams,
+        urlParams: urlParams,
+        database: this.database,
+        indexedDocs: this.indexedDocs,
+        designDocs: this.designDocs,
+        view: view
+      });
+
+      this.sidebar.setSelectedTab(app.utils.removeSpecialCharacters(ddoc) + '_' + app.utils.removeSpecialCharacters(view));
+
+      this.rightHeader.updateApiUrl([this.indexedDocs.urlRef("apiurl", urlParams), "docs"]);
+      this.leftheader.forceRender();
+    },
+
+    ddocInfo: function (designDoc, designDocs, view) {
+      return {
+        id: "_design/" + designDoc,
+        currView: view,
+        designDocs: designDocs
+      };
+    },
+
+    createViewDocumentsView: function (options) {
+
+      return this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
+        database: options.database,
+        collection: options.indexedDocs,
+        nestedView: Documents.Views.Row,
+        viewList: true,
+        ddocInfo: this.ddocInfo(options.designDoc, options.designDocs, options.view),
+        docParams: options.docParams,
+        params: options.urlParams
+      }));
+    },
+
+    newViewEditor: function (database, designDoc) {
+      var params = app.getParams();
+
+      this.toolsView && this.toolsView.remove();
+      this.documentsView && this.documentsView.remove();
+
+      this.viewEditor = this.setView("#dashboard-upper-content", new Index.ViewEditor({
+        currentddoc: "_design/"+designDoc || "",
+        ddocs: this.designDocs,
+        params: params,
+        database: this.database,
+        newView: true
+      }));
+
+      this.sidebar.setSelectedTab('new-view');
+      this.crumbs = function () {
+        return [
+          {"name": this.database.id, "link": Databases.databaseUrl(this.database)},
+        ];
+      };
+    },
+
+    updateAllDocsFromView: function (event) {
+      var view = event.view,
+          params = this.createParams(),
+          urlParams = params.urlParams,
+          docParams = params.docParams,
+          ddoc = event.ddoc,
+          pageSize,
+          collection;
+
+      var defaultPageSize = _.isUndefined(this.documentsView) ? 20 : this.documentsView.perPage();
+      docParams.limit = pageSize = this.getDocPerPageLimit(urlParams, defaultPageSize);
+
+      if (event.allDocs) {
+        this.eventAllDocs = true; // this is horrible. But I cannot get the trigger not to fire the route!
+        this.database.buildAllDocs(docParams);
+        collection = this.database.allDocs;
+        collection.paging.pageSize = pageSize;
+
+      } else {
+        collection = this.indexedDocs = new Documents.IndexCollection(null, {
+          database: this.database,
+          design: ddoc,
+          view: view,
+          params: docParams,
+          paging: {
+            pageSize: pageSize
+          }
+        });
+
+        if (!this.documentsView) {
+          this.documentsView = this.createViewDocumentsView({
+            designDoc: ddoc,
+            docParams: docParams,
+            urlParams: urlParams,
+            database: this.database,
+            indexedDocs: this.indexedDocs,
+            designDocs: this.designDocs,
+            view: view
+          });
+        }
+      }
+
+      this.documentsView.setCollection(collection);
+      this.documentsView.setParams(docParams, urlParams);
+      this.documentsView.forceRender();
+
+      this.apiUrl = [collection.urlRef("apiurl", urlParams), "docs"];
+    },
+
+    perPageChange: function (perPage) {
+      // We need to restore the collection parameters to the defaults (1st page)
+      // and update the page size
+      this.perPage = perPage;
+      this.documentsView.forceRender();
+      this.documentsView.collection.pageSizeReset(perPage, {fetch: false});
+      this.setDocPerPageLimit(perPage);
+    },
+
+    paginate: function (options) {
+      var collection = this.documentsView.collection;
+
+      this.documentsView.forceRender();
+      collection.paging.pageSize = options.perPage;
+      var promise = collection[options.direction]({fetch: false});
+    },
+
+    reloadDesignDocs: function (event) {
+      this.sidebar.forceRender();
+
+      if (event && event.selectedTab) {
+        this.sidebar.setSelectedTab(event.selectedTab);
+      }
+    },
+
+    setDocPerPageLimit: function (perPage) {
+      window.localStorage.setItem('fauxton:perpage', perPage);
+    },
+
+
+    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);
+      }
+    },
+
+    changes: function () {
+      var docParams = app.getParams();
+      this.database.buildChanges(docParams);
+
+      this.changesView = this.setView("#dashboard-lower-content", new Changes.Changes({
+        model: this.database
+      }));
+
+      this.filterView = new Components.FilterView({
+        eventNamespace: "changes"
+      });
+
+      this.headerView = this.setView("#dashboard-upper-content", new Changes.ChangesHeader({
+        filterView: this.filterView
+      }));
+
+      this.toolsView && this.toolsView.remove();
+      this.viewEditor && this.viewEditor.remove();
+
+      this.sidebar.setSelectedTab('changes');
+
+      this.leftheader.updateCrumbs(crumbs.changes(this.database));
+      this.leftheader.forceRender();
+      this.rightHeader.updateApiUrl([this.database.url("changes-apiurl"), this.database.documentation()]);
+    },
+
+    addFilter: function (filter) {
+      this.changesView.filters.push(filter);
+      this.changesView.render();
+    },
+
+    removeFilter: function (filter) {
+      this.changesView.filters.splice(this.changesView.filters.indexOf(filter), 1);
+      this.changesView.render();
+    },
+
+  });
+
+  return DocumentsRouteObject;
+});
+

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/1e0f4de0/app/addons/documents/routes.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/routes.js b/app/addons/documents/routes.js
index c176116..02106c8 100644
--- a/app/addons/documents/routes.js
+++ b/app/addons/documents/routes.js
@@ -11,544 +11,18 @@
 // the License.
 
 define([
-  "app",
-
-  "api",
-
-  // Modules
-  //views
   "addons/documents/views",
-  "addons/documents/views-changes",
-  "addons/documents/views-index",
-  "addons/documents/views-doceditor",
-
-  "addons/databases/base",
-  "addons/documents/resources",
-  "addons/fauxton/components"
+  "addons/documents/routes-documents",
+  "addons/documents/routes-doc-editor",
 ],
 
-function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resources, Components) {
-
-  var DocEditorRouteObject = FauxtonAPI.RouteObject.extend({
-    layout: "one_pane",
-    disableLoader: true,
-    selectedHeader: "Databases",
-    initialize: function(route, masterLayout, options) {
-      var databaseName = options[0];
-      this.docID = options[1]||'new';
-
-      this.database = this.database || new Databases.Model({id: databaseName});
-      this.doc = new Documents.Doc({
-        _id: this.docID
-      }, {
-        database: this.database
-      });
-    },
-
-    routes: {
-      "database/:database/:doc/code_editor": "code_editor",
-      "database/:database/:doc": "code_editor"
-    },
-
-    events: {
-      "route:reRenderDoc": "reRenderDoc",
-      "route:duplicateDoc": "duplicateDoc"
-    },
-
-    crumbs: function() {
-      return [
-        {"name": this.database.id, "link": Databases.databaseUrl(this.database)},
-        {"name": this.docID, "link": "#"}
-      ];
-    },
-
-    code_editor: function (database, doc) {
-
-      this.docView = this.setView("#dashboard-content", new DocEditor.CodeEditor({
-        model: this.doc,
-        database: this.database
-      }));
-    },
-
-    reRenderDoc: function () {
-      this.docView.forceRender();
-    },
-
-    duplicateDoc: function (newId) {
-      var doc = this.doc,
-      docView = this.docView,
-      database = this.database;
-      this.docID = newId;
-
-      doc.copy(newId).then(function () {
-        doc.set({_id: newId});
-        docView.forceRender();
-        FauxtonAPI.navigate('/database/' + database.safeID() + '/' + app.utils.safeURLName(newId), {trigger: true});
-        FauxtonAPI.addNotification({
-          msg: "Document has been duplicated."
-        });
-
-      }, function (error) {
-        var errorMsg = "Could not duplicate document, reason: " + error.responseText + ".";
-        FauxtonAPI.addNotification({
-          msg: errorMsg,
-          type: "error"
-        });
-      });
-    },
-
-    apiUrl: function() {
-      return [this.doc.url("apiurl"), this.doc.documentation()];
-    }
-  });
-
-  var NewDocEditorRouteObject = DocEditorRouteObject.extend({
-    initialize: function (route, masterLayout, options) {
-      var databaseName = options[0];
-
-      this.database = this.database || new Databases.Model({id: databaseName});
-      this.doc = new Documents.NewDoc(null,{
-        database: this.database
-      });
-
-    },
-    crumbs: function() {
-      return [
-        {"name": this.database.id, "link": Databases.databaseUrl(this.database)},
-        {"name": "New", "link": "#"}
-      ];
-    },
-    routes: {
-      "database/:database/new": "code_editor"
-    },
-    selectedHeader: "Databases",
-
-  });
-
-  var DocumentsRouteObject = FauxtonAPI.RouteObject.extend({
-    layout: "with_tabs_sidebar",
-    selectedHeader: "Databases",
-    routes: {
-
-      "database/:database/_all_docs(:extra)": {
-        route: "allDocs",
-        roles: ["_reader","_writer","_admin"]
-      },
-      "database/:database/_design/:ddoc/_views/:view": {
-        route: "viewFn",
-        roles: ['_admin']
-      },
-      "database/:database/_design/:ddoc/_lists/:fn": {
-        route: "tempFn",
-        roles: ['_admin']
-      },
-      "database/:database/_design/:ddoc/_filters/:fn": {
-        route: "tempFn",
-        roles: ['_admin']
-      },
-      "database/:database/_design/:ddoc/_show/:fn": {
-        route: "tempFn",
-        roles: ['_admin']
-      },
-      "database/:database/_design/:ddoc/metadata": {
-        route: "designDocMetadata",
-        roles: ['_admin']
-      },
-      "database/:database/new_view": "newViewEditor",
-      "database/:database/new_view/:designDoc": "newViewEditor",
-      "database/:database/_changes(:params)": "changes"
-    },
-
-    events: {
-      "route:updateAllDocs": "updateAllDocsFromView",
-      "route:updatePreviewDocs": "updateAllDocsFromPreview",
-      "route:reloadDesignDocs": "reloadDesignDocs",
-      "route:paginate": "paginate",
-      "route:perPageChange": "perPageChange",
-      "route:changesFilterAdd": "addFilter",
-      "route:changesFilterRemove": "removeFilter"
-    },
-
-    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: '_design0',
-          include_docs: true,
-          limit: 500
-        }
-      });
-
-      this.sidebar = this.setView("#sidebar-content", new Documents.Views.Sidebar({
-        collection: this.data.designDocs,
-        database: this.data.database
-      }));
-
-    },
-    designDocMetadata:  function(database, ddoc){
-      this.toolsView && this.toolsView.remove();
-      this.viewEditor && this.viewEditor.remove();
-
-      var designDocInfo = new Resources.DdocInfo({_id: "_design/"+ddoc},{database: this.data.database });
-
-      this.setView("#dashboard-lower-content", new Documents.Views.DdocInfo({
-        ddocName: ddoc,
-        model: designDocInfo
-      }));
-
-      this.sidebar.setSelectedTab(app.utils.removeSpecialCharacters(ddoc)+"_metadata");
-
-      this.crumbs = function () {
-        return [
-          {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)},
-        ];
-      };
-
-      this.apiUrl = [designDocInfo.url('apiurl'), designDocInfo.documentation() ];
-
-    },
-    tempFn:  function(databaseName, ddoc, fn){
-      this.setView("#dashboard-upper-content", new Documents.Views.temp({}));
-      this.crumbs = function () {
-        return [
-          {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)},
-        ];
-      };
-
-    },
-
-    establish: function () {
-      return this.data.designDocs.fetch({reset: true});
-    },
-
-    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)})
-      };
-    },
-
-    /*
-    * docParams are the options collection uses to fetch from the server
-    * urlParams are what are shown in the url and to the user
-    * They are not the same when paginating
-    */
-    allDocs: function(databaseName, options) {
-      var params = this.createParams(options),
-          urlParams = params.urlParams,
-          docParams = params.docParams;
-
-      if (this.eventAllDocs) {
-        this.eventAllDocs = false;
-        return;
-      }
-
-      this.data.database.buildAllDocs(docParams);
-
-      if (docParams.startkey && docParams.startkey.indexOf('_design') > -1) {
-        this.sidebar.setSelectedTab('design-docs');
-      } else {
-        this.sidebar.setSelectedTab('all-docs');
-      }
-
-      this.viewEditor && this.viewEditor.remove();
-
-      this.data.database.allDocs.paging.pageSize = this.getDocPerPageLimit(urlParams, parseInt(docParams.limit, 10));
-
-      this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.AllDocsLayout({
-        database: this.data.database,
-        collection: this.data.database.allDocs,
-        params: urlParams,
-        docParams: docParams
-      }));
-
-      this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
-        database: this.data.database,
-        collection: this.data.database.allDocs,
-        docParams: docParams,
-        params: urlParams,
-        bulkDeleteDocsCollection: new Documents.BulkDeleteDocCollection([], {databaseId: this.data.database.get('id')})
-      }));
-
-      this.crumbs = [
-        {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)}
-      ];
-
-      this.apiUrl = [this.data.database.allDocs.urlRef("apiurl", urlParams), this.data.database.allDocs.documentation() ];
-    },
-
-    viewFn: function (databaseName, ddoc, view) {
-      var params = this.createParams(),
-          urlParams = params.urlParams,
-          docParams = params.docParams,
-          decodeDdoc = decodeURIComponent(ddoc);
-
-      view = view.replace(/\?.*$/,'');
-
-      this.data.indexedDocs = new Documents.IndexCollection(null, {
-        database: this.data.database,
-        design: decodeDdoc,
-        view: view,
-        params: docParams,
-        paging: {
-          pageSize: this.getDocPerPageLimit(urlParams, parseInt(docParams.limit, 10))
-        }
-      });
-
-      this.viewEditor = this.setView("#dashboard-upper-content", new Index.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)
-      }));
-
-      this.toolsView && this.toolsView.remove();
-
-      this.documentsView = this.createViewDocumentsView({
-        designDoc: decodeDdoc,
-        docParams: docParams,
-        urlParams: urlParams,
-        database: this.data.database,
-        indexedDocs: this.data.indexedDocs,
-        designDocs: this.data.designDocs,
-        view: view
-      });
-
-      this.sidebar.setSelectedTab(app.utils.removeSpecialCharacters(ddoc) + '_' + app.utils.removeSpecialCharacters(view));
-
-      this.crumbs = function () {
-        return [
-          {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)},
-        ];
-      };
-
-      this.apiUrl = [this.data.indexedDocs.urlRef("apiurl", urlParams), "docs"];
-    },
-
-    ddocInfo: function (designDoc, designDocs, view) {
-      return {
-        id: "_design/" + designDoc,
-        currView: view,
-        designDocs: designDocs
-      };
-    },
-
-    createViewDocumentsView: function (options) {
-
-      return this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
-        database: options.database,
-        collection: options.indexedDocs,
-        nestedView: Documents.Views.Row,
-        viewList: true,
-        ddocInfo: this.ddocInfo(options.designDoc, options.designDocs, options.view),
-        docParams: options.docParams,
-        params: options.urlParams
-      }));
-    },
-
-    newViewEditor: function (database, designDoc) {
-      var params = app.getParams();
-
-      this.toolsView && this.toolsView.remove();
-      this.documentsView && this.documentsView.remove();
-
-      this.viewEditor = this.setView("#dashboard-upper-content", new Index.ViewEditor({
-        currentddoc: "_design/"+designDoc || "",
-        ddocs: this.data.designDocs,
-        params: params,
-        database: this.data.database,
-        newView: true
-      }));
-
-      this.sidebar.setSelectedTab('new-view');
-      this.crumbs = function () {
-        return [
-          {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)},
-        ];
-      };
-    },
-
-    updateAllDocsFromView: function (event) {
-      var view = event.view,
-          params = this.createParams(),
-          urlParams = params.urlParams,
-          docParams = params.docParams,
-          ddoc = event.ddoc,
-          pageSize,
-          collection;
-
-      var defaultPageSize = _.isUndefined(this.documentsView) ? 20 : this.documentsView.perPage();
-      docParams.limit = pageSize = this.getDocPerPageLimit(urlParams, defaultPageSize);
-
-      if (event.allDocs) {
-        this.eventAllDocs = true; // this is horrible. But I cannot get the trigger not to fire the route!
-        this.data.database.buildAllDocs(docParams);
-        collection = this.data.database.allDocs;
-        collection.paging.pageSize = pageSize;
-
-      } else {
-        collection = this.data.indexedDocs = new Documents.IndexCollection(null, {
-          database: this.data.database,
-          design: ddoc,
-          view: view,
-          params: docParams,
-          paging: {
-            pageSize: pageSize
-          }
-        });
-
-        if (!this.documentsView) {
-          this.documentsView = this.createViewDocumentsView({
-            designDoc: ddoc,
-            docParams: docParams,
-            urlParams: urlParams,
-            database: this.data.database,
-            indexedDocs: this.indexedDocs,
-            designDocs: this.data.designDocs,
-            view: view
-          });
-        }
-      }
-
-      this.documentsView.setCollection(collection);
-      this.documentsView.setParams(docParams, urlParams);
-      this.documentsView.forceRender();
-
-      this.apiUrl = [collection.urlRef("apiurl", urlParams), "docs"];
-    },
-
-    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("#dashboard-lower-content", new Documents.Views.AllDocsList({
-        database: this.data.database,
-        collection: this.data.indexedDocs,
-        nestedView: Documents.Views.Row,
-        viewList: true
-      }));
-    },
-
-    perPageChange: function (perPage) {
-      // We need to restore the collection parameters to the defaults (1st page)
-      // and update the page size
-      this.perPage = perPage;
-      this.documentsView.forceRender();
-      this.documentsView.collection.pageSizeReset(perPage, {fetch: false});
-      this.setDocPerPageLimit(perPage);
-    },
-
-    paginate: function (options) {
-      var collection = this.documentsView.collection;
-
-      this.documentsView.forceRender();
-      collection.paging.pageSize = options.perPage;
-      var promise = collection[options.direction]({fetch: false});
-    },
-
-    reloadDesignDocs: function (event) {
-      this.sidebar.forceRender();
-
-      if (event && event.selectedTab) {
-        this.sidebar.setSelectedTab(event.selectedTab);
-      }
-    },
-
-    setDocPerPageLimit: function (perPage) {
-      window.localStorage.setItem('fauxton:perpage', perPage);
-    },
-
-
-    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);
-      }
-    },
-
-    changes: function () {
-      var docParams = app.getParams();
-      this.data.database.buildChanges(docParams);
-
-      this.changesView = this.setView("#dashboard-lower-content", new Changes.Changes({
-        model: this.data.database
-      }));
-
-      this.filterView = new Components.FilterView({
-        eventNamespace: "changes"
-      });
-      this.headerView = this.setView("#dashboard-upper-content", new Changes.ChangesHeader({
-        filterView: this.filterView
-      }));
-
-      this.toolsView && this.toolsView.remove();
-      this.viewEditor && this.viewEditor.remove();
-
-      this.sidebar.setSelectedTab('changes');
-
-      this.crumbs = function () {
-        return [
-          {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)},
-          {"name": "_changes", "link": "/_changes"}
-        ];
-      };
-
-      this.apiUrl = function() {
-        return [this.data.database.url("changes-apiurl"), this.data.database.documentation()];
-      };
-    },
-
-    addFilter: function (filter) {
-      this.changesView.filters.push(filter);
-      this.changesView.render();
-    },
-
-    removeFilter: function (filter) {
-      this.changesView.filters.splice(this.changesView.filters.indexOf(filter), 1);
-      this.changesView.render();
-    },
-
-  });
+function(Documents, DocumentsRouteObject, docEditor) {
 
-  Documents.RouteObjects = [DocEditorRouteObject, NewDocEditorRouteObject, DocumentsRouteObject];
+  Documents.RouteObjects = [
+    docEditor.DocEditorRouteObject, 
+    docEditor.NewDocEditorRouteObject, 
+    DocumentsRouteObject
+  ];
 
   return Documents;
 });

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/1e0f4de0/app/addons/documents/templates/header_alldocs.html
----------------------------------------------------------------------
diff --git a/app/addons/documents/templates/header_alldocs.html b/app/addons/documents/templates/header_alldocs.html
new file mode 100644
index 0000000..b353d89
--- /dev/null
+++ b/app/addons/documents/templates/header_alldocs.html
@@ -0,0 +1,31 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+  <!-- floats right -->
+
+  <div id="header-api-bar" class="button"></div>
+
+  <!-- Query Options-->
+  <!--<div class="button header-query-options">
+    <div id="query-options"></div>
+  </div>-->
+
+  <!-- search (jump to doc)-->
+  <div id="header-search" class="js-search searchbox-container"></div>
+
+  <!-- Select toggle -->
+  <!--<div id="header-select-all" class="button">
+    <span class="toggle-select-menu icon fonticon-ok-circled">Select</span>
+  </div>-->
+

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/1e0f4de0/app/addons/documents/tests/routeSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/routeSpec.js b/app/addons/documents/tests/routeSpec.js
index e2eaca8..2927845 100644
--- a/app/addons/documents/tests/routeSpec.js
+++ b/app/addons/documents/tests/routeSpec.js
@@ -19,14 +19,6 @@ define([
   describe('Documents Route', function () {
 
     describe('changes route', function () {
-
-      it('Should set correct changes api url', function () {
-        var docRoute = new DocumentRoute('changes', {}, ['fakeDB']);
-        docRoute.changes();
-
-        assert.ok(/\/database\/fakeDB\/_changes\?descending=true&limit=100&include_docs=true/.test(docRoute.apiUrl()[0]));
-      });
-
     });
   });
 

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/1e0f4de0/app/addons/documents/views-doceditor.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/views-doceditor.js b/app/addons/documents/views-doceditor.js
index e05b8f4..d1cc85c 100644
--- a/app/addons/documents/views-doceditor.js
+++ b/app/addons/documents/views-doceditor.js
@@ -26,13 +26,10 @@ define([
        "plugins/prettify"
 ],
 
-function(app, FauxtonAPI, Components, Documents, Databases,
-         resizeColumns, prettify) {
+function(app, FauxtonAPI, Components, Documents, Databases, resizeColumns, prettify) {
 
   var Views = {};
 
-  /* Attachments upload modal */
-
   Views.UploadModal = Components.ModalView.extend({
     template: "addons/documents/templates/upload_modal",
 
@@ -141,19 +138,20 @@ function(app, FauxtonAPI, Components, Documents, Databases,
           editorId: "string-editor-container",
           mode: "plain"
         });
-        this.subEditor.render();
+
+        this.subEditor.render().promise().then(function () {
         /* optimize by disabling auto sizing (35 is the lines fitting into the pop-up) */
-        this.subEditor.configureFixedHeightEditor(35);
+          this.subEditor.configureFixedHeightEditor(35);
+        }.bind(this));
       }
     },
 
     cleanup: function () {
-      if (this.subEditor) this.subEditor.remove();
+      if (this.subEditor) { this.subEditor.remove(); }
     }
 
   });
 
-
   /* Doc Duplication modal */
   Views.DuplicateDocModal = Components.ModalView.extend({
     template: "addons/documents/templates/duplicate_doc_modal",
@@ -232,16 +230,15 @@ function(app, FauxtonAPI, Components, Documents, Databases,
       var selEnd = this.editor.getSelectionEnd().row;
       /* one JS(ON) string can't span more than one line - we edit one string, so ensure we don't select several lines */
       if (selStart >=0 && selEnd >= 0 && selStart === selEnd && this.editor.isRowExpanded(selStart)) {    
-        var editLine = this.editor.getLine(selStart);
-	var editMatch = editLine.match(/^([ \t]*)("[a-zA-Z0-9_]*": )?(".*",?[ \t]*)$/);
-	if (editMatch) {
+        var editLine = this.editor.getLine(selStart),
+            editMatch = editLine.match(/^([ \t]*)("[a-zA-Z0-9_]*": )?(".*",?[ \t]*)$/);
+
+        if (editMatch) {
           return editMatch;
-	} else {
-          return null;
-	}
-      } else {
-        return null;
-      }
+        }
+      } 
+
+      return null;
     }, 
 
     showHideEditDocString: function (event) {
@@ -312,14 +309,10 @@ function(app, FauxtonAPI, Components, Documents, Databases,
 
     beforeRender: function () {
       this.uploadModal = this.setView('#upload-modal', new Views.UploadModal({model: this.model}));
-      this.uploadModal.render();
-
       this.duplicateModal = this.setView('#duplicate-modal', new Views.DuplicateDocModal({model: this.model}));
 
       /* initialization is automatic - and make sure ONCE */
       this.stringEditModal = this.stringEditModal || this.setView('#string-edit-modal', new Views.StringEditModal());
-      /* this.stringEditModal.render(); */
-      this.duplicateModal.render();
     },
 
     upload: function (event) {
@@ -473,6 +466,8 @@ function(app, FauxtonAPI, Components, Documents, Databases,
           editor,
           model;
 
+      this.listenTo(this.model, "sync", this.updateValues);
+
       this.editor = new Components.Editor({
         editorId: "editor-container",
         forceMissingId: true,
@@ -485,46 +480,51 @@ function(app, FauxtonAPI, Components, Documents, Databases,
           readOnly: true // false if this command should not apply in readOnly mode
         }]
       });
+
       this.editor.render();
 
       editor = this.editor;
       model = this.model;
+      //only start listening to editor once it has been rendered
+      this.editor.promise().then(function () {
+
+        this.listenTo(editor.editor, "change", function (event) {
+          var changedDoc;
+          try {
+            changedDoc = JSON.parse(editor.getValue());
+          } catch(exception) {
+            //not complete doc. Cannot work with it
+            return;
+          }
+
+          var keyChecked = ["_id"];
+          if (model.get("_rev")) { keyChecked.push("_rev");}
+
+          //check the changedDoc has all the required standard keys
+          if (_.isEmpty(_.difference(keyChecked, _.keys(changedDoc)))) { return; }
+
+          editor.setReadOnly(true);
+          setTimeout(function () { editor.setReadOnly(false);}, 400);
+          // use extend so that _id stays at the top of the object with displaying the doc
+          changedDoc = _.extend({_id: model.id, _rev: model.get("_rev")}, changedDoc);
+          editor.setValue(JSON.stringify(changedDoc, null, "  "));
+          FauxtonAPI.addNotification({
+            type: "error",
+            msg: "Cannot remove a documents Id or Revision.",
+            clear:  true
+          });
+        });
 
-      this.listenTo(this.model, "sync", this.updateValues);
-      this.listenTo(editor.editor, "change", function (event) {
-        var changedDoc;
-        try {
-          changedDoc = JSON.parse(editor.getValue());
-        } catch(exception) {
-          //not complete doc. Cannot work with it
-          return;
-        }
-
-        var keyChecked = ["_id"];
-        if (model.get("_rev")) { keyChecked.push("_rev");}
-
-        //check the changedDoc has all the required standard keys
-        if (_.isEmpty(_.difference(keyChecked, _.keys(changedDoc)))) { return; }
+        var showHideEditDocString = _.bind(this.showHideEditDocString, this);
 
-        editor.setReadOnly(true);
-        setTimeout(function () { editor.setReadOnly(false);}, 400);
-        // use extend so that _id stays at the top of the object with displaying the doc
-        changedDoc = _.extend({_id: model.id, _rev: model.get("_rev")}, changedDoc);
-        editor.setValue(JSON.stringify(changedDoc, null, "  "));
-        FauxtonAPI.addNotification({
-          type: "error",
-          msg: "Cannot remove a documents Id or Revision.",
-          clear:  true
+        this.listenTo(editor.editor, "changeSelection", function (event) {
+          showHideEditDocString(event);
+        });
+        this.listenTo(editor.editor.session, "changeBackMarker", function (event) {
+          showHideEditDocString(event);
         });
-      });
 
-      var that = this;
-      this.listenTo(editor.editor, "changeSelection", function (event) {
-        that.showHideEditDocString(event);
-      });
-      this.listenTo(editor.editor.session, "changeBackMarker", function (event) {
-        that.showHideEditDocString(event);
-      });
+      }.bind(this));
     },
 
     cleanup: function () {

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/1e0f4de0/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/views.js b/app/addons/documents/views.js
index 185c975..c6a6bf9 100644
--- a/app/addons/documents/views.js
+++ b/app/addons/documents/views.js
@@ -38,6 +38,120 @@ function(app, FauxtonAPI, Components, Documents, Databases, Views, QueryOptions,
     });
   }
 
+  Views.RightAllDocsHeader = FauxtonAPI.View.extend({
+    className: "header-right",
+    template: "addons/documents/templates/header_alldocs",
+    events: {
+      'click .toggle-select-menu': 'selectAllMenu'
+    },
+
+    initialize: function(options){
+      //adding the database to the object
+      this.database = options.database;
+      _.bindAll(this);
+      this.selectVisible = false;
+      FauxtonAPI.Events.on('advancedOptions:updateView', this.updateAllDocs);
+      FauxtonAPI.Events.on('success:bulkDelete', this.selectAllMenu);
+    },
+
+    cleanup:function(){
+      FauxtonAPI.Events.unbind('advancedOptions:updateView');
+      FauxtonAPI.Events.unbind('success:bulkDelete');
+    },
+
+    selectAllMenu: function(e){
+      FauxtonAPI.triggerRouteEvent("toggleSelectHeader");
+      FauxtonAPI.Events.trigger("documents:showSelectAll",this.selectVisible);
+    },
+
+    addAllDocsMenu: function(){
+      //search docs
+      this.headerSearch = this.insertView("#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.queryOptions = this.insertView("#query-options", new QueryOptions.AdvancedOptions({
+        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({}));
+    },
+
+    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(){
+      this.addAllDocsMenu();
+    },
+
+    //moved from alldocs layout
+    updateAllDocs: function (event, paramInfo) {
+      event.preventDefault();
+
+      var errorParams = paramInfo.errorParams,
+          params = paramInfo.params;
+
+      if (_.any(errorParams)) {
+        _.map(errorParams, function(param) {
+          return FauxtonAPI.addNotification({
+            msg: "JSON Parse Error on field: "+param.name,
+            type: "error",
+            clear:  true
+          });
+        });
+        FauxtonAPI.addNotification({
+          msg: "Make sure that strings are properly quoted and any other values are valid JSON structures",
+          type: "warning",
+          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});
+    }
+  });
 
   Views.DeleteDBModal = Components.ModalView.extend({
     template: "addons/documents/templates/delete_database_modal",

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/1e0f4de0/app/addons/fauxton/components.js
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/components.js b/app/addons/fauxton/components.js
index a58de19..2087394 100644
--- a/app/addons/fauxton/components.js
+++ b/app/addons/fauxton/components.js
@@ -35,6 +35,43 @@ 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.dropdownEvents = options.dropdownEvents;
+      this.dropdownMenuLinks = options.dropdownMenu;
+      this.crumbs = options.crumbs || [];
+    },
+    updateCrumbs: function(crumbs){
+      this.crumbs = crumbs;
+      this.breadcrumbs && this.breadcrumbs.update(crumbs);
+    },
+    updateDropdown: function(menuLinks){
+      this.dropdownMenuLinks = 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,
+          events: this.dropdownEvents
+        }));
+      }
+    }
+  });
+
   Components.Breadcrumbs = FauxtonAPI.View.extend({
     className: "breadcrumb pull-left",
     tagName: "ul",
@@ -742,11 +779,31 @@ function(app, FauxtonAPI, ace, spin, ZeroClipboard) {
     className: "dropdown",
     initialize: function(options){
       this.links = options.links;
+      this.icon = options.icon || "fonticon-plus-circled";
+      this.setUpEvents();
+    },
+    setUpEvents: function(){
+      this.events = {};
+      _.each(this.links, function (parentLink) {
+        _.each(parentLink.links, function (link) {
+          if (!link.trigger) { return; }
+          this.events['click .' + link.icon] = "triggerEvent";
+        }, this);
+      }, this);
+    },
+    triggerEvent: function(e){
+      e.preventDefault();
+      var eventTrigger = $(e.currentTarget).attr('triggerEvent');
+      FauxtonAPI.Events.trigger(eventTrigger);
+    },
+    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
       };
     }
   });

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/1e0f4de0/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..420b90b
--- /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" class="add-dropdown"></div>

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/1e0f4de0/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..ba73793 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,10 @@ the License.
     <% } %>
     <% _.each(linkSection.links, function (link) { %>
       <li>
-        <a 
+        <a
+          <% if (link.trigger){ %> data-bypass="true" triggerEvent="<%-link.trigger%>" <%}%>
           <% if (link.icon) { %>
-          class="icon <%- link.icon %>" 
+          class="icon <%- link.icon %>"
           <% } %>
           href="<%- link.url %>">
           <%- link.title %>
@@ -31,3 +32,4 @@ the License.
     <%});%>
   <%});%>
  </ul>
+

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/1e0f4de0/app/core/api.js
----------------------------------------------------------------------
diff --git a/app/core/api.js b/app/core/api.js
index 1b21dca..9007195 100644
--- a/app/core/api.js
+++ b/app/core/api.js
@@ -26,6 +26,8 @@ function(FauxtonAPI, Layout, Router, RouteObject, utils) {
     utils: utils
   });
 
+  FauxtonAPI.Events = _.extend({}, Backbone.Events);
+
   FauxtonAPI.navigate = function(url, _opts) {
     var options = _.extend({trigger: true}, _opts );
     FauxtonAPI.router.navigate(url,options);

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/1e0f4de0/app/templates/layouts/with_tabs_sidebar.html
----------------------------------------------------------------------
diff --git a/app/templates/layouts/with_tabs_sidebar.html b/app/templates/layouts/with_tabs_sidebar.html
index 3d86130..125f75c 100644
--- a/app/templates/layouts/with_tabs_sidebar.html
+++ b/app/templates/layouts/with_tabs_sidebar.html
@@ -13,22 +13,18 @@ the License.
 -->
 
 <div id="primary-navbar"></div>
-<div id="dashboard" class="container-fluid">
-
-  <div class="fixed-header">
-    <div id="breadcrumbs"></div>
+<div id="dashboard" class="container-fluid with-sidebar">
+  <div id="global-notifications" class="container errors-container window-resizeable"></div>
+  <header class="fixed-header row-fluid">
+    <div id="breadcrumbs" class="sidebar"></div>
     <div id="api-navbar" class="window-resizeable"></div>
-  </div>
+  </header>
 
   <div class="with-sidebar content-area">
-
-    <div id="tabs" class="row-fluid"></div>
-
     <aside id="sidebar-content" class="sidebar"></aside>
 
     <section id="dashboard-content" class="list pull-right window-resizeable">
       <div class="inner">
-        <!-- <div id="dashboard-upper-menu" class="window-resizeable"></div> -->
         <div id="dashboard-upper-content">
 
         </div>
@@ -39,3 +35,4 @@ the License.
 
   </div>
 </div>
+

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/1e0f4de0/assets/less/fauxton.less
----------------------------------------------------------------------
diff --git a/assets/less/fauxton.less b/assets/less/fauxton.less
index efd8613..86b2147 100644
--- a/assets/less/fauxton.less
+++ b/assets/less/fauxton.less
@@ -595,7 +595,7 @@ table.databases {
   .closeMenu & {
     left: @collapsedNavWidth;
   }
-  border-bottom: 5px solid @breadcrumbBorder;
+  //border-bottom: 5px solid @breadcrumbBorder;
   .box-shadow(0 4px 6px -2px #808080);
   z-index: 100;
   .one-pane & {
@@ -1101,7 +1101,7 @@ div.add-dropdown {
 
 #breadcrumbs {
   height: 60px;
-  width: @sidebarWidth - 4;
+  width: @sidebarWidth;
   /* these styles are for the new header*/
   .header-left{
     > div{
@@ -1147,7 +1147,7 @@ div.add-dropdown {
   position: relative;
   #header-dropdown-menu {
     position: absolute;
-    right: 0;
+    right: 5px;
     top: 0;
     .dropdown-toggle {
       color: #666666;


Mime
View raw message