| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505 | /* eslint-disable max-len *//* eslint-disable no-param-reassign *//* eslint-disable eqeqeq */import {    cloneDeepWith,    isEqualWith,    get,    filter,    find,    map,    clone as lodashClone,    each,    findIndex,    some,    includes,    toString,    isFunction} from 'lodash';import { strings, numbers } from './constants';import isNullOrUndefined from '../utils/isNullOrUndefined';import Logger from '../utils/Logger';export function cloneDeep(value: any, customizer?: (v: any) => any) {    return cloneDeepWith(value, v => {        if (typeof v === 'function') {            return v;        } else if (typeof customizer === 'function') {            return customizer(v);        }        return undefined;    });}export function equalWith(value: any, other: any, customizer?: (...args: any[]) => boolean) {    return isEqualWith(value, other, (objVal, othVal, ...rest) => {        if (typeof objVal === 'function' && typeof othVal === 'function') {            return toString(objVal) === toString(othVal);        }        if (typeof customizer === 'function') {            return customizer(objVal, othVal, ...rest);        }        // If customizer returns undefined, comparisons are handled by isEqual instead        return undefined;    });}export function getColumnKey(column: any, keyPropNames: any[]): any {    keyPropNames = Array.isArray(keyPropNames) ? keyPropNames : ['key', 'dataIndex'];    let key = null;    each(keyPropNames, propName => {        key = get(column, propName);        if (key != null) {            return false;        }        return undefined;    });    return key;}export function mergeColumns(oldColumns: any[] = [], newColumns: any[] = [], keyPropNames: any[] = null, deep = true) {    const finalColumns: any[] = [];    const clone = deep ? cloneDeep : lodashClone;    map(newColumns, newColumn => {        newColumn = { ...newColumn };        const key = getColumnKey(newColumn, keyPropNames);        const oldColumn = key != null && find(oldColumns, item => getColumnKey(item, keyPropNames) === key);        if (oldColumn) {            finalColumns.push(                clone({                    ...oldColumn,                    ...newColumn,                })            );        } else {            finalColumns.push(clone(newColumn));        }    });    return finalColumns;}/** * * @param {Array<number>} arr * @param {number} [beginIndex] begin index, included * @param {number} [endIndex] end index, not included * @returns {number} */export function arrayAdd(arr: any[] = [], beginIndex = 0, endIndex?: number) {    beginIndex = beginIndex < 0 || typeof beginIndex !== 'number' ? 0 : beginIndex;    endIndex = endIndex > arr.length || typeof endIndex !== 'number' ? arr.length : endIndex;    let result = 0;    each(arr, (value, index) => {        if (index >= beginIndex && index < endIndex) {            result += typeof value === 'number' && !isNaN(value) ? value : 0;        }    });    return result;}export function isLastLeftFixed(columns: Record<string, any>[], column: Record<string, any>, checkKeys = ['key']) {    const leftFixedColumns = filter(columns, col => col.fixed === true || col.fixed === 'left');    const index = findIndex(leftFixedColumns, col =>        checkKeys.every(key => col[key] != null && col[key] === column[key])    );    return leftFixedColumns.length > 0 && index === leftFixedColumns.length - 1;}export function isFirstFixedRight(columns: Record<string, any>[], column: Record<string, any>, checkKeys = ['key']) {    const rightFixedColumns = filter(columns, col => col.fixed === 'right');    const index = findIndex(rightFixedColumns, col =>        checkKeys.every(key => col[key] != null && col[key] === column[key])    );    return rightFixedColumns.length > 0 && index === 0;}export function isAnyFixed(columns: Record<string, any>[], fixedSet = ['left', true, 'right']) {    if (typeof fixedSet === 'string' || typeof fixedSet === 'boolean') {        fixedSet = [fixedSet];    }    return fixedSet.length > 0 && some(columns, col => fixedSet.includes(col.fixed));}export function isAnyFixedRight(columns: Record<string, any>[]) {    return some(columns, col => col.fixed === 'right');}export function isFixedLeft(column: Record<string, any>) {    return ['left', true].includes(get(column, 'fixed'));}export function isFixedRight(column: Record<string, any>) {    return ['right'].includes(get(column, 'fixed'));}export function isFixed(column: Record<string, any>) {    return isFixedLeft(column) || isFixedRight(column);}export function isInnerColumnKey(key: string | number) {    return [        strings.DEFAULT_KEY_COLUMN_EXPAND,        strings.DEFAULT_KEY_COLUMN_SCROLLBAR,        strings.DEFAULT_KEY_COLUMN_SELECTION,    ].includes(key as any);}export function isExpandedColumn(column: Record<string, any>) {    return get(column, 'key') === strings.DEFAULT_KEY_COLUMN_EXPAND;}export function isScrollbarColumn(column: Record<string, any>) {    return get(column, 'key') === strings.DEFAULT_KEY_COLUMN_SCROLLBAR;}export function isSelectionColumn(column: Record<string, any>) {    return get(column, 'key') === strings.DEFAULT_KEY_COLUMN_SELECTION;}export function filterColumns(columns: Record<string, any>[], ignoreKeys = [strings.DEFAULT_KEY_COLUMN_SCROLLBAR as string]) {    return filter(columns, col => !ignoreKeys.includes(col.key));}/** * get width of scroll bar * @param {Array} columns * @returns {Number|undefined} */export function getScrollbarColumnWidth(columns: Record<string, any>[] = []) {    const len = columns.length;    if (len) {        const lastColumn = columns[len - 1];        if (get(lastColumn, 'key') === strings.DEFAULT_KEY_COLUMN_SCROLLBAR) {            return get(lastColumn, 'width', 0);        }    }}export function getRecordKey(record: Record<string, any>, rowKey: string | number | ((record: any) => string | number)) {    if (rowKey === undefined) {        rowKey = 'key';    }    return typeof rowKey === 'function' ? rowKey(record) : get(record, rowKey);}/** * Determine whether the expandedRowKeys includes a key (rowKey will be added to expandedRowKeys when the expand button is clicked) * @param {*} expandedRowKeys * @param {*} key */export function isExpanded(expandedRowKeys: (string | number)[], key: string | number) {    return key != null && includes(expandedRowKeys, key);}/** * Determine whether the selectedKeysSet includes the key * @param {Set} selectedRowKeysSet * @param {String} key */export function isSelected(selectedRowKeysSet: Set<string | number>, key: string | number) {    return key !== null && selectedRowKeysSet.has(key);}/** * Whether the key is included in the disabledRowKeysSet * @param {Set} disabledRowKeysSet * @param {String} key */export function isDisabled(disabledRowKeysSet: Set<string | number>, key: string | number) {    return key !== null && disabledRowKeysSet.has(key);}export function getRecord(data: any[], recordKey: string | number, rowKey: string | number | ((record: any) => string | number)) {    if (rowKey === undefined) {        rowKey = 'key';    }    return find(data, record => recordKey != null && recordKey !== '' && getRecordKey(record, rowKey) === recordKey);}export function getRecordChildren(record: Record<string, any>, childrenRecordName: string) {    if (childrenRecordName === undefined) {        childrenRecordName = 'children';    }    return get(record, childrenRecordName);}export function genExpandedRowKey(recordKey = '', suffix?: string) {    if (suffix === undefined) {        suffix = '__expanded_row';    }    return recordKey + suffix;}export function getDefaultVirtualizedRowConfig(size = '', sectionRow = false) {    const config: { height?: number; minHeight?: number } = {};    if (size === 'small') {        config.height = sectionRow ?            numbers.DEFAULT_VIRTUALIZED_SECTION_ROW_SMALL_HEIGHT :            numbers.DEFAULT_VIRTUALIZED_ROW_SMALL_HEIGHT;        config.minHeight = numbers.DEFAULT_VIRTUALIZED_ROW_SMALL_MIN_HEIGHT;    } else if (size === 'middle') {        config.height = sectionRow ?            numbers.DEFAULT_VIRTUALIZED_SECTION_ROW_MIDDLE_HEIGHT :            numbers.DEFAULT_VIRTUALIZED_ROW_MIDDLE_HEIGHT;        config.minHeight = numbers.DEFAULT_VIRTUALIZED_ROW_MIDDLE_MIN_HEIGHT;    } else {        config.height = sectionRow ?            numbers.DEFAULT_VIRTUALIZED_SECTION_ROW_HEIGHT :            numbers.DEFAULT_VIRTUALIZED_ROW_HEIGHT;        config.minHeight = numbers.DEFAULT_VIRTUALIZED_ROW_MIN_HEIGHT;    }    return config;}export function flattenColumns(cols: Record<string, any>[], childrenColumnName = 'children'): Record<string, any>[] {    const list = [];    if (Array.isArray(cols) && cols.length) {        for (const col of cols) {            if (Array.isArray(col[childrenColumnName]) && col[childrenColumnName].length) {                list.push(...flattenColumns(col[childrenColumnName], childrenColumnName));            } else {                warnIfNoDataIndex(col);                list.push(col);            }        }    }    return list;}export function assignColumnKeys(columns: Record<string, any>[], childrenColumnName = 'children', level = 0) {    const sameLevelCols: Record<string, any>[] = [];    each(columns, (column, index) => {        if (column.key == null) {            // if user give column a dataIndex, use it for backup            const _index = column.dataIndex || index;            column.key = `${level}-${_index}`;        }        if (Array.isArray(column[childrenColumnName]) && column[childrenColumnName].length) {            sameLevelCols.push(...column[childrenColumnName]);        }    });    if (sameLevelCols.length) {        assignColumnKeys(sameLevelCols, childrenColumnName, level + 1);    }    return columns;}export function sliceColumnsByLevel(columns: any[], targetLevel = 0, childrenColumnName = 'children', currentLevel = 0) {    const slicedColumns: any[] = [];    if (Array.isArray(columns) && columns.length && currentLevel <= targetLevel) {        columns.forEach(column => {            const children = column[childrenColumnName];            if (Array.isArray(children) && children.length && currentLevel < targetLevel) {                slicedColumns.push(...sliceColumnsByLevel(children, targetLevel, childrenColumnName, currentLevel + 1));            } else {                slicedColumns.push(column);            }        });    }    return slicedColumns;}export function getColumnsByLevel(    columns: Record<string, any>[],    targetLevel = 0,    targetColumns: Record<string, any>[] = [],    currentLevel = 0,    childrenColumnName = 'children') {    if (Array.isArray(columns) && columns.length) {        if (targetLevel === currentLevel) {            targetColumns.push(...columns);        } else {            columns.forEach(column => {                getColumnsByLevel(                    column[childrenColumnName],                    targetLevel,                    targetColumns,                    currentLevel + 1,                    childrenColumnName                );            });        }    }    return targetColumns;}export function getAllLevelColumns(columns: Record<string, any>[], childrenColumnName = 'children') {    const all = [];    if (Array.isArray(columns) && columns.length) {        all.push([...columns]);        const sameLevelColumns: Record<string, any>[] = [];        columns.forEach(column => {            const children = column[childrenColumnName];            if (Array.isArray(children) && children.length) {                sameLevelColumns.push(...children);            }        });        if (sameLevelColumns.length) {            all.push(sameLevelColumns);        }    }    return all;}export function getColumnByLevelIndex(columns: Record<string, any>[], index: number, level = 0, childrenColumnName = 'children') {    const allLevelColumns = getAllLevelColumns(columns, childrenColumnName);    return allLevelColumns[level][index];}export function findColumn(columns: Record<string, any>[], column: Record<string, any>, childrenColumnName = 'children') {    let found: any;    each(columns, item => {        if (item && item.key != null && !found) {            if (item.key === column.key) {                found = item;            }        }        if (item && Array.isArray(item[childrenColumnName]) && !found) {            found = findColumn(item[childrenColumnName], column, childrenColumnName);        }        if (found) {            return false;        }        return undefined;    });    return found;}export function expandBtnShouldInRow(props: ExpandBtnShouldInRowProps) {    const { expandedRowRender, dataSource, hideExpandedColumn, childrenRecordName, rowExpandable } = props;    const hasExpandedRowRender = typeof expandedRowRender === 'function';    return (        (hideExpandedColumn && hasExpandedRowRender) ||        (!hasExpandedRowRender && dataSource.some(record => {            const children = get(record, childrenRecordName);            if ((Array.isArray(children) && children.length) || rowExpandable(record)) {                return true;            } else {                return false;            }        }))    );}export type ExpandBtnShouldInRowProps = {    expandedRowRender: (record?: Record<string, any>, index?: number, expanded?: boolean) => any;    dataSource: Record<string, any>[];    hideExpandedColumn: boolean;    childrenRecordName: string;    rowExpandable: (record?: Record<string, any>) => boolean;};/** * merge query * @param {*} query * @param {*} queries */export function mergeQueries(query: Record<string, any>, queries: Record<string, any>[] = []) {    let _mergedQuery;    const idx = queries.findIndex(item => {        if (query.dataIndex === item.dataIndex) {            _mergedQuery = { ...item, ...query };            return true;        }        return false;    });    if (idx > -1) {        queries.splice(idx, 1, _mergedQuery);    } else {        queries.push(_mergedQuery);    }    return [...queries];}/** * Replace the width of the newColumns column with the width of the column after resize * @param {Object[]} columns columns retain the column width after resize * @param {Object[]} newColumns */export function withResizeWidth(columns: Record<string, any>[], newColumns: Record<string, any>[]) {    const _newColumns = cloneDeep(newColumns);    for (const column of columns) {        if (!isNullOrUndefined(column.width)) {            const currentColumn = column.key;            const columnIndex = findIndex(_newColumns, item => (item as any).key === currentColumn);            if (columnIndex !== -1) {                _newColumns[columnIndex].width = get(column, 'width');            }        }    }    return _newColumns;}/** * Pure function version of the same function in table foundation * This is not accessible in getDerivedStateFromProps, so fork one out */export function getAllDisabledRowKeys({ dataSource, getCheckboxProps, childrenRecordName, rowKey }: GetAllDisabledRowKeysProps): (string | number)[] {    const disabledRowKeys = [];    if (Array.isArray(dataSource) && dataSource.length && typeof getCheckboxProps === 'function') {        for (const record of dataSource) {            const props = getCheckboxProps(record);            const recordKey = typeof rowKey === 'function' ? rowKey(record) : get(record, rowKey);            if (props && props.disabled) {                disabledRowKeys.push(recordKey);            }            const children = get(record, childrenRecordName);            if (Array.isArray(children) && children.length) {                const keys = getAllDisabledRowKeys({ dataSource: children, getCheckboxProps });                disabledRowKeys.push(...keys);            }        }    }    return disabledRowKeys;}export interface GetAllDisabledRowKeysProps {    dataSource: Record<string, any>[];    getCheckboxProps: (record?: Record<string, any>) => any;    childrenRecordName?: string;    rowKey?: string | number | ((record: Record<string, any>) => string | number);}export function warnIfNoDataIndex(column: Record<string, any>) {    if (typeof column === 'object' && column !== null) {        const { filters, sorter, dataIndex } = column;        const logger = new Logger('[@douyinfe/semi-ui Table]');        if ((Array.isArray(filters) || isFunction(sorter)) && isNullOrUndefined(dataIndex) ) {            logger.warn(`The column with sorter or filter must pass the 'dataIndex' prop`);        }    }}/** * Whether is tree table */export function isTreeTable({ dataSource, childrenRecordName = 'children' }: { dataSource: Record<string, any>; childrenRecordName?: string; }) {    let flag = false;    if (Array.isArray(dataSource)) {        for (const data of dataSource) {            const children = get(data, childrenRecordName);            if (Array.isArray(children) && children.length) {                flag = true;                break;            }        }    }    return flag;}
 |