couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From deathb...@apache.org
Subject [06/26] 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
Date Wed, 06 Aug 2014 19:31:13 GMT
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/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/dbdd1fe3/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/dbdd1fe3/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/dbdd1fe3/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..e7a2282
--- /dev/null
+++ b/app/addons/indexes/routes-list.js
@@ -0,0 +1,70 @@
+// 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"
+],
+
+function (app, FauxtonAPI, Databases, Views, Documents, Resources, RouteCore) {
+
+  var ListIndexes = RouteCore.extend({
+    routes: {
+      "database/:database/_design/:ddoc/_lists/:fn": {
+        route: "tempFn",
+        roles: ['_admin']
+      },
+      "database/:database/new_list": "newListsEditor",
+      "database/:database/_design/:designDoc/new_list": "newListsEditor"
+    },
+
+    apiUrl: function() {
+      //TODO: Hook up proper API urls
+      return '';
+    },
+
+    newListsEditor: function (database, designDoc) {
+      var params = app.getParams();
+
+      this.setView("#left-content", new Views.ListEditor({
+        currentddoc: "_design/"+designDoc || "",
+        ddocs: this.data.designDocs,
+        params: params,
+        database: this.data.database,
+        newView: true
+      }));
+
+      this.setView("#right-content", new Views.PreviewScreen({}));
+      this.crumbs = function () {
+        return [
+          {"name": "Create List Index", "link": Databases.databaseUrl(this.data.database)},
+        ];
+      };
+    },
+    tempFn:  function(databaseName, ddoc, fn){
+      this.setView("#left-content", new Views.ListEditor({}));
+
+      this.setView("#right-content", new Views.PreviewScreen({}));
+      this.crumbs = function () {
+        return [
+          {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)},
+        ];
+      };
+    }
+  });
+
+  return ListIndexes;
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/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..9c9e451
--- /dev/null
+++ b/app/addons/indexes/routes-show.js
@@ -0,0 +1,71 @@
+// 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"
+],
+
+function (app, FauxtonAPI, Databases, Views, Documents, Resources, RouteCore) {
+
+  var ShowIndexes = RouteCore.extend({
+    routes: {
+      "database/:database/_design/:ddoc/_show/:fn": {
+        route: "tempFn",
+        roles: ['_admin']
+      },
+      "database/:database/new_show": "newShowEditor",
+      "database/:database/_design/:designDoc/new_show": "newShowEditor"
+    },
+
+    newShowEditor: function (database, designDoc) {
+      var params = app.getParams();
+
+      this.setView("#left-content", new Views.ShowEditor({
+        currentddoc: "_design/"+designDoc || "",
+        ddocs: this.data.designDocs,
+        params: params,
+        database: this.data.database,
+        newView: true
+      }));
+
+      this.setView("#right-content", new Views.PreviewScreen({}));
+      this.crumbs = function () {
+        return [
+          {"name": "Create Show Index", "link": Databases.databaseUrl(this.data.database)},
+        ];
+      };
+    },
+
+    apiUrl: function() {
+      //TODO: Hook up proper API urls
+      return '';
+    },
+
+    tempFn:  function(databaseName, ddoc, fn){
+      this.setView("#left-content", new Views.ShowEditor({}));
+
+      this.setView("#right-content", new Views.PreviewScreen({}));
+      this.crumbs = function () {
+        return [
+          {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)},
+        ];
+      };
+    }
+  });
+
+  return ShowIndexes;
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/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..86006f3
--- /dev/null
+++ b/app/addons/indexes/routes-viewindexes.js
@@ -0,0 +1,106 @@
+// 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"
+],
+
+function (app, FauxtonAPI, Databases, Views, Documents, Resources, RouteCore) {
+
+  var ViewIndexes = RouteCore.extend({
+    routes: {
+      "database/:database/_design/:ddoc/_view/:view": {
+        route: "viewFn",
+        roles: ['_admin']
+      },
+      "database/:database/new_view": "newViewEditor",
+      "database/:database/_design/:designDoc/new_view": "newViewEditor"
+    },
+
+    newViewEditor: function (database, designDoc) {
+      var params = app.getParams();
+
+      this.setView("#right-content", new Views.PreviewScreen({}));
+
+      this.viewEditor = this.setView("#left-content", new Views.ViewEditor({
+        currentddoc: "_design/"+designDoc || "",
+        ddocs: this.data.designDocs,
+        params: params,
+        database: this.data.database,
+        newView: true
+      }));
+
+      this.crumbs = function () {
+        return [
+          {"name": "Create View Index", "link": Databases.databaseUrl(this.data.database)},
+        ];
+      };
+    },
+
+    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 Resources.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("#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)
+      }));
+
+      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.crumbs = function () {
+        return [
+          {"name": view, "link": Databases.databaseUrl(this.data.database)},
+        ];
+      };
+
+      this.apiUrl = [this.data.indexedDocs.urlRef("apiurl", urlParams), "docs"];
+    }
+  });
+
+  return ViewIndexes;
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/app/addons/indexes/routes.js
----------------------------------------------------------------------
diff --git a/app/addons/indexes/routes.js b/app/addons/indexes/routes.js
new file mode 100644
index 0000000..90c9aac
--- /dev/null
+++ b/app/addons/indexes/routes.js
@@ -0,0 +1,24 @@
+// 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/indexes/views",
+  "addons/indexes/routes-viewindexes",
+  "addons/indexes/routes-show",
+  "addons/indexes/routes-list",
+],
+
+function (app, FauxtonAPI, Views, ViewIndex, Show, List) {
+  Views.RouteObjects = [ViewIndex, Show, List];
+  return Views;
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/app/addons/indexes/templates/design_doc_selector.html
----------------------------------------------------------------------
diff --git a/app/addons/indexes/templates/design_doc_selector.html b/app/addons/indexes/templates/design_doc_selector.html
new file mode 100644
index 0000000..d12cd64
--- /dev/null
+++ b/app/addons/indexes/templates/design_doc_selector.html
@@ -0,0 +1,38 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+<div class="span3">
+  <label for="ddoc">Save to Design Document <a class="help-link" data-bypass="true" href="<%-getDocUrl('design_doc')%>" target="_blank"><i class="icon-question-sign"></i></a></label>
+  <select id="ddoc">
+    <optgroup label="Select a document">
+      <option value="new-doc">New document</option>
+
+      <% ddocs.each(function(ddoc) { %>
+      <%= ddoc.id %>
+      <%= ddocName %>
+      <% if (ddoc.id === ddocName) { %>
+      <option selected="selected" value="<%- ddoc.id %>"><%- ddoc.id %></option>
+      <% } else { %>
+      <option value="<%- ddoc.id %>"><%- ddoc.id %></option>
+      <% } %>
+      <% }); %>
+    </optgroup>
+  </select>
+</div>
+
+<div id="new-ddoc-section" class="span5" style="display:none">
+  <label class="control-label" for="new-ddoc"> _design/ </label>
+  <div class="controls">
+    <input type="text" id="new-ddoc" placeholder="newDesignDoc" />
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/app/addons/indexes/templates/index_header.html
----------------------------------------------------------------------
diff --git a/app/addons/indexes/templates/index_header.html b/app/addons/indexes/templates/index_header.html
new file mode 100644
index 0000000..662f3ea
--- /dev/null
+++ b/app/addons/indexes/templates/index_header.html
@@ -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.
+-->
+
+<div class="header-left">
+
+<!--back arrow-->
+<span class="icon "
+
+<!--title-->
+
+<!-- Menu gear-->
+
+</div>
+
+
+<div class="header-right">
+  <!-- Query Options-->
+  <!--right margin for api bar-->
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/app/addons/indexes/templates/index_row_docular.html
----------------------------------------------------------------------
diff --git a/app/addons/indexes/templates/index_row_docular.html b/app/addons/indexes/templates/index_row_docular.html
new file mode 100644
index 0000000..ba88d06
--- /dev/null
+++ b/app/addons/indexes/templates/index_row_docular.html
@@ -0,0 +1,35 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+<% if (doc.isEditable()) { %>
+  <div class="select"><input type="checkbox"></div>
+<% } %>
+
+<div class="doc-item">
+  <header>
+    _id <span class="header-id-number">"<%=docID%>"</span>
+
+    <div class="doc-menu">
+      <a href="#<%= url %>" class="doc-menu-item icon fonticon-pencil"></a>
+      <% if (doc.isEditable()) { %>
+        <button href="#" class="btn btn-small btn-danger delete" title="Delete this document."><i class="icon icon-trash"></i></button>
+      <% } %>
+
+      <div id="view-doc-menu" class="doc-menu-item"></div>
+    </div>
+  </header>
+  <div class="doc-data">
+    <pre class="prettyprint"><%- doc.prettyJSON() %></pre>
+  </div>
+</div>
+<div class="clearfix"></div>

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/app/addons/indexes/templates/list_editor.html
----------------------------------------------------------------------
diff --git a/app/addons/indexes/templates/list_editor.html b/app/addons/indexes/templates/list_editor.html
new file mode 100644
index 0000000..d36004c
--- /dev/null
+++ b/app/addons/indexes/templates/list_editor.html
@@ -0,0 +1,39 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+<div class="all-docs-list errors-container"></div>
+<div id="define-view" class="ddoc-alert index-form">
+  <div class="errors-container"></div>
+  <form class="form-horizontal view-query-save">
+    <div class="control-group">
+      <p>Views are the primary tool used for querying and reporting on CouchDB databases.</p>
+    </div>
+
+    <div class="control-group design-doc-group">
+    </div>
+
+
+    <div class="control-group">
+      <label for="index-name">Index name <a class="help-link" href="<%-getDocUrl('view_functions')%>" target="_blank"><i class="icon-question-sign"></i></a></label>
+      <input type="text" id="index-name" value="<%- viewName %>" placeholder="Index name" />
+    </div>
+
+    <div class="control-group">
+      <button class="btn btn-success save"><i class="icon fonticon-ok-circled"></i> Save &amp; Build Index</button>
+      <% if (!newView) { %>
+      <button class="btn btn-danger delete"><i class="icon fonticon-cancel-circled"></i> Delete</button>
+      <% } %>
+    </div>
+    <div class="clearfix"></div>
+  </form>
+</div>=

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/app/addons/indexes/templates/preview_screen.html
----------------------------------------------------------------------
diff --git a/app/addons/indexes/templates/preview_screen.html b/app/addons/indexes/templates/preview_screen.html
new file mode 100644
index 0000000..654e557
--- /dev/null
+++ b/app/addons/indexes/templates/preview_screen.html
@@ -0,0 +1,16 @@
+<!--
+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.
+-->
+
+<h3>No Index Created Yet!</h3>
+<p> Run <span class="btn btn-success preview icon fonticon-play"> Preview</span> to query result</p>

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/app/addons/indexes/templates/show_editor.html
----------------------------------------------------------------------
diff --git a/app/addons/indexes/templates/show_editor.html b/app/addons/indexes/templates/show_editor.html
new file mode 100644
index 0000000..9afa2bf
--- /dev/null
+++ b/app/addons/indexes/templates/show_editor.html
@@ -0,0 +1,41 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<div class="all-docs-list errors-container"></div>
+<div id="define-view" class="ddoc-alert index-form">
+  <div class="errors-container"></div>
+  <form class="form-horizontal view-query-save">
+    <div class="control-group">
+      <p>Views are the primary tool used for querying and reporting on CouchDB databases.</p>
+    </div>
+
+    <div class="control-group design-doc-group">
+    </div>
+
+
+    <div class="control-group">
+      <label for="index-name">Index name <a class="help-link" href="<%-getDocUrl('view_functions')%>" target="_blank"><i class="icon-question-sign"></i></a></label>
+      <input type="text" id="index-name" value="<%- viewName %>" placeholder="Index name" />
+    </div>
+
+
+    <div class="control-group">
+      <button class="btn btn-success save"><i class="icon fonticon-ok-circled"></i> Save &amp; Build Index</button>
+      <% if (!newView) { %>
+      <button class="btn btn-danger delete"><i class="icon fonticon-cancel-circled"></i> Delete</button>
+      <% } %>
+    </div>
+    <div class="clearfix"></div>
+  </form>
+</div>=

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/app/addons/indexes/templates/view_editor.html
----------------------------------------------------------------------
diff --git a/app/addons/indexes/templates/view_editor.html b/app/addons/indexes/templates/view_editor.html
new file mode 100644
index 0000000..f33d3f9
--- /dev/null
+++ b/app/addons/indexes/templates/view_editor.html
@@ -0,0 +1,80 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+<div class="all-docs-list errors-container"></div>
+<div id="define-view" class="ddoc-alert index-form">
+  <div class="errors-container"></div>
+  <form class="form-horizontal view-query-save">
+    <div class="control-group">
+      <p>Views are the primary tool used for querying and reporting on CouchDB databases.</p>
+    </div>
+
+
+    <div class="control-group">
+      <label for="index-name">Database name</label>
+      <p><%- database %></p>
+    </div>
+
+
+    <div class="control-group design-doc-group">
+    </div>
+
+
+    <div class="control-group">
+      <label for="index-name">Index name <a class="help-link" href="<%-getDocUrl('view_functions')%>" target="_blank"><i class="icon-question-sign"></i></a></label>
+      <input type="text" id="index-name" value="<%- viewName %>" placeholder="Index name" />
+    </div>
+
+    <div class="control-group">
+      <label for="map-function">Map function <a class="help-link" href="<%-getDocUrl('map_functions')%>" target="_blank"><i class="icon-question-sign"></i></a></label>
+      <% if (newView) { %>
+      <div class="js-editor" id="map-function"><%= langTemplates.map %></div>
+      <% } else { %>
+      <div class="js-editor" id="map-function"><%- ddoc.get('views')[viewName].map %></div>
+      <button class="beautify beautify_map btn btn-primary btn-large hide beautify-tooltip" type="button" data-toggle="tooltip" title="Reformat your minified code to make edits to it.">beautify this code</button>
+      <% } %>
+    </div>
+
+
+    <div class="control-group">
+      <label for="reduce-function-selector">Reduce (optional) <a class="help-link" href="<%-getDocUrl('reduce_functions')%>" target="_blank"><i class="icon-question-sign"></i></a></label>
+
+      <select id="reduce-function-selector">
+        <option value="" <%- !reduceFunStr ? 'selected="selected"' : '' %>>None</option>
+        <% _.each(["_sum", "_count", "_stats"], function(reduce) { %>
+        <option value="<%- reduce %>" <% if (reduce == reduceFunStr) { %>selected<% } %>><%= reduce %></option>
+        <% }) %>
+        <option value="CUSTOM" <% if (isCustomReduce) { %>selected<% } %>>Custom Reduce function</option>
+      </select>
+    </div>
+
+    <div class="control-group reduce-function">
+      <label for="reduce-function">Custom Reduce function</label>
+      <% if (newView) { %>
+      <div class="js-editor" id="reduce-function"><%- langTemplates.reduce %></div>
+      <% } else { %>
+      <div class="js-editor" id="reduce-function"><%- ddoc.get('views')[viewName].reduce %></div>
+      <button class="beautify beautify_reduce btn btn-primary btn-large hide beautify-tooltip" type="button" data-toggle="tooltip" title="Reformat your minified code to make edits to it.">beautify this code</button>
+      <% } %>
+    </div>
+
+    <div class="control-group">
+      <button class="btn btn-success save"><i class="icon fonticon-ok-circled"></i> Save &amp; Build Index</button>
+      <% if (!newView) { %>
+      <button class="btn btn-danger delete"><i class="icon fonticon-cancel-circled"></i> Delete</button>
+      <% } %>
+    </div>
+    <div class="clearfix"></div>
+  </form>
+</div>
+

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/app/addons/indexes/views.js
----------------------------------------------------------------------
diff --git a/app/addons/indexes/views.js b/app/addons/indexes/views.js
new file mode 100644
index 0000000..73ed6ea
--- /dev/null
+++ b/app/addons/indexes/views.js
@@ -0,0 +1,678 @@
+// 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 = {};
+
+  //Index view CORE  extend this
+  Views.IndexCore = FauxtonAPI.View.extend({
+    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();
+      }
+    },
+    serialize: function() {
+      return {
+        database: this.database.get('id'),
+        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
+      };
+    }
+  });
+
+
+
+  Views.IndexHeader = Views.IndexCore.extend({
+    template: "addons/indexes/templates/index_header"
+  });
+
+  Views.PreviewScreen = Views.IndexCore.extend({
+    template: "addons/indexes/templates/preview_screen",
+    className: "watermark-logo"
+  });
+
+  Views.ShowEditor = FauxtonAPI.View.extend({
+    template: "addons/indexes/templates/show_editor",
+    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);
+    },
+  });
+
+  Views.ListEditor = FauxtonAPI.View.extend({
+    template: "addons/indexes/templates/list_editor",
+  });
+
+
+
+  Views.Row = FauxtonAPI.View.extend({
+    template: "addons/indexes/templates/index_row_docular",
+    className: "doc-row",
+    events: {
+      "click button.delete": "destroy"
+    },
+
+    destroy: function (event) {
+      event.preventDefault();
+
+      window.alert('Cannot delete a document generated from a view.');
+    },
+
+    beforeRender: function(){
+      var newLinks = [{
+        links: [{
+          title: 'Table',
+          icon: 'fonticon-table'
+        },{
+          title: 'JSON',
+          icon: 'fonticon-json'
+        }]
+      }];
+
+      this.insertView("#view-doc-menu", new Components.MenuDropDown({
+        icon: 'fonticon-drop-down-dots',
+        links: newLinks,
+      }));
+    },
+
+    serialize: function() {
+      return {
+        docID: this.model.get('id'),
+        doc: this.model,
+        url: this.model.url('app')
+      };
+    }
+  });
+
+
+
+
+
+
+  Views.ViewEditor = FauxtonAPI.View.extend({
+    template: "addons/indexes/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"
+    },
+
+    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
+      //check if the code is valid & the inputs are filled out
+      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;
+        this.viewNameChange = false;
+
+
+        if (this.viewName !== viewName) {
+          ddoc.removeDdocView(this.viewName);
+          this.viewName = viewName;
+          this.viewNameChange = true;
+        }
+
+        notification = FauxtonAPI.addNotification({
+          msg: "Saving document.",
+          selector: "#define-view .errors-container",
+          clear: true
+        });
+
+        ddoc.setDdocView(viewName, mapVal, reduceVal);
+
+        ddoc.save().then(function () {
+          //on success
+          that.afterSave(ddoc, viewName, ddocName);
+        },
+        function(xhr) {
+          //on failure
+          var responseText = JSON.parse(xhr.responseText).reason;
+          notification = FauxtonAPI.addNotification({
+            msg: "Save failed: " + responseText,
+            type: "error",
+            clear: true
+          });
+        });
+      } else {
+        //if nothing is filled out give an error message
+        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
+        });
+      }
+    },
+
+    afterSave: function(ddoc, viewName, ddocName){
+      var reduceVal = this.reduceVal();
+      //add ddoc to the collection
+      this.ddocs.add(ddoc);
+
+      //trigger the EditSaved function on the map editor & reduce editor
+      this.mapEditor.editSaved();
+      this.reduceEditor && this.reduceEditor.editSaved();
+
+
+      //show a notification
+      FauxtonAPI.addNotification({
+        msg: "View has been saved.",
+        type: "success",
+        selector: "#define-view .errors-container",
+        clear: true
+      });
+
+
+      //if it's new or the name changed (aka created a new doc)
+      if (this.newView || this.viewNameChange) {
+        var fragment = '/database/' + this.database.safeID() +'/' + ddoc.safeID() + '/_view/' + app.utils.safeURLName(viewName);
+
+        FauxtonAPI.navigate(fragment, {trigger: false});
+        this.newView = false;
+        this.ddocID = ddoc.safeID();
+        this.viewName = viewName;
+        this.ddocInfo = ddoc;
+        this.showIndex = true;
+        this.render();
+        FauxtonAPI.triggerRouteEvent('reloadDesignDocs', {
+          selectedTab: app.utils.removeSpecialCharacters(ddocName.replace(/_design\//,'')) + '_' + app.utils.removeSpecialCharacters(viewName)
+        });
+      }
+
+      // TODO:// this should change to a trigger because we shouldn't define advanced options in this view
+      if (this.reduceFunStr !== reduceVal) {
+        this.reduceFunStr = reduceVal;
+       // this.advancedOptions.renderOnUpdatehasReduce(this.hasReduce());
+      }
+
+      // Route Event will reload the right content
+      FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: ddocName, view: viewName});
+    },
+
+    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);
+    },
+
+
+    serialize: function() {
+      return {
+        database: this.database.get('id'),
+        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
+      }));
+
+    },
+
+    afterRender: function() {
+      //TODO: have this happen on a trigger once we move advanced options to the header
+      // if (this.params && !this.newView) {
+      //   this.advancedOptions.updateFromParams(this.params);
+      // }
+
+      this.designDocSelector.updateDesignDoc();
+      this.showEditors();
+      this.showIndex = false;
+
+    },
+
+    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/indexes/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/dbdd1fe3/app/templates/layouts/two_pane.html
----------------------------------------------------------------------
diff --git a/app/templates/layouts/two_pane.html b/app/templates/layouts/two_pane.html
index 031ad12..52b7d2a 100644
--- a/app/templates/layouts/two_pane.html
+++ b/app/templates/layouts/two_pane.html
@@ -12,18 +12,16 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 
-
 <div id="primary-navbar"></div>
