<commit_before>/**
 * @file Thead component
 * @author liangxiaojun(<EMAIL>)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

// Components
import Th from '../_Th';

// Statics
import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';
import TableFragment from '../_statics/TableFragment';
import Direction from '../_statics/Direction';

// Vendors
import Util from '../_vendors/Util';
import TC from '../_vendors/TableCalculation';
import classNames from 'classnames';
import ScrollBar from '../_vendors/ScrollBar';

class Thead extends Component {

    static Align = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    getColumnsSpan = row => {

        const {tableData, onRequestColumnsSpan} = this.props;

        return onRequestColumnsSpan ?
            onRequestColumnsSpan(TableFragment.HEAD, row, tableData)
            :
            TC.getColumnsSpan(TableFragment.HEAD, row, tableData);

    };

    getStyle = (column, colIndex, columns) => {
        const {columnKeyField, columnsWidth, defaultColumnWidth, hasVerticalScroll} = this.props;
        return {
            ...column.headStyle,
            ...TC.getStickyColumnStyle(column?.fixed, colIndex, columns,
                columnKeyField, columnsWidth, defaultColumnWidth, hasVerticalScroll)
        };
    };

    handleClick = e => {
        const {tableData, disabled, onHeadClick} = this.props;
        !disabled && onHeadClick && onHeadClick(tableData, e);
    };

    render() {

        const {

                className, style, columns, columnsWidth, tableData, disabled, ignoreColumnSpan,
                hasFixedRightColumn, hasVerticalScroll, sorting, columnKeyField,
                defaultSortingType, sortingAscIconCls, sortingDescIconCls, defaultColumnWidth,
                onSortChange,

                ...restProps

            } = this.props,
            verticalScrollBarSize = ScrollBar.getSize(Direction.VERTICAL);

        return (
            <thead className={className}
                   style={style}
                   disabled="disabled"
                   onClick={this.handleClick}>
            {
                columns && columns.map((row, rowIndex) => {

                    if (!row) {
                        return null;
                    }

                    const columnsSpan = this.getColumnsSpan(row);

                    return (
                        <tr key={rowIndex}>

                            {
                                columnsSpan ?
                                    columnsSpan.map(({column, span}, colIndex) => column ?
                                        <Th {...restProps}
                                            key={colIndex}
                                            column={column}
                                            columnKeyField={columnKeyField}
                                            className={classNames(column.headClassName, {
                                                'fixed-left': column.fixed === HorizontalAlign.LEFT,
                                                'last-fixed-left': column.fixed === HorizontalAlign.LEFT
                                                    && columnsSpan?.[colIndex + 1]?.column?.fixed
                                                    !== HorizontalAlign.LEFT,
                                                'fixed-right': column.fixed === HorizontalAlign.RIGHT,
                                                'first-fixed-right': column.fixed === HorizontalAlign.RIGHT
                                                    && columnsSpan?.[colIndex - 1]?.column?.fixed
                                                    !== HorizontalAlign.RIGHT
                                            })}
                                            style={this.getStyle(column, colIndex, row)}
                                            width={(
                                                columnsWidth && columnKeyField
                                                && columnsWidth.get(TC.getColumnKey(column, columnKeyField))
                                            ) || defaultColumnWidth}
                                            tableData={tableData}
                                            title={column.headTitle}
                                            renderer={column.headRenderer}
                                            align={column.headAlign || column.align}
                                            colIndex={colIndex}
                                            rowSpan={column.rowSpan}
                                            colSpan={ignoreColumnSpan ? null : column.colSpan}
                                            noWrap={TC.handleNoWrap(column.headNoWrap, column.noWrap, {
                                                data: tableData,
                                                rowIndex,
                                                colIndex: colIndex,
                                                tableData
                                            })}
                                            sorting={sorting}
                                            defaultSortingType={column.defaultSortingType || defaultSortingType}
                                            sortingAscIconCls={sortingAscIconCls}
                                            sortingDescIconCls={sortingDescIconCls}
                                            sortable={column.sortable}
                                            sortingProp={column.sortingProp}
                                            onSortChange={onSortChange}/>
                                        :
                                        null
                                    )
                                    :
                                    null
                            }

                            {
                                hasVerticalScroll && columnsSpan && verticalScrollBarSize > 0 && rowIndex === 0 ?
                                    <th className={classNames('scroll-bar-th', {
                                        'fixed-right': hasFixedRightColumn
                                    })}
                                        style={{
                                            width: verticalScrollBarSize,
                                            ...(hasFixedRightColumn ? {
                                                position: 'sticky',
                                                right: 0
                                            } : null)
                                        }}
                                        rowSpan={columns.length}>
                                    </th>
                                    :
                                    null
                            }

                        </tr>
                    );

                })
            }
            </thead>
        );

    }
}

Thead.propTypes = {

    className: PropTypes.string,
    style: PropTypes.object,

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.shape({

        /**
         * unique keyof column.
         */
        key: PropTypes.string,

        /**<commit_msg>update Thead<commit_after>/**
 * @file Thead component
 * @author liangxiaojun(<EMAIL>)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

// Components
import Th from '../_Th';

// Statics
import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';
import TableFragment from '../_statics/TableFragment';
import Direction from '../_statics/Direction';

// Vendors
import Util from '../_vendors/Util';
import TC from '../_vendors/TableCalculation';
import classNames from 'classnames';
import ScrollBar from '../_vendors/ScrollBar';

class Thead extends Component {

    static Align = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    getColumnsSpan = row => {

        const {tableData, onRequestColumnsSpan} = this.props;

        return onRequestColumnsSpan ?
            onRequestColumnsSpan(TableFragment.HEAD, row, tableData)
            :
            TC.getColumnsSpan(TableFragment.HEAD, row, tableData);

    };

    getStyle = (column, colIndex, columns) => {
        const {columnKeyField, columnsWidth, defaultColumnWidth, hasVerticalScroll} = this.props;
        return {
            ...column.headStyle,
            ...TC.getStickyColumnStyle(
                column?.fixed, colIndex, columns, columnKeyField, columnsWidth, defaultColumnWidth, hasVerticalScroll
            )
        };
    };

    handleClick = e => {
        const {tableData, disabled} = this.props;
        !disabled && this.props.onHeadClick?.(tableData, e);
    };

    render() {

        const {

                className, style, columns, columnsWidth, tableData, disabled, ignoreColumnSpan,
                hasFixedRightColumn, hasVerticalScroll, sorting, columnKeyField,
                defaultSortingType, sortingAscIconCls, sortingDescIconCls, defaultColumnWidth,
                onSortChange,

                ...restProps

            } = this.props,
            verticalScrollBarSize = ScrollBar.getSize(Direction.VERTICAL);

        return (
            <thead className={className}
                   style={style}
                   disabled={disabled}
                   onClick={this.handleClick}>
                {
                    columns && columns.map((row, rowIndex) => {

                        if (!row) {
                            return null;
                        }

                        const columnsSpan = this.getColumnsSpan(row);

                        return (
                            <tr key={rowIndex}>

                                {
                                    columnsSpan ?
                                        columnsSpan.map(({column, span}, colIndex) => column ?
                                            <Th {...restProps}
                                                key={colIndex}
                                                column={column}
                                                columnKeyField={columnKeyField}
                                                className={classNames(column.headClassName, {
                                                    'fixed-left': column.fixed === HorizontalAlign.LEFT,
                                                    'last-fixed-left': column.fixed === HorizontalAlign.LEFT
                                                        && columnsSpan?.[colIndex + 1]?.column?.fixed
                                                        !== HorizontalAlign.LEFT,
                                                    'fixed-right': column.fixed === HorizontalAlign.RIGHT,
                                                    'first-fixed-right': column.fixed === HorizontalAlign.RIGHT
                                                        && columnsSpan?.[colIndex - 1]?.column?.fixed
                                                        !== HorizontalAlign.RIGHT
                                                })}
                                                style={this.getStyle(column, colIndex, row)}
                                                width={(
                                                    columnsWidth && columnKeyField
                                                    && columnsWidth.get(TC.getColumnKey(column, columnKeyField))
                                                ) || defaultColumnWidth}
                                                tableData={tableData}
                                                title={column.headTitle}
                                                renderer={column.headRenderer}
                                                align={column.headAlign || column.align}
                                                colIndex={colIndex}
                                                rowSpan={column.rowSpan}
                                                colSpan={ignoreColumnSpan ? null : column.colSpan}
                                                noWrap={TC.handleNoWrap(column.headNoWrap, column.noWrap, {
                                                    data: tableData,
                                                    rowIndex,
                                                    colIndex: colIndex,
                                                    tableData
                                                })}
                                                sorting={sorting}
                                                defaultSortingType={column.defaultSortingType || defaultSortingType}
                                                sortingAscIconCls={sortingAscIconCls}
                                                sortingDescIconCls={sortingDescIconCls}
                                                sortable={column.sortable}
                                                sortingProp={column.sortingProp}
                                                onSortChange={onSortChange}/>
                                            :
                                            null
                                        )
                                        :
                                        null
                                }

                                {
                                    hasVerticalScroll && columnsSpan && verticalScrollBarSize > 0 && rowIndex === 0 ?
                                        <th className={classNames('scroll-bar-th', {
                                            'fixed-right': hasFixedRightColumn
                                        })}
                                            style={{
                                                width: verticalScrollBarSize,
                                                ...(hasFixedRightColumn ? {
                                                    position: 'sticky',
                                                    right: 0
                                                } : null)
                                            }}
                                            rowSpan={columns.length}>
                                        </th>
                                        :
                                        null
                                }

                            </tr>
                        );

                    })
                }
            </thead>
        );

    }
}

Thead.propTypes = {

    className: PropTypes.string,
    style: PropTypes.object,

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.shape({

        /**
         * unique keyof column.
         */
        key: PropTypes.string,

        /**
{'fraction_non_alphanumeric': 0.07964772435073283, 'fraction_numerical': 0.0006428387760349704, 'mean_word_length': 0.8617759693633318, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 215, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1833271', 'n_tokens_mistral': 2895, 'n_tokens_neox': 2737, 'n_words': 548}