<commit_before>import React, { PropTypes } from 'react';
import { Link } from 'react-router';
import { SplitButton, Button, MenuItem } from 'react-bootstrap';

import { DataApi } from 'loom-data';

import FileConsts from '../../utils/Consts/FileConsts';
import PageConsts from '../../utils/Consts/PageConsts';
import { EntitySetPropType } from './EntitySetStorage';
import styles from './entityset.module.css';

const MAX_DESCRIPTION_LENGTH = 300;

class ExpandableText extends React.Component {
  static propTypes = {
    text: PropTypes.string,
    maxLength: PropTypes.number
  };

  constructor(props) {
    super(props);
    this.state = {
      isOpen: false
    };

    this.switchState = () => {
      this.setState({ isOpen: !this.state.isOpen });
    };
  }

  render() {
    const { text, maxLength } = this.props;
    if (text.length <= maxLength) {
      return (<div>{text}</div>);
    }

    const { isOpen } = this.state;
    let controlText,
      displayText;
    if (isOpen) {
      controlText = 'Read less';
      displayText = text;
    } else {
      controlText = 'Read more';
      displayText = `${text.substring(0, maxLength)}...`;
    }

    return (
      <div>
        {displayText}
        <Button bsStyle="link" className={styles.expandTextButton} onClick={this.switchState}>{controlText}</Button>
      </div>
    );

  }
}

class ActionDropdown extends React.Component {
  static propTypes = {
    entitySet: EntitySetPropType.isRequired,
    showDetails: PropTypes.bool
  };

  render() {
    const { entitySet } = this.props;
    const type = entitySet.type;

    let details;
    if (this.props.showDetails) {
      details = (
        <li role="presentation">
          <Link to={`/entitysets/${this.props.entitySet.id}`}>
            View Details
          </Link>
        </li>
      );
    }

    return (
      <SplitButton pullRight title="Actions" id="action-dropdown">
        {details}
        <MenuItem header>Download</MenuItem>
        <MenuItem href={DataApi.getAllEntitiesOfTypeInSetFileUrl(type, entitySet.name, FileConsts.CSV)}>CSV</MenuItem>
        <MenuItem href={DataApi.getAllEntitiesOfTypeInSetFileUrl(type, entitySet.name, FileConsts.JSON)}>JSON</MenuItem>
        <MenuItem divider/>
        <li role="presentation">
          <Link
            to={{
              pathname: `/${PageConsts.VISUALIZE}`,
              query: {
                name: entitySet.name,
                typeNamespace: type.namespace,
                typeName: type.name
              }
            }}>
            Visualize
          </Link>
        </li>
      </SplitButton>
    );
  }
}
<commit_msg>Upgraded loom-data via npm link<commit_after>import React, { PropTypes } from 'react';
import { Link } from 'react-router';
import { SplitButton, Button, MenuItem } from 'react-bootstrap';

import { DataApi } from 'loom-data';

import FileConsts from '../../utils/Consts/FileConsts';
import PageConsts from '../../utils/Consts/PageConsts';
import { EntitySetPropType } from './EntitySetStorage';
import styles from './entityset.module.css';

const MAX_DESCRIPTION_LENGTH = 300;

class ExpandableText extends React.Component {
  static propTypes = {
    text: PropTypes.string,
    maxLength: PropTypes.number
  };

  constructor(props) {
    super(props);
    this.state = {
      isOpen: false
    };

    this.switchState = () => {
      this.setState({ isOpen: !this.state.isOpen });
    };
  }

  render() {
    const { text, maxLength } = this.props;
    if (text.length <= maxLength) {
      return (<div>{text}</div>);
    }

    const { isOpen } = this.state;
    let controlText,
      displayText;
    if (isOpen) {
      controlText = 'Read less';
      displayText = text;
    } else {
      controlText = 'Read more';
      displayText = `${text.substring(0, maxLength)}...`;
    }

    return (
      <div>
        {displayText}
        <Button bsStyle="link" className={styles.expandTextButton} onClick={this.switchState}>{controlText}</Button>
      </div>
    );

  }
}

class ActionDropdown extends React.Component {
  static propTypes = {
    entitySet: EntitySetPropType.isRequired,
    showDetails: PropTypes.bool
  };

  render() {
    const { entitySet } = this.props;
    const type = entitySet.type;

    let details;
    if (this.props.showDetails) {
      details = (
        <li role="presentation">
          <Link to={`/entitysets/${this.props.entitySet.id}`}>
            View Details
          </Link>
        </li>
      );
    }

    return (
      <SplitButton pullRight title="Actions" id="action-dropdown">
        {details}
        <MenuItem header>Download</MenuItem>
        <MenuItem href={DataApi.getEntitySetDataFileUrl(entitySet.id, FileConsts.CSV)}>CSV</MenuItem>
        <MenuItem href={DataApi.getEntitySetDataFileUrl(entitySet.id, FileConsts.JSON)}>JSON</MenuItem>
        <MenuItem divider/>
        <li role="presentation">
          <Link
            to={{
              pathname: `/${PageConsts.VISUALIZE}`,
              query: {
                name: entitySet.name,
                typeNamespace: type.namespace,
                typeName: type.name
              }
            }}>
            Visualize
          </Link>
        </li>
      </SplitButton>
    );
  }
}

{'fraction_non_alphanumeric': 0.1354483282674772, 'fraction_numerical': 0.001519756838905775, 'mean_word_length': 2.3030112923462984, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3089476', 'n_tokens_mistral': 1590, 'n_tokens_neox': 1572, 'n_words': 322}