<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import {Table, Column, Cell, ColumnGroup} from 'fixed-data-table';
import Immutable from 'immutable';
import _ from 'underscore';
import messages from "../lang/messages";
import Selector from './selector';
import CellRenderer from './cellRenderer';
import HeaderCell from './headerCell';
import bs from 'binarysearch';
import clone from 'clone';
import {shallowEqualImmutable} from 'react-immutable-render-mixin';
import cache from '../lib/rowcache';

//Const
const SELECTOR_COL_NAME = 'selector-multiple-column'; // Name of the selector column
const Set = require('es6-set');


/**
 * Check if the table has nested columns. Columns inside other columns. In that case this component will render the single columns as a
 * column inside a ColumnGroup even if the column has not childrens.
 *
 * @param (array)		cols  	Describe columns
 * @return (boolean)	result	True if has nested columns or false otherwhise
 */
function hasNested(cols) {
	let result = false;

	if (cols.size) {
		cols.forEach((c) => {
			if (c.get('children') && c.get('children').size) {
				result = true;
				return false;
			}
		});
	}

	return result;
}

/**
 * A proper table component based on react Fixed-DataTables with an amount of new functionalities.
 * Rows selection with callback, sorting (single, multisorting), cell formating, fixed columns when scrolling, etc...
 * See Examples folder for more detail.
 *
 * Simple example usage:
 *
 * let cols = [
 *		{
 *			name: 'col1',
 *			label: <span>A number</span>,
 *			field: 'number',
 *			fixed: true
 *		},{
 *			name: 'col2',
 *			label: 'col2',
 *			field: 'col2'
 *		}
 *	]
 *
 * let data = [];
 *	  data.push({
 *		  col1: 5,
 *		  col2: 'abcde'
 *	  });
 *
 * 	<ProperTable.Table
 *		key='TableKey'
 *		uniqueId={1}
 *		rowHeight={40}
 *		cols={cols}
 *		data={data}
 *		afterSelect={
 *			function(rows) {
 *				console.log('selected', rows);
 *			}
 *		}
 *	/>
 * ```
 */
class ProperTable extends React.Component {

	constructor(props) {

		super(props);

		// Get initial data
		let initialData = this.prepareData();
		// Get initial columns sort
		let initialColSettings = this.prepareColSettings(this.props, initialData.rawdata);

		this.state = {
			cols: Immutable.fromJS(this.props.cols),
			colSettings: initialColSettings.colSettings,
			colSortParsers: initialColSettings.colSortParsers,
			data: initialData.data,
			initialData: initialData.initialData,
			indexed: initialData.indexed,
			initialIndexed: initialData.initialIndexed,
			rawdata: initialData.rawdata,
			sizes: Immutable.fromJS({}),
			selection:initialData.defSelection,
			sortCache: initialData.defSortCache,
			allSelected: false,
			sendSorted: false
		};
	}

	componentWillMount() {
		this.uniqueId = this.props.uniqueId || _.uniqueId('propertable-');

		// Sort the table and apply filters if exist in props
		this.applySettings();

		// Add new click listener if exist
		if (this.props.restartOnClick) {
			this.addClickListener(this.props.restartOnClick);
		}
	}

	componentDidMount() {
		// In some cases the callback of setState it's called before the new state is set up so we use a flag to prevent this.
		if (this.state.sendSorted) {
			this.setState({
				sendSorted: false
			}, this.sendSortedAndSettings(this.state.data, this.state.colSettings));
		} else {
			this.sendColSettings(this.state.colSettings);
		}
	}

	componentWillUnmount() {
		cache.flush('formatted');

		// Remove listener if exist
		if (this.props.restartOnClick) {
			this.removeClickListener(this.props.restartOnClick);
		}
	}

