couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From robertkowal...@apache.org
Subject fauxton commit: updated refs/heads/master to b7c7865
Date Tue, 01 Mar 2016 12:07:36 GMT
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 <ben.keen@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 <robertkowalski@apache.org>
Authored: Tue Feb 23 13:46:28 2016 +0000
Committer: Robert Kowalski <robertkowalski@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'
     },
 


Mime
View raw message