<commit_before>let React = require('react');
let StylePropable = require('../mixins/style-propable');
let ClickAwayable = require('../mixins/click-awayable');
let TableHeader = require('./table-header');
let TableRow = require('./table-row');
let TableFooter = require('./table-footer');


let Table = React.createClass({

  mixins: [StylePropable, ClickAwayable],

  contextTypes: {
    muiTheme: React.PropTypes.object,
  },

  propTypes: {
    rowData: React.PropTypes.array.isRequired,
    canSelectAll: React.PropTypes.bool,
    columnOrder: React.PropTypes.array,
    defaultColumnWidth: React.PropTypes.string,
    deselectOnClickaway: React.PropTypes.bool,
    displayRowCheckbox: React.PropTypes.bool,
    displaySelectAll: React.PropTypes.bool,
    fixedFooter: React.PropTypes.bool,
    fixedHeader: React.PropTypes.bool,
    footer: React.PropTypes.element,
    footerColumns: React.PropTypes.object,
    header: React.PropTypes.element,
    headerColumns: React.PropTypes.object,
    height: React.PropTypes.string,
    multiSelectable: React.PropTypes.bool,
    onCellClick: React.PropTypes.func,
    onCellHover: React.PropTypes.func,
    onCellHoverExit: React.PropTypes.func,
    onRowHover: React.PropTypes.func,
    onRowHoverExit: React.PropTypes.func,
    onRowSelection: React.PropTypes.func,
    preScanRowData: React.PropTypes.bool,
    selectable: React.PropTypes.bool,
    showRowHover: React.PropTypes.bool,
    stripedRows: React.PropTypes.bool,
  },

  getDefaultProps() {
    return {
      canSelectAll: false,
      defaultColumnWidth: '50px',
      deselectOnClickaway: true,
      displayRowCheckbox: true,
      displaySelectAll: true,
      fixedFooter: true,
      fixedHeader: true,
      height: 'inherit',
      multiSelectable: false,
      preScanRowData: true,
      selectable: true,
      showRowHover: false,
      stripedRows: false,
    };
  },

  getInitialState() {
    // Determine what rows are 'pre-selected'.
    let preSelectedRows = [];
    if (this.props.selectable && this.props.preScanRowData) {
      for (let idx = 0; idx < this.props.rowData.length; idx++) {
        let row = this.props.rowData[idx];
        if (row.selected !== undefined && row.selected) {
          preSelectedRows.push(idx);

          if (!this.props.multiSelectable) {
            break;
          }
        }
      }
    }

    return {
      selectedRows: preSelectedRows,
    };
  },

  getTheme() {
    return this.context.muiTheme.component.table;
  },

  getStyles() {
    let styles = {
      root: {
        backgroundColor: this.getTheme().backgroundColor,
        padding: '0 ' + this.context.muiTheme.spacing.desktopGutter + 'px',
        width: '100%',
        borderCollapse: 'collapse',
        borderSpacing: 0,
        tableLayout: 'fixed',
      },
      bodyTable: {
        height: (this.props.fixedHeader || this.props.fixedFooter) ? this.props.height : 'auto',
        overflowX: 'hidden',
        overflowY: 'auto',
      },
      tableWrapper: {
        height: (this.props.fixedHeader || this.props.fixedFooter) ? 'auto' : this.props.height,
        overflow: 'auto',
      },
    };

    return styles;
  },

  componentClickAway() {
    if (this.props.deselectOnClickaway && this.state.selectedRows.length) {
      this.setState({ selectedRows: [] });
    }
  },

  render() {
    let className = 'mui-table';
    let styles = this.getStyles();

    let tHead = this._getHeader();
    let tBody = this._getBody();
    let tFoot = this._getFooter();

    let headerTable, footerTable;
    let inlineHeader, inlineFooter;
    if (tHead !== undefined) {
      if (this.props.fixedHeader) {
        headerTable = (
          <div className='mui-header-table'>
            <table ref='headerTable' className={className} style={styles.root}>
              {tHead}
            </table>
          </div>
        );
      }
      else {
        inlineHeader = tHead;
      }
    }
    if (tFoot !== undefined) {
      if (this.props.fixedFooter) {
        footerTable = (
          <div className='mui-footer-table'>
            <table ref='footerTable' className={className} style={styles.root}>
              {tFoot}
            </table>
          </div>
        );
      }
      else {
        inlineFooter = tFoot;
      }
    }

    return (
      <div className='mui-table-wrapper' style={styles.tableWrapper}>
        {headerTable}
        <div className='mui-body-table' style={styles.bodyTable}>
          <table ref='bodyTable' className={className} style={styles.root}>
            {inlineHeader}
            {inlineFooter}
            {tBody}
          </table>
        </div>
        {footerTable}
      </div>
    );
  },

  _getHeader() {
    if (this.props.header) return this.props.header;

    if (this.props.headerColumns !== undefined) {
      let orderedHeaderColumns = this._orderColumnBasedData(this.props.headerColumns);
      return (
        <TableHeader
          columns={orderedHeaderColumns}
          enableSelectAll={this.props.canSelectAll && this.props.selectable}
          displaySelectAll={this.props.displaySelectAll}
          onSelectAll={this._onSelectAll} />
      );
    }
  },

  _getFooter() {
    if (this.props.footer) return this.props.footer;

    if (this.props.footerColumns !== undefined) {
      let orderedFooterColumns = this._orderColumnBasedData(this.props.footerColumns);
      if (this.props.displaySelectAll) {
        orderedFooterColumns.splice(0, 0, {content: ''});
      }

      return (
        <TableFooter columns={orderedFooterColumns} />
      );
    }
  },

  _getBody() {
    let body = this._orderColumnBasedData(this.props.rowData, (rowData, rowNumber) => {
      let selected = this._isRowSelected(rowNumber);
      let striped = this.props.stripedRows && (rowNumber % 2 === 0);
      let border = true;
      if (rowNumber === this.props.rowData.length - 1) {
        border = false;
      }

      let row = (
        <TableRow
          key={'r-' + rowNumber}
          rowNumber={rowNumber}
          columns={rowData}
          selected={selected}
          striped={striped}
          displayRowCheckbox={this.props.displayRowCheckbox}
          hoverable={this.props.showRowHover}
          displayBorder={border}
          selectable={this.props.selectable}
          onRowClick={this._handleRowClick}
          onCellClick={this._handleCellClick}
          onRowHover={this._handleRowHover}
          onRowHoverExit={this._handleRowHoverExit}
          onCellHover={this._handleCellHover}
          onCellHoverExit={this._handleCellHoverExit} />
      );

      return row;
    });

    return (
      <tbody style={{height: this.props.height}}>
        {body}
      </tbody>
    );
  },

  _orderColumnBasedData(columnBasedData, cb) {
    // If we do not have a columnOrder, return.
    if (this.props.columnOrder === undefined) return;

    let data = (Object.prototype.toString.call(columnBasedData) !== '[object Array]') ? [columnBasedData] : columnBasedData;
    let orderedData = [];

    for (let rowIdx = 0; rowIdx < data.length; rowIdx++) {
      let rowData = data[rowIdx];
      let orderedRowData = [];

      for (let colIdx = 0; colIdx < this.props.columnOrder.length; colIdx++) {
        let columnId = this.props.columnOrder[colIdx];
        let columnData = rowData[columnId] || {};

        orderedRowData.push(columnData);
      }

      if (orderedRowData.length) {
        rowData = orderedRowData;
      }

      // Fixed table layout only requires widths on first row.
      if (rowIdx === 1 && data.length > 1) {
        rowData = this._setColumnWidths(rowData);
      }

      orderedData.push((cb !== undefined) ? cb(rowData, rowIdx) : rowData);
    }

    return (data.length === 1) ? orderedData[0] : orderedData;
  },

  _setColumnWidths(columnData) {
    columnData.forEach((column) => {
      if (column.style === undefined) {
        column.style = {
          width: this.props.defaultColumnWidth,
          maxWidth: this.props.defaultColumnWidth,
        };
      }
      else {
        if (column.style.width === undefined) column.style.width = this.props.defaultColumnWidth;
        if (column.style.maxWidth === undefined) column.style.maxWidth = this.props.defaultColumnWidth;
      }
    });

    return columnData;
  },

  _isRowSelected(rowNumber) {
    if (this.state.allRowsSelected) {
      return true;
    }

    for (let i = 0; i < this.state.selectedRows.length; i++) {
      let selection = this.state.selectedRows[i];<commit_msg>ensure changes in rowData item selected key gets reflected in table<commit_after>let React = require('react');
let StylePropable = require('../mixins/style-propable');
let ClickAwayable = require('../mixins/click-awayable');
let TableHeader = require('./table-header');
let TableRow = require('./table-row');
let TableFooter = require('./table-footer');


let Table = React.createClass({

  mixins: [StylePropable, ClickAwayable],

  contextTypes: {
    muiTheme: React.PropTypes.object,
  },

  propTypes: {
    rowData: React.PropTypes.array.isRequired,
    canSelectAll: React.PropTypes.bool,
    columnOrder: React.PropTypes.array,
    defaultColumnWidth: React.PropTypes.string,
    deselectOnClickaway: React.PropTypes.bool,
    displayRowCheckbox: React.PropTypes.bool,
    displaySelectAll: React.PropTypes.bool,
    fixedFooter: React.PropTypes.bool,
    fixedHeader: React.PropTypes.bool,
    footer: React.PropTypes.element,
    footerColumns: React.PropTypes.object,
    header: React.PropTypes.element,
    headerColumns: React.PropTypes.object,
    height: React.PropTypes.string,
    multiSelectable: React.PropTypes.bool,
    onCellClick: React.PropTypes.func,
    onCellHover: React.PropTypes.func,
    onCellHoverExit: React.PropTypes.func,
    onRowHover: React.PropTypes.func,
    onRowHoverExit: React.PropTypes.func,
    onRowSelection: React.PropTypes.func,
    preScanRowData: React.PropTypes.bool,
    selectable: React.PropTypes.bool,
    showRowHover: React.PropTypes.bool,
    stripedRows: React.PropTypes.bool,
  },

  getDefaultProps() {
    return {
      canSelectAll: false,
      defaultColumnWidth: '50px',
      deselectOnClickaway: true,
      displayRowCheckbox: true,
      displaySelectAll: true,
      fixedFooter: true,
      fixedHeader: true,
      height: 'inherit',
      multiSelectable: false,
      preScanRowData: true,
      selectable: true,
      showRowHover: false,
      stripedRows: false,
    };
  },

  getInitialState() {
    let preSelectedRows = this._calculatePreselectedRows();

    return {
      selectedRows: preSelectedRows,
    };
  },

  getTheme() {
    return this.context.muiTheme.component.table;
  },

  getStyles() {
    let styles = {
      root: {
        backgroundColor: this.getTheme().backgroundColor,
        padding: '0 ' + this.context.muiTheme.spacing.desktopGutter + 'px',
        width: '100%',
        borderCollapse: 'collapse',
        borderSpacing: 0,
        tableLayout: 'fixed',
      },
      bodyTable: {
        height: (this.props.fixedHeader || this.props.fixedFooter) ? this.props.height : 'auto',
        overflowX: 'hidden',
        overflowY: 'auto',
      },
      tableWrapper: {
        height: (this.props.fixedHeader || this.props.fixedFooter) ? 'auto' : this.props.height,
        overflow: 'auto',
      },
    };

    return styles;
  },

  componentClickAway() {
    if (this.props.deselectOnClickaway && this.state.selectedRows.length) {
      this.setState({ selectedRows: [] });
    }
  },

  componentDidUpdate(oldProps) {
    if (oldProps.rowData !== this.props.rowData) {
      let preSelectedRows = this._calculatePreselectedRows();

      this.setState({
        selectedRows: preSelectedRows,
      });
    }
  },

  render() {
    let className = 'mui-table';
    let styles = this.getStyles();

    let tHead = this._getHeader();
    let tBody = this._getBody();
    let tFoot = this._getFooter();

    let headerTable, footerTable;
    let inlineHeader, inlineFooter;
    if (tHead !== undefined) {
      if (this.props.fixedHeader) {
        headerTable = (
          <div className='mui-header-table'>
            <table ref='headerTable' className={className} style={styles.root}>
              {tHead}
            </table>
          </div>
        );
      }
      else {
        inlineHeader = tHead;
      }
    }
    if (tFoot !== undefined) {
      if (this.props.fixedFooter) {
        footerTable = (
          <div className='mui-footer-table'>
            <table ref='footerTable' className={className} style={styles.root}>
              {tFoot}
            </table>
          </div>
        );
      }
      else {
        inlineFooter = tFoot;
      }
    }

    return (
      <div className='mui-table-wrapper' style={styles.tableWrapper}>
        {headerTable}
        <div className='mui-body-table' style={styles.bodyTable}>
          <table ref='bodyTable' className={className} style={styles.root}>
            {inlineHeader}
            {inlineFooter}
            {tBody}
          </table>
        </div>
        {footerTable}
      </div>
    );
  },

  _getHeader() {
    if (this.props.header) return this.props.header;

    if (this.props.headerColumns !== undefined) {
      let orderedHeaderColumns = this._orderColumnBasedData(this.props.headerColumns);
      return (
        <TableHeader
          columns={orderedHeaderColumns}
          enableSelectAll={this.props.canSelectAll && this.props.selectable}
          displaySelectAll={this.props.displaySelectAll}
          onSelectAll={this._onSelectAll} />
      );
    }
  },

  _getFooter() {
    if (this.props.footer) return this.props.footer;

    if (this.props.footerColumns !== undefined) {
      let orderedFooterColumns = this._orderColumnBasedData(this.props.footerColumns);
      if (this.props.displaySelectAll) {
        orderedFooterColumns.splice(0, 0, {content: ''});
      }

      return (
        <TableFooter columns={orderedFooterColumns} />
      );
    }
  },

  _getBody() {
    let body = this._orderColumnBasedData(this.props.rowData, (rowData, rowNumber) => {
      let selected = this._isRowSelected(rowNumber);
      let striped = this.props.stripedRows && (rowNumber % 2 === 0);
      let border = true;
      if (rowNumber === this.props.rowData.length - 1) {
        border = false;
      }

      let row = (
        <TableRow
          key={'r-' + rowNumber}
          rowNumber={rowNumber}
          columns={rowData}
          selected={selected}
          striped={striped}
          displayRowCheckbox={this.props.displayRowCheckbox}
          hoverable={this.props.showRowHover}
          displayBorder={border}
          selectable={this.props.selectable}
          onRowClick={this._handleRowClick}
          onCellClick={this._handleCellClick}
          onRowHover={this._handleRowHover}
          onRowHoverExit={this._handleRowHoverExit}
          onCellHover={this._handleCellHover}
          onCellHoverExit={this._handleCellHoverExit} />
      );

      return row;
    });

    return (
      <tbody style={{height: this.props.height}}>
        {body}
      </tbody>
    );
  },

  _orderColumnBasedData(columnBasedData, cb) {
    // If we do not have a columnOrder, return.
    if (this.props.columnOrder === undefined) return;

    let data = (Object.prototype.toString.call(columnBasedData) !== '[object Array]') ? [columnBasedData] : columnBasedData;
    let orderedData = [];

    for (let rowIdx = 0; rowIdx < data.length; rowIdx++) {
      let rowData = data[rowIdx];
      let orderedRowData = [];

      for (let colIdx = 0; colIdx < this.props.columnOrder.length; colIdx++) {
        let columnId = this.props.columnOrder[colIdx];
        let columnData = rowData[columnId] || {};

        orderedRowData.push(columnData);
      }

      if (orderedRowData.length) {
        rowData = orderedRowData;
      }

      // Fixed table layout only requires widths on first row.
      if (rowIdx === 1 && data.length > 1) {
        rowData = this._setColumnWidths(rowData);
      }

      orderedData.push((cb !== undefined) ? cb(rowData, rowIdx) : rowData);
    }

    return (data.length === 1) ? orderedData[0] : orderedData;
  },

  _setColumnWidths(columnData) {
    columnData.forEach((column) => {
      if (column.style === undefined) {
        column.style = {
          width: this.props.defaultColumnWidth,
          maxWidth: this.props.defaultColumnWidth,
        };
      }
      else {
        if (column.style.width === undefined) column.style.width = this.props.defaultColumnWidth;
        if (column.style.maxWidth === undefined) column.style.maxWidth = this.props.defaultColumnWidth;
      }
    });

    return columnData;
  },

  _calculatePreselectedRows () {
    // Determine what rows are 'pre-selected'.
    let preSelectedRows = [];
    if (this.props.selectable && this.props.preScanRowData) {
      for (let idx = 0; idx < this.props.rowData.length; idx++) {
        let row = this.props.rowData[idx];
        if (row.selected !== undefined && row.selected) {
          preSelectedRows.push(idx);

          if (!this.props.multiSelectable) {
            break;
          }
        }
      }
    }

    return preSelectedRows;
  },

  _isRowSelected(rowNumber) {
    if (this.state.allRowsSelected) {
      return true;
    }

    for (let i = 0; i < this.state.selectedRows.length; i++) {
      let selection = this.state.selectedRows[i];
{'fraction_non_alphanumeric': 0.12765103748710305, 'fraction_numerical': 0.0022927891780350797, 'mean_word_length': 2.471348985276562, 'pattern_counts': {'":': 0, '<': 49, '<?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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '71197', 'n_tokens_mistral': 5334, 'n_tokens_neox': 5226, 'n_words': 959}