-<div id="dashboard" class="container-fluid">
-  <div class="fixed-header">
+<div id="dashboard" class="container-fluid two-pane">
+
+  <header class="fixed-header">
     <div id="breadcrumbs"></div>
     <div id="api-navbar"></div>
-  </div>
+  </header>
 
-
-  <div class="row-fluid content-area">
-    <div id="left-content" class="span6"></div>
-    <div id="right-content" class="span6"></div>
+  <div class="content-area two-pane">
+    <div id="left-content" class="span6 window-resizeable"></div>
+    <div id="right-content" class="span6 window-resizeable"></div>
   </div>
 </div>
-

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/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 a0ed03d..65d702e 100644
--- a/app/templates/layouts/with_tabs_sidebar.html
+++ b/app/templates/layouts/with_tabs_sidebar.html
@@ -21,9 +21,6 @@ the License.
   </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">

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/assets/img/couchWatermark.png
----------------------------------------------------------------------
diff --git a/assets/img/couchWatermark.png b/assets/img/couchWatermark.png
new file mode 100644
index 0000000..cab9ce4
Binary files /dev/null and b/assets/img/couchWatermark.png differ

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/assets/less/fauxton.less
----------------------------------------------------------------------
diff --git a/assets/less/fauxton.less b/assets/less/fauxton.less
index 10b1e78..3ddcff9 100644
--- a/assets/less/fauxton.less
+++ b/assets/less/fauxton.less
@@ -22,7 +22,8 @@
 @import "bootstrap/mixins.less";
 @import "prettyprint.less";
 @import "icons.less";
