You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ro...@apache.org on 2014/10/16 12:03:11 UTC
[4/4] fauxton commit: updated refs/heads/master to 332c7b5
New Query Options tray added
This is a cherry-picked branch the clears up the old PR:
https://github.com/apache/couchdb-fauxton/pull/78
For comments regarding this PR, see the original PR. For scope
and discussion of the fix, see the Jira ticket:
https://issues.apache.org/jira/browse/COUCHDB-2347
Closes COUCHDB-2347
Project: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/commit/332c7b53
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/tree/332c7b53
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/diff/332c7b53
Branch: refs/heads/master
Commit: 332c7b5350a928e35006e821f1f8bf9b6b748c12
Parents: 5976c65
Author: Benjamin Keen <be...@gmail.com>
Authored: Fri Oct 3 10:38:33 2014 -0700
Committer: Robert Kowalski <ro...@apache.org>
Committed: Thu Oct 16 11:59:30 2014 +0200
----------------------------------------------------------------------
app/addons/compaction/base.js | 3 +-
.../documents/assets/less/advancedOptions.less | 1 -
app/addons/documents/assets/less/changes.less | 3 -
app/addons/documents/assets/less/documents.less | 122 ++---
.../documents/assets/less/queryOptions.less | 161 ++++++
app/addons/documents/resources.js | 1 -
app/addons/documents/routes-documents.js | 106 ++--
.../documents/templates/advanced_options.html | 157 ------
.../documents/templates/all_docs_layout.html | 11 +-
.../documents/templates/all_docs_list.html | 4 +-
app/addons/documents/templates/ddoc_info.html | 2 +-
.../documents/templates/header_alldocs.html | 5 +-
.../documents/templates/query_options.html | 38 ++
.../query_options_additional_params.html | 61 +++
.../templates/query_options_key_search.html | 50 ++
.../templates/query_options_main_fields.html | 55 ++
app/addons/documents/templates/view_editor.html | 7 +-
.../documents/tests/views-advancedoptsSpec.js | 6 +-
app/addons/documents/views-advancedopts.js | 270 ----------
app/addons/documents/views-index.js | 90 ++--
app/addons/documents/views-queryoptions.js | 519 +++++++++++++++++++
app/addons/documents/views.js | 239 +++------
app/addons/fauxton/base.js | 3 +-
app/addons/fauxton/components.js | 6 +-
app/addons/fauxton/templates/api_bar.html | 2 +-
app/core/routeObject.js | 7 +-
app/core/router.js | 3 +-
app/core/utils.js | 10 +
assets/fonts/fauxtonicon.eot | Bin 17640 -> 18290 bytes
assets/fonts/fauxtonicon.svg | 259 +++++----
assets/fonts/fauxtonicon.ttf | Bin 17452 -> 18100 bytes
assets/fonts/fauxtonicon.woff | Bin 10000 -> 10368 bytes
.../fonts/styleguide/fauxtonicon-preview.html | 441 ++++++++--------
assets/icons/gears.svg | 8 +
assets/less/bootstrap/forms.less | 2 +-
assets/less/fauxton.less | 27 +-
assets/less/formstyles.less | 38 +-
assets/less/icons.less | 214 ++++----
38 files changed, 1688 insertions(+), 1243 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/compaction/base.js
----------------------------------------------------------------------
diff --git a/app/addons/compaction/base.js b/app/addons/compaction/base.js
index de0f124..f80c42e 100644
--- a/app/addons/compaction/base.js
+++ b/app/addons/compaction/base.js
@@ -17,6 +17,7 @@ define([
],
function(app, FauxtonAPI, Compaction) {
+
Compaction.initialize = function() {
FauxtonAPI.registerExtension('docLinks', {
title: "Compact & Clean",
@@ -24,7 +25,7 @@ function(app, FauxtonAPI, Compaction) {
icon: "icon-cogs"
});
- FauxtonAPI.registerExtension('advancedOptions:ViewButton', new Compaction.CompactView({}));
+ FauxtonAPI.registerExtension('ViewEditor:ButtonRow', new Compaction.CompactView({}));
};
return Compaction;
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/assets/less/advancedOptions.less
----------------------------------------------------------------------
diff --git a/app/addons/documents/assets/less/advancedOptions.less b/app/addons/documents/assets/less/advancedOptions.less
deleted file mode 100644
index 2e29d38..0000000
--- a/app/addons/documents/assets/less/advancedOptions.less
+++ /dev/null
@@ -1 +0,0 @@
-/*for advanced options css*/
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/assets/less/changes.less
----------------------------------------------------------------------
diff --git a/app/addons/documents/assets/less/changes.less b/app/addons/documents/assets/less/changes.less
index 96e6d19..ebba21d 100644
--- a/app/addons/documents/assets/less/changes.less
+++ b/app/addons/documents/assets/less/changes.less
@@ -7,9 +7,6 @@
right: 15px;
}
-.changes-view {
- padding-top: 70px;
-}
.change-wrapper {
margin-top: 20px;
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/assets/less/documents.less
----------------------------------------------------------------------
diff --git a/app/addons/documents/assets/less/documents.less b/app/addons/documents/assets/less/documents.less
index 2b29744..8e730b5 100644
--- a/app/addons/documents/assets/less/documents.less
+++ b/app/addons/documents/assets/less/documents.less
@@ -10,31 +10,31 @@
// License for the specific language governing permissions and limitations under
// the License.
/*ALL DOCS TABLE*/
-
@import "../../../../../assets/less/variables.less";
@import "../../../../../assets/less/bootstrap/variables.less";
@import "../../../../../assets/less/bootstrap/mixins.less";
-@import "advancedOptions.less";
+@import "queryOptions.less";
@import "changes.less";
@import "sidenav.less";
tr.all-docs-item {
border: none;
background: transparent;
- .btn-group {
- position: absolute;
- right: 0;
- top: 6px;
- }
+ .btn-group {
+ position: absolute;
+ right: 0;
+ top: 6px;
+ }
}
+
button.beautify {
margin-top: 20px;
}
.toggle-btns {
- label{
- margin-right: 0;
- }
+ label {
+ margin-right: 0;
+ }
}
#per-page {
@@ -43,65 +43,66 @@ button.beautify {
#select-per-page {
margin-top: 10px;
}
-
}
-
-#query div.controls-group.well{
- height: 180px;
- margin-right: 17px;
+#query div.controls-group.well {
+ height: 180px;
+ margin-right: 17px;
}
/** used in all_docs_list.html **/
.view {
- table td div {
- position: relative;
- }
+ table td div {
+ position: relative;
+ }
- table td div div {
- display: none;
- line-height: 1;
- position: absolute;
- right: 4px;
- top: 4px;
- }
+ table td div div {
+ display: none;
+ line-height: 1;
+ position: absolute;
+ right: 4px;
+ top: 4px;
+ }
- table td div:hover div a.edits {
- padding-left: 16px;
- padding-right: 16px;
- }
+ table td div:hover div a.edits {
+ padding-left: 16px;
+ padding-right: 16px;
+ }
- table td div:hover div {
- display: block;
- }
+ table td div:hover div {
+ display: block;
+ }
}
/** used in view_editor.html **/
-.design-doc-group{
- .span3 { margin: 0;}
- #new-ddoc-section {
- margin-top: 10px;
- label{ width: 100px}
- .controls{
- margin-left: 100px;
- }
+.design-doc-group {
+ .span3 {
+ margin: 0;
+ }
+ #new-ddoc-section {
+ margin-top: 10px;
+ label {
+ width: 100px
}
+ .controls {
+ margin-left: 100px;
+ }
+ }
}
-
-#map-function, #reduce-function{
- width: 100%;
- font-size: 16px;
+#map-function, #reduce-function {
+ width: 100%;
+ font-size: 16px;
}
#doc-actions {
- height: 42px;
+ height: 42px;
}
#editor-container {
- width: 1316px;
- height: 688px;
- font-size: 16px;
+ width: 1316px;
+ height: 688px;
+ font-size: 16px;
}
button.string-edit {
@@ -137,21 +138,20 @@ button.string-edit[disabled] {
display: inline-block;
}
-
.change-sequence {
word-wrap: break-word;
}
-
-#dashboard-upper-content{
- .js-query-keys-wrapper{
+#dashboard-upper-content {
+ .js-query-keys-wrapper {
padding-top: 0;
}
- /** used in advanced-options.html**/
+
+ /** used in query-options.html**/
.custom-inputs {
- .row-fluid{
+ .row-fluid {
padding-top: 20px;
- .radio, .checkbox{
+ .radio, .checkbox {
padding-left: 0;
}
.checkbox.inline,
@@ -163,12 +163,14 @@ button.string-edit[disabled] {
}
}
-.nav-list{
+.nav-list {
border-top: none;
}
+.end-of-results {
+ margin-bottom: 30px;
-
-
-
-
+ .muted {
+ margin-bottom: 0px;
+ }
+}
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/assets/less/queryOptions.less
----------------------------------------------------------------------
diff --git a/app/addons/documents/assets/less/queryOptions.less b/app/addons/documents/assets/less/queryOptions.less
new file mode 100644
index 0000000..f326c5e
--- /dev/null
+++ b/app/addons/documents/assets/less/queryOptions.less
@@ -0,0 +1,161 @@
+// 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.
+
+#query-options-tray:before {
+ right: 140px;
+}
+
+#query-options-tray {
+ width: 490px;
+
+ .query-group:first-child {
+ margin-top: 0px;
+ padding-top: 0px;
+ }
+
+ .icon-question-sign {
+ margin-left: 3px;
+ font-size: 17.5px;
+ }
+
+ .query-group {
+ padding: 20px;
+ border-bottom: 1px solid #555;
+ }
+
+ .query-group:last-child {
+ border-bottom: none;
+ }
+ .controls-group {
+ margin: 0;
+ }
+ .controls-group:last-child {
+ margin: 0;
+ }
+ form {
+ overflow: scroll;
+ margin-bottom: 0;
+ .dropdown.inline {
+ display: inline-block;
+ }
+
+ input[type="text"],
+ textarea {
+ .border-radius(5px);
+ background-color: #666;
+ padding: 8px;
+ border: none;
+ color: #eee;
+ font-size: 13px;
+ }
+ .input-small {
+ width: 70px;
+ margin-left: 5px;
+ }
+ .checkbox {
+ padding: 0;
+ margin: 0;
+ }
+ .btn-success {
+ .border-radius(5px);
+ }
+ .btn-cancel, .btn-cancel:active {
+ background: none;
+ border: none;
+ box-shadow: none;
+ color: @red;
+ line-height: 1em;
+ }
+ select {
+ margin-top: -4px;
+ margin-bottom: 0px;
+ }
+ .include-end-key-row {
+ line-height: 20px;
+ margin-left: 8px;
+ }
+ }
+
+ .toggle-btns {
+ .btn {
+ padding: 5px 12px 5px;
+ background: #727A82;
+ color: #fff;
+ font-size: 12px;
+ border: none;
+ }
+ .btn.active {
+ background: #fff;
+ color: #E33F3B;
+ box-shadow: 2px 2px 0px rgba(0, 0, 0, 0.25) inset, 2px 2px 2px rgba(0, 0, 0, 0.15);
+ }
+ label:first-child {
+ .border-radius(5px 0 0 5px);
+ }
+ label:last-child {
+ .border-radius(0 5px 5px 0);
+ margin-left: 1px;
+ }
+ }
+
+ label {
+ margin-right: 0;
+ font-size: 13px;
+
+ /*
+ due to: https://code.google.com/p/chromium/issues/detail?id=411065 - that bug causes the checkbox state not to
+ update when the user clicks on labels quickly. It can be removed once the fix is in Chrome stable
+ */
+ -webkit-user-select: none;
+ }
+ label.disabled {
+ color: #777777;
+ }
+ div.controls-group.well{
+ height: 156px;
+ background: none;
+ border: none;
+ padding: 10px 0;
+ }
+ .row-fluid.fieldsets {
+ .inline {
+ width: 32%;
+ }
+ .inline:nth-child(3) {
+ text-align: right;
+ width: 34%;
+ }
+ }
+ .row-fluid.fieldsets {
+ margin-bottom: 5px;
+ :last-child {
+ margin-bottom: 2px;
+ }
+ }
+
+ #skipRows {
+ margin-left: 5px;
+ }
+ .add-on {
+ height: 28px;
+ }
+ .hide {
+ display: none;
+ }
+
+ .icon-question-sign:hover {
+ color: @red;
+ }
+ .additionalParams {
+ margin-bottom: 2px;
+ }
+}
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/resources.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/resources.js b/app/addons/documents/resources.js
index ef119ac..651ca37 100644
--- a/app/addons/documents/resources.js
+++ b/app/addons/documents/resources.js
@@ -249,7 +249,6 @@ function(app, FauxtonAPI, PagingCollection) {
var ddoc = this.id.replace(/^_design\//,"");
return "_design/"+app.utils.safeURLName(ddoc);
}
-
});
Documents.ViewRow = FauxtonAPI.Model.extend({
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/routes-documents.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/routes-documents.js b/app/addons/documents/routes-documents.js
index d3f693f..37ec482 100644
--- a/app/addons/documents/routes-documents.js
+++ b/app/addons/documents/routes-documents.js
@@ -12,7 +12,6 @@
define([
"app",
-
"api",
// Modules
@@ -85,16 +84,16 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
"route:paginate": "paginate",
"route:perPageChange": "perPageChange",
"route:changesFilterAdd": "addFilter",
- "route:changesFilterRemove": "removeFilter"
+ "route:changesFilterRemove": "removeFilter",
+ "route:updateQueryOptions": "updateQueryOptions",
+ "route:resetQueryOptions": "resetQueryOptions"
},
overrideBreadcrumbs: true,
initialize: function (route, masterLayout, options) {
this.databaseName = options[0];
-
this.database = new Databases.Model({id:this.databaseName});
-
this.designDocs = new Documents.AllDocs(null, {
database: this.database,
paging: {
@@ -123,12 +122,12 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
}));
},
- setUpDropdown: function(){
+ setUpDropdown: function() {
var defaultMenuLinks = [{
links: [{
title: 'Replicate Database',
icon: 'fonticon-replicate',
- url: '#/replication/'+this.databaseName
+ url: '#/replication/' + this.databaseName
},{
title: 'Delete',
icon: 'fonticon-trash',
@@ -159,37 +158,33 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
}];
return _.reduce(FauxtonAPI.getExtensions('sidebar:links'), function (menuLinks, link) {
-
menuLinks.push({
title: link.title,
url: newurlPrefix + "/" + link.url,
icon: 'fonticon-plus-circled'
});
-
return menuLinks;
- }, menuLinks);
-
+ }, menuLinks);
},
designDocMetadata: function(database, ddoc){
this.toolsView && this.toolsView.remove();
this.viewEditor && this.viewEditor.remove();
- var designDocInfo = new Resources.DdocInfo({_id: "_design/"+ddoc},{database: this.database });
-
+ var designDocInfo = new Resources.DdocInfo({ _id: "_design/" + ddoc }, { database: this.database });
this.setView("#dashboard-lower-content", new Documents.Views.DdocInfo({
ddocName: ddoc,
model: designDocInfo
}));
this.sidebar.setSelectedTab(app.utils.removeSpecialCharacters(ddoc)+"_metadata");
+ this.leftheader.updateCrumbs(crumbs.allDocs(this.database));
+ this.rightHeader.hideQueryOptions();
-
- this.leftheader.updateCrumbs(crumbs.allDocs(this.database));
-
+ // problem line again
this.apiUrl = [designDocInfo.url('apiurl'), designDocInfo.documentation() ];
-
},
+
tempFn: function(databaseName, ddoc, fn){
this.setView("#dashboard-upper-content", new Documents.Views.temp({}));
this.crumbs = function () {
@@ -197,7 +192,6 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
{"name": this.database.id, "link": Databases.databaseUrl(this.database)},
];
};
-
},
establish: function () {
@@ -215,10 +209,10 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
},
/*
- * docParams are the options collection uses to fetch from the server
- * urlParams are what are shown in the url and to the user
- * They are not the same when paginating
- */
+ * docParams are the options collection uses to fetch from the server
+ * urlParams are what are shown in the url and to the user
+ * They are not the same when paginating
+ */
allDocs: function(databaseName, options) {
var params = this.createParams(options),
urlParams = params.urlParams,
@@ -232,23 +226,15 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
this.leftheader.updateCrumbs(crumbs.allDocs(this.database));
this.database.buildAllDocs(docParams);
- if (docParams.startkey && docParams.startkey.indexOf('_design') > -1) {
- this.sidebar.setSelectedTab('design-docs');
+ if (docParams.startkey && docParams.startkey.indexOf("_design") > -1) {
+ this.sidebar.setSelectedTab("design-docs");
} else {
- this.sidebar.setSelectedTab('all-docs');
+ this.sidebar.setSelectedTab("all-docs");
}
this.viewEditor && this.viewEditor.remove();
-
this.database.allDocs.paging.pageSize = this.getDocPerPageLimit(urlParams, parseInt(docParams.limit, 10));
- this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.AllDocsLayout({
- database: this.database,
- collection: this.database.allDocs,
- params: urlParams,
- docParams: docParams
- }));
-
this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
database: this.database,
collection: this.database.allDocs,
@@ -261,20 +247,23 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
return [this.database.allDocs.urlRef("apiurl", urlParams), this.database.allDocs.documentation()];
};
+ // update the rightHeader with the latest & greatest info
+ this.rightHeader.resetQueryOptions({ queryParams: urlParams });
+ this.rightHeader.showQueryOptions();
},
- viewFn: function (databaseName, ddoc, view) {
+ viewFn: function (databaseName, ddoc, viewName) {
var params = this.createParams(),
urlParams = params.urlParams,
docParams = params.docParams,
decodeDdoc = decodeURIComponent(ddoc);
- view = view.replace(/\?.*$/,'');
+ viewName = viewName.replace(/\?.*$/,'');
this.indexedDocs = new Documents.IndexCollection(null, {
database: this.database,
design: decodeDdoc,
- view: view,
+ view: viewName,
params: docParams,
paging: {
pageSize: this.getDocPerPageLimit(urlParams, parseInt(docParams.limit, 10))
@@ -284,11 +273,11 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
this.viewEditor = this.setView("#dashboard-upper-content", new Index.ViewEditor({
model: this.database,
ddocs: this.designDocs,
- viewName: view,
+ viewName: viewName,
params: urlParams,
newView: false,
database: this.database,
- ddocInfo: this.ddocInfo(decodeDdoc, this.designDocs, view)
+ ddocInfo: this.ddocInfo(decodeDdoc, this.designDocs, viewName)
}));
this.toolsView && this.toolsView.remove();
@@ -300,14 +289,23 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
database: this.database,
indexedDocs: this.indexedDocs,
designDocs: this.designDocs,
- view: view
+ view: viewName
});
- this.sidebar.setSelectedTab(app.utils.removeSpecialCharacters(ddoc) + '_' + app.utils.removeSpecialCharacters(view));
+ this.sidebar.setSelectedTab(app.utils.removeSpecialCharacters(ddoc) + '_' + app.utils.removeSpecialCharacters(viewName));
this.apiUrl = function() {
return [this.indexedDocs.urlRef("apiurl", urlParams), "docs"];
};
+
+ this.rightHeader.showQueryOptions();
+ this.rightHeader.resetQueryOptions({
+ queryParams: urlParams,
+ showStale: true,
+ hasReduce: true,
+ viewName: viewName,
+ ddocName: ddoc
+ });
},
ddocInfo: function (designDoc, designDocs, view) {
@@ -319,7 +317,6 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
},
createViewDocumentsView: function (options) {
-
return this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
database: options.database,
collection: options.indexedDocs,
@@ -338,19 +335,22 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
this.documentsView && this.documentsView.remove();
this.viewEditor = this.setView("#dashboard-upper-content", new Index.ViewEditor({
- currentddoc: "_design/"+designDoc || "",
+ currentddoc: "_design/" + designDoc || "",
ddocs: this.designDocs,
params: params,
database: this.database,
newView: true
}));
- this.sidebar.setSelectedTab('new-view');
+ this.sidebar.setSelectedTab("new-view");
+ this.rightHeader.hideQueryOptions();
// clear out anything that was in the lower section
this.removeView("#dashboard-lower-content");
- //this.rightHeader.updateApiUrl([this.indexedDocs.urlRef("apiurl", urlParams), "docs"]);
+ // TODO
+// var apiUrl = this.database.url("app") + "/new_view/" + designDoc;
+// this.rightHeader.updateApiUrl([apiUrl, "docs"]);
},
updateAllDocsFromView: function (event) {
@@ -370,7 +370,6 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
this.database.buildAllDocs(docParams);
collection = this.database.allDocs;
collection.paging.pageSize = pageSize;
-
} else {
collection = this.indexedDocs = new Documents.IndexCollection(null, {
database: this.database,
@@ -399,7 +398,11 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
this.documentsView.setParams(docParams, urlParams);
this.documentsView.forceRender();
- this.apiUrl = [collection.urlRef("apiurl", urlParams), "docs"];
+ // this has been commented out because it causes the header bar to disappear after a search (i.e the "Query
+ // Options" link disappears). This issue is being addressed in a separate ticket (not sure about the Jira ID)
+// this.apiUrl = function() {
+// return [this.indexedDocs.urlRef("apiurl", urlParams), "docs"];
+// };
},
perPageChange: function (perPage) {
@@ -473,13 +476,12 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
this.viewEditor && this.viewEditor.remove();
this.sidebar.setSelectedTab('changes');
-
this.leftheader.updateCrumbs(crumbs.changes(this.database));
+ this.rightHeader.showQueryOptions();
this.apiUrl = function () {
return [this.database.url("changes-apiurl"), this.database.documentation()];
};
-
},
addFilter: function (filter) {
@@ -490,10 +492,16 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
removeFilter: function (filter) {
this.changesView.filters.splice(this.changesView.filters.indexOf(filter), 1);
this.changesView.render();
- }
+ },
+ resetQueryOptions: function(options) {
+ this.rightHeader.resetQueryOptions(options);
+ },
+
+ updateQueryOptions: function(options) {
+ this.rightHeader.updateQueryOptions(options);
+ }
});
return DocumentsRouteObject;
});
-
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/templates/advanced_options.html
----------------------------------------------------------------------
diff --git a/app/addons/documents/templates/advanced_options.html b/app/addons/documents/templates/advanced_options.html
deleted file mode 100644
index c986d4e..0000000
--- a/app/addons/documents/templates/advanced_options.html
+++ /dev/null
@@ -1,157 +0,0 @@
-<!--
-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="js-view-query-update custom-inputs">
-
-<!-- tabs for choosing Keys or Start & end -->
-
- <div class="btn-group toggle-btns row-fluid">
- <label for="showKeys" class="drop-down btn span6">
- By Key(s)
- </label>
- <label for="showStartEnd" class="drop-down btn span6">
- Between Keys
- </label>
- </div>
-
- <div class="controls-group well hide js-query-keys-wrapper">
- <div class="row-fluid" id="js-showKeys">
- <div class="controls controls-row">
- <label for="keys-input" class="drop-down">A key, or an array of keys.</label>
- <textarea id="keys-input" name="keys" class="input-xxlarge" rows="5" type="text" placeholder='Enter valid JSON; e.g., ["1234"] or ["1234","2345"]'></textarea>
- <div id="keys-error" class="inline-block js-keys-error"></div>
- </div>
- </div>
- <div class="row-fluid hide" id="js-showStartEnd">
- <div class="controls controls-row">
- <div class="span6">
- <label for="startkey" class="drop-down">Start key</label>
- <input name="startkey" id="startkey" type="text" placeholder='e.g., "1234"' disabled>
- </div>
- <div class="span6">
- <label for="endkey" class="drop-down">End key</label>
- <input id="endkey" name="endkey" type="text" placeholder='e.g., "1234"'>
- <div class="controls controls-row checkbox inline">
- <input id="check5" name="inclusive_end" type="checkbox" value="true" checked disabled>
- <label for="check5">Include End Key in results</label>
- </div>
- </div>
-
- </div>
-
- </div>
- </div>
-
-<!-- Limit and Skip are conditional -->
-
- <div class="controls-group">
-
- <div class="row-fluid">
- <div class="span6">
- <label class="drop-down inline">
- Limit:
- <select name="limit" class="input-medium">
- <option selected="selected">None</option>
- <option>5</option>
- <option>10</option>
- <option>20</option>
- <option>30</option>
- <option>50</option>
- <option>100</option>
- <option>500</option>
- </select>
- </label>
- </div>
- <div class="span6">
- <label for="skipRows" class="inline drop-down">
- # of rows to skip
- <input name="skip" class="input-small" type="text" id="skipRows" placeholder="0">
- </label>
- </div>
- </div>
- <div class="row-fluid">
- <div class="span6">
- <label id="select2" class="drop-down inline">
- Order:
- <select id="select2" name="descending" class="input-medium">
- <option value="false">Ascending</option>
- <option value="true">Descending</option>
- </select>
- </label>
- </div>
- <div class="span6">
- <label id="select2" class="drop-down inline">
- Docs:
- <select id="select2" name="include_docs" class="input-medium">
- <option value="false">Exclude</option>
- <option value="true">Include</option>
- </select>
- </label>
- </div>
- </div>
- <div class="row-fluid">
- <% if (showStale) { %>
- <div class="span6">
- <div class="checkbox inline">
- <input id="check7" name="stale" type="checkbox" value="ok">
- <label for="check7">Stale</label>
- </div>
- </div>
- <% } %>
- <div class="span6 update-seq">
- <div class="checkbox inline">
- <input id="check6" name="update_seq" type="checkbox" value="true">
- <label for="check6">Update Sequence</label>
- </div>
- </div>
-
- </div>
- <% if (hasReduce) { %>
- <div class="row-fluid">
- <div class="span6">
- <div class="checkbox inline">
- <input id="check2" name="reduce" type="checkbox" value="true">
- <label for="check2">Reduce</label>
- </div>
- </div>
- <div class="span6">
- <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>
- </div>
- <% } %>
- </div>
-
- <div class="controls-group">
- <div id="button-options" class="controls controls-row">
- <button type="submit" class="btn btn-success">Query</button>
- </div>
- </div>
-</form>
-</div>
-
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/templates/all_docs_layout.html
----------------------------------------------------------------------
diff --git a/app/addons/documents/templates/all_docs_layout.html b/app/addons/documents/templates/all_docs_layout.html
index e2c2479..8db91ed 100644
--- a/app/addons/documents/templates/all_docs_layout.html
+++ b/app/addons/documents/templates/all_docs_layout.html
@@ -11,15 +11,6 @@ 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="dashboard-upper-menu">
- <ul class="nav nav-tabs window-resizeable" id="db-views-tabs-nav">
- <li><a id="toggle-query" href="#query" data-bypass="true" data-toggle="tab">
- <i class="fonticon fonticon-plus"></i> Query Options</a></li>
- </ul>
- <div class="js-search searchbox-container"></div>
-</div>
-
<div class="tab-content">
- <div class="tab-pane" id="query">
- </div>
+ <div class="tab-pane" id="query"></div>
</div>
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/templates/all_docs_list.html
----------------------------------------------------------------------
diff --git a/app/addons/documents/templates/all_docs_list.html b/app/addons/documents/templates/all_docs_list.html
index 8db7bbe..c77fc05 100644
--- a/app/addons/documents/templates/all_docs_list.html
+++ b/app/addons/documents/templates/all_docs_list.html
@@ -33,9 +33,9 @@ the License.
</table>
<% if (endOfResults) { %>
- <div class="text-center well">
+ <div class="end-of-results text-center well">
<p class="muted">
- End of results - <a id="js-end-results" href="#query" data-bypass="true" data-toggle="tab">edit query</a>
+ End of results - <a id="js-end-results" href="#query" data-bypass="true">edit query</a>
</p>
</div>
<% } %>
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/templates/ddoc_info.html
----------------------------------------------------------------------
diff --git a/app/addons/documents/templates/ddoc_info.html b/app/addons/documents/templates/ddoc_info.html
index e9b1b6e..5c180ec 100644
--- a/app/addons/documents/templates/ddoc_info.html
+++ b/app/addons/documents/templates/ddoc_info.html
@@ -58,4 +58,4 @@ the License.
</dl>
</div>
</div>
-</div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/templates/header_alldocs.html
----------------------------------------------------------------------
diff --git a/app/addons/documents/templates/header_alldocs.html b/app/addons/documents/templates/header_alldocs.html
index b353d89..a4da0fb 100644
--- a/app/addons/documents/templates/header_alldocs.html
+++ b/app/addons/documents/templates/header_alldocs.html
@@ -13,13 +13,12 @@ the License.
-->
<!-- floats right -->
-
<div id="header-api-bar" class="button"></div>
<!-- Query Options-->
- <!--<div class="button header-query-options">
+ <div id="header-query-options" class="button">
<div id="query-options"></div>
- </div>-->
+ </div>
<!-- search (jump to doc)-->
<div id="header-search" class="js-search searchbox-container"></div>
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/templates/query_options.html
----------------------------------------------------------------------
diff --git a/app/addons/documents/templates/query_options.html b/app/addons/documents/templates/query_options.html
new file mode 100644
index 0000000..8126457
--- /dev/null
+++ b/app/addons/documents/templates/query_options.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.
+*/ %>
+<a id="toggle-query" href="#query-options-tray" data-bypass="true" data-toggle="tab"
+ class="btn btn-primary pull-right query-options-btn">
+ <i class="icon header-icon fonticon-gears"></i>
+ Query Options
+</a>
+
+<div id="query-options-tray" class="query-options tray">
+ <form class="js-view-query-update custom-inputs">
+
+ <div class="query-group" id="query-options-main-fields"></div>
+ <div class="query-group" id="query-options-key-search"></div>
+ <div class="controls-group query-group" id="query-options-additional-params"></div>
+
+ <div class="controls-group query-group">
+ <div id="button-options" class="controls controls-row">
+ <button type="submit" class="btn btn-success">
+ <i class="fonticon-play icon"></i>
+ Query
+ </button>
+ <a class="btn btn-cancel">Cancel</a>
+ </div>
+ </div>
+
+ </form>
+</div>
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/templates/query_options_additional_params.html
----------------------------------------------------------------------
diff --git a/app/addons/documents/templates/query_options_additional_params.html b/app/addons/documents/templates/query_options_additional_params.html
new file mode 100644
index 0000000..3784315
--- /dev/null
+++ b/app/addons/documents/templates/query_options_additional_params.html
@@ -0,0 +1,61 @@
+<% /*
+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.
+*/ %>
+
+<!-- Limit and Skip are conditional -->
+<div class="add-on additionalParams">Additional Parameters</div>
+
+<div class="row-fluid fieldsets">
+
+ <% if (showStale) { %>
+ <div class="checkbox inline">
+ <input id="qoStale" name="stale" type="checkbox" value="ok" />
+ <label for="qoStale">Stale</label>
+ </div>
+ <% } %>
+
+ <div class="checkbox inline">
+ <input id="qoUpdateSeq" name="update_seq" type="checkbox" value="true" />
+ <label for="qoUpdateSeq">Update Sequence</label>
+ </div>
+
+ <div class="dropdown inline">
+ <label class="drop-down">
+ Limit
+ <select id="qoLimit" name="limit" class="input-small">
+ <option value="" selected="selected">None</option>
+ <option value="5">5</option>
+ <option value="10">10</option>
+ <option value="20">20</option>
+ <option value="30">30</option>
+ <option value="50">50</option>
+ <option value="100">100</option>
+ <option value="500">500</option>
+ </select>
+ </label>
+ </div>
+</div>
+
+<div class="row-fluid fieldsets">
+ <div class="checkbox inline">
+ <input id="qoDescending" name="descending" type="checkbox" value="true" />
+ <label for="qoDescending">Descending</label>
+ </div>
+
+ <div class="dropdown inline">
+ <label for="qoSkip" class="drop-down">
+ Skip
+ <input name="skip" class="input-small" type="text" id="qoSkip" placeholder="# of rows" />
+ </label>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/templates/query_options_key_search.html
----------------------------------------------------------------------
diff --git a/app/addons/documents/templates/query_options_key_search.html b/app/addons/documents/templates/query_options_key_search.html
new file mode 100644
index 0000000..b288b4d
--- /dev/null
+++ b/app/addons/documents/templates/query_options_key_search.html
@@ -0,0 +1,50 @@
+<% /*
+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="add-on">Keys</div>
+
+<!-- tabs for choosing Keys or start & end -->
+<div class="btn-group toggle-btns row-fluid">
+ <label data-action="showByKeys" class="drop-down btn">By Key(s)</label>
+ <label data-action="showBetweenKeys" class="drop-down btn">Between Keys</label>
+</div>
+
+<div class="controls-group well hide js-query-keys-wrapper">
+ <div class="row-fluid js-keys-section" id="js-showKeys">
+ <div class="controls controls-row">
+ <label for="keys-input" class="drop-down">A key, or an array of keys.</label>
+ <textarea id="keys-input" name="keys" class="input-xxlarge" rows="5" type="text"
+ placeholder='Enter valid JSON; e.g., ["1234"] or ["1234","2345"]'></textarea>
+ <div id="keys-error" class="inline-block js-keys-error"></div>
+ </div>
+ </div>
+
+ <div class="row-fluid js-keys-section hide" id="js-showStartEnd">
+ <div class="controls controls-row">
+ <div>
+ <label for="startkey" class="drop-down">Start key</label>
+ <input name="startkey" id="startkey" type="text" placeholder='e.g., "1234"' disabled />
+ </div>
+ <div>
+ <label for="endkey" class="drop-down">End key</label>
+ <input id="endkey" name="endkey" type="text" placeholder='e.g., "1234"'>
+ <div class="controls include-end-key-row checkbox controls-row inline">
+ <input id="qoIncludeEndKeyInResults" name="inclusive_end" type="checkbox" value="true" checked disabled />
+ <label for="qoIncludeEndKeyInResults">Include End Key in results</label>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/templates/query_options_main_fields.html
----------------------------------------------------------------------
diff --git a/app/addons/documents/templates/query_options_main_fields.html b/app/addons/documents/templates/query_options_main_fields.html
new file mode 100644
index 0000000..48b5d3c
--- /dev/null
+++ b/app/addons/documents/templates/query_options_main_fields.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.
+*/ %>
+
+<span class="add-on">
+ Query Options
+ <a class="help-link" href="<%-getDocUrl(documentation)%>" target="_blank" data-bypass="true">
+ <i class="icon-question-sign"></i>
+ </a>
+</span>
+
+<div class="errors-container"></div>
+
+<div class="controls-group">
+ <div class="row-fluid fieldsets">
+ <div class="checkbox inline">
+ <input id="qoIncludeDocs" name="include_docs" type="checkbox" value="true" />
+ <label for="qoIncludeDocs" id="qoIncludeDocsLabel">Include Docs</label>
+ </div>
+
+ <% if (hasReduce) { %>
+ <div class="checkbox inline">
+ <input id="qoReduce" name="reduce" type="checkbox" value="true" />
+ <label for="qoReduce">Reduce</label>
+ </div>
+
+ <label class="drop-down inline" id="qoGroupLevelGroup">
+ Group Level
+ <select id="qoGroupLevel" 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>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/templates/view_editor.html
----------------------------------------------------------------------
diff --git a/app/addons/documents/templates/view_editor.html b/app/addons/documents/templates/view_editor.html
index 769deed..d22c734 100644
--- a/app/addons/documents/templates/view_editor.html
+++ b/app/addons/documents/templates/view_editor.html
@@ -15,12 +15,8 @@ the License.
<ul class="nav nav-tabs" id="db-views-tabs-nav">
<li class="active"> <a data-bypass="true" id="index-nav" data-toggle="tab" href="#index">
<i class="fonticon-wrench fonticon"></i>
- <% if (newView) { %>Create Index <% } else { %>Edit Index <% } %></a></li>
- <% if (!newView) { %>
- <li><a data-bypass="true" id="query-nav" href="#query" data-toggle="tab">
- <i class="fonticon-plus fonticon"></i> Query Options</a>
+ <% if (newView) { %>Create Index <% } else { %>Edit Index <% } %></a>
</li>
- <% } %>
</ul>
</div>
<div class="all-docs-list errors-container"></div>
@@ -78,6 +74,7 @@ the License.
<% if (!newView) { %>
<button class="btn btn-danger delete"><i class="icon fonticon-cancel-circled"></i> Delete</button>
<% } %>
+ <span id="viewBtnExtensions"></span>
</div>
<div class="clearfix"></div>
</form>
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/tests/views-advancedoptsSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/views-advancedoptsSpec.js b/app/addons/documents/tests/views-advancedoptsSpec.js
index 3f9373b..fe9bbe5 100644
--- a/app/addons/documents/tests/views-advancedoptsSpec.js
+++ b/app/addons/documents/tests/views-advancedoptsSpec.js
@@ -10,14 +10,14 @@
// License for the specific language governing permissions and limitations under
// the License.
define([
- 'addons/documents/views-advancedopts',
- 'testUtils'
+ 'addons/documents/views-queryoptions',
+ 'testUtils'
], function (Views, testUtils) {
var assert = testUtils.assert,
ViewSandbox = testUtils.ViewSandbox,
viewSandbox;
- describe('Documents AdvancedOptions', function () {
+ describe('Documents QueryOptions', function () {
var view;
beforeEach(function () {
viewSandbox = new ViewSandbox();
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/views-advancedopts.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/views-advancedopts.js b/app/addons/documents/views-advancedopts.js
deleted file mode 100644
index b2e1af5..0000000
--- a/app/addons/documents/views-advancedopts.js
+++ /dev/null
@@ -1,270 +0,0 @@
-// 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",
- // Libs
- "addons/fauxton/resizeColumns",
-],
-
-function(app, FauxtonAPI, resizeColumns ) {
-
- var Views = {};
-
- Views.AdvancedOptions = FauxtonAPI.View.extend({
- template: "addons/documents/templates/advanced_options",
- className: "advanced-options well",
-
- initialize: function (options) {
- this.database = options.database;
- this.ddocName = options.ddocName;
- this.viewName = options.viewName;
- this.updateViewFn = options.updateViewFn;
- this.previewFn = options.previewFn;
- this.showStale = _.isUndefined(options.showStale) ? false : options.showStale;
- this.hasReduce = _.isUndefined(options.hasReduce) ? true : options.hasReduce;
- },
-
- events: {
- "change form.js-view-query-update input": "updateFilters",
- "change form.js-view-query-update select": "updateFilters",
- "submit form.js-view-query-update": "updateView",
- "click .toggle-btns > label": "toggleQuery"
- },
-
- toggleQuery: function(e){
- e.preventDefault();
-
- if (this.$(e.currentTarget).hasClass("active")){
- this.$('.js-query-keys-wrapper').addClass("hide");
- this.$(".toggle-btns > label").removeClass('active');
- this.$('.js-query-keys-wrapper').find("input,textarea").attr("disabled","true");
- } else {
- this.$('.js-query-keys-wrapper').removeClass("hide");
- var showFunctionName =this.$(e.currentTarget).attr("for");
- //highlight current
- this.$(".toggle-btns > label").removeClass('active');
- this.$(e.currentTarget).addClass("active");
- this.$("[id^='js-show']").hide();
- //show section & disable what needs to be disabled
- this[showFunctionName]();
- }
- },
-
- showKeys: function(){
- this.$("#js-showKeys, .js-disabled-message").show();
- this.$('[name="startkey"],[name="endkey"],[name="inclusive_end"]').attr("disabled","true");
- this.$('[name="keys"]').removeAttr("disabled");
- },
-
- showStartEnd: function(){
- this.$("#js-showStartEnd").show();
- this.$('[name="startkey"],[name="endkey"],[name="inclusive_end"]').removeAttr("disabled");
- this.$('.js-disabled-message').hide();
- this.$('[name="keys"]').attr("disabled","true");
- },
-
- beforeRender: function () {
- if (this.viewName && this.ddocName) {
- var buttonViews = FauxtonAPI.getExtensions('advancedOptions:ViewButton');
- _.each(buttonViews, function (view) {
- this.insertView('#button-options', view);
- view.update(this.database, this.ddocName, this.viewName);
- }, this);
- }
- },
-
- renderOnUpdatehasReduce: function (hasReduce) {
- this.hasReduce = hasReduce;
- this.render();
- },
-
- parseJSON: function (value) {
- try {
- return JSON.parse(value);
- } catch(e) {
- return undefined;
- }
- },
-
- validateKeys: function(param){
- var errorMsg = false,
- parsedValue = this.parseJSON(param.value);
-
- if (_.isUndefined(parsedValue)) {
- errorMsg = "Keys must be valid json.";
- } else if (!_.isArray(parsedValue)) {
- errorMsg = "Keys values must be in an array. E.g [1,2,3]";
- }
-
- if (errorMsg) {
- this.$('.js-keys-error').empty();
- FauxtonAPI.addNotification({
- type: "error",
- msg: errorMsg,
- clear: false,
- selector: '.advanced-options .errors-container'
- });
- return false;
- }
-
- return true;
- },
- validateFields: function(params){
- var errors = false;
- //so ghetto. Spaghetti code.
- for (var i= 0; i <params.length; i++){
- if (params[i].name === "skip"){
- if (!(/^\d+$/).test(params[i].value)){
- FauxtonAPI.addNotification({
- msg: "Numbers only for skip",
- type: "warn",
- selector: ".advanced-options .errors-container",
- clear: true
- });
- errors = true;
- }
- }
- }
- return errors;
- },
- queryParams: function () {
- var $form = this.$(".js-view-query-update"),
- keysParam = false;
-
- var params = _.reduce($form.serializeArray(), function(params, param) {
- if (!param.value) { return params; }
- if (param.name === "limit" && param.value === 'None') { return params; }
- if (param.name === "keys") { keysParam = param; }
- params.push(param);
- return params;
- }, []);
-
-
- if (keysParam && !this.validateKeys(keysParam)) { return false; }
-
- if (params && this.validateFields(params)){ return false; }
-
- // Validate *key* params to ensure they're valid JSON
- var keyParams = ["keys","startkey","endkey"];
- var errorParams = _.filter(params, function(param) {
- if (_.contains(keyParams, param.name) && _.isUndefined(this.parseJSON(param.value))) {
- return true;
- }
-
- return false;
- }, this);
-
- return {params: params, errorParams: errorParams};
- },
-
- updateView: function (event) {
- event.preventDefault();
- var params = this.queryParams();
- if (!params) { return;}
- this.updateViewFn(event, params);
- },
-
- 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.js-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: ".advanced-options .errors-container",
- clear: true
- });
- }
- $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]").val("999").prop("disabled", true);
- $form.find("input[name=include_docs]").prop("disabled", false);
- }
- break;
- case "skip":
- if (!(/^\d+$/).test($ele.val())){
- FauxtonAPI.addNotification({
- msg: "Numbers only for skip",
- type: "warn",
- selector: ".advanced-options .errors-container",
- clear: true
- });
- }
- break;
- case "include_docs":
- break;
- }
- },
-
- updateFromParams: function (params) {
- var $form = this.$el.find("form.js-view-query-update");
- _.each(params, function(val, key) {
- var $ele;
- switch (key) {
- case "limit":
- case "descending":
- case "group_level":
- if (!val) { return; }
- $form.find("select[name='"+key+"']").val(val);
- break;
- case "include_docs":
- case "stale":
- 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;
- case "key":
- case "keys":
- $form.find("textarea[name='"+key+"']").val(val);
- break;
- default:
- $form.find("input[name='"+key+"']").val(val);
- break;
- }
- }, this);
- },
-
- serialize: function () {
- return {
- hasReduce: this.hasReduce,
- showPreview: false,
- showStale: this.showStale
- };
- }
- });
-
-
- return Views;
-
-});
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/views-index.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/views-index.js b/app/addons/documents/views-index.js
index db4a83b..cbc76ad 100644
--- a/app/addons/documents/views-index.js
+++ b/app/addons/documents/views-index.js
@@ -12,15 +12,15 @@
define([
"app",
-
"api",
"addons/fauxton/components",
-
"addons/documents/resources",
"addons/databases/resources",
"addons/pouchdb/base",
+
//views
- "addons/documents/views-advancedopts",
+ "addons/documents/views-queryoptions",
+
// Libs
"addons/fauxton/resizeColumns",
@@ -29,11 +29,20 @@ define([
"plugins/prettify"
],
-function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
- QueryOptions, resizeColumns, beautify, prettify) {
+function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, QueryOptions, resizeColumns, beautify) {
var Views = {};
+
+ // this is a temporary workaround until I hear of a better on. The problem is that on initial page load (i.e. a refresh
+ // of the View page) the afterRender() functions calls a FauxtonAPI.triggerRouteEvent(). That causes this View to be
+ // rendered twice (at least, the afterRender() function then gets called twice) - and that causes the header content to
+ // disappear. This var tracks whether the View has been rendered and if not, doesn't call the triggerRouteEvent. btw,
+ // the reason the triggerRouteEvent('resetQueryOptions') code is there is that it ensures the Query Options tray shows
+ // the appropriate content for the current View (i.e. hasReduce or not)
+ var hasRenderedOnce = false;
+
+
Views.ViewEditor = FauxtonAPI.View.extend({
template: "addons/documents/templates/view_editor",
builtinReduces: ['_sum', '_count', '_stats'],
@@ -57,13 +66,16 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
},
defaultLang: "javascript",
+ rendered: false,
initialize: function(options) {
+ this.rightHeader = options.rightHeader;
this.newView = options.newView || false;
this.ddocs = options.ddocs;
this.params = options.params;
this.database = options.database;
this.currentDdoc = options.currentddoc;
+
if (this.newView) {
this.viewName = 'newView';
} else {
@@ -133,14 +145,14 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
},
saveView: function(event) {
- var json, notification,
- that = this;
+ var notification,
+ that = this;
- if (event) { event.preventDefault();}
+ if (event) { event.preventDefault(); }
$('#dashboard-content').scrollTop(0); //scroll up
- if (this.hasValidCode() && this.$('#new-ddoc:visible').val() !=="") {
+ if (this.hasValidCode() && this.$('#new-ddoc:visible').val() !== "") {
var mapVal = this.mapEditor.getValue(),
reduceVal = this.reduceVal(),
viewName = this.$('#index-name').val(),
@@ -177,7 +189,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
if (that.newView || viewNameChange) {
var fragment = '/database/' + that.database.safeID() +'/' + ddoc.safeID() + '/_views/' + app.utils.safeURLName(viewName);
- FauxtonAPI.navigate(fragment, {trigger: false});
+ FauxtonAPI.navigate(fragment, { trigger: false });
that.newView = false;
that.ddocID = ddoc.safeID();
that.viewName = viewName;
@@ -192,7 +204,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
if (that.reduceFunStr !== reduceVal) {
that.reduceFunStr = reduceVal;
- that.advancedOptions.renderOnUpdatehasReduce(that.hasReduce());
+ FauxtonAPI.triggerRouteEvent("updateQueryOptions", { hasReduce: that.hasReduce() });
}
FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: ddocName, view: viewName});
@@ -231,29 +243,25 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
// 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,
+ msg: "JSON Parse Error on field: " + param.name,
type: "error",
- selector: ".advanced-options .errors-container",
+ selector: ".query-options .errors-container",
clear: true
});
});
FauxtonAPI.addNotification({
msg: "Make sure that strings are properly quoted and any other values are valid JSON structures",
type: "warning",
- selector: ".advanced-options .errors-container",
+ selector: ".query-options .errors-container",
clear: true
});
return false;
}
- var fragment = window.location.hash.replace(/\?.*$/, '');
- if (!_.isEmpty(params)) {
- fragment = fragment + '?' + $.param(params);
- }
-
- FauxtonAPI.navigate(fragment, {trigger: false});
- FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
+ var url = app.utils.replaceQueryParams(params);
+ FauxtonAPI.navigate(url, {trigger: false});
+ FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
},
@@ -276,7 +284,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
FauxtonAPI.addNotification({
msg: "<strong>Warning!</strong> Preview executes the Map/Reduce functions in your browser, and may behave differently from CouchDB.",
type: "warning",
- selector: ".advanced-options .errors-container",
+ selector: ".query-options .errors-container",
fade: true,
escape: false // beware of possible XSS when the message changes
});
@@ -311,7 +319,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
if (this.mapEditor) {
return this.mapEditor.getValue();
}
-
return this.$('#map-function').text();
},
@@ -401,8 +408,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
$('.beautify-tooltip').tooltip();
}
},
- beforeRender: function () {
+ beforeRender: function () {
if (this.newView) {
this.reduceFunStr = '';
if (this.ddocs.length === 0) {
@@ -427,7 +434,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
});
designDocs.reset(filteredModels, {silent: true});
}
-
+
if (!this.designDocSelector) {
this.designDocSelector = this.setView('.design-doc-group', new Views.DesignDocSelector({
collection: designDocs,
@@ -436,27 +443,25 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
}));
}
+ // if this isn't a new View, add in whatever extensions have been associated with this location
if (!this.newView) {
- this.eventer = _.extend({}, Backbone.Events);
-
- this.advancedOptions = this.insertView('#query', new QueryOptions.AdvancedOptions({
- updateViewFn: this.updateView,
- previewFn: this.previewView,
- database: this.database,
- viewName: this.viewName,
- ddocName: this.model.id,
- hasReduce: this.hasReduce(),
- eventer: this.eventer,
- showStale: true
- }));
+ var buttonViews = FauxtonAPI.getExtensions('ViewEditor:ButtonRow');
+ _.each(buttonViews, function (view) {
+ this.insertView("#viewBtnExtensions", view);
+ view.update(this.database, this.ddocInfo.safeID(), this.viewName);
+ }, this);
}
-
},
afterRender: function() {
-
- if (this.params && !this.newView) {
- this.advancedOptions.updateFromParams(this.params);
+ if (this.params && !this.newView && hasRenderedOnce) {
+ FauxtonAPI.triggerRouteEvent('resetQueryOptions', {
+ queryParams: this.params,
+ hasReduce: this.hasReduce(),
+ showStale: true,
+ viewName: this.viewName,
+ ddocName: this.ddocInfo.get('name')
+ });
}
this.designDocSelector.updateDesignDoc();
@@ -468,6 +473,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
this.$('#index-nav').parent().removeClass('active');
}
+ // note that this View has been rendered
+ hasRenderedOnce = true;
},
showEditors: function () {
@@ -550,6 +557,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
newDocValidation: function(){
return this.newDesignDoc() && this.$('#new-ddoc').val()==="";
},
+
getCurrentDesignDoc: function () {
if (this.newDesignDoc()) {
var doc = {
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/332c7b53/app/addons/documents/views-queryoptions.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/views-queryoptions.js b/app/addons/documents/views-queryoptions.js
new file mode 100644
index 0000000..5bea495
--- /dev/null
+++ b/app/addons/documents/views-queryoptions.js
@@ -0,0 +1,519 @@
+// 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",
+
+ // libs
+ "addons/fauxton/resizeColumns"
+],
+
+ function (app, FauxtonAPI) {
+
+ // our default settings for the Query Options tray
+ var defaultOptions = {
+ showStale: false,
+ hasReduce: false,
+ viewName: null,
+ ddocName: null,
+
+ // all the possible query search params. Ultimately these should probably be moved higher-up (route object?),
+ // because they also apply to the actual search results. Seems better to place them there, then use them in
+ // both places
+ queryParams: {
+ include_docs: "false",
+ keys: "",
+ limit: "",
+ descending: "false",
+ skip: "",
+ update_seq: "false",
+ startkey: "",
+ endkey: "",
+ inclusive_end: "true",
+ reduce: "false",
+ stale: "",
+ group_level: "999"
+ }
+ };
+
+
+ var Views = {};
+
+ // our main View. This is the only View exposed externally
+ Views.QueryOptionsTray = FauxtonAPI.View.extend({
+ template: "addons/documents/templates/query_options",
+ className: "query-options",
+
+ initialize: function (options) {
+
+ // overlays whatever custom options were passed with defaultOptions above, so this.options
+ // always contains all options. [This does a deep copy: we never overwrite defaultOptions!]
+ this.options = $.extend(true, {}, defaultOptions, options);
+
+ // add any general events relating to the Query Options tray
+ this.addEvents();
+
+ // add the sub-views
+ this.mainFieldsView = this.setView("#query-options-main-fields", new MainFieldsView(this.options));
+ this.keySearchFieldsView = this.setView("#query-options-key-search", new KeySearchFieldsView(this.options));
+ this.additionalParamsView = this.setView("#query-options-additional-params", new AdditionalParamsView(this.options));
+ },
+
+ addEvents: function () {
+ FauxtonAPI.Events.on('QueryOptions:closeTray', this.closeTray, this);
+ FauxtonAPI.Events.on('QueryOptions:openTray', this.toggleQueryOptionsTray, this);
+
+ // if the user just clicked outside the tray, close it [TODO be nice to generalize for all trays]
+ var trayIsVisible = this.trayIsVisible;
+ var closeTray = this.closeTray;
+
+ $("body").on("click.queryOptions", function (e) {
+ if (!trayIsVisible()) { return; }
+ if ($(e.target).closest("#query-options-tray").length === 0) {
+ closeTray();
+ }
+ });
+
+ $(window).on("resize", this.onResize);
+ },
+
+ afterRender: function () {
+ this.onResize();
+ },
+
+ cleanup: function () {
+ FauxtonAPI.Events.unbind("QueryOptions:closeTray");
+ FauxtonAPI.Events.unbind("QueryOptions:openTray");
+ $(window).off("resize", this.onResize);
+ },
+
+ events: {
+ "click #toggle-query": "toggleQueryOptionsTray", // hide/show the Query Options tray
+ "submit form.js-view-query-update": "onSubmit", // submits the form
+ "click .btn-cancel": "onCancel" // closes the tray (doesn't reset the fields)
+ },
+
+ toggleQueryOptionsTray: function () {
+ if (!this.trayIsVisible()) {
+ $("#query-options-tray").velocity("transition.slideDownIn", 250); // TODO constant
+ FauxtonAPI.Events.trigger("APIbar:closeTray");
+ }
+ },
+
+ // returns all applicable query parameters for the Query Options tray
+ getQueryParams: function () {
+ var mainFieldParams = this.mainFieldsView.getParams();
+ var keySearchParams = this.keySearchFieldsView.getParams();
+ var additionalParams = this.additionalParamsView.getParams();
+
+ // assumption: there aren't conflicting keys
+ return _.extend({}, mainFieldParams, keySearchParams, additionalParams);
+ },
+
+ onSubmit: function (e) {
+ e.preventDefault();
+
+ // validate the user-inputted fields. If anything is invalid, the sub-view will display the appropriate
+ // errors to the user
+ if (!this.keySearchFieldsView.hasValidInputs() || !this.additionalParamsView.hasValidInputs()) {
+ return;
+ }
+
+ this.closeTray();
+
+ // this may be empty. That's ok! Perhaps the user just did a search with params, then removed them & wants the default
+ var params = this.getQueryParams();
+
+ // all looks good! Close the tray and publish the message
+ var url = app.utils.replaceQueryParams(params);
+ FauxtonAPI.navigate(url, { trigger: false });
+
+ if (this.options.viewName !== null && this.options.ddocName !== null) {
+ FauxtonAPI.triggerRouteEvent('updateAllDocs', { ddoc: this.options.ddocName, view: this.options.viewName });
+ } else {
+ FauxtonAPI.triggerRouteEvent("updateAllDocs", { allDocs: true });
+ }
+ },
+
+ onCancel: function () {
+ this.closeTray();
+ },
+
+ // if the screen is so small there isn't space for the full tray height we manually shrink the height to allow scrolling.
+ // Technically this should handle width as well, but we won't bother because there are way bigger issues with a screen
+ // with such a small width!
+ onResize: function () {
+ var $tray = $("#query-options-tray");
+ var heightFromTop = parseInt($tray.css("top"), 10);
+ var windowHeight = $(window).height();
+
+ // we apply the max-height to the form rather than the entire tray to allow the little up arrow to appear normally
+ $tray.find("form").css("max-height", windowHeight - heightFromTop);
+ },
+
+ /*
+ * Updates specific query options, leaving any that have been set already intact.
+ */
+ updateQueryOptions: function (options) {
+ this.options = $.extend(this.options, options);
+ this.updateSubViews();
+ },
+
+ /*
+ * Reset the query options back to the defaults, then apply whatever new options are needed.
+ */
+ resetQueryOptions: function (options) {
+ this.options = $.extend(true, {}, defaultOptions, options);
+ this.updateSubViews();
+ },
+
+ // helper
+ updateSubViews: function () {
+ this.mainFieldsView.update(this.options);
+ this.keySearchFieldsView.update(this.options);
+ this.additionalParamsView.update(this.options);
+ },
+
+ trayIsVisible: function () {
+ return $("#query-options-tray").is(":visible");
+ },
+
+ closeTray: function () {
+ $("#query-options-tray").velocity("reverse", 250, function () { // TODO constant
+ $("#query-options-tray").hide();
+ });
+ }
+ });
+
+
+ // ------ "private" Views ------
+
+ var MainFieldsView = FauxtonAPI.View.extend({
+ template: "addons/documents/templates/query_options_main_fields",
+ events: {
+ "change #qoReduce": "onToggleReduceCheckbox"
+ },
+
+ initialize: function (options) {
+ this.queryParams = options.queryParams;
+ this.showStale = options.showStale;
+ this.hasReduce = options.hasReduce;
+ },
+
+ update: function (options) {
+ this.queryParams = options.queryParams;
+ this.showStale = options.showStale;
+ this.hasReduce = options.hasReduce;
+
+ // if the View hasn't already rendered we can rely on afterRender() to pre-fill the fields
+ if (this.hasRendered) {
+ this.render();
+ }
+ },
+
+ afterRender: function () {
+ $("#qoIncludeDocs").prop("checked", this.queryParams.include_docs === "true");
+ this.updateReduceSettings(this.queryParams.reduce === "true");
+ },
+
+ /*
+ * The "Reduce" option comes with baggage:
+ * - we can't include_docs for reduce = true
+ * - can't include group_level for reduce = false
+ */
+ onToggleReduceCheckbox: function (e) {
+ e.preventDefault();
+ var isChecked = $(e.currentTarget).prop("checked");
+ this.updateReduceSettings(isChecked);
+ },
+
+
+ // helper function to hide/show, disable/enable fields based on whether "Reduce" is an option and whether
+ // it's checked
+ updateReduceSettings: function (isChecked) {
+ $("#qoReduce").prop("checked", isChecked);
+
+ var $qoIncludeDocs = $("#qoIncludeDocs"),
+ $qoIncludeDocsLabel = $("#qoIncludeDocsLabel"),
+ $qoGroupLevelGroup = $("#qoGroupLevelGroup");
+
+ if (this.hasReduce) {
+ $("#qoGroupLevel").val(this.queryParams.group_level);
+
+ if (isChecked) {
+ $qoIncludeDocs.prop({ "checked": false, "disabled": true });
+ $qoIncludeDocsLabel.addClass("disabled");
+ $qoGroupLevelGroup.removeClass("hide");
+ } else {
+ $qoIncludeDocs.prop("disabled", false);
+ $qoIncludeDocsLabel.removeClass("disabled");
+ $qoGroupLevelGroup.addClass("hide");
+ }
+ } else {
+ $qoIncludeDocs.prop("disabled", false);
+ $qoIncludeDocsLabel.removeClass("disabled");
+ $qoGroupLevelGroup.addClass("hide");
+ }
+ },
+
+ getParams: function () {
+ var params = {};
+ this.$("input:checked,select").each(function () {
+
+ // this ensures that only settings that differ from the defaults are passed along. If we didn't do this,
+ // the query string would be loaded up with all possible vals for each search (which would work, but would be ugly)
+ if (this.value !== defaultOptions.queryParams[this.name]) {
+ params[this.name] = this.value;
+ }
+ });
+ return params;
+ },
+
+ serialize: function () {
+ return {
+ hasReduce: this.hasReduce,
+ showStale: this.showStale
+ };
+ }
+ });
+
+
+ var KeySearchFieldsView = FauxtonAPI.View.extend({
+ template: "addons/documents/templates/query_options_key_search",
+ events: {
+ "click .toggle-btns > label": "toggleKeysSection"
+ },
+
+ initialize: function (options) {
+ this.queryParams = options.queryParams;
+ this.hasReduce = options.hasReduce;
+ },
+
+ update: function (options) {
+ this.queryParams = options.queryParams;
+ this.hasReduce = options.hasReduce;
+
+ if (this.hasRendered) {
+ this.render();
+ }
+ },
+
+ // prefill the form fields
+ afterRender: function () {
+ if (this.queryParams.keys) {
+ this.$(".toggle-btns > label[data-action=showByKeys]").addClass("active");
+ this.$(".js-query-keys-wrapper").removeClass("hide");
+ this.showByKeysSection();
+ $("#keys-input").val(this.queryParams.keys);
+ } else {
+
+ // if the startKey, endKey or inclusive_end differs from the defaults, show the section. Meh, this sucks...
+ if (defaultOptions.queryParams.startkey !== this.queryParams.startkey ||
+ defaultOptions.queryParams.endkey !== this.queryParams.endkey ||
+ defaultOptions.queryParams.inclusive_end !== this.queryParams.inclusive_end) {
+ this.$(".toggle-btns > label[data-action=showBetweenKeys]").addClass("active");
+ this.$(".js-keys-section").addClass("hide");
+ this.$(".js-query-keys-wrapper").removeClass("hide");
+ this.showBetweenKeysSection();
+
+ $("#startkey").prop("disabled", false).val(this.queryParams.startkey);
+ $("#endkey").prop("disabled", false).val(this.queryParams.endkey);
+ $("#qoIncludeEndKeyInResults").prop("checked", this.queryParams.inclusive_end === "true");
+ }
+ }
+ },
+
+ toggleKeysSection: function (e) {
+ e.preventDefault();
+
+ var $clickedEl = $(e.currentTarget);
+ var $keyFieldsWrapper = this.$(".js-query-keys-wrapper");
+
+ if ($clickedEl.hasClass("active")){
+ $clickedEl.removeClass("active");
+ $keyFieldsWrapper.addClass("hide");
+ } else {
+ this.$(".toggle-btns > label").removeClass("active");
+ this.$(".js-keys-section").hide();
+
+ $clickedEl.addClass("active");
+ $keyFieldsWrapper.removeClass("hide");
+
+ // show section and disable what needs to be disabled
+ var action = $clickedEl.data("action");
+ if (action === "showByKeys") {
+ this.showByKeysSection();
+ } else {
+ this.showBetweenKeysSection();
+ }
+ }
+ },
+
+ showByKeysSection: function () {
+ this.$("#js-showKeys, .js-disabled-message").show();
+ this.$('[name="startkey"],[name="endkey"],[name="inclusive_end"]').prop("disabled", true);
+ this.$('[name="keys"]').removeAttr("disabled");
+ },
+
+ showBetweenKeysSection: function (){
+ this.$("#js-showStartEnd").show();
+ this.$('[name="startkey"],[name="endkey"],[name="inclusive_end"]').removeAttr("disabled");
+ this.$('.js-disabled-message').hide();
+ this.$('[name="keys"]').prop("disabled", true);
+ },
+
+ // this assumes that hasValidInputs has been called. Otherwise the returned param data may be invalid
+ getParams: function () {
+ var params = {};
+ var selectedKeysSection = this.getSelectedKeysSection();
+
+ // basically the gist of this is that it only actually returns *relevant* key-value pairs. Defaults
+ // aren't included because they'd clutter up the URL
+ if (selectedKeysSection === "showByKeys") {
+ var keys = $.trim($("#keys-input").val());
+ if (keys !== "") {
+ params.keys = keys;
+ }
+ } else if (selectedKeysSection === "showBetweenKeys") {
+ var startKey = $.trim($("#startkey").val());
+ if (startKey !== defaultOptions.queryParams.startkey) {
+ params.startkey = startKey;
+ }
+ var endKey = $.trim($("#endkey").val());
+ if (endKey !== defaultOptions.queryParams.endkey) {
+ params.endkey = endKey;
+ }
+ var includeEndKeyVal = $("#qoIncludeEndKeyInResults").is(":checked");
+ params.inclusive_end = (includeEndKeyVal) ? "true" : "false";
+ }
+ return params;
+ },
+
+ /*
+ * Checks to see that the user-inputted values are valid. If not, it displays a message to the user.
+ * @returns {boolean} true if all valid; false otherwise
+ */
+ hasValidInputs: function () {
+ var selectedKeysSection = this.getSelectedKeysSection(),
+ errorMsg = null;
+
+ if (selectedKeysSection === "showByKeys") {
+ var keys = this.parseJSON($("#keys-input").val());
+ if (_.isUndefined(keys) || !_.isArray(keys)) {
+ errorMsg = "Keys values must be in an array, e.g [1,2,3]";
+ }
+ } else {
+ var startKey = $.trim($("#startkey").val()),
+ endKey = $.trim($("#endkey").val());
+
+ if (startKey !== "" && _.isUndefined(this.parseJSON(startKey))) {
+ errorMsg = "JSON Parse Error on the Start Key field";
+ } else if (endKey !== "" && _.isUndefined(this.parseJSON(endKey))) {
+ errorMsg = "JSON Parse Error on the End Key field";
+ }
+ }
+
+ if (errorMsg !== null) {
+ this.$(".js-keys-error").empty();
+
+ FauxtonAPI.addNotification({
+ type: "error",
+ msg: errorMsg,
+ clear: false,
+ selector: ".query-options .errors-container"
+ });
+ return false;
+ }
+
+ return true;
+ },
+
+ parseJSON: function (value) {
+ try {
+ return JSON.parse(value);
+ } catch(e) {
+ return undefined;
+ }
+ },
+
+ getSelectedKeysSection: function () {
+ return this.$(".toggle-btns > label.active").data("action");
+ }
+ });
+
+
+ var AdditionalParamsView = FauxtonAPI.View.extend({
+ template: "addons/documents/templates/query_options_additional_params",
+
+ initialize: function (options) {
+ this.queryParams = options.queryParams;
+ this.showStale = options.showStale;
+ },
+
+ update: function (options) {
+ this.queryParams = options.queryParams;
+ this.showStale = options.showStale;
+ if (this.hasRendered) {
+ this.render();
+ }
+ },
+
+ afterRender: function () {
+ $("#qoUpdateSeq").prop("checked", this.queryParams.update_seq === "true");
+ $("#qoDescending").prop("checked", this.queryParams.descending === "true");
+ $("#qoLimit").val(this.queryParams.limit);
+ $("#qoSkip").val(this.queryParams.skip);
+ $("#qoStale").prop("checked", this.queryParams.stale === "ok");
+ },
+
+ getParams: function () {
+ var params = {};
+ this.$("input,select").each(function () {
+ if ($(this).is(":checkbox")) {
+ if (this.checked) {
+ params[this.name] = this.value;
+ }
+ } else {
+ var val = $.trim(this.value);
+ if (val !== "") {
+ params[this.name] = this.value;
+ }
+ }
+ });
+ return params;
+ },
+
+ hasValidInputs: function () {
+ var allValid = true;
+ var skipVal = $("#qoSkip").val();
+ if (skipVal !== "" && /\D/.test(skipVal)) {
+ FauxtonAPI.addNotification({
+ msg: "Please only enter numbers only for the Skip field.",
+ type: "error",
+ selector: ".query-options .errors-container",
+ clear: true
+ });
+ allValid = false;
+ }
+ return allValid;
+ },
+
+ serialize: function () {
+ return {
+ showStale: this.showStale
+ };
+ }
+ });
+
+ return Views;
+ });