You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@couchdb.apache.org by sebastianrothbucher <gi...@git.apache.org> on 2015/04/09 16:38:42 UTC

[GitHub] couchdb-fauxton pull request: [WIP] Databases view in react

GitHub user sebastianrothbucher opened a pull request:

    https://github.com/apache/couchdb-fauxton/pull/370

    [WIP] Databases view in react

    just wanted to let you guys know I started working on it - and it's far from complete. So do not merge just yet... (I stole a lot from michellephung's active tasks btw - thanks!)
    Pagination is still missing, so is search for a DB and all tests (including the one for the tray that we can share). 
    When I'm too slow pls. feel free move ahead (pls. let me know ;-) )

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/sebastianrothbucher/couchdb-fauxton databases-react-new

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/couchdb-fauxton/pull/370.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #370
    
----
commit 14577703af6b866dbe288d73a6116091180bf4f8
Author: sebastianrothbucher <se...@googlemail.com>
Date:   2015-04-09T14:35:39Z

    databases in react

----


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28456234
  
    --- Diff: app/addons/fauxton/components.react.jsx ---
    @@ -84,9 +84,131 @@ function (app, FauxtonAPI, React, ZeroClipboard) {
       });
     
     
    +  var Tray = React.createClass({
    +
    +    getInitialState : function () {
    +      return {
    +        show: false
    +      };
    +    },
    +
    +    toggle : function (done) {
    +      if (this.state.show) {
    +        this.hide(done);
    +      } else {
    +        this.show(done);
    +      }
    +    },
    +
    +    componentDidMount : function () {
    +      var that = this;
    +      $('body').on('click.Tray-' + this.props.trayid + "-" + this._rootNodeID, function (e) {
    +        var tgt = $(e.target);
    +        if (that.state.show && tgt.closest('.tray').length === 0) {
    +          that.hide();
    +        }
    +      });
    +    },
    +
    +    componentWillUnmount : function () {
    +      $('body').off('click.Tray-' + this.props.trayid + "-" + this._rootNodeID);
    +    },
    +
    +    show : function (done) {
    +      this.setState({show: true});
    +      $(this.refs.myself.getDOMNode()).velocity('transition.slideDownIn', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        if (done) {
    +          done(true);
    +        }
    +      });
    +    },
    +
    +    hide : function (done) {
    +      var that = this;
    +      $(this.refs.myself.getDOMNode()).velocity('reverse', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        that.setState({show: false});
    +        if (done) {
    +          done(false);
    +        }
    +      });
    +    },
    +
    +    render : function () {
    +      var styleSpec = this.state.show ? {"display": "block", "opacity": 1} :  {"display": "none", "opacity": 0};
    +      var classSpec = this.props.className || "";
    +      classSpec += " tray";
    +      return (
    +        <div ref="myself" style={styleSpec} className={classSpec}>{this.props.children}</div>
    +      );
    +    }
    +  });
    +
    +  var Pagination = React.createClass({
    +
    +    getInitialState: function () {
    +      return {};
    +    },
    --- End diff --
    
    actually: no - you'll break the logic, removing these three lines will crash the UI (or you just drop the possibility to set some things via state also and not just via props)


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28225022
  
    --- Diff: app/addons/databases/components.react.jsx ---
    @@ -0,0 +1,271 @@
    +// 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',
    +  'react',
    +  'addons/fauxton/components.react',
    +  'addons/databases/stores',
    +  'addons/databases/resources',
    +  'addons/databases/actions',
    +  'helpers'
    +], function (app, FauxtonAPI, React, ComponentsReact, Stores, Resources, Actions, Helpers) {
    +
    +  var databasesStore = Stores.databasesStore;
    +
    +  var DatabasesController = React.createClass({
    +
    +    getStoreState: function () {
    +      return {
    +        collection: databasesStore.getCollection()
    +      };
    +    },
    +
    +    getInitialState: function () {
    +      return this.getStoreState();
    +    },
    +
    +    render: function () {
    +      return (
    +        <DatabaseTable body={this.state.collection} />
    +      );
    +    }
    +  });
    +
    +  var DatabaseTable = React.createClass({
    +
    +    createRows: function () {
    +      return _.map(this.props.body, function (item, iteration) {
    +        return (
    +          <DatabaseRow row={item} />
    +        );
    +      });
    +    },
    +
    +    render: function () {
    +      var rows = this.createRows();
    +      return (
    +        <div className="view">
    +          <table className="databases table table-striped">
    +            <thead>
    +              <th>Name</th>
    +              <th>Size</th>
    +              <th># of Docs</th>
    +              <th>Update Seq</th>
    +              <th>Actions</th>
    +            </thead>
    +            <tbody>
    +            {rows}
    +            </tbody>
    +          </table>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var DatabaseRow = React.createClass({
    +
    +    renderGraveyard : function (row) {
    +      if (row.status.isGraveYard()) {
    +        return (
    +          <GraveyardInfo row={row} />
    +        );
    +      } else {
    +        return null;
    +      }
    +    },
    +
    +    render: function () {
    +      var row = this.props.row;
    +      var name = row.get("name");
    +      var encoded = app.utils.safeURLName(name);
    +      var size = Helpers.formatSize(row.status.dataSize());
    +      return (
    +        <tr>
    +          <td>
    +            <a href={"#/database/"+encoded+"/_all_docs"}>{name}</a>
    +          </td>
    +          <td>{size}</td>
    +          <td>{row.status.numDocs()} {this.renderGraveyard(row)}</td>
    +          <td>{row.status.updateSeq()}</td>
    +          <td>
    +            <a className="db-actions btn fonticon-replicate set-replication-start" title={"Replicate "+name} href={"#/replication/"+encoded}></a>&#160;
    +            <a className="db-actions btn icon-lock set-permissions" title={"Set permissions for "+name} href={"#/database/"+encoded+"/permissions"}></a>
    +          </td>
    +        </tr>
    +      );
    +    }
    +  });
    +
    +  var GraveyardInfo = React.createClass({
    +
    +    componentDidMount : function () {
    +      $(this.refs.myself.getDOMNode()).tooltip();
    +    },
    +
    +    render : function () {
    +      var row = this.props.row;
    +      return (
    +        <i className="js-db-graveyard icon icon-exclamation-sign" ref="myself" title={"This database has just " + row.status.numDocs() + " docs and " + row.status.numDeletedDocs() + " deleted docs"}></i>
    +      );
    +    }
    +  });
    +
    +  var RightDatabasesHeader = React.createClass({
    +
    +    render : function () {
    +      return (
    +        <div className="header-right">
    +          <AddDatabaseWidget />
    +          <JumpToDatabaseWidget />
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var AddDatabaseWidget = React.createClass({
    +
    +    onTrayToggle : function () {
    +      var that = this;
    +      this.refs.newDbTray.toggle(function (shown) {
    +        if (shown) {
    +          that.refs.newDbName.getDOMNode().focus();
    +        }
    +      });
    +    },
    +
    +    onKeyUpInInput : function (e) {
    +      if (e.which === 13) {
    +        this.onAddDatabase();
    +      }
    +    },
    +
    +    onAddDatabase : function () {
    +      var databaseName = $(this.refs.newDbName.getDOMNode()).val();
    +      Actions.createNewDatabase(databaseName, this.refs.newDbTray.hide, FauxtonAPI.addNotification);
    +    },
    +
    +    render : function () {
    +
    +      return (
    +        <div className="button" id="add-db-button">
    +          <a id="add-new-database" className="add-new-database-btn" href="#" onClick={this.onTrayToggle}><i className="header-icon fonticon-new-database"></i> Add New Database</a>
    +          <ComponentsReact.Tray trayid="new-database-tray" ref="newDbTray" className="new-database-tray">
    +            <span className="add-on">Add New Database</span>
    +            <input id="js-new-database-name" type="text" onKeyUp={this.onKeyUpInInput} ref="newDbName" className="input-xxlarge" placeholder="Name of database" />
    +            <a className="btn" id="js-create-database" onClick={this.onAddDatabase}>Create</a>
    +          </ComponentsReact.Tray>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var JumpToDatabaseWidget = React.createClass({
    +
    +    componentDidMount : function () {
    +      var that = this;
    +      $(this.refs.searchDbName.getDOMNode()).typeahead({
    +        source : databasesStore.getDatabaseNames(),
    +        updater: function (item) {
    +          that.jumpToDb(item);
    +        }
    +      });
    --- End diff --
    
    that = this vs bind


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: [WIP] Databases view in react

Posted by michellephung <gi...@git.apache.org>.
Github user michellephung commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-91349868
  
    nice! 
    this is looking pretty good so far, keep going!



---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28455897
  
    --- Diff: app/addons/databases/components.react.jsx ---
    @@ -0,0 +1,271 @@
    +// 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',
    +  'react',
    +  'addons/fauxton/components.react',
    +  'addons/databases/stores',
    +  'addons/databases/resources',
    +  'addons/databases/actions',
    +  'helpers'
    +], function (app, FauxtonAPI, React, ComponentsReact, Stores, Resources, Actions, Helpers) {
    +
    +  var databasesStore = Stores.databasesStore;
    +
    +  var DatabasesController = React.createClass({
    +
    +    getStoreState: function () {
    +      return {
    +        collection: databasesStore.getCollection()
    +      };
    +    },
    +
    +    getInitialState: function () {
    +      return this.getStoreState();
    +    },
    +
    +    render: function () {
    +      return (
    +        <DatabaseTable body={this.state.collection} />
    +      );
    +    }
    +  });
    +
    +  var DatabaseTable = React.createClass({
    +
    +    createRows: function () {
    +      return _.map(this.props.body, function (item, iteration) {
    +        return (
    +          <DatabaseRow row={item} />
    +        );
    +      });
    +    },
    +
    +    render: function () {
    +      var rows = this.createRows();
    +      return (
    +        <div className="view">
    +          <table className="databases table table-striped">
    +            <thead>
    +              <th>Name</th>
    +              <th>Size</th>
    +              <th># of Docs</th>
    +              <th>Update Seq</th>
    +              <th>Actions</th>
    +            </thead>
    +            <tbody>
    +            {rows}
    +            </tbody>
    +          </table>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var DatabaseRow = React.createClass({
    +
    +    renderGraveyard : function (row) {
    +      if (row.status.isGraveYard()) {
    +        return (
    +          <GraveyardInfo row={row} />
    +        );
    +      } else {
    +        return null;
    +      }
    +    },
    +
    +    render: function () {
    +      var row = this.props.row;
    +      var name = row.get("name");
    +      var encoded = app.utils.safeURLName(name);
    +      var size = Helpers.formatSize(row.status.dataSize());
    +      return (
    +        <tr>
    +          <td>
    +            <a href={"#/database/"+encoded+"/_all_docs"}>{name}</a>
    +          </td>
    +          <td>{size}</td>
    +          <td>{row.status.numDocs()} {this.renderGraveyard(row)}</td>
    +          <td>{row.status.updateSeq()}</td>
    +          <td>
    +            <a className="db-actions btn fonticon-replicate set-replication-start" title={"Replicate "+name} href={"#/replication/"+encoded}></a>&#160;
    +            <a className="db-actions btn icon-lock set-permissions" title={"Set permissions for "+name} href={"#/database/"+encoded+"/permissions"}></a>
    +          </td>
    +        </tr>
    +      );
    +    }
    +  });
    +
    +  var GraveyardInfo = React.createClass({
    +
    +    componentDidMount : function () {
    +      $(this.refs.myself.getDOMNode()).tooltip();
    +    },
    +
    +    render : function () {
    +      var row = this.props.row;
    +      return (
    +        <i className="js-db-graveyard icon icon-exclamation-sign" ref="myself" title={"This database has just " + row.status.numDocs() + " docs and " + row.status.numDeletedDocs() + " deleted docs"}></i>
    +      );
    +    }
    +  });
    +
    +  var RightDatabasesHeader = React.createClass({
    +
    +    render : function () {
    +      return (
    +        <div className="header-right">
    +          <AddDatabaseWidget />
    +          <JumpToDatabaseWidget />
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var AddDatabaseWidget = React.createClass({
    +
    +    onTrayToggle : function () {
    +      var that = this;
    +      this.refs.newDbTray.toggle(function (shown) {
    +        if (shown) {
    +          that.refs.newDbName.getDOMNode().focus();
    +        }
    +      });
    +    },
    +
    +    onKeyUpInInput : function (e) {
    +      if (e.which === 13) {
    +        this.onAddDatabase();
    +      }
    +    },
    +
    +    onAddDatabase : function () {
    +      var databaseName = $(this.refs.newDbName.getDOMNode()).val();
    +      Actions.createNewDatabase(databaseName, this.refs.newDbTray.hide, FauxtonAPI.addNotification);
    --- End diff --
    
    I'm with you with FauxtonAPI.addNotification
    However, I'd keep the hide callback: using another action dispatch just to hide the tray is a lot of overhead - and it gets more brittle: 1.) right now you have one tray, but for how long? 2.) When passing in, you already KNOW which react node you're dealing with, you don't have to remember for an event coming in and 3.) you might not want to change behavior - which right now is: hide the tray in the middle of things (when all trivial checks were performed and going back is possible).
    So, I'd leave the callback here (plus: testing is also quite simple)


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28225460
  
    --- Diff: app/addons/fauxton/components.react.jsx ---
    @@ -84,9 +84,131 @@ function (app, FauxtonAPI, React, ZeroClipboard) {
       });
     
     
    +  var Tray = React.createClass({
    +
    +    getInitialState : function () {
    +      return {
    +        show: false
    +      };
    +    },
    +
    +    toggle : function (done) {
    +      if (this.state.show) {
    +        this.hide(done);
    +      } else {
    +        this.show(done);
    +      }
    +    },
    +
    +    componentDidMount : function () {
    +      var that = this;
    +      $('body').on('click.Tray-' + this.props.trayid + "-" + this._rootNodeID, function (e) {
    +        var tgt = $(e.target);
    +        if (that.state.show && tgt.closest('.tray').length === 0) {
    +          that.hide();
    +        }
    +      });
    +    },
    +
    +    componentWillUnmount : function () {
    +      $('body').off('click.Tray-' + this.props.trayid + "-" + this._rootNodeID);
    +    },
    +
    +    show : function (done) {
    +      this.setState({show: true});
    +      $(this.refs.myself.getDOMNode()).velocity('transition.slideDownIn', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        if (done) {
    +          done(true);
    +        }
    +      });
    +    },
    +
    +    hide : function (done) {
    +      var that = this;
    +      $(this.refs.myself.getDOMNode()).velocity('reverse', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        that.setState({show: false});
    +        if (done) {
    +          done(false);
    +        }
    +      });
    +    },
    +
    +    render : function () {
    +      var styleSpec = this.state.show ? {"display": "block", "opacity": 1} :  {"display": "none", "opacity": 0};
    +      var classSpec = this.props.className || "";
    +      classSpec += " tray";
    +      return (
    +        <div ref="myself" style={styleSpec} className={classSpec}>{this.props.children}</div>
    +      );
    +    }
    +  });
    +
    +  var Pagination = React.createClass({
    +
    +    getInitialState: function () {
    +      return {};
    +    },
    +
    +    getDefaultProps : function () {
    +      return {
    +        perPage: FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE,
    +        page: 1,
    +        total: 0
    +      };
    +    },
    +
    +    render : function () {
    +      function getVisiblePages (page, totalPages) {
    +        var from, to;
    +        if (totalPages < 10) {
    +          from = 1;
    +          to = totalPages + 1;
    +        } else {
    +          from = page - 5;
    +          to = page + 5;
    +          if (from <= 1) {
    +            from = 1;
    +            to = 11;
    +          }
    +          if (to > totalPages + 1) {
    +            from =  totalPages - 9;
    +            to = totalPages + 1;
    +          }
    +        }
    +        return {
    +          from: from,
    +          to: to
    +        };
    +      }
    +      var page = this.state.page || this.props.page;
    +      var total = this.state.total || this.props.total;
    +      var perPage = this.props.perPage;
    +      var prefix = this.props.urlPrefix || "";
    +      var suffix = this.props.urlSuffix || "";
    +      var totalPages = total === 0 ? 1 : Math.ceil(total / perPage);
    +      var visiblePages = getVisiblePages(page, totalPages);
    +      var rangeItems = [];
    +      for (var i = visiblePages.from; i < visiblePages.to; i++) {
    +        rangeItems.push(
    +          <li className={(page === i ? "active" : null)}><a href={prefix + i + suffix}>{i}</a></li>
    +        );
    +      }
    +      return (
    +        <ul className="pagination">
    +          <li className={(page === 1 ? "disabled" : null)}><a href={prefix + Math.max(page - 1, 1) + suffix}>&laquo;</a></li>
    +          {rangeItems}
    +          <li className={(page < totalPages ? null : "disabled")}><a href={prefix + Math.min(page + 1, totalPages) + suffix}>&raquo;</a></li>
    +        </ul>
    +      );
    +    }
    +  });
    +
    +
    --- End diff --
    
    not sure while this file uses 
    ```
    {
      property : 'attribute'
    }
    ```
    
    while we/you use 
    
    ```
    {
      prop: 'foo'
    }
    ```
    elsewhere


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28765101
  
    --- Diff: app/addons/fauxton/components.react.jsx ---
    @@ -83,10 +83,132 @@ function (app, FauxtonAPI, React, ZeroClipboard) {
         }
       });
     
    +  var _NextTrayInternalId = 0;
    +  var Tray = React.createClass({
    +
    +    getInitialState: function () {
    +      return {
    +        show: false,
    +        internalid: (_NextTrayInternalId++)
    +      };
    +    },
    +
    +    toggle: function (done) {
    +      if (this.state.show) {
    +        this.hide(done);
    +      } else {
    +        this.show(done);
    +      }
    +    },
    +
    +    componentDidMount: function () {
    +      $('body').on('click.Tray-' + this.state.internalid, function (e) {
    +        var tgt = $(e.target);
    +        if (this.state.show && tgt.closest('.tray').length === 0) {
    +          this.hide();
    +        }
    +      }.bind(this));
    +    },
    +
    +    componentWillUnmount: function () {
    +      $('body').off('click.Tray-' + this.state.internalid);
    +    },
    +
    +    show: function (done) {
    +      this.setState({show: true});
    +      $(this.refs.myself.getDOMNode()).velocity('transition.slideDownIn', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        if (done) {
    +          done(true);
    +        }
    +      });
    +    },
    +
    +    hide: function (done) {
    +      $(this.refs.myself.getDOMNode()).velocity('reverse', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        this.setState({show: false});
    +        if (done) {
    +          done(false);
    +        }
    +      }.bind(this));
    +    },
    +
    +    render: function () {
    +      var styleSpec = this.state.show ? {"display": "block", "opacity": 1} :  {"display": "none", "opacity": 0};
    +      var classSpec = this.props.className || "";
    +      classSpec += " tray";
    +      return (
    +        <div ref="myself" style={styleSpec} className={classSpec}>{this.props.children}</div>
    +      );
    +    }
    +  });
    +
    +  var Pagination = React.createClass({
    +
    +    getInitialState: function () {
    +      return {};
    +    },
    +
    +    getDefaultProps: function () {
    +      return {
    +        perPage: FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE,
    +        page: 1,
    +        total: 0
    +      };
    +    },
    +
    +    getVisiblePages: function (page, totalPages) {
    +      var from, to;
    +      if (totalPages < 10) {
    +        from = 1;
    +        to = totalPages + 1;
    +      } else {
    +        from = page - 5;
    +        to = page + 5;
    +        if (from <= 1) {
    +          from = 1;
    +          to = 11;
    +        }
    +        if (to > totalPages + 1) {
    +          from =  totalPages - 9;
    +          to = totalPages + 1;
    +        }
    +      }
    +      return {
    +        from: from,
    +        to: to
    +      };
    +    },
    +
    +    render: function () {
    +      var page = this.state.page || this.props.page;
    +      var total = this.state.total || this.props.total;
    +      var perPage = this.props.perPage;
    +      var prefix = this.props.urlPrefix || "";
    +      var suffix = this.props.urlSuffix || "";
    +      var totalPages = total === 0 ? 1 : Math.ceil(total / perPage);
    +      var visiblePages = this.getVisiblePages(page, totalPages);
    +      var rangeItems = [];
    +      for (var i = visiblePages.from; i < visiblePages.to; i++) {
    --- End diff --
    
    Could you change this for loop to use (_.range)[http://underscorejs.org/#range]. Something like:
    ```javascript
    return _.range(visiblePages.from, visiblePages.to).map(function (i) {
       return <li className={(page === i ? "active" : null)}><a href={prefix + i + suffix}>{i}</a></li> 
    });
    ```
    
    I also think this would be better in a function something like `createDBItemsForPage()`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28456298
  
    --- Diff: app/addons/fauxton/components.react.jsx ---
    @@ -84,9 +84,131 @@ function (app, FauxtonAPI, React, ZeroClipboard) {
       });
     
     
    +  var Tray = React.createClass({
    +
    +    getInitialState : function () {
    +      return {
    +        show: false
    +      };
    +    },
    +
    +    toggle : function (done) {
    +      if (this.state.show) {
    +        this.hide(done);
    +      } else {
    +        this.show(done);
    +      }
    +    },
    +
    +    componentDidMount : function () {
    +      var that = this;
    +      $('body').on('click.Tray-' + this.props.trayid + "-" + this._rootNodeID, function (e) {
    --- End diff --
    
    For Databases I'm with you, but when you want to make the tray reusable, I think it's not the worst idea to make it very sure we're distinct...


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-99989886
  
    Great work @sebastianrothbucher :D Great to see this merged.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by asfgit <gi...@git.apache.org>.
Github user asfgit closed the pull request at:

    https://github.com/apache/couchdb-fauxton/pull/370


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28225179
  
    --- Diff: app/addons/databases/components.react.jsx ---
    @@ -0,0 +1,271 @@
    +// 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',
    +  'react',
    +  'addons/fauxton/components.react',
    +  'addons/databases/stores',
    +  'addons/databases/resources',
    +  'addons/databases/actions',
    +  'helpers'
    +], function (app, FauxtonAPI, React, ComponentsReact, Stores, Resources, Actions, Helpers) {
    +
    +  var databasesStore = Stores.databasesStore;
    +
    +  var DatabasesController = React.createClass({
    +
    +    getStoreState: function () {
    +      return {
    +        collection: databasesStore.getCollection()
    +      };
    +    },
    +
    +    getInitialState: function () {
    +      return this.getStoreState();
    +    },
    +
    +    render: function () {
    +      return (
    +        <DatabaseTable body={this.state.collection} />
    +      );
    +    }
    +  });
    +
    +  var DatabaseTable = React.createClass({
    +
    +    createRows: function () {
    +      return _.map(this.props.body, function (item, iteration) {
    +        return (
    +          <DatabaseRow row={item} />
    +        );
    +      });
    +    },
    +
    +    render: function () {
    +      var rows = this.createRows();
    +      return (
    +        <div className="view">
    +          <table className="databases table table-striped">
    +            <thead>
    +              <th>Name</th>
    +              <th>Size</th>
    +              <th># of Docs</th>
    +              <th>Update Seq</th>
    +              <th>Actions</th>
    +            </thead>
    +            <tbody>
    +            {rows}
    +            </tbody>
    +          </table>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var DatabaseRow = React.createClass({
    +
    +    renderGraveyard : function (row) {
    +      if (row.status.isGraveYard()) {
    +        return (
    +          <GraveyardInfo row={row} />
    +        );
    +      } else {
    +        return null;
    +      }
    +    },
    +
    +    render: function () {
    +      var row = this.props.row;
    +      var name = row.get("name");
    +      var encoded = app.utils.safeURLName(name);
    +      var size = Helpers.formatSize(row.status.dataSize());
    +      return (
    +        <tr>
    +          <td>
    +            <a href={"#/database/"+encoded+"/_all_docs"}>{name}</a>
    +          </td>
    +          <td>{size}</td>
    +          <td>{row.status.numDocs()} {this.renderGraveyard(row)}</td>
    +          <td>{row.status.updateSeq()}</td>
    +          <td>
    +            <a className="db-actions btn fonticon-replicate set-replication-start" title={"Replicate "+name} href={"#/replication/"+encoded}></a>&#160;
    +            <a className="db-actions btn icon-lock set-permissions" title={"Set permissions for "+name} href={"#/database/"+encoded+"/permissions"}></a>
    +          </td>
    +        </tr>
    +      );
    +    }
    +  });
    +
    +  var GraveyardInfo = React.createClass({
    +
    +    componentDidMount : function () {
    +      $(this.refs.myself.getDOMNode()).tooltip();
    +    },
    +
    +    render : function () {
    +      var row = this.props.row;
    +      return (
    +        <i className="js-db-graveyard icon icon-exclamation-sign" ref="myself" title={"This database has just " + row.status.numDocs() + " docs and " + row.status.numDeletedDocs() + " deleted docs"}></i>
    +      );
    +    }
    +  });
    +
    +  var RightDatabasesHeader = React.createClass({
    +
    +    render : function () {
    +      return (
    +        <div className="header-right">
    +          <AddDatabaseWidget />
    +          <JumpToDatabaseWidget />
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var AddDatabaseWidget = React.createClass({
    +
    +    onTrayToggle : function () {
    +      var that = this;
    +      this.refs.newDbTray.toggle(function (shown) {
    +        if (shown) {
    +          that.refs.newDbName.getDOMNode().focus();
    +        }
    +      });
    +    },
    +
    +    onKeyUpInInput : function (e) {
    +      if (e.which === 13) {
    +        this.onAddDatabase();
    +      }
    +    },
    +
    +    onAddDatabase : function () {
    +      var databaseName = $(this.refs.newDbName.getDOMNode()).val();
    +      Actions.createNewDatabase(databaseName, this.refs.newDbTray.hide, FauxtonAPI.addNotification);
    +    },
    +
    +    render : function () {
    +
    +      return (
    +        <div className="button" id="add-db-button">
    +          <a id="add-new-database" className="add-new-database-btn" href="#" onClick={this.onTrayToggle}><i className="header-icon fonticon-new-database"></i> Add New Database</a>
    +          <ComponentsReact.Tray trayid="new-database-tray" ref="newDbTray" className="new-database-tray">
    +            <span className="add-on">Add New Database</span>
    +            <input id="js-new-database-name" type="text" onKeyUp={this.onKeyUpInInput} ref="newDbName" className="input-xxlarge" placeholder="Name of database" />
    +            <a className="btn" id="js-create-database" onClick={this.onAddDatabase}>Create</a>
    +          </ComponentsReact.Tray>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var JumpToDatabaseWidget = React.createClass({
    +
    +    componentDidMount : function () {
    +      var that = this;
    +      $(this.refs.searchDbName.getDOMNode()).typeahead({
    +        source : databasesStore.getDatabaseNames(),
    +        updater: function (item) {
    +          that.jumpToDb(item);
    +        }
    +      });
    +      // turn of browser autocomplete
    +      $(this.refs.searchDbName.getDOMNode()).attr("autocomplete", "off");
    +    },
    +
    +    jumpToDb : function (dbname) {
    +      dbname = dbname || $(this.refs.searchDbName.getDOMNode()).val();
    +      dbname = dbname === null ? null : dbname.trim();
    +      if (dbname === null || dbname.length === 0) {
    +        return;
    +      }
    +      if (databasesStore.getDatabaseNames().indexOf(dbname) >= 0) {
    +        var url = FauxtonAPI.urls('allDocs', 'app', app.utils.safeURLName(dbname));
    +        FauxtonAPI.navigate(url);
    +      } else {
    +        FauxtonAPI.addNotification({
    +          msg: 'Database does not exist.',
    +          type: 'error'
    +        });
    +      }
    +    },
    +
    +    jumpToDbHandler : function () {
    +      this.jumpToDb();
    +      return false;
    +    },
    +
    +    render : function () {
    +      return (
    +        <div className="searchbox-wrapper">
    +          <div id="header-search" className="js-search searchbox-container">
    +            <form onSubmit={this.jumpToDbHandler} id="jump-to-db" className="navbar-form pull-right database-search">
    +              <div className="input-append">
    +                <input type="text" className="search-autocomplete" ref="searchDbName" name="search-query" placeholder="Database name" />
    +                <button className="btn btn-primary" type="submit"><i className="icon icon-search"></i></button>
    +              </div>
    +            </form>
    +          </div>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var DatabasePagination = React.createClass({
    +
    +    render : function () {
    +      var page = this.props.page;
    +      var total = this.props.total || databasesStore.getDatabaseNames().length;
    --- End diff --
    
    `databasesStore.getDatabaseNames().length` - please use this.state instead


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28763914
  
    --- Diff: app/addons/databases/actions.js ---
    @@ -0,0 +1,105 @@
    +// 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',
    +  'addons/databases/stores',
    +  'addons/databases/actiontypes',
    +  'addons/databases/resources'
    +],
    +function (app, FauxtonAPI, Stores, ActionTypes, Resources) {
    +  return {
    +    init: function (collection, backboneCollection) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_INIT,
    +        options: {
    +          collection: collection,
    +          backboneCollection: backboneCollection
    +        }
    +      });
    +    },
    +
    +    setPage: function (_page) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_SETPAGE,
    +        options: {
    +          page: _page
    +        }
    +      });
    +    },
    +
    +    setStartLoading: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_STARTLOADING,
    +        options: {}
    +      });
    +    },
    +
    +    setLoadComplete: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_LOADCOMPLETE,
    +        options: {}
    +      });
    +    },
    +
    +    createNewDatabase: function (databaseName, nameAccCallback) {
    +      databaseName = (databaseName === null ? null : databaseName.trim());
    +      if (databaseName === null || databaseName.length === 0) {
    +        FauxtonAPI.addNotification({
    +          msg: 'Please enter a valid database name',
    +          type: 'error',
    +          clear: true
    +        });
    +        return;
    +      }
    +      // name accepted, make sure prompt can be removed
    +      nameAccCallback();
    +
    +      var db = Stores.databasesStore.obtainNewDatabaseModel(databaseName);
    +      FauxtonAPI.addNotification({ msg: 'Creating database.' });
    +      db.save().done(function () {
    +          FauxtonAPI.addNotification({
    +            msg: 'Database created successfully',
    +            type: 'success',
    +            clear: true
    +          });
    +          var route = '#/database/' + app.utils.safeURLName(databaseName) + '/_all_docs?limit=' + Resources.DocLimit;
    --- End diff --
    
    This needs to be updated to use the `Fauxton.urls` method. @michellephung could you help with this.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-99977683
  
    +1 on Robert's last remark. :) 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

Re: [GitHub] couchdb-fauxton pull request: Databases view in react

Posted by Robert Kowalski <ro...@kowalski.gd>.
i would like to take garren a second look as the pr is fairly large

On Mon, Apr 20, 2015 at 11:12 PM, sebastianrothbucher
<gi...@git.apache.org> wrote:
> Github user sebastianrothbucher commented on the pull request:
>
>     https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-94569550
>
>     OK, did the last comment also - you think this is OK now?
>
>
> ---
> If your project is set up for it, you can reply to this email and have your
> reply appear on GitHub as well. If your project does not have this feature
> enabled and wishes so, or if the feature is enabled but not working, please
> contact infrastructure at infrastructure@apache.org or file a JIRA ticket
> with INFRA.
> ---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-94569550
  
    OK, did the last comment also - you think this is OK now?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-95253652
  
    Hey @sebastianrothbucher - one more issue. To reproduce:
    - Create a new database - which will redirect you to the new database's All Docs page.
    - Click the "<" icon to return to the Databases page.
    - Click the "Add Database" again. The page just reloads and you don't see the Add Database tray. The URL hash changes to `#` - looks like the JS isn't firing.
    
    To second everyone else here: really awesome work! If you want a hand with any of this, let me know.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28224794
  
    --- Diff: app/addons/databases/components.react.jsx ---
    @@ -0,0 +1,271 @@
    +// 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',
    +  'react',
    +  'addons/fauxton/components.react',
    +  'addons/databases/stores',
    +  'addons/databases/resources',
    +  'addons/databases/actions',
    +  'helpers'
    +], function (app, FauxtonAPI, React, ComponentsReact, Stores, Resources, Actions, Helpers) {
    +
    +  var databasesStore = Stores.databasesStore;
    +
    +  var DatabasesController = React.createClass({
    +
    +    getStoreState: function () {
    +      return {
    +        collection: databasesStore.getCollection()
    +      };
    +    },
    +
    +    getInitialState: function () {
    +      return this.getStoreState();
    +    },
    +
    +    render: function () {
    +      return (
    +        <DatabaseTable body={this.state.collection} />
    +      );
    +    }
    +  });
    +
    +  var DatabaseTable = React.createClass({
    +
    +    createRows: function () {
    +      return _.map(this.props.body, function (item, iteration) {
    +        return (
    +          <DatabaseRow row={item} />
    +        );
    +      });
    +    },
    +
    +    render: function () {
    +      var rows = this.createRows();
    +      return (
    +        <div className="view">
    +          <table className="databases table table-striped">
    +            <thead>
    +              <th>Name</th>
    +              <th>Size</th>
    +              <th># of Docs</th>
    +              <th>Update Seq</th>
    +              <th>Actions</th>
    +            </thead>
    +            <tbody>
    +            {rows}
    +            </tbody>
    +          </table>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var DatabaseRow = React.createClass({
    +
    +    renderGraveyard : function (row) {
    +      if (row.status.isGraveYard()) {
    +        return (
    +          <GraveyardInfo row={row} />
    +        );
    +      } else {
    +        return null;
    +      }
    +    },
    +
    +    render: function () {
    +      var row = this.props.row;
    +      var name = row.get("name");
    +      var encoded = app.utils.safeURLName(name);
    +      var size = Helpers.formatSize(row.status.dataSize());
    +      return (
    +        <tr>
    +          <td>
    +            <a href={"#/database/"+encoded+"/_all_docs"}>{name}</a>
    +          </td>
    +          <td>{size}</td>
    +          <td>{row.status.numDocs()} {this.renderGraveyard(row)}</td>
    +          <td>{row.status.updateSeq()}</td>
    +          <td>
    +            <a className="db-actions btn fonticon-replicate set-replication-start" title={"Replicate "+name} href={"#/replication/"+encoded}></a>&#160;
    +            <a className="db-actions btn icon-lock set-permissions" title={"Set permissions for "+name} href={"#/database/"+encoded+"/permissions"}></a>
    +          </td>
    +        </tr>
    +      );
    +    }
    +  });
    +
    +  var GraveyardInfo = React.createClass({
    +
    +    componentDidMount : function () {
    +      $(this.refs.myself.getDOMNode()).tooltip();
    +    },
    +
    +    render : function () {
    +      var row = this.props.row;
    +      return (
    +        <i className="js-db-graveyard icon icon-exclamation-sign" ref="myself" title={"This database has just " + row.status.numDocs() + " docs and " + row.status.numDeletedDocs() + " deleted docs"}></i>
    +      );
    +    }
    +  });
    +
    +  var RightDatabasesHeader = React.createClass({
    +
    +    render : function () {
    +      return (
    +        <div className="header-right">
    +          <AddDatabaseWidget />
    +          <JumpToDatabaseWidget />
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var AddDatabaseWidget = React.createClass({
    +
    +    onTrayToggle : function () {
    +      var that = this;
    +      this.refs.newDbTray.toggle(function (shown) {
    +        if (shown) {
    +          that.refs.newDbName.getDOMNode().focus();
    +        }
    +      });
    +    },
    +
    +    onKeyUpInInput : function (e) {
    +      if (e.which === 13) {
    +        this.onAddDatabase();
    +      }
    +    },
    +
    +    onAddDatabase : function () {
    +      var databaseName = $(this.refs.newDbName.getDOMNode()).val();
    --- End diff --
    
    that is how we would do it in jquery, take a look at https://github.com/apache/couchdb-fauxton/blob/master/app/addons/cors/components.react.jsx#L69 for how to solve that in react components without jquery


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: [WIP] Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-91885780
  
    thanks! - still lacks some tests, then I guess we're good to go...


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by michellephung <gi...@git.apache.org>.
Github user michellephung commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28532960
  
    --- Diff: app/addons/fauxton/components.react.jsx ---
    @@ -84,9 +84,129 @@ function (app, FauxtonAPI, React, ZeroClipboard) {
       });
     
     
    +  var Tray = React.createClass({
    +
    +    getInitialState: function () {
    +      return {
    +        show: false
    +      };
    +    },
    +
    +    toggle: function (done) {
    +      if (this.state.show) {
    +        this.hide(done);
    +      } else {
    +        this.show(done);
    +      }
    +    },
    +
    +    componentDidMount: function () {
    +      $('body').on('click.Tray-' + this.props.trayid + "-" + this._rootNodeID, function (e) {
    +        var tgt = $(e.target);
    +        if (this.state.show && tgt.closest('.tray').length === 0) {
    +          this.hide();
    +        }
    +      }.bind(this));
    +    },
    +
    +    componentWillUnmount: function () {
    +      $('body').off('click.Tray-' + this.props.trayid + "-" + this._rootNodeID);
    +    },
    +
    +    show: function (done) {
    +      this.setState({show: true});
    +      $(this.refs.myself.getDOMNode()).velocity('transition.slideDownIn', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        if (done) {
    +          done(true);
    +        }
    +      });
    +    },
    +
    +    hide: function (done) {
    +      $(this.refs.myself.getDOMNode()).velocity('reverse', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        this.setState({show: false});
    +        if (done) {
    +          done(false);
    +        }
    +      }.bind(this));
    +    },
    +
    +    render: function () {
    +      var styleSpec = this.state.show ? {"display": "block", "opacity": 1} :  {"display": "none", "opacity": 0};
    +      var classSpec = this.props.className || "";
    +      classSpec += " tray";
    +      return (
    +        <div ref="myself" style={styleSpec} className={classSpec}>{this.props.children}</div>
    +      );
    +    }
    +  });
    +
    +  var Pagination = React.createClass({
    +
    +    getInitialState: function () {
    +      return {};
    +    },
    +
    +    getDefaultProps: function () {
    +      return {
    +        perPage: FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE,
    +        page: 1,
    +        total: 0
    +      };
    +    },
    +
    +    render: function () {
    +      function getVisiblePages (page, totalPages) {
    --- End diff --
    
    you can pull this function out of the render, and add it to the Pagination object


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-92292344
  
    @sebastianrothbucher this is exciting. Thanks for working on it. @robertkowalski has given some nice recommendations. Keep going.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by michellephung <gi...@git.apache.org>.
Github user michellephung commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-94591639
  
    if you're feeling up to it, some whitespace nits:
    
    in the render functions, 
    1.) there are some html code that have nested tags and create long lines of html, put each tag on a newline (the nested tags that are short don't need new lines, but for the longer ones, its easier and faster to review and debug)
    2.) and for very long tags with lots of attributes, put each attribute on a new line, for example:
    https://github.com/apache/couchdb-fauxton/blob/master/app/addons/documents/index-editor/components.react.jsx#L96
    
    other than adding the key prop, 
    tests look good :)  code logic looks good :)
    
    FWIW, I am plus one after adding the key attribute to those 2 files, and white space changes are a "nice to have". 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by michellephung <gi...@git.apache.org>.
Github user michellephung commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28821282
  
    --- Diff: app/addons/databases/actions.js ---
    @@ -0,0 +1,105 @@
    +// 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',
    +  'addons/databases/stores',
    +  'addons/databases/actiontypes',
    +  'addons/databases/resources'
    +],
    +function (app, FauxtonAPI, Stores, ActionTypes, Resources) {
    +  return {
    +    init: function (collection, backboneCollection) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_INIT,
    +        options: {
    +          collection: collection,
    +          backboneCollection: backboneCollection
    +        }
    +      });
    +    },
    +
    +    setPage: function (_page) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_SETPAGE,
    +        options: {
    +          page: _page
    +        }
    +      });
    +    },
    +
    +    setStartLoading: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_STARTLOADING,
    +        options: {}
    +      });
    +    },
    +
    +    setLoadComplete: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_LOADCOMPLETE,
    +        options: {}
    +      });
    +    },
    +
    +    createNewDatabase: function (databaseName, nameAccCallback) {
    +      databaseName = (databaseName === null ? null : databaseName.trim());
    +      if (databaseName === null || databaseName.length === 0) {
    +        FauxtonAPI.addNotification({
    +          msg: 'Please enter a valid database name',
    +          type: 'error',
    +          clear: true
    +        });
    +        return;
    +      }
    +      // name accepted, make sure prompt can be removed
    +      nameAccCallback();
    +
    +      var db = Stores.databasesStore.obtainNewDatabaseModel(databaseName);
    +      FauxtonAPI.addNotification({ msg: 'Creating database.' });
    +      db.save().done(function () {
    +          FauxtonAPI.addNotification({
    +            msg: 'Database created successfully',
    +            type: 'success',
    +            clear: true
    +          });
    +          var route = '#/database/' + app.utils.safeURLName(databaseName) + '/_all_docs?limit=' + Resources.DocLimit;
    --- End diff --
    
    ```var route = FauxtonAPI.urls('allDocs', 'app', app.utils.safeURLName(databaseName), '?limit=' + Resources.DocLimit);```
    
    a bit of context:
    A couple of months ago we changed how to retrieve generalized urls in Fauxton.
    https://github.com/apache/couchdb-fauxton/pull/258
    
    there started to be several ways one could build a url string:
    -models.url(type);
    -string building
    -sequences of if-elseif statements
    
    so we centralized it to keep things uniform across the board.
    
    If you need to create a urls() function, you'd register/specify it in its respective base.js file.
    For Example, for documents urls: https://github.com/apache/couchdb-fauxton/blob/master/app/addons/documents/base.js



---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by michellephung <gi...@git.apache.org>.
Github user michellephung commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28735910
  
    --- Diff: app/addons/fauxton/components.react.jsx ---
    @@ -83,10 +83,132 @@ function (app, FauxtonAPI, React, ZeroClipboard) {
         }
       });
     
    +  var _NextTrayInternalId = 0;
    +  var Tray = React.createClass({
    +
    +    getInitialState: function () {
    +      return {
    +        show: false,
    +        internalid: (_NextTrayInternalId++)
    +      };
    +    },
    +
    +    toggle: function (done) {
    +      if (this.state.show) {
    +        this.hide(done);
    +      } else {
    +        this.show(done);
    +      }
    +    },
    +
    +    componentDidMount: function () {
    +      $('body').on('click.Tray-' + this.state.internalid, function (e) {
    +        var tgt = $(e.target);
    +        if (this.state.show && tgt.closest('.tray').length === 0) {
    +          this.hide();
    +        }
    +      }.bind(this));
    +    },
    +
    +    componentWillUnmount: function () {
    +      $('body').off('click.Tray-' + this.state.internalid);
    +    },
    +
    +    show: function (done) {
    +      this.setState({show: true});
    +      $(this.refs.myself.getDOMNode()).velocity('transition.slideDownIn', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        if (done) {
    +          done(true);
    +        }
    +      });
    +    },
    +
    +    hide: function (done) {
    +      $(this.refs.myself.getDOMNode()).velocity('reverse', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        this.setState({show: false});
    +        if (done) {
    +          done(false);
    +        }
    +      }.bind(this));
    +    },
    +
    +    render: function () {
    +      var styleSpec = this.state.show ? {"display": "block", "opacity": 1} :  {"display": "none", "opacity": 0};
    +      var classSpec = this.props.className || "";
    +      classSpec += " tray";
    +      return (
    +        <div ref="myself" style={styleSpec} className={classSpec}>{this.props.children}</div>
    +      );
    +    }
    +  });
    +
    +  var Pagination = React.createClass({
    +
    +    getInitialState: function () {
    +      return {};
    +    },
    +
    +    getDefaultProps: function () {
    +      return {
    +        perPage: FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE,
    +        page: 1,
    +        total: 0
    +      };
    +    },
    +
    +    getVisiblePages: function (page, totalPages) {
    +      var from, to;
    +      if (totalPages < 10) {
    +        from = 1;
    +        to = totalPages + 1;
    +      } else {
    +        from = page - 5;
    +        to = page + 5;
    +        if (from <= 1) {
    +          from = 1;
    +          to = 11;
    +        }
    +        if (to > totalPages + 1) {
    +          from =  totalPages - 9;
    +          to = totalPages + 1;
    +        }
    +      }
    +      return {
    +        from: from,
    +        to: to
    +      };
    +    },
    +
    +    render: function () {
    +      var page = this.state.page || this.props.page;
    +      var total = this.state.total || this.props.total;
    +      var perPage = this.props.perPage;
    +      var prefix = this.props.urlPrefix || "";
    +      var suffix = this.props.urlSuffix || "";
    +      var totalPages = total === 0 ? 1 : Math.ceil(total / perPage);
    +      var visiblePages = this.getVisiblePages(page, totalPages);
    +      var rangeItems = [];
    +      for (var i = visiblePages.from; i < visiblePages.to; i++) {
    +        rangeItems.push(
    +          <li className={(page === i ? "active" : null)}><a href={prefix + i + suffix}>{i}</a></li>
    +        );
    +      }
    +      return (
    +        <ul className="pagination">
    +          <li className={(page === 1 ? "disabled" : null)}><a href={prefix + Math.max(page - 1, 1) + suffix}>&laquo;</a></li>
    +          {rangeItems}
    +          <li className={(page < totalPages ? null : "disabled")}><a href={prefix + Math.min(page + 1, totalPages) + suffix}>&raquo;</a></li>
    +        </ul>
    +      );
    +    }
    --- End diff --
    
    ```
    <li key={i} className={(page === i ? "active" : null)} >
       <a href={prefix + i + suffix} >{i}</a>
    </li>
    ```
    
    to get rid of console error


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28763820
  
    --- Diff: app/addons/databases/actions.js ---
    @@ -0,0 +1,105 @@
    +// 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',
    +  'addons/databases/stores',
    +  'addons/databases/actiontypes',
    +  'addons/databases/resources'
    +],
    +function (app, FauxtonAPI, Stores, ActionTypes, Resources) {
    +  return {
    +    init: function (collection, backboneCollection) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_INIT,
    +        options: {
    +          collection: collection,
    +          backboneCollection: backboneCollection
    +        }
    +      });
    +    },
    +
    +    setPage: function (_page) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_SETPAGE,
    +        options: {
    +          page: _page
    +        }
    +      });
    +    },
    +
    +    setStartLoading: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_STARTLOADING,
    +        options: {}
    +      });
    +    },
    +
    +    setLoadComplete: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_LOADCOMPLETE,
    +        options: {}
    +      });
    +    },
    +
    +    createNewDatabase: function (databaseName, nameAccCallback) {
    +      databaseName = (databaseName === null ? null : databaseName.trim());
    +      if (databaseName === null || databaseName.length === 0) {
    +        FauxtonAPI.addNotification({
    +          msg: 'Please enter a valid database name',
    +          type: 'error',
    +          clear: true
    +        });
    +        return;
    +      }
    +      // name accepted, make sure prompt can be removed
    +      nameAccCallback();
    --- End diff --
    
    This doesn't really work, callbacks violate the flux one direction flow.
    I think what is better is to have a property on the store that maintains the state of the prompt. And rather change that which then causes the React Component to hide the prompt.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28225837
  
    --- Diff: app/addons/fauxton/components.react.jsx ---
    @@ -84,9 +84,131 @@ function (app, FauxtonAPI, React, ZeroClipboard) {
       });
     
     
    +  var Tray = React.createClass({
    +
    +    getInitialState : function () {
    +      return {
    +        show: false
    +      };
    +    },
    +
    +    toggle : function (done) {
    +      if (this.state.show) {
    +        this.hide(done);
    +      } else {
    +        this.show(done);
    +      }
    +    },
    +
    +    componentDidMount : function () {
    +      var that = this;
    +      $('body').on('click.Tray-' + this.props.trayid + "-" + this._rootNodeID, function (e) {
    +        var tgt = $(e.target);
    +        if (that.state.show && tgt.closest('.tray').length === 0) {
    +          that.hide();
    +        }
    +      });
    +    },
    +
    +    componentWillUnmount : function () {
    +      $('body').off('click.Tray-' + this.props.trayid + "-" + this._rootNodeID);
    +    },
    +
    +    show : function (done) {
    +      this.setState({show: true});
    +      $(this.refs.myself.getDOMNode()).velocity('transition.slideDownIn', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        if (done) {
    +          done(true);
    +        }
    +      });
    +    },
    +
    +    hide : function (done) {
    +      var that = this;
    +      $(this.refs.myself.getDOMNode()).velocity('reverse', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        that.setState({show: false});
    +        if (done) {
    +          done(false);
    +        }
    +      });
    --- End diff --
    
    we use bind


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-92027732
  
    Did the test also - would be great if you could have a look - thanks!


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28532530
  
    --- Diff: app/addons/fauxton/components.react.jsx ---
    @@ -84,9 +84,129 @@ function (app, FauxtonAPI, React, ZeroClipboard) {
       });
     
     
    +  var Tray = React.createClass({
    +
    +    getInitialState: function () {
    +      return {
    +        show: false
    +      };
    +    },
    +
    +    toggle: function (done) {
    +      if (this.state.show) {
    +        this.hide(done);
    +      } else {
    +        this.show(done);
    +      }
    +    },
    +
    +    componentDidMount: function () {
    +      $('body').on('click.Tray-' + this.props.trayid + "-" + this._rootNodeID, function (e) {
    --- End diff --
    
    I found a better solution for that one - thanks!
    BTW: while testing I realized that TestUtils.renderIntoDocument drops our container. So we can get more stable results by just using React.renderComponent


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-93710083
  
    one small comment - this is coming along very nicely! 
    
    also :heart: the testcoverage - this is awesome work!


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28764771
  
    --- Diff: app/addons/databases/routes.js ---
    @@ -46,43 +41,37 @@ function (app, FauxtonAPI, Databases, Views, Components) {
           this.databases = new Databases.List();
         },
     
    -    allDatabases: function () {
    -      var params = app.getParams(),
    -          dbPage = params.page ? parseInt(params.page, 10) : 1,
    -          perPage = FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE,
    -          pagination;
    -
    -      pagination = new Components.Pagination({
    -        page: dbPage,
    -        perPage: perPage,
    -        collection: this.databases,
    -        urlFun: function (page) {
    -          return '#/_all_dbs?page=' + page;
    -        }
    -      });
    -
    -      this.footer = this.setView('#footer', new Views.Footer());
    -      this.setView('#database-pagination', pagination);
    -
    -      this.databasesView = this.setView("#dashboard-content", new Views.List({
    -        collection: this.databases,
    -        perPage: perPage,
    -        page: dbPage
    -      }));
    -
    -      this.rightHeader = this.setView("#right-header", new Views.RightAllDBsHeader({
    -        collection: this.databases,
    -      }));
    +    paginated: function () {
    +      var start = (this.page - 1) * this.perPage;
    +      var end = this.page * this.perPage;
    +      return this.databases.slice(start, end);
    +    },
     
    -      this.databasesView.setPage(dbPage);
    +    allDatabases: function () {
    +      var params = app.getParams();
    +      this.page = params.page ? parseInt(params.page, 10) : 1;
    +      this.perPage = FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE;
    +
    +      Actions.setStartLoading();
    --- End diff --
    
    Could you move all of this fetching code into an action. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28888980
  
    --- Diff: app/addons/databases/components.react.jsx ---
    @@ -0,0 +1,303 @@
    +// 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',
    +  'react',
    +  'addons/components/react-components.react',
    +  'addons/fauxton/components.react',
    +  'addons/databases/stores',
    +  'addons/databases/resources',
    +  'addons/databases/actions',
    +  'helpers'
    +], function (app, FauxtonAPI, React, Components, ComponentsReact, Stores, Resources, Actions, Helpers) {
    +
    +  var databasesStore = Stores.databasesStore;
    +
    +  var DatabasesController = React.createClass({
    +
    +    getStoreState: function () {
    +      return {
    +        collection: databasesStore.getCollection(),
    +        loading: databasesStore.isLoading()
    +      };
    +    },
    +
    +    getInitialState: function () {
    +      return this.getStoreState();
    +    },
    +
    +    componentDidMount: function () {
    +      databasesStore.on('change', this.onChange, this);
    +    },
    +
    +    componentWillUnmount: function () {
    +      databasesStore.off('change', this.onChange, this);
    +    },
    +
    +    onChange: function () {
    +      this.setState(this.getStoreState());
    +    },
    +
    +    render: function () {
    +      var collection = this.state.collection || {};
    +      var loading = this.state.loading || false;
    +      return (
    +        <DatabaseTable body={collection} loading={loading} />
    +      );
    +    }
    +  });
    +
    +  var DatabaseTable = React.createClass({
    +
    +    createRows: function () {
    +      return _.map(this.props.body, function (item, iteration) {
    +        return (
    +          <DatabaseRow row={item} />
    +        );
    +      });
    +    },
    +
    +    render: function () {
    +      if (this.props.loading) {
    +        return (
    +          <div className="view">
    +            <Components.LoadLines />
    +          </div>
    +        );
    +      }
    +      var rows = this.createRows();
    +      return (
    +        <div className="view">
    +          <table className="databases table table-striped">
    +            <thead>
    +              <th>Name</th>
    +              <th>Size</th>
    +              <th># of Docs</th>
    +              <th>Update Seq</th>
    +              <th>Actions</th>
    +            </thead>
    +            <tbody>
    +            {rows}
    +            </tbody>
    +          </table>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var DatabaseRow = React.createClass({
    +
    +    renderGraveyard: function (row) {
    +      if (row.status.isGraveYard()) {
    +        return (
    +          <GraveyardInfo row={row} />
    +        );
    +      } else {
    +        return null;
    +      }
    +    },
    +
    +    render: function () {
    +      var row = this.props.row;
    +      var name = row.get("name");
    +      var encoded = app.utils.safeURLName(name);
    +      var size = Helpers.formatSize(row.status.dataSize());
    +      return (
    +        <tr>
    +          <td>
    +            <a href={"#/database/"+encoded+"/_all_docs"}>{name}</a>
    +          </td>
    +          <td>{size}</td>
    +          <td>{row.status.numDocs()} {this.renderGraveyard(row)}</td>
    +          <td>{row.status.updateSeq()}</td>
    +          <td>
    +            <a className="db-actions btn fonticon-replicate set-replication-start" title={"Replicate "+name} href={"#/replication/"+encoded}></a>&#160;
    +            <a className="db-actions btn icon-lock set-permissions" title={"Set permissions for "+name} href={"#/database/"+encoded+"/permissions"}></a>
    +          </td>
    +        </tr>
    +      );
    +    }
    +  });
    +
    +  var GraveyardInfo = React.createClass({
    +
    +    componentDidMount: function () {
    +      $(this.refs.myself.getDOMNode()).tooltip();
    +    },
    +
    +    render: function () {
    +      var row = this.props.row;
    +      return (
    +        <i className="js-db-graveyard icon icon-exclamation-sign" ref="myself" title={"This database has just " + row.status.numDocs() + " docs and " + row.status.numDeletedDocs() + " deleted docs"}></i>
    +      );
    --- End diff --
    
    We generally try to keep row length to <= 120 chars.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by michellephung <gi...@git.apache.org>.
Github user michellephung commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28533171
  
    --- Diff: app/addons/fauxton/components.react.jsx ---
    @@ -84,9 +84,131 @@ function (app, FauxtonAPI, React, ZeroClipboard) {
       });
     
     
    +  var Tray = React.createClass({
    +
    +    getInitialState : function () {
    +      return {
    +        show: false
    +      };
    +    },
    +
    +    toggle : function (done) {
    +      if (this.state.show) {
    +        this.hide(done);
    +      } else {
    +        this.show(done);
    +      }
    +    },
    +
    +    componentDidMount : function () {
    +      var that = this;
    +      $('body').on('click.Tray-' + this.props.trayid + "-" + this._rootNodeID, function (e) {
    +        var tgt = $(e.target);
    +        if (that.state.show && tgt.closest('.tray').length === 0) {
    +          that.hide();
    +        }
    +      });
    +    },
    +
    +    componentWillUnmount : function () {
    +      $('body').off('click.Tray-' + this.props.trayid + "-" + this._rootNodeID);
    +    },
    +
    +    show : function (done) {
    +      this.setState({show: true});
    +      $(this.refs.myself.getDOMNode()).velocity('transition.slideDownIn', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        if (done) {
    +          done(true);
    +        }
    +      });
    +    },
    +
    +    hide : function (done) {
    +      var that = this;
    +      $(this.refs.myself.getDOMNode()).velocity('reverse', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        that.setState({show: false});
    +        if (done) {
    +          done(false);
    +        }
    +      });
    +    },
    +
    +    render : function () {
    +      var styleSpec = this.state.show ? {"display": "block", "opacity": 1} :  {"display": "none", "opacity": 0};
    +      var classSpec = this.props.className || "";
    +      classSpec += " tray";
    +      return (
    +        <div ref="myself" style={styleSpec} className={classSpec}>{this.props.children}</div>
    +      );
    +    }
    +  });
    +
    +  var Pagination = React.createClass({
    +
    +    getInitialState: function () {
    +      return {};
    +    },
    +
    +    getDefaultProps : function () {
    +      return {
    +        perPage: FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE,
    +        page: 1,
    +        total: 0
    +      };
    +    },
    +
    +    render : function () {
    +      function getVisiblePages (page, totalPages) {
    +        var from, to;
    +        if (totalPages < 10) {
    +          from = 1;
    +          to = totalPages + 1;
    +        } else {
    +          from = page - 5;
    +          to = page + 5;
    +          if (from <= 1) {
    +            from = 1;
    +            to = 11;
    +          }
    +          if (to > totalPages + 1) {
    +            from =  totalPages - 9;
    +            to = totalPages + 1;
    +          }
    +        }
    +        return {
    +          from: from,
    +          to: to
    +        };
    +      }
    +      var page = this.state.page || this.props.page;
    +      var total = this.state.total || this.props.total;
    +      var perPage = this.props.perPage;
    +      var prefix = this.props.urlPrefix || "";
    +      var suffix = this.props.urlSuffix || "";
    +      var totalPages = total === 0 ? 1 : Math.ceil(total / perPage);
    +      var visiblePages = getVisiblePages(page, totalPages);
    +      var rangeItems = [];
    +      for (var i = visiblePages.from; i < visiblePages.to; i++) {
    +        rangeItems.push(
    +          <li className={(page === i ? "active" : null)}><a href={prefix + i + suffix}>{i}</a></li>
    +        );
    +      }
    +      return (
    +        <ul className="pagination">
    +          <li className={(page === 1 ? "disabled" : null)}><a href={prefix + Math.max(page - 1, 1) + suffix}>&laquo;</a></li>
    +          {rangeItems}
    +          <li className={(page < totalPages ? null : "disabled")}><a href={prefix + Math.min(page + 1, totalPages) + suffix}>&raquo;</a></li>
    +        </ul>
    +      );
    +    }
    +  });
    +
    +
    --- End diff --
    
    can you explain what you mean @robertkowalski ?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28456063
  
    --- Diff: app/addons/databases/components.react.jsx ---
    @@ -0,0 +1,271 @@
    +// 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',
    +  'react',
    +  'addons/fauxton/components.react',
    +  'addons/databases/stores',
    +  'addons/databases/resources',
    +  'addons/databases/actions',
    +  'helpers'
    +], function (app, FauxtonAPI, React, ComponentsReact, Stores, Resources, Actions, Helpers) {
    +
    +  var databasesStore = Stores.databasesStore;
    +
    +  var DatabasesController = React.createClass({
    +
    +    getStoreState: function () {
    +      return {
    +        collection: databasesStore.getCollection()
    +      };
    +    },
    +
    +    getInitialState: function () {
    +      return this.getStoreState();
    +    },
    +
    +    render: function () {
    +      return (
    +        <DatabaseTable body={this.state.collection} />
    +      );
    +    }
    +  });
    +
    +  var DatabaseTable = React.createClass({
    +
    +    createRows: function () {
    +      return _.map(this.props.body, function (item, iteration) {
    +        return (
    +          <DatabaseRow row={item} />
    +        );
    +      });
    +    },
    +
    +    render: function () {
    +      var rows = this.createRows();
    +      return (
    +        <div className="view">
    +          <table className="databases table table-striped">
    +            <thead>
    +              <th>Name</th>
    +              <th>Size</th>
    +              <th># of Docs</th>
    +              <th>Update Seq</th>
    +              <th>Actions</th>
    +            </thead>
    +            <tbody>
    +            {rows}
    +            </tbody>
    +          </table>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var DatabaseRow = React.createClass({
    +
    +    renderGraveyard : function (row) {
    +      if (row.status.isGraveYard()) {
    +        return (
    +          <GraveyardInfo row={row} />
    +        );
    +      } else {
    +        return null;
    +      }
    +    },
    +
    +    render: function () {
    +      var row = this.props.row;
    +      var name = row.get("name");
    +      var encoded = app.utils.safeURLName(name);
    +      var size = Helpers.formatSize(row.status.dataSize());
    +      return (
    +        <tr>
    +          <td>
    +            <a href={"#/database/"+encoded+"/_all_docs"}>{name}</a>
    +          </td>
    +          <td>{size}</td>
    +          <td>{row.status.numDocs()} {this.renderGraveyard(row)}</td>
    +          <td>{row.status.updateSeq()}</td>
    +          <td>
    +            <a className="db-actions btn fonticon-replicate set-replication-start" title={"Replicate "+name} href={"#/replication/"+encoded}></a>&#160;
    +            <a className="db-actions btn icon-lock set-permissions" title={"Set permissions for "+name} href={"#/database/"+encoded+"/permissions"}></a>
    +          </td>
    +        </tr>
    +      );
    +    }
    +  });
    +
    +  var GraveyardInfo = React.createClass({
    +
    +    componentDidMount : function () {
    +      $(this.refs.myself.getDOMNode()).tooltip();
    +    },
    +
    +    render : function () {
    +      var row = this.props.row;
    +      return (
    +        <i className="js-db-graveyard icon icon-exclamation-sign" ref="myself" title={"This database has just " + row.status.numDocs() + " docs and " + row.status.numDeletedDocs() + " deleted docs"}></i>
    +      );
    +    }
    +  });
    +
    +  var RightDatabasesHeader = React.createClass({
    +
    +    render : function () {
    +      return (
    +        <div className="header-right">
    +          <AddDatabaseWidget />
    +          <JumpToDatabaseWidget />
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var AddDatabaseWidget = React.createClass({
    +
    +    onTrayToggle : function () {
    +      var that = this;
    +      this.refs.newDbTray.toggle(function (shown) {
    +        if (shown) {
    +          that.refs.newDbName.getDOMNode().focus();
    +        }
    +      });
    +    },
    +
    +    onKeyUpInInput : function (e) {
    +      if (e.which === 13) {
    +        this.onAddDatabase();
    +      }
    +    },
    +
    +    onAddDatabase : function () {
    +      var databaseName = $(this.refs.newDbName.getDOMNode()).val();
    +      Actions.createNewDatabase(databaseName, this.refs.newDbTray.hide, FauxtonAPI.addNotification);
    +    },
    +
    +    render : function () {
    +
    +      return (
    +        <div className="button" id="add-db-button">
    +          <a id="add-new-database" className="add-new-database-btn" href="#" onClick={this.onTrayToggle}><i className="header-icon fonticon-new-database"></i> Add New Database</a>
    +          <ComponentsReact.Tray trayid="new-database-tray" ref="newDbTray" className="new-database-tray">
    +            <span className="add-on">Add New Database</span>
    +            <input id="js-new-database-name" type="text" onKeyUp={this.onKeyUpInInput} ref="newDbName" className="input-xxlarge" placeholder="Name of database" />
    +            <a className="btn" id="js-create-database" onClick={this.onAddDatabase}>Create</a>
    +          </ComponentsReact.Tray>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var JumpToDatabaseWidget = React.createClass({
    +
    +    componentDidMount : function () {
    +      var that = this;
    +      $(this.refs.searchDbName.getDOMNode()).typeahead({
    +        source : databasesStore.getDatabaseNames(),
    +        updater: function (item) {
    +          that.jumpToDb(item);
    +        }
    +      });
    +      // turn of browser autocomplete
    +      $(this.refs.searchDbName.getDOMNode()).attr("autocomplete", "off");
    --- End diff --
    
    you can't - React will drop the attribute. And we're doing JQuery here anyway. As long as we don't tynamically update the input field I think we're very OK and won't break things. We just have to remember not to bind anything to the input dynamically via react. Otherwise there would be "data-autocomplete='off'" - but still: we're using JQuery anyway and data-... does at least have a similar chance of getting in the way...


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28225486
  
    --- Diff: app/addons/fauxton/components.react.jsx ---
    @@ -84,9 +84,131 @@ function (app, FauxtonAPI, React, ZeroClipboard) {
       });
     
     
    +  var Tray = React.createClass({
    +
    +    getInitialState : function () {
    +      return {
    +        show: false
    +      };
    +    },
    +
    +    toggle : function (done) {
    +      if (this.state.show) {
    +        this.hide(done);
    +      } else {
    +        this.show(done);
    +      }
    +    },
    +
    +    componentDidMount : function () {
    +      var that = this;
    +      $('body').on('click.Tray-' + this.props.trayid + "-" + this._rootNodeID, function (e) {
    +        var tgt = $(e.target);
    +        if (that.state.show && tgt.closest('.tray').length === 0) {
    +          that.hide();
    +        }
    +      });
    +    },
    +
    +    componentWillUnmount : function () {
    +      $('body').off('click.Tray-' + this.props.trayid + "-" + this._rootNodeID);
    +    },
    +
    +    show : function (done) {
    +      this.setState({show: true});
    +      $(this.refs.myself.getDOMNode()).velocity('transition.slideDownIn', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        if (done) {
    +          done(true);
    +        }
    +      });
    +    },
    +
    +    hide : function (done) {
    +      var that = this;
    +      $(this.refs.myself.getDOMNode()).velocity('reverse', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        that.setState({show: false});
    +        if (done) {
    +          done(false);
    +        }
    +      });
    +    },
    +
    +    render : function () {
    +      var styleSpec = this.state.show ? {"display": "block", "opacity": 1} :  {"display": "none", "opacity": 0};
    +      var classSpec = this.props.className || "";
    +      classSpec += " tray";
    +      return (
    +        <div ref="myself" style={styleSpec} className={classSpec}>{this.props.children}</div>
    +      );
    +    }
    +  });
    +
    +  var Pagination = React.createClass({
    +
    +    getInitialState: function () {
    +      return {};
    +    },
    --- End diff --
    
    i think we can delete it


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-93818658
  
    @michellephung the LoadLines are too cool to not use them, so I did that - I still have to take care of your other comment though


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28224996
  
    --- Diff: app/addons/databases/components.react.jsx ---
    @@ -0,0 +1,271 @@
    +// 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',
    +  'react',
    +  'addons/fauxton/components.react',
    +  'addons/databases/stores',
    +  'addons/databases/resources',
    +  'addons/databases/actions',
    +  'helpers'
    +], function (app, FauxtonAPI, React, ComponentsReact, Stores, Resources, Actions, Helpers) {
    +
    +  var databasesStore = Stores.databasesStore;
    +
    +  var DatabasesController = React.createClass({
    +
    +    getStoreState: function () {
    +      return {
    +        collection: databasesStore.getCollection()
    +      };
    +    },
    +
    +    getInitialState: function () {
    +      return this.getStoreState();
    +    },
    +
    +    render: function () {
    +      return (
    +        <DatabaseTable body={this.state.collection} />
    +      );
    +    }
    +  });
    +
    +  var DatabaseTable = React.createClass({
    +
    +    createRows: function () {
    +      return _.map(this.props.body, function (item, iteration) {
    +        return (
    +          <DatabaseRow row={item} />
    +        );
    +      });
    +    },
    +
    +    render: function () {
    +      var rows = this.createRows();
    +      return (
    +        <div className="view">
    +          <table className="databases table table-striped">
    +            <thead>
    +              <th>Name</th>
    +              <th>Size</th>
    +              <th># of Docs</th>
    +              <th>Update Seq</th>
    +              <th>Actions</th>
    +            </thead>
    +            <tbody>
    +            {rows}
    +            </tbody>
    +          </table>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var DatabaseRow = React.createClass({
    +
    +    renderGraveyard : function (row) {
    +      if (row.status.isGraveYard()) {
    +        return (
    +          <GraveyardInfo row={row} />
    +        );
    +      } else {
    +        return null;
    +      }
    +    },
    +
    +    render: function () {
    +      var row = this.props.row;
    +      var name = row.get("name");
    +      var encoded = app.utils.safeURLName(name);
    +      var size = Helpers.formatSize(row.status.dataSize());
    +      return (
    +        <tr>
    +          <td>
    +            <a href={"#/database/"+encoded+"/_all_docs"}>{name}</a>
    +          </td>
    +          <td>{size}</td>
    +          <td>{row.status.numDocs()} {this.renderGraveyard(row)}</td>
    +          <td>{row.status.updateSeq()}</td>
    +          <td>
    +            <a className="db-actions btn fonticon-replicate set-replication-start" title={"Replicate "+name} href={"#/replication/"+encoded}></a>&#160;
    +            <a className="db-actions btn icon-lock set-permissions" title={"Set permissions for "+name} href={"#/database/"+encoded+"/permissions"}></a>
    +          </td>
    +        </tr>
    +      );
    +    }
    +  });
    +
    +  var GraveyardInfo = React.createClass({
    +
    +    componentDidMount : function () {
    +      $(this.refs.myself.getDOMNode()).tooltip();
    +    },
    +
    +    render : function () {
    +      var row = this.props.row;
    +      return (
    +        <i className="js-db-graveyard icon icon-exclamation-sign" ref="myself" title={"This database has just " + row.status.numDocs() + " docs and " + row.status.numDeletedDocs() + " deleted docs"}></i>
    +      );
    +    }
    +  });
    +
    +  var RightDatabasesHeader = React.createClass({
    +
    +    render : function () {
    +      return (
    +        <div className="header-right">
    +          <AddDatabaseWidget />
    +          <JumpToDatabaseWidget />
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var AddDatabaseWidget = React.createClass({
    +
    +    onTrayToggle : function () {
    +      var that = this;
    +      this.refs.newDbTray.toggle(function (shown) {
    +        if (shown) {
    +          that.refs.newDbName.getDOMNode().focus();
    +        }
    +      });
    +    },
    +
    +    onKeyUpInInput : function (e) {
    +      if (e.which === 13) {
    +        this.onAddDatabase();
    +      }
    +    },
    +
    +    onAddDatabase : function () {
    +      var databaseName = $(this.refs.newDbName.getDOMNode()).val();
    +      Actions.createNewDatabase(databaseName, this.refs.newDbTray.hide, FauxtonAPI.addNotification);
    --- End diff --
    
    no need to inject `FauxtonAPI.addNotification`
    
    also no need to inject the callback `this.refs.newDbTray.hide` - you can update a store which notifies this component after a successful update 
    



---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-93573286
  
    thanks for all your feedback - I incorporated it (also the react routes) to the best of my know...


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r29696422
  
    --- Diff: app/addons/databases/actions.js ---
    @@ -0,0 +1,123 @@
    +// 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',
    +  'addons/databases/stores',
    +  'addons/databases/actiontypes',
    +  'addons/databases/resources'
    +],
    +function (app, FauxtonAPI, Stores, ActionTypes, Resources) {
    +  return {
    +
    +    init: function (databases) {
    +      var params = app.getParams();
    +      var page = params.page ? parseInt(params.page, 10) : 1;
    +      var perPage = FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE;
    +
    +      this.setStartLoading();
    +      FauxtonAPI.when(databases.fetch({ cache: false })).then(function () {
    +        FauxtonAPI.when(databases.paginated(page, perPage).map(function (database) {
    +          return database.status.fetchOnce();
    +        })).always(function () {
    +          //make this always so that even if a user is not allowed access to a database
    +          //they will still see a list of all databases
    +          FauxtonAPI.dispatch({
    +            type: ActionTypes.DATABASES_INIT,
    +            options: {
    +              collection: databases.paginated(page, perPage),
    +              backboneCollection: databases,
    +              page: page
    +            }
    +          });
    +        }.bind(this));
    +      }.bind(this));
    +    },
    +
    +    setPage: function (_page) {
    +      FauxtonAPI.dispatch({
    --- End diff --
    
    Small thing. We don't use underscore prefixes for local vars. Mind just calling it `page`?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-94730048
  
    @sebastianrothbucher wow this is amazing work. Thank you. I've left a fair amount of comments, just somethings to get it more consistent with how we are using React. You are almost there. Please let me know if I can help you with any of it or if my comments don't make sense.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by michellephung <gi...@git.apache.org>.
Github user michellephung commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28737382
  
    --- Diff: app/addons/fauxton/components.react.jsx ---
    @@ -83,10 +83,132 @@ function (app, FauxtonAPI, React, ZeroClipboard) {
         }
       });
     
    +  var _NextTrayInternalId = 0;
    +  var Tray = React.createClass({
    +
    +    getInitialState: function () {
    +      return {
    +        show: false,
    +        internalid: (_NextTrayInternalId++)
    +      };
    +    },
    +
    +    toggle: function (done) {
    +      if (this.state.show) {
    +        this.hide(done);
    +      } else {
    +        this.show(done);
    +      }
    +    },
    +
    +    componentDidMount: function () {
    +      $('body').on('click.Tray-' + this.state.internalid, function (e) {
    +        var tgt = $(e.target);
    +        if (this.state.show && tgt.closest('.tray').length === 0) {
    +          this.hide();
    +        }
    +      }.bind(this));
    +    },
    +
    +    componentWillUnmount: function () {
    +      $('body').off('click.Tray-' + this.state.internalid);
    +    },
    +
    +    show: function (done) {
    +      this.setState({show: true});
    +      $(this.refs.myself.getDOMNode()).velocity('transition.slideDownIn', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        if (done) {
    +          done(true);
    +        }
    +      });
    +    },
    +
    +    hide: function (done) {
    +      $(this.refs.myself.getDOMNode()).velocity('reverse', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        this.setState({show: false});
    +        if (done) {
    +          done(false);
    +        }
    +      }.bind(this));
    +    },
    +
    +    render: function () {
    +      var styleSpec = this.state.show ? {"display": "block", "opacity": 1} :  {"display": "none", "opacity": 0};
    +      var classSpec = this.props.className || "";
    +      classSpec += " tray";
    +      return (
    +        <div ref="myself" style={styleSpec} className={classSpec}>{this.props.children}</div>
    +      );
    +    }
    +  });
    +
    +  var Pagination = React.createClass({
    +
    +    getInitialState: function () {
    +      return {};
    +    },
    +
    +    getDefaultProps: function () {
    +      return {
    +        perPage: FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE,
    +        page: 1,
    +        total: 0
    +      };
    +    },
    +
    +    getVisiblePages: function (page, totalPages) {
    +      var from, to;
    +      if (totalPages < 10) {
    +        from = 1;
    +        to = totalPages + 1;
    +      } else {
    +        from = page - 5;
    +        to = page + 5;
    +        if (from <= 1) {
    +          from = 1;
    +          to = 11;
    +        }
    +        if (to > totalPages + 1) {
    +          from =  totalPages - 9;
    +          to = totalPages + 1;
    +        }
    +      }
    +      return {
    +        from: from,
    +        to: to
    +      };
    +    },
    +
    +    render: function () {
    +      var page = this.state.page || this.props.page;
    +      var total = this.state.total || this.props.total;
    +      var perPage = this.props.perPage;
    +      var prefix = this.props.urlPrefix || "";
    +      var suffix = this.props.urlSuffix || "";
    +      var totalPages = total === 0 ? 1 : Math.ceil(total / perPage);
    +      var visiblePages = this.getVisiblePages(page, totalPages);
    +      var rangeItems = [];
    +      for (var i = visiblePages.from; i < visiblePages.to; i++) {
    +        rangeItems.push(
    +          <li className={(page === i ? "active" : null)}><a href={prefix + i + suffix}>{i}</a></li>
    +        );
    --- End diff --
    
    you might be able to pull this for-loop out of render and into it's own function as well. I haven't tested this, but if you can pull it out, it'd be nice :)


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-99843503
  
    @sebastianrothbucher yes, we all feel sorry for making this a long process for you.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by michellephung <gi...@git.apache.org>.
Github user michellephung commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28735951
  
    --- Diff: app/addons/fauxton/components.react.jsx ---
    @@ -83,10 +83,132 @@ function (app, FauxtonAPI, React, ZeroClipboard) {
         }
       });
     
    +  var _NextTrayInternalId = 0;
    +  var Tray = React.createClass({
    +
    +    getInitialState: function () {
    +      return {
    +        show: false,
    +        internalid: (_NextTrayInternalId++)
    +      };
    +    },
    +
    +    toggle: function (done) {
    +      if (this.state.show) {
    +        this.hide(done);
    +      } else {
    +        this.show(done);
    +      }
    +    },
    +
    +    componentDidMount: function () {
    +      $('body').on('click.Tray-' + this.state.internalid, function (e) {
    +        var tgt = $(e.target);
    +        if (this.state.show && tgt.closest('.tray').length === 0) {
    +          this.hide();
    +        }
    +      }.bind(this));
    +    },
    +
    +    componentWillUnmount: function () {
    +      $('body').off('click.Tray-' + this.state.internalid);
    +    },
    +
    +    show: function (done) {
    +      this.setState({show: true});
    +      $(this.refs.myself.getDOMNode()).velocity('transition.slideDownIn', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        if (done) {
    +          done(true);
    +        }
    +      });
    +    },
    +
    +    hide: function (done) {
    +      $(this.refs.myself.getDOMNode()).velocity('reverse', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        this.setState({show: false});
    +        if (done) {
    +          done(false);
    +        }
    +      }.bind(this));
    +    },
    +
    +    render: function () {
    +      var styleSpec = this.state.show ? {"display": "block", "opacity": 1} :  {"display": "none", "opacity": 0};
    +      var classSpec = this.props.className || "";
    +      classSpec += " tray";
    +      return (
    +        <div ref="myself" style={styleSpec} className={classSpec}>{this.props.children}</div>
    +      );
    +    }
    +  });
    +
    +  var Pagination = React.createClass({
    +
    +    getInitialState: function () {
    +      return {};
    +    },
    +
    +    getDefaultProps: function () {
    +      return {
    +        perPage: FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE,
    +        page: 1,
    +        total: 0
    +      };
    +    },
    +
    +    getVisiblePages: function (page, totalPages) {
    +      var from, to;
    +      if (totalPages < 10) {
    +        from = 1;
    +        to = totalPages + 1;
    +      } else {
    +        from = page - 5;
    +        to = page + 5;
    +        if (from <= 1) {
    +          from = 1;
    +          to = 11;
    +        }
    +        if (to > totalPages + 1) {
    +          from =  totalPages - 9;
    +          to = totalPages + 1;
    +        }
    +      }
    +      return {
    +        from: from,
    +        to: to
    +      };
    +    },
    +
    +    render: function () {
    +      var page = this.state.page || this.props.page;
    +      var total = this.state.total || this.props.total;
    +      var perPage = this.props.perPage;
    +      var prefix = this.props.urlPrefix || "";
    +      var suffix = this.props.urlSuffix || "";
    +      var totalPages = total === 0 ? 1 : Math.ceil(total / perPage);
    +      var visiblePages = this.getVisiblePages(page, totalPages);
    +      var rangeItems = [];
    +      for (var i = visiblePages.from; i < visiblePages.to; i++) {
    +        rangeItems.push(
    +          <li className={(page === i ? "active" : null)}><a href={prefix + i + suffix}>{i}</a></li>
    +        );
    --- End diff --
    
    ```
    <li key={i} className={(page === i ? "active" : null)} >
       <a href={prefix + i + suffix} >{i}</a>
    </li>
    ```
    
    to get rid of console error


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-99407635
  
    hey @sebastianrothbucher i think after you fixed the last two small issues and rebased the branch we can merge it


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-99988464
  
    it's merged - thanks for all your great feedback and for cheering on!


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by michellephung <gi...@git.apache.org>.
Github user michellephung commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-93807018
  
    theres a component for that ! :)
    
    loadinglines:  https://github.com/apache/couchdb-fauxton/blob/master/app/addons/documents/index-results/index-results.components.react.jsx#L81,
    
    although if you prefer the look of the spinner, i don't mind


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28803298
  
    --- Diff: app/addons/databases/actions.js ---
    @@ -0,0 +1,105 @@
    +// 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',
    +  'addons/databases/stores',
    +  'addons/databases/actiontypes',
    +  'addons/databases/resources'
    +],
    +function (app, FauxtonAPI, Stores, ActionTypes, Resources) {
    +  return {
    +    init: function (collection, backboneCollection) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_INIT,
    +        options: {
    +          collection: collection,
    +          backboneCollection: backboneCollection
    +        }
    +      });
    +    },
    +
    +    setPage: function (_page) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_SETPAGE,
    +        options: {
    +          page: _page
    +        }
    +      });
    +    },
    +
    +    setStartLoading: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_STARTLOADING,
    +        options: {}
    +      });
    +    },
    +
    +    setLoadComplete: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_LOADCOMPLETE,
    +        options: {}
    --- End diff --
    
    It depends on whether we just always want to have options - if we do it case-by-case we can just kick them out.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28225121
  
    --- Diff: app/addons/databases/components.react.jsx ---
    @@ -0,0 +1,271 @@
    +// 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',
    +  'react',
    +  'addons/fauxton/components.react',
    +  'addons/databases/stores',
    +  'addons/databases/resources',
    +  'addons/databases/actions',
    +  'helpers'
    +], function (app, FauxtonAPI, React, ComponentsReact, Stores, Resources, Actions, Helpers) {
    +
    +  var databasesStore = Stores.databasesStore;
    +
    +  var DatabasesController = React.createClass({
    +
    +    getStoreState: function () {
    +      return {
    +        collection: databasesStore.getCollection()
    +      };
    +    },
    +
    +    getInitialState: function () {
    +      return this.getStoreState();
    +    },
    +
    +    render: function () {
    +      return (
    +        <DatabaseTable body={this.state.collection} />
    +      );
    +    }
    +  });
    +
    +  var DatabaseTable = React.createClass({
    +
    +    createRows: function () {
    +      return _.map(this.props.body, function (item, iteration) {
    +        return (
    +          <DatabaseRow row={item} />
    +        );
    +      });
    +    },
    +
    +    render: function () {
    +      var rows = this.createRows();
    +      return (
    +        <div className="view">
    +          <table className="databases table table-striped">
    +            <thead>
    +              <th>Name</th>
    +              <th>Size</th>
    +              <th># of Docs</th>
    +              <th>Update Seq</th>
    +              <th>Actions</th>
    +            </thead>
    +            <tbody>
    +            {rows}
    +            </tbody>
    +          </table>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var DatabaseRow = React.createClass({
    +
    +    renderGraveyard : function (row) {
    +      if (row.status.isGraveYard()) {
    +        return (
    +          <GraveyardInfo row={row} />
    +        );
    +      } else {
    +        return null;
    +      }
    +    },
    +
    +    render: function () {
    +      var row = this.props.row;
    +      var name = row.get("name");
    +      var encoded = app.utils.safeURLName(name);
    +      var size = Helpers.formatSize(row.status.dataSize());
    +      return (
    +        <tr>
    +          <td>
    +            <a href={"#/database/"+encoded+"/_all_docs"}>{name}</a>
    +          </td>
    +          <td>{size}</td>
    +          <td>{row.status.numDocs()} {this.renderGraveyard(row)}</td>
    +          <td>{row.status.updateSeq()}</td>
    +          <td>
    +            <a className="db-actions btn fonticon-replicate set-replication-start" title={"Replicate "+name} href={"#/replication/"+encoded}></a>&#160;
    +            <a className="db-actions btn icon-lock set-permissions" title={"Set permissions for "+name} href={"#/database/"+encoded+"/permissions"}></a>
    +          </td>
    +        </tr>
    +      );
    +    }
    +  });
    +
    +  var GraveyardInfo = React.createClass({
    +
    +    componentDidMount : function () {
    +      $(this.refs.myself.getDOMNode()).tooltip();
    +    },
    +
    +    render : function () {
    +      var row = this.props.row;
    +      return (
    +        <i className="js-db-graveyard icon icon-exclamation-sign" ref="myself" title={"This database has just " + row.status.numDocs() + " docs and " + row.status.numDeletedDocs() + " deleted docs"}></i>
    +      );
    +    }
    +  });
    +
    +  var RightDatabasesHeader = React.createClass({
    +
    +    render : function () {
    +      return (
    +        <div className="header-right">
    +          <AddDatabaseWidget />
    +          <JumpToDatabaseWidget />
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var AddDatabaseWidget = React.createClass({
    +
    +    onTrayToggle : function () {
    +      var that = this;
    +      this.refs.newDbTray.toggle(function (shown) {
    +        if (shown) {
    +          that.refs.newDbName.getDOMNode().focus();
    +        }
    +      });
    +    },
    +
    +    onKeyUpInInput : function (e) {
    +      if (e.which === 13) {
    +        this.onAddDatabase();
    +      }
    +    },
    +
    +    onAddDatabase : function () {
    +      var databaseName = $(this.refs.newDbName.getDOMNode()).val();
    +      Actions.createNewDatabase(databaseName, this.refs.newDbTray.hide, FauxtonAPI.addNotification);
    +    },
    +
    +    render : function () {
    +
    +      return (
    +        <div className="button" id="add-db-button">
    +          <a id="add-new-database" className="add-new-database-btn" href="#" onClick={this.onTrayToggle}><i className="header-icon fonticon-new-database"></i> Add New Database</a>
    +          <ComponentsReact.Tray trayid="new-database-tray" ref="newDbTray" className="new-database-tray">
    +            <span className="add-on">Add New Database</span>
    +            <input id="js-new-database-name" type="text" onKeyUp={this.onKeyUpInInput} ref="newDbName" className="input-xxlarge" placeholder="Name of database" />
    +            <a className="btn" id="js-create-database" onClick={this.onAddDatabase}>Create</a>
    +          </ComponentsReact.Tray>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var JumpToDatabaseWidget = React.createClass({
    +
    +    componentDidMount : function () {
    +      var that = this;
    +      $(this.refs.searchDbName.getDOMNode()).typeahead({
    +        source : databasesStore.getDatabaseNames(),
    +        updater: function (item) {
    +          that.jumpToDb(item);
    +        }
    +      });
    +      // turn of browser autocomplete
    +      $(this.refs.searchDbName.getDOMNode()).attr("autocomplete", "off");
    +    },
    +
    +    jumpToDb : function (dbname) {
    --- End diff --
    
    this method should be an action and should not use jquery


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-97744254
  
    maybe I did some subtle mistakes yesterday. Now we get it done with data-bypass (thx to @garrensmith for the hint!). Feedback is included now...


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-93804502
  
    thanks! - actually we lost the spinner when getting rid of views.js (was tied to establish), I have to put it back in 2morrow...


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-99413729
  
    K, great


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28764497
  
    --- Diff: app/addons/databases/components.react.jsx ---
    @@ -0,0 +1,303 @@
    +// 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',
    +  'react',
    +  'addons/components/react-components.react',
    +  'addons/fauxton/components.react',
    +  'addons/databases/stores',
    +  'addons/databases/resources',
    +  'addons/databases/actions',
    +  'helpers'
    +], function (app, FauxtonAPI, React, Components, ComponentsReact, Stores, Resources, Actions, Helpers) {
    +
    +  var databasesStore = Stores.databasesStore;
    +
    +  var DatabasesController = React.createClass({
    +
    +    getStoreState: function () {
    +      return {
    +        collection: databasesStore.getCollection(),
    +        loading: databasesStore.isLoading()
    +      };
    +    },
    +
    +    getInitialState: function () {
    +      return this.getStoreState();
    +    },
    +
    +    componentDidMount: function () {
    +      databasesStore.on('change', this.onChange, this);
    +    },
    +
    +    componentWillUnmount: function () {
    +      databasesStore.off('change', this.onChange, this);
    +    },
    +
    +    onChange: function () {
    +      this.setState(this.getStoreState());
    +    },
    +
    +    render: function () {
    +      var collection = this.state.collection || {};
    --- End diff --
    
    Instead of having these initialisations here. Could you move them to the store. And the store can either return the collection or an empty array if the collection hasn't been fetched yet.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by michellephung <gi...@git.apache.org>.
Github user michellephung commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28735599
  
    --- Diff: app/addons/databases/components.react.jsx ---
    @@ -0,0 +1,303 @@
    +// 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',
    +  'react',
    +  'addons/components/react-components.react',
    +  'addons/fauxton/components.react',
    +  'addons/databases/stores',
    +  'addons/databases/resources',
    +  'addons/databases/actions',
    +  'helpers'
    +], function (app, FauxtonAPI, React, Components, ComponentsReact, Stores, Resources, Actions, Helpers) {
    +
    +  var databasesStore = Stores.databasesStore;
    +
    +  var DatabasesController = React.createClass({
    +
    +    getStoreState: function () {
    +      return {
    +        collection: databasesStore.getCollection(),
    +        loading: databasesStore.isLoading()
    +      };
    +    },
    +
    +    getInitialState: function () {
    +      return this.getStoreState();
    +    },
    +
    +    componentDidMount: function () {
    +      databasesStore.on('change', this.onChange, this);
    +    },
    +
    +    componentWillUnmount: function () {
    +      databasesStore.off('change', this.onChange, this);
    +    },
    +
    +    onChange: function () {
    +      this.setState(this.getStoreState());
    +    },
    +
    +    render: function () {
    +      var collection = this.state.collection || {};
    +      var loading = this.state.loading || false;
    +      return (
    +        <DatabaseTable body={collection} loading={loading} />
    +      );
    +    }
    +  });
    +
    +  var DatabaseTable = React.createClass({
    +
    +    createRows: function () {
    +      return _.map(this.props.body, function (item, iteration) {
    +        return (
    +          <DatabaseRow row={item} />
    --- End diff --
    
    <DatabaseRow row={item} key={iteration} />


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28763361
  
    --- Diff: app/addons/databases/actions.js ---
    @@ -0,0 +1,105 @@
    +// 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',
    +  'addons/databases/stores',
    +  'addons/databases/actiontypes',
    +  'addons/databases/resources'
    +],
    +function (app, FauxtonAPI, Stores, ActionTypes, Resources) {
    +  return {
    +    init: function (collection, backboneCollection) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_INIT,
    +        options: {
    +          collection: collection,
    +          backboneCollection: backboneCollection
    +        }
    +      });
    +    },
    +
    +    setPage: function (_page) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_SETPAGE,
    +        options: {
    +          page: _page
    +        }
    +      });
    +    },
    +
    +    setStartLoading: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_STARTLOADING,
    +        options: {}
    +      });
    +    },
    +
    +    setLoadComplete: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_LOADCOMPLETE,
    +        options: {}
    --- End diff --
    
    Since the object is empty do we need this property?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r29639665
  
    --- Diff: app/addons/databases/components.react.jsx ---
    @@ -0,0 +1,321 @@
    +// 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',
    +  'react',
    +  'addons/components/react-components.react',
    +  'addons/fauxton/components.react',
    +  'addons/databases/stores',
    +  'addons/databases/resources',
    +  'addons/databases/actions',
    +  'helpers'
    +], function (app, FauxtonAPI, React, Components, ComponentsReact, Stores, Resources, Actions, Helpers) {
    +
    +  var databasesStore = Stores.databasesStore;
    +
    +  var DatabasesController = React.createClass({
    +
    +    getStoreState: function () {
    +      return {
    +        collection: databasesStore.getCollection(),
    +        loading: databasesStore.isLoading()
    +      };
    +    },
    +
    +    getInitialState: function () {
    +      return this.getStoreState();
    +    },
    +
    +    componentDidMount: function () {
    +      databasesStore.on('change', this.onChange, this);
    +    },
    +
    +    componentWillUnmount: function () {
    +      databasesStore.off('change', this.onChange, this);
    +    },
    +
    +    onChange: function () {
    +      this.setState(this.getStoreState());
    +    },
    +
    +    render: function () {
    +      var collection = this.state.collection;
    +      var loading = this.state.loading;
    +      return (
    +        <DatabaseTable body={collection} loading={loading} />
    +      );
    +    }
    +  });
    +
    +  var DatabaseTable = React.createClass({
    +
    +    createRows: function () {
    +      return _.map(this.props.body, function (item, iteration) {
    +        return (
    +          <DatabaseRow row={item} key={iteration} />
    +        );
    +      });
    +    },
    +
    +    render: function () {
    +      if (this.props.loading) {
    +        return (
    +          <div className="view">
    +            <Components.LoadLines />
    +          </div>
    +        );
    +      }
    +      var rows = this.createRows();
    +      return (
    +        <div className="view">
    +          <table className="databases table table-striped">
    +            <thead>
    +              <th>Name</th>
    +              <th>Size</th>
    +              <th># of Docs</th>
    +              <th>Update Seq</th>
    +              <th>Actions</th>
    +            </thead>
    +            <tbody>
    +            {rows}
    +            </tbody>
    +          </table>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var DatabaseRow = React.createClass({
    +
    +    renderGraveyard: function (row) {
    +      if (row.status.isGraveYard()) {
    +        return (
    +          <GraveyardInfo row={row} />
    +        );
    +      } else {
    +        return null;
    +      }
    +    },
    +
    +    render: function () {
    +      var row = this.props.row;
    +      var name = row.get("name");
    +      var encoded = app.utils.safeURLName(name);
    +      var size = Helpers.formatSize(row.status.dataSize());
    +      return (
    +        <tr>
    +          <td>
    +            <a href={"#/database/"+encoded+"/_all_docs"}>{name}</a>
    +          </td>
    +          <td>{size}</td>
    +          <td>{row.status.numDocs()} {this.renderGraveyard(row)}</td>
    +          <td>{row.status.updateSeq()}</td>
    +          <td>
    +            <a className="db-actions btn fonticon-replicate set-replication-start" title={"Replicate "+name} href={"#/replication/"+encoded}></a>&#160;
    +            <a className="db-actions btn icon-lock set-permissions" title={"Set permissions for "+name} href={"#/database/"+encoded+"/permissions"}></a>
    +          </td>
    +        </tr>
    +      );
    +    }
    +  });
    +
    +  var GraveyardInfo = React.createClass({
    +
    +    componentDidMount: function () {
    +      $(this.refs.myself.getDOMNode()).tooltip();
    +    },
    +
    +    render: function () {
    +      var row = this.props.row;
    +      var graveyardTitle = "This database has just " + row.status.numDocs() +
    +        " docs and " + row.status.numDeletedDocs() + " deleted docs";
    +      return (
    +        <i className="js-db-graveyard icon icon-exclamation-sign" ref="myself" title={graveyardTitle}></i>
    +      );
    +    }
    +  });
    +
    +  var RightDatabasesHeader = React.createClass({
    +
    +    render: function () {
    +      return (
    +        <div className="header-right">
    +          <AddDatabaseWidget />
    +          <JumpToDatabaseWidget />
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var AddDatabaseWidget = React.createClass({
    +
    +    onTrayToggle: function (e) {
    +      e.preventDefault();
    +      this.refs.newDbTray.toggle(function (shown) {
    +        if (shown) {
    +          this.refs.newDbName.getDOMNode().focus();
    +        }
    +      }.bind(this));
    +    },
    +
    +    onKeyUpInInput: function (e) {
    +      if (e.which === 13) {
    +        this.onAddDatabase();
    +      }
    +    },
    +
    +    componentDidMount: function () {
    +      databasesStore.on('change', this.onChange, this);
    +    },
    +
    +    componentWillUnmount: function () {
    +      databasesStore.off('change', this.onChange, this);
    +    },
    +
    +    onChange: function () {
    +      if (this.isMounted()) {
    +        this.refs.newDbTray.setVisible(databasesStore.isPromptVisible());
    +      }
    +    },
    +
    +    onAddDatabase: function () {
    +      var databaseName = this.refs.newDbName.getDOMNode().value;
    +      Actions.createNewDatabase(databaseName);
    +    },
    +
    +    render: function () {
    +
    +      return (
    +        <div className="button" id="add-db-button">
    +          <a id="add-new-database" href="#" className="add-new-database-btn" onClick={this.onTrayToggle} data-bypass="true">
    +                <i className="header-icon fonticon-new-database"></i>
    +                Add New Database
    +          </a>
    +          <ComponentsReact.Tray ref="newDbTray" className="new-database-tray">
    +            <span className="add-on">Add New Database</span>
    +            <input id="js-new-database-name" type="text" onKeyUp={this.onKeyUpInInput} ref="newDbName" className="input-xxlarge" placeholder="Name of database" />
    +            <a className="btn" id="js-create-database" onClick={this.onAddDatabase}>Create</a>
    +          </ComponentsReact.Tray>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var JumpToDatabaseWidget = React.createClass({
    +
    +    getStoreState: function () {
    +      return {
    +        databaseNames: databasesStore.getDatabaseNames()
    +      };
    +    },
    +
    +    getInitialState: function () {
    +      return this.getStoreState();
    +    },
    +
    +    componentDidMount: function () {
    +      databasesStore.on('change', this.onChange, this);
    +      $(this.refs.searchDbName.getDOMNode()).typeahead({
    +        source: this.state.databaseNames,
    +        updater: function (item) {
    +          this.jumpToDb(item);
    +        }.bind(this)
    +      });
    +      // turn of browser autocomplete (direct markup is not passed on)
    +      $(this.refs.searchDbName.getDOMNode()).attr("autocomplete", "off");
    --- End diff --
    
    no need for the hack, as promised i searched: it is `autoComplete` (note the camelCase): https://facebook.github.io/react/docs/tags-and-attributes.html#html-attributes


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-97607879
  
    did most of it - but the bug persists. data-bypass is not it
    Leaving out href does it - strange. Need to investigate further
    The failing travis is somewhere else btw - I guess a wait was added (otherwise I'll just do it)


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28764003
  
    --- Diff: app/addons/databases/actions.js ---
    @@ -0,0 +1,105 @@
    +// 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',
    +  'addons/databases/stores',
    +  'addons/databases/actiontypes',
    +  'addons/databases/resources'
    +],
    +function (app, FauxtonAPI, Stores, ActionTypes, Resources) {
    +  return {
    +    init: function (collection, backboneCollection) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_INIT,
    +        options: {
    +          collection: collection,
    +          backboneCollection: backboneCollection
    +        }
    +      });
    +    },
    +
    +    setPage: function (_page) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_SETPAGE,
    +        options: {
    +          page: _page
    +        }
    +      });
    +    },
    +
    +    setStartLoading: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_STARTLOADING,
    +        options: {}
    +      });
    +    },
    +
    +    setLoadComplete: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_LOADCOMPLETE,
    +        options: {}
    +      });
    +    },
    +
    +    createNewDatabase: function (databaseName, nameAccCallback) {
    +      databaseName = (databaseName === null ? null : databaseName.trim());
    +      if (databaseName === null || databaseName.length === 0) {
    +        FauxtonAPI.addNotification({
    +          msg: 'Please enter a valid database name',
    +          type: 'error',
    +          clear: true
    +        });
    +        return;
    +      }
    +      // name accepted, make sure prompt can be removed
    +      nameAccCallback();
    +
    +      var db = Stores.databasesStore.obtainNewDatabaseModel(databaseName);
    +      FauxtonAPI.addNotification({ msg: 'Creating database.' });
    +      db.save().done(function () {
    +          FauxtonAPI.addNotification({
    +            msg: 'Database created successfully',
    +            type: 'success',
    +            clear: true
    +          });
    +          var route = '#/database/' + app.utils.safeURLName(databaseName) + '/_all_docs?limit=' + Resources.DocLimit;
    +          app.router.navigate(route, { trigger: true });
    +        }
    +      ).error(function (xhr) {
    +          var responseText = JSON.parse(xhr.responseText).reason;
    +          FauxtonAPI.addNotification({
    +            msg: 'Create database failed: ' + responseText,
    +            type: 'error',
    +            clear: true
    +          });
    +        }
    +      );
    +    },
    +
    +    jumpToDatabase: function (databaseName) {
    +      databaseName = databaseName === null ? null : databaseName.trim();
    +      if (databaseName === null || databaseName.length === 0) {
    --- End diff --
    
    You could change this to:
    
    ```javascript
    if (_.isNull(databaseName) || _.isEmpty(databaseName) {...
    ```
    
    Makes it a little more readable.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-92294763
  
    looks very promising! i left a few comments


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by sebastianrothbucher <gi...@git.apache.org>.
Github user sebastianrothbucher commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-95355071
  
    this is great feedback - thanks! Give me a few days... ;-) (and I'll come back to you when stuck)


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28224419
  
    --- Diff: app/addons/databases/components.react.jsx ---
    @@ -0,0 +1,271 @@
    +// 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',
    +  'react',
    +  'addons/fauxton/components.react',
    +  'addons/databases/stores',
    +  'addons/databases/resources',
    +  'addons/databases/actions',
    +  'helpers'
    +], function (app, FauxtonAPI, React, ComponentsReact, Stores, Resources, Actions, Helpers) {
    +
    +  var databasesStore = Stores.databasesStore;
    +
    +  var DatabasesController = React.createClass({
    +
    +    getStoreState: function () {
    +      return {
    +        collection: databasesStore.getCollection()
    +      };
    +    },
    +
    +    getInitialState: function () {
    +      return this.getStoreState();
    +    },
    +
    +    render: function () {
    +      return (
    +        <DatabaseTable body={this.state.collection} />
    +      );
    +    }
    +  });
    +
    +  var DatabaseTable = React.createClass({
    +
    +    createRows: function () {
    +      return _.map(this.props.body, function (item, iteration) {
    +        return (
    +          <DatabaseRow row={item} />
    +        );
    +      });
    +    },
    +
    +    render: function () {
    +      var rows = this.createRows();
    +      return (
    +        <div className="view">
    +          <table className="databases table table-striped">
    +            <thead>
    +              <th>Name</th>
    +              <th>Size</th>
    +              <th># of Docs</th>
    +              <th>Update Seq</th>
    +              <th>Actions</th>
    +            </thead>
    +            <tbody>
    +            {rows}
    +            </tbody>
    +          </table>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var DatabaseRow = React.createClass({
    +
    +    renderGraveyard : function (row) {
    +      if (row.status.isGraveYard()) {
    +        return (
    +          <GraveyardInfo row={row} />
    +        );
    +      } else {
    +        return null;
    +      }
    +    },
    +
    +    render: function () {
    +      var row = this.props.row;
    +      var name = row.get("name");
    +      var encoded = app.utils.safeURLName(name);
    +      var size = Helpers.formatSize(row.status.dataSize());
    +      return (
    +        <tr>
    +          <td>
    +            <a href={"#/database/"+encoded+"/_all_docs"}>{name}</a>
    +          </td>
    +          <td>{size}</td>
    +          <td>{row.status.numDocs()} {this.renderGraveyard(row)}</td>
    +          <td>{row.status.updateSeq()}</td>
    +          <td>
    +            <a className="db-actions btn fonticon-replicate set-replication-start" title={"Replicate "+name} href={"#/replication/"+encoded}></a>&#160;
    +            <a className="db-actions btn icon-lock set-permissions" title={"Set permissions for "+name} href={"#/database/"+encoded+"/permissions"}></a>
    +          </td>
    +        </tr>
    +      );
    +    }
    +  });
    +
    +  var GraveyardInfo = React.createClass({
    +
    +    componentDidMount : function () {
    +      $(this.refs.myself.getDOMNode()).tooltip();
    +    },
    +
    +    render : function () {
    +      var row = this.props.row;
    +      return (
    +        <i className="js-db-graveyard icon icon-exclamation-sign" ref="myself" title={"This database has just " + row.status.numDocs() + " docs and " + row.status.numDeletedDocs() + " deleted docs"}></i>
    +      );
    +    }
    +  });
    +
    +  var RightDatabasesHeader = React.createClass({
    +
    +    render : function () {
    +      return (
    +        <div className="header-right">
    +          <AddDatabaseWidget />
    +          <JumpToDatabaseWidget />
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var AddDatabaseWidget = React.createClass({
    +
    +    onTrayToggle : function () {
    +      var that = this;
    --- End diff --
    
    we use bind and try to avoid this = that



---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28547303
  
    --- Diff: app/addons/fauxton/components.react.jsx ---
    @@ -84,9 +84,131 @@ function (app, FauxtonAPI, React, ZeroClipboard) {
       });
     
     
    +  var Tray = React.createClass({
    +
    +    getInitialState : function () {
    +      return {
    +        show: false
    +      };
    +    },
    +
    +    toggle : function (done) {
    +      if (this.state.show) {
    +        this.hide(done);
    +      } else {
    +        this.show(done);
    +      }
    +    },
    +
    +    componentDidMount : function () {
    +      var that = this;
    +      $('body').on('click.Tray-' + this.props.trayid + "-" + this._rootNodeID, function (e) {
    +        var tgt = $(e.target);
    +        if (that.state.show && tgt.closest('.tray').length === 0) {
    +          that.hide();
    +        }
    +      });
    +    },
    +
    +    componentWillUnmount : function () {
    +      $('body').off('click.Tray-' + this.props.trayid + "-" + this._rootNodeID);
    +    },
    +
    +    show : function (done) {
    +      this.setState({show: true});
    +      $(this.refs.myself.getDOMNode()).velocity('transition.slideDownIn', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        if (done) {
    +          done(true);
    +        }
    +      });
    +    },
    +
    +    hide : function (done) {
    +      var that = this;
    +      $(this.refs.myself.getDOMNode()).velocity('reverse', FauxtonAPI.constants.MISC.TRAY_TOGGLE_SPEED, function () {
    +        that.setState({show: false});
    +        if (done) {
    +          done(false);
    +        }
    +      });
    +    },
    +
    +    render : function () {
    +      var styleSpec = this.state.show ? {"display": "block", "opacity": 1} :  {"display": "none", "opacity": 0};
    +      var classSpec = this.props.className || "";
    +      classSpec += " tray";
    +      return (
    +        <div ref="myself" style={styleSpec} className={classSpec}>{this.props.children}</div>
    +      );
    +    }
    +  });
    +
    +  var Pagination = React.createClass({
    +
    +    getInitialState: function () {
    +      return {};
    +    },
    +
    +    getDefaultProps : function () {
    +      return {
    +        perPage: FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE,
    +        page: 1,
    +        total: 0
    +      };
    +    },
    +
    +    render : function () {
    +      function getVisiblePages (page, totalPages) {
    +        var from, to;
    +        if (totalPages < 10) {
    +          from = 1;
    +          to = totalPages + 1;
    +        } else {
    +          from = page - 5;
    +          to = page + 5;
    +          if (from <= 1) {
    +            from = 1;
    +            to = 11;
    +          }
    +          if (to > totalPages + 1) {
    +            from =  totalPages - 9;
    +            to = totalPages + 1;
    +          }
    +        }
    +        return {
    +          from: from,
    +          to: to
    +        };
    +      }
    +      var page = this.state.page || this.props.page;
    +      var total = this.state.total || this.props.total;
    +      var perPage = this.props.perPage;
    +      var prefix = this.props.urlPrefix || "";
    +      var suffix = this.props.urlSuffix || "";
    +      var totalPages = total === 0 ? 1 : Math.ceil(total / perPage);
    +      var visiblePages = getVisiblePages(page, totalPages);
    +      var rangeItems = [];
    +      for (var i = visiblePages.from; i < visiblePages.to; i++) {
    +        rangeItems.push(
    +          <li className={(page === i ? "active" : null)}><a href={prefix + i + suffix}>{i}</a></li>
    +        );
    +      }
    +      return (
    +        <ul className="pagination">
    +          <li className={(page === 1 ? "disabled" : null)}><a href={prefix + Math.max(page - 1, 1) + suffix}>&laquo;</a></li>
    +          {rangeItems}
    +          <li className={(page < totalPages ? null : "disabled")}><a href={prefix + Math.min(page + 1, totalPages) + suffix}>&raquo;</a></li>
    +        </ul>
    +      );
    +    }
    +  });
    +
    +
    --- End diff --
    
    it was related to the previous formatting of the code, take a look at the whitespace around the `:`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28225072
  
    --- Diff: app/addons/databases/components.react.jsx ---
    @@ -0,0 +1,271 @@
    +// 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',
    +  'react',
    +  'addons/fauxton/components.react',
    +  'addons/databases/stores',
    +  'addons/databases/resources',
    +  'addons/databases/actions',
    +  'helpers'
    +], function (app, FauxtonAPI, React, ComponentsReact, Stores, Resources, Actions, Helpers) {
    +
    +  var databasesStore = Stores.databasesStore;
    +
    +  var DatabasesController = React.createClass({
    +
    +    getStoreState: function () {
    +      return {
    +        collection: databasesStore.getCollection()
    +      };
    +    },
    +
    +    getInitialState: function () {
    +      return this.getStoreState();
    +    },
    +
    +    render: function () {
    +      return (
    +        <DatabaseTable body={this.state.collection} />
    +      );
    +    }
    +  });
    +
    +  var DatabaseTable = React.createClass({
    +
    +    createRows: function () {
    +      return _.map(this.props.body, function (item, iteration) {
    +        return (
    +          <DatabaseRow row={item} />
    +        );
    +      });
    +    },
    +
    +    render: function () {
    +      var rows = this.createRows();
    +      return (
    +        <div className="view">
    +          <table className="databases table table-striped">
    +            <thead>
    +              <th>Name</th>
    +              <th>Size</th>
    +              <th># of Docs</th>
    +              <th>Update Seq</th>
    +              <th>Actions</th>
    +            </thead>
    +            <tbody>
    +            {rows}
    +            </tbody>
    +          </table>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var DatabaseRow = React.createClass({
    +
    +    renderGraveyard : function (row) {
    +      if (row.status.isGraveYard()) {
    +        return (
    +          <GraveyardInfo row={row} />
    +        );
    +      } else {
    +        return null;
    +      }
    +    },
    +
    +    render: function () {
    +      var row = this.props.row;
    +      var name = row.get("name");
    +      var encoded = app.utils.safeURLName(name);
    +      var size = Helpers.formatSize(row.status.dataSize());
    +      return (
    +        <tr>
    +          <td>
    +            <a href={"#/database/"+encoded+"/_all_docs"}>{name}</a>
    +          </td>
    +          <td>{size}</td>
    +          <td>{row.status.numDocs()} {this.renderGraveyard(row)}</td>
    +          <td>{row.status.updateSeq()}</td>
    +          <td>
    +            <a className="db-actions btn fonticon-replicate set-replication-start" title={"Replicate "+name} href={"#/replication/"+encoded}></a>&#160;
    +            <a className="db-actions btn icon-lock set-permissions" title={"Set permissions for "+name} href={"#/database/"+encoded+"/permissions"}></a>
    +          </td>
    +        </tr>
    +      );
    +    }
    +  });
    +
    +  var GraveyardInfo = React.createClass({
    +
    +    componentDidMount : function () {
    +      $(this.refs.myself.getDOMNode()).tooltip();
    +    },
    +
    +    render : function () {
    +      var row = this.props.row;
    +      return (
    +        <i className="js-db-graveyard icon icon-exclamation-sign" ref="myself" title={"This database has just " + row.status.numDocs() + " docs and " + row.status.numDeletedDocs() + " deleted docs"}></i>
    +      );
    +    }
    +  });
    +
    +  var RightDatabasesHeader = React.createClass({
    +
    +    render : function () {
    +      return (
    +        <div className="header-right">
    +          <AddDatabaseWidget />
    +          <JumpToDatabaseWidget />
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var AddDatabaseWidget = React.createClass({
    +
    +    onTrayToggle : function () {
    +      var that = this;
    +      this.refs.newDbTray.toggle(function (shown) {
    +        if (shown) {
    +          that.refs.newDbName.getDOMNode().focus();
    +        }
    +      });
    +    },
    +
    +    onKeyUpInInput : function (e) {
    +      if (e.which === 13) {
    +        this.onAddDatabase();
    +      }
    +    },
    +
    +    onAddDatabase : function () {
    +      var databaseName = $(this.refs.newDbName.getDOMNode()).val();
    +      Actions.createNewDatabase(databaseName, this.refs.newDbTray.hide, FauxtonAPI.addNotification);
    +    },
    +
    +    render : function () {
    +
    +      return (
    +        <div className="button" id="add-db-button">
    +          <a id="add-new-database" className="add-new-database-btn" href="#" onClick={this.onTrayToggle}><i className="header-icon fonticon-new-database"></i> Add New Database</a>
    +          <ComponentsReact.Tray trayid="new-database-tray" ref="newDbTray" className="new-database-tray">
    +            <span className="add-on">Add New Database</span>
    +            <input id="js-new-database-name" type="text" onKeyUp={this.onKeyUpInInput} ref="newDbName" className="input-xxlarge" placeholder="Name of database" />
    +            <a className="btn" id="js-create-database" onClick={this.onAddDatabase}>Create</a>
    +          </ComponentsReact.Tray>
    +        </div>
    +      );
    +    }
    +  });
    +
    +  var JumpToDatabaseWidget = React.createClass({
    +
    +    componentDidMount : function () {
    +      var that = this;
    +      $(this.refs.searchDbName.getDOMNode()).typeahead({
    +        source : databasesStore.getDatabaseNames(),
    +        updater: function (item) {
    +          that.jumpToDb(item);
    +        }
    +      });
    +      // turn of browser autocomplete
    +      $(this.refs.searchDbName.getDOMNode()).attr("autocomplete", "off");
    --- End diff --
    
    why not just add `autocomplete=off` to the markup?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28225290
  
    --- Diff: app/addons/databases/stores.js ---
    @@ -0,0 +1,99 @@
    +// 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',
    +  'addons/databases/actiontypes',
    +  'addons/databases/resources'
    +], function (app, FauxtonAPI, ActionTypes, Resources) {
    +
    +  var DatabasesStore = FauxtonAPI.Store.extend({
    +
    +    init: function (collection, backboneCollection) {
    +      // allow partial inits - don't depend on creation order
    +      this._collection = collection || this._collection;
    +      this._backboneCollection = backboneCollection || this._backboneCollection;
    +    },
    +
    +    createNewDatabase: function (databaseName, nameAccCallback, notifyCallback) {
    +      databaseName = (databaseName === null ? null : databaseName.trim());
    +      if (databaseName === null || databaseName.length === 0) {
    +        notifyCallback({
    +          msg: 'Please enter a valid database name',
    +          type: 'error',
    +          clear: true
    +        });
    +        return;
    +      }
    +      nameAccCallback();
    +
    +      var db = new this._backboneCollection.model({
    +        id: databaseName,
    +        name: databaseName
    +      });
    +      notifyCallback({ msg: 'Creating database.' });
    +
    +      db.save().done(function () {
    +          notifyCallback({
    +            msg: 'Database created successfully',
    +            type: 'success',
    +            clear: true
    +          });
    +          var route = '#/database/' + app.utils.safeURLName(databaseName) + '/_all_docs?limit=' + Resources.DocLimit;
    +          app.router.navigate(route, { trigger: true });
    +        }
    +      ).error(function (xhr) {
    +          var responseText = JSON.parse(xhr.responseText).reason;
    +          notifyCallback({
    +            msg: 'Create database failed: ' + responseText,
    +            type: 'error',
    +            clear: true
    +          });
    +        }
    +      );
    +    },
    --- End diff --
    
    you can't know but this async operation belongs to an action. all async stuff happens in actions for fauxton


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28225727
  
    --- Diff: app/addons/fauxton/components.react.jsx ---
    @@ -84,9 +84,131 @@ function (app, FauxtonAPI, React, ZeroClipboard) {
       });
     
     
    +  var Tray = React.createClass({
    +
    +    getInitialState : function () {
    +      return {
    +        show: false
    +      };
    +    },
    +
    +    toggle : function (done) {
    +      if (this.state.show) {
    +        this.hide(done);
    +      } else {
    +        this.show(done);
    +      }
    +    },
    +
    +    componentDidMount : function () {
    +      var that = this;
    +      $('body').on('click.Tray-' + this.props.trayid + "-" + this._rootNodeID, function (e) {
    --- End diff --
    
    I think we don't need a trayid - you can take `this.props.className`
    
    I thin we don't nee a _rootNodeID - there will just one tray at all for creating databases


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-94816126
  
    @sebastianrothbucher I also found one bug. If I go to page 2 and then click new database, it then takes me back to page 1. I think you might need to add `data-bypass=true` for the new database link


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28763442
  
    --- Diff: app/addons/databases/actions.js ---
    @@ -0,0 +1,105 @@
    +// 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',
    +  'addons/databases/stores',
    +  'addons/databases/actiontypes',
    +  'addons/databases/resources'
    +],
    +function (app, FauxtonAPI, Stores, ActionTypes, Resources) {
    +  return {
    +    init: function (collection, backboneCollection) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_INIT,
    +        options: {
    +          collection: collection,
    +          backboneCollection: backboneCollection
    +        }
    +      });
    +    },
    +
    +    setPage: function (_page) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_SETPAGE,
    +        options: {
    +          page: _page
    +        }
    +      });
    +    },
    +
    +    setStartLoading: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_STARTLOADING,
    +        options: {}
    +      });
    +    },
    +
    +    setLoadComplete: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_LOADCOMPLETE,
    +        options: {}
    +      });
    +    },
    +
    +    createNewDatabase: function (databaseName, nameAccCallback) {
    +      databaseName = (databaseName === null ? null : databaseName.trim());
    --- End diff --
    
    could you change this from `databaseName === null` to `_.isNull(databaseName)`. I think an if statement might be nicer here.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28764131
  
    --- Diff: app/addons/databases/actions.js ---
    @@ -0,0 +1,105 @@
    +// 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',
    +  'addons/databases/stores',
    +  'addons/databases/actiontypes',
    +  'addons/databases/resources'
    +],
    +function (app, FauxtonAPI, Stores, ActionTypes, Resources) {
    +  return {
    +    init: function (collection, backboneCollection) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_INIT,
    +        options: {
    +          collection: collection,
    +          backboneCollection: backboneCollection
    +        }
    +      });
    +    },
    +
    +    setPage: function (_page) {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_SETPAGE,
    +        options: {
    +          page: _page
    +        }
    +      });
    +    },
    +
    +    setStartLoading: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_STARTLOADING,
    +        options: {}
    +      });
    +    },
    +
    +    setLoadComplete: function () {
    +      FauxtonAPI.dispatch({
    +        type: ActionTypes.DATABASES_LOADCOMPLETE,
    +        options: {}
    +      });
    +    },
    +
    +    createNewDatabase: function (databaseName, nameAccCallback) {
    +      databaseName = (databaseName === null ? null : databaseName.trim());
    +      if (databaseName === null || databaseName.length === 0) {
    +        FauxtonAPI.addNotification({
    +          msg: 'Please enter a valid database name',
    +          type: 'error',
    +          clear: true
    +        });
    +        return;
    +      }
    +      // name accepted, make sure prompt can be removed
    +      nameAccCallback();
    +
    +      var db = Stores.databasesStore.obtainNewDatabaseModel(databaseName);
    +      FauxtonAPI.addNotification({ msg: 'Creating database.' });
    +      db.save().done(function () {
    +          FauxtonAPI.addNotification({
    +            msg: 'Database created successfully',
    +            type: 'success',
    +            clear: true
    +          });
    +          var route = '#/database/' + app.utils.safeURLName(databaseName) + '/_all_docs?limit=' + Resources.DocLimit;
    +          app.router.navigate(route, { trigger: true });
    +        }
    +      ).error(function (xhr) {
    +          var responseText = JSON.parse(xhr.responseText).reason;
    +          FauxtonAPI.addNotification({
    +            msg: 'Create database failed: ' + responseText,
    +            type: 'error',
    +            clear: true
    +          });
    +        }
    +      );
    +    },
    +
    +    jumpToDatabase: function (databaseName) {
    +      databaseName = databaseName === null ? null : databaseName.trim();
    +      if (databaseName === null || databaseName.length === 0) {
    +        return;
    +      }
    +      if (Stores.databasesStore.getDatabaseNames().indexOf(databaseName) >= 0) {
    --- End diff --
    
    Could you make this a function on the databasesStore. Something like `Stores.databasesStore.doesDatabaseExist(databaseName)`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28500914
  
    --- Diff: app/addons/fauxton/components.react.jsx ---
    @@ -84,9 +84,129 @@ function (app, FauxtonAPI, React, ZeroClipboard) {
       });
     
     
    +  var Tray = React.createClass({
    +
    +    getInitialState: function () {
    +      return {
    +        show: false
    +      };
    +    },
    +
    +    toggle: function (done) {
    +      if (this.state.show) {
    +        this.hide(done);
    +      } else {
    +        this.show(done);
    +      }
    +    },
    +
    +    componentDidMount: function () {
    +      $('body').on('click.Tray-' + this.props.trayid + "-" + this._rootNodeID, function (e) {
    --- End diff --
    
    be careful regarding `this._rootNodeID`, it will break as soon as we update to 0.13:
    
    from: https://facebook.github.io/react/blog/2015/03/10/react-v0.13.html
    
    ```
    Access to most internal properties has been completely removed, including this._pendingState and this._rootNodeID.
    ```
    



---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by michellephung <gi...@git.apache.org>.
Github user michellephung commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#issuecomment-92464693
  
    Hey @sebastianrothbucher,
    
    We are trying not to use jQuery in the React code, because usually there is a good way to handle an event without it. I don't think this is written anywhere, since we just started building with React code. Sorry about that, if that was unclear.
    
    However! for the tray/tooltip, it's okay to use jQuery, since there's not another way to capture a `$('body').onclick` event or init the tooltip. 
    
    Also, @garrensmith just added https://github.com/apache/couchdb-fauxton/commit/02a5ee3f0067432d3abf4fd683397ed6d66137ab, so we can render/remove the react components from the routes file.  I also changed my Active Tasks PR to reflect this change, and I'll wait for Garren's feedback before I merge it in, but something to keep in mind while your making changes. 



---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Databases view in react

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/370#discussion_r28764806
  
    --- Diff: app/addons/databases/routes.js ---
    @@ -46,43 +41,37 @@ function (app, FauxtonAPI, Databases, Views, Components) {
           this.databases = new Databases.List();
         },
     
    -    allDatabases: function () {
    -      var params = app.getParams(),
    -          dbPage = params.page ? parseInt(params.page, 10) : 1,
    -          perPage = FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE,
    -          pagination;
    -
    -      pagination = new Components.Pagination({
    -        page: dbPage,
    -        perPage: perPage,
    -        collection: this.databases,
    -        urlFun: function (page) {
    -          return '#/_all_dbs?page=' + page;
    -        }
    -      });
    -
    -      this.footer = this.setView('#footer', new Views.Footer());
    -      this.setView('#database-pagination', pagination);
    -
    -      this.databasesView = this.setView("#dashboard-content", new Views.List({
    -        collection: this.databases,
    -        perPage: perPage,
    -        page: dbPage
    -      }));
    -
    -      this.rightHeader = this.setView("#right-header", new Views.RightAllDBsHeader({
    -        collection: this.databases,
    -      }));
    +    paginated: function () {
    --- End diff --
    
    I think this paginated could go into the collection.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---