index.tsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import {Spin, Pagination} from 'antd';
  2. import {
  3. createTablePageContext,
  4. createTableSearchContext,
  5. createTableSettingContext,
  6. useTablePageContext,
  7. useTableSearchContext,
  8. } from '@hooks';
  9. import {PAGE_SIZE_LIST, TABLE_CELL_WIDTH} from '@utils';
  10. import {
  11. Dispatch,
  12. ReactElement,
  13. ReactNode,
  14. SetStateAction,
  15. useEffect,
  16. useState,
  17. } from 'react';
  18. import {useTable, useTableShadow} from './hooks';
  19. import {ColumnSort, Row, RowSelectionState} from '@tanstack/react-table';
  20. import './index.css';
  21. import {ModifyData} from '@models';
  22. import TableHead from './Header';
  23. import TableBody from './Body';
  24. import {klona} from 'klona/json';
  25. type GroupKey<T extends Record<string, unknown>> = keyof T extends string
  26. ? `${keyof T}Group`
  27. : never;
  28. export type LDColumnsType<T extends Record<string, unknown>> = {
  29. dataIndex: keyof T | GroupKey<T>,
  30. title: string,
  31. width: number,
  32. render?: (info: T, index: number, row: Row<Record<string, any>>) => ReactNode,
  33. align?: 'left' | 'right' | 'center',
  34. fixed?: 'left' | 'right',
  35. sort?: boolean,
  36. children?: LDColumnsType<T>[],
  37. };
  38. type Props<T extends Record<string, unknown>> = {
  39. columns: LDColumnsType<T>[];
  40. data: T[];
  41. pageContext: ReturnType<typeof createTablePageContext>;
  42. searchContext: ReturnType<typeof createTableSearchContext>;
  43. settingContext: ReturnType<typeof createTableSettingContext>;
  44. count: number;
  45. 'data-testid'?: string;
  46. pageSizeList?: string[];
  47. isSecondLevel?: boolean;
  48. rowSelection?: RowSelectionState;
  49. setRowSelection?: Dispatch<SetStateAction<RowSelectionState>>;
  50. disabledHeadSort?: boolean;
  51. disabledSizeChange?: boolean;
  52. highlightValue?: unknown;
  53. hightlightKey?: keyof T;
  54. enableRowDnd?: boolean;
  55. rawKey?: keyof T;
  56. onSortingChange?: (state: ColumnSort | null) => void;
  57. subRowKey?: keyof T;
  58. renderSubComponent?: (row: Row<Record<string, any>>) => ReactNode;
  59. };
  60. function LDTable<T extends Record<string, any>>(props: Props<T>): ReactElement {
  61. const {
  62. columns,
  63. data,
  64. pageContext,
  65. searchContext,
  66. count,
  67. pageSizeList = PAGE_SIZE_LIST,
  68. isSecondLevel,
  69. rowSelection,
  70. setRowSelection,
  71. settingContext,
  72. disabledHeadSort,
  73. disabledSizeChange,
  74. highlightValue,
  75. hightlightKey,
  76. rawKey,
  77. enableRowDnd,
  78. onSortingChange,
  79. subRowKey,
  80. renderSubComponent,
  81. } = props;
  82. const [klonaData, setKlonaData] = useState(klona(data));
  83. const [{page, pageSize}, {setPageContext}] = useTablePageContext(pageContext);
  84. const [{isSearching}] = useTableSearchContext(searchContext);
  85. useEffect(function() {
  86. enableRowDnd && setKlonaData(klona(data));
  87. }, [data, enableRowDnd]);
  88. const [
  89. {
  90. getHeaderGroups, getRowModel, getCenterTotalSize,
  91. active, hasSort, hasGroup,
  92. },
  93. {onDragEnd, onDragStart},
  94. ] = useTable(
  95. columns,
  96. enableRowDnd ? klonaData : data,
  97. {
  98. settingContext,
  99. rowSelection,
  100. setRowSelection,
  101. rawKey,
  102. onSortingChange,
  103. subRowKey,
  104. hasRenderSubComponent: Boolean(renderSubComponent),
  105. },
  106. );
  107. const {
  108. scrollProgess,
  109. scrollTableRef,
  110. headerTableRef,
  111. } = useTableShadow(getCenterTotalSize());
  112. return (
  113. <Spin spinning={isSearching}>
  114. <div
  115. className="ld-table-wrapper"
  116. id={props['data-testid'] ?? 'ld_table_wrapper'}
  117. data-testid={props['data-testid']}
  118. >
  119. <TableHead
  120. ref={headerTableRef}
  121. isSecondLevel={isSecondLevel}
  122. disabledHeadSort={disabledHeadSort || hasGroup}
  123. disabledSizeChange={disabledSizeChange}
  124. active={active}
  125. getHeaderGroups={getHeaderGroups}
  126. onDragStart={onDragStart}
  127. onDragEnd={onDragEnd}
  128. columns={columns}
  129. scrollProgess={scrollProgess}
  130. getCenterTotalSize={getCenterTotalSize}
  131. />
  132. <TableBody
  133. ref={scrollTableRef}
  134. scrollProgess={scrollProgess}
  135. getCenterTotalSize={getCenterTotalSize}
  136. getRowModel={getRowModel}
  137. highlightValue={highlightValue}
  138. hightlightKey={hightlightKey}
  139. getHeaderGroups={getHeaderGroups}
  140. data={klonaData}
  141. rawKey={rawKey}
  142. enableDnd={enableRowDnd && (!hasSort || Boolean(onSortingChange))}
  143. setData={setKlonaData}
  144. isSecondLevel={isSecondLevel}
  145. renderSubComponent={renderSubComponent}
  146. />
  147. </div>
  148. <Pagination
  149. className="ld-table-pagination"
  150. pageSize={pageSize}
  151. showQuickJumper
  152. pageSizeOptions={pageSizeList}
  153. total={count}
  154. showSizeChanger
  155. onChange={(page, pageSize) => setPageContext({page, pageSize})}
  156. current={page}
  157. showTotal={total => `共${total}条数据`}
  158. />
  159. </Spin>
  160. );
  161. }
  162. export default LDTable;
  163. export const modifyDataColumns: LDColumnsType<ModifyData>[] = [
  164. {
  165. title: '最后修改人',
  166. dataIndex: 'modifyUser',
  167. width: TABLE_CELL_WIDTH.normal,
  168. },
  169. {
  170. title: '最后修改时间',
  171. dataIndex: 'modifyTime',
  172. width: TABLE_CELL_WIDTH.date,
  173. },
  174. ];