bodyFoundation.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import BaseFoundation, { DefaultAdapter } from '../base/foundation';
  2. import { get, includes, isMap, findLastIndex, isObject } from 'lodash';
  3. import { strings } from './constants';
  4. import { getRecordKey, genExpandedRowKey, getRecordChildren, expandBtnShouldInRow } from './utils';
  5. export interface BodyAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
  6. setVirtualizedData: (virtualizedData: any[], cb: () => void) => void;
  7. setCachedExpandBtnShouldInRow: (cachedExpandBtnShouldInRow: boolean) => void;
  8. setCachedExpandRelatedProps: (cachedExpandRelatedProps: string[]) => void;
  9. observeBodyResize: (bodyWrapDOM: any) => void;
  10. unobserveBodyResize: () => void;
  11. }
  12. export default class TableBodyFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<BodyAdapter<P, S>, P, S> {
  13. init() {
  14. this.initVirtualizedData();
  15. this.initExpandBtnShouldInRow();
  16. }
  17. destroy() {
  18. this.unobserveBodyResize();
  19. }
  20. initVirtualizedData(cb?: (...args: any[]) => void) {
  21. this._adapter.setVirtualizedData(this.flattenData(this.getProp('dataSource')), cb);
  22. }
  23. initExpandBtnShouldInRow(newExpandRelatedProps?: any[]) {
  24. const props = this.getProps(); // TODO check: this._adapter.getProps -> this.getProps
  25. const cachedExpandBtnShouldInRow = expandBtnShouldInRow(props);
  26. this._adapter.setCachedExpandBtnShouldInRow(cachedExpandBtnShouldInRow);
  27. if (!isObject(newExpandRelatedProps) && !newExpandRelatedProps) {
  28. const expandRelatedProps = strings.EXPAND_RELATED_PROPS;
  29. // eslint-disable-next-line no-param-reassign
  30. newExpandRelatedProps = expandRelatedProps.map(key => get(props, key, undefined));
  31. }
  32. this._adapter.setCachedExpandRelatedProps(newExpandRelatedProps);
  33. }
  34. flattenData(dataSource: any[] = [], level = 0, parentKeys: any[] = [], childrenKeys: any[] = []) {
  35. const flattenData: Array<FlattenData | GroupFlattenData> = [];
  36. const { rowKey, childrenRecordName, expandedRowRender, expandedRowKeys, groups } = this.getProps();
  37. if (level === 0 && isMap(groups)) {
  38. groups.forEach((set, key) => {
  39. const firstIndex = dataSource.findIndex(record => set.has(getRecordKey(record, rowKey)));
  40. if (firstIndex > -1) {
  41. const lastIndex = findLastIndex(dataSource, record => set.has(getRecordKey(record, rowKey)));
  42. const expanded = includes(expandedRowKeys, key);
  43. flattenData.push({
  44. key,
  45. level,
  46. sectionRow: true,
  47. group: set,
  48. groupKey: key,
  49. expanded,
  50. });
  51. if (expanded) {
  52. flattenData.push(
  53. ...this.flattenData(
  54. dataSource.slice(firstIndex, lastIndex + 1),
  55. level + 1,
  56. [...parentKeys],
  57. [...childrenKeys]
  58. )
  59. );
  60. }
  61. }
  62. });
  63. } else {
  64. dataSource.forEach((record, index) => {
  65. const recordKey = getRecordKey(record, rowKey);
  66. const children = getRecordChildren(record, childrenRecordName);
  67. if (level) {
  68. childrenKeys.push(recordKey);
  69. }
  70. const item = {
  71. key: recordKey,
  72. record,
  73. level,
  74. parentKeys: [...parentKeys],
  75. childrenKeys: [...childrenKeys],
  76. };
  77. flattenData.push(item);
  78. const extras = [];
  79. if (includes(expandedRowKeys, recordKey)) {
  80. if (Array.isArray(children) && children.length) {
  81. extras.push(
  82. ...this.flattenData(children, level + 1, [...item.parentKeys], [...item.childrenKeys])
  83. );
  84. } else if (expandedRowRender) {
  85. extras.push({
  86. key: genExpandedRowKey(recordKey),
  87. level,
  88. expandedRow: true,
  89. record,
  90. });
  91. }
  92. flattenData.push(...extras);
  93. }
  94. });
  95. }
  96. return flattenData;
  97. }
  98. /**
  99. * Use ResizeObserver to monitor changes in the size of the body content area, and notify Table to recalculate if it changes. columns #1219
  100. * (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)
  101. */
  102. observeBodyResize(bodyDOM: any) {
  103. const { scroll } = this.getProps(); // TODO check: this._adapter.getProps -> this.getProps
  104. if (get(scroll, 'y')) {
  105. return this._adapter.observeBodyResize(bodyDOM);
  106. }
  107. }
  108. unobserveBodyResize() {
  109. return this._adapter.unobserveBodyResize();
  110. }
  111. }
  112. export interface GroupFlattenData {
  113. key: number | string;
  114. level: number;
  115. sectionRow: boolean;
  116. group: Map<string, Record<string, any>[]>;
  117. groupKey: number;
  118. expanded: boolean;
  119. }
  120. export interface FlattenData {
  121. key: number | string;
  122. record: Record<string, any>;
  123. level: number;
  124. parentKeys?: any[];
  125. childrenKeys?: any[];
  126. expandedRow?: boolean;
  127. sectionRow?: boolean;
  128. }