-
+@import "templates.less";
+@import "formstyles.less";
 /**
  * HTML-wide overrides
  **/
@@ -56,28 +57,7 @@ a:hover {
   color: @red;
 }
 
-input[type=text],
-input[type=password] {
-  .border-radius(0);
-  padding: 12px;
-  border: 1px solid #ccc;
-  height: auto;
-  font-size: 16px;
-  margin-top: 0;
-}
-
-input[type="checkbox"],
-input[type="radio"] {
-  box-sizing: border-box;
-  padding: 0;
-}
 
-input[type="file"],
-input[type="checkbox"],
-input[type="radio"],
-select {
-  margin: 0 0 1em 0;
-}
 
 
 /* bootstrap overrides */
@@ -166,109 +146,7 @@ tbody {
   background-color: #F7F7F7;
 }
 
-/*form elements and buttons*/
-.btn-group {
-  > .btn + .dropdown-toggle,
-  > .btn:first-child,
-  > .btn:last-child,
-  > .dropdown-toggle {
-    .border-radius(0);
-    background-image: none;
-    text-shadow: none;
-  }
-}
-
-.btn {
-  .box-shadow(none);
-  .border-radius(@baseBorderRadius);
-  background-image: none;
-  text-shadow: none;
-  background-repeat: no-repeat;
-  padding: 10px;
-  margin-top: 0px;
-  .icon {
-    margin-right: 0.2em;
-  }
-  &.btn-small {
-    padding: 5px 10px;
-    .icon {
-      margin-right: 0;
-      font-size: inherit;
-    }
-  }
-  &.btn-mini {
-    padding: 3px 8px;
-    .icon {
-      margin-right: 0;
-      font-size: inherit;
-    }
-  }
-}
-.btn-primary {
-  background: @redButton;
-}
-
-.btn-primary a:visited {
-  color: #fff;
-}
 
