diff options
author | Garren Smith <garren.smith@gmail.com> | 2013-10-11 11:27:45 +0200 |
---|---|---|
committer | Garren Smith <garren.smith@gmail.com> | 2013-10-16 10:24:52 +0200 |
commit | bcb4fba312ba2ad74b9f19adcaf9eecbaf1bffe7 (patch) | |
tree | aee4ba6a7ee0fbd20a3fb887d9c0f24adc5548e6 | |
parent | 807c4e32fa0e5aa4fd4a74a2338df215ffbe5ac7 (diff) | |
download | couchdb-bcb4fba312ba2ad74b9f19adcaf9eecbaf1bffe7.tar.gz |
Fauxton: Add advanced options to Alldocs
Fixes COUCHDB-1694
-rw-r--r-- | src/fauxton/app/modules/documents/routes.js | 16 | ||||
-rw-r--r-- | src/fauxton/app/modules/documents/views.js | 433 | ||||
-rw-r--r-- | src/fauxton/app/modules/fauxton/base.js | 4 | ||||
-rw-r--r-- | src/fauxton/app/templates/documents/advanced_options.html | 94 | ||||
-rw-r--r-- | src/fauxton/app/templates/documents/all_docs_layout.html | 20 | ||||
-rw-r--r-- | src/fauxton/app/templates/documents/jumpdoc.html | 7 | ||||
-rw-r--r-- | src/fauxton/app/templates/documents/view_editor.html | 123 | ||||
-rw-r--r-- | src/fauxton/assets/less/fauxton.less | 6 | ||||
-rw-r--r-- | src/fauxton/test/core/routeObjectSpec.js | 5 |
9 files changed, 445 insertions, 263 deletions
diff --git a/src/fauxton/app/modules/documents/routes.js b/src/fauxton/app/modules/documents/routes.js index 572bf1f71..13b2bc9a9 100644 --- a/src/fauxton/app/modules/documents/routes.js +++ b/src/fauxton/app/modules/documents/routes.js @@ -204,12 +204,17 @@ function(app, FauxtonAPI, Documents, Databases) { 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 })); @@ -295,7 +300,14 @@ function(app, FauxtonAPI, Documents, Databases) { updateAllDocsFromView: function (event) { var view = event.view, - ddoc = event.ddoc; + 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, diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js index 376a2ac9e..6c3904400 100644 --- a/src/fauxton/app/modules/documents/views.js +++ b/src/fauxton/app/modules/documents/views.js @@ -457,6 +457,81 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re }); + Views.AllDocsLayout = FauxtonAPI.View.extend({ + template: "templates/documents/all_docs_layout", + className: "row", + + initialize: function (options) { + this.database = options.database; + this.params = options.params; + }, + + events: { + 'click #toggle-query': "toggleQuery" + }, + + toggleQuery: function (event) { + this.$('#query').toggle('fast'); + }, + + beforeRender: function () { + this.advancedOptions = this.insertView('#query', new Views.AdvancedOptions({ + updateViewFn: this.updateView, + previewFn: this.previewView, + hasReduce: false, + showPreview: false + })); + + this.$('#query').hide(); + }, + + afterRender: function () { + if (this.params) { + this.advancedOptions.updateFromParams(this.params); + } + + }, + + updateView: function (event, paramInfo) { + event.preventDefault(); + + var errorParams = paramInfo.errorParams, + params = paramInfo.params; + + if (_.any(errorParams)) { + _.map(errorParams, function(param) { + + // TODO: Where to add this error? + // bootstrap wants the error on a control-group div, but we're not using that + //$('form.view-query-update input[name='+param+'], form.view-query-update select[name='+param+']').addClass('error'); + return FauxtonAPI.addNotification({ + msg: "JSON Parse Error on field: "+param.name, + type: "error", + selector: ".advanced-options .errors-container" + }); + }); + FauxtonAPI.addNotification({ + msg: "Make sure that strings are properly quoted and any other values are valid JSON structures", + type: "warning", + selector: ".advanced-options .errors-container" + }); + + return false; + } + + var fragment = window.location.hash.replace(/\?.*$/, ''); + fragment = fragment + '?' + $.param(params); + FauxtonAPI.navigate(fragment, {trigger: false}); + + FauxtonAPI.triggerRouteEvent('updateAllDocs', {allDocs: true}); + }, + + previewView: function (event) { + event.preventDefault(); + } + + }); + // TODO: Rename to reflect that this is a list of rows or documents Views.AllDocsList = FauxtonAPI.View.extend({ template: "templates/documents/all_docs_list", @@ -886,6 +961,140 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re } }); + Views.AdvancedOptions = FauxtonAPI.View.extend({ + template: "templates/documents/advanced_options", + className: "advanced-options well", + + initialize: function (options) { + this.updateViewFn = options.updateViewFn; + this.previewFn = options.previewFn; + this.hadReduce = options.hasReduce || true; + + if (typeof(options.hasReduce) === 'undefined') { + this.hasReduce = true; + } else { + this.hasReduce = options.hasReduce; + } + + if (typeof(options.showPreview) === 'undefined') { + this.showPreview = true; + } else { + this.showPreview = options.showPreview; + } + }, + + events: { + "change form.view-query-update input": "updateFilters", + "change form.view-query-update select": "updateFilters", + "submit form.view-query-update": "updateView", + "click button.preview": "previewView" + }, + + queryParams: function () { + var $form = this.$(".view-query-update"); + // Ignore params without a value + var params = _.filter($form.serializeArray(), function(param) { + return param.value; + }); + + // Validate *key* params to ensure they're valid JSON + var keyParams = ["key","keys","startkey","endkey"]; + var errorParams = _.filter(params, function(param) { + if (_.contains(keyParams, param.name)) { + try { + JSON.parse(param.value); + return false; + } catch(e) { + return true; + } + } else { + return false; + } + }); + + return {params: params, errorParams: errorParams}; + }, + + updateFilters: function(event) { + event.preventDefault(); + var $ele = $(event.currentTarget); + var name = $ele.attr('name'); + this.updateFiltersFor(name, $ele); + }, + + updateFiltersFor: function(name, $ele) { + var $form = $ele.parents("form.view-query-update:first"); + switch (name) { + // Reduce constraints + // - Can't include_docs for reduce=true + // - can't include group_level for reduce=false + case "reduce": + if ($ele.prop('checked') === true) { + if ($form.find("input[name=include_docs]").prop("checked") === true) { + $form.find("input[name=include_docs]").prop("checked", false); + var notification = FauxtonAPI.addNotification({ + msg: "include_docs has been disabled as you cannot include docs on a reduced view", + type: "warn", + selector: ".view.show .all-docs-list.errors-container" + }); + } + $form.find("input[name=include_docs]").prop("disabled", true); + $form.find("select[name=group_level]").prop("disabled", false); + } else { + $form.find("select[name=group_level]").prop("disabled", true); + $form.find("input[name=include_docs]").prop("disabled", false); + } + break; + case "include_docs": + break; + } + }, + + updateFromParams: function (params) { + var $form = this.$el.find("form.view-query-update"); + _.each(params, function(val, key) { + var $ele; + switch (key) { + case "limit": + case "group_level": + $form.find("select[name='"+key+"']").val(val); + break; + case "include_docs": + case "stale": + case "descending": + case "inclusive_end": + $form.find("input[name='"+key+"']").prop('checked', true); + break; + case "reduce": + $ele = $form.find("input[name='"+key+"']"); + if (val == "true") { + $ele.prop('checked', true); + } + this.updateFiltersFor(key, $ele); + break; + default: + $form.find("input[name='"+key+"']").val(val); + break; + } + }, this); + }, + + updateView: function (event) { + this.updateViewFn(event, this.queryParams()); + }, + + previewView: function (event) { + this.previewFn(event, this.queryParams()); + }, + + serialize: function () { + return { + hasReduce: this.hasReduce, + showPreview: this.showPreview + }; + } + }); + //TODO split this into two smaller views, one for advance query options and other for index editing Views.ViewEditor = FauxtonAPI.View.extend({ template: "templates/documents/view_editor", @@ -893,13 +1102,9 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re events: { "click button.save": "saveView", - "click button.preview": "previewView", "click button.delete": "deleteView", "change select#reduce-function-selector": "updateReduce", - "change form.view-query-update input": "updateFilters", - "change form.view-query-update select": "updateFilters", "change select#ddoc": "updateDesignDoc", - "submit form.view-query-update": "updateView", "click #db-views-tabs-nav": 'toggleIndexNav' }, @@ -924,6 +1129,8 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re this.viewName = options.viewName; this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database}); } + + _.bindAll(this); }, establish: function () { @@ -965,31 +1172,6 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re } }, - queryParams: function () { - var $form = $(".view-query-update"); - // Ignore params without a value - var params = _.filter($form.serializeArray(), function(param) { - return param.value; - }); - - // Validate *key* params to ensure they're valid JSON - var keyParams = ["key","keys","startkey","endkey"]; - var errorParams = _.filter(params, function(param) { - if (_.contains(keyParams, param.name)) { - try { - JSON.parse(param.value); - return false; - } catch(e) { - return true; - } - } else { - return false; - } - }); - - return {params: params, errorParams: errorParams}; - }, - deleteView: function (event) { event.preventDefault(); @@ -1016,14 +1198,70 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re }); }, - updateView: function(event) { + saveView: function(event) { + var json, notification, + that = this; + + if (event) { event.preventDefault();} + + if (this.hasValidCode()) { + var mapVal = this.mapEditor.getValue(), + reduceVal = this.reduceVal(), + viewName = this.$('#index-name').val(), + ddoc = this.getCurrentDesignDoc(), + ddocName = ddoc.id; + + this.viewName = viewName; + + notification = FauxtonAPI.addNotification({ + msg: "Saving document.", + selector: "#define-view .errors-container" + }); + + ddoc.setDdocView(viewName, mapVal, reduceVal); + + ddoc.save().then(function () { + FauxtonAPI.addNotification({ + msg: "View has been saved.", + type: "success", + selector: "#define-view .errors-container" + }); + + if (that.newView) { + var fragment = '/database/' + that.database.id +'/' + ddocName + '/_view/' + viewName; + + FauxtonAPI.navigate(fragment, {trigger: false}); + FauxtonAPI.triggerRouteEvent('reloadDesignDocs',{selectedTab: ddocName.replace('_design/','') + '_' + viewName}); + + that.newView = false; + } + + FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: ddocName, view: viewName}); + + }, function(xhr) { + var responseText = JSON.parse(xhr.responseText).reason; + notification = FauxtonAPI.addNotification({ + msg: "Save failed: " + responseText, + type: "error", + clear: true + }); + }); + } else { + notification = FauxtonAPI.addNotification({ + msg: "Please fix the Javascript errors and try again.", + type: "error", + selector: "#define-view .errors-container" + }); + } + }, + + updateView: function(event, paramInfo) { event.preventDefault(); if (this.newView) { return alert('Please save this new view before querying it.'); } - var paramInfo = this.queryParams(), - errorParams = paramInfo.errorParams, - params = paramInfo.params; + var errorParams = paramInfo.errorParams, + params = paramInfo.params; if (_.any(errorParams)) { _.map(errorParams, function(param) { @@ -1053,46 +1291,11 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName}); }, - updateFilters: function(event) { - event.preventDefault(); - var $ele = $(event.currentTarget); - var name = $ele.attr('name'); - this.updateFiltersFor(name, $ele); - }, - - updateFiltersFor: function(name, $ele) { - var $form = $ele.parents("form.view-query-update:first"); - switch (name) { - // Reduce constraints - // - Can't include_docs for reduce=true - // - can't include group_level for reduce=false - case "reduce": - if ($ele.prop('checked') === true) { - if ($form.find("input[name=include_docs]").prop("checked") === true) { - $form.find("input[name=include_docs]").prop("checked", false); - var notification = FauxtonAPI.addNotification({ - msg: "include_docs has been disabled as you cannot include docs on a reduced view", - type: "warn", - selector: ".view.show .all-docs-list.errors-container" - }); - } - $form.find("input[name=include_docs]").prop("disabled", true); - $form.find("select[name=group_level]").prop("disabled", false); - } else { - $form.find("select[name=group_level]").prop("disabled", true); - $form.find("input[name=include_docs]").prop("disabled", false); - } - break; - case "include_docs": - break; - } - }, - - previewView: function(event) { + previewView: function(event, paramsInfo) { var that = this, mapVal = this.mapEditor.getValue(), reduceVal = this.reduceVal(), - paramsArr = this.queryParams().params; + paramsArr = paramsInfo.params; var params = _.reduce(paramsArr, function (params, param) { params[param.name] = param.value; @@ -1127,63 +1330,6 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re }); }, - saveView: function(event) { - var json, notification, - that = this; - - if (event) { event.preventDefault();} - - if (this.hasValidCode()) { - var mapVal = this.mapEditor.getValue(), - reduceVal = this.reduceVal(), - viewName = this.$('#index-name').val(), - ddoc = this.getCurrentDesignDoc(), - ddocName = ddoc.id; - - this.viewName = viewName; - - notification = FauxtonAPI.addNotification({ - msg: "Saving document.", - selector: "#define-view .errors-container" - }); - - ddoc.setDdocView(viewName, mapVal, reduceVal); - - ddoc.save().then(function () { - FauxtonAPI.addNotification({ - msg: "View has been saved.", - type: "success", - selector: "#define-view .errors-container" - }); - - if (that.newView) { - var fragment = '/database/' + that.database.id +'/' + ddocName + '/_view/' + viewName; - - FauxtonAPI.navigate(fragment, {trigger: false}); - FauxtonAPI.triggerRouteEvent('reloadDesignDocs',{selectedTab: ddocName.replace('_design/','') + '_' + viewName}); - - that.newView = false; - } - - FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: ddocName, view: viewName}); - - }, function(xhr) { - var responseText = JSON.parse(xhr.responseText).reason; - notification = FauxtonAPI.addNotification({ - msg: "Save failed: " + responseText, - type: "error", - clear: true - }); - }); - } else { - notification = FauxtonAPI.addNotification({ - msg: "Please fix the Javascript errors and try again.", - type: "error", - selector: "#define-view .errors-container" - }); - } - }, - getCurrentDesignDoc: function () { if (this.newDesignDoc()) { var doc = { @@ -1310,6 +1456,11 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re this.reduceFunStr = this.model.viewHasReduce(this.viewName); this.setView('#ddoc-info', new Views.DdocInfo({model: this.ddocInfo })); } + + this.advancedOptions = this.insertView('#query', new Views.AdvancedOptions({ + updateViewFn: this.updateView, + previewFn: this.previewView + })); }, afterRender: function() { @@ -1375,32 +1526,7 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re } if (this.params) { - var $form = this.$el.find("form.view-query-update"); - _.each(this.params, function(val, key) { - var $ele; - switch (key) { - case "limit": - case "group_level": - $form.find("select[name='"+key+"']").val(val); - break; - case "include_docs": - case "stale": - case "descending": - case "inclusive_end": - $form.find("input[name='"+key+"']").prop('checked', true); - break; - case "reduce": - $ele = $form.find("input[name='"+key+"']"); - if (val == "true") { - $ele.prop('checked', true); - } - this.updateFiltersFor(key, $ele); - break; - default: - $form.find("input[name='"+key+"']").val(val); - break; - } - }, this); + this.advancedOptions.updateFromParams(this.params); } } @@ -1415,6 +1541,7 @@ function(app, FauxtonAPI, Components, Documents, pouchdb, Codemirror, JSHint, re events: { "submit #jump-to-doc": "jumpToDoc", + "click #jump-to-doc-label": "jumpToDoc" }, jumpToDoc: function (event) { diff --git a/src/fauxton/app/modules/fauxton/base.js b/src/fauxton/app/modules/fauxton/base.js index f1d2f70d2..01c29287d 100644 --- a/src/fauxton/app/modules/fauxton/base.js +++ b/src/fauxton/app/modules/fauxton/base.js @@ -216,10 +216,10 @@ function(app, Backbone, resizeColumns) { }, hide: function(){ - $(this.el).addClass('hide'); + this.$el.addClass('hide'); }, show: function(){ - $(this.el).removeClass('hide'); + this.$el.removeClass('hide'); }, update: function(endpoint) { this.show(); diff --git a/src/fauxton/app/templates/documents/advanced_options.html b/src/fauxton/app/templates/documents/advanced_options.html new file mode 100644 index 000000000..aee2f652f --- /dev/null +++ b/src/fauxton/app/templates/documents/advanced_options.html @@ -0,0 +1,94 @@ +<!-- +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> + <% } %> + <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">Descending</label> + </div> + </div> + </div> + </div> + <div class="controls-group"> + <div class="row-fluid"> + <div class="controls controls-row"> + <button type="submit" class="btn btn-primary btn-large">Query</button> + <% if (showPreview) { %> + <button class="btn btn-info btn-large preview">Preview</button> + <% } %> + </div> + </div> + </div> +</form> +</div> + diff --git a/src/fauxton/app/templates/documents/all_docs_layout.html b/src/fauxton/app/templates/documents/all_docs_layout.html new file mode 100644 index 000000000..cdbd1619e --- /dev/null +++ b/src/fauxton/app/templates/documents/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">Advanced Options</a></li> +</ul> +<div class="tab-content"> + <div class="tab-pane" id="query"> + </div> +</div> diff --git a/src/fauxton/app/templates/documents/jumpdoc.html b/src/fauxton/app/templates/documents/jumpdoc.html index 2e83c52cd..c6f46523b 100644 --- a/src/fauxton/app/templates/documents/jumpdoc.html +++ b/src/fauxton/app/templates/documents/jumpdoc.html @@ -12,9 +12,8 @@ License for the specific language governing permissions and limitations under the License. --> - -<form id="jump-to-doc" class="form-inline"> - <label id="jump-to-doc-label" class="fonticon-search"> - <input type="text" id="jump-to-doc-id" class="i1nput-large" placeholder="Document ID"></input> +<form id="jump-to-doc" class="form-inline" > + <label id="jump-to-doc-label" class="fonticon-search"> + <input type="text" id="jump-to-doc-id" class="input-large" placeholder="Document ID"></input> </label> </form> diff --git a/src/fauxton/app/templates/documents/view_editor.html b/src/fauxton/app/templates/documents/view_editor.html index b1ca470f3..64f0f9821 100644 --- a/src/fauxton/app/templates/documents/view_editor.html +++ b/src/fauxton/app/templates/documents/view_editor.html @@ -57,42 +57,42 @@ the License. <div class="control-group"> <label for="map-function">Map function <a href="<%=getDocUrl('map_functions')%>" target="_blank"><i class="icon-question-sign"></i></a></label> - <% if (newView) { %> - <textarea class="js-editor" id="map-function"><%= langTemplates.map %></textarea> - <% } else { %> - <textarea class="js-editor" id="map-function"><%= ddoc.get('views')[viewName].map %></textarea> - <% } %> + <% if (newView) { %> + <textarea class="js-editor" id="map-function"><%= langTemplates.map %></textarea> + <% } else { %> + <textarea class="js-editor" id="map-function"><%= ddoc.get('views')[viewName].map %></textarea> + <% } %> </div> <div class="control-group"> <label for="reduce-function-selector">Reduce function <a href="<%=getDocUrl('reduce_functions')%>" target="_blank"><i class="icon-question-sign"></i></a></label> - <select id="reduce-function-selector"> - <option value="" <%= !reduceFunStr ? 'selected="selected"' : '' %>>None</option> - <% _.each(["_sum", "_count", "_stats"], function(reduce) { %> - <option value="<%= reduce %>" <% if (reduce == reduceFunStr) { %>selected<% } %>><%= reduce %></option> - <% }) %> - <option value="CUSTOM" <% if (isCustomReduce) { %>selected<% } %>>Custom reduce</option> - </select> - <span class="help-block">Reduce functions are optional.</span> + <select id="reduce-function-selector"> + <option value="" <%= !reduceFunStr ? 'selected="selected"' : '' %>>None</option> + <% _.each(["_sum", "_count", "_stats"], function(reduce) { %> + <option value="<%= reduce %>" <% if (reduce == reduceFunStr) { %>selected<% } %>><%= reduce %></option> + <% }) %> + <option value="CUSTOM" <% if (isCustomReduce) { %>selected<% } %>>Custom reduce</option> + </select> + <span class="help-block">Reduce functions are optional.</span> </div> <div class="control-group reduce-function"> <label for="reduce-function">Custom Reduce</label> - <% if (newView) { %> - <textarea class="js-editor" id="reduce-function"><%= langTemplates.reduce %></textarea> - <% } else { %> - <textarea class="js-editor" id="reduce-function"><%= ddoc.get('views')[viewName].reduce %></textarea> - <% } %> + <% if (newView) { %> + <textarea class="js-editor" id="reduce-function"><%= langTemplates.reduce %></textarea> + <% } else { %> + <textarea class="js-editor" id="reduce-function"><%= ddoc.get('views')[viewName].reduce %></textarea> + <% } %> </div> <div class="control-group"> - <button class="button green save fonticon-circle-check">Save</button> - <% if (!this.newView) { %> - <button class="button cancel-button outlineGray fonticon-circle-x">Delete</button> - <% } %> + <button class="button green save fonticon-circle-check">Save</button> + <% if (!this.newView) { %> + <button class="button cancel-button outlineGray fonticon-circle-x">Delete</button> + <% } %> </div> <div class="clearfix"></div> </form> @@ -102,85 +102,6 @@ the License. <div id="ddoc-info" class="well"> </div> </div> <div class="tab-pane" id="query"> - <div class="advanced-options well"> - <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> - <% } %> - <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">Descending</label> - </div> - </div> - </div> - </div> - <div class="controls-group"> - <div class="row-fluid"> - <div class="controls controls-row"> - <button type="submit" class="btn btn-primary btn-large">Query</button> - <button class="btn btn-info btn-large preview">Preview</button> - </div> - </div> - </div> - </form> - </div> </div> </div> </div> diff --git a/src/fauxton/assets/less/fauxton.less b/src/fauxton/assets/less/fauxton.less index 42b783660..56d145356 100644 --- a/src/fauxton/assets/less/fauxton.less +++ b/src/fauxton/assets/less/fauxton.less @@ -519,6 +519,10 @@ footer#mainFooter{ padding: 0 20px; } +.db-views-smaller { + max-width: 500px; +} + .nav-tabs > li{ margin-right: 2px; > a { @@ -969,6 +973,8 @@ div.spinner { #jump-to-doc { width: 88%; max-width: 600px; + float:right; + margin-right: 40px; #jump-to-doc-label { width: 100%; diff --git a/src/fauxton/test/core/routeObjectSpec.js b/src/fauxton/test/core/routeObjectSpec.js index d043d6356..987d5b7e4 100644 --- a/src/fauxton/test/core/routeObjectSpec.js +++ b/src/fauxton/test/core/routeObjectSpec.js @@ -27,6 +27,8 @@ define([ }); testRouteObject = new TestRouteObject(); + var apiBar = {}; + apiBar.hide = sinon.spy(); // Need to find a better way of doing this mockLayout = { @@ -35,7 +37,8 @@ define([ setView: sinon.spy(), renderView: sinon.spy(), hooks: [], - setBreadcrumbs: sinon.spy() + setBreadcrumbs: sinon.spy(), + apiBar: apiBar }; }); |