couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gar...@apache.org
Subject [5/7] git commit: updated refs/heads/fauxton-modularise to 752819c
Date Mon, 06 Jan 2014 14:16:34 GMT
Fauxton: move modules to addons


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

Branch: refs/heads/fauxton-modularise
Commit: fae1de24c23d87621140732178d3b2d7ba445d0e
Parents: 9068db2
Author: Garren Smith <garren.smith@gmail.com>
Authored: Mon Jan 6 12:33:00 2014 +0200
Committer: Garren Smith <garren.smith@gmail.com>
Committed: Mon Jan 6 12:33:00 2014 +0200

----------------------------------------------------------------------
 .gitignore                                      |    4 +
 src/fauxton/app/addons/activetasks/resources.js |    2 +-
 src/fauxton/app/addons/compaction/routes.js     |    2 +-
 src/fauxton/app/addons/databases/base.js        |   37 +
 src/fauxton/app/addons/databases/resources.js   |  193 ++
 src/fauxton/app/addons/databases/routes.js      |   69 +
 .../app/addons/databases/templates/item.html    |   24 +
 .../app/addons/databases/templates/list.html    |   35 +
 .../addons/databases/templates/newdatabase.html |   17 +
 .../app/addons/databases/templates/sidebar.html |   31 +
 src/fauxton/app/addons/databases/views.js       |  255 +++
 src/fauxton/app/addons/documents/base.js        |   24 +
 src/fauxton/app/addons/documents/resources.js   |  638 +++++++
 src/fauxton/app/addons/documents/routes.js      |  408 ++++
 .../documents/templates/advanced_options.html   |   97 +
 .../documents/templates/all_docs_item.html      |   26 +
 .../documents/templates/all_docs_layout.html    |   20 +
 .../documents/templates/all_docs_list.html      |   43 +
 .../documents/templates/all_docs_number.html    |   21 +
 .../app/addons/documents/templates/changes.html |   38 +
 .../addons/documents/templates/ddoc_info.html   |   28 +
 .../templates/design_doc_selector.html          |   35 +
 .../app/addons/documents/templates/doc.html     |   55 +
 .../documents/templates/doc_field_editor.html   |   74 +
 .../templates/doc_field_editor_tabs.html        |   19 +
 .../templates/duplicate_doc_modal.html          |   36 +
 .../addons/documents/templates/edit_tools.html  |   44 +
 .../documents/templates/index_menu_item.html    |   17 +
 .../documents/templates/index_row_docular.html  |   26 +
 .../documents/templates/index_row_tabular.html  |   25 +
 .../app/addons/documents/templates/jumpdoc.html |   19 +
 .../app/addons/documents/templates/search.html  |   15 +
 .../app/addons/documents/templates/sidebar.html |   67 +
 .../app/addons/documents/templates/tabs.html    |   18 +
 .../documents/templates/upload_modal.html       |   42 +
 .../addons/documents/templates/view_editor.html |   87 +
 .../app/addons/documents/tests/resourcesSpec.js |   84 +
 src/fauxton/app/addons/documents/views.js       | 1805 ++++++++++++++++++
 src/fauxton/app/addons/fauxton/base.js          |  266 +++
 src/fauxton/app/addons/fauxton/components.js    |  316 +++
 src/fauxton/app/addons/fauxton/layout.js        |   98 +
 .../app/addons/fauxton/templates/api_bar.html   |   30 +
 .../addons/fauxton/templates/breadcrumbs.html   |   24 +
 .../app/addons/fauxton/templates/footer.html    |   15 +
 .../fauxton/templates/index_pagination.html     |   24 +
 .../app/addons/fauxton/templates/nav_bar.html   |   75 +
 .../addons/fauxton/templates/notification.html  |   18 +
 .../addons/fauxton/templates/pagination.html    |   31 +
 src/fauxton/app/addons/permissions/routes.js    |    2 +-
 src/fauxton/app/addons/pouchdb/base.js          |   47 +
 src/fauxton/app/addons/pouchdb/pouch.collate.js |  115 ++
 .../app/addons/pouchdb/pouchdb.mapreduce.js     |  324 ++++
 src/fauxton/app/addons/replication/views.js     |    2 +-
 src/fauxton/app/addons/stats/resources.js       |    2 +-
 .../app/addons/verifyinstall/resources.js       |    4 +-
 src/fauxton/app/api.js                          |    2 +-
 src/fauxton/app/app.js                          |    8 +-
 src/fauxton/app/modules/databases/base.js       |   37 -
 src/fauxton/app/modules/databases/resources.js  |  193 --
 src/fauxton/app/modules/databases/routes.js     |   69 -
 src/fauxton/app/modules/databases/views.js      |  255 ---
 src/fauxton/app/modules/documents/base.js       |   24 -
 src/fauxton/app/modules/documents/resources.js  |  638 -------
 src/fauxton/app/modules/documents/routes.js     |  408 ----
 .../modules/documents/tests/resourcesSpec.js    |   84 -
 src/fauxton/app/modules/documents/views.js      | 1805 ------------------
 src/fauxton/app/modules/fauxton/base.js         |  276 ---
 src/fauxton/app/modules/fauxton/components.js   |  316 ---
 src/fauxton/app/modules/fauxton/layout.js       |   98 -
 src/fauxton/app/modules/pouchdb/base.js         |   47 -
 .../app/modules/pouchdb/pouch.collate.js        |  115 --
 .../app/modules/pouchdb/pouchdb.mapreduce.js    |  324 ----
 src/fauxton/app/router.js                       |   39 +-
 src/fauxton/settings.json.default               |    3 +
 74 files changed, 5880 insertions(+), 4734 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 1f8c4a6..7f6d618 100644
--- a/.gitignore
+++ b/.gitignore
@@ -102,6 +102,10 @@ src/fauxton/app/addons/*
 !src/fauxton/app/addons/permissions
 !src/fauxton/app/addons/verifyinstall
 !src/fauxton/app/addons/compaction
+!src/fauxton/app/addons/fauxton
+!src/fauxton/app/addons/pouchdb
+!src/fauxton/app/addons/databases
+!src/fauxton/app/addons/documents
 src/fauxton/settings.json*
 !src/fauxton/settings.json.default
 src/ibrowse/ibrowse.app

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/activetasks/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/resources.js b/src/fauxton/app/addons/activetasks/resources.js
index ca732fb..3ac0898 100644
--- a/src/fauxton/app/addons/activetasks/resources.js
+++ b/src/fauxton/app/addons/activetasks/resources.js
@@ -13,7 +13,7 @@
 define([
   "app",
   "backbone",
-  "modules/fauxton/base",
+  "addons/fauxton/base",
   "d3"
 ],
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/compaction/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/compaction/routes.js b/src/fauxton/app/addons/compaction/routes.js
index 2a33e07..ff15c88 100644
--- a/src/fauxton/app/addons/compaction/routes.js
+++ b/src/fauxton/app/addons/compaction/routes.js
@@ -17,7 +17,7 @@ define([
 
        // Modules
        "addons/compaction/views",
-       "modules/databases/resources"
+       "addons/databases/resources"
 ],
 
 function(app, FauxtonAPI, Compaction, Databases) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/databases/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/base.js b/src/fauxton/app/addons/databases/base.js
new file mode 100644
index 0000000..1a3dc66
--- /dev/null
+++ b/src/fauxton/app/addons/databases/base.js
@@ -0,0 +1,37 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+define([
+  "app",
+
+  "api",
+
+  // Modules
+  "addons/databases/routes",
+  // Views
+  "addons/databases/views"
+
+],
+
+function(app, FauxtonAPI, Databases, Views) {
+  Databases.Views = Views;
+
+  // Utility functions
+  Databases.databaseUrl = function(database) {
+    var name = _.isObject(database) ? database.id : database,
+        dbname = app.mixins.safeURLName(name);
+
+    return ["/database/", dbname, "/_all_docs?limit=" + Databases.DocLimit].join('');
+  };
+
+  return Databases;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/databases/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/resources.js b/src/fauxton/app/addons/databases/resources.js
new file mode 100644
index 0000000..b6d6536
--- /dev/null
+++ b/src/fauxton/app/addons/databases/resources.js
@@ -0,0 +1,193 @@
+// 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
+  "addons/documents/resources"
+],
+
+function(app, FauxtonAPI, Documents) {
+  var Databases = FauxtonAPI.addon();
+
+  Databases.DocLimit = 20;
+
+  Databases.Model = Backbone.Model.extend({
+    initialize: function(options) {
+      this.status = new Databases.Status({
+        database: this
+      });
+    },
+
+    documentation: function(){
+      return "all_dbs";
+    },
+    
+    buildAllDocs: function(params) {
+      this.allDocs = new Documents.AllDocs(null, {
+        database: this,
+        params: params
+      });
+
+      return this.allDocs;
+    },
+
+    isNew: function(){
+      // Databases are never new, to make Backbone do a PUT
+      return false;
+    },
+
+    url: function(context) {
+      if (context === "index") {
+        return "/database/" + this.safeID() + "/_all_docs";
+      } else if (context === "web-index") {
+        return "#/database/"+ this.safeID() + "/_all_docs?limit=" + Databases.DocLimit;
+      } else if (context === "apiurl") { 
+        return window.location.origin + "/database/" + this.safeID() + "/_all_docs";
+      } else if (context === "changes") {
+        return "/database/" + this.safeID() + "/_changes?descending=true&limit=100&include_docs=true";
+      } else if (context === "changes-apiurl") { 
+        return window.location.origin + "/database/" + this.safeID() + "/_changes?descending=true&limit=100&include_docs=true";
+      } else if (context === "app") {
+        return "/database/" + this.safeID();
+      } else {
+        return app.host + "/" + this.safeID();
+      }
+    },
+    safeName: function(){
+      return app.mixins.safeURLName(this.get("name"));
+    },
+    safeID: function() {
+      return app.mixins.safeURLName(this.id);
+    },
+    buildChanges: function (params) {
+      this.changes = new Databases.Changes({
+        database: this,
+        params: params
+      });
+
+      return this.changes;
+    }
+  });
+
+  Databases.Changes = Backbone.Collection.extend({
+
+    initialize: function(options) {
+      this.database = options.database;
+      this.params = options.params;
+    },
+    documentation: function(){
+      return "changes";
+    },
+    url: function (context) {
+      var query = "";
+      if (this.params) {
+        query = "?" + $.param(this.params);
+      }
+      if (context === "apiurl") { 
+        return window.location.origin + '/' + this.database.safeID() + '/_changes' + query;
+      } else {
+
+      return app.host + '/' + this.database.safeID() + '/_changes' + query;
+      }
+    },
+
+    parse: function (resp) {
+      this.last_seq = resp.last_seq;
+      return resp.results;
+    }
+  });
+
+  Databases.Status = Backbone.Model.extend({
+    url: function() {
+      return app.host + "/" + this.database.safeID();
+    },
+
+    initialize: function(options) {
+      this.database = options.database;
+    },
+
+    numDocs: function() {
+      return this.get("doc_count");
+    },
+
+    updateSeq: function(full) {
+      var updateSeq = this.get("update_seq");
+      if (full || (typeof(updateSeq) === 'number')) {
+        return updateSeq;
+      } else if (updateSeq) {
+        return updateSeq.split('-')[0];
+      } else {
+        return 0;
+      }
+    },
+
+    humanSize: function() {
+      // cribbed from http://stackoverflow.com/questions/10420352/converting-file-size-in-bytes-to-human-readable
+      var i = -1;
+      var byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB'];
+      var fileSizeInBytes = this.dataSize();
+
+      if (!fileSizeInBytes) {
+        return 0;
+      }
+
+      do {
+          fileSizeInBytes = fileSizeInBytes / 1024;
+          i++;
+      } while (fileSizeInBytes > 1024);
+
+      return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
+    },
+    diskSize: function () {
+      return this.get("disk_size");
+    },
+
+    dataSize: function () {
+      if (this.get("other")){
+        return this.get("other").data_size;
+      }else{
+        return 0;
+      }  
+    }
+  });
+
+  // TODO: shared databases - read from the user doc
+  Databases.List = Backbone.Collection.extend({
+    model: Databases.Model,
+    documentation: function(){
+      return "all_dbs";
+    },
+    url: function(context) {
+      if (context === "apiurl") { 
+        return window.location.origin + "/_all_dbs";
+      } else {
+        return app.host + "/_all_dbs";
+      }
+    },
+
+    parse: function(resp) {
+      // TODO: pagination!
+      return _.map(resp, function(database) {
+        return {
+          id: app.mixins.safeURLName(database),
+          name: database
+        };
+      });
+    }
+  });
+
+  return Databases;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/databases/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/routes.js b/src/fauxton/app/addons/databases/routes.js
new file mode 100644
index 0000000..c413018
--- /dev/null
+++ b/src/fauxton/app/addons/databases/routes.js
@@ -0,0 +1,69 @@
+// 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
+  "addons/databases/resources",
+  // TODO:: fix the include flow modules so we don't have to require views here
+  "addons/databases/views"
+],
+
+function(app, FauxtonAPI, Databases, Views) {
+
+  var AllDbsRouteObject = FauxtonAPI.RouteObject.extend({
+    layout: "one_pane",
+
+    crumbs: [
+      {"name": "Databases", "link": "/_all_dbs"}
+    ],
+
+    routes: {
+      "": "allDatabases",
+      "index.html": "allDatabases",
+      "_all_dbs(:params)": "allDatabases"
+    },
+
+    apiUrl: function() {
+      return [this.databases.url("apiurl"), this.databases.documentation()];
+    },
+
+    selectedHeader: "Databases",
+
+    initialize: function() {
+      this.databases = new Databases.List();
+      this.deferred = FauxtonAPI.Deferred();
+    },
+
+    allDatabases: function() {
+      var params = app.getParams(),
+          dbPage = params.page;
+
+      this.databasesView = this.setView("#dashboard-content", new Views.List({
+        collection: this.databases
+      }));
+
+      this.databasesView.setPage(dbPage);
+    },
+
+    establish: function() {
+     return [this.databases.fetch()];
+    }
+  });
+
+  Databases.RouteObjects = [AllDbsRouteObject];
+
+  return Databases;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/databases/templates/item.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/templates/item.html b/src/fauxton/app/addons/databases/templates/item.html
new file mode 100644
index 0000000..e2f8071
--- /dev/null
+++ b/src/fauxton/app/addons/databases/templates/item.html
@@ -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.
+-->
+
+<td>
+  <a href="#/database/<%=encoded%>/_all_docs?limit=<%=docLimit%>"><%= database.get("name") %></a>
+</td>
+<td><%= database.status.humanSize() %></td>
+<td><%= database.status.numDocs() %></td>
+<td><%= database.status.updateSeq() %></td>
+<td>
+  <a class="db-actions btn fonticon-replicate set-replication-start" title="Replicate <%= database.get("name") %>" href="#/replication/new/<%=encoded%>"></a>
+  <a class="db-actions btn icon-lock set-permissions" title="Set permissions for <%= database.get("name") %>" href="#/database/<%=encoded%>/permissions"></a>
+</td>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/databases/templates/list.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/templates/list.html b/src/fauxton/app/addons/databases/templates/list.html
new file mode 100644
index 0000000..31c0977
--- /dev/null
+++ b/src/fauxton/app/addons/databases/templates/list.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.
+-->
+
+<div class="result-tools" style="">
+  <div id="newButton" class="pull-left"></div>
+  <form id="jump-to-db" class="navbar-form pull-right input-append database-search">
+    <input type="text" class="search-autocomplete" name="search-query" placeholder="Database name"></input>
+    <button class="fonticon-search btn button red " type="submit"></button>
+  </form>
+
+
+</div>
+<table class="databases table table-striped">
+  <thead>
+    <th>Name</th>
+    <th>Size</th>
+    <th># of Docs</th>
+    <th>Update Seq</th>
+    <th>Actions</th>
+  </thead>
+  <tbody>
+  </tbody>
+</table>
+<div id="database-pagination"></div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/databases/templates/newdatabase.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/templates/newdatabase.html b/src/fauxton/app/addons/databases/templates/newdatabase.html
new file mode 100644
index 0000000..b357e0b
--- /dev/null
+++ b/src/fauxton/app/addons/databases/templates/newdatabase.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.
+-->
+
+<a class="button new" id="new"><i class="icon fonticon-new-database"></i>Add New Database</a>
+
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/databases/templates/sidebar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/templates/sidebar.html b/src/fauxton/app/addons/databases/templates/sidebar.html
new file mode 100644
index 0000000..a8bbd89
--- /dev/null
+++ b/src/fauxton/app/addons/databases/templates/sidebar.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.
+-->
+
+<div class="row-fluid">
+  <a href="http://couchdb.org" target="_blank"><img src="img/couchdblogo.png"/></a>
+  <br/>
+</div>
+<hr>
+<ul class="nav nav-list">
+  <!-- <li class="nav-header">Database types</li> -->
+  <li class="active"><a class="toggle-view" id="owned">Your databases</a></li>
+  <li><a class="btn new" id="new"><i class="icon-plus"></i> New database</a></li>
+</ul>
+<hr>
+
+<div>
+  <a class="twitter-timeline" data-dnt="true" href="https://twitter.com/CouchDB" data-widget-id="314360971646869505">Tweets by @CouchDB</a>
+<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
+
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/databases/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/views.js b/src/fauxton/app/addons/databases/views.js
new file mode 100644
index 0000000..80d64ed
--- /dev/null
+++ b/src/fauxton/app/addons/databases/views.js
@@ -0,0 +1,255 @@
+// 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",
+  
+  "addons/fauxton/components",
+  "api",
+  "addons/databases/resources"
+],
+
+function(app, Components, FauxtonAPI, Databases) {
+  var Views = {};
+
+  Views.Item = FauxtonAPI.View.extend({
+    template: "templates/databases/item",
+    tagName: "tr",
+    establish: function(){
+      return [this.model.fetch()];
+    },
+    serialize: function() {
+      return {
+        encoded: app.mixins.safeURLName(this.model.get("name")),
+        database: this.model,
+        docLimit: Databases.DocLimit
+      };
+    }
+  });
+
+  Views.List = FauxtonAPI.View.extend({
+    dbLimit: 20,
+    perPage: 20,
+    template: "templates/databases/list",
+    events: {
+      "click button.all": "selectAll",
+      "submit form#jump-to-db": "switchDatabase"
+    },
+
+    initialize: function(options) {
+      var params = app.getParams();
+      this.page = params.page ? parseInt(params.page, 10) : 1;
+    },
+
+    serialize: function() {
+      return {
+        databases: this.collection
+      };
+    },
+    establish: function(){
+      var currentDBs = this.paginated();
+      var deferred = FauxtonAPI.Deferred();
+
+      FauxtonAPI.when(currentDBs.map(function(database) {
+        return database.status.fetch();
+      })).always(function(resp) {
+        //make this always so that even if a user is not allowed access to a database
+        //they will still see a list of all databases
+        deferred.resolve();
+      });
+      return [deferred];
+    },
+    switchDatabase: function(event, selectedName) {
+      event && event.preventDefault();
+
+      var dbname = this.$el.find("[name='search-query']").val().trim();
+
+      if (selectedName) {
+        dbname = selectedName;
+      }
+
+      if (dbname && this.collection.where({"id":app.mixins.safeURLName(dbname)}).length > 0){
+          // TODO: switch to using a model, or Databases.databaseUrl()
+          // Neither of which are in scope right now
+          // var db = new Database.Model({id: dbname});
+          var url = ["/database/", app.mixins.safeURLName(dbname), "/_all_docs?limit=" + Databases.DocLimit].join('');
+          FauxtonAPI.navigate(url);
+      } else {
+        FauxtonAPI.addNotification({
+          msg: 'Database does not exist.',
+          type: 'error'
+        });
+      }
+    },
+
+    paginated: function() {
+      var start = (this.page - 1) * this.perPage;
+      var end = this.page * this.perPage;
+      return this.collection.slice(start, end);
+    },
+
+    beforeRender: function() {
+
+      this.insertView("#newButton", new Views.NewDatabaseButton({
+        collection: this.collection
+      }));
+
+      _.each(this.paginated(), function(database) {
+        this.insertView("table.databases tbody", new Views.Item({
+          model: database
+        }));
+      }, this);
+
+      this.insertView("#database-pagination", new Components.Pagination({
+        page: this.page,
+        perPage: this.perPage,
+        total: this.collection.length,
+        urlFun: function(page) {
+          return "#/_all_dbs?page=" + page;
+        }
+      }));
+    },
+
+    setPage: function(page) {
+      this.page = page || 1;
+    },
+
+    afterRender: function() {
+      var that = this;
+      this.dbSearchTypeahead = new Components.DbSearchTypeahead({
+        dbLimit: this.dbLimit,
+        el: "input.search-autocomplete",
+        onUpdate: function (item) {
+          that.switchDatabase(null, item);
+        }
+      });
+
+      this.dbSearchTypeahead.render();
+    },
+
+    selectAll: function(evt){
+      $("input:checkbox").attr('checked', !$(evt.target).hasClass('active'));
+    }
+  });
+
+
+  Views.NewDatabaseButton = FauxtonAPI.View.extend({
+    template: "templates/databases/newdatabase",
+    events: {
+      "click a#new": "newDatabase"
+    },
+    newDatabase: function() {
+      var notification;
+      var db;
+      // TODO: use a modal here instead of the prompt
+      var name = prompt('Name of database', 'newdatabase');
+      if (name === null) {
+        return;
+      } else if (name.length === 0) {
+        notification = FauxtonAPI.addNotification({
+          msg: "Please enter a valid database name",
+          type: "error",
+          clear: true
+        });
+        return;
+      }
+      db = new this.collection.model({
+        id: name,
+        name: name
+      });
+      notification = FauxtonAPI.addNotification({msg: "Creating database."});
+      db.save().done(function() {
+        notification = FauxtonAPI.addNotification({
+          msg: "Database created successfully",
+          type: "success",
+          clear: true
+        });
+        var route = "#/database/" +  app.mixins.safeURLName(name) + "/_all_docs?limit=" + Databases.DocLimit;
+        app.router.navigate(route, { trigger: true });
+      }
+      ).error(function(xhr) {
+        var responseText = JSON.parse(xhr.responseText).reason;
+        notification = FauxtonAPI.addNotification({
+          msg: "Create database failed: " + responseText,
+          type: "error",
+          clear: true
+        });
+      }
+      );
+    }
+  });
+
+  Views.Sidebar = FauxtonAPI.View.extend({
+    template: "templates/databases/sidebar",
+    events: {
+      "click a#new": "newDatabase",
+      "click a#owned": "showMine",
+      "click a#shared": "showShared"
+    },
+
+    newDatabase: function() {
+      var notification;
+      var db;
+      // TODO: use a modal here instead of the prompt
+      var name = prompt('Name of database', 'newdatabase');
+      if (name === null) {
+        return;
+      } else if (name.length === 0) {
+        notification = FauxtonAPI.addNotification({
+          msg: "Please enter a valid database name",
+          type: "error",
+          clear: true
+        });
+        return;
+      }
+      db = new this.collection.model({
+        id: encodeURIComponent(name),
+        name: name
+      });
+      notification = FauxtonAPI.addNotification({msg: "Creating database."});
+      db.save().done(function() {
+        notification = FauxtonAPI.addNotification({
+          msg: "Database created successfully",
+          type: "success",
+          clear: true
+        });
+        var route = "#/database/" +  name + "/_all_docs?limit=" + Databases.DocLimit;
+        app.router.navigate(route, { trigger: true });
+      }
+      ).error(function(xhr) {
+        var responseText = JSON.parse(xhr.responseText).reason;
+        notification = FauxtonAPI.addNotification({
+          msg: "Create database failed: " + responseText,
+          type: "error",
+          clear: true
+        });
+      }
+      );
+    },
+
+    showMine: function(){
+      $.contribute(
+        'Show unshared databases',
+        'app/addons/databases/views.js'
+      );
+    },
+
+    showShared: function(){
+      $.contribute(
+        'Show shared databases (e.g. continuous replications to/from the database)',
+        'app/addons/databases/views.js'
+      );
+    }
+  });
+
+  return Views;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/base.js b/src/fauxton/app/addons/documents/base.js
new file mode 100644
index 0000000..cb68a31
--- /dev/null
+++ b/src/fauxton/app/addons/documents/base.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",
+
+  // Modules
+  "addons/documents/routes"
+],
+
+function(app, FauxtonAPI, Documents) {
+  return Documents;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/resources.js b/src/fauxton/app/addons/documents/resources.js
new file mode 100644
index 0000000..d87c2c9
--- /dev/null
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -0,0 +1,638 @@
+// 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"
+],
+
+function(app, FauxtonAPI) {
+  var Documents = FauxtonAPI.addon();
+
+  Documents.Doc = Backbone.Model.extend({
+    idAttribute: "_id",
+    documentation: function(){
+      return "docs";
+    },
+    url: function(context) {
+      if (context === "app") {
+        return this.getDatabase().url("app") + "/" + this.safeID();
+      } else if (context === "web-index") {
+        return this.getDatabase().url("app") + "/" + app.mixins.safeURLName(this.id);
+      } else if (context === "apiurl"){
+        return window.location.origin + "/" + this.getDatabase().safeID() + "/" + this.safeID();
+      } else {
+        return app.host + "/" + this.getDatabase().safeID() + "/" + this.safeID();
+      }
+    },
+
+    initialize: function(_attrs, options) {
+      if (this.collection && this.collection.database) {
+        this.database = this.collection.database;
+      } else if (options.database) {
+        this.database = options.database;
+      }
+    },
+
+    // HACK: the doc needs to know about the database, but it may be
+    // set directly or indirectly in all docs
+    getDatabase: function() {
+      return this.database ? this.database : this.collection.database;
+    },
+
+    validate: function(attrs, options) {
+      if (this.id && this.id !== attrs._id && this.get('_rev') ) {
+        return "Cannot change a documents id.";
+      }
+    },
+
+    docType: function() {
+      return this.id.match(/^_design/) ? "design doc" : "doc";
+    },
+
+    isEditable: function() {
+      return this.docType() != "reduction";
+    },
+
+    isDdoc: function() {
+      return this.docType() === "design doc";
+    },
+
+    hasViews: function() {
+      if (!this.isDdoc()) return false;
+      var doc = this.get('doc');
+      if (doc) {
+        return doc && doc.views && _.keys(doc.views).length > 0;
+      }
+
+      var views = this.get('views');
+      return views && _.keys(views).length > 0;
+    },
+
+    hasAttachments: function () {
+      return !!this.get('_attachments');
+    },
+
+    getDdocView: function(view) {
+      if (!this.isDdoc() || !this.hasViews()) return false;
+
+      var doc = this.get('doc');
+      if (doc) {
+        return doc.views[view];
+      }
+
+      return this.get('views')[view];
+    },
+
+    setDdocView: function (view, map, reduce) {
+      if (!this.isDdoc()) return false;
+      var views = this.get('views');
+          tempView = views[view] || {};
+
+      if (reduce) {
+        tempView.reduce=reduce;
+      } else {
+        delete tempView.reduce;
+      }
+      tempView.map= map;
+
+      views[view] = tempView;
+      this.set({views: views});
+
+      return true;
+    },
+
+    removeDdocView: function (viewName) {
+      if (!this.isDdoc()) return false;
+      var views = this.get('views');
+
+      delete views[viewName];
+      this.set({views: views});
+    },
+
+    dDocModel: function () {
+      if (!this.isDdoc()) return false;
+      var doc = this.get('doc');
+
+      if (doc) {
+        return new Documents.Doc(doc, {database: this.database});
+      } 
+
+      return this;
+    },
+
+    viewHasReduce: function(viewName) {
+      var view = this.getDdocView(viewName);
+
+      return view && view.reduce;
+    },
+
+    // Need this to work around backbone router thinking _design/foo
+    // is a separate route. Alternatively, maybe these should be
+    // treated separately. For instance, we could default into the
+    // json editor for docs, or into a ddoc specific page.
+    safeID: function() {
+      if (this.isDdoc()){
+        var ddoc = this.id.replace(/^_design\//,"");
+        return "_design/"+app.mixins.safeURLName(ddoc);
+      }else{
+        return app.mixins.safeURLName(this.id);
+      }
+    },
+
+    destroy: function() {
+      var url = this.url() + "?rev=" + this.get('_rev');
+      return $.ajax({
+        url: url,
+        dataType: 'json',
+        type: 'DELETE'
+      });
+    },
+
+    parse: function(resp) {
+      if (resp.rev) {
+        resp._rev = resp.rev;
+        delete resp.rev;
+      }
+      if (resp.id) {
+        if (typeof(this.id) === "undefined") {
+          resp._id = resp.id;
+        }
+        delete resp.id;
+      }
+      if (resp.ok) {
+        delete resp.ok;
+      }
+      return resp;
+    },
+
+    prettyJSON: function() {
+      var data = this.get("doc") ? this.get("doc") : this;
+
+      return JSON.stringify(data, null, "  ");
+    },
+
+    copy: function (copyId) {
+      return $.ajax({
+        type: 'COPY',
+        url: '/' + this.database.safeID() + '/' + this.safeID(),
+        headers: {Destination: copyId}
+      });
+    },
+
+    isNewDoc: function () {
+      return this.get('_rev') ? false : true;
+    }
+  });
+
+  Documents.DdocInfo = Backbone.Model.extend({
+    idAttribute: "_id",
+    documentation: function(){
+      return "docs";
+    },
+    initialize: function (_attrs, options) {
+      this.database = options.database;
+    },
+
+    url: function(context) {
+      if (context === "app") {
+        return this.database.url("app") + "/" + this.safeID() + '/_info';
+      } else if (context === "apiurl"){
+        return window.location.origin + "/" + this.database.safeID() + "/" + this.safeID() + '/_info';
+      } else {
+        return app.host + "/" + this.database.safeID() + "/" + this.safeID() + '/_info';
+      }
+    },
+
+    // Need this to work around backbone router thinking _design/foo
+    // is a separate route. Alternatively, maybe these should be
+    // treated separately. For instance, we could default into the
+    // json editor for docs, or into a ddoc specific page.
+    safeID: function() {
+      var ddoc = this.id.replace(/^_design\//,"");
+      return "_design/"+app.mixins.safeURLName(ddoc);
+    }
+
+  });
+
+  Documents.ViewRow = Backbone.Model.extend({
+    docType: function() {
+      if (!this.id) return "reduction";
+
+      return this.id.match(/^_design/) ? "design doc" : "doc";
+    },
+    documentation: function(){
+      return "docs";
+    },
+    url: function(context) {
+      if (!this.isEditable()) return false;
+
+      return this.collection.database.url(context) + "/" + this.safeID();
+    },
+
+    isEditable: function() {
+      return this.docType() != "reduction";
+    },
+    safeID: function() {
+      return app.mixins.safeURLName(this.id);
+    },
+
+    prettyJSON: function() {
+      //var data = this.get("doc") ? this.get("doc") : this;
+      return JSON.stringify(this, null, "  ");
+    }
+  });
+
+  Documents.NewDoc = Documents.Doc.extend({
+    fetch: function() {
+      var uuid = new FauxtonAPI.UUID();
+      var deferred = this.deferred = $.Deferred();
+      var that = this;
+
+      uuid.fetch().done(function() {
+        that.set("_id", uuid.next());
+        deferred.resolve();
+      });
+
+      return deferred.promise();
+    }
+
+  });
+
+  Documents.AllDocs = Backbone.Collection.extend({
+    model: Documents.Doc,
+    documentation: function(){
+      return "docs";
+    },
+    initialize: function(_models, options) {
+      this.database = options.database;
+      this.params = options.params;
+      this.skipFirstItem = false;
+
+      this.on("remove",this.decrementTotalRows , this);
+    },
+
+    url: function(context) {
+      var query = "";
+      if (this.params) {
+        query = "?" + $.param(this.params);
+      }
+
+      if (context === 'app') {
+        return 'database/' + this.database.safeID() + "/_all_docs" + query;
+      } else if (context === "apiurl"){
+        return window.location.origin + "/" + this.database.safeID() + "/_all_docs" + query;
+      } else {
+        return app.host + "/" + this.database.safeID() + "/_all_docs" + query;
+      }
+    },
+
+    simple: function () {
+      var docs = this.map(function (item) {
+        return {
+          _id: item.id,
+          _rev: item.get('_rev'),
+        };
+      });
+
+      return new Documents.AllDocs(docs, {
+        database: this.database,
+        params: this.params
+      });
+    },
+
+    urlNextPage: function (num, lastId) {
+      if (!lastId) {
+        var doc = this.last();
+
+        if (doc) {
+          lastId = doc.id;
+        } else {
+          lastId = '';
+        }
+      }
+
+      this.params.startkey_docid = '"' + lastId + '"';
+      this.params.startkey = '"' + lastId + '"';
+      // when paginating forward, fetch 21 and don't show
+      // the first item as it was the last item in the previous list
+      this.params.limit = num + 1;
+      return this.url('app');
+    },
+
+    urlPreviousPage: function (num, firstId) {
+      this.params.limit = num;
+      if (firstId) { 
+        this.params.startkey_docid = '"' + firstId + '"';
+        this.params.startkey = '"' + firstId + '"';
+      } else {
+        delete this.params.startkey;
+        delete this.params.startkey_docid;
+      }
+      return this.url('app');
+    },
+
+    totalRows: function() {
+      return this.viewMeta.total_rows || "unknown";
+    },
+
+    decrementTotalRows: function () {
+      if (this.viewMeta.total_rows) {
+        this.viewMeta.total_rows = this.viewMeta.total_rows -1;
+        this.trigger('totalRows:decrement');
+      }
+    },
+
+    updateSeq: function() {
+      return this.viewMeta.update_seq || false;
+    },
+
+    recordStart: function () {
+      if (this.viewMeta.offset === 0) {
+        return 1;
+      }
+
+      if (this.skipFirstItem) {
+        return this.viewMeta.offset + 2;
+      }
+
+      return this.viewMeta.offset + 1;
+    },
+
+    parse: function(resp) {
+      var rows = resp.rows;
+
+      this.viewMeta = {
+        total_rows: resp.total_rows,
+        offset: resp.offset,
+        update_seq: resp.update_seq
+      };
+
+      //Paginating, don't show first item as it was the last
+      //item in the previous page
+      if (this.skipFirstItem) {
+        rows = rows.splice(1);
+      }
+      return _.map(rows, function(row) {
+        return {
+          _id: row.id,
+          _rev: row.value.rev,
+          value: row.value,
+          key: row.key,
+          doc: row.doc || undefined
+        };
+      });
+    }
+  });
+
+  Documents.IndexCollection = Backbone.Collection.extend({
+    model: Documents.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.skipFirstItem = false;
+    },
+
+    url: function(context) {
+      var query = "";
+      if (this.params) {
+        query = "?" + $.param(this.params);
+      }
+      
+      var startOfUrl = app.host;
+      if (context === 'app') {
+        startOfUrl = 'database';
+      } else if (context === "apiurl"){
+        startOfUrl = window.location.origin;
+      }
+      var design = app.mixins.safeURLName(this.design),
+          view = app.mixins.safeURLName(this.view);
+
+      var url = [startOfUrl, this.database.safeID(), "_design", design, this.idxType, view];
+      return url.join("/") + query;
+    },
+
+    urlNextPage: function (num, lastId) {
+      if (!lastId) {
+        lastId = this.last().id;
+      }
+
+      this.params.startkey_docid = '"' + lastId + '"';
+      this.params.startkey = '"' + lastId + '"';
+      this.params.limit = num;
+      return this.url('app');
+    },
+
+     urlPreviousPage: function (num, firstId) {
+      this.params.limit = num;
+      if (firstId) { 
+        this.params.startkey_docid = '"' + firstId + '"';
+        this.params.startkey = '"' + firstId + '"';
+      } else {
+        delete this.params.startkey;
+        delete this.params.startkey_docid;
+      }
+      return this.url('app');
+    },
+
+    recordStart: function () {
+      if (this.viewMeta.offset === 0) {
+        return 1;
+      }
+
+      if (this.skipFirstItem) {
+        return this.viewMeta.offset + 2;
+      }
+
+      return this.viewMeta.offset + 1;
+    },
+
+    totalRows: function() {
+      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 Documents.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);
+
+      if (this.skipFirstItem) {
+        rows = rows.splice(1);
+      }
+
+      this.viewMeta = {
+        total_rows: resp.total_rows,
+        offset: resp.offset,
+        update_seq: resp.update_seq
+      };
+      return _.map(rows, function(row) {
+        return {
+          value: row.value,
+          key: row.key,
+          doc: row.doc,
+          id: row.id
+        };
+      });
+    },
+
+    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 Backbone.Collection.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;
+    }
+  });
+
+  
+  Documents.PouchIndexCollection = Backbone.Collection.extend({
+    model: Documents.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 Documents.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;
+    },
+
+    recordStart: function () {
+      return 1;
+    },
+
+    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;
+    }
+  });
+
+
+
+  return Documents;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/routes.js b/src/fauxton/app/addons/documents/routes.js
new file mode 100644
index 0000000..b1c16ef
--- /dev/null
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -0,0 +1,408 @@
+// 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
+       "addons/documents/views",
+       "addons/databases/base"
+],
+
+function(app, FauxtonAPI, Documents, 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
+      });
+
+      this.tabsView = this.setView("#tabs", new Documents.Views.FieldEditorTabs({
+        disableLoader: true,
+        selected: "code_editor",
+        model: this.doc
+      }));
+
+    },
+
+    routes: {
+      // We are hiding the field_editor for this first release
+      // "database/:database/:doc/field_editor": "field_editor",
+      "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.tabsView.updateSelected('code_editor');
+
+      this.docView = this.setView("#dashboard-content", new Documents.Views.Doc({
+        model: this.doc,
+        database: this.database
+      }));
+    },
+
+    reRenderDoc: function () {
+      this.docView.forceRender();
+    },
+
+    field_editor: function(events) {
+      this.tabsView.updateSelected('field_editor');
+      this.docView = this.setView("#dashboard-content", new Documents.Views.DocFieldEditor({
+        model: this.doc
+      }));
+    },
+
+    duplicateDoc: function (newId) {
+      var doc = this.doc,
+      docView = this.docView,
+      database = this.database;
+
+      doc.copy(newId).then(function () {
+        doc.set({_id: newId}); 
+        docView.forceRender();
+        FauxtonAPI.navigate('/database/' + database.safeID() + '/' + app.mixins.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
+      });
+
+      this.tabsView = this.setView("#tabs", new Documents.Views.FieldEditorTabs({
+        selected: "code_editor",
+        model: this.doc
+      }));
+
+    },
+    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)": "allDocs", 
+      "database/:database/_design/:ddoc/_view/:view": {
+        route: "viewFn",
+        roles: ['_admin']
+      },
+      "database/:database/new_view": "newViewEditor"
+    },
+
+    events: {
+      "route:updateAllDocs": "updateAllDocsFromView",
+      "route:updatePreviewDocs": "updateAllDocsFromPreview",
+      "route:reloadDesignDocs": "reloadDesignDocs",
+      "route:paginate": "paginate"
+    },
+
+    initialize: function (route, masterLayout, options) {
+      var docOptions = app.getParams();
+      docOptions.include_docs = true;
+
+      this.databaseName = options[0];
+
+      this.data = {
+        database: new Databases.Model({id:this.databaseName})
+      };
+
+      this.data.designDocs = new Documents.AllDocs(null, {
+        database: this.data.database,
+        params: {startkey: '"_design"',
+          endkey: '"_design1"',
+          include_docs: true}
+      });
+
+      this.sidebar = this.setView("#sidebar-content", new Documents.Views.Sidebar({
+        collection: this.data.designDocs,
+        database: this.data.database
+      }));
+    },
+
+    establish: function () {
+      return this.data.designDocs.fetch();
+    },
+
+    allDocs: function(databaseName, options) {
+      var docOptions = app.getParams(options);
+
+      docOptions.include_docs = true;
+      this.data.database.buildAllDocs(docOptions);
+
+      if (docOptions.startkey && docOptions.startkey.indexOf('_design') > -1) {
+        this.sidebar.setSelectedTab('design-docs');
+      } else {
+        this.sidebar.setSelectedTab('all-docs');
+      }
+
+      if (this.viewEditor) { this.viewEditor.remove(); }
+
+      this.toolsView = this.setView("#dashboard-upper-menu", new Documents.Views.JumpToDoc({
+        database: this.data.database,
+        collection: this.data.database.allDocs
+      }));
+
+      this.setView("#dashboard-upper-content", new Documents.Views.AllDocsLayout({
+        database: this.data.database,
+        collection: this.data.database.allDocs,
+        params: docOptions
+      }));
+
+      this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
+        collection: this.data.database.allDocs
+      }));
+
+      this.crumbs = [
+        {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)}
+      ];
+
+      this.apiUrl = [this.data.database.allDocs.url("apiurl"), this.data.database.allDocs.documentation() ];
+    },
+
+    viewFn: function (databaseName, ddoc, view) {
+      var params = app.getParams(),
+          decodeDdoc = decodeURIComponent(ddoc);
+
+      view = view.replace(/\?.*$/,'');
+
+      this.data.indexedDocs = new Documents.IndexCollection(null, {
+        database: this.data.database,
+        design: decodeDdoc,
+        view: view,
+        params: params
+      });
+
+
+
+      var ddocInfo = {
+        id: "_design/" + decodeDdoc,
+        currView: view,
+        designDocs: this.data.designDocs
+      };
+
+      this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.ViewEditor({
+        model: this.data.database,
+        ddocs: this.data.designDocs,
+        viewName: view,
+        params: params,
+        newView: false,
+        database: this.data.database,
+        ddocInfo: ddocInfo
+      }));
+
+      if (this.toolsView) { this.toolsView.remove(); }
+
+      this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
+        database: this.data.database,
+        collection: this.data.indexedDocs,
+        nestedView: Documents.Views.Row,
+        viewList: true,
+        ddocInfo: ddocInfo
+      }));
+
+      this.sidebar.setSelectedTab(app.mixins.removeSpecialCharacters(ddoc) + '_' + app.mixins.removeSpecialCharacters(view));
+
+      this.crumbs = function () {
+        return [
+          {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)},
+        ];
+      };
+
+      this.apiUrl = [this.data.indexedDocs.url("apiurl"), "docs"];
+    },
+
+    newViewEditor: function () {
+      var params = app.getParams();
+
+      if (this.toolsView) {
+        this.toolsView.remove();
+      }
+
+      this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.ViewEditor({
+        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,
+          docOptions = app.getParams(),
+          ddoc = event.ddoc;
+
+      if (event.allDocs) {
+        docOptions.include_docs = true;
+        this.data.database.buildAllDocs(docOptions);
+        return;
+      }
+
+      this.data.indexedDocs = new Documents.IndexCollection(null, {
+        database: this.data.database,
+        design: ddoc,
+        view: view,
+        params: app.getParams()
+      });
+
+      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
+      }));
+    },
+
+    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
+      }));
+    },
+
+    paginate: function (direction) {
+      _.extend(this.documentsView.collection.params, app.getParams());
+      this.documentsView.forceRender();
+      if (direction === 'next') {
+        this.documentsView.collection.skipFirstItem = true;
+      } else {
+        this.documentsView.collection.skipFirstItem = false;
+      }
+    },
+
+    reloadDesignDocs: function (event) {
+      this.sidebar.forceRender();
+
+      if (event && event.selectedTab) {
+        this.sidebar.setSelectedTab(event.selectedTab);
+      }
+    }
+
+  });
+
+  var ChangesRouteObject = FauxtonAPI.RouteObject.extend({
+    layout: "with_tabs",
+    selectedHeader: "Databases",
+    crumbs: function () {
+      return [
+        {"name": this.database.id, "link": Databases.databaseUrl(this.database)},
+        {"name": "_changes", "link": "/_changes"}
+      ];
+    },
+
+    routes: {
+      "database/:database/_changes(:params)": "changes"
+    },
+
+    initialize: function (route, masterLayout, options) {
+      this.databaseName = options[0];
+      this.database = new Databases.Model({id: this.databaseName});
+
+      var docOptions = app.getParams();
+
+      this.database.buildChanges(docOptions);
+
+      this.setView("#tabs", new Documents.Views.Tabs({
+        collection: this.designDocs,
+        database: this.database,
+        active_id: 'changes'
+      }));
+    },
+
+    changes: function (event) {
+      this.setView("#dashboard-content", new Documents.Views.Changes({
+        model: this.database
+      }));
+    },
+
+    apiUrl: function() {
+      return [this.database.url("apiurl"), this.database.documentation()];
+    }
+
+  });
+
+  Documents.RouteObjects = [DocEditorRouteObject, NewDocEditorRouteObject, DocumentsRouteObject, ChangesRouteObject];
+
+  return Documents;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/templates/advanced_options.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/advanced_options.html b/src/fauxton/app/addons/documents/templates/advanced_options.html
new file mode 100644
index 0000000..8e96574
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/advanced_options.html
@@ -0,0 +1,97 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+<div class="errors-container"></div>
+<form class="view-query-update custom-inputs">
+  <div class="controls-group">
+    <div class="row-fluid">
+      <div class="controls controls-row">
+        <input name="key" class="span6" type="text" placeholder="Key">
+        <input name="keys" class="span6" type="text" placeholder="Keys">
+      </div>
+    </div>
+    <div class="row-fluid">
+      <div class="controls controls-row">
+        <input name="startkey" class="span6" type="text" placeholder="Start Key">
+        <input name="endkey" class="span6" type="text" placeholder="End Key">
+      </div>
+    </div>
+  </div>
+  <div class="controls-group">
+    <div class="row-fluid">
+      <div class="controls controls-row">
+        <div class="checkbox inline">  
+          <input id="check1" type="checkbox" name="include_docs" value="true">  
+          <label name="include_docs" for="check1">Include Docs</label>  
+          <% if (hasReduce) { %>
+          <input id="check2" name="reduce" type="checkbox" value="true">
+          <label for="check2">Reduce</label>  
+        </div> 
+        <label id="select1" class="drop-down inline">
+          Group Level:
+          <select id="select1" disabled name="group_level" class="input-small">
+            <option value="0">None</option>
+            <option value="1">1</option>
+            <option value="2">2</option>
+            <option value="3">3</option>
+            <option value="4">4</option>
+            <option value="5">5</option>
+            <option value="6">6</option>
+            <option value="7">7</option>
+            <option value="8">8</option>
+            <option value="9">9</option>
+            <option value="999" selected="selected">exact</option>
+          </select>
+        </label>
+        <% } else{ %>
+        </div>
+        <% } %>
+
+        <div class="checkbox inline">  
+          <input id="check3" name="stale" type="checkbox" value="ok">
+          <label for="check3">Stale</label>
+          <input id="check4" name="descending" type="checkbox" value="true">  
+          <label for="check4">Descending</label>  
+        </div> 
+        <label class="drop-down inline">
+          Limit:
+          <select name="limit" class="input-small">
+            <option>5</option>
+            <option selected="selected">10</option>
+            <option>25</option>
+            <option>50</option>
+            <option>100</option>
+          </select>
+        </label>
+        <div class="checkbox inline">  
+          <input id="check5" name="inclusive_end" type="checkbox" value="false">
+          <label for="check5">Disable Inclusive End</label>
+          <input id="check6" name="update_seq" type="checkbox" value="true">  
+          <label for="check6">Update Sequence</label>  
+        </div>
+      </div>
+    </div>
+  </div>
+  <div class="controls-group">
+    <div class="row-fluid">
+      <div id="button-options" class="controls controls-row">
+        <button type="submit" class="button green">Query</button>
+        <% if (showPreview) { %>
+        <button class="button btn-info preview">Browser Preview</button>
+        <% } %>
+      </div>
+    </div>
+  </div>
+</form>
+</div>
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/templates/all_docs_item.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/all_docs_item.html b/src/fauxton/app/addons/documents/templates/all_docs_item.html
new file mode 100644
index 0000000..bfedaaa
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/all_docs_item.html
@@ -0,0 +1,26 @@
+<!--
+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.
+-->
+
+<td class="select"><input type="checkbox" class="row-select"></td>
+<td>
+  <div>
+    <pre class="prettyprint"><%- doc.prettyJSON() %></pre>
+    <% if (doc.isEditable()) { %>
+      <div class="btn-group">
+        <a href="#<%= doc.url('web-index') %>" class="btn btn-small edits">Edit <%= doc.docType() %></a>
+        <button href="#" class="btn btn-small btn-danger delete" title="Delete this document."><i class="icon icon-trash"></i></button>
+      </div>
+    <% } %>
+  </div>
+</td>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/templates/all_docs_layout.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/all_docs_layout.html b/src/fauxton/app/addons/documents/templates/all_docs_layout.html
new file mode 100644
index 0000000..526c200
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/all_docs_layout.html
@@ -0,0 +1,20 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+<ul class="nav nav-tabs window-resizeable" id="db-views-tabs-nav">
+  <li><a id="toggle-query" class="fonticon-plus fonticon" href="#query" data-toggle="tab">Query Options</a></li>
+</ul>
+<div class="tab-content">
+  <div class="tab-pane" id="query">
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/templates/all_docs_list.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/all_docs_list.html b/src/fauxton/app/addons/documents/templates/all_docs_list.html
new file mode 100644
index 0000000..335b040
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/all_docs_list.html
@@ -0,0 +1,43 @@
+<!--
+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="view show">
+  <% if (!viewList) { %>
+    <div class="row">
+      <div class="btn-toolbar span6">
+        <button type="button" class="btn all" data-toggle="button">✓ All</button>
+        <button class="btn btn-small disabled bulk-delete"><i class="icon-trash"></i></button>
+        <% if (expandDocs) { %>
+        <button id="collapse" class="btn"><i class="icon-minus"></i> Collapse</button>
+        <% } else { %>
+        <button id="collapse" class="btn"><i class="icon-plus"></i> Expand</button>
+        <% } %>
+      </div>
+    </div>
+  <% } %>
+  <p>
+
+  <div id="item-numbers"> </div>
+
+  <% if (requestDuration) { %>
+    <span class="view-request-duration">
+    View request duration: <strong> <%= requestDuration %> </strong> 
+    </span>
+  <% } %>
+  </p>
+  <table class="all-docs table table-striped table-condensed">
+    <tbody></tbody>
+  </table>
+  <div id="documents-pagination"></div>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/templates/all_docs_number.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/all_docs_number.html b/src/fauxton/app/addons/documents/templates/all_docs_number.html
new file mode 100644
index 0000000..c4ea8f6
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/all_docs_number.html
@@ -0,0 +1,21 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+<% if (totalRows === "unknown"){ %>
+  Showing 0 documents. <a href="#/database/<%=database%>/new"> Create your first document.</a>
+<% } else { %>
+  Showing <%=offset%> - <%= numModels %> of <%= totalRows %> rows
+<%}%>
+<% if (updateSeq) { %>
+  -- Update Sequence: <%= updateSeq %>
+<% } %>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/templates/changes.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/changes.html b/src/fauxton/app/addons/documents/templates/changes.html
new file mode 100644
index 0000000..9408979
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/changes.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.
+-->
+
+<table id="changes-table" class="table">
+  <thead>
+    <th id="seq"> seq </th>
+    <th> id </th>
+    <th id="changes"> changes </th>
+    <th id="deleted"> deleted? </th>
+  </thead>
+  <tbody>
+  <% _.each(changes, function (change) { %>
+    <tr>
+      <td> <%= change.seq %> </td>
+      <% if (change.deleted) { %>
+        <td> <%= change.id %> </td>
+      <% } else { %>
+        <td> <a href="#<%= database.url('app') %>/<%= change.id %>"><%= change.id %></a> </td>
+      <% } %>
+        <td> 
+          <pre class="prettyprint">  <%- JSON.stringify({changes: change.changes, doc: change.doc}, null, " ") %> </pre>
+      </td>
+      <td><%= change.deleted ? "true" : "false" %></td>
+    </tr>
+  <% }); %>
+  </tbody>
+</table>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/templates/ddoc_info.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/ddoc_info.html b/src/fauxton/app/addons/documents/templates/ddoc_info.html
new file mode 100644
index 0000000..ed0aed6
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/ddoc_info.html
@@ -0,0 +1,28 @@
+<!--
+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>
+  <h2> Design Doc MetaData </h2>
+  <div class="row-fluid">
+	<% i=0; _.map(view_index, function (val, key) { %>
+		<% if(i%2==0){%>
+			<div class="row-fluid">
+		<% }; %>
+	    <div class="span6 well-item"><strong> <%= key %></strong> : <%= val %>  </div>
+	    <% if(i%2==1){%>
+			</div>
+		<% }; %>
+	  	<% ++i;
+	}); %>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/templates/design_doc_selector.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/design_doc_selector.html b/src/fauxton/app/addons/documents/templates/design_doc_selector.html
new file mode 100644
index 0000000..7bbe310
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/design_doc_selector.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.
+-->
+<div class="span3">
+  <label for="ddoc">Save to Design Document <a 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) { %>
+      <% 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/blob/fae1de24/src/fauxton/app/addons/documents/templates/doc.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/doc.html b/src/fauxton/app/addons/documents/templates/doc.html
new file mode 100644
index 0000000..10bbf8b
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/doc.html
@@ -0,0 +1,55 @@
+<!--
+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 id="doc">
+  <div class="errors-container"></div>
+   
+<div class="row doc-editor-buttons"> 
+  <div class="span3">
+    <button class="save-doc button green btn-medium save fonticon-circle-check" type="button">Save</button>
+    <button class="button cancel-button gray btn-medium">Back to _all_docs</button>
+  </div>
+
+  <div class="span7">
+    <% if (attachments) { %>
+    <div class="btn-group">
+      <a class="button gray btn-medium dropdown-toggle btn" data-bypass="true" data-toggle="dropdown" href="#">
+        View Attachments
+        <span class="caret"></span>
+      </a>
+      <ul class="dropdown-menu">
+        <%_.each(attachments, function (att) { %>
+        <li>
+        <a href="<%= att.url %>" target="_blank"> <strong> <%= att.fileName %> </strong> -
+          <span> <%= att.contentType %>, <%= formatSize(att.size)%> </span>
+        </a>
+        </li>
+        <% }) %>
+      </ul>
+    </div>
+    <% } %> 
+    <button class="button gray btn-medium  upload"><i class="icon-circle-arrow-up"></i> Upload Attachment</button>
+    <button class="button gray btn-medium duplicate"><i class="icon-repeat"></i> Duplicate document</button>
+  </div>
+
+  <button class="button red btn-medium delete"><i class="icon-trash"></i></button>
+  </ul>
+
+<div id="upload-modal"> </div>
+<div id="duplicate-modal"> </div> 
+</div>
+
+  <div id="editor-container" class="doc-code"><%- JSON.stringify(doc.attributes, null, "  ") %></div>
+
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/templates/doc_field_editor.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/doc_field_editor.html b/src/fauxton/app/addons/documents/templates/doc_field_editor.html
new file mode 100644
index 0000000..77d9278
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/doc_field_editor.html
@@ -0,0 +1,74 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<div id="doc-field-editor">
+  <div class="tools">
+
+    <div class="btn-toolbar pull-left">
+      <button class="btn btn-small all">&#x2713; All</button>
+      <button class="btn btn-small disabled delete"><i class="icon-trash"></i> Delete field</button>
+      <button class="btn btn-small new" style="margin-left: 64px"><i class="icon-plus"></i> New field</button>
+    </div>
+    <div class="btn-toolbar pull-right">
+      <button class="btn btn-small cancel button cancel-button outlineGray fonticon-circle-x">Cancel</button>
+      <button class="btn btn-small save button green fonticon-circle-check">Save</button>
+    </div>
+  </div>
+
+  <div class="clearfix"></div>
+  <!-- <hr style="margin-top: 0"/> -->
+
+  <table class="table table-striped  table-condensed">
+    <thead>
+      <tr>
+        <th class="select">
+        </th>
+        <th>Key</th>
+        <th>Value</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr style="display:none">
+        <td class="select"><input type="checkbox" /></td>
+        <td class="key"><input type="text" class="input-large" value='' /></td>
+        <td class="value"><input type="text" class="input-xxlarge" value='' /></td>
+      </tr>
+      <% _.each(doc, function(value, key) { %>
+        <tr>
+          <td class="select"><input type="checkbox" /></td>
+          <td class="key">
+            <input type="text" class="input-large" name="doc[<%= key %>]" value="<%= key %>" />
+          </td>
+          <td class="value"><input type="text" class="input-xxlarge" value='<%= JSON.stringify(value) %>' /></td>
+        </tr>
+      <% }); %>
+        <tr>
+          <th colspan="3">
+            Attachments
+          </th>
+        </tr>
+      <%_.each(attachments, function (att) { %>
+        <tr>
+          <td class="select"><input type="checkbox" /></td>
+          <td colspan="2">
+            <a href="<%= att.url %>" target="_blank"> <%= att.fileName %> </a>
+            <span> <%= att.contentType %>, <%= formatSize(att.size)%> </span>
+          </td>
+        </tr>
+      <% }) %>
+    </tbody>
+  </table>
+  <a class="btn btn-small new" style="margin-left: 64px"><i class="icon-plus"></i> New field</a>
+
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/templates/doc_field_editor_tabs.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/doc_field_editor_tabs.html b/src/fauxton/app/addons/documents/templates/doc_field_editor_tabs.html
new file mode 100644
index 0000000..766647c
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/doc_field_editor_tabs.html
@@ -0,0 +1,19 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<!--<ul class="nav nav-tabs">
+  <li id="field_editor" class="<%= isSelectedClass('field_editor') %>"><a href="#<%= doc.url('app') %>/field_editor">Doc fields</a></li>
+  <li id="code_editor" class="<%= isSelectedClass('code_editor') %>"><a href="#<%= doc.url('app') %>/code_editor"><i class="icon-pencil"> </i> Code editor</a>
+  </li>
+</ul>-->

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/templates/duplicate_doc_modal.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/duplicate_doc_modal.html b/src/fauxton/app/addons/documents/templates/duplicate_doc_modal.html
new file mode 100644
index 0000000..3f374b6
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/duplicate_doc_modal.html
@@ -0,0 +1,36 @@
+<!--
+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="modal hide fade">
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h3>Duplicate Document</h3>
+  </div>
+  <div class="modal-body">
+    <div id="modal-error" class="hide alert alert-error"/>
+    <form id="file-upload" class="form" method="post">
+      <p class="help-block">
+      Set new documents ID:
+      </p>
+      <input id="dup-id" type="text" class="input-xlarge">
+    </form>
+
+  </div>
+  <div class="modal-footer">
+    <a href="#" data-dismiss="modal" class="btn button cancel-button outlineGray fonticon-circle-x">Cancel</a>
+    <a href="#" id="duplicate-btn" class="btn btn-primary button green save fonticon-circle-check">Duplicate</a>
+  </div>
+</div>
+
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/templates/edit_tools.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/edit_tools.html b/src/fauxton/app/addons/documents/templates/edit_tools.html
new file mode 100644
index 0000000..40c884d
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/edit_tools.html
@@ -0,0 +1,44 @@
+<!--
+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="view show">
+  <p>
+    Showing 1-<%= numModels %> of <%= totalRows %> rows
+    <% if (updateSeq) { %>
+      -- Update Sequence: <%= updateSeq %>
+    <% } %>
+    <% if (requestDuration) { %>
+  <span class="view-request-duration">
+    View request duration: <strong> <%= requestDuration %> </strong> 
+   </span>
+   <% } %>
+  </p>
+  <table class="all-docs table table-striped table-condensed">
+    <tbody></tbody>
+  </table>
+  <!--
+  <div class="pagination pagination-centered">
+    <ul>
+      <li class="disabled"><a href="#">&laquo;</a></li>
+      <li class="active"><a href="#">1</a></li>
+      <li><a href="#">2</a></li>
+      <li><a href="#">3</a></li>
+      <li><a href="#">4</a></li>
+      <li><a href="#">5</a></li>
+      <li><a href="#">&raquo;</a></li>
+    </ul>
+  </div>
+  -->
+
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/documents/templates/index_menu_item.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/index_menu_item.html b/src/fauxton/app/addons/documents/templates/index_menu_item.html
new file mode 100644
index 0000000..7ca9012
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/index_menu_item.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.
+-->
+
+<a id="<%= ddoc_clean %>_<%= index_clean %>" href="#database/<%= database_encoded %>/_design/<%= ddoc_encoded %>/_view/<%= index_encoded %>" class="toggle-view">
+  <%= ddoc %><span class="divider">/</span><%= index %>
+</a>


Mime
View raw message