index.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. import React, { useState, useMemo } from 'react';
  2. import { Table, Button } from '@douyinfe/semi-ui/';
  3. import {IconArrowUp, IconArrowDown} from '@douyinfe/semi-icons';
  4. /**
  5. * Aligned to Ant Design APIs for migration, see [antd-demo](https://codesandbox.io/s/great-mcclintock-14fl7).
  6. */
  7. const Demo = () => {
  8. const childrenRecordName = 'children';
  9. const rowKey = 'key';
  10. const [expandedRowKeys, setExpandedRowKeys] = useState([1]);
  11. const [data, setData] = useState([
  12. {
  13. key: 1,
  14. name: 'John Brown sr.',
  15. age: 60,
  16. address: 'New York No. 1 Lake Park',
  17. children: [
  18. {
  19. key: 11,
  20. name: 'John Brown',
  21. age: 42,
  22. address: 'New York No. 2 Lake Park',
  23. },
  24. {
  25. key: 12,
  26. name: 'John Brown jr.',
  27. age: 30,
  28. address: 'New York No. 3 Lake Park',
  29. children: [
  30. {
  31. key: 121,
  32. name: 'Jimmy Brown',
  33. age: 16,
  34. address: 'New York No. 3 Lake Park',
  35. },
  36. ],
  37. },
  38. {
  39. key: 13,
  40. name: 'Jim Green sr.',
  41. age: 72,
  42. address: 'London No. 1 Lake Park',
  43. children: [
  44. {
  45. key: 131,
  46. name: 'Jim Green',
  47. age: 42,
  48. address: 'London No. 2 Lake Park',
  49. children: [
  50. {
  51. key: 1311,
  52. name: 'Jim Green jr.',
  53. age: 25,
  54. address: 'London No. 3 Lake Park',
  55. },
  56. {
  57. key: 1312,
  58. name: 'Jimmy Green sr.',
  59. age: 18,
  60. address: 'London No. 4 Lake Park',
  61. },
  62. ],
  63. },
  64. ],
  65. },
  66. ],
  67. },
  68. {
  69. key: 2,
  70. name: 'Joe Black',
  71. age: 32,
  72. address: 'Sidney No. 1 Lake Park',
  73. },
  74. ]);
  75. const switchRecord = (key1, key2) => {
  76. const newData = [...data];
  77. if (key1 != null && key2 != null) {
  78. const item1 = findRecordByKey(key1, newData);
  79. const item2 = findRecordByKey(key2, newData);
  80. // you have to copy item1 and item2 first
  81. const copiedItem1 = { ...item1 };
  82. const copiedItem2 = { ...item2 };
  83. coverRecord(item1, copiedItem2);
  84. coverRecord(item2, copiedItem1);
  85. setData(newData);
  86. }
  87. };
  88. const findRecordByKey = (key, data) => {
  89. if (Array.isArray(data) && data.length && key != null) {
  90. for (let item of data) {
  91. if (item[rowKey] === key) {
  92. return item;
  93. }
  94. const children = item[childrenRecordName];
  95. if (Array.isArray(children) && children.length) {
  96. const item = findRecordByKey(key, children);
  97. if (item != null) {
  98. return item;
  99. }
  100. }
  101. }
  102. }
  103. };
  104. const coverRecord = (obj, srcObj) => {
  105. if (obj && typeof obj === 'object' && srcObj && typeof srcObj === 'object') {
  106. const srcKeys = Object.keys(srcObj);
  107. const copied = { ...srcObj };
  108. Object.assign(obj, copied);
  109. Object.keys(obj).forEach(key => {
  110. if (!srcKeys.includes(key)) {
  111. delete obj[key];
  112. }
  113. });
  114. }
  115. return obj;
  116. };
  117. const getSameLevelRecords = (key, data = []) => {
  118. if (key != null && Array.isArray(data) && data.length) {
  119. if (data.find(item => item[rowKey] === key)) {
  120. return data;
  121. }
  122. for (let item of data) {
  123. const records = getSameLevelRecords(key, item[childrenRecordName]);
  124. if (records.length) {
  125. return records;
  126. }
  127. }
  128. }
  129. return [];
  130. };
  131. const columns = [
  132. {
  133. title: 'Name',
  134. dataIndex: 'name',
  135. key: 'name',
  136. width: 300,
  137. fixed: 'left',
  138. },
  139. {
  140. title: 'Age',
  141. dataIndex: 'age',
  142. key: 'age',
  143. width: 150,
  144. filterChildrenRecord: true,
  145. filters: [
  146. { text: 'age < 30', value: 30 },
  147. { text: 'age < 20', value: 20 },
  148. { text: 'age < 10', value: 10 },
  149. ],
  150. onFilter: (filteredValue, record) => {
  151. // console.log(`filteredValue: `, filteredValue, ` record: `, record);
  152. return record.age < filteredValue;
  153. },
  154. sorter: (v1, v2) => {
  155. return v1.age < v2.age ? -1 : 1;
  156. },
  157. sortChildrenRecord: true,
  158. },
  159. {
  160. title: 'Address',
  161. dataIndex: 'address',
  162. key: 'address',
  163. width: 300,
  164. },
  165. {
  166. key: 'operation',
  167. render: record => {
  168. const records = getSameLevelRecords(record[rowKey], data);
  169. const index = records.findIndex(item => item[rowKey] === record[rowKey]);
  170. const upProps = {};
  171. const downProps = {};
  172. if (index > 0) {
  173. const upRow = records[index - 1];
  174. upProps.onClick = () => switchRecord(record[rowKey], upRow[rowKey]);
  175. } else {
  176. upProps.disabled = true;
  177. }
  178. if (index < records.length - 1) {
  179. const downRow = records[index + 1];
  180. downProps.onClick = () => switchRecord(record[rowKey], downRow[rowKey]);
  181. } else {
  182. downProps.disabled = true;
  183. }
  184. return (
  185. <>
  186. <Button icon={<IconArrowUp />} {...upProps} />
  187. <Button icon={<IconArrowDown />} {...downProps} />
  188. </>
  189. );
  190. },
  191. },
  192. ];
  193. return (
  194. <Table
  195. columns={columns}
  196. rowKey={rowKey}
  197. childrenRecordName={childrenRecordName}
  198. expandedRowKeys={expandedRowKeys}
  199. onExpand={(expanded, row, event) => {
  200. console.log([expanded, row, event]);
  201. if (event) {
  202. event.stopPropagation();
  203. }
  204. }}
  205. onRow={(record, index) => {
  206. return {
  207. onClick: () => {
  208. console.log(`Clicked row ${index}: `, record);
  209. },
  210. };
  211. }}
  212. onExpandedRowsChange={rows => setExpandedRowKeys(rows.map(item => item[rowKey]))}
  213. rowSelection={{
  214. getCheckboxProps: record => ({
  215. disabled: record.name && record.name.includes('Jimmy'), // Column configuration not to be checked
  216. }),
  217. fixed: 'left',
  218. }}
  219. dataSource={data}
  220. // indentSize={0}
  221. // expandIcon={false}
  222. scroll={{
  223. x: '160%',
  224. y: 480,
  225. }}
  226. />
  227. );
  228. };
  229. export default Demo;