bodyFoundation.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. newExpandRelatedProps = expandRelatedProps.map(key => get(props, key, undefined));
  30. }
  31. this._adapter.setCachedExpandRelatedProps(newExpandRelatedProps);
  32. }
  33. flattenData(dataSource: any[] = [], level = 0, parentKeys: any[] = [], childrenKeys: any[] = []) {
  34. const flattenData: Array<FlattenData | GroupFlattenData> = [];
  35. const { rowKey, childrenRecordName, expandedRowRender, expandedRowKeys, groups } = this.getProps();
  36. if (level === 0 && isMap(groups)) {
  37. groups.forEach((set, key) => {
  38. const firstIndex = dataSource.findIndex(record => set.has(getRecordKey(record, rowKey)));
  39. if (firstIndex > -1) {
  40. const lastIndex = findLastIndex(dataSource, record => set.has(getRecordKey(record, rowKey)));
  41. const expanded = includes(expandedRowKeys, key);
  42. flattenData.push({
  43. key,
  44. level,
  45. sectionRow: true,
  46. group: set,
  47. groupKey: key,
  48. expanded,
  49. });
  50. if (expanded) {
  51. flattenData.push(
  52. ...this.flattenData(
  53. dataSource.slice(firstIndex, lastIndex + 1),
  54. level + 1,
  55. [...parentKeys],
  56. [...childrenKeys]
  57. )
  58. );
  59. }
  60. }
  61. });
  62. } else {
  63. dataSource.forEach((record, index) => {
  64. const recordKey = getRecordKey(record, rowKey);
  65. const children = getRecordChildren(record, childrenRecordName);
  66. if (level) {
  67. childrenKeys.push(recordKey);
  68. }
  69. const item = {
  70. key: recordKey,
  71. record,
  72. level,
  73. parentKeys: [...parentKeys],
  74. childrenKeys: [...childrenKeys],
  75. };
  76. flattenData.push(item);
  77. const extras = [];
  78. if (includes(expandedRowKeys, recordKey)) {
  79. if (Array.isArray(children) && children.length) {
  80. extras.push(
  81. ...this.flattenData(children, level + 1, [...item.parentKeys], [...item.childrenKeys])
  82. );
  83. } else if (expandedRowRender) {
  84. extras.push({
  85. key: genExpandedRowKey(recordKey),
  86. level,
  87. expandedRow: true,
  88. record,
  89. });
  90. }
  91. flattenData.push(...extras);
  92. }
  93. });
  94. }
  95. return flattenData;
  96. }
  97. /**
  98. * Use ResizeObserver to monitor changes in the size of the body content area, and notify Table to recalculate if it changes. columns #1219
  99. * (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)
  100. */
  101. observeBodyResize(bodyDOM: any) {
  102. const { scroll } = this.getProps(); // TODO check: this._adapter.getProps -> this.getProps
  103. if (get(scroll, 'y')) {
  104. return this._adapter.observeBodyResize(bodyDOM);
  105. }
  106. }
  107. unobserveBodyResize() {
  108. return this._adapter.unobserveBodyResize();
  109. }
  110. }
  111. export interface GroupFlattenData {
  112. key: number | string;
  113. level: number;
  114. sectionRow: boolean;
  115. group: Map<string, Record<string, any>[]>;
  116. groupKey: number;
  117. expanded: boolean
  118. }
  119. export interface FlattenData {
  120. key: number | string;
  121. record: Record<string, any>;
  122. level: number;
  123. parentKeys?: any[];
  124. childrenKeys?: any[];
  125. expandedRow?: boolean;
  126. sectionRow?: boolean
  127. }