couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gar...@apache.org
Subject [19/27] fauxton commit: updated refs/heads/master to 0ca35da
Date Tue, 31 May 2016 07:58:47 GMT
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/documents/changes/components.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/documents/changes/components.react.jsx b/app/addons/documents/changes/components.react.jsx
index 9c6f90e..4836125 100644
--- a/app/addons/documents/changes/components.react.jsx
+++ b/app/addons/documents/changes/components.react.jsx
@@ -10,450 +10,445 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-define([
-  '../../../app',
-  '../../../core/api',
-  'react',
-  'react-dom',
-  './actions',
-  './stores',
-  '../../fauxton/components.react',
-  '../../components/react-components.react',
-
-  'react-addons-css-transition-group',
-  '../../../../assets/js/plugins/prettify',
-], function (app, FauxtonAPI, React, ReactDOM, Actions, Stores, Components, ReactComponents, ReactCSSTransitionGroup) {
-
-  var changesStore = Stores.changesStore;
-
-  var BadgeList = ReactComponents.BadgeList;
-
-  // the top-level component for the Changes Filter section. Handles hiding/showing of the filters form
-  var ChangesHeaderController = React.createClass({
-    getInitialState: function () {
-      return this.getStoreState();
-    },
-
-    getStoreState: function () {
-      return {
-        showTabContent: changesStore.isTabVisible()
-      };
-    },
-
-    onChange: function () {
-      this.setState(this.getStoreState());
-    },
-
-    componentDidMount: function () {
-      changesStore.on('change', this.onChange, this);
-    },
-
-    componentWillUnmount: function () {
-      changesStore.off('change', this.onChange);
-    },
-
-    toggleFilterSection: function () {
-      Actions.toggleTabVisibility();
-    },
-
-    render: function () {
-      var tabContent = '';
-      if (this.state.showTabContent) {
-        tabContent = <ChangesTabContent key="changesFilterSection" />;
-      }
-
-      return (
-        <div className="changes-header-section">
-          <ChangesHeaderTab onToggle={this.toggleFilterSection} />
-          <ReactCSSTransitionGroup transitionName="toggle-changes-filter" component="div" className="changes-tab-content"
-             transitionEnterTimeout={500} transitionLeaveTimeout={300}>
-            {tabContent}
-          </ReactCSSTransitionGroup>
-        </div>
-      );
-    }
-  });
-
-
-  var ChangesHeaderTab = React.createClass({
-    propTypes: {
-      onToggle: React.PropTypes.func.isRequired
-    },
-
-    render: function () {
-      return (
-        <div className="dashboard-upper-menu">
-          <ul className="nav nav-tabs" id="db-views-tabs-nav">
-            <li>
-              <a href="#filter" onClick={this.props.onToggle} data-bypass="true" data-toggle="tab">
-                <i className="fonticon fonticon-plus"></i> Filter
-              </a>
-            </li>
-          </ul>
-        </div>
-      );
+import app from "../../../app";
+import FauxtonAPI from "../../../core/api";
+import React from "react";
+import ReactDOM from "react-dom";
+import Actions from "./actions";
+import Stores from "./stores";
+import Components from "../../fauxton/components.react";
+import ReactComponents from "../../components/react-components.react";
+import ReactCSSTransitionGroup from "react-addons-css-transition-group";
+import "../../../../assets/js/plugins/prettify";
+
+var changesStore = Stores.changesStore;
+
+var BadgeList = ReactComponents.BadgeList;
+
+// the top-level component for the Changes Filter section. Handles hiding/showing of the filters form
+var ChangesHeaderController = React.createClass({
+  getInitialState: function () {
+    return this.getStoreState();
+  },
+
+  getStoreState: function () {
+    return {
+      showTabContent: changesStore.isTabVisible()
+    };
+  },
+
+  onChange: function () {
+    this.setState(this.getStoreState());
+  },
+
+  componentDidMount: function () {
+    changesStore.on('change', this.onChange, this);
+  },
+
+  componentWillUnmount: function () {
+    changesStore.off('change', this.onChange);
+  },
+
+  toggleFilterSection: function () {
+    Actions.toggleTabVisibility();
+  },
+
+  render: function () {
+    var tabContent = '';
+    if (this.state.showTabContent) {
+      tabContent = <ChangesTabContent key="changesFilterSection" />;
     }
-  });
 
+    return (
+      <div className="changes-header-section">
+        <ChangesHeaderTab onToggle={this.toggleFilterSection} />
+        <ReactCSSTransitionGroup transitionName="toggle-changes-filter" component="div" className="changes-tab-content"
+           transitionEnterTimeout={500} transitionLeaveTimeout={300}>
+          {tabContent}
+        </ReactCSSTransitionGroup>
+      </div>
+    );
+  }
+});
 
-  var ChangesTabContent = React.createClass({
-    getStoreState: function () {
-      return {
-        filters: changesStore.getFilters(),
-        pollingEnabled: changesStore.pollingEnabled()
-      };
-    },
 
-    onChange: function () {
-      this.setState(this.getStoreState());
-    },
+var ChangesHeaderTab = React.createClass({
+  propTypes: {
+    onToggle: React.PropTypes.func.isRequired
+  },
+
+  render: function () {
+    return (
+      <div className="dashboard-upper-menu">
+        <ul className="nav nav-tabs" id="db-views-tabs-nav">
+          <li>
+            <a href="#filter" onClick={this.props.onToggle} data-bypass="true" data-toggle="tab">
+              <i className="fonticon fonticon-plus"></i> Filter
+            </a>
+          </li>
+        </ul>
+      </div>
+    );
+  }
+});
 
-    componentDidMount: function () {
-      changesStore.on('change', this.onChange, this);
-    },
 
-    componentWillUnmount: function () {
-      changesStore.off('change', this.onChange);
-    },
+var ChangesTabContent = React.createClass({
+  getStoreState: function () {
+    return {
+      filters: changesStore.getFilters(),
+      pollingEnabled: changesStore.pollingEnabled()
+    };
+  },
 
-    getInitialState: function () {
-      return this.getStoreState();
-    },
+  onChange: function () {
+    this.setState(this.getStoreState());
+  },
 
-    removeFilter: function (label) {
-      Actions.removeFilter(label);
-    },
+  componentDidMount: function () {
+    changesStore.on('change', this.onChange, this);
+  },
 
-    addFilter: function (newFilter) {
-      if (_.isEmpty(newFilter)) {
-        return;
-      }
-      Actions.addFilter(newFilter);
-    },
+  componentWillUnmount: function () {
+    changesStore.off('change', this.onChange);
+  },
 
-    hasFilter: function (filter) {
-      return changesStore.hasFilter(filter);
-    },
+  getInitialState: function () {
+    return this.getStoreState();
+  },
 
-    togglePolling: function () {
-      Actions.togglePolling();
-    },
+  removeFilter: function (label) {
+    Actions.removeFilter(label);
+  },
 
-    render: function () {
-      return (
-        <div className="tab-content">
-          <div className="tab-pane active" ref="filterTab">
-            <div className="changes-header js-filter">
-              <div className="changes-polling">
-                <input
-                  type="checkbox"
-                  id="changes-toggle-polling"
-                  checked={this.state.pollingEnabled}
-                  onChange={this.togglePolling}
-                />
-                <label htmlFor="changes-toggle-polling">Auto-update changes list</label>
-              </div>
-              <AddFilterForm tooltip={this.props.tooltip} filter={this.state.filter} addFilter={this.addFilter}
-                hasFilter={this.hasFilter} />
-              <BadgeList elements={this.state.filters} removeBadge={this.removeFilter} />
-            </div>
-            <div className="changes-auto-update">
+  addFilter: function (newFilter) {
+    if (_.isEmpty(newFilter)) {
+      return;
+    }
+    Actions.addFilter(newFilter);
+  },
+
+  hasFilter: function (filter) {
+    return changesStore.hasFilter(filter);
+  },
+
+  togglePolling: function () {
+    Actions.togglePolling();
+  },
+
+  render: function () {
+    return (
+      <div className="tab-content">
+        <div className="tab-pane active" ref="filterTab">
+          <div className="changes-header js-filter">
+            <div className="changes-polling">
+              <input
+                type="checkbox"
+                id="changes-toggle-polling"
+                checked={this.state.pollingEnabled}
+                onChange={this.togglePolling}
+              />
+              <label htmlFor="changes-toggle-polling">Auto-update changes list</label>
             </div>
+            <AddFilterForm tooltip={this.props.tooltip} filter={this.state.filter} addFilter={this.addFilter}
+              hasFilter={this.hasFilter} />
+            <BadgeList elements={this.state.filters} removeBadge={this.removeFilter} />
+          </div>
+          <div className="changes-auto-update">
           </div>
         </div>
-      );
+      </div>
+    );
+  }
+});
+
+
+var AddFilterForm = React.createClass({
+  propTypes: {
+    addFilter: React.PropTypes.func.isRequired,
+    hasFilter: React.PropTypes.func.isRequired
+  },
+
+  getInitialState: function () {
+    return {
+      filter: '',
+      error: false
+    };
+  },
+
+  getDefaultProps: function () {
+    return {
+      tooltip: ''
+    };
+  },
+
+  submitForm: function (e) {
+    e.preventDefault();
+    e.stopPropagation();
+
+    if (this.props.hasFilter(this.state.filter)) {
+      this.setState({ error: true });
+
+      // Yuck. This removes the class after the effect has completed so it can occur again. The
+      // other option is to use jQuery to add the flash. This seemed slightly less crumby
+      var component = this;
+      setTimeout(function () {
+        component.setState({ error: false });
+      }, 1000);
+    } else {
+      this.props.addFilter(this.state.filter);
+      this.setState({ filter: '', error: false });
     }
-  });
-
-
-  var AddFilterForm = React.createClass({
-    propTypes: {
-      addFilter: React.PropTypes.func.isRequired,
-      hasFilter: React.PropTypes.func.isRequired
-    },
-
-    getInitialState: function () {
-      return {
-        filter: '',
-        error: false
-      };
-    },
-
-    getDefaultProps: function () {
-      return {
-        tooltip: ''
-      };
-    },
-
-    submitForm: function (e) {
-      e.preventDefault();
-      e.stopPropagation();
-
-      if (this.props.hasFilter(this.state.filter)) {
-        this.setState({ error: true });
-
-        // Yuck. This removes the class after the effect has completed so it can occur again. The
-        // other option is to use jQuery to add the flash. This seemed slightly less crumby
-        var component = this;
-        setTimeout(function () {
-          component.setState({ error: false });
-        }, 1000);
-      } else {
-        this.props.addFilter(this.state.filter);
-        this.setState({ filter: '', error: false });
-      }
-    },
-
-    componentDidMount: function () {
-      this.focusFilterField();
-    },
-
-    componentDidUpdate: function () {
-      this.focusFilterField();
-    },
-
-    focusFilterField: function () {
-      ReactDOM.findDOMNode(this.refs.addItem).focus();
-    },
-
-    onChangeFilter: function (e) {
-      this.setState({ filter: e.target.value });
-    },
-
-    inputClassNames: function () {
-      var className = 'js-changes-filter-field';
-      if (this.state.error) {
-        className += ' errorHighlight';
-      }
-      return className;
-    },
-
-    render: function () {
-      return (
-        <form className="form-inline js-filter-form" onSubmit={this.submitForm}>
-          <fieldset>
-            <input type="text" ref="addItem" className={this.inputClassNames()} placeholder="Type a filter"
-              onChange={this.onChangeFilter} value={this.state.filter} />
-            <button type="submit" className="btn btn-primary">Filter</button>
-            <div className="help-block">
-              <strong ref="helpText">e.g. _design or document ID</strong>
-              {' '}
-              <FilterTooltip tooltip={this.props.tooltip} />
-            </div>
-          </fieldset>
-        </form>
-      );
+  },
+
+  componentDidMount: function () {
+    this.focusFilterField();
+  },
+
+  componentDidUpdate: function () {
+    this.focusFilterField();
+  },
+
+  focusFilterField: function () {
+    ReactDOM.findDOMNode(this.refs.addItem).focus();
+  },
+
+  onChangeFilter: function (e) {
+    this.setState({ filter: e.target.value });
+  },
+
+  inputClassNames: function () {
+    var className = 'js-changes-filter-field';
+    if (this.state.error) {
+      className += ' errorHighlight';
     }
-  });
+    return className;
+  },
+
+  render: function () {
+    return (
+      <form className="form-inline js-filter-form" onSubmit={this.submitForm}>
+        <fieldset>
+          <input type="text" ref="addItem" className={this.inputClassNames()} placeholder="Type a filter"
+            onChange={this.onChangeFilter} value={this.state.filter} />
+          <button type="submit" className="btn btn-primary">Filter</button>
+          <div className="help-block">
+            <strong ref="helpText">e.g. _design or document ID</strong>
+            {' '}
+            <FilterTooltip tooltip={this.props.tooltip} />
+          </div>
+        </fieldset>
+      </form>
+    );
+  }
+});
 
 
-  var FilterTooltip = React.createClass({
-    componentDidMount: function () {
-      if (this.props.tooltip) {
-        $(ReactDOM.findDOMNode(this.refs.tooltip)).tooltip();
-      }
-    },
+var FilterTooltip = React.createClass({
+  componentDidMount: function () {
+    if (this.props.tooltip) {
+      $(ReactDOM.findDOMNode(this.refs.tooltip)).tooltip();
+    }
+  },
 
-    render: function () {
-      if (!this.props.tooltip) {
-        return false;
-      }
-      return (
-        <i ref="tooltip" className="icon icon-question-sign js-filter-tooltip" data-toggle="tooltip"
-          data-original-title={this.props.tooltip}></i>
-      );
+  render: function () {
+    if (!this.props.tooltip) {
+      return false;
     }
-  });
-
-  var ChangesController = React.createClass({
-    getInitialState: function () {
-      return this.getStoreState();
-    },
-
-    getStoreState: function () {
-      return {
-        changes: changesStore.getChanges(),
-        loaded: changesStore.isLoaded(),
-        databaseName: changesStore.getDatabaseName(),
-        isShowingSubset: changesStore.isShowingSubset()
-      };
-    },
-
-    onChange: function () {
-      this.setState(this.getStoreState());
-    },
-
-    componentDidMount: function () {
-      changesStore.on('change', this.onChange, this);
-    },
-
-    componentWillUnmount: function () {
-      changesStore.off('change', this.onChange);
-    },
-
-    showingSubsetMsg: function () {
-      var msg = '';
-      if (this.state.isShowingSubset) {
-        var numChanges = this.state.changes.length;
-        msg = <p className="changes-result-limit">Limiting results to latest <b>{numChanges}</b> changes.</p>;
-      }
-      return msg;
-    },
-
-    getRows: function () {
-      if (!this.state.changes.length && this.state.loaded) {
-        return (
-          <p>
-            No document changes have occurred in this database.
-          </p>
-        );
-      }
-
-      return _.map(this.state.changes, function (change) {
-        var key = change.id + '-' + change.seq;
-        return <ChangeRow change={change} key={key} databaseName={this.state.databaseName} />;
-      }, this);
-    },
-
-    render: function () {
+    return (
+      <i ref="tooltip" className="icon icon-question-sign js-filter-tooltip" data-toggle="tooltip"
+        data-original-title={this.props.tooltip}></i>
+    );
+  }
+});
+
+var ChangesController = React.createClass({
+  getInitialState: function () {
+    return this.getStoreState();
+  },
+
+  getStoreState: function () {
+    return {
+      changes: changesStore.getChanges(),
+      loaded: changesStore.isLoaded(),
+      databaseName: changesStore.getDatabaseName(),
+      isShowingSubset: changesStore.isShowingSubset()
+    };
+  },
+
+  onChange: function () {
+    this.setState(this.getStoreState());
+  },
+
+  componentDidMount: function () {
+    changesStore.on('change', this.onChange, this);
+  },
+
+  componentWillUnmount: function () {
+    changesStore.off('change', this.onChange);
+  },
+
+  showingSubsetMsg: function () {
+    var msg = '';
+    if (this.state.isShowingSubset) {
+      var numChanges = this.state.changes.length;
+      msg = <p className="changes-result-limit">Limiting results to latest <b>{numChanges}</b> changes.</p>;
+    }
+    return msg;
+  },
+
+  getRows: function () {
+    if (!this.state.changes.length && this.state.loaded) {
       return (
-        <div className="js-changes-view">
-          {this.showingSubsetMsg()}
-          {this.getRows()}
-        </div>
+        <p>
+          No document changes have occurred in this database.
+        </p>
       );
     }
-  });
-
-
-  var ChangeRow = React.createClass({
-    propTypes: function () {
-      return {
-        change: React.PropTypes.object,
-        databaseName: React.PropTypes.string.isRequired
-      };
-    },
-
-    getInitialState: function () {
-      return {
-        codeVisible: false
-      };
-    },
-
-    toggleJSON: function (e) {
-      e.preventDefault();
-      this.setState({ codeVisible: !this.state.codeVisible });
-    },
-
-    getChangesCode: function () {
-      var json = '';
-      if (this.state.codeVisible) {
-        json = <Components.CodeFormat key="changesCodeSection" code={this.getChangeCode()} />;
-      }
-      return json;
-    },
-
-    getChangeCode: function () {
-      return {
-        changes: this.props.change.changes,
-        doc: this.props.change.doc
-      };
-    },
-
-    onClipboardClick: function (target) {
-      var msg = 'The document ID has been copied to your clipboard.';
-      if (target === 'seq') {
-        msg = 'The document seq number has been copied to your clipboard.';
-      }
-      FauxtonAPI.addNotification({
-        msg: msg,
-        type: 'info',
-        clear: true
-      });
-    },
-
-    render: function () {
-      var jsonBtnClasses = 'btn btn-small' + (this.state.codeVisible ? ' btn-secondary' : ' btn-primary');
-      var wrapperClass = 'change-wrapper' + (this.props.change.isNew ? ' new-change-row' : '');
 
-      return (
-        <div className={wrapperClass}>
-          <div className="change-box" data-id={this.props.change.id}>
-            <div className="row-fluid">
-              <div className="span2">seq</div>
-              <div className="span8 change-sequence">{this.props.change.seq}</div>
-              <div className="span2 text-right">
-                <Components.Clipboard text={this.props.change.seq} onClipboardClick={() => this.onClipboardClick('seq')} />
-              </div>
+    return _.map(this.state.changes, function (change) {
+      var key = change.id + '-' + change.seq;
+      return <ChangeRow change={change} key={key} databaseName={this.state.databaseName} />;
+    }, this);
+  },
+
+  render: function () {
+    return (
+      <div className="js-changes-view">
+        {this.showingSubsetMsg()}
+        {this.getRows()}
+      </div>
+    );
+  }
+});
+
+
+var ChangeRow = React.createClass({
+  propTypes: function () {
+    return {
+      change: React.PropTypes.object,
+      databaseName: React.PropTypes.string.isRequired
+    };
+  },
+
+  getInitialState: function () {
+    return {
+      codeVisible: false
+    };
+  },
+
+  toggleJSON: function (e) {
+    e.preventDefault();
+    this.setState({ codeVisible: !this.state.codeVisible });
+  },
+
+  getChangesCode: function () {
+    var json = '';
+    if (this.state.codeVisible) {
+      json = <Components.CodeFormat key="changesCodeSection" code={this.getChangeCode()} />;
+    }
+    return json;
+  },
+
+  getChangeCode: function () {
+    return {
+      changes: this.props.change.changes,
+      doc: this.props.change.doc
+    };
+  },
+
+  onClipboardClick: function (target) {
+    var msg = 'The document ID has been copied to your clipboard.';
+    if (target === 'seq') {
+      msg = 'The document seq number has been copied to your clipboard.';
+    }
+    FauxtonAPI.addNotification({
+      msg: msg,
+      type: 'info',
+      clear: true
+    });
+  },
+
+  render: function () {
+    var jsonBtnClasses = 'btn btn-small' + (this.state.codeVisible ? ' btn-secondary' : ' btn-primary');
+    var wrapperClass = 'change-wrapper' + (this.props.change.isNew ? ' new-change-row' : '');
+
+    return (
+      <div className={wrapperClass}>
+        <div className="change-box" data-id={this.props.change.id}>
+          <div className="row-fluid">
+            <div className="span2">seq</div>
+            <div className="span8 change-sequence">{this.props.change.seq}</div>
+            <div className="span2 text-right">
+              <Components.Clipboard text={this.props.change.seq} onClipboardClick={() => this.onClipboardClick('seq')} />
             </div>
+          </div>
 
-            <div className="row-fluid">
-              <div className="span2">id</div>
-              <div className="span8">
-                <ChangeID id={this.props.change.id} deleted={this.props.change.deleted} databaseName={this.props.databaseName} />
-              </div>
-              <div className="span2 text-right">
-                <Components.Clipboard text={this.props.change.id} onClipboardClick={() => this.onClipboardClick('id')} />
-              </div>
+          <div className="row-fluid">
+            <div className="span2">id</div>
+            <div className="span8">
+              <ChangeID id={this.props.change.id} deleted={this.props.change.deleted} databaseName={this.props.databaseName} />
             </div>
+            <div className="span2 text-right">
+              <Components.Clipboard text={this.props.change.id} onClipboardClick={() => this.onClipboardClick('id')} />
+            </div>
+          </div>
 
-            <div className="row-fluid">
-              <div className="span2">changes</div>
-              <div className="span10">
-                <button type="button" className={jsonBtnClasses} onClick={this.toggleJSON}>
-                  {this.state.codeVisible ? 'Close JSON' : 'View JSON'}
-                </button>
-              </div>
+          <div className="row-fluid">
+            <div className="span2">changes</div>
+            <div className="span10">
+              <button type="button" className={jsonBtnClasses} onClick={this.toggleJSON}>
+                {this.state.codeVisible ? 'Close JSON' : 'View JSON'}
+              </button>
             </div>
+          </div>
 
-            <ReactCSSTransitionGroup transitionName="toggle-changes-code" component="div" className="changesCodeSectionWrapper"
-              transitionEnterTimeout={500} transitionLeaveTimeout={300}>
-              {this.getChangesCode()}
-            </ReactCSSTransitionGroup>
+          <ReactCSSTransitionGroup transitionName="toggle-changes-code" component="div" className="changesCodeSectionWrapper"
+            transitionEnterTimeout={500} transitionLeaveTimeout={300}>
+            {this.getChangesCode()}
+          </ReactCSSTransitionGroup>
 
-            <div className="row-fluid">
-              <div className="span2">deleted</div>
-              <div className="span10">{this.props.change.deleted ? 'True' : 'False'}</div>
-            </div>
+          <div className="row-fluid">
+            <div className="span2">deleted</div>
+            <div className="span10">{this.props.change.deleted ? 'True' : 'False'}</div>
           </div>
         </div>
+      </div>
+    );
+  }
+});
+
+
+var ChangeID = React.createClass({
+  render: function () {
+    if (this.props.deleted) {
+      return (
+        <span className="js-doc-id">{this.props.id}</span>
+      );
+    } else {
+      var link = '#' + FauxtonAPI.urls('document', 'app', this.props.databaseName, this.props.id);
+      return (
+        <a href={link} className="js-doc-link">{this.props.id}</a>
       );
     }
-  });
-
-
-  var ChangeID = React.createClass({
-    render: function () {
-      if (this.props.deleted) {
-        return (
-          <span className="js-doc-id">{this.props.id}</span>
-        );
-      } else {
-        var link = '#' + FauxtonAPI.urls('document', 'app', this.props.databaseName, this.props.id);
-        return (
-          <a href={link} className="js-doc-link">{this.props.id}</a>
-        );
-      }
-    }
-  });
-
-
-  return {
-    renderHeader: function (el) {
-      ReactDOM.render(<ChangesHeaderController />, el);
-    },
-    renderChanges: function (el) {
-      ReactDOM.render(<ChangesController />, el);
-    },
-    remove: function (el) {
-      ReactDOM.unmountComponentAtNode(el);
-    },
-
-    ChangesHeaderController: ChangesHeaderController,
-    ChangesHeaderTab: ChangesHeaderTab,
-    ChangesTabContent: ChangesTabContent,
-    ChangesController: ChangesController,
-    ChangeRow: ChangeRow
-  };
-
+  }
 });
+
+
+export default {
+  renderHeader: function (el) {
+    ReactDOM.render(<ChangesHeaderController />, el);
+  },
+  renderChanges: function (el) {
+    ReactDOM.render(<ChangesController />, el);
+  },
+  remove: function (el) {
+    ReactDOM.unmountComponentAtNode(el);
+  },
+
+  ChangesHeaderController: ChangesHeaderController,
+  ChangesHeaderTab: ChangesHeaderTab,
+  ChangesTabContent: ChangesTabContent,
+  ChangesController: ChangesController,
+  ChangeRow: ChangeRow
+};

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/documents/changes/stores.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/changes/stores.js b/app/addons/documents/changes/stores.js
index 4730ed9..2f64cb2 100644
--- a/app/addons/documents/changes/stores.js
+++ b/app/addons/documents/changes/stores.js
@@ -10,179 +10,176 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-define([
-  '../../../core/api',
-  './actiontypes',
-  '../helpers'
-], function (FauxtonAPI, ActionTypes, Helpers) {
-
-
-  var ChangesStore = FauxtonAPI.Store.extend({
-    initialize: function () {
-      this.reset();
-    },
-
-    reset: function () {
-      this._isLoaded = false;
-      this._tabVisible = false;
-      this._filters = [];
-      this._changes = [];
-      this._databaseName = '';
-      this._maxChangesListed = 100;
-      this._showingSubset = false;
-      this._pollingEnabled = false;
-      this._lastSequenceNum = null;
-    },
-
-    initChanges: function (options) {
-      this.reset();
-      this._databaseName = options.databaseName;
-    },
-
-    isLoaded: function () {
-      return this._isLoaded;
-    },
-
-    updateChanges: function (seqNum, changes) {
-
-      // make a note of the most recent sequence number. This is used for a point of reference for polling for new changes
-      this._lastSequenceNum = seqNum;
-
-      // mark any additional changes that come after first page load as "new" so we can add a nice highlight effect
-      // when the new row is rendered
-      var firstBatch = this._changes.length === 0;
-      _.each(this._changes, function (change) {
-        change.isNew = false;
-      });
-
-      var newChanges = _.map(changes, function (change) {
-        var seq = Helpers.getSeqNum(change.seq);
-        return {
-          id: change.id,
-          seq: seq,
-          deleted: _.has(change, 'deleted') ? change.deleted : false,
-          changes: change.changes,
-          doc: change.doc, // only populated with ?include_docs=true
-          isNew: !firstBatch
-        };
+import FauxtonAPI from "../../../core/api";
+import ActionTypes from "./actiontypes";
+import Helpers from "../helpers";
+
+
+var ChangesStore = FauxtonAPI.Store.extend({
+  initialize: function () {
+    this.reset();
+  },
+
+  reset: function () {
+    this._isLoaded = false;
+    this._tabVisible = false;
+    this._filters = [];
+    this._changes = [];
+    this._databaseName = '';
+    this._maxChangesListed = 100;
+    this._showingSubset = false;
+    this._pollingEnabled = false;
+    this._lastSequenceNum = null;
+  },
+
+  initChanges: function (options) {
+    this.reset();
+    this._databaseName = options.databaseName;
+  },
+
+  isLoaded: function () {
+    return this._isLoaded;
+  },
+
+  updateChanges: function (seqNum, changes) {
+
+    // make a note of the most recent sequence number. This is used for a point of reference for polling for new changes
+    this._lastSequenceNum = seqNum;
+
+    // mark any additional changes that come after first page load as "new" so we can add a nice highlight effect
+    // when the new row is rendered
+    var firstBatch = this._changes.length === 0;
+    _.each(this._changes, function (change) {
+      change.isNew = false;
+    });
+
+    var newChanges = _.map(changes, function (change) {
+      var seq = Helpers.getSeqNum(change.seq);
+      return {
+        id: change.id,
+        seq: seq,
+        deleted: _.has(change, 'deleted') ? change.deleted : false,
+        changes: change.changes,
+        doc: change.doc, // only populated with ?include_docs=true
+        isNew: !firstBatch
+      };
+    });
+
+    // add the new changes to the start of the list
+    this._changes = newChanges.concat(this._changes);
+    this._isLoaded = true;
+  },
+
+  getChanges: function () {
+    this._showingSubset = false;
+    var numMatches = 0;
+
+    return _.filter(this._changes, function (change) {
+      if (numMatches >= this._maxChangesListed) {
+        this._showingSubset = true;
+        return false;
+      }
+      var changeStr = JSON.stringify(change);
+      var match = _.every(this._filters, function (filter) {
+        return new RegExp(filter, 'i').test(changeStr);
       });
 
-      // add the new changes to the start of the list
-      this._changes = newChanges.concat(this._changes);
-      this._isLoaded = true;
-    },
-
-    getChanges: function () {
-      this._showingSubset = false;
-      var numMatches = 0;
-
-      return _.filter(this._changes, function (change) {
-        if (numMatches >= this._maxChangesListed) {
-          this._showingSubset = true;
-          return false;
-        }
-        var changeStr = JSON.stringify(change);
-        var match = _.every(this._filters, function (filter) {
-          return new RegExp(filter, 'i').test(changeStr);
-        });
-
-        if (match) {
-          numMatches++;
-        }
-        return match;
-      }, this);
-    },
-
-    toggleTabVisibility: function () {
-      this._tabVisible = !this._tabVisible;
-    },
-
-    isTabVisible: function () {
-      return this._tabVisible;
-    },
-
-    addFilter: function (filter) {
-      this._filters.push(filter);
-    },
-
-    removeFilter: function (filter) {
-      this._filters = _.without(this._filters, filter);
-    },
-
-    getFilters: function () {
-      return this._filters;
-    },
-
-    hasFilter: function (filter) {
-      return _.contains(this._filters, filter);
-    },
-
-    getDatabaseName: function () {
-      return this._databaseName;
-    },
-
-    isShowingSubset: function () {
-      return this._showingSubset;
-    },
-
-    // added to speed up the tests
-    setMaxChanges: function (num) {
-      this._maxChangesListed = num;
-    },
-
-    togglePolling: function () {
-      this._pollingEnabled = !this._pollingEnabled;
-
-      // if polling was just enabled, reset the last sequence num to 'now' so only future changes will appear
-      this._lastSequenceNum = 'now';
-    },
-
-    pollingEnabled: function () {
-      return this._pollingEnabled;
-    },
-
-    getLastSeqNum: function () {
-      return this._lastSequenceNum;
-    },
-
-    dispatch: function (action) {
-      switch (action.type) {
-        case ActionTypes.INIT_CHANGES:
-          this.initChanges(action.options);
-        break;
-
-        case ActionTypes.UPDATE_CHANGES:
-          this.updateChanges(action.seqNum, action.changes);
-        break;
-
-        case ActionTypes.TOGGLE_CHANGES_TAB_VISIBILITY:
-          this.toggleTabVisibility();
-        break;
-
-        case ActionTypes.ADD_CHANGES_FILTER_ITEM:
-          this.addFilter(action.filter);
-        break;
-
-        case ActionTypes.REMOVE_CHANGES_FILTER_ITEM:
-          this.removeFilter(action.filter);
-        break;
-
-        case ActionTypes.TOGGLE_CHANGES_POLLING:
-          this.togglePolling();
-        break;
-
-        default:
-          return;
+      if (match) {
+        numMatches++;
       }
-
-      this.triggerChange();
+      return match;
+    }, this);
+  },
+
+  toggleTabVisibility: function () {
+    this._tabVisible = !this._tabVisible;
+  },
+
+  isTabVisible: function () {
+    return this._tabVisible;
+  },
+
+  addFilter: function (filter) {
+    this._filters.push(filter);
+  },
+
+  removeFilter: function (filter) {
+    this._filters = _.without(this._filters, filter);
+  },
+
+  getFilters: function () {
+    return this._filters;
+  },
+
+  hasFilter: function (filter) {
+    return _.contains(this._filters, filter);
+  },
+
+  getDatabaseName: function () {
+    return this._databaseName;
+  },
+
+  isShowingSubset: function () {
+    return this._showingSubset;
+  },
+
+  // added to speed up the tests
+  setMaxChanges: function (num) {
+    this._maxChangesListed = num;
+  },
+
+  togglePolling: function () {
+    this._pollingEnabled = !this._pollingEnabled;
+
+    // if polling was just enabled, reset the last sequence num to 'now' so only future changes will appear
+    this._lastSequenceNum = 'now';
+  },
+
+  pollingEnabled: function () {
+    return this._pollingEnabled;
+  },
+
+  getLastSeqNum: function () {
+    return this._lastSequenceNum;
+  },
+
+  dispatch: function (action) {
+    switch (action.type) {
+      case ActionTypes.INIT_CHANGES:
+        this.initChanges(action.options);
+      break;
+
+      case ActionTypes.UPDATE_CHANGES:
+        this.updateChanges(action.seqNum, action.changes);
+      break;
+
+      case ActionTypes.TOGGLE_CHANGES_TAB_VISIBILITY:
+        this.toggleTabVisibility();
+      break;
+
+      case ActionTypes.ADD_CHANGES_FILTER_ITEM:
+        this.addFilter(action.filter);
+      break;
+
+      case ActionTypes.REMOVE_CHANGES_FILTER_ITEM:
+        this.removeFilter(action.filter);
+      break;
+
+      case ActionTypes.TOGGLE_CHANGES_POLLING:
+        this.togglePolling();
+      break;
+
+      default:
+        return;
     }
-  });
 
+    this.triggerChange();
+  }
+});
 
-  var Stores = {};
-  Stores.changesStore = new ChangesStore();
-  Stores.changesStore.dispatchToken = FauxtonAPI.dispatcher.register(Stores.changesStore.dispatch);
 
-  return Stores;
-});
+var Stores = {};
+Stores.changesStore = new ChangesStore();
+Stores.changesStore.dispatchToken = FauxtonAPI.dispatcher.register(Stores.changesStore.dispatch);
+
+export default Stores;

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/documents/changes/tests/changes.componentsSpec.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/documents/changes/tests/changes.componentsSpec.react.jsx b/app/addons/documents/changes/tests/changes.componentsSpec.react.jsx
index b77e262..9179b4a 100644
--- a/app/addons/documents/changes/tests/changes.componentsSpec.react.jsx
+++ b/app/addons/documents/changes/tests/changes.componentsSpec.react.jsx
@@ -10,370 +10,366 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-define([
-  '../../../../app',
-  '../../../../core/api',
-  'react',
-  'react-dom',
-  '../components.react',
-  '../stores',
-  '../actions',
-  '../../../../../test/mocha/testUtils',
-  'react-addons-test-utils',
-  'sinon'
-], function (app, FauxtonAPI, React, ReactDOM, Changes, Stores, Actions, utils, TestUtils, sinon) {
-
-  var assert = utils.assert;
-
-  describe('ChangesHeader', function () {
-    var container, tab, spy;
-
-    describe('Testing DOM', function () {
-      beforeEach(function () {
-        spy = sinon.spy(Actions, 'toggleTabVisibility');
-        container = document.createElement('div');
-        tab = TestUtils.renderIntoDocument(<Changes.ChangesHeaderController />, container);
-      });
-
-      afterEach(function () {
-        spy.restore();
-        Stores.changesStore.reset();
-        ReactDOM.unmountComponentAtNode(container);
-      });
-
-      // similar as previous, except it confirms that the action gets fired, not the custom toggle func
-      it('calls toggleTabVisibility action on selecting a tab', function () {
-        TestUtils.Simulate.click($(ReactDOM.findDOMNode(tab)).find('a')[0]);
-        assert.ok(spy.calledOnce);
-      });
-    });
-  });
-
-  describe('ChangesHeaderTab', function () {
-    var container, tab, toggleTabVisibility;
-
+import app from "../../../../app";
+import FauxtonAPI from "../../../../core/api";
+import React from "react";
+import ReactDOM from "react-dom";
+import Changes from "../components.react";
+import Stores from "../stores";
+import Actions from "../actions";
+import utils from "../../../../../test/mocha/testUtils";
+import TestUtils from "react-addons-test-utils";
+import sinon from "sinon";
+
+var assert = utils.assert;
+
+describe('ChangesHeader', function () {
+  var container, tab, spy;
+
+  describe('Testing DOM', function () {
     beforeEach(function () {
-      toggleTabVisibility = sinon.spy();
+      spy = sinon.spy(Actions, 'toggleTabVisibility');
       container = document.createElement('div');
-      tab = TestUtils.renderIntoDocument(<Changes.ChangesHeaderTab onToggle={toggleTabVisibility} />, container);
+      tab = TestUtils.renderIntoDocument(<Changes.ChangesHeaderController />, container);
     });
 
     afterEach(function () {
+      spy.restore();
       Stores.changesStore.reset();
       ReactDOM.unmountComponentAtNode(container);
     });
 
-    it('should call toggle function on clicking tab', function () {
+    // similar as previous, except it confirms that the action gets fired, not the custom toggle func
+    it('calls toggleTabVisibility action on selecting a tab', function () {
       TestUtils.Simulate.click($(ReactDOM.findDOMNode(tab)).find('a')[0]);
-      assert.ok(toggleTabVisibility.calledOnce);
+      assert.ok(spy.calledOnce);
     });
   });
+});
 
+describe('ChangesHeaderTab', function () {
+  var container, tab, toggleTabVisibility;
 
-  describe('ChangesTabContent', function () {
-    var container, changesFilterEl;
+  beforeEach(function () {
+    toggleTabVisibility = sinon.spy();
+    container = document.createElement('div');
+    tab = TestUtils.renderIntoDocument(<Changes.ChangesHeaderTab onToggle={toggleTabVisibility} />, container);
+  });
 
-    beforeEach(function () {
-      container = document.createElement('div');
-      changesFilterEl = TestUtils.renderIntoDocument(<Changes.ChangesTabContent />, container);
-    });
+  afterEach(function () {
+    Stores.changesStore.reset();
+    ReactDOM.unmountComponentAtNode(container);
+  });
 
-    afterEach(function () {
-      Stores.changesStore.reset();
-      ReactDOM.unmountComponentAtNode(container);
-    });
+  it('should call toggle function on clicking tab', function () {
+    TestUtils.Simulate.click($(ReactDOM.findDOMNode(tab)).find('a')[0]);
+    assert.ok(toggleTabVisibility.calledOnce);
+  });
+});
 
-    it('should add filter markup', function () {
-      var $el = $(ReactDOM.findDOMNode(changesFilterEl)),
-          submitBtn = $el.find('[type="submit"]')[0],
-          addItemField = $el.find('.js-changes-filter-field')[0];
 
-      addItemField.value = 'I wandered lonely as a filter';
-      TestUtils.Simulate.change(addItemField);
-      TestUtils.Simulate.submit(submitBtn);
+describe('ChangesTabContent', function () {
+  var container, changesFilterEl;
 
-      addItemField.value = 'A second filter';
-      TestUtils.Simulate.change(addItemField);
-      TestUtils.Simulate.submit(submitBtn);
+  beforeEach(function () {
+    container = document.createElement('div');
+    changesFilterEl = TestUtils.renderIntoDocument(<Changes.ChangesTabContent />, container);
+  });
 
-      assert.equal(2, $el.find('.js-remove-filter').length);
-    });
+  afterEach(function () {
+    Stores.changesStore.reset();
+    ReactDOM.unmountComponentAtNode(container);
+  });
 
-    it('should call addFilter action on click', function () {
-      var $el = $(ReactDOM.findDOMNode(changesFilterEl)),
+  it('should add filter markup', function () {
+    var $el = $(ReactDOM.findDOMNode(changesFilterEl)),
         submitBtn = $el.find('[type="submit"]')[0],
         addItemField = $el.find('.js-changes-filter-field')[0];
 
-      var spy = sinon.spy(Actions, 'addFilter');
+    addItemField.value = 'I wandered lonely as a filter';
+    TestUtils.Simulate.change(addItemField);
+    TestUtils.Simulate.submit(submitBtn);
 
-      addItemField.value = 'I wandered lonely as a filter';
-      TestUtils.Simulate.change(addItemField);
-      TestUtils.Simulate.submit(submitBtn);
+    addItemField.value = 'A second filter';
+    TestUtils.Simulate.change(addItemField);
+    TestUtils.Simulate.submit(submitBtn);
 
-      assert.ok(spy.calledOnce);
-    });
+    assert.equal(2, $el.find('.js-remove-filter').length);
+  });
 
-    it('should remove filter markup', function () {
-      var $el = $(ReactDOM.findDOMNode(changesFilterEl)),
-        submitBtn = $el.find('[type="submit"]')[0],
-        addItemField = $el.find('.js-changes-filter-field')[0];
+  it('should call addFilter action on click', function () {
+    var $el = $(ReactDOM.findDOMNode(changesFilterEl)),
+      submitBtn = $el.find('[type="submit"]')[0],
+      addItemField = $el.find('.js-changes-filter-field')[0];
 
-      addItemField.value = 'Bloop';
-      TestUtils.Simulate.change(addItemField);
-      TestUtils.Simulate.submit(submitBtn);
+    var spy = sinon.spy(Actions, 'addFilter');
 
-      addItemField.value = 'Flibble';
-      TestUtils.Simulate.change(addItemField);
-      TestUtils.Simulate.submit(submitBtn);
+    addItemField.value = 'I wandered lonely as a filter';
+    TestUtils.Simulate.change(addItemField);
+    TestUtils.Simulate.submit(submitBtn);
 
-      // clicks ALL 'remove' elements
-      TestUtils.Simulate.click($el.find('.js-remove-filter')[0]);
-      TestUtils.Simulate.click($el.find('.js-remove-filter')[0]);
+    assert.ok(spy.calledOnce);
+  });
 
-      assert.equal(0, $el.find('.js-remove-filter').length);
-    });
+  it('should remove filter markup', function () {
+    var $el = $(ReactDOM.findDOMNode(changesFilterEl)),
+      submitBtn = $el.find('[type="submit"]')[0],
+      addItemField = $el.find('.js-changes-filter-field')[0];
 
-    it('should call removeFilter action on click', function () {
-      var $el = $(ReactDOM.findDOMNode(changesFilterEl)),
-        submitBtn = $el.find('[type="submit"]')[0],
-        addItemField = $el.find('.js-changes-filter-field')[0];
+    addItemField.value = 'Bloop';
+    TestUtils.Simulate.change(addItemField);
+    TestUtils.Simulate.submit(submitBtn);
 
-      var spy = sinon.spy(Actions, 'removeFilter');
+    addItemField.value = 'Flibble';
+    TestUtils.Simulate.change(addItemField);
+    TestUtils.Simulate.submit(submitBtn);
 
-      addItemField.value = 'I wandered lonely as a filter';
-      TestUtils.Simulate.change(addItemField);
-      TestUtils.Simulate.submit(submitBtn);
-      TestUtils.Simulate.click($el.find('.js-remove-filter')[0]);
+    // clicks ALL 'remove' elements
+    TestUtils.Simulate.click($el.find('.js-remove-filter')[0]);
+    TestUtils.Simulate.click($el.find('.js-remove-filter')[0]);
 
-      assert.ok(spy.calledOnce);
-    });
+    assert.equal(0, $el.find('.js-remove-filter').length);
+  });
 
-    it('should not add empty filters', function () {
-      var $el = $(ReactDOM.findDOMNode(changesFilterEl)),
-        submitBtn = $el.find('[type="submit"]')[0],
-        addItemField = $el.find('.js-changes-filter-field')[0];
+  it('should call removeFilter action on click', function () {
+    var $el = $(ReactDOM.findDOMNode(changesFilterEl)),
+      submitBtn = $el.find('[type="submit"]')[0],
+      addItemField = $el.find('.js-changes-filter-field')[0];
 
-      addItemField.value = '';
-      TestUtils.Simulate.change(addItemField);
-      TestUtils.Simulate.submit(submitBtn);
+    var spy = sinon.spy(Actions, 'removeFilter');
 
-      assert.equal(0, $el.find('.js-remove-filter').length);
-    });
+    addItemField.value = 'I wandered lonely as a filter';
+    TestUtils.Simulate.change(addItemField);
+    TestUtils.Simulate.submit(submitBtn);
+    TestUtils.Simulate.click($el.find('.js-remove-filter')[0]);
 
-    it('should not add tooltips by default', function () {
-      assert.equal(0, $(ReactDOM.findDOMNode(changesFilterEl)).find('.js-remove-filter').length);
-    });
+    assert.ok(spy.calledOnce);
+  });
 
-    it('should not add the same filter twice', function () {
-      var $el = $(ReactDOM.findDOMNode(changesFilterEl)),
-          submitBtn = $el.find('[type="submit"]')[0],
-          addItemField = $el.find('.js-changes-filter-field')[0];
+  it('should not add empty filters', function () {
+    var $el = $(ReactDOM.findDOMNode(changesFilterEl)),
+      submitBtn = $el.find('[type="submit"]')[0],
+      addItemField = $el.find('.js-changes-filter-field')[0];
 
-      var filter = 'I am unique in the whole wide world';
-      addItemField.value = filter;
-      TestUtils.Simulate.change(addItemField);
-      TestUtils.Simulate.submit(submitBtn);
+    addItemField.value = '';
+    TestUtils.Simulate.change(addItemField);
+    TestUtils.Simulate.submit(submitBtn);
 
-      addItemField.value = filter;
-      TestUtils.Simulate.change(addItemField);
-      TestUtils.Simulate.submit(submitBtn);
+    assert.equal(0, $el.find('.js-remove-filter').length);
+  });
 
-      assert.equal(1, $el.find('.js-remove-filter').length);
-    });
+  it('should not add tooltips by default', function () {
+    assert.equal(0, $(ReactDOM.findDOMNode(changesFilterEl)).find('.js-remove-filter').length);
   });
 
+  it('should not add the same filter twice', function () {
+    var $el = $(ReactDOM.findDOMNode(changesFilterEl)),
+        submitBtn = $el.find('[type="submit"]')[0],
+        addItemField = $el.find('.js-changes-filter-field')[0];
 
-  // tests Changes Controller; includes tests in conjunction with ChangesHeaderController
-  describe('ChangesController', function () {
-    var container, container2, headerEl, $headerEl, changesEl, $changesEl;
-
-    var results = [
-      { id: 'doc_1', seq: 4, deleted: false, changes: { code: 'here' } },
-      { id: 'doc_2', seq: 1, deleted: false, changes: { code: 'here' } },
-      { id: 'doc_3', seq: 6, deleted: true, changes: { code: 'here' } },
-      { id: 'doc_4', seq: 7, deleted: false, changes: { code: 'here' } },
-      { id: 'doc_5', seq: 1, deleted: true, changes: { code: 'here' } }
-    ];
-    var changesResponse = {
-      last_seq: 123,
-      'results': results
-    };
+    var filter = 'I am unique in the whole wide world';
+    addItemField.value = filter;
+    TestUtils.Simulate.change(addItemField);
+    TestUtils.Simulate.submit(submitBtn);
 
-    beforeEach(function () {
-      container = document.createElement('div');
-      container2 = document.createElement('div');
-      Actions.initChanges({ databaseName: 'testDatabase' });
-      headerEl  = TestUtils.renderIntoDocument(<Changes.ChangesHeaderController />, container);
-      $headerEl = $(ReactDOM.findDOMNode(headerEl));
-      changesEl = TestUtils.renderIntoDocument(<Changes.ChangesController />, container2);
-      $changesEl = $(ReactDOM.findDOMNode(changesEl));
-      Actions.updateChanges(changesResponse);
-    });
+    addItemField.value = filter;
+    TestUtils.Simulate.change(addItemField);
+    TestUtils.Simulate.submit(submitBtn);
 
-    afterEach(function () {
-      Stores.changesStore.reset();
-      ReactDOM.unmountComponentAtNode(container);
-      ReactDOM.unmountComponentAtNode(container2);
-    });
+    assert.equal(1, $el.find('.js-remove-filter').length);
+  });
+});
 
 
-    it('should list the right number of changes', function () {
-      assert.equal(results.length, $changesEl.find('.change-box').length);
-    });
+// tests Changes Controller; includes tests in conjunction with ChangesHeaderController
+describe('ChangesController', function () {
+  var container, container2, headerEl, $headerEl, changesEl, $changesEl;
+
+  var results = [
+    { id: 'doc_1', seq: 4, deleted: false, changes: { code: 'here' } },
+    { id: 'doc_2', seq: 1, deleted: false, changes: { code: 'here' } },
+    { id: 'doc_3', seq: 6, deleted: true, changes: { code: 'here' } },
+    { id: 'doc_4', seq: 7, deleted: false, changes: { code: 'here' } },
+    { id: 'doc_5', seq: 1, deleted: true, changes: { code: 'here' } }
+  ];
+  var changesResponse = {
+    last_seq: 123,
+    'results': results
+  };
+
+  beforeEach(function () {
+    container = document.createElement('div');
+    container2 = document.createElement('div');
+    Actions.initChanges({ databaseName: 'testDatabase' });
+    headerEl  = TestUtils.renderIntoDocument(<Changes.ChangesHeaderController />, container);
+    $headerEl = $(ReactDOM.findDOMNode(headerEl));
+    changesEl = TestUtils.renderIntoDocument(<Changes.ChangesController />, container2);
+    $changesEl = $(ReactDOM.findDOMNode(changesEl));
+    Actions.updateChanges(changesResponse);
+  });
 
+  afterEach(function () {
+    Stores.changesStore.reset();
+    ReactDOM.unmountComponentAtNode(container);
+    ReactDOM.unmountComponentAtNode(container2);
+  });
 
-    it('"false"/"true" filter strings should apply to change deleted status', function () {
-      // expand the header
-      TestUtils.Simulate.click($headerEl.find('a')[0]);
 
-      // add a filter
-      var addItemField = $headerEl.find('.js-changes-filter-field')[0];
-      var submitBtn = $headerEl.find('[type="submit"]')[0];
-      addItemField.value = 'true';
-      TestUtils.Simulate.change(addItemField);
-      TestUtils.Simulate.submit(submitBtn);
+  it('should list the right number of changes', function () {
+    assert.equal(results.length, $changesEl.find('.change-box').length);
+  });
 
-      // confirm only the two deleted items shows up and the IDs maps to the deleted rows
-      assert.equal(2, $changesEl.find('.change-box').length);
-      assert.equal('doc_3', $($changesEl.find('.js-doc-id').get(0)).html());
-      assert.equal('doc_5', $($changesEl.find('.js-doc-id').get(1)).html());
-    });
 
+  it('"false"/"true" filter strings should apply to change deleted status', function () {
+    // expand the header
+    TestUtils.Simulate.click($headerEl.find('a')[0]);
 
-    it('confirms that a filter affects the actual search results', function () {
-      // expand the header
-      TestUtils.Simulate.click($headerEl.find('a')[0]);
+    // add a filter
+    var addItemField = $headerEl.find('.js-changes-filter-field')[0];
+    var submitBtn = $headerEl.find('[type="submit"]')[0];
+    addItemField.value = 'true';
+    TestUtils.Simulate.change(addItemField);
+    TestUtils.Simulate.submit(submitBtn);
 
-      // add a filter
-      var addItemField = $headerEl.find('.js-changes-filter-field')[0];
-      var submitBtn = $headerEl.find('[type="submit"]')[0];
-      addItemField.value = '6'; // should match doc_3's sequence ID
-      TestUtils.Simulate.change(addItemField);
-      TestUtils.Simulate.submit(submitBtn);
+    // confirm only the two deleted items shows up and the IDs maps to the deleted rows
+    assert.equal(2, $changesEl.find('.change-box').length);
+    assert.equal('doc_3', $($changesEl.find('.js-doc-id').get(0)).html());
+    assert.equal('doc_5', $($changesEl.find('.js-doc-id').get(1)).html());
+  });
 
-      // confirm only one item shows up and the ID maps to what we'd expect
-      assert.equal(1, $changesEl.find('.change-box').length);
-      assert.equal('doc_3', $($changesEl.find('.js-doc-id').get(0)).html());
-    });
 
+  it('confirms that a filter affects the actual search results', function () {
+    // expand the header
+    TestUtils.Simulate.click($headerEl.find('a')[0]);
 
-    // confirms that if there are multiple filters, ALL are applied to return the subset of results that match
-    // all filters
-    it('multiple filters should all be applied to results', function () {
-      TestUtils.Simulate.click($headerEl.find('a')[0]);
+    // add a filter
+    var addItemField = $headerEl.find('.js-changes-filter-field')[0];
+    var submitBtn = $headerEl.find('[type="submit"]')[0];
+    addItemField.value = '6'; // should match doc_3's sequence ID
+    TestUtils.Simulate.change(addItemField);
+    TestUtils.Simulate.submit(submitBtn);
 
-      // add the filters
-      var addItemField = $headerEl.find('.js-changes-filter-field')[0];
-      var submitBtn = $headerEl.find('[type="submit"]')[0];
+    // confirm only one item shows up and the ID maps to what we'd expect
+    assert.equal(1, $changesEl.find('.change-box').length);
+    assert.equal('doc_3', $($changesEl.find('.js-doc-id').get(0)).html());
+  });
 
-      // *** should match doc_1, doc_2 and doc_5
-      addItemField.value = '1';
-      TestUtils.Simulate.change(addItemField);
-      TestUtils.Simulate.submit(submitBtn);
 
-      // *** should match doc_3 and doc_5
-      addItemField.value = 'true';
-      TestUtils.Simulate.change(addItemField);
-      TestUtils.Simulate.submit(submitBtn);
+  // confirms that if there are multiple filters, ALL are applied to return the subset of results that match
+  // all filters
+  it('multiple filters should all be applied to results', function () {
+    TestUtils.Simulate.click($headerEl.find('a')[0]);
 
-      // confirm only one item shows up and that it's doc_5
-      assert.equal(1, $changesEl.find('.change-box').length);
-      assert.equal('doc_5', $($changesEl.find('.js-doc-id').get(0)).html());
-    });
+    // add the filters
+    var addItemField = $headerEl.find('.js-changes-filter-field')[0];
+    var submitBtn = $headerEl.find('[type="submit"]')[0];
 
-    it('shows a No Docs Found message if no docs', function () {
-      Stores.changesStore.reset();
-      Actions.updateChanges({ last_seq: 124, results: [] });
-      assert.ok(/No\sdocument\schanges\shave\soccurred/.test($changesEl[0].outerHTML));
-    });
+    // *** should match doc_1, doc_2 and doc_5
+    addItemField.value = '1';
+    TestUtils.Simulate.change(addItemField);
+    TestUtils.Simulate.submit(submitBtn);
+
+    // *** should match doc_3 and doc_5
+    addItemField.value = 'true';
+    TestUtils.Simulate.change(addItemField);
+    TestUtils.Simulate.submit(submitBtn);
 
+    // confirm only one item shows up and that it's doc_5
+    assert.equal(1, $changesEl.find('.change-box').length);
+    assert.equal('doc_5', $($changesEl.find('.js-doc-id').get(0)).html());
   });
 
+  it('shows a No Docs Found message if no docs', function () {
+    Stores.changesStore.reset();
+    Actions.updateChanges({ last_seq: 124, results: [] });
+    assert.ok(/No\sdocument\schanges\shave\soccurred/.test($changesEl[0].outerHTML));
+  });
 
-  describe('ChangesController max results', function () {
-    var changesEl;
-    var container;
-    var maxChanges = 10;
+});
 
 
-    beforeEach(function () {
-      container = document.createElement('div');
-      var changes = [];
-      _.times(maxChanges + 10, function (i) {
-        changes.push({ id: 'doc_' + i, seq: 1, changes: { code: 'here' } });
-      });
+describe('ChangesController max results', function () {
+  var changesEl;
+  var container;
+  var maxChanges = 10;
 
-      var response = {
-        last_seq: 1,
-        results: changes
-      };
 
-      Actions.initChanges({ databaseName: 'test' });
+  beforeEach(function () {
+    container = document.createElement('div');
+    var changes = [];
+    _.times(maxChanges + 10, function (i) {
+      changes.push({ id: 'doc_' + i, seq: 1, changes: { code: 'here' } });
+    });
 
-      // to keep the test speedy, override the default value (1000)
-      Stores.changesStore.setMaxChanges(maxChanges);
+    var response = {
+      last_seq: 1,
+      results: changes
+    };
 
-      Actions.updateChanges(response);
-      changesEl = TestUtils.renderIntoDocument(<Changes.ChangesController />, container);
-    });
+    Actions.initChanges({ databaseName: 'test' });
 
-    afterEach(function () {
-      Stores.changesStore.reset();
-      ReactDOM.unmountComponentAtNode(container);
-    });
+    // to keep the test speedy, override the default value (1000)
+    Stores.changesStore.setMaxChanges(maxChanges);
 
-    it('should truncate the number of results with very large # of changes', function () {
-      // check there's no more than maxChanges results
-      assert.equal(maxChanges, $(ReactDOM.findDOMNode(changesEl)).find('.change-box').length);
-    });
+    Actions.updateChanges(response);
+    changesEl = TestUtils.renderIntoDocument(<Changes.ChangesController />, container);
+  });
 
-    it('should show a message if the results are truncated', function () {
-      assert.equal(1, $(ReactDOM.findDOMNode(changesEl)).find('.changes-result-limit').length);
-    });
+  afterEach(function () {
+    Stores.changesStore.reset();
+    ReactDOM.unmountComponentAtNode(container);
+  });
 
+  it('should truncate the number of results with very large # of changes', function () {
+    // check there's no more than maxChanges results
+    assert.equal(maxChanges, $(ReactDOM.findDOMNode(changesEl)).find('.change-box').length);
   });
 
+  it('should show a message if the results are truncated', function () {
+    assert.equal(1, $(ReactDOM.findDOMNode(changesEl)).find('.changes-result-limit').length);
+  });
 
-  describe('ChangeRow', function () {
-    var container;
-    var change = {
-      id: '123',
-      seq: 5,
-      deleted: false,
-      changes: { code: 'here' }
-    };
+});
 
-    beforeEach(function () {
-      container = document.createElement('div');
-    });
 
-    afterEach(function () {
-      ReactDOM.unmountComponentAtNode(container);
-    });
+describe('ChangeRow', function () {
+  var container;
+  var change = {
+    id: '123',
+    seq: 5,
+    deleted: false,
+    changes: { code: 'here' }
+  };
 
+  beforeEach(function () {
+    container = document.createElement('div');
+  });
 
-    it('clicking the toggle-json button shows the code section', function () {
-      var changeRow = TestUtils.renderIntoDocument(<Changes.ChangeRow change={change} databaseName="testDatabase" />, container);
+  afterEach(function () {
+    ReactDOM.unmountComponentAtNode(container);
+  });
 
-      // confirm it's hidden by default
-      assert.equal(0, $(ReactDOM.findDOMNode(changeRow)).find('.prettyprint').length);
 
-      // confirm clicking it shows the element
-      TestUtils.Simulate.click($(ReactDOM.findDOMNode(changeRow)).find('button.btn')[0]);
-      assert.equal(1, $(ReactDOM.findDOMNode(changeRow)).find('.prettyprint').length);
-    });
+  it('clicking the toggle-json button shows the code section', function () {
+    var changeRow = TestUtils.renderIntoDocument(<Changes.ChangeRow change={change} databaseName="testDatabase" />, container);
 
-    it('deleted docs should not be clickable', function () {
-      change.deleted = true;
-      var changeRow = TestUtils.renderIntoDocument(<Changes.ChangeRow change={change} databaseName="testDatabase" />, container);
-      assert.equal(0, $(ReactDOM.findDOMNode(changeRow)).find('a.js-doc-link').length);
-    });
+    // confirm it's hidden by default
+    assert.equal(0, $(ReactDOM.findDOMNode(changeRow)).find('.prettyprint').length);
 
-    it('non-deleted docs should be clickable', function () {
-      change.deleted = false;
-      var changeRow = TestUtils.renderIntoDocument(<Changes.ChangeRow change={change} databaseName="testDatabase" />, container);
-      assert.equal(1, $(ReactDOM.findDOMNode(changeRow)).find('a.js-doc-link').length);
-    });
+    // confirm clicking it shows the element
+    TestUtils.Simulate.click($(ReactDOM.findDOMNode(changeRow)).find('button.btn')[0]);
+    assert.equal(1, $(ReactDOM.findDOMNode(changeRow)).find('.prettyprint').length);
   });
 
+  it('deleted docs should not be clickable', function () {
+    change.deleted = true;
+    var changeRow = TestUtils.renderIntoDocument(<Changes.ChangeRow change={change} databaseName="testDatabase" />, container);
+    assert.equal(0, $(ReactDOM.findDOMNode(changeRow)).find('a.js-doc-link').length);
+  });
+
+  it('non-deleted docs should be clickable', function () {
+    change.deleted = false;
+    var changeRow = TestUtils.renderIntoDocument(<Changes.ChangeRow change={change} databaseName="testDatabase" />, container);
+    assert.equal(1, $(ReactDOM.findDOMNode(changeRow)).find('a.js-doc-link').length);
+  });
 });

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/documents/changes/tests/changes.storesSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/changes/tests/changes.storesSpec.js b/app/addons/documents/changes/tests/changes.storesSpec.js
index f571c7b..2daeb33 100644
--- a/app/addons/documents/changes/tests/changes.storesSpec.js
+++ b/app/addons/documents/changes/tests/changes.storesSpec.js
@@ -10,98 +10,94 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-define([
-  '../../../../app',
-  '../../../../core/api',
-  '../stores',
-  '../../../../../test/mocha/testUtils',
-], function (app, FauxtonAPI, Stores, utils) {
-  FauxtonAPI.router = new FauxtonAPI.Router([]);
+import app from "../../../../app";
+import FauxtonAPI from "../../../../core/api";
+import Stores from "../stores";
+import utils from "../../../../../test/mocha/testUtils";
+FauxtonAPI.router = new FauxtonAPI.Router([]);
 
-  var assert = utils.assert;
+var assert = utils.assert;
 
 
-  describe('ChangesStore', function () {
+describe('ChangesStore', function () {
 
-    afterEach(function () {
-      Stores.changesStore.reset();
-    });
-
-    it('toggleTabVisibility() changes state in store', function () {
-      assert.ok(Stores.changesStore.isTabVisible() === false);
-      Stores.changesStore.toggleTabVisibility();
-      assert.ok(Stores.changesStore.isTabVisible() === true);
-    });
-
-    it('reset() changes tab visibility to hidden', function () {
-      Stores.changesStore.toggleTabVisibility();
-      Stores.changesStore.reset();
-      assert.ok(Stores.changesStore.isTabVisible() === false);
-    });
+  afterEach(function () {
+    Stores.changesStore.reset();
+  });
 
-    it('addFilter() adds item in store', function () {
-      var filter = 'My filter';
-      Stores.changesStore.addFilter(filter);
-      var filters = Stores.changesStore.getFilters();
-      assert.ok(filters.length === 1);
-      assert.ok(filters[0] === filter);
-    });
+  it('toggleTabVisibility() changes state in store', function () {
+    assert.ok(Stores.changesStore.isTabVisible() === false);
+    Stores.changesStore.toggleTabVisibility();
+    assert.ok(Stores.changesStore.isTabVisible() === true);
+  });
 
-    it('removeFilter() removes item from store', function () {
-      var filter1 = 'My filter 1';
-      var filter2 = 'My filter 2';
-      Stores.changesStore.addFilter(filter1);
-      Stores.changesStore.addFilter(filter2);
-      Stores.changesStore.removeFilter(filter1);
+  it('reset() changes tab visibility to hidden', function () {
+    Stores.changesStore.toggleTabVisibility();
+    Stores.changesStore.reset();
+    assert.ok(Stores.changesStore.isTabVisible() === false);
+  });
 
-      var filters = Stores.changesStore.getFilters();
-      assert.ok(filters.length === 1);
-      assert.ok(filters[0] === filter2);
-    });
+  it('addFilter() adds item in store', function () {
+    var filter = 'My filter';
+    Stores.changesStore.addFilter(filter);
+    var filters = Stores.changesStore.getFilters();
+    assert.ok(filters.length === 1);
+    assert.ok(filters[0] === filter);
+  });
 
-    it('hasFilter() finds item in store', function () {
-      var filter = 'My filter';
-      Stores.changesStore.addFilter(filter);
-      assert.ok(Stores.changesStore.hasFilter(filter) === true);
-    });
+  it('removeFilter() removes item from store', function () {
+    var filter1 = 'My filter 1';
+    var filter2 = 'My filter 2';
+    Stores.changesStore.addFilter(filter1);
+    Stores.changesStore.addFilter(filter2);
+    Stores.changesStore.removeFilter(filter1);
 
-    it('getDatabaseName() returns database name', function () {
-      var dbName = 'hoopoes';
-      Stores.changesStore.initChanges({ databaseName: dbName });
-      assert.equal(Stores.changesStore.getDatabaseName(), dbName);
+    var filters = Stores.changesStore.getFilters();
+    assert.ok(filters.length === 1);
+    assert.ok(filters[0] === filter2);
+  });
 
-      Stores.changesStore.reset();
-      assert.equal(Stores.changesStore.getDatabaseName(), '');
-    });
+  it('hasFilter() finds item in store', function () {
+    var filter = 'My filter';
+    Stores.changesStore.addFilter(filter);
+    assert.ok(Stores.changesStore.hasFilter(filter) === true);
+  });
 
-    it("getChanges() should return a subset if there are a lot of changes", function () {
+  it('getDatabaseName() returns database name', function () {
+    var dbName = 'hoopoes';
+    Stores.changesStore.initChanges({ databaseName: dbName });
+    assert.equal(Stores.changesStore.getDatabaseName(), dbName);
 
-      // to keep the test speedy, we override the default max value
-      var maxChanges = 10;
-      var changes = [];
-      _.times(maxChanges + 10, function (i) {
-        changes.push({ id: 'doc_' + i, seq: 1, changes: {}});
-      });
-      Stores.changesStore.initChanges({ databaseName: "test" });
-      Stores.changesStore.setMaxChanges(maxChanges);
+    Stores.changesStore.reset();
+    assert.equal(Stores.changesStore.getDatabaseName(), '');
+  });
 
-      var seqNum = 123;
-      Stores.changesStore.updateChanges(seqNum, changes);
+  it("getChanges() should return a subset if there are a lot of changes", function () {
 
-      var results = Stores.changesStore.getChanges();
-      assert.equal(maxChanges, results.length);
+    // to keep the test speedy, we override the default max value
+    var maxChanges = 10;
+    var changes = [];
+    _.times(maxChanges + 10, function (i) {
+      changes.push({ id: 'doc_' + i, seq: 1, changes: {}});
     });
+    Stores.changesStore.initChanges({ databaseName: "test" });
+    Stores.changesStore.setMaxChanges(maxChanges);
+
+    var seqNum = 123;
+    Stores.changesStore.updateChanges(seqNum, changes);
 
-    it("tracks last sequence number", function () {
-      assert.equal(null, Stores.changesStore.getLastSeqNum());
+    var results = Stores.changesStore.getChanges();
+    assert.equal(maxChanges, results.length);
+  });
 
-      var seqNum = 123;
-      Stores.changesStore.updateChanges(seqNum, []);
+  it("tracks last sequence number", function () {
+    assert.equal(null, Stores.changesStore.getLastSeqNum());
 
-      // confirm it's been stored
-      assert.equal(seqNum, Stores.changesStore.getLastSeqNum());
-    });
+    var seqNum = 123;
+    Stores.changesStore.updateChanges(seqNum, []);
 
+    // confirm it's been stored
+    assert.equal(seqNum, Stores.changesStore.getLastSeqNum());
   });
 
 });

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/documents/designdocinfo/actions.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/designdocinfo/actions.js b/app/addons/documents/designdocinfo/actions.js
index 655c38e..7e6ec4a 100644
--- a/app/addons/documents/designdocinfo/actions.js
+++ b/app/addons/documents/designdocinfo/actions.js
@@ -10,51 +10,47 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-define([
-  '../../../app',
-  '../../../core/api',
-  './actiontypes',
-  './stores'
-],
-function (app, FauxtonAPI, ActionTypes, Stores) {
-  var store = Stores.designDocInfoStore;
-
-  return {
-    fetchDesignDocInfo: function (options) {
-      var designDocInfo = options.designDocInfo;
-
-      FauxtonAPI.dispatch({
-        type: ActionTypes.DESIGN_FETCHING
+import app from "../../../app";
+import FauxtonAPI from "../../../core/api";
+import ActionTypes from "./actiontypes";
+import Stores from "./stores";
+var store = Stores.designDocInfoStore;
+
+export default {
+  fetchDesignDocInfo: function (options) {
+    var designDocInfo = options.designDocInfo;
+
+    FauxtonAPI.dispatch({
+      type: ActionTypes.DESIGN_FETCHING
+    });
+
+    designDocInfo.fetch().then(function () {
+      this.monitorDesignDoc({
+        ddocName: options.ddocName,
+        designDocInfo: designDocInfo
       });
 
-      designDocInfo.fetch().then(function () {
-        this.monitorDesignDoc({
-          ddocName: options.ddocName,
-          designDocInfo: designDocInfo
-        });
+    }.bind(this));
 
-      }.bind(this));
+  },
 
-    },
+  monitorDesignDoc: function (options) {
+    options.intervalId = window.setInterval(_.bind(this.refresh, this), 5000);
+    FauxtonAPI.dispatch({
+      type: ActionTypes.DESIGN_DOC_MONITOR,
+      options: options
+    });
+  },
 
-    monitorDesignDoc: function (options) {
-      options.intervalId = window.setInterval(_.bind(this.refresh, this), 5000);
+  refresh: function () {
+    store.getDesignDocInfo().fetch().then(function () {
       FauxtonAPI.dispatch({
-        type: ActionTypes.DESIGN_DOC_MONITOR,
-        options: options
-      });
-    },
-
-    refresh: function () {
-      store.getDesignDocInfo().fetch().then(function () {
-        FauxtonAPI.dispatch({
-          type: ActionTypes.DESIGN_REFRESH
-        });
+        type: ActionTypes.DESIGN_REFRESH
       });
-    },
+    });
+  },
 
-    stopRefresh: function () {
-      window.clearInterval(store.getIntervalId());
-    }
-  };
-});
+  stopRefresh: function () {
+    window.clearInterval(store.getIntervalId());
+  }
+};

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/documents/designdocinfo/actiontypes.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/designdocinfo/actiontypes.js b/app/addons/documents/designdocinfo/actiontypes.js
index d93a8fa..063072e 100644
--- a/app/addons/documents/designdocinfo/actiontypes.js
+++ b/app/addons/documents/designdocinfo/actiontypes.js
@@ -10,10 +10,8 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-define([], function () {
-  return {
-    DESIGN_DOC_MONITOR: 'DESIGN_DOC_MONITOR',
-    DESIGN_FETCHING: 'DESIGN_FETCHING',
-    DESIGN_REFRESH: 'DESIGN_REFRESH'
-  };
-});
+export default {
+  DESIGN_DOC_MONITOR: 'DESIGN_DOC_MONITOR',
+  DESIGN_FETCHING: 'DESIGN_FETCHING',
+  DESIGN_REFRESH: 'DESIGN_REFRESH'
+};

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/documents/designdocinfo/components.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/documents/designdocinfo/components.react.jsx b/app/addons/documents/designdocinfo/components.react.jsx
index c877dc4..a6909e8 100644
--- a/app/addons/documents/designdocinfo/components.react.jsx
+++ b/app/addons/documents/designdocinfo/components.react.jsx
@@ -10,146 +10,140 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-define([
-  '../../../app',
-  '../../../core/api',
-  'react',
-  './stores',
-  './actions',
-  '../../components/react-components.react',
-  '../../fauxton/components.react'
-],
-
-function (app, FauxtonAPI, React, Stores, Actions, ReactComponents, GeneralComponents) {
-  var designDocInfoStore = Stores.designDocInfoStore;
-  var LoadLines = ReactComponents.LoadLines;
-  var Clipboard = GeneralComponents.Clipboard;
-
-
-  var DesignDocInfo = React.createClass({
-    getStoreState: function () {
-      return {
-        viewIndex: designDocInfoStore.getViewIndex(),
-        isLoading: designDocInfoStore.isLoading(),
-        ddocName: designDocInfoStore.getDdocName()
-      };
-    },
-
-    getInitialState: function () {
-      return this.getStoreState();
-    },
-
-    componentDidMount: function () {
-      designDocInfoStore.on('change', this.onChange, this);
-    },
-
-    componentWillUnmount: function () {
-      designDocInfoStore.off('change', this.onChange);
-      Actions.stopRefresh();
-    },
-
-    onChange: function () {
-      this.setState(this.getStoreState());
-    },
-
-    showCopiedMessage: function () {
-      FauxtonAPI.addNotification({
-        type: 'success',
-        msg: 'The MD5 sha has been copied to your clipboard.',
-        clear: true
-      });
-    },
-
-    render: function () {
-      var getDocUrl = app.helpers.getDocUrl;
-      var viewIndex = this.state.viewIndex;
-
-      if (this.state.isLoading) {
-        return <LoadLines />;
-      }
-
-      var actualSize = (viewIndex.data_size) ? viewIndex.data_size.toLocaleString('en') : 0;
-      var dataSize = (viewIndex.disk_size) ? viewIndex.disk_size.toLocaleString('en') : 0;
-
-      return (
-        <div className="metadata-page">
-          <header>
-            <div className="preheading">Design Document Metadata</div>
-            <h2>_design/{this.state.ddocName}</h2>
-
-            <p className="help">
-              Information about the specified design document, including the index, index size and current status of the
-              design document and associated index information.
-              <a href={getDocUrl('DESIGN_DOC_METADATA')} className="help-link" target="_blank" data-bypass="true">
-                <i className="icon-question-sign" />
-              </a>
-            </p>
-          </header>
-
-          <section className="container">
-            <h3>Index Information</h3>
-
-            <ul>
-              <li>
-                <span className="item-title">Language:</span>
-                <span className="capitalize">{viewIndex.language}</span>
-              </li>
-              <li>
-                <span className="item-title">Currently being updated?</span>
-                {viewIndex.updater_running ? 'Yes' : 'No'}
-              </li>
-              <li>
-                <span className="item-title">Currently running compaction?</span>
-                {viewIndex.compact_running ? 'Yes' : 'No'}
-              </li>
-              <li>
-                <span className="item-title">Waiting for a commit?</span>
-                {viewIndex.waiting_commit ? 'Yes' : 'No'}
-              </li>
-            </ul>
-
-            <ul>
-              <li>
-                <span className="item-title">Clients waiting for the index:</span>
-                {viewIndex.waiting_clients}
-              </li>
-              <li>
-                <span className="item-title">Update sequence on DB:</span>
-                {viewIndex.update_seq}
-              </li>
-              <li>
-                <span className="item-title">Processed purge sequence:</span>
-                {viewIndex.purge_seq}
-              </li>
-              <li>
-                <span className="item-title">Actual data size (bytes):</span>
-                {actualSize}
-              </li>
-              <li>
-                <span className="item-title">Data size on disk (bytes):</span>
-                {dataSize}
-              </li>
-            </ul>
-
-            <ul>
-              <li>
-                <span className="item-title">MD5 Signature:</span>
-                <Clipboard
-                  onClipboardClick={this.showCopiedMessage}
-                  text={viewIndex.signature} />
-              </li>
-            </ul>
-
-          </section>
-
-        </div>
-      );
+import app from "../../../app";
+import FauxtonAPI from "../../../core/api";
+import React from "react";
+import Stores from "./stores";
+import Actions from "./actions";
+import ReactComponents from "../../components/react-components.react";
+import GeneralComponents from "../../fauxton/components.react";
+var designDocInfoStore = Stores.designDocInfoStore;
+var LoadLines = ReactComponents.LoadLines;
+var Clipboard = GeneralComponents.Clipboard;
+
+
+var DesignDocInfo = React.createClass({
+  getStoreState: function () {
+    return {
+      viewIndex: designDocInfoStore.getViewIndex(),
+      isLoading: designDocInfoStore.isLoading(),
+      ddocName: designDocInfoStore.getDdocName()
+    };
+  },
+
+  getInitialState: function () {
+    return this.getStoreState();
+  },
+
+  componentDidMount: function () {
+    designDocInfoStore.on('change', this.onChange, this);
+  },
+
+  componentWillUnmount: function () {
+    designDocInfoStore.off('change', this.onChange);
+    Actions.stopRefresh();
+  },
+
+  onChange: function () {
+    this.setState(this.getStoreState());
+  },
+
+  showCopiedMessage: function () {
+    FauxtonAPI.addNotification({
+      type: 'success',
+      msg: 'The MD5 sha has been copied to your clipboard.',
+      clear: true
+    });
+  },
+
+  render: function () {
+    var getDocUrl = app.helpers.getDocUrl;
+    var viewIndex = this.state.viewIndex;
+
+    if (this.state.isLoading) {
+      return <LoadLines />;
     }
-  });
 
+    var actualSize = (viewIndex.data_size) ? viewIndex.data_size.toLocaleString('en') : 0;
+    var dataSize = (viewIndex.disk_size) ? viewIndex.disk_size.toLocaleString('en') : 0;
+
+    return (
+      <div className="metadata-page">
+        <header>
+          <div className="preheading">Design Document Metadata</div>
+          <h2>_design/{this.state.ddocName}</h2>
+
+          <p className="help">
+            Information about the specified design document, including the index, index size and current status of the
+            design document and associated index information.
+            <a href={getDocUrl('DESIGN_DOC_METADATA')} className="help-link" target="_blank" data-bypass="true">
+              <i className="icon-question-sign" />
+            </a>
+          </p>
+        </header>
+
+        <section className="container">
+          <h3>Index Information</h3>
+
+          <ul>
+            <li>
+              <span className="item-title">Language:</span>
+              <span className="capitalize">{viewIndex.language}</span>
+            </li>
+            <li>
+              <span className="item-title">Currently being updated?</span>
+              {viewIndex.updater_running ? 'Yes' : 'No'}
+            </li>
+            <li>
+              <span className="item-title">Currently running compaction?</span>
+              {viewIndex.compact_running ? 'Yes' : 'No'}
+            </li>
+            <li>
+              <span className="item-title">Waiting for a commit?</span>
+              {viewIndex.waiting_commit ? 'Yes' : 'No'}
+            </li>
+          </ul>
+
+          <ul>
+            <li>
+              <span className="item-title">Clients waiting for the index:</span>
+              {viewIndex.waiting_clients}
+            </li>
+            <li>
+              <span className="item-title">Update sequence on DB:</span>
+              {viewIndex.update_seq}
+            </li>
+            <li>
+              <span className="item-title">Processed purge sequence:</span>
+              {viewIndex.purge_seq}
+            </li>
+            <li>
+              <span className="item-title">Actual data size (bytes):</span>
+              {actualSize}
+            </li>
+            <li>
+              <span className="item-title">Data size on disk (bytes):</span>
+              {dataSize}
+            </li>
+          </ul>
+
+          <ul>
+            <li>
+              <span className="item-title">MD5 Signature:</span>
+              <Clipboard
+                onClipboardClick={this.showCopiedMessage}
+                text={viewIndex.signature} />
+            </li>
+          </ul>
+
+        </section>
+
+      </div>
+    );
+  }
+});
 
-  return {
-    DesignDocInfo: DesignDocInfo
-  };
 
-});
+export default {
+  DesignDocInfo: DesignDocInfo
+};

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/documents/designdocinfo/stores.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/designdocinfo/stores.js b/app/addons/documents/designdocinfo/stores.js
index 514bdca..4024229 100644
--- a/app/addons/documents/designdocinfo/stores.js
+++ b/app/addons/documents/designdocinfo/stores.js
@@ -10,78 +10,73 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-define([
-  '../../../core/api',
-  './actiontypes'
-],
-
-function (FauxtonAPI, ActionTypes) {
-  var Stores = {};
-
-  Stores.DesignDocInfoStore = FauxtonAPI.Store.extend({
-
-    initialize: function () {
-      this._isLoading = true;
-    },
-
-    isLoading: function () {
-      return this._isLoading;
-    },
-
-    getDdocName: function () {
-      return this._ddocName;
-    },
-
-    getDesignDocInfo: function () {
-      return this._designDocInfo;
-    },
-
-    monitorDesignDoc: function (options) {
-      this._isLoading = false;
-      this._designDocInfo = options.designDocInfo;
-      this._ddocName = options.ddocName;
-      this._intervalId = options.intervalId;
-    },
-
-    getIntervalId: function () {
-      return this._intervalId;
-    },
-
-    getViewIndex: function () {
-      if (this._isLoading) {
-        return {};
-      }
-
-      return this._designDocInfo.get('view_index');
-    },
-
-    dispatch: function (action) {
-      switch (action.type) {
-        case ActionTypes.DESIGN_FETCHING:
-          this._isLoading = true;
-          this.triggerChange();
-        break;
-
-        case ActionTypes.DESIGN_DOC_MONITOR:
-          this.monitorDesignDoc(action.options);
-          this.triggerChange();
-        break;
-
-        case ActionTypes.DESIGN_DOC_REFRESH:
-          this.triggerChange();
-        break;
-
-        default:
-        return;
-        // do nothing
-      }
+import FauxtonAPI from "../../../core/api";
+import ActionTypes from "./actiontypes";
+var Stores = {};
+
+Stores.DesignDocInfoStore = FauxtonAPI.Store.extend({
+
+  initialize: function () {
+    this._isLoading = true;
+  },
+
+  isLoading: function () {
+    return this._isLoading;
+  },
+
+  getDdocName: function () {
+    return this._ddocName;
+  },
+
+  getDesignDocInfo: function () {
+    return this._designDocInfo;
+  },
+
+  monitorDesignDoc: function (options) {
+    this._isLoading = false;
+    this._designDocInfo = options.designDocInfo;
+    this._ddocName = options.ddocName;
+    this._intervalId = options.intervalId;
+  },
+
+  getIntervalId: function () {
+    return this._intervalId;
+  },
+
+  getViewIndex: function () {
+    if (this._isLoading) {
+      return {};
     }
 
-  });
+    return this._designDocInfo.get('view_index');
+  },
 
-  Stores.designDocInfoStore = new Stores.DesignDocInfoStore();
+  dispatch: function (action) {
+    switch (action.type) {
+      case ActionTypes.DESIGN_FETCHING:
+        this._isLoading = true;
+        this.triggerChange();
+      break;
 
-  Stores.designDocInfoStore.dispatchToken = FauxtonAPI.dispatcher.register(Stores.designDocInfoStore.dispatch);
+      case ActionTypes.DESIGN_DOC_MONITOR:
+        this.monitorDesignDoc(action.options);
+        this.triggerChange();
+      break;
+
+      case ActionTypes.DESIGN_DOC_REFRESH:
+        this.triggerChange();
+      break;
+
+      default:
+      return;
+      // do nothing
+    }
+  }
 
-  return Stores;
 });
+
+Stores.designDocInfoStore = new Stores.DesignDocInfoStore();
+
+Stores.designDocInfoStore.dispatchToken = FauxtonAPI.dispatcher.register(Stores.designDocInfoStore.dispatch);
+
+export default Stores;

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/documents/designdocinfo/tests/actionsSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/designdocinfo/tests/actionsSpec.js b/app/addons/documents/designdocinfo/tests/actionsSpec.js
index 3735e62..ac54353 100644
--- a/app/addons/documents/designdocinfo/tests/actionsSpec.js
+++ b/app/addons/documents/designdocinfo/tests/actionsSpec.js
@@ -10,43 +10,40 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-define([
-  '../../../../core/api',
-  '../actions',
-  '../../../../../test/mocha/testUtils',
-  'sinon'
-], function (FauxtonAPI, Actions, testUtils, sinon) {
-  var assert = testUtils.assert;
-  var restore = testUtils.restore;
+import FauxtonAPI from "../../../../core/api";
+import Actions from "../actions";
+import testUtils from "../../../../../test/mocha/testUtils";
+import sinon from "sinon";
+var assert = testUtils.assert;
+var restore = testUtils.restore;
 
-  describe('DesignDocInfo Actions', function () {
+describe('DesignDocInfo Actions', function () {
 
-    describe('fetchDesignDocInfo', function () {
+  describe('fetchDesignDocInfo', function () {
 
-      afterEach(function () {
-        restore(Actions.monitorDesignDoc);
-      });
-
-      it('calls monitorDesignDoc on successful fetch', function () {
-        var promise = FauxtonAPI.Deferred();
-        promise.resolve();
-        var fakeDesignDocInfo = {
-          fetch: function () {
-            return promise;
-          }
-        };
+    afterEach(function () {
+      restore(Actions.monitorDesignDoc);
+    });
 
-        var spy = sinon.spy(Actions, 'monitorDesignDoc');
+    it('calls monitorDesignDoc on successful fetch', function () {
+      var promise = FauxtonAPI.Deferred();
+      promise.resolve();
+      var fakeDesignDocInfo = {
+        fetch: function () {
+          return promise;
+        }
+      };
 
+      var spy = sinon.spy(Actions, 'monitorDesignDoc');
 
-        Actions.fetchDesignDocInfo({
-          ddocName: 'test-designdoc-info',
-          designDocInfo: fakeDesignDocInfo
-        });
 
-        assert.ok(spy.calledOnce);
+      Actions.fetchDesignDocInfo({
+        ddocName: 'test-designdoc-info',
+        designDocInfo: fakeDesignDocInfo
       });
-    });
 
+      assert.ok(spy.calledOnce);
+    });
   });
+
 });


Mime
View raw message