	shouldComponentUpdate(nextProps, nextState) {
		let propschanged = !shallowEqualImmutable(this.props, nextProps);
		let statechanged = !shallowEqualImmutable(this.state, nextState);
		let somethingchanged = propschanged || statechanged;

		if (propschanged) {
			let colsChanged = !shallowEqualImmutable(nextProps.cols, this.props.cols);
			let dataChanged = !shallowEqualImmutable(nextProps.data, this.props.data);
			let colSortDirsChanged = nextProps.colSortDirs ? !shallowEqualImmutable(nextProps.colSortDirs, this.props.colSortDirs) : false;
			let colFiltersChanged = nextProps.colFilters ? !shallowEqualImmutable(nextProps.colFilters, this.props.colFilters) : false;
			let selectedChanged = nextProps.selected ? !shallowEqualImmutable(nextProps.selected, this.props.selected) : false;
			let colData = null, preparedData = null;

			// If data and columns change the colSettings and all data states must be updated. Then apply default (sort table
			// and set selection if it has been received). If both change It's almost the same as rebuild the component. Almost everything changes
			if (colsChanged || dataChanged) {
				cache.flush('formatted');

				if (dataChanged) { // The most probably case
					let colSettings = nextState.colSettings;
					preparedData = this.prepareData(nextProps, nextState);
<commit_msg>Improve should component update of Table<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import {Table, Column, Cell, ColumnGroup} from 'fixed-data-table';
import Immutable from 'immutable';
import _ from 'underscore';
import messages from "../lang/messages";
import Selector from './selector';
import CellRenderer from './cellRenderer';
import HeaderCell from './headerCell';
import bs from 'binarysearch';
import clone from 'clone';
import {shallowEqualImmutable} from 'react-immutable-render-mixin';
import cache from '../lib/rowcache';

//Const
const SELECTOR_COL_NAME = 'selector-multiple-column'; // Name of the selector column
const Set = require('es6-set');


/**
 * Check if the table has nested columns. Columns inside other columns. In that case this component will render the single columns as a
 * column inside a ColumnGroup even if the column has not childrens.
 *
 * @param (array)		cols  	Describe columns
 * @return (boolean)	result	True if has nested columns or false otherwhise
 */
function hasNested(cols) {
	let result = false;

	if (cols.size) {
		cols.forEach((c) => {
			if (c.get('children') && c.get('children').size) {
				result = true;
				return false;
			}
		});
	}

	return result;
}

/**
 * A proper table component based on react Fixed-DataTables with an amount of new functionalities.
 * Rows selection with callback, sorting (single, multisorting), cell formating, fixed columns when scrolling, etc...
 * See Examples folder for more detail.
 *
 * Simple example usage:
 *
 * let cols = [
 *		{
 *			name: 'col1',
 *			label: <span>A number</span>,
 *			field: 'number',
 *			fixed: true
 *		},{
 *			name: 'col2',
 *			label: 'col2',
 *			field: 'col2'
 *		}
 *	]
 *
 * let data = [];
 *	  data.push({
 *		  col1: 5,
 *		  col2: 'abcde'
 *	  });
 *
 * 	<ProperTable.Table
 *		key='TableKey'
 *		uniqueId={1}
 *		rowHeight={40}
 *		cols={cols}
 *		data={data}
 *		afterSelect={
 *			function(rows) {
 *				console.log('selected', rows);
 *			}
 *		}
 *	/>
 * ```
 */
class ProperTable extends React.Component {

	constructor(props) {

		super(props);

		// Get initial data
		let initialData = this.prepareData();
		// Get initial columns sort
		let initialColSettings = this.prepareColSettings(this.props, initialData.rawdata);

		this.state = {
			cols: Immutable.fromJS(this.props.cols),
			colSettings: initialColSettings.colSettings,
			colSortParsers: initialColSettings.colSortParsers,
			data: initialData.data,
			initialData: initialData.initialData,
			indexed: initialData.indexed,
			initialIndexed: initialData.initialIndexed,
			rawdata: initialData.rawdata,
			sizes: Immutable.fromJS({}),
			selection:initialData.defSelection,
			sortCache: initialData.defSortCache,
			allSelected: false,
			sendSorted: false
		};
	}

	componentWillMount() {
		this.uniqueId = this.props.uniqueId || _.uniqueId('propertable-');

		// Sort the table and apply filters if exist in props
		this.applySettings();

		// Add new click listener if exist
		if (this.props.restartOnClick) {
			this.addClickListener(this.props.restartOnClick);
		}
	}

	componentDidMount() {
		// In some cases the callback of setState it's called before the new state is set up so we use a flag to prevent this.
		if (this.state.sendSorted) {
			this.setState({
				sendSorted: false
			}, this.sendSortedAndSettings(this.state.data, this.state.colSettings));
		} else {
			this.sendColSettings(this.state.colSettings);
		}
	}

	componentWillUnmount() {
		cache.flush('formatted');

		// Remove listener if exist
		if (this.props.restartOnClick) {
			this.removeClickListener(this.props.restartOnClick);
		}
	}

	shouldComponentUpdate(nextProps, nextState) {
		let propschanged = !shallowEqualImmutable(this.props, nextProps);
		let statechanged = !shallowEqualImmutable(this.state, nextState);
		let somethingchanged = propschanged || statechanged;

		if (propschanged) {
			let colsChanged = !shallowEqualImmutable(nextProps.cols, this.props.cols);
			let dataChanged = !shallowEqualImmutable(nextProps.data, this.props.data);
			let colSortDirsChanged = nextProps.colSortDirs ? !shallowEqualImmutable(nextProps.colSortDirs, this.props.colSortDirs) : false;
			let colFiltersChanged = nextProps.colFilters ? !shallowEqualImmutable(nextProps.colFilters, this.props.colFilters) : false;
			let colData = null, preparedData = null;

			// If data and columns change the colSettings and all data states must be updated. Then apply default (sort table
			// and set selection if it has been received). If both change It's almost the same as rebuild the component. Almost everything changes
			if (colsChanged || dataChanged) {
				cache.flush('formatted');

				if (dataChanged) { // The most probably case
					let colSettings = nextState.colSettings;
					preparedData = this.prepareData(nextProps, nextState);

{'fraction_non_alphanumeric': 0.11762303451092505, 'fraction_numerical': 0.002246273228507249, 'mean_word_length': 3.9620060790273555, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, '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': '7192270', 'n_tokens_mistral': 3306, 'n_tokens_neox': 3020, 'n_words': 841}