import BaseFoundation, { DefaultAdapter } from '../base/foundation'; import { get, includes, isMap, findLastIndex, isObject } from 'lodash'; import { strings } from './constants'; import { getRecordKey, genExpandedRowKey, getRecordChildren, expandBtnShouldInRow } from './utils'; export interface BodyAdapter

, S = Record> extends DefaultAdapter { setVirtualizedData: (virtualizedData: any[], cb: () => void) => void; setCachedExpandBtnShouldInRow: (cachedExpandBtnShouldInRow: boolean) => void; setCachedExpandRelatedProps: (cachedExpandRelatedProps: string[]) => void; observeBodyResize: (bodyWrapDOM: any) => void; unobserveBodyResize: () => void } export default class TableBodyFoundation

, S = Record> extends BaseFoundation, P, S> { init() { this.initVirtualizedData(); this.initExpandBtnShouldInRow(); } destroy() { this.unobserveBodyResize(); } initVirtualizedData(cb?: (...args: any[]) => void) { this._adapter.setVirtualizedData(this.flattenData(this.getProp('dataSource')), cb); } initExpandBtnShouldInRow(newExpandRelatedProps?: any[]) { const props = this.getProps(); // TODO check: this._adapter.getProps -> this.getProps const cachedExpandBtnShouldInRow = expandBtnShouldInRow(props); this._adapter.setCachedExpandBtnShouldInRow(cachedExpandBtnShouldInRow); if (!isObject(newExpandRelatedProps) && !newExpandRelatedProps) { const expandRelatedProps = strings.EXPAND_RELATED_PROPS; // eslint-disable-next-line no-param-reassign newExpandRelatedProps = expandRelatedProps.map(key => get(props, key, undefined)); } this._adapter.setCachedExpandRelatedProps(newExpandRelatedProps); } flattenData(dataSource: any[] = [], level = 0, parentKeys: any[] = [], childrenKeys: any[] = []) { const flattenData: Array = []; const { rowKey, childrenRecordName, expandedRowRender, expandedRowKeys, groups } = this.getProps(); if (level === 0 && isMap(groups)) { groups.forEach((set, key) => { const firstIndex = dataSource.findIndex(record => set.has(getRecordKey(record, rowKey))); if (firstIndex > -1) { const lastIndex = findLastIndex(dataSource, record => set.has(getRecordKey(record, rowKey))); const expanded = includes(expandedRowKeys, key); flattenData.push({ key, level, sectionRow: true, group: set, groupKey: key, expanded, }); if (expanded) { flattenData.push( ...this.flattenData( dataSource.slice(firstIndex, lastIndex + 1), level + 1, [...parentKeys], [...childrenKeys] ) ); } } }); } else { dataSource.forEach((record, index) => { const recordKey = getRecordKey(record, rowKey); const children = getRecordChildren(record, childrenRecordName); if (level) { childrenKeys.push(recordKey); } const item = { key: recordKey, record, level, parentKeys: [...parentKeys], childrenKeys: [...childrenKeys], }; flattenData.push(item); const extras = []; if (includes(expandedRowKeys, recordKey)) { if (Array.isArray(children) && children.length) { extras.push( ...this.flattenData(children, level + 1, [...item.parentKeys], [...item.childrenKeys]) ); } else if (expandedRowRender) { extras.push({ key: genExpandedRowKey(recordKey), level, expandedRow: true, record, }); } flattenData.push(...extras); } }); } return flattenData; } /** * Use ResizeObserver to monitor changes in the size of the body content area, and notify Table to recalculate if it changes. columns #1219 * (Only monitor the scroll.y scene, other scenes are not monitored, because the header of the scroll.y scene is a separate table, and a scrollbar column will be inserted) */ observeBodyResize(bodyDOM: any) { const { scroll } = this.getProps(); // TODO check: this._adapter.getProps -> this.getProps if (get(scroll, 'y')) { return this._adapter.observeBodyResize(bodyDOM); } } unobserveBodyResize() { return this._adapter.unobserveBodyResize(); } } export interface GroupFlattenData { key: number | string; level: number; sectionRow: boolean; group: Map[]>; groupKey: number; expanded: boolean } export interface FlattenData { key: number | string; record: Record; level: number; parentKeys?: any[]; childrenKeys?: any[]; expandedRow?: boolean; sectionRow?: boolean }