<commit_before>import React from 'react';
import $ from 'jquery';
import _ from 'underscore';
import Board from './Board';
import { CircularProgress } from 'material-ui';

const App = React.createClass({
  propTypes: {
    pivotalToken: React.PropTypes.string.isRequired,
    pivotalProjectId: React.PropTypes.string.isRequired,
    gitHubToken: React.PropTypes.string.isRequired
  },

  getInitialState() {
    return { stories: null, pullRequests: null, projectName: null };
  },

  componentDidMount() {
    this._fetchProjectName();
    this._fetchStories();
    this._fetchPullRequests();
  },

  _fetchProjectName() {
    const { pivotalProjectId } = this.props;
    $.ajax({
      url: `https://www.pivotaltracker.com/services/v5/projects/${pivotalProjectId}`,
      method: 'GET',
      beforeSend: xhr => xhr.setRequestHeader('X-TrackerToken', this.props.pivotalToken)
    }).done(data => this.setState({ projectName: data.name }));
  },

  _fetchStories() {
    const { pivotalProjectId } = this.props;
    $.ajax({
      url: `https://www.pivotaltracker.com/services/v5/projects/${pivotalProjectId}/iterations?scope=current`,
      method: 'GET',
      beforeSend: xhr => xhr.setRequestHeader('X-TrackerToken', this.props.pivotalToken)
    }).done(data =>
      this.setState({ stories: _.select(data[0].stories, story => story.story_type !== 'release') })
    );
  },

  _fetchPullRequests() {
    const { gitHubToken } = this.props;
    $.ajax({
      url: `https://api.github.com/repos/mojotech/squadlocker/pulls?state=open&access_token=${gitHubToken}`,
      method: 'GET'
    }).done(data => this.setState({ pullRequests: data }));
  },

  render() {
    const styles = {
      centered: { textAlign: 'center' }
    };
    const { stories, pullRequests, projectName } = this.state;
    const loading = (_.isNull(stories) || _.isNull(pullRequests) || _.isNull(projectName));
    return (
      <div>
        {loading ? (
          <div style={styles.centered}>
            <CircularProgress mode='indeterminate' />
          </div>
        ) : (
          <div>
            <h1 style={styles.centered}>{projectName} Sprint</h1>
            <Board projectName={projectName} stories={stories} pullRequests={pullRequests} />
          </div>
        )}
      </div>
    );
  }
});

export default App;<commit_msg>add error state<commit_after>import React from 'react';
import $ from 'jquery';
import _ from 'underscore';
import Board from './Board';
import { CircularProgress } from 'material-ui';

const App = React.createClass({
  propTypes: {
    pivotalToken: React.PropTypes.string.isRequired,
    pivotalProjectId: React.PropTypes.string.isRequired,
    gitHubToken: React.PropTypes.string.isRequired
  },

  getInitialState() {
    return { stories: null, pullRequests: null, projectName: null };
  },

  componentDidMount() {
    this._fetchProjectName();
    this._fetchStories();
    this._fetchPullRequests();
  },

  _fetchProjectName() {
    const { pivotalProjectId } = this.props;
    $.ajax({
      url: `https://www.pivotaltracker.com/services/v5/projects/${pivotalProjectId}`,
      method: 'GET',
      beforeSend: xhr => xhr.setRequestHeader('X-TrackerToken', this.props.pivotalToken)
    }).done(data =>
      this.setState({ projectName: data.name })
    ).fail(() =>
      this.setState({ errorFetchingData: true })
    );
  },

  _fetchStories() {
    const { pivotalProjectId } = this.props;
    $.ajax({
      url: `https://www.pivotaltracker.com/services/v5/projects/${pivotalProjectId}/iterations?scope=current`,
      method: 'GET',
      beforeSend: xhr => xhr.setRequestHeader('X-TrackerToken', this.props.pivotalToken)
    }).done(data =>
      this.setState({ stories: _.select(data[0].stories, story => story.story_type !== 'release') })
    ).fail(() =>
      this.setState({ errorFetchingData: true })
    );
  },

  _fetchPullRequests() {
    const { gitHubToken } = this.props;
    $.ajax({
      url: `https://api.github.com/repos/mojotech/squadlocker/pulls?state=open&access_token=${gitHubToken}`,
      method: 'GET'
    }).done(data => {
      this.setState({ pullRequests: data })
    }
    ).fail(() =>
      this.setState({ errorFetchingData: true })
    );
  },

  render() {
    const styles = {
      centered: { textAlign: 'center' }
    };
    const { stories, pullRequests, projectName, errorFetchingData } = this.state;
    const loading = (!errorFetchingData && (_.isNull(stories) || _.isNull(pullRequests) || _.isNull(projectName)));
    return (
      <div>
        {loading ? (
          <div style={styles.centered}>
            <CircularProgress mode='indeterminate' />
          </div>
        ) : (
          errorFetchingData ? (
            <div>Error fetching data.</div>
          ) : (
            <div>
              <h1 style={styles.centered}>{projectName} Sprint</h1>
              <Board projectName={projectName} stories={stories} pullRequests={pullRequests} />
            </div>
          )
        )}
      </div>
    );
  }
});

export default App;
{'fraction_non_alphanumeric': 0.15749751737835155, 'fraction_numerical': 0.0019860973187686196, 'mean_word_length': 2.9282371294851792, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 40, 'https://': 6, 'lorem ipsum': 0, 'www.': 4, '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': '4081651', 'n_tokens_mistral': 1597, 'n_tokens_neox': 1592, 'n_words': 273}