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 2016/03/01 13:07:36 UTC
fauxton commit: updated refs/heads/master to b7c7865
Repository: couchdb-fauxton
Updated Branches:
refs/heads/master b8c4554cf -> b7c786586
Trays: finish softmigration
Fix bug where the query panel stayed open after multiple clicks:
When opening the Options Tray in the all_docs view, clicking query
and then cancel, clicking Cancel in the Query Options panel
doesn't close it.
uses flux for state management of the tray.
closes COUCHDB-2943
PR: #654
PR-URL: https://github.com/apache/couchdb-fauxton/pull/654
Reviewed-By: Benjamin Keen <be...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/commit/b7c78658
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/tree/b7c78658
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/diff/b7c78658
Branch: refs/heads/master
Commit: b7c7865865a402bad836bc1f116184ad25b98a6a
Parents: b8c4554
Author: Robert Kowalski <ro...@apache.org>
Authored: Tue Feb 23 13:46:28 2016 +0000
Committer: Robert Kowalski <ro...@apache.org>
Committed: Tue Mar 1 12:05:07 2016 +0000
----------------------------------------------------------------------
.../components/react-components.react.jsx | 82 +--------
app/addons/documents/queryoptions/actions.js | 7 +
.../documents/queryoptions/actiontypes.js | 3 +-
.../queryoptions/queryoptions.react.jsx | 171 +++++++++++--------
app/addons/documents/queryoptions/stores.js | 13 ++
.../tests/nightwatch/queryOptionsCloseBug.js | 37 ++++
app/addons/fauxton/components.js | 2 -
app/constants.js | 2 -
8 files changed, 163 insertions(+), 154 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b7c78658/app/addons/components/react-components.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/components/react-components.react.jsx b/app/addons/components/react-components.react.jsx
index 499eb97..81b7d05 100644
--- a/app/addons/components/react-components.react.jsx
+++ b/app/addons/components/react-components.react.jsx
@@ -1205,11 +1205,6 @@ function (app, FauxtonAPI, React, ReactDOM, Actions, Stores, FauxtonComponents,
var TrayContents = React.createClass({
getChildren: function () {
- // XXX sofmigration new tray wrapper
- if (!this.props.trayVisible) {
- return null;
- }
-
var className = "tray show-tray " + this.props.className;
return (
<div key={1} id={this.props.id} className={className}>
@@ -1331,8 +1326,7 @@ function (app, FauxtonAPI, React, ReactDOM, Actions, Stores, FauxtonComponents,
}
return (
- // XXX softmigration new tray wrapper: trayVisible={true}
- <TrayContents trayVisible={true} className="tray show-tray api-bar-tray">
+ <TrayContents className="tray show-tray api-bar-tray">
<div className="input-prepend input-append">
<span className="add-on">
API URL
@@ -1418,79 +1412,6 @@ function (app, FauxtonAPI, React, ReactDOM, Actions, Stores, FauxtonComponents,
}
});
- // The tray components work as follows:
- // <Tray> Outer wrapper for all components in the tray
- // <ToggleHeaderButton /> The tray button to activate the tray, e.g the ToggleHeaderButton
- // <TrayContents> </TrayContents> What is displayed when the tray is active
- // </Tray>
- // See documents/queryoptions/queryoptions.react.jsx for a complete example
-
- var Tray = React.createClass({
-
- propTypes: {
- id: React.PropTypes.string.isRequired
- },
-
- getDefaultProps: function () {
- return {
- className: ''
- };
- },
-
- componentDidMount: function () {
- $('body').on('click.' + this.props.id, _.bind(this.closeIfOpen, this));
- FauxtonAPI.Events.on(FauxtonAPI.constants.EVENTS.TRAY_HIDE, this.closeIfOpen, this);
- },
-
- componentWillUnmount: function () {
- FauxtonAPI.Events.off(FauxtonAPI.constants.EVENTS.TRAY_HIDE);
- $('body').off('click.' + this.props.id);
- },
-
- getInitialState: function () {
- return {
- trayVisible: false
- };
- },
-
- toggleTray: function () {
- this.setState({trayVisible: !this.state.trayVisible});
- },
-
- hideTray: function () {
- this.setState({ trayVisible: false });
- },
-
- renderChildren: function () {
- return React.Children.map(this.props.children, function (child, key) {
- return React.cloneElement(child, {
- trayVisible: this.state.trayVisible,
- selected: this.state.trayVisible,
- toggleCallback: this.toggleTray,
- key: key
- });
- }.bind(this));
- },
-
- render: function () {
- return (
- <div className={this.props.className}>
- {this.renderChildren()}
- </div>
- );
- },
-
- closeIfOpen: function (e) {
- if (!this.state.trayVisible) { return; }
- var trayEl = $(ReactDOM.findDOMNode(this));
-
- if (!trayEl.is(e.target) && trayEl.has(e.target).length === 0) {
- this.toggleTray();
- }
- }
-
- });
-
var DeleteDatabaseModal = React.createClass({
getInitialState: function () {
@@ -1602,7 +1523,6 @@ function (app, FauxtonAPI, React, ReactDOM, Actions, Stores, FauxtonComponents,
Document: Document,
LoadLines: LoadLines,
MenuDropDown: MenuDropDown,
- Tray: Tray,
TrayContents: TrayContents,
TrayWrapper: TrayWrapper,
connectToStores: connectToStores,
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b7c78658/app/addons/documents/queryoptions/actions.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/queryoptions/actions.js b/app/addons/documents/queryoptions/actions.js
index 642e46a..3bdc7de 100644
--- a/app/addons/documents/queryoptions/actions.js
+++ b/app/addons/documents/queryoptions/actions.js
@@ -83,6 +83,13 @@ function (app, FauxtonAPI, ActionTypes, Stores) {
FauxtonAPI.navigate(url);
},
+ toggleQueryBarVisibility: function (options) {
+ FauxtonAPI.dispatch({
+ type: ActionTypes.QUERY_UPDATE_VISIBILITY,
+ options: options
+ });
+ },
+
updateGroupLevel: function (groupLevel) {
FauxtonAPI.dispatch({
type: ActionTypes.QUERY_UPDATE_GROUP_LEVEL,
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b7c78658/app/addons/documents/queryoptions/actiontypes.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/queryoptions/actiontypes.js b/app/addons/documents/queryoptions/actiontypes.js
index aaf4131..b91e92a 100644
--- a/app/addons/documents/queryoptions/actiontypes.js
+++ b/app/addons/documents/queryoptions/actiontypes.js
@@ -23,6 +23,7 @@ define([], function () {
QUERY_UPDATE_LIMIT: 'QUERY_UPDATE_LIMIT',
QUERY_RESET: 'QUERY_RESET',
QUERY_SHOW_REDUCE: 'QUERY_SHOW_REDUCE',
- QUERY_UPDATE_GROUP_LEVEL: 'QUERY_UPDATE_GROUP_LEVEL'
+ QUERY_UPDATE_GROUP_LEVEL: 'QUERY_UPDATE_GROUP_LEVEL',
+ QUERY_UPDATE_VISIBILITY: 'QUERY_UPDATE_VISIBILITY'
};
});
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b7c78658/app/addons/documents/queryoptions/queryoptions.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/documents/queryoptions/queryoptions.react.jsx b/app/addons/documents/queryoptions/queryoptions.react.jsx
index d679407..74e8dd2 100644
--- a/app/addons/documents/queryoptions/queryoptions.react.jsx
+++ b/app/addons/documents/queryoptions/queryoptions.react.jsx
@@ -22,10 +22,12 @@ define([
function (app, FauxtonAPI, React, ReactDOM, Stores, Actions, Components) {
var store = Stores.queryOptionsStore;
- var Tray = Components.Tray;
var TrayContents = Components.TrayContents;
var ToggleHeaderButton = Components.ToggleHeaderButton;
+ var TrayWrapper = Components.TrayWrapper;
+ var connectToStores = Components.connectToStores;
+
var MainFieldsView = React.createClass({
propTypes: {
toggleIncludeDocs: React.PropTypes.func.isRequired,
@@ -43,7 +45,7 @@ function (app, FauxtonAPI, React, ReactDOM, Stores, Actions, Components) {
},
toggleIncludeDocs: function (e) {
- this.props.toggleIncludeDocs();
+ this.props.toggleIncludeDocs(e);
},
groupLevelChange: function (e) {
@@ -273,7 +275,7 @@ A key value is the first parameter emitted in a map function. For example emit("
var QueryButtons = React.createClass({
hideTray: function (e) {
- FauxtonAPI.Events.trigger(FauxtonAPI.constants.EVENTS.TRAY_HIDE, {});
+ Actions.toggleQueryBarVisibility(false);
},
render: function () {
@@ -292,93 +294,126 @@ A key value is the first parameter emitted in a map function. For example emit("
});
var QueryOptionsController = React.createClass({
- getStoreState: function () {
- return {
- includeDocs: store.includeDocs(),
- showBetweenKeys: store.showBetweenKeys(),
- showByKeys: store.showByKeys(),
- betweenKeys: store.betweenKeys(),
- byKeys: store.byKeys(),
- descending: store.descending(),
- skip: store.skip(),
- limit: store.limit(),
- showReduce: store.showReduce(),
- reduce: store.reduce(),
- groupLevel: store.groupLevel()
- };
+
+ getWrap: function () {
+ return connectToStores(TrayWrapper, [store], function () {
+
+ return {
+ includeDocs: store.includeDocs(),
+ showBetweenKeys: store.showBetweenKeys(),
+ showByKeys: store.showByKeys(),
+ betweenKeys: store.betweenKeys(),
+ byKeys: store.byKeys(),
+ descending: store.descending(),
+ skip: store.skip(),
+ limit: store.limit(),
+ showReduce: store.showReduce(),
+ reduce: store.reduce(),
+ groupLevel: store.groupLevel(),
+ contentVisible: store.getTrayVisible(),
+ queryParams: store.getQueryParams()
+ };
+ });
},
- getInitialState: function () {
- return this.getStoreState();
+ render: function () {
+ var TrayWrapper = this.getWrap();
+ return (
+ <TrayWrapper>
+ <QueryTray contentVisible={false} />
+ </TrayWrapper>
+ );
+ }
+ });
+
+ var QueryTray = React.createClass({
+
+ propTypes: {
+ contentVisible: React.PropTypes.bool.isRequired
+ },
+
+ runQuery: function (e) {
+ e.preventDefault();
+
+ Actions.runQuery(this.props.queryParams);
+ this.toggleTrayVisibility();
+ },
+
+ toggleTrayVisibility: function () {
+ Actions.toggleQueryBarVisibility(!this.props.contentVisible);
},
componentDidMount: function () {
- store.on('change', this.onChange, this);
+ $('body').on('click.QueryTray', function (e) {
+ if ($(e.target).closest('#query-options').length) {
+ return;
+ }
+ Actions.toggleQueryBarVisibility(false);
+ }.bind(this));
},
componentWillUnmount: function () {
- store.off('change', this.onChange);
+ $('body').off('click.QueryTray');
},
- onChange: function () {
- this.setState(this.getStoreState());
+ toggleIncludeDocs: function (e) {
+ Actions.toggleIncludeDocs();
},
- runQuery: function (e) {
- e.preventDefault();
+ getTray: function () {
+ if (!this.props.contentVisible) {
+ return null;
+ }
+
+ return (
+ <TrayContents
+ className="query-options"
+ id="query-options-tray">
+
+ <form onSubmit={this.runQuery} className="js-view-query-update custom-inputs">
+ <MainFieldsView
+ includeDocs={this.props.includeDocs}
+ toggleIncludeDocs={this.toggleIncludeDocs}
+ showReduce={this.props.showReduce}
+ reduce={this.props.reduce}
+ toggleReduce={Actions.toggleReduce}
+ groupLevel={this.props.groupLevel}
+ updateGroupLevel={Actions.updateGroupLevel} />
+ <KeySearchFields
+ key={1}
+ showByKeys={this.props.showByKeys}
+ showBetweenKeys={this.props.showBetweenKeys}
+ toggleByKeys={Actions.toggleByKeys}
+ toggleBetweenKeys={Actions.toggleBetweenKeys}
+ betweenKeys={this.props.betweenKeys}
+ updateBetweenKeys={Actions.updateBetweenKeys}
+ byKeys={this.props.byKeys}
+ updateByKeys={Actions.updateByKeys} />
+ <AdditionalParams
+ descending={this.props.descending}
+ toggleDescending={Actions.toggleDescending}
+ skip={this.props.skip}
+ updateSkip={Actions.updateSkip}
+ updateLimit={Actions.updateLimit}
+ limit={this.props.limit} />
+ <QueryButtons />
+ </form>
+ </TrayContents>
+ );
- this.refs.tray.hideTray();
- Actions.runQuery(store.getQueryParams());
},
render: function () {
return (
- <Tray id="query-options-tray" ref="tray">
-
+ <div>
<ToggleHeaderButton
+ toggleCallback={this.toggleTrayVisibility}
containerClasses="header-control-box control-toggle-queryoptions"
title="Query Options"
fonticon="fonticon-gears"
text="Options" />
-
- <TrayContents
- className="query-options"
- id="query-options-tray">
-
- <form onSubmit={this.runQuery} className="js-view-query-update custom-inputs">
- <MainFieldsView
- includeDocs={this.state.includeDocs}
- toggleIncludeDocs={Actions.toggleIncludeDocs}
- showReduce={this.state.showReduce}
- reduce={this.state.reduce}
- toggleReduce={Actions.toggleReduce}
- groupLevel={this.state.groupLevel}
- updateGroupLevel={Actions.updateGroupLevel}
- />
- <KeySearchFields
- key={1}
- showByKeys={this.state.showByKeys}
- showBetweenKeys={this.state.showBetweenKeys}
- toggleByKeys={Actions.toggleByKeys}
- toggleBetweenKeys={Actions.toggleBetweenKeys}
- betweenKeys={this.state.betweenKeys}
- updateBetweenKeys={Actions.updateBetweenKeys}
- byKeys={this.state.byKeys}
- updateByKeys={Actions.updateByKeys}
- />
- <AdditionalParams
- descending={this.state.descending}
- toggleDescending={Actions.toggleDescending}
- skip={this.state.skip}
- updateSkip={Actions.updateSkip}
- updateLimit={Actions.updateLimit}
- limit={this.state.limit}
- />
- <QueryButtons />
- </form>
-
- </TrayContents>
- </Tray>
+ {this.getTray()}
+ </div>
);
}
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b7c78658/app/addons/documents/queryoptions/stores.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/queryoptions/stores.js b/app/addons/documents/queryoptions/stores.js
index 14299c2..a123c2e 100644
--- a/app/addons/documents/queryoptions/stores.js
+++ b/app/addons/documents/queryoptions/stores.js
@@ -34,6 +34,8 @@ function (app, FauxtonAPI, ActionTypes) {
include: true,
};
+ this._trayVisible = false;
+
this._byKeys = '';
this._descending = false;
this._skip = '';
@@ -48,6 +50,14 @@ function (app, FauxtonAPI, ActionTypes) {
return this._loading;
},
+ setTrayVisible: function (trayVisible) {
+ this._trayVisible = trayVisible;
+ },
+
+ getTrayVisible: function () {
+ return this._trayVisible;
+ },
+
showReduce: function () {
return this._showReduce;
},
@@ -263,6 +273,9 @@ function (app, FauxtonAPI, ActionTypes) {
case ActionTypes.QUERY_UPDATE_GROUP_LEVEL:
this.updateGroupLevel(action.groupLevel);
break;
+ case ActionTypes.QUERY_UPDATE_VISIBILITY:
+ this.setTrayVisible(action.options);
+ break;
default:
return;
// do nothing
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b7c78658/app/addons/documents/tests/nightwatch/queryOptionsCloseBug.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/nightwatch/queryOptionsCloseBug.js b/app/addons/documents/tests/nightwatch/queryOptionsCloseBug.js
new file mode 100644
index 0000000..561e1ea
--- /dev/null
+++ b/app/addons/documents/tests/nightwatch/queryOptionsCloseBug.js
@@ -0,0 +1,37 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+module.exports = {
+
+ 'Query Options: close if opened / closed multiple times': function (client) {
+ /*jshint multistr: true */
+ var waitTime = client.globals.maxWaitTime,
+ newDatabaseName = client.globals.testDatabaseName,
+ baseUrl = client.globals.test_settings.launch_url;
+
+ client
+ .populateDatabase(newDatabaseName, 3)
+ .loginToGUI()
+ .url(baseUrl + '/#/database/' + newDatabaseName + '/_all_docs')
+ .clickWhenVisible('.control-toggle-queryoptions')
+ .clickWhenVisible('#betweenKeys', waitTime, false)
+ .setValue('#startkey', '"document_2"')
+ .clickWhenVisible('#query-options .btn-success')
+ .waitForElementNotPresent('#doc-list [data-id="document_1"]', waitTime, false)
+ .clickWhenVisible('.control-toggle-queryoptions')
+ .clickWhenVisible('#query-options .btn-cancel')
+
+ .waitForElementNotPresent('#query-options .js-view-query-update', waitTime, false)
+
+ .end();
+ }
+};
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b7c78658/app/addons/fauxton/components.js
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/components.js b/app/addons/fauxton/components.js
index b2f03fb..4046794 100644
--- a/app/addons/fauxton/components.js
+++ b/app/addons/fauxton/components.js
@@ -265,8 +265,6 @@ function (app, FauxtonAPI, ace, spin, ReactComponents, Helpers) {
if (!_.isNull(this.toggleTrayBtnSelector)) {
this.$(this.toggleTrayBtnSelector).removeClass('enabled');
}
- // announce that the tray is being closed
- FauxtonAPI.Events.trigger(FauxtonAPI.constants.EVENTS.TRAY_CLOSED, { trayId: this.trayId });
},
showTray: function () {
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/b7c78658/app/constants.js
----------------------------------------------------------------------
diff --git a/app/constants.js b/app/constants.js
index f9a8123..a90b21d 100644
--- a/app/constants.js
+++ b/app/constants.js
@@ -26,9 +26,7 @@ define([], function () {
// global events for common used components
EVENTS: {
- TRAY_CLOSED: 'tray:closed',
TRAY_OPENED: 'tray:opened',
- TRAY_HIDE: 'tray:hide',
NAVBAR_SIZE_CHANGED: 'navbar:size_changed'
},