<commit_before>import PropTypes from 'prop-types';
import React from 'react';
import { FormattedMessage, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import MenuItem from 'material-ui/MenuItem';
import { getBrandDarkColor } from '../../../styles/colors';
import withAsyncFetch from '../../common/hocs/AsyncContainer';
import { fetchSourceSplitStoryCount } from '../../../actions/sourceActions';
import DataCard from '../../common/DataCard';
import AttentionOverTimeChart from '../../vis/AttentionOverTimeChart';
import messages from '../../../resources/messages';
import withHelp from '../../common/hocs/HelpfulContainer';
import ActionMenu from '../../common/ActionMenu';
import { DownloadButton } from '../../common/IconButton';
import { urlToExplorerQuery } from '../../../lib/urlUtil';

const localMessages = {
  title: { id: 'source.summary.splitCount.title', defaultMessage: 'Stories from this Media Source (over the last year)' },
  helpTitle: { id: 'source.summary.splitCount.help.title', defaultMessage: 'About Stories Over Time' },
  helpText: { id: 'source.summary.splitCount.help.text',
    defaultMessage: '<p>This chart shows you the number of stories we have collected from this source over time. Click on the line to see a summary of the content in this source for that date. The grey vertical lines indicate weeks where we didn\'t get as many stories as we\'d expect to.</p>',
  },
  regularlyCollectedStories: { id: 'explorer.attention.series.regular', defaultMessage: 'Regularly Collected Stories (default)' },
  allStories: { id: 'explorer.attention.series.allstories', defaultMessage: 'All Stories' },

};

const VIEW_ALL_STORIES = 'VIEW_ALL_STORIES';
const VIEW_REGULARLY_COLLECTED = 'VIEW_REGULARLY_COLLECTED';


class SourceSplitStoryCountContainer extends React.Component {
  state = {
    storyCollection: VIEW_REGULARLY_COLLECTED,
  }
  componentWillUnmount() {
    this.setState({ storyCollection: 'weird' });
  }
  onIncludeSpidered = (d) => {
    this.setState({ storyCollection: d });  // reset this to trigger a re-render
  }
  handleDataPointClick = (startDate, endDate) => {
    const { sourceId, sourceName } = this.props;
    const startDateStr = `${startDate.getFullYear()}-${startDate.getMonth() + 1}-${startDate.getDate()}`;
    const endDateStr = `${endDate.getFullYear()}-${endDate.getMonth() + 1}-${endDate.getDate()}`;
    const url = urlToExplorerQuery(sourceName, '*', [sourceId], [], startDateStr, endDateStr);
    window.open(url, '_blank');
  }
  downloadCsv = () => {
    const { sourceId } = this.props;
    const url = `/api/sources/${sourceId}/story-split/count.csv`;
    window.location = url;
  }
  render() {
    const { allStories, partialStories, health, filename, helpButton, sourceName } = this.props;
    const { formatMessage } = this.props.intl;
    let stories = allStories;
    if (this.state.storyCollection === VIEW_REGULARLY_COLLECTED) {
      stories = partialStories;
    }
    return (
      <DataCard>
        <div className="action-menu-set">
          <ActionMenu>
            <MenuItem
              className="action-icon-menu-item"
              primaryText={formatMessage(messages.downloadCSV)}
              rightIcon={<DownloadButton />}
              onTouchTap={this.downloadCsv}
            />
            <MenuItem
              className="action-icon-menu-item"
              primaryText={formatMessage(localMessages.regularlyCollectedStories)}
              disabled={this.state.storyCollection === VIEW_REGULARLY_COLLECTED}
              onClick={() => this.onIncludeSpidered(VIEW_REGULARLY_COLLECTED)}
            />
            <MenuItem
              className="action-icon-menu-item"
              primaryText={formatMessage(localMessages.allStories)}
              disabled={this.state.storyCollection === VIEW_ALL_STORIES}
              onClick={() => this.onIncludeSpidered(VIEW_ALL_STORIES)}
            />
          </ActionMenu>
        </div>
        <h2>
          <FormattedMessage {...localMessages.title} />
          {helpButton}
        </h2>
        <AttentionOverTimeChart
          total={stories.total}
          series={[{
            id: 0,
            name: sourceName,
            color: getBrandDarkColor(),
            data: stories.list.map(c => [c.date, c.count]),
            showInLegend: false,
          }]}
          health={health}
          height={250}
          filename={filename}
          onDataPointClick={this.handleDataPointClick}
        />
      </DataCard>
    );
  }
}

SourceSplitStoryCountContainer.propTypes = {
  // from state
  fetchStatus: PropTypes.string.isRequired,
  health: PropTypes.array,
  allStories: PropTypes.object,
  partialStories: PropTypes.object,
  splitStoryCount: PropTypes.object,
  // from parent
  sourceId: PropTypes.number.isRequired,
  sourceName: PropTypes.string.isRequired,<commit_msg>#920 text and fix health<commit_after>import PropTypes from 'prop-types';
import React from 'react';
import { FormattedMessage, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import MenuItem from 'material-ui/MenuItem';
import { getBrandDarkColor } from '../../../styles/colors';
import withAsyncFetch from '../../common/hocs/AsyncContainer';
import { fetchSourceSplitStoryCount } from '../../../actions/sourceActions';
import DataCard from '../../common/DataCard';
import AttentionOverTimeChart from '../../vis/AttentionOverTimeChart';
import messages from '../../../resources/messages';
import withHelp from '../../common/hocs/HelpfulContainer';
import ActionMenu from '../../common/ActionMenu';
import { DownloadButton } from '../../common/IconButton';
import { urlToExplorerQuery } from '../../../lib/urlUtil';

const localMessages = {
  title: { id: 'source.summary.splitCount.title', defaultMessage: 'All Stories over the last year' },
  helpTitle: { id: 'source.summary.splitCount.help.title', defaultMessage: 'About Stories Over Time' },
  helpText: { id: 'source.summary.splitCount.help.text',
    defaultMessage: '<p>This chart shows you the number of stories we have collected from this source over time. Some stories are collected regularly from RSS feeds associated with the media source, while others are discovered via tracing through links in other stories (ie. spidering). Click on the line to see a summary of the content in this source for that date. The grey vertical lines indicate weeks where we didn\'t get as many stories as we\'d expect to.</p>',
  },
  regularlyCollectedStories: { id: 'explorer.attention.series.regular', defaultMessage: 'Regularly Collected Stories over the last year (default)' },
  allStories: { id: 'explorer.attention.series.allstories', defaultMessage: 'All Stories' },

};

const VIEW_ALL_STORIES = 'VIEW_ALL_STORIES';
const VIEW_REGULARLY_COLLECTED = 'VIEW_REGULARLY_COLLECTED';


class SourceSplitStoryCountContainer extends React.Component {
  state = {
    storyCollection: VIEW_REGULARLY_COLLECTED,
  }
  componentWillUnmount() {
    this.setState({ storyCollection: 'weird' });
  }
  onIncludeSpidered = (d) => {
    this.setState({ storyCollection: d });  // reset this to trigger a re-render
  }
  handleDataPointClick = (startDate, endDate) => {
    const { sourceId, sourceName } = this.props;
    const startDateStr = `${startDate.getFullYear()}-${startDate.getMonth() + 1}-${startDate.getDate()}`;
    const endDateStr = `${endDate.getFullYear()}-${endDate.getMonth() + 1}-${endDate.getDate()}`;
    const url = urlToExplorerQuery(sourceName, '*', [sourceId], [], startDateStr, endDateStr);
    window.open(url, '_blank');
  }
  downloadCsv = () => {
    const { sourceId } = this.props;
    const url = `/api/sources/${sourceId}/story-split/count.csv`;
    window.location = url;
  }
  render() {
    const { allStories, partialStories, filename, helpButton, sourceName } = this.props;
    const { formatMessage } = this.props.intl;
    let stories = allStories;
    if (this.state.storyCollection === VIEW_REGULARLY_COLLECTED) {
      stories = partialStories;
    }
    return (
      <DataCard>
        <div className="action-menu-set">
          <ActionMenu>
            <MenuItem
              className="action-icon-menu-item"
              primaryText={formatMessage(messages.downloadCSV)}
              rightIcon={<DownloadButton />}
              onTouchTap={this.downloadCsv}
            />
            <MenuItem
              className="action-icon-menu-item"
              primaryText={formatMessage(localMessages.regularlyCollectedStories)}
              disabled={this.state.storyCollection === VIEW_REGULARLY_COLLECTED}
              onClick={() => this.onIncludeSpidered(VIEW_REGULARLY_COLLECTED)}
            />
            <MenuItem
              className="action-icon-menu-item"
              primaryText={formatMessage(localMessages.allStories)}
              disabled={this.state.storyCollection === VIEW_ALL_STORIES}
              onClick={() => this.onIncludeSpidered(VIEW_ALL_STORIES)}
            />
          </ActionMenu>
        </div>
        <h2>
          <FormattedMessage {...localMessages.title} />
          {helpButton}
        </h2>
        <AttentionOverTimeChart
          total={stories.total}
          series={[{
            id: 0,
            name: sourceName,
            color: getBrandDarkColor(),
            data: stories.list.map(c => [c.date, c.count]),
            showInLegend: false,
          }]}
          health={stories.health}
          height={250}
          filename={filename}
          onDataPointClick={this.handleDataPointClick}
        />
      </DataCard>
    );
  }
}

SourceSplitStoryCountContainer.propTypes = {
  // from state
  fetchStatus: PropTypes.string.isRequired,
  health: PropTypes.array,
  allStories: PropTypes.object,
  partialStories: PropTypes.object,
  splitStoryCount: PropTypes.object,
  // from parent
  sourceId: PropTypes.number.isRequired,
  sourceName: PropTypes.string.isRequired,
{'fraction_non_alphanumeric': 0.1309727391610502, 'fraction_numerical': 0.0019112765315360627, 'mean_word_length': 3.0513447432762835, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '258558', 'n_tokens_mistral': 2830, 'n_tokens_neox': 2840, 'n_words': 633}