<commit_before>/** @jsx React.DOM */

define([
  "React",
  "Underscore",
  "jsx!components/AppComponent",
  "mixins/BackboneMixin"
], function(React, _, AppComponent, BackboneMixin) {
  "use strict";

  var STATE_LOADING = 0;
  var STATE_ERROR = 1;
  var STATE_SUCCESS = 2;

  var UPDATE_INTERVAL = 5000;

  return React.createClass({
    displayName: "AppListComponent",
    mixins: [BackboneMixin],

    propTypes: {
      collection: React.PropTypes.object.isRequired,
      deployments: React.PropTypes.object.isRequired,
      onSelectApp: React.PropTypes.func.isRequired
    },

    componentDidMount: function() {
      this.startPolling();
    },

    componentWillUnmount: function() {
      this.stopPolling();
    },

    getInitialState: function() {
      return {
        fetchState: STATE_LOADING
      };
    },

    getResource: function() {
      return this.props.collection;
    },

    fetchResource: function() {
      this.props.collection.fetch({
        error: function() {
          this.setState({fetchState: STATE_ERROR});
        }.bind(this),
        reset: true,
        success: function() {
          this.setState({fetchState: STATE_SUCCESS});
          this.props.deployments.fetch({
            error: function() {
              this.setState({fetchState: STATE_ERROR});
            }.bind(this),
            reset: true
          });
        }.bind(this)
      });
    },

    onClickApp: function(app) {
      this.stopPolling();
      this.props.onSelectApp(app);
    },

    sortCollectionBy: function(comparator) {
      var collection = this.props.collection;
      comparator =
        collection.sortKey === comparator && !collection.sortReverse ?
        "-" + comparator :
        comparator;
      collection.setComparator(comparator);
      collection.sort();
    },

    startPolling: function() {
      if (this._interval == null) {
        this.fetchResource();
        this._interval = setInterval(this.fetchResource, UPDATE_INTERVAL);
      }
    },

    stopPolling: function() {
      if (this._interval != null) {
        clearInterval(this._interval);
        this._interval = null;
      }
    },

    render: function() {
      var sortKey = this.props.collection.sortKey;

      var appNodes;
      var tableClassName = "table table-fixed table-badged";

      var headerClassSet = React.addons.classSet({
        "clickable": true,
        "dropup": this.props.collection.sortReverse
      });

      if (this.state.fetchState === STATE_LOADING) {
        appNodes =
          <tr>
            <td className="text-center text-muted" colSpan="5">
              Loading apps...
            </td>
          </tr>;
      } else if (this.state.fetchState === STATE_ERROR) {
        appNodes =
          <tr>
            <td className="text-center text-danger" colSpan="5">
              Error fetching apps. Refresh to try again.
            </td>
          </tr>;
      } else if (this.props.collection.length === 0) {
        appNodes =
          <tr>
            <td className="text-center" colSpan="5">No running apps.</td>
          </tr>;
      } else {

        /* jshint trailing:false, quotmark:false, newcap:false */
        appNodes = this.props.collection.map(function(model) {
          return <AppComponent key={model.id} model={model} onClick={this.onClickApp} />;
        }, this);

        // Give rows the selectable look when there are apps to click.
        tableClassName += " table-hover table-selectable";
      }

      /* jshint trailing:false, quotmark:false, newcap:false */
      return (
        <table className={tableClassName}>
          <colgroup>
            <col style={{width: "30%"}} />
            <col style={{width: "18%"}} />
            <col style={{width: "18%"}} />
            <col style={{width: "18%"}} />
            <col style={{width: "18%"}} />
          </colgroup>
          <thead>
            <tr>
              <th>
                <span onClick={this.sortCollectionBy.bind(null, "id")} className={headerClassSet}>
                  ID {sortKey === "id" ? <span className="caret"></span> : null}
                </span>
              </th>
              <th className="text-right">
                <span onClick={this.sortCollectionBy.bind(null, "mem")} className={headerClassSet}>
                  {sortKey === "mem" ? <span className="caret"></span> : null} Memory (MB)
                </span>
              </th>
              <th className="text-right">
                <span onClick={this.sortCollectionBy.bind(null, "cpus")} className={headerClassSet}>
                  {sortKey === "cpus" ? <span className="caret"></span> : null} CPUs
                </span>
              </th>
              <th className="text-right">
                <span onClick={this.sortCollectionBy.bind(null, "instances")} className={headerClassSet}>
                  {sortKey === "instances" ? <span className="caret"></span> : null} Tasks / Instances<commit_msg>Balancing columns out<commit_after>/** @jsx React.DOM */

define([
  "React",
  "Underscore",
  "jsx!components/AppComponent",
  "mixins/BackboneMixin"
], function(React, _, AppComponent, BackboneMixin) {
  "use strict";

  var STATE_LOADING = 0;
  var STATE_ERROR = 1;
  var STATE_SUCCESS = 2;

  var UPDATE_INTERVAL = 5000;

  return React.createClass({
    displayName: "AppListComponent",
    mixins: [BackboneMixin],

    propTypes: {
      collection: React.PropTypes.object.isRequired,
      deployments: React.PropTypes.object.isRequired,
      onSelectApp: React.PropTypes.func.isRequired
    },

    componentDidMount: function() {
      this.startPolling();
    },

    componentWillUnmount: function() {
      this.stopPolling();
    },

    getInitialState: function() {
      return {
        fetchState: STATE_LOADING
      };
    },

    getResource: function() {
      return this.props.collection;
    },

    fetchResource: function() {
      this.props.collection.fetch({
        error: function() {
          this.setState({fetchState: STATE_ERROR});
        }.bind(this),
        reset: true,
        success: function() {
          this.setState({fetchState: STATE_SUCCESS});
          this.props.deployments.fetch({
            error: function() {
              this.setState({fetchState: STATE_ERROR});
            }.bind(this),
            reset: true
          });
        }.bind(this)
      });
    },

    onClickApp: function(app) {
      this.stopPolling();
      this.props.onSelectApp(app);
    },

    sortCollectionBy: function(comparator) {
      var collection = this.props.collection;
      comparator =
        collection.sortKey === comparator && !collection.sortReverse ?
        "-" + comparator :
        comparator;
      collection.setComparator(comparator);
      collection.sort();
    },

    startPolling: function() {
      if (this._interval == null) {
        this.fetchResource();
        this._interval = setInterval(this.fetchResource, UPDATE_INTERVAL);
      }
    },

    stopPolling: function() {
      if (this._interval != null) {
        clearInterval(this._interval);
        this._interval = null;
      }
    },

    render: function() {
      var sortKey = this.props.collection.sortKey;

      var appNodes;
      var tableClassName = "table table-fixed table-badged";

      var headerClassSet = React.addons.classSet({
        "clickable": true,
        "dropup": this.props.collection.sortReverse
      });

      if (this.state.fetchState === STATE_LOADING) {
        appNodes =
          <tr>
            <td className="text-center text-muted" colSpan="5">
              Loading apps...
            </td>
          </tr>;
      } else if (this.state.fetchState === STATE_ERROR) {
        appNodes =
          <tr>
            <td className="text-center text-danger" colSpan="5">
              Error fetching apps. Refresh to try again.
            </td>
          </tr>;
      } else if (this.props.collection.length === 0) {
        appNodes =
          <tr>
            <td className="text-center" colSpan="5">No running apps.</td>
          </tr>;
      } else {

        /* jshint trailing:false, quotmark:false, newcap:false */
        appNodes = this.props.collection.map(function(model) {
          return <AppComponent key={model.id} model={model} onClick={this.onClickApp} />;
        }, this);

        // Give rows the selectable look when there are apps to click.
        tableClassName += " table-hover table-selectable";
      }

      /* jshint trailing:false, quotmark:false, newcap:false */
      return (
        <table className={tableClassName}>
          <colgroup>
            <col style={{width: "28%"}} />
            <col style={{width: "18%"}} />
            <col style={{width: "18%"}} />
            <col style={{width: "18%"}} />
            <col style={{width: "18%"}} />
          </colgroup>
          <thead>
            <tr>
              <th>
                <span onClick={this.sortCollectionBy.bind(null, "id")} className={headerClassSet}>
                  ID {sortKey === "id" ? <span className="caret"></span> : null}
                </span>
              </th>
              <th className="text-right">
                <span onClick={this.sortCollectionBy.bind(null, "mem")} className={headerClassSet}>
                  {sortKey === "mem" ? <span className="caret"></span> : null} Memory (MB)
                </span>
              </th>
              <th className="text-right">
                <span onClick={this.sortCollectionBy.bind(null, "cpus")} className={headerClassSet}>
                  {sortKey === "cpus" ? <span className="caret"></span> : null} CPUs
                </span>
              </th>
              <th className="text-right">
                <span onClick={this.sortCollectionBy.bind(null, "instances")} className={headerClassSet}>
                  {sortKey === "instances" ? <span className="caret"></span> : null} Tasks / Instances
{'fraction_non_alphanumeric': 0.14210950080515297, 'fraction_numerical': 0.004227053140096618, 'mean_word_length': 2.00120809423135, 'pattern_counts': {'":': 4, '<': 93, '<?xml version=': 0, '>': 93, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3291597', 'n_tokens_mistral': 2932, 'n_tokens_neox': 2807, 'n_words': 563}