-.form-actions {
-  background: none;
-  border: none;
-}
-
-.input-append,
-.input-prepend {
-  .add-on {
-    font-size: 18px;
-    padding: 14px 5px 30px;
-  }
-  .btn .icon {
-    font-size: 21.5px;
-    margin-right: 0;
-  }
-}
-
-.row-fluid .input-append [class*="span"],
-.input-prepend input[class*="span"] {
-  width: auto;
-}
-
-.form-inline {
-  input[type=password],
-  input[type=text] {
-    width: auto;
-  }
-}
-.checkbox {
-  label {
-    display: inline-block;
-    padding-left:25px;
-  }
-}
-
-label {
-  margin-right: 15px;
-  padding-left:0;
-  display: block;
-  cursor: pointer;
-  position: relative;
-  font-size: 14px;
-  &.inline {
-    display: inline-block;
-  }
-}
-.help-block {
-  font-size: 12px;
-}
-
-a.help-link:hover {
-  text-decoration: none;
-}
-
-input[type=text].error {
-  border: red 1px solid;
-}
 
 /**
  * Fauxton-specific Bootstrap additions
@@ -297,457 +175,9 @@ table.databases {
   }
 }
 
-/* ajax loader */
-.loader {
-  background: url('../img/loader.gif') center center no-repeat;
-  min-height:  100px;
-}
-#app-container.loader{
-  min-height: 400px;
-  > *{
-    display: none;
-  }
-}
-
-#global-notifications {
-  position: fixed;
-  top: 0px;
-  display: block;
-  z-index: 100000;
-  left: @navWidth;
-  .closeMenu & {
-    left: @collapsedNavWidth;
-  }
-  width: 100%;
-}
-
-#app-container{
-  padding: 0;
-  height: 100%;
-  width: 100%;
-  position: absolute;
-  top: 0;
-  left: 0;
-  > .row-fluid {
-    height: 100%;
-  }
-}
-
-/* Fixed side navigation */
-#primary-navbar {
-  /* hack for the scrollbar that shines through from the sidebar */
-  -webkit-transform: translate3d(0, 0, 0);
-  height: 100%;
-  position: fixed;
-  width: @navWidth;
-  top: 0;
-  bottom: 0;
-  background-color: @primaryNav;
-  overflow-y: scroll;
-  .version {
-    color: #fff;
-    font-size: 10px;
-    padding-left: 10px;
-  }
-  #footer-links{
-    position: absolute;
-    bottom: 0;
-    width: 100%;
-  }
-  #user-create-admin{
-    font-size: 12px
-  }
-  .navbar {
-     .burger{
-        .transition(all @transitionSpeed @transitionEaseType);
-        padding: 22px 0 0 18px;
-        position: fixed;
-        top: 0;
-        background-color: @primaryNav;
-        width: @navWidth;
-        div{
-          .transition(all @transitionSpeed @transitionEaseType);
-          height: 4px;
-          width: 24px;
-          .border-radius(2);
-          background-color: @navBG;
-          margin: 2px 0px;
-        }
-        &:hover div{
-          background-color: @orange;
-        }
-      }
-      .bottom-container {
-	     height: 110px;
-	     position: fixed;
-	     bottom: 0;
-	     width: 220px;
-	     background: #3a2c2b;
-       .brand {
-         .box-sizing(content-box);
-         .hide-text;
-         .customTransition(left, 1s, 0.805, 0.005, 0.165, 0.985);
-         margin: 10px 0 0 0;
-         width: 200px;
-         height: 40px;
-         padding: 10px;
-         float: none;
-         background: #3a2c2b;
-         .icon {
-           .box-sizing(content-box);
-           background: url(../img/couchdb-site.png) no-repeat 0 0;
-           display: block;
-           height: 100%;
-           width: 100%;
-         }
-         .closeMenu & {
-           .icon {
-              background: url(../img/minilogo.png) no-repeat 0 0;
-            }
-            width: 45px;
-          }
-       }
-       #footer-nav-links {
-	     li {
-		   a {
-		     font-size: 12px;
-		     color: @red;
-		     padding: 12px;
-		     text-shadow: none;
-		   }
-		   &.active, &:hover{
-             a {
-               text-decoration: underline;
-             }
-           }
-		 }
-       }
-    }
-    nav {
-      margin-top: 64px;
-      .nav{
-        margin: 0;
-        li{
-          .transition(all @transitionSpeed @transitionEaseType);
-          padding: 0;
-          font-size: 16px;
-          letter-spacing: 1px;
-          line-height: 23px;
-          width: @navWidth;
-          font-weight: normal;
-          font-family: helvetica;
-          .box-sizing(border-box);
-          background-color: @navBG;
-          border-bottom:  1px solid @primaryNav;
-          min-height: 48px;
-          &.active, &:hover{
-            a{
-              .box-shadow(none);
-            }
-            background-color: @red;
-          }
-          &:hover .fonticon:before{
-            color: @white;
-          }
-          &.active .fonticon:before,
-          &:hover .fonticon:before,
-          {
-            text-shadow: @boxShadow;
-            color: @NavIconActive;
-          }
-          a{
-            padding: 12px 25px 12px 60px;
-            background-color: transparent;
-            color: #fff;
-            text-shadow: @textShadowOff;
-            &.closeMenu{
-              color: transparent;
-            }
-            .fonticon {
-              position: relative;
-              &:before {
-                position: absolute;
-                top: -5px;
-                left: -41px;
-                font-size: 24px;
-                color: @NavIcon;
-                text-shadow: @boxShadowOff;
-              }
-            }
-            .closeMenu &{
-              color: transparent;
-            }
-          }
-        }
-      }
-      ul#footer-nav-links{
-        li{
-          background-color: @primaryNav;
-          border-top: 1px solid @red;
-          border-bottom: none;
-          font-size: 12px;
-          padding: 12px;
-          min-height: 44px;
-          &.active, &:hover{
-            background-color: @linkRed;
-            border-top: 1px solid @red;
-            a{
-              color: white;
-            }
-          }
-          a{
-            color: @red;
-          }
-        }
-
-      }
-      ul#bottom-nav-links{
-        margin-top: 0;
-        padding-bottom: 70px;
-        li{
-          min-height: 55px;
-          background-color: @bottomNav;
-          &.active{
-            background-color:@linkRed;
-          }
-          &:hover{
-            background-color: @navBGHover;
-          }
-          a{
-            &.fonticon {
-              position: relative;
-              &:before {
-                top: -5px;
-                left: -40px;
-                font-size: 22px;
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-
-
-#dashboard {
-  .box-shadow(-6px 0 rgba(0, 0, 0, 0.1));
-  border-left: 1px solid #999;
-  position: absolute;
-  left: @navWidth;
-  margin-left: 0;
-  padding-left: 0;
-  padding-right: 0;
-  background-color: @sidebarBG;
-  min-width: 600px;
-  height: 100%;
-  .closeMenu &{
-    left: @collapsedNavWidth;
-  }
-  &.one-pane{
-    min-width: 800px;
-    margin-top: 0;
-    overflow-x: hidden;
-  }
-}
-
-/*dashboard content can be in multiple templates*/
-
-#dashboard-content{
-  &.row-fluid,
-  &.window-resizeable{
-    /*remove gutter without rewriting variable*/
-    margin-left: 0px;
-  }
-  padding: 20px;
-  .with-sidebar &{
-    border-left: 1px solid #999;
-    border-right: 1px solid #999;
-    width: auto;
-    .box-shadow(-6px 0 rgba(0, 0, 0, 0.1));
-    padding: 0px;
-    bottom: 0px;
-    top: 60px;
-    position: fixed;
-    overflow-x: hidden;
-    overflow-y: auto;
-    left: @sidebarWidth+@navWidth;
-    right: 0;
-    .box-sizing(border-box);
-    .closeMenu & {
-      left: @sidebarWidth+@collapsedNavWidth;
-    }
-  }
-  > div.inner {
-    display: block;
-  }
-}
-
-.with-sidebar.content-area {
-  position: absolute;
-  top: 0;
-  bottom: 0;
-  left: 0;
-  right: 0;
-}
-
-// .closeMenu .with-sidebar.content-area {
-//   left: 0;
-// }
-/*tools*/
-
-.row-fluid.content-area{
-  background-color: @background;
-}
-
-
-.fixed-header{
-  background-color: @breadcrumbBG;
-  position: fixed;
-  top: 0;
-  right: 0;
-  left: @navWidth;
-  .closeMenu & {
-    left: @collapsedNavWidth;
-  }
-  border-bottom: 5px solid @breadcrumbBorder;
-  .box-shadow(0 4px 6px -2px #808080);
-  z-index: 100;
-  .one-pane & {
-    position: relative;
-    border: none;
-    .box-shadow(none);
-    left: auto;
-  }
-}
-
-#breadcrumbs {
-   .breadcrumb {
-    margin: 15px 20px;
-    margin-bottom: 0;
-    background-color: transparent;
-    padding: 0;
-    li {
-      .divider {
-        font-size: 12px;
-        color: @breadcrumbArrow;
-      }
-      &:first-child {
-        font-size: 30px;
-      }
-      color: @breadcrumbText;
-      font-size: 18px;
-      text-shadow: none;
-      &.active{
-        color: #333;
-      }
-      a{
-        color: @breadcrumbText;
-      }
-    }
-   }
-}
-
-
-/*SIDEBAR TEMPLATE STYLES*/
-.topmenu-defaults {
-  height: 70px;
-  padding: 12px 10px 0;
-  .box-sizing(border-box);
-}
-
-.dashboard-upper-menu{
-  right: 0;
-  left: @sidebarWidth+@navWidth;
-  position: fixed;
-  z-index: 11;
-  display: block;
-  .topmenu-defaults;
-  background-color: #CBCBCB;
-  .closeMenu & {
-    left: @sidebarWidth+@collapsedNavWidth;
-  }
-}
-
-#dashboard-lower-content{
-  padding: 20px;
-  background-color: #F1F1F1;
-}
-
-#dashboard-upper-content{
-  .tab-content {
-    padding-top: 70px;
-  }
-  .well{
-    padding: 20px;
-    .border-radius(0);
-    .box-shadow(none);
-  }
-}
-
-.sidenav {
-  padding: 0;
-  header {
-    width: @sidebarWidth;
-    border-bottom: 1px solid #d3d7db;
-  }
-  .nav-list{
-    .divider {
-      border: none;
-    }
-    > li > a:hover,
-    > li > a:focus{
-      background-color: @darkRed;
-      color: #fff;
-    }
-    li.active > a {
-      color: @darkRed;
-    }
-    > li > a{
-      color: @linkRed;
-      padding: 10px 13px 10px 24px;
-      border-bottom: 1px solid #d3d7db;
-      span{
-        margin-right: 8px;
-        width: 14px;
-        display: inline-block;
-        text-align: center;
-      }
-    }
-    a{
-      display: block;
-      padding: 10px 5px 5px 15px;
-      color: @subListGray;
-      .divider {
-        background: none;
-        color: #ccc;
-        padding: 0 2px;
-      }
-    }
-    .nav-header{
-      padding: 0px;
-      text-shadow: none;
-      color: #333333;
-      & > span:hover {
-        color: @red;
-      }
-    }
-  }
-}
 
-#sidebar-content {
-  position: absolute;
-  top: 60px;
-  width: @sidebarWidth;
-  left: 0;
-  background-color: @secondarySidebar;
-  > div.inner {
-    display: block;
-  }
-}
 
 
-/*ONE PANEL TEMPLATE ONLY STYLES  AKA _all_dbs */
 
 .result-tools{
   border-bottom: 1px solid #999999;
@@ -803,76 +233,7 @@ table.databases {
   }
 }
 
-.custom-inputs{
-
-  input[type=radio],
-  input[type=checkbox] {
-    display: none;
-  }
-
-  .checkbox label:before {
-    border-radius: 3px;
-  }
-
-  .controls > .radio:first-child, .controls > .checkbox:first-child {
-    padding-top: 15px;
-  }
-
-  .radio.inline, .checkbox.inline {
-    display: inline-block;
-    padding-top: 15px;
-    margin-bottom: 12px;
-    vertical-align: middle;
-  }
-
-  input[type=checkbox]:checked + label:before {
-    /*content: "\2713"; */
-    content: "\00d7";
-    text-shadow: 1px 1px 1px rgba(0, 0, 0, .2);
-    font-size: 16px;
-    background-color: @red;
-    color: white;
-    text-align: center;
-    line-height: 15px;
-  }
-
-  label:before {
-    content: "";
-    display: inline-block;
 
-    width: 16px;
-    height: 16px;
-
-    margin-right: 10px;
-    position: absolute;
-    left: 0;
-    bottom: 1px;
-    background-color: #aaa;
-    box-shadow: inset 0px 2px 3px 0px rgba(0, 0, 0, .3), 0px 1px 0px 0px rgba(255, 255, 255, .8);
-  }
-
-  .radio label:before {
-    border-radius: 8px;
-  }
-
-  input[type=radio]:checked + label:before {
-    content: "\2022";
-    color: #f3f3f3;
-    font-size: 30px;
-    text-align: center;
-    line-height: 18px;
-  }
-
-  label.drop-down{
-    &:before{
-    display: none;
-    }
-  }
-}
-
-form.view-query-update, form.view-query-save {
-  max-width: 100%;
-}
 
 /*documents and databases */
 .view.show{
@@ -985,39 +346,4 @@ div.spinner {
   }
 }
 
-div.add-dropdown {
-  position: absolute;
-  top: 2px;
-  right: 0px;
-  .dropdown-menu{
-    left: -110px;
-    padding-bottom: 0;
-    width: 148px;
-    min-width: 0;
-    top: 38px;
-    .box-shadow(@boxShadow);
-      &.arrow:before{
-        right: 4px;
-      }
-      a {
-        background-color: #202326;
-        color: rgba(255, 255, 255, 0.8);
-        &:hover{
-          background-color: @red;
-          color: white;
-        }
-      }
-    li a {
-      padding: 10px 15px 10px 12px;
-    }
-  }
-  .dropdown-toggle{
-    border-top: none !important;
-    text-decoration: none;
-  }
-  > a {
-    border-bottom: none;
-    text-decoration: none;
-    font-size: 16px;
-  }
-}
+

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/dbdd1fe3/assets/less/formstyles.less
----------------------------------------------------------------------
diff --git a/assets/less/formstyles.less b/assets/less/formstyles.less
new file mode 100644
index 0000000..4645664
--- /dev/null
+++ b/assets/less/formstyles.less
@@ -0,0 +1,247 @@
+/*  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 "variables.less";
+
+input[type=text],
+input[type=password] {
+  .border-radius(0);
+  padding: 12px;
+  border: 1px solid #ccc;
+  height: auto;
+  font-size: 16px;
+  margin-top: 0;
+}
+
+input[type="checkbox"],
+input[type="radio"] {
+  box-sizing: border-box;
+  padding: 0;
+}
+
+input[type="file"],
+input[type="checkbox"],
+input[type="radio"],
+select {
+  margin: 0 0 1em 0;
+}
+
+/*form elements and buttons*/
+.btn-group {
+  > .btn + .dropdown-toggle,
+  > .btn:first-child,
+  > .btn:last-child,
+  > .dropdown-toggle {
+    .border-radius(0);
+    background-image: none;
+    text-shadow: none;
+  }
+}
+
+.btn {
+  .box-shadow(none);
+  .border-radius(@baseBorderRadius);
+  background-image: none;
+  text-shadow: none;
+  background-repeat: no-repeat;
+  padding: 10px;
+  margin-top: 0px;
+  .icon {
+    margin-right: 0.2em;
+  }
+  &.btn-small {
+    padding: 5px 10px;
+    .icon {
+      margin-right: 0;
+      font-size: inherit;
+    }
+  }
+  &.btn-mini {
+    padding: 3px 8px;
+    .icon {
+      margin-right: 0;
+      font-size: inherit;
+    }
+  }
+}
+.btn-primary {
+  background: @redButton;
+}
+
+.btn-primary a:visited {
+  color: #fff;
+}
+
+.form-actions {
+  background: none;
+  border: none;
+}
+
+.input-append,
+.input-prepend {
+  .add-on {
+    font-size: 18px;
+    padding: 14px 5px 30px;
+  }
+  .btn .icon {
+    font-size: 21.5px;
+    margin-right: 0;
+  }
+}
+
+.row-fluid .input-append [class*="span"],
+.input-prepend input[class*="span"] {
+  width: auto;
+}
+
+.form-inline {
+  input[type=password],
+  input[type=text] {
+    width: auto;
+  }
+}
+.checkbox {
+  label {
+    display: inline-block;
+    padding-left:25px;
+  }
+}
+
+label {
+  margin-right: 15px;
+  padding-left:0;
+  display: block;
+  cursor: pointer;
+  position: relative;
+  font-size: 14px;
+  &.inline {
+    display: inline-block;
+  }
+}
+.help-block {
+  font-size: 12px;
+}
+
+a.help-link:hover {
+  text-decoration: none;
+}
+
+input[type=text].error {
+  border: red 1px solid;
+}
+
+form.view-query-update, form.view-query-save {
+  max-width: 100%;
+}
+.custom-inputs{
+
+  input[type=radio],
+  input[type=checkbox] {
+    display: none;
+  }
+
+  .checkbox label:before {
+    border-radius: 3px;
+  }
+
+  .controls > .radio:first-child, .controls > .checkbox:first-child {
+    padding-top: 15px;
+  }
+
+  .radio.inline, .checkbox.inline {
+    display: inline-block;
+    padding-top: 15px;
+    margin-bottom: 12px;
+    vertical-align: middle;
+  }
+
+  input[type=checkbox]:checked + label:before {
+    /*content: "\2713"; */
+    content: "\00d7";
+    text-shadow: 1px 1px 1px rgba(0, 0, 0, .2);
+    font-size: 16px;
+    background-color: @red;
+    color: white;
+    text-align: center;
+    line-height: 15px;
+  }
+
+  label:before {
+    content: "";
+    display: inline-block;
+
+    width: 16px;
+    height: 16px;
+
+    margin-right: 10px;
+    position: absolute;
+    left: 0;
+    bottom: 1px;
+    background-color: #aaa;
+    box-shadow: inset 0px 2px 3px 0px rgba(0, 0, 0, .3), 0px 1px 0px 0px rgba(255, 255, 255, .8);
+  }
+
+  .radio label:before {
+    border-radius: 8px;
+  }
+
+  input[type=radio]:checked + label:before {
+    content: "\2022";
+    color: #f3f3f3;
+    font-size: 30px;
+    text-align: center;
+    line-height: 18px;
+  }
+
+  label.drop-down{
+    &:before{
+    display: none;
+    }
+  }
+}
+
+div.add-dropdown {
+  position: absolute;
+  top: 2px;
+  right: 0px;
+  .dropdown-menu{
+    left: -110px;
+    padding-bottom: 0;
+    width: 148px;
+    min-width: 0;
+    top: 38px;
+    .box-shadow(@boxShadow);
+      &.arrow:before{
+        right: 4px;
+      }
+      a {
+        background-color: #202326;
+        color: rgba(255, 255, 255, 0.8);
+        &:hover{
+          background-color: @red;
+          color: white;
+        }
+      }
+    li a {
+      padding: 10px 15px 10px 12px;
+    }
+  }
+  .dropdown-toggle{
+    border-top: none !important;
+    text-decoration: none;
+  }
+  > a {
+    border-bottom: none;
+    text-decoration: none;
+    font-size: 16px;
+  }
+}


Mime
View raw message