couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j..@apache.org
Subject [1/50] [abbrv] git commit: Initial advanced view options functionality
Date Mon, 11 Feb 2013 11:12:15 GMT
Initial advanced view options functionality

Not super happy with this, number of things that could be done better or
differently, but I figured I would get this out as it works decently
well and provides a good baseline for figuring out where to go next.


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

Branch: refs/heads/fauxton
Commit: 776620d710e7bb33619341ab4c6540e1233b9216
Parents: 180d822
Author: Russell Branca <chewbranca@gmail.com>
Authored: Tue Jan 8 19:03:11 2013 -0800
Committer: Russell Branca <chewbranca@gmail.com>
Committed: Tue Jan 8 19:03:11 2013 -0800

----------------------------------------------------------------------
 src/fauxton/app/modules/documents/resources.js     |   41 +++++++-
 src/fauxton/app/modules/documents/routes.js        |   22 +++-
 src/fauxton/app/modules/documents/views.js         |   87 ++++++++++++++-
 .../app/templates/documents/all_docs_list.html     |   71 ++++++++++++-
 src/fauxton/app/templates/documents/index_row.html |   11 --
 .../app/templates/documents/index_row_docular.html |   10 ++
 .../app/templates/documents/index_row_tabular.html |   11 ++
 7 files changed, 230 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/776620d7/src/fauxton/app/modules/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/resources.js b/src/fauxton/app/modules/documents/resources.js
index a042fe3..2a15cf8 100644
--- a/src/fauxton/app/modules/documents/resources.js
+++ b/src/fauxton/app/modules/documents/resources.js
@@ -39,6 +39,29 @@ function(app, FauxtonAPI, Views) {
       return this.id.match(/^_design/) ? "design doc" : "doc";
     },
 
+    isDdoc: function() {
+      return this.docType() === "design doc";
+    },
+
+    hasViews: function() {
+      if (!this.isDdoc()) return false;
+      var doc = this.get('doc');
+      return doc && doc.views && doc.views.length > 0;
+    },
+
+    getDdocView: function(view) {
+      if (!this.isDdoc() || !this.hasViews()) return false;
+
+      var doc = this.get('doc');
+      return doc.views[view];
+    },
+
+    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
@@ -81,6 +104,19 @@ function(app, FauxtonAPI, Views) {
     }
   });
 
+  Documents.ViewRow = Backbone.Model.extend({
+    docType: function() {
+      if (!this.id) return "reduction";
+
+      return this.id.match(/^_design/) ? "design doc" : "doc";
+    },
+
+    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();
@@ -126,7 +162,7 @@ function(app, FauxtonAPI, Views) {
   });
 
   Documents.IndexCollection = Backbone.Collection.extend({
-    model: Backbone.Model,
+    model: Documents.ViewRow,
 
     initialize: function(_models, options) {
       this.database = options.database;
@@ -151,7 +187,8 @@ function(app, FauxtonAPI, Views) {
         return {
           value: row.value,
           key: row.key,
-          doc: row.doc || undefined
+          doc: row.doc,
+          id: row.id
         };
       });
     },

http://git-wip-us.apache.org/repos/asf/couchdb/blob/776620d7/src/fauxton/app/modules/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/routes.js b/src/fauxton/app/modules/documents/routes.js
index fb35867..233308d 100644
--- a/src/fauxton/app/modules/documents/routes.js
+++ b/src/fauxton/app/modules/documents/routes.js
@@ -258,8 +258,14 @@ function(app, FauxtonAPI, Documents, Databases) {
 
     "database/:database/new": newDocCodeEditorCallback,
 
-    "database/:database/_design/:ddoc/_view/:view": function(databaseName, ddoc, view) {
-      // alert("This will filter your data by the " + ddoc + "/" + view + "view.");
+    // TODO: fix optional search params
+    // Can't get ":view(?*search)" to work
+    // However ":view?*search" does work
+    //"database/:database/_design/:ddoc/_view/:view(\?*options)": function(databaseName,
ddoc, view, options) {
+    "database/:database/_design/:ddoc/_view/:view": function(databaseName, ddoc, view, options)
{
+      // hack around backbone router limitations
+      view = view.replace(/\?.*$/,'');
+      var params = app.getParams();
       var data = {
         database: new Databases.Model({id:databaseName})
       };
@@ -268,7 +274,7 @@ function(app, FauxtonAPI, Documents, Databases) {
         database: data.database,
         design: ddoc,
         view: view,
-        params: {}
+        params: params
       });
 
       data.designDocs = new Documents.AllDocs(null, {
@@ -278,6 +284,11 @@ function(app, FauxtonAPI, Documents, Databases) {
                  include_docs: true}
       });
 
+      var ddocInfo = {
+        id: "_design/" + ddoc,
+        designDocs: data.designDocs
+      };
+
       return {
         layout: "with_tabs_sidebar",
 
@@ -286,7 +297,10 @@ function(app, FauxtonAPI, Documents, Databases) {
         views: {
           "#dashboard-content": new Documents.Views.AllDocsList({
             collection: data.indexedDocs,
-            nestedView: Documents.Views.Row
+            nestedView: Documents.Views.Row,
+            viewList: true,
+            ddocInfo: ddocInfo,
+            params: params
           }),
 
           "#sidebar-content": new Documents.Views.Sidebar({

http://git-wip-us.apache.org/repos/asf/couchdb/blob/776620d7/src/fauxton/app/modules/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js
index fb0e271..5c5f3cc 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -122,7 +122,7 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
   });
 
   Views.Row = FauxtonAPI.View.extend({
-    template: "templates/documents/index_row",
+    template: "templates/documents/index_row_docular",
     tagName: "tr",
 
     serialize: function() {
@@ -155,26 +155,77 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
     template: "templates/documents/all_docs_list",
     events: {
       "click button.all": "selectAll",
-      "click button.bulk-delete": "bulkDelete"
+      "click button.bulk-delete": "bulkDelete",
+      "submit form.view-query-update": "updateView"
     },
 
     initialize: function(options){
       this.nestedView = options.nestedView || Views.Document;
       this.rows = {};
+      this.viewList = !! options.viewList;
+      this.params = options.params;
+      if (options.ddocInfo) {
+        this.designDocs = options.ddocInfo.designDocs;
+        this.ddocID = options.ddocInfo.id;
+      }
     },
 
     establish: function() {
-      return [this.collection.fetch()];
+      var deferreds = [this.collection.fetch()];
+      if (this.designDocs) {
+        deferreds.push(this.designDocs.fetch());
+      }
+      return deferreds;
     },
 
     selectAll: function(evt){
       $("input:checkbox").attr('checked', !$(evt.target).hasClass('active'));
     },
 
+    // TODO:: HACK::
+    // Hack to grab info about the ddoc and current view to determine whether
+    // or not the view has a reduce function so we can display the advanced
+    // options appropriately.
+    //
+    // NOTE: we have this here temporarily because we have to wait for the
+    // design docs to be present.
+    //
+    // NOTE: We should probably refactor this View out into a separate View
+    // dedicated to displaying view query results.
+    // If nothing else, we should at least switch to something along the lines
+    // of fetchOnce to ensure we're not reloading the ddocs here in addition to
+    // the sidebar.
+    setDdocInfo: function() {
+      if (!this.ddoc && this.designDocs) {
+        this.ddoc = this.designDocs.get(this.ddocID);
+      }
+    },
+
     serialize: function() {
-      return {
-        database: this.collection
+      this.setDdocInfo();
+      var data = {
+        database: this.collection,
+        viewList: this.viewList,
+        hasReduce: false,
+        params: this.params
       };
+      if (this.ddoc) {
+        data.ddoc = this.ddoc;
+        data.hasReduce = this.ddoc.viewHasReduce(this.collection.view);
+      }
+      return data;
+    },
+
+    updateView: function(event) {
+      event.preventDefault();
+      var $form = $(event.currentTarget);
+      // Ignore params without a value
+      var params = _.filter($form.serializeArray(), function(param) {
+        return param.value;
+      });
+      var fragment = window.location.hash.replace(/\?.*$/, '');
+      fragment = fragment + '?' + $.param(params);
+      FauxtonAPI.navigate(fragment);
     },
 
     /*
@@ -221,6 +272,32 @@ function(app, FauxtonAPI, Codemirror, JSHint) {
 
     afterRender: function(){
       prettyPrint();
+      if (this.params) {
+        var $form = this.$el.find("form.view-query-update");
+        _.each(this.params, function(val, key) {
+          switch (key) {
+            case "limit":
+              $form.find("select[name=limit]").val(val);
+              break;
+            case "include_docs":
+              if (val == "true") {
+                $form.find("input[name=include_docs]").prop('checked', true);
+              }
+              break;
+            case "reduce":
+              if (val == "true") {
+                $form.find("input[reduce]").prop('checked', true);
+              }
+              break;
+            case "group_level":
+              $form.find("select[name=group_level]").attr('selected', val);
+              break;
+            default:
+              $form.find("input[name='"+key+"']").val(val);
+              break;
+          }
+        });
+      }
     }
   });
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/776620d7/src/fauxton/app/templates/documents/all_docs_list.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/all_docs_list.html b/src/fauxton/app/templates/documents/all_docs_list.html
index 132c4dd..e987dff 100644
--- a/src/fauxton/app/templates/documents/all_docs_list.html
+++ b/src/fauxton/app/templates/documents/all_docs_list.html
@@ -1,5 +1,5 @@
 <div class="view show">
-  <div>
+  <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>
@@ -10,6 +10,75 @@
     </div>
   </div>
 
+  <div class="row">
+    <div class="accordion" id="advanced-options-accordion">
+      <div class="accordion-group">
+        <div class="accordion-heading">
+          <a class="accordion-toggle" data-bypass="true" data-toggle="collapse" data-parent="#advanced-options-accordion"
href="#collapse-advanced-options">
+            Advanced Options
+          </a>
+        </div>
+        <div id="collapse-advanced-options" class="accordion-body collapse in">
+          <div class="accordion-inner">
+            <form class="view-query-update">
+              <div class="controls controls-row">
+                <label class="span3 inline">
+                  Limit:
+                  <select name="limit" class="input-small">
+                    <option>5</option>
+                    <option selected="selected">10</option>
+                    <option>25</option>
+                    <option>50</option>
+                    <option>100</option>
+                  </select>
+                </label>
+                <label class="span3 checkbox inline">
+                  <input name="include_docs" type="checkbox" id="inlineCheckbox1" value="true">
Include Docs
+                </label>
+                <% if (hasReduce) { %>
+                  <label class="span2 checkbox inline">
+                    <input name="reduce" type="checkbox" id="inlineCheckbox1" value="true">
Reduce
+                  </label>
+                  <label class="span4 inline">
+                    Group Level:
+                    <select name="group_level" class="input-small">
+                      <option value="0">None</option>
+                      <option value="1">1</option>
+                      <option value="2">2</option>
+                      <option value="3">3</option>
+                      <option value="4">4</option>
+                      <option value="5">5</option>
+                      <option value="6">6</option>
+                      <option value="7">7</option>
+                      <option value="8">8</option>
+                      <option value="9">9</option>
+                      <option value="999" selected="selected">exact</option>
+                    </select>
+                  </label>
+                <% } %>
+              </div>
+
+              <div class="controls controls-row">
+                <input name="key" class="span4" type="text" placeholder="Key">
+                <input name="keys" class="span8" type="text" placeholder="Keys">
+              </div>
+              <div class="controls controls-row">
+                <input name="startkey" class="span6" type="text" placeholder="Start Key">
+                <input name="endkey" class="span6" type="text" placeholder="End Key">
+              </div>
+              <div class="controls controls-row">
+                <button type="submit" class="btn btn-primary">Query</button>
+              </div>
+            </form>
+ 
+          </div>
+        </div>
+
+      </div>
+    </div>
+  </div>
+
+
   <table class="all-docs table table-striped table-condensed">
     <tbody></tbody>
   </table>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/776620d7/src/fauxton/app/templates/documents/index_row.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/index_row.html b/src/fauxton/app/templates/documents/index_row.html
deleted file mode 100644
index 7eed46d..0000000
--- a/src/fauxton/app/templates/documents/index_row.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<td class="select"><input type="checkbox"></td>
-<td>
-  <div>
-    <pre class="prettyprint"><%= JSON.stringify(doc.get("key")) %></pre>
-  </div>
-</td>
-<td>
-  <div>
-    <pre class="prettyprint"><%= JSON.stringify(doc.get("value"), null, "  ") %></pre>
-  </div>
-</td>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/couchdb/blob/776620d7/src/fauxton/app/templates/documents/index_row_docular.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/index_row_docular.html b/src/fauxton/app/templates/documents/index_row_docular.html
new file mode 100644
index 0000000..3caf8ba
--- /dev/null
+++ b/src/fauxton/app/templates/documents/index_row_docular.html
@@ -0,0 +1,10 @@
+<td class="select"><input type="checkbox"></td>
+<td>
+  <div>
+    <pre class="prettyprint"><%= doc.prettyJSON() %></pre>
+    <div class="btn-group">
+      <a href="#<%= doc.url('app') %>" 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>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/couchdb/blob/776620d7/src/fauxton/app/templates/documents/index_row_tabular.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/index_row_tabular.html b/src/fauxton/app/templates/documents/index_row_tabular.html
new file mode 100644
index 0000000..cf4bbcf
--- /dev/null
+++ b/src/fauxton/app/templates/documents/index_row_tabular.html
@@ -0,0 +1,11 @@
+<td class="select"><input type="checkbox"></td>
+<td>
+  <div>
+    <pre class="prettyprint"><%= JSON.stringify(doc.get("key")) %></pre>
+  </div>
+</td>
+<td>
+  <div>
+    <pre class="prettyprint"><%= JSON.stringify(doc.get("value")) %></pre>
+  </div>
+</td>
\ No newline at end of file


Mime
View raw message