<commit_before>import classNames from 'classnames';
import {Link} from 'react-router';
import React from 'react';
import {Table, Tooltip} from 'reactjs-components';

import DeclinedOffersReasons from '../constants/DeclinedOffersReasons';
import DateUtil from '../../../../../src/js/utils/DateUtil';
import Icon from '../../../../../src/js/components/Icon';
import MesosStateStore from '../../../../../src/js/stores/MesosStateStore';
import TableUtil from '../../../../../src/js/utils/TableUtil';
import TimeAgo from '../../../../../src/js/components/TimeAgo';
import Units from '../../../../../src/js/utils/Units';

class RejectedOffersTable extends React.Component {
  getColumnClassNameFn(classes) {
    return (prop, sortBy) => {
      return classNames(classes, {
        'active': prop === sortBy.prop
      });
    };
  }

  getColumnHeadingFn(defaultHeading, abbreviation) {
    return (prop, order, sortBy) => {
      let caretClassNames = classNames('caret', {
        [`caret--${order}`]: order != null,
        'caret--visible': sortBy.prop === prop
      });

      let columnHeading = defaultHeading || prop;

      if (abbreviation != null) {
        columnHeading = [
          <span className="hidden-medium-down" key="full-text">
            {columnHeading}
          </span>,
          <span className="hidden-large-up" key="abbreviation">
            {abbreviation}
          </span>
        ];
      }

      return (
        <span>
          {columnHeading}
          <span className={caretClassNames} />
        </span>
      );
    };
  }

  getMatchedResourcesSortFn(resource) {
    return (item, prop) => {
      // It's possible that prop is one of the resources, or timestamp for a
      // tiebreaker. Return the timestamp in ms if it's the current prop.
      if (prop === 'timestamp') {
        return DateUtil.strToMs(item[prop]);
      }

      const {unmatchedResource = []} = item;

      if (unmatchedResource.includes(resource)) {
        return 1;
      }

      return 0;
    };
  }

  getMatchedOfferRenderFn(resource) {
    const {summary} = this.props;

    return (prop, row) => {
      const {unmatchedResource = []} = row;
      const isOfferDeclined = unmatchedResource.includes(resource);
      const receivedResourceClasses = classNames({
        'text-danger': isOfferDeclined
      });

      let receivedResource = row.offered[prop] || 'N/A';
      if (Array.isArray(receivedResource)) {
        receivedResource = receivedResource.join(', ') || 'N/A';
      } else if (['cpus', 'mem', 'disk'].includes(prop)) {
        receivedResource = Units.formatResource(prop, receivedResource);
      }

      let icon = null;
      if (isOfferDeclined) {
        icon = <Icon color="red" family="mini" id="close" size="mini" />;
      } else {
        icon = <Icon color="neutral" family="mini" id="check" size="mini" />;
      }

      const tooltipContent = (
        <div>
          <div className="">
            <strong>Requested</strong>{': '}
            {summary[prop].requested}
          </div>
          <div className="">
            <strong>Received</strong>{': '}
            <span className={receivedResourceClasses}>{receivedResource}</span>
          </div>
        </div>
      );

      return (
        <Tooltip content={tooltipContent}
          maxWidth={300}
          wrapText={true}>
          {icon}
        </Tooltip>
      );
    };
  }

  getColGroup() {
    return (
      <colgroup>
        <col />
        <col style={{width: '10%'}} />
        <col style={{width: '10%'}} />
        <col className="hidden-large-up" style={{width: '30%'}} />
        <col className="hidden-medium-down" style={{width: '10%'}} />
        <col className="hidden-medium-down" style={{width: '10%'}} /><commit_msg>Remove empty className props<commit_after>import classNames from 'classnames';
import {Link} from 'react-router';
import React from 'react';
import {Table, Tooltip} from 'reactjs-components';

import DeclinedOffersReasons from '../constants/DeclinedOffersReasons';
import DateUtil from '../../../../../src/js/utils/DateUtil';
import Icon from '../../../../../src/js/components/Icon';
import MesosStateStore from '../../../../../src/js/stores/MesosStateStore';
import TableUtil from '../../../../../src/js/utils/TableUtil';
import TimeAgo from '../../../../../src/js/components/TimeAgo';
import Units from '../../../../../src/js/utils/Units';

class RejectedOffersTable extends React.Component {
  getColumnClassNameFn(classes) {
    return (prop, sortBy) => {
      return classNames(classes, {
        'active': prop === sortBy.prop
      });
    };
  }

  getColumnHeadingFn(defaultHeading, abbreviation) {
    return (prop, order, sortBy) => {
      let caretClassNames = classNames('caret', {
        [`caret--${order}`]: order != null,
        'caret--visible': sortBy.prop === prop
      });

      let columnHeading = defaultHeading || prop;

      if (abbreviation != null) {
        columnHeading = [
          <span className="hidden-medium-down" key="full-text">
            {columnHeading}
          </span>,
          <span className="hidden-large-up" key="abbreviation">
            {abbreviation}
          </span>
        ];
      }

      return (
        <span>
          {columnHeading}
          <span className={caretClassNames} />
        </span>
      );
    };
  }

  getMatchedResourcesSortFn(resource) {
    return (item, prop) => {
      // It's possible that prop is one of the resources, or timestamp for a
      // tiebreaker. Return the timestamp in ms if it's the current prop.
      if (prop === 'timestamp') {
        return DateUtil.strToMs(item[prop]);
      }

      const {unmatchedResource = []} = item;

      if (unmatchedResource.includes(resource)) {
        return 1;
      }

      return 0;
    };
  }

  getMatchedOfferRenderFn(resource) {
    const {summary} = this.props;

    return (prop, row) => {
      const {unmatchedResource = []} = row;
      const isOfferDeclined = unmatchedResource.includes(resource);
      const receivedResourceClasses = classNames({
        'text-danger': isOfferDeclined
      });

      let receivedResource = row.offered[prop] || 'N/A';
      if (Array.isArray(receivedResource)) {
        receivedResource = receivedResource.join(', ') || 'N/A';
      } else if (['cpus', 'mem', 'disk'].includes(prop)) {
        receivedResource = Units.formatResource(prop, receivedResource);
      }

      let icon = null;
      if (isOfferDeclined) {
        icon = <Icon color="red" family="mini" id="close" size="mini" />;
      } else {
        icon = <Icon color="neutral" family="mini" id="check" size="mini" />;
      }

      const tooltipContent = (
        <div>
          <div>
            <strong>Requested</strong>{': '}
            {summary[prop].requested}
          </div>
          <div>
            <strong>Received</strong>{': '}
            <span className={receivedResourceClasses}>{receivedResource}</span>
          </div>
        </div>
      );

      return (
        <Tooltip content={tooltipContent}
          maxWidth={300}
          wrapText={true}>
          {icon}
        </Tooltip>
      );
    };
  }

  getColGroup() {
    return (
      <colgroup>
        <col />
        <col style={{width: '10%'}} />
        <col style={{width: '10%'}} />
        <col className="hidden-large-up" style={{width: '30%'}} />
        <col className="hidden-medium-down" style={{width: '10%'}} />
        <col className="hidden-medium-down" style={{width: '10%'}} />
{'fraction_non_alphanumeric': 0.16881563206167752, 'fraction_numerical': 0.003987770836102618, 'mean_word_length': 2.2153846153846155, 'pattern_counts': {'":': 0, '<': 63, '<?xml version=': 0, '>': 71, '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': '4667073', 'n_tokens_mistral': 2270, 'n_tokens_neox': 2212, 'n_words': 473}