useSorter.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  2. import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
  3. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  4. import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
  5. import _typeof from "@babel/runtime/helpers/esm/typeof";
  6. import { createVNode as _createVNode } from "vue";
  7. import CaretDownOutlined from "@ant-design/icons-vue/es/icons/CaretDownOutlined";
  8. import CaretUpOutlined from "@ant-design/icons-vue/es/icons/CaretUpOutlined";
  9. import Tooltip from '../../tooltip';
  10. import { getColumnKey, getColumnPos, renderColumnTitle } from '../util';
  11. import classNames from '../../_util/classNames';
  12. import { computed } from 'vue';
  13. import useState from '../../_util/hooks/useState';
  14. var ASCEND = 'ascend';
  15. var DESCEND = 'descend';
  16. function getMultiplePriority(column) {
  17. if (_typeof(column.sorter) === 'object' && typeof column.sorter.multiple === 'number') {
  18. return column.sorter.multiple;
  19. }
  20. return false;
  21. }
  22. function getSortFunction(sorter) {
  23. if (typeof sorter === 'function') {
  24. return sorter;
  25. }
  26. if (sorter && _typeof(sorter) === 'object' && sorter.compare) {
  27. return sorter.compare;
  28. }
  29. return false;
  30. }
  31. function nextSortDirection(sortDirections, current) {
  32. if (!current) {
  33. return sortDirections[0];
  34. }
  35. return sortDirections[sortDirections.indexOf(current) + 1];
  36. }
  37. function collectSortStates(columns, init, pos) {
  38. var sortStates = [];
  39. function pushState(column, columnPos) {
  40. sortStates.push({
  41. column: column,
  42. key: getColumnKey(column, columnPos),
  43. multiplePriority: getMultiplePriority(column),
  44. sortOrder: column.sortOrder
  45. });
  46. }
  47. (columns || []).forEach(function (column, index) {
  48. var columnPos = getColumnPos(index, pos);
  49. if (column.children) {
  50. if ('sortOrder' in column) {
  51. // Controlled
  52. pushState(column, columnPos);
  53. }
  54. sortStates = [].concat(_toConsumableArray(sortStates), _toConsumableArray(collectSortStates(column.children, init, columnPos)));
  55. } else if (column.sorter) {
  56. if ('sortOrder' in column) {
  57. // Controlled
  58. pushState(column, columnPos);
  59. } else if (init && column.defaultSortOrder) {
  60. // Default sorter
  61. sortStates.push({
  62. column: column,
  63. key: getColumnKey(column, columnPos),
  64. multiplePriority: getMultiplePriority(column),
  65. sortOrder: column.defaultSortOrder
  66. });
  67. }
  68. }
  69. });
  70. return sortStates;
  71. }
  72. function injectSorter(prefixCls, columns, sorterSates, triggerSorter, defaultSortDirections, tableLocale, tableShowSorterTooltip, pos) {
  73. return (columns || []).map(function (column, index) {
  74. var columnPos = getColumnPos(index, pos);
  75. var newColumn = column;
  76. if (newColumn.sorter) {
  77. var sortDirections = newColumn.sortDirections || defaultSortDirections;
  78. var showSorterTooltip = newColumn.showSorterTooltip === undefined ? tableShowSorterTooltip : newColumn.showSorterTooltip;
  79. var columnKey = getColumnKey(newColumn, columnPos);
  80. var sorterState = sorterSates.find(function (_ref) {
  81. var key = _ref.key;
  82. return key === columnKey;
  83. });
  84. var sorterOrder = sorterState ? sorterState.sortOrder : null;
  85. var nextSortOrder = nextSortDirection(sortDirections, sorterOrder);
  86. var upNode = sortDirections.includes(ASCEND) && _createVNode(CaretUpOutlined, {
  87. "class": classNames("".concat(prefixCls, "-column-sorter-up"), {
  88. active: sorterOrder === ASCEND
  89. })
  90. }, null);
  91. var downNode = sortDirections.includes(DESCEND) && _createVNode(CaretDownOutlined, {
  92. "class": classNames("".concat(prefixCls, "-column-sorter-down"), {
  93. active: sorterOrder === DESCEND
  94. })
  95. }, null);
  96. var _ref2 = tableLocale || {},
  97. cancelSort = _ref2.cancelSort,
  98. triggerAsc = _ref2.triggerAsc,
  99. triggerDesc = _ref2.triggerDesc;
  100. var sortTip = cancelSort;
  101. if (nextSortOrder === DESCEND) {
  102. sortTip = triggerDesc;
  103. } else if (nextSortOrder === ASCEND) {
  104. sortTip = triggerAsc;
  105. }
  106. var tooltipProps = _typeof(showSorterTooltip) === 'object' ? showSorterTooltip : {
  107. title: sortTip
  108. };
  109. newColumn = _objectSpread(_objectSpread({}, newColumn), {}, {
  110. className: classNames(newColumn.className, _defineProperty({}, "".concat(prefixCls, "-column-sort"), sorterOrder)),
  111. title: function title(renderProps) {
  112. var renderSortTitle = _createVNode("div", {
  113. "class": "".concat(prefixCls, "-column-sorters")
  114. }, [_createVNode("span", {
  115. "class": "".concat(prefixCls, "-column-title")
  116. }, [renderColumnTitle(column.title, renderProps)]), _createVNode("span", {
  117. "class": classNames("".concat(prefixCls, "-column-sorter"), _defineProperty({}, "".concat(prefixCls, "-column-sorter-full"), !!(upNode && downNode)))
  118. }, [_createVNode("span", {
  119. "class": "".concat(prefixCls, "-column-sorter-inner")
  120. }, [upNode, downNode])])]);
  121. return showSorterTooltip ? _createVNode(Tooltip, tooltipProps, {
  122. default: function _default() {
  123. return [renderSortTitle];
  124. }
  125. }) : renderSortTitle;
  126. },
  127. customHeaderCell: function customHeaderCell(col) {
  128. var cell = column.customHeaderCell && column.customHeaderCell(col) || {};
  129. var originOnClick = cell.onClick;
  130. cell.onClick = function (event) {
  131. triggerSorter({
  132. column: column,
  133. key: columnKey,
  134. sortOrder: nextSortOrder,
  135. multiplePriority: getMultiplePriority(column)
  136. });
  137. if (originOnClick) {
  138. originOnClick(event);
  139. }
  140. };
  141. cell.class = classNames(cell.class, "".concat(prefixCls, "-column-has-sorters"));
  142. return cell;
  143. }
  144. });
  145. }
  146. if ('children' in newColumn) {
  147. newColumn = _objectSpread(_objectSpread({}, newColumn), {}, {
  148. children: injectSorter(prefixCls, newColumn.children, sorterSates, triggerSorter, defaultSortDirections, tableLocale, tableShowSorterTooltip, columnPos)
  149. });
  150. }
  151. return newColumn;
  152. });
  153. }
  154. function stateToInfo(sorterStates) {
  155. var column = sorterStates.column,
  156. sortOrder = sorterStates.sortOrder;
  157. return {
  158. column: column,
  159. order: sortOrder,
  160. field: column.dataIndex,
  161. columnKey: column.key
  162. };
  163. }
  164. function generateSorterInfo(sorterStates) {
  165. var list = sorterStates.filter(function (_ref3) {
  166. var sortOrder = _ref3.sortOrder;
  167. return sortOrder;
  168. }).map(stateToInfo);
  169. // =========== Legacy compatible support ===========
  170. // https://github.com/ant-design/ant-design/pull/19226
  171. if (list.length === 0 && sorterStates.length) {
  172. return _objectSpread(_objectSpread({}, stateToInfo(sorterStates[sorterStates.length - 1])), {}, {
  173. column: undefined
  174. });
  175. }
  176. if (list.length <= 1) {
  177. return list[0] || {};
  178. }
  179. return list;
  180. }
  181. export function getSortData(data, sortStates, childrenColumnName) {
  182. var innerSorterStates = sortStates.slice().sort(function (a, b) {
  183. return b.multiplePriority - a.multiplePriority;
  184. });
  185. var cloneData = data.slice();
  186. var runningSorters = innerSorterStates.filter(function (_ref4) {
  187. var sorter = _ref4.column.sorter,
  188. sortOrder = _ref4.sortOrder;
  189. return getSortFunction(sorter) && sortOrder;
  190. });
  191. // Skip if no sorter needed
  192. if (!runningSorters.length) {
  193. return cloneData;
  194. }
  195. return cloneData.sort(function (record1, record2) {
  196. for (var i = 0; i < runningSorters.length; i += 1) {
  197. var sorterState = runningSorters[i];
  198. var sorter = sorterState.column.sorter,
  199. sortOrder = sorterState.sortOrder;
  200. var compareFn = getSortFunction(sorter);
  201. if (compareFn && sortOrder) {
  202. var compareResult = compareFn(record1, record2, sortOrder);
  203. if (compareResult !== 0) {
  204. return sortOrder === ASCEND ? compareResult : -compareResult;
  205. }
  206. }
  207. }
  208. return 0;
  209. }).map(function (record) {
  210. var subRecords = record[childrenColumnName];
  211. if (subRecords) {
  212. return _objectSpread(_objectSpread({}, record), {}, _defineProperty({}, childrenColumnName, getSortData(subRecords, sortStates, childrenColumnName)));
  213. }
  214. return record;
  215. });
  216. }
  217. export default function useFilterSorter(_ref5) {
  218. var prefixCls = _ref5.prefixCls,
  219. mergedColumns = _ref5.mergedColumns,
  220. onSorterChange = _ref5.onSorterChange,
  221. sortDirections = _ref5.sortDirections,
  222. tableLocale = _ref5.tableLocale,
  223. showSorterTooltip = _ref5.showSorterTooltip;
  224. var _useState = useState(collectSortStates(mergedColumns.value, true)),
  225. _useState2 = _slicedToArray(_useState, 2),
  226. sortStates = _useState2[0],
  227. setSortStates = _useState2[1];
  228. var mergedSorterStates = computed(function () {
  229. var validate = true;
  230. var collectedStates = collectSortStates(mergedColumns.value, false);
  231. // Return if not controlled
  232. if (!collectedStates.length) {
  233. return sortStates.value;
  234. }
  235. var validateStates = [];
  236. function patchStates(state) {
  237. if (validate) {
  238. validateStates.push(state);
  239. } else {
  240. validateStates.push(_objectSpread(_objectSpread({}, state), {}, {
  241. sortOrder: null
  242. }));
  243. }
  244. }
  245. var multipleMode = null;
  246. collectedStates.forEach(function (state) {
  247. if (multipleMode === null) {
  248. patchStates(state);
  249. if (state.sortOrder) {
  250. if (state.multiplePriority === false) {
  251. validate = false;
  252. } else {
  253. multipleMode = true;
  254. }
  255. }
  256. } else if (multipleMode && state.multiplePriority !== false) {
  257. patchStates(state);
  258. } else {
  259. validate = false;
  260. patchStates(state);
  261. }
  262. });
  263. return validateStates;
  264. });
  265. // Get render columns title required props
  266. var columnTitleSorterProps = computed(function () {
  267. var sortColumns = mergedSorterStates.value.map(function (_ref6) {
  268. var column = _ref6.column,
  269. sortOrder = _ref6.sortOrder;
  270. return {
  271. column: column,
  272. order: sortOrder
  273. };
  274. });
  275. return {
  276. sortColumns: sortColumns,
  277. // Legacy
  278. sortColumn: sortColumns[0] && sortColumns[0].column,
  279. sortOrder: sortColumns[0] && sortColumns[0].order
  280. };
  281. });
  282. function triggerSorter(sortState) {
  283. var newSorterStates;
  284. if (sortState.multiplePriority === false || !mergedSorterStates.value.length || mergedSorterStates.value[0].multiplePriority === false) {
  285. newSorterStates = [sortState];
  286. } else {
  287. newSorterStates = [].concat(_toConsumableArray(mergedSorterStates.value.filter(function (_ref7) {
  288. var key = _ref7.key;
  289. return key !== sortState.key;
  290. })), [sortState]);
  291. }
  292. setSortStates(newSorterStates);
  293. onSorterChange(generateSorterInfo(newSorterStates), newSorterStates);
  294. }
  295. var transformColumns = function transformColumns(innerColumns) {
  296. return injectSorter(prefixCls.value, innerColumns, mergedSorterStates.value, triggerSorter, sortDirections.value, tableLocale.value, showSorterTooltip.value);
  297. };
  298. var sorters = computed(function () {
  299. return generateSorterInfo(mergedSorterStates.value);
  300. });
  301. return [transformColumns, mergedSorterStates, columnTitleSorterProps, sorters];
  302. }