@strapi/content-manager 5.60.0 → 5.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/dist/admin/constants/customOrder.js +14 -0
  2. package/dist/admin/constants/customOrder.js.map +1 -0
  3. package/dist/admin/constants/customOrder.mjs +10 -0
  4. package/dist/admin/constants/customOrder.mjs.map +1 -0
  5. package/dist/admin/hooks/useDocument.js +22 -11
  6. package/dist/admin/hooks/useDocument.js.map +1 -1
  7. package/dist/admin/hooks/useDocument.mjs +22 -11
  8. package/dist/admin/hooks/useDocument.mjs.map +1 -1
  9. package/dist/admin/hooks/useDocumentLayout.js.map +1 -1
  10. package/dist/admin/hooks/useDocumentLayout.mjs.map +1 -1
  11. package/dist/admin/hooks/useHasBeenNearViewport.js +70 -0
  12. package/dist/admin/hooks/useHasBeenNearViewport.js.map +1 -0
  13. package/dist/admin/hooks/useHasBeenNearViewport.mjs +46 -0
  14. package/dist/admin/hooks/useHasBeenNearViewport.mjs.map +1 -0
  15. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.js +102 -32
  16. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.js.map +1 -1
  17. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.mjs +104 -35
  18. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.mjs.map +1 -1
  19. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.js +20 -17
  20. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.js.map +1 -1
  21. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.mjs +20 -17
  22. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.mjs.map +1 -1
  23. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js +15 -1
  24. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js.map +1 -1
  25. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs +17 -3
  26. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs.map +1 -1
  27. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withStrapiSchema.js +21 -0
  28. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withStrapiSchema.js.map +1 -1
  29. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withStrapiSchema.mjs +22 -1
  30. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withStrapiSchema.mjs.map +1 -1
  31. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js +4 -7
  32. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js.map +1 -1
  33. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs +4 -7
  34. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs.map +1 -1
  35. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +46 -10
  36. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
  37. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +47 -11
  38. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
  39. package/dist/admin/pages/EditView/components/FormLayout.js +201 -51
  40. package/dist/admin/pages/EditView/components/FormLayout.js.map +1 -1
  41. package/dist/admin/pages/EditView/components/FormLayout.mjs +202 -53
  42. package/dist/admin/pages/EditView/components/FormLayout.mjs.map +1 -1
  43. package/dist/admin/pages/ListConfiguration/components/Settings.js +31 -2
  44. package/dist/admin/pages/ListConfiguration/components/Settings.js.map +1 -1
  45. package/dist/admin/pages/ListConfiguration/components/Settings.mjs +31 -2
  46. package/dist/admin/pages/ListConfiguration/components/Settings.mjs.map +1 -1
  47. package/dist/admin/pages/ListView/ListViewPage.js +196 -132
  48. package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
  49. package/dist/admin/pages/ListView/ListViewPage.mjs +196 -132
  50. package/dist/admin/pages/ListView/ListViewPage.mjs.map +1 -1
  51. package/dist/admin/pages/ListView/components/CustomOrder.js +571 -0
  52. package/dist/admin/pages/ListView/components/CustomOrder.js.map +1 -0
  53. package/dist/admin/pages/ListView/components/CustomOrder.mjs +546 -0
  54. package/dist/admin/pages/ListView/components/CustomOrder.mjs.map +1 -0
  55. package/dist/admin/pages/ListView/components/TableActions.js +4 -1
  56. package/dist/admin/pages/ListView/components/TableActions.js.map +1 -1
  57. package/dist/admin/pages/ListView/components/TableActions.mjs +4 -1
  58. package/dist/admin/pages/ListView/components/TableActions.mjs.map +1 -1
  59. package/dist/admin/services/documents.js +22 -1
  60. package/dist/admin/services/documents.js.map +1 -1
  61. package/dist/admin/services/documents.mjs +21 -2
  62. package/dist/admin/services/documents.mjs.map +1 -1
  63. package/dist/admin/src/constants/customOrder.d.ts +8 -0
  64. package/dist/admin/src/exports.d.ts +1 -1
  65. package/dist/admin/src/hooks/useDocument.d.ts +4 -0
  66. package/dist/admin/src/hooks/useDocumentLayout.d.ts +6 -2
  67. package/dist/admin/src/hooks/useHasBeenNearViewport.d.ts +13 -0
  68. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.d.ts +13 -1
  69. package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +11 -1
  70. package/dist/admin/src/pages/ListView/components/CustomOrder.d.ts +72 -0
  71. package/dist/admin/src/services/documents.d.ts +10 -2
  72. package/dist/admin/translations/en.json.js +9 -0
  73. package/dist/admin/translations/en.json.js.map +1 -1
  74. package/dist/admin/translations/en.json.mjs +9 -0
  75. package/dist/admin/translations/en.json.mjs.map +1 -1
  76. package/dist/server/audit-logs.js +36 -0
  77. package/dist/server/audit-logs.js.map +1 -0
  78. package/dist/server/audit-logs.mjs +33 -0
  79. package/dist/server/audit-logs.mjs.map +1 -0
  80. package/dist/server/bootstrap.js +8 -0
  81. package/dist/server/bootstrap.js.map +1 -1
  82. package/dist/server/bootstrap.mjs +8 -0
  83. package/dist/server/bootstrap.mjs.map +1 -1
  84. package/dist/server/controllers/collection-types.js +8 -0
  85. package/dist/server/controllers/collection-types.js.map +1 -1
  86. package/dist/server/controllers/collection-types.mjs +8 -0
  87. package/dist/server/controllers/collection-types.mjs.map +1 -1
  88. package/dist/server/controllers/content-types.js +15 -0
  89. package/dist/server/controllers/content-types.js.map +1 -1
  90. package/dist/server/controllers/content-types.mjs +16 -1
  91. package/dist/server/controllers/content-types.mjs.map +1 -1
  92. package/dist/server/controllers/index.js +3 -1
  93. package/dist/server/controllers/index.js.map +1 -1
  94. package/dist/server/controllers/index.mjs +2 -0
  95. package/dist/server/controllers/index.mjs.map +1 -1
  96. package/dist/server/controllers/relations.js +5 -1
  97. package/dist/server/controllers/relations.js.map +1 -1
  98. package/dist/server/controllers/relations.mjs +5 -1
  99. package/dist/server/controllers/relations.mjs.map +1 -1
  100. package/dist/server/controllers/single-types.js +10 -1
  101. package/dist/server/controllers/single-types.js.map +1 -1
  102. package/dist/server/controllers/single-types.mjs +10 -1
  103. package/dist/server/controllers/single-types.mjs.map +1 -1
  104. package/dist/server/controllers/validation/model-configuration.js +2 -1
  105. package/dist/server/controllers/validation/model-configuration.js.map +1 -1
  106. package/dist/server/controllers/validation/model-configuration.mjs +2 -1
  107. package/dist/server/controllers/validation/model-configuration.mjs.map +1 -1
  108. package/dist/server/custom-order/constants.js +21 -0
  109. package/dist/server/custom-order/constants.js.map +1 -0
  110. package/dist/server/custom-order/constants.mjs +17 -0
  111. package/dist/server/custom-order/constants.mjs.map +1 -0
  112. package/dist/server/custom-order/controllers/custom-order.js +77 -0
  113. package/dist/server/custom-order/controllers/custom-order.js.map +1 -0
  114. package/dist/server/custom-order/controllers/custom-order.mjs +75 -0
  115. package/dist/server/custom-order/controllers/custom-order.mjs.map +1 -0
  116. package/dist/server/custom-order/controllers/index.js +10 -0
  117. package/dist/server/custom-order/controllers/index.js.map +1 -0
  118. package/dist/server/custom-order/controllers/index.mjs +8 -0
  119. package/dist/server/custom-order/controllers/index.mjs.map +1 -0
  120. package/dist/server/custom-order/index.js +71 -0
  121. package/dist/server/custom-order/index.js.map +1 -0
  122. package/dist/server/custom-order/index.mjs +69 -0
  123. package/dist/server/custom-order/index.mjs.map +1 -0
  124. package/dist/server/custom-order/routes/custom-order.js +38 -0
  125. package/dist/server/custom-order/routes/custom-order.js.map +1 -0
  126. package/dist/server/custom-order/routes/custom-order.mjs +36 -0
  127. package/dist/server/custom-order/routes/custom-order.mjs.map +1 -0
  128. package/dist/server/custom-order/routes/index.js +13 -0
  129. package/dist/server/custom-order/routes/index.js.map +1 -0
  130. package/dist/server/custom-order/routes/index.mjs +11 -0
  131. package/dist/server/custom-order/routes/index.mjs.map +1 -0
  132. package/dist/server/custom-order/services/custom-order.js +286 -0
  133. package/dist/server/custom-order/services/custom-order.js.map +1 -0
  134. package/dist/server/custom-order/services/custom-order.mjs +284 -0
  135. package/dist/server/custom-order/services/custom-order.mjs.map +1 -0
  136. package/dist/server/custom-order/services/document-middleware.js +83 -0
  137. package/dist/server/custom-order/services/document-middleware.js.map +1 -0
  138. package/dist/server/custom-order/services/document-middleware.mjs +81 -0
  139. package/dist/server/custom-order/services/document-middleware.mjs.map +1 -0
  140. package/dist/server/custom-order/services/index.js +10 -0
  141. package/dist/server/custom-order/services/index.js.map +1 -0
  142. package/dist/server/custom-order/services/index.mjs +8 -0
  143. package/dist/server/custom-order/services/index.mjs.map +1 -0
  144. package/dist/server/custom-order/services/utils.js +152 -0
  145. package/dist/server/custom-order/services/utils.js.map +1 -0
  146. package/dist/server/custom-order/services/utils.mjs +148 -0
  147. package/dist/server/custom-order/services/utils.mjs.map +1 -0
  148. package/dist/server/custom-order/utils.js +13 -0
  149. package/dist/server/custom-order/utils.js.map +1 -0
  150. package/dist/server/custom-order/utils.mjs +10 -0
  151. package/dist/server/custom-order/utils.mjs.map +1 -0
  152. package/dist/server/history/constants.js +2 -1
  153. package/dist/server/history/constants.js.map +1 -1
  154. package/dist/server/history/constants.mjs +2 -1
  155. package/dist/server/history/constants.mjs.map +1 -1
  156. package/dist/server/history/controllers/history-version.js +6 -2
  157. package/dist/server/history/controllers/history-version.js.map +1 -1
  158. package/dist/server/history/controllers/history-version.mjs +6 -2
  159. package/dist/server/history/controllers/history-version.mjs.map +1 -1
  160. package/dist/server/history/services/history.js +23 -6
  161. package/dist/server/history/services/history.js.map +1 -1
  162. package/dist/server/history/services/history.mjs +24 -7
  163. package/dist/server/history/services/history.mjs.map +1 -1
  164. package/dist/server/history/services/lifecycles.js +2 -16
  165. package/dist/server/history/services/lifecycles.js.map +1 -1
  166. package/dist/server/history/services/lifecycles.mjs +2 -16
  167. package/dist/server/history/services/lifecycles.mjs.map +1 -1
  168. package/dist/server/register.js +4 -0
  169. package/dist/server/register.js.map +1 -1
  170. package/dist/server/register.mjs +4 -0
  171. package/dist/server/register.mjs.map +1 -1
  172. package/dist/server/routes/index.js +3 -1
  173. package/dist/server/routes/index.js.map +1 -1
  174. package/dist/server/routes/index.mjs +2 -0
  175. package/dist/server/routes/index.mjs.map +1 -1
  176. package/dist/server/services/content-types.js +2 -2
  177. package/dist/server/services/content-types.js.map +1 -1
  178. package/dist/server/services/content-types.mjs +2 -2
  179. package/dist/server/services/content-types.mjs.map +1 -1
  180. package/dist/server/services/document-manager.js +13 -0
  181. package/dist/server/services/document-manager.js.map +1 -1
  182. package/dist/server/services/document-manager.mjs +14 -1
  183. package/dist/server/services/document-manager.mjs.map +1 -1
  184. package/dist/server/services/index.js +3 -1
  185. package/dist/server/services/index.js.map +1 -1
  186. package/dist/server/services/index.mjs +2 -0
  187. package/dist/server/services/index.mjs.map +1 -1
  188. package/dist/server/services/utils/configuration/settings.js +2 -1
  189. package/dist/server/services/utils/configuration/settings.js.map +1 -1
  190. package/dist/server/services/utils/configuration/settings.mjs +2 -1
  191. package/dist/server/services/utils/configuration/settings.mjs.map +1 -1
  192. package/dist/server/src/audit-logs.d.ts +40 -0
  193. package/dist/server/src/audit-logs.d.ts.map +1 -0
  194. package/dist/server/src/bootstrap.d.ts.map +1 -1
  195. package/dist/server/src/controllers/collection-types.d.ts +1 -1
  196. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  197. package/dist/server/src/controllers/content-types.d.ts.map +1 -1
  198. package/dist/server/src/controllers/index.d.ts +21 -3
  199. package/dist/server/src/controllers/index.d.ts.map +1 -1
  200. package/dist/server/src/controllers/relations.d.ts +19 -1
  201. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  202. package/dist/server/src/controllers/single-types.d.ts +1 -1
  203. package/dist/server/src/controllers/single-types.d.ts.map +1 -1
  204. package/dist/server/src/custom-order/constants.d.ts +18 -0
  205. package/dist/server/src/custom-order/constants.d.ts.map +1 -0
  206. package/dist/server/src/custom-order/controllers/custom-order.d.ts +8 -0
  207. package/dist/server/src/custom-order/controllers/custom-order.d.ts.map +1 -0
  208. package/dist/server/src/custom-order/controllers/index.d.ts +3 -0
  209. package/dist/server/src/custom-order/controllers/index.d.ts.map +1 -0
  210. package/dist/server/src/custom-order/index.d.ts +8 -0
  211. package/dist/server/src/custom-order/index.d.ts.map +1 -0
  212. package/dist/server/src/custom-order/routes/custom-order.d.ts +4 -0
  213. package/dist/server/src/custom-order/routes/custom-order.d.ts.map +1 -0
  214. package/dist/server/src/custom-order/routes/index.d.ts +10 -0
  215. package/dist/server/src/custom-order/routes/index.d.ts.map +1 -0
  216. package/dist/server/src/custom-order/services/custom-order.d.ts +43 -0
  217. package/dist/server/src/custom-order/services/custom-order.d.ts.map +1 -0
  218. package/dist/server/src/custom-order/services/document-middleware.d.ts +16 -0
  219. package/dist/server/src/custom-order/services/document-middleware.d.ts.map +1 -0
  220. package/dist/server/src/custom-order/services/index.d.ts +24 -0
  221. package/dist/server/src/custom-order/services/index.d.ts.map +1 -0
  222. package/dist/server/src/custom-order/services/utils.d.ts +34 -0
  223. package/dist/server/src/custom-order/services/utils.d.ts.map +1 -0
  224. package/dist/server/src/custom-order/utils.d.ts +6 -0
  225. package/dist/server/src/custom-order/utils.d.ts.map +1 -0
  226. package/dist/server/src/history/constants.d.ts.map +1 -1
  227. package/dist/server/src/history/controllers/history-version.d.ts.map +1 -1
  228. package/dist/server/src/history/services/history.d.ts.map +1 -1
  229. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  230. package/dist/server/src/index.d.ts +22 -6
  231. package/dist/server/src/index.d.ts.map +1 -1
  232. package/dist/server/src/register.d.ts.map +1 -1
  233. package/dist/server/src/routes/index.d.ts.map +1 -1
  234. package/dist/server/src/services/content-types.d.ts +1 -3
  235. package/dist/server/src/services/content-types.d.ts.map +1 -1
  236. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  237. package/dist/server/src/services/index.d.ts +1 -3
  238. package/dist/server/src/services/index.d.ts.map +1 -1
  239. package/dist/server/src/services/utils/configuration/settings.d.ts.map +1 -1
  240. package/dist/shared/contracts/content-types.d.ts +5 -0
  241. package/dist/shared/contracts/content-types.d.ts.map +1 -1
  242. package/dist/shared/contracts/custom-order.d.ts +33 -0
  243. package/dist/shared/contracts/custom-order.d.ts.map +1 -0
  244. package/dist/shared/contracts/custom-order.js +3 -0
  245. package/dist/shared/contracts/custom-order.js.map +1 -0
  246. package/dist/shared/contracts/custom-order.mjs +2 -0
  247. package/dist/shared/contracts/custom-order.mjs.map +1 -0
  248. package/dist/shared/contracts/history-versions.d.ts +0 -1
  249. package/dist/shared/contracts/history-versions.d.ts.map +1 -1
  250. package/dist/shared/contracts/index.d.ts +1 -0
  251. package/dist/shared/contracts/index.d.ts.map +1 -1
  252. package/dist/shared/contracts/index.js +2 -0
  253. package/dist/shared/contracts/index.js.map +1 -1
  254. package/dist/shared/contracts/index.mjs +2 -0
  255. package/dist/shared/contracts/index.mjs.map +1 -1
  256. package/package.json +8 -8
@@ -0,0 +1,546 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { useSensors, useSensor, PointerSensor, DndContext, closestCenter } from '@dnd-kit/core';
4
+ import { SortableContext, verticalListSortingStrategy, useSortable, arrayMove } from '@dnd-kit/sortable';
5
+ import { CSS } from '@dnd-kit/utilities';
6
+ import { QueryStatus } from '@reduxjs/toolkit/query';
7
+ import { Table, useNotification, useAPIErrorHandler } from '@strapi/admin/strapi-admin';
8
+ import { Td, Flex, Tooltip, Typography } from '@strapi/design-system';
9
+ import { ArrowUp, ArrowDown, Drag } from '@strapi/icons';
10
+ import { useIntl } from 'react-intl';
11
+ import { useStore } from 'react-redux';
12
+ import { css, styled } from 'styled-components';
13
+ import { CUSTOM_ORDER_SORT } from '../../../constants/customOrder.mjs';
14
+ import { useMoveDocumentMutation, useLazyGetAllDocumentsQuery } from '../../../services/documents.mjs';
15
+ import { getTranslation } from '../../../utils/translations.mjs';
16
+
17
+ /**
18
+ * How many times the list is asked again after a move before giving up. Each attempt waits
19
+ * for a whole request, so two are enough in practice (see `refetchList`).
20
+ */ const MAX_REFETCH_ATTEMPTS = 3;
21
+ const useCustomOrder = ({ model, isAvailable, canUpdate, sort, params, results, pagination })=>{
22
+ const { formatMessage } = useIntl();
23
+ const { toggleNotification } = useNotification();
24
+ const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
25
+ const [moveDocument] = useMoveDocumentMutation();
26
+ const [fetchDocuments] = useLazyGetAllDocumentsQuery();
27
+ const store = useStore();
28
+ const [isMoving, setIsMoving] = React.useState(false);
29
+ // Same value for the handlers, which may run again before React has rendered the state
30
+ const isMovingRef = React.useRef(false);
31
+ /** Order to display until the move has landed, when it stays within the page. */ const [pendingOrder, setPendingOrder] = React.useState(null);
32
+ const isActive = isAvailable && sort?.toUpperCase() === CUSTOM_ORDER_SORT.toUpperCase();
33
+ /**
34
+ * The list is fetched again after each move. Until that answer lands, the table keeps
35
+ * showing its rows instead of a loading state, which would make every move blink.
36
+ * Any other answer landing in the meantime does not touch the order shown.
37
+ */ const rows = React.useMemo(()=>{
38
+ if (!isMoving || !pendingOrder) {
39
+ return results;
40
+ }
41
+ const rowsById = new Map(results.map((row)=>[
42
+ row.documentId,
43
+ row
44
+ ]));
45
+ return pendingOrder.flatMap((documentId)=>rowsById.get(documentId) ?? []);
46
+ }, [
47
+ isMoving,
48
+ pendingOrder,
49
+ results
50
+ ]);
51
+ const offset = pagination ? (pagination.page - 1) * pagination.pageSize : 0;
52
+ const total = pagination?.total ?? results.length;
53
+ const locale = typeof params.locale === 'string' ? params.locale : undefined;
54
+ /**
55
+ * Runs a move while blocking any other one: from the moment it is asked until the list
56
+ * shows its result, the handles, the position inputs and the row actions are inert.
57
+ */ const runExclusively = async (run)=>{
58
+ if (isMovingRef.current) {
59
+ return;
60
+ }
61
+ isMovingRef.current = true;
62
+ setIsMoving(true);
63
+ try {
64
+ await run();
65
+ } finally{
66
+ isMovingRef.current = false;
67
+ setPendingOrder(null);
68
+ setIsMoving(false);
69
+ }
70
+ };
71
+ /**
72
+ * Resolves once no request of the list is in flight anymore.
73
+ */ const waitForList = (queryCacheKey)=>new Promise((resolve)=>{
74
+ const isSettled = ()=>store.getState().adminApi.queries[queryCacheKey]?.status !== QueryStatus.pending;
75
+ if (isSettled()) {
76
+ resolve();
77
+ return;
78
+ }
79
+ const unsubscribe = store.subscribe(()=>{
80
+ if (isSettled()) {
81
+ unsubscribe();
82
+ resolve();
83
+ }
84
+ });
85
+ });
86
+ /**
87
+ * Waits for the list to be fetched again after a move. The mutation invalidates the list,
88
+ * but RTK Query drops that refetch when another request is already in flight, and that
89
+ * request may have started before the server applied the move. So the list is asked again
90
+ * until a request started after the move was answered, otherwise the table could settle on
91
+ * a stale snapshot. An attempt is dropped the same way when a request is in flight: it
92
+ * then waits for that request, which is the one the mutation started most of the time.
93
+ *
94
+ * @param movedAt - When the server answered the move
95
+ */ const refetchList = async (movedAt)=>{
96
+ for(let attempt = 0; attempt < MAX_REFETCH_ATTEMPTS; attempt += 1){
97
+ const request = fetchDocuments({
98
+ model,
99
+ params
100
+ });
101
+ const { requestId, startedTimeStamp = 0 } = await request;
102
+ // The page subscribes to the list itself
103
+ request.unsubscribe();
104
+ if (requestId === request.requestId) {
105
+ return;
106
+ }
107
+ await waitForList(request.queryCacheKey);
108
+ if (startedTimeStamp >= movedAt) {
109
+ return;
110
+ }
111
+ }
112
+ };
113
+ const move = async (documentId, anchorId, placement, order)=>{
114
+ if (order) {
115
+ setPendingOrder(order);
116
+ }
117
+ const mutation = moveDocument({
118
+ model,
119
+ id: documentId,
120
+ body: placement === 'before' ? {
121
+ before: anchorId
122
+ } : {
123
+ after: anchorId
124
+ },
125
+ params: {
126
+ locale
127
+ }
128
+ });
129
+ const res = await mutation;
130
+ if ('error' in res) {
131
+ setPendingOrder(null);
132
+ toggleNotification({
133
+ type: 'danger',
134
+ message: formatAPIError(res.error)
135
+ });
136
+ return false;
137
+ }
138
+ const { fulfilledTimeStamp: movedAt = Date.now() } = store.getState().adminApi.mutations[mutation.requestId] ?? {};
139
+ await refetchList(movedAt);
140
+ return true;
141
+ };
142
+ const moveWithinPage = (from, to)=>{
143
+ const moved = rows[from];
144
+ const anchor = rows[to];
145
+ return move(moved.documentId, anchor.documentId, to > from ? 'after' : 'before', arrayMove(rows, from, to).map((row)=>row.documentId));
146
+ };
147
+ const moveToIndex = async (from, to)=>{
148
+ if (from === to || !rows[from] || !rows[to]) {
149
+ return;
150
+ }
151
+ await runExclusively(async ()=>{
152
+ await moveWithinPage(from, to);
153
+ });
154
+ };
155
+ const moveToPosition = async (documentId, position)=>{
156
+ const from = rows.findIndex((row)=>row.documentId === documentId);
157
+ if (from === -1 || total === 0) {
158
+ return;
159
+ }
160
+ const currentPosition = offset + from + 1;
161
+ const targetPosition = Math.min(Math.max(Math.trunc(position), 1), total);
162
+ if (targetPosition === currentPosition) {
163
+ return;
164
+ }
165
+ const to = targetPosition - offset - 1;
166
+ await runExclusively(async ()=>{
167
+ if (to >= 0 && to < rows.length) {
168
+ await moveWithinPage(from, to);
169
+ return;
170
+ }
171
+ // The destination is on another page: ask the server which entry sits there in this view
172
+ const lookup = fetchDocuments({
173
+ model,
174
+ params: {
175
+ ...params,
176
+ page: String(targetPosition),
177
+ pageSize: '1'
178
+ }
179
+ });
180
+ const res = await lookup;
181
+ // Otherwise every later invalidation of the list would fetch that entry again
182
+ lookup.unsubscribe();
183
+ if (res.error) {
184
+ toggleNotification({
185
+ type: 'danger',
186
+ message: formatAPIError(res.error)
187
+ });
188
+ return;
189
+ }
190
+ const anchor = res.data?.results[0];
191
+ if (!anchor) {
192
+ return;
193
+ }
194
+ const hasMoved = await move(documentId, anchor.documentId, targetPosition > currentPosition ? 'after' : 'before');
195
+ if (hasMoved) {
196
+ toggleNotification({
197
+ type: 'success',
198
+ message: formatMessage({
199
+ id: getTranslation('custom-order.moved'),
200
+ defaultMessage: 'Entry moved to position {position}'
201
+ }, {
202
+ position: targetPosition
203
+ })
204
+ });
205
+ }
206
+ });
207
+ };
208
+ return {
209
+ isAvailable,
210
+ isActive,
211
+ canReorder: isActive && canUpdate,
212
+ isMoving,
213
+ rows,
214
+ total,
215
+ getPosition (documentId) {
216
+ const index = rows.findIndex((row)=>row.documentId === documentId);
217
+ return index === -1 ? undefined : offset + index + 1;
218
+ },
219
+ moveToIndex,
220
+ moveToPosition
221
+ };
222
+ };
223
+ const CustomOrderContext = /*#__PURE__*/ React.createContext({
224
+ isAvailable: false,
225
+ isActive: false,
226
+ canReorder: false,
227
+ isMoving: false,
228
+ rows: [],
229
+ total: 0,
230
+ getPosition: ()=>undefined,
231
+ moveToIndex: async ()=>{},
232
+ moveToPosition: async ()=>{}
233
+ });
234
+ /* -------------------------------------------------------------------------------------------------
235
+ * Root
236
+ * -----------------------------------------------------------------------------------------------*/ const restrictToVerticalAxis = ({ transform })=>({
237
+ ...transform,
238
+ x: 0
239
+ });
240
+ /**
241
+ * Has to wrap the whole table: the drag and drop context renders elements for screen
242
+ * readers next to its children, and those are not valid inside a table.
243
+ */ const Root = ({ children, state })=>{
244
+ // Entries are dragged with a pointer only. The grid owns the arrow keys, so the keyboard
245
+ // goes through the position input and the row actions instead.
246
+ const sensors = useSensors(useSensor(PointerSensor, {
247
+ activationConstraint: {
248
+ distance: 4
249
+ }
250
+ }));
251
+ const items = React.useMemo(()=>state.rows.map((row)=>row.documentId), [
252
+ state.rows
253
+ ]);
254
+ if (!state.isAvailable) {
255
+ return children;
256
+ }
257
+ const handleDragEnd = ({ active, over })=>{
258
+ if (!over || active.id === over.id) {
259
+ return;
260
+ }
261
+ void state.moveToIndex(items.indexOf(String(active.id)), items.indexOf(String(over.id)));
262
+ };
263
+ return /*#__PURE__*/ jsx(CustomOrderContext.Provider, {
264
+ value: state,
265
+ children: /*#__PURE__*/ jsx(DndContext, {
266
+ sensors: sensors,
267
+ collisionDetection: closestCenter,
268
+ modifiers: [
269
+ restrictToVerticalAxis
270
+ ],
271
+ onDragEnd: handleDragEnd,
272
+ children: /*#__PURE__*/ jsx(SortableContext, {
273
+ items: items,
274
+ strategy: verticalListSortingStrategy,
275
+ disabled: !state.canReorder || state.isMoving,
276
+ children: children
277
+ })
278
+ })
279
+ });
280
+ };
281
+ const SortableRowContext = /*#__PURE__*/ React.createContext(null);
282
+ /**
283
+ * A table row that can be dragged when the entries follow a custom order,
284
+ * a regular table row otherwise.
285
+ */ const Row = ({ documentId, ...props })=>{
286
+ const { isAvailable } = React.useContext(CustomOrderContext);
287
+ if (!isAvailable) {
288
+ return /*#__PURE__*/ jsx(Table.Row, {
289
+ ...props
290
+ });
291
+ }
292
+ return /*#__PURE__*/ jsx(DraggableRow, {
293
+ documentId: documentId,
294
+ ...props
295
+ });
296
+ };
297
+ const DraggableRow = ({ documentId, style, ...props })=>{
298
+ const { setNodeRef, setActivatorNodeRef, listeners, transform, transition, isDragging } = useSortable({
299
+ id: documentId
300
+ });
301
+ const sortableRow = React.useMemo(()=>({
302
+ setNodeRef,
303
+ setActivatorNodeRef,
304
+ listeners,
305
+ isDragging
306
+ }), [
307
+ setNodeRef,
308
+ setActivatorNodeRef,
309
+ listeners,
310
+ isDragging
311
+ ]);
312
+ // The provider has to stay outside of the row, which only expects cells as children
313
+ return /*#__PURE__*/ jsx(SortableRowContext.Provider, {
314
+ value: sortableRow,
315
+ children: /*#__PURE__*/ jsx(StyledRow, {
316
+ ...props,
317
+ $isDragging: isDragging,
318
+ style: {
319
+ ...style,
320
+ transform: CSS.Translate.toString(transform),
321
+ transition
322
+ }
323
+ })
324
+ });
325
+ };
326
+ const StyledRow = styled(Table.Row)`
327
+ ${({ $isDragging, theme })=>$isDragging && css`
328
+ position: relative;
329
+ z-index: 1;
330
+ background: ${theme.colors.primary100};
331
+ box-shadow: ${theme.shadows.tableShadow};
332
+ `}
333
+ `;
334
+ const PositionCell = ({ documentId, position, total, ...props })=>{
335
+ const { formatMessage } = useIntl();
336
+ const { isActive, canReorder, isMoving, moveToPosition } = React.useContext(CustomOrderContext);
337
+ const sortableRow = React.useContext(SortableRowContext);
338
+ const [isEditing, setIsEditing] = React.useState(false);
339
+ const buttonRef = React.useRef(null);
340
+ const shouldRestoreFocus = React.useRef(false);
341
+ /**
342
+ * Table rows don't forward their ref, so the row is reached through its cell.
343
+ */ const setRowNode = sortableRow?.setNodeRef;
344
+ const setCellNode = React.useCallback((node)=>{
345
+ setRowNode?.(node?.parentElement ?? null);
346
+ }, [
347
+ setRowNode
348
+ ]);
349
+ /**
350
+ * The button is disabled while the entry moves, and a disabled button cannot take the
351
+ * focus: when the input was left to move the entry, the focus comes back once the move
352
+ * is over.
353
+ */ React.useEffect(()=>{
354
+ if (!isEditing && !isMoving && shouldRestoreFocus.current) {
355
+ shouldRestoreFocus.current = false;
356
+ buttonRef.current?.focus();
357
+ }
358
+ }, [
359
+ isEditing,
360
+ isMoving
361
+ ]);
362
+ const handleKeyDown = (e)=>{
363
+ // Keeps the keys typed in the input away from the keyboard navigation of the grid
364
+ e.stopPropagation();
365
+ if (e.key === 'Enter') {
366
+ e.preventDefault();
367
+ shouldRestoreFocus.current = true;
368
+ setIsEditing(false);
369
+ const nextPosition = Number.parseInt(e.currentTarget.value, 10);
370
+ if (!Number.isNaN(nextPosition)) {
371
+ void moveToPosition(documentId, nextPosition);
372
+ }
373
+ } else if (e.key === 'Escape') {
374
+ shouldRestoreFocus.current = true;
375
+ setIsEditing(false);
376
+ }
377
+ };
378
+ const renderPosition = ()=>{
379
+ if (!canReorder) {
380
+ return /*#__PURE__*/ jsx(Typography, {
381
+ textColor: "neutral800",
382
+ children: position
383
+ });
384
+ }
385
+ if (isEditing) {
386
+ return /*#__PURE__*/ jsx(PositionInput, {
387
+ // eslint-disable-next-line jsx-a11y/no-autofocus -- the input replaces the button that was just activated
388
+ autoFocus: true,
389
+ "aria-label": formatMessage({
390
+ id: getTranslation('custom-order.position.input'),
391
+ defaultMessage: 'New position, from 1 to {total}'
392
+ }, {
393
+ total
394
+ }),
395
+ defaultValue: position,
396
+ inputMode: "numeric",
397
+ onBlur: ()=>setIsEditing(false),
398
+ onFocus: (e)=>e.currentTarget.select(),
399
+ onKeyDown: handleKeyDown
400
+ });
401
+ }
402
+ return /*#__PURE__*/ jsx(PositionButton, {
403
+ ref: buttonRef,
404
+ type: "button",
405
+ "aria-label": formatMessage({
406
+ id: getTranslation('custom-order.position.button'),
407
+ defaultMessage: 'Position {position} of {total}, change position'
408
+ }, {
409
+ position,
410
+ total
411
+ }),
412
+ disabled: isMoving,
413
+ onClick: ()=>setIsEditing(true),
414
+ children: position
415
+ });
416
+ };
417
+ return /*#__PURE__*/ jsx(Td, {
418
+ ref: setCellNode,
419
+ ...props,
420
+ onClick: (e)=>e.stopPropagation(),
421
+ children: isActive ? /*#__PURE__*/ jsxs(Flex, {
422
+ gap: 1,
423
+ alignItems: "center",
424
+ children: [
425
+ canReorder ? /*#__PURE__*/ jsx(Handle, {
426
+ ref: sortableRow?.setActivatorNodeRef,
427
+ ...sortableRow?.listeners,
428
+ "aria-hidden": true,
429
+ $isDragging: sortableRow?.isDragging ?? false,
430
+ children: /*#__PURE__*/ jsx(Drag, {})
431
+ }) : null,
432
+ renderPosition()
433
+ ]
434
+ }) : /*#__PURE__*/ jsx(Tooltip, {
435
+ label: formatMessage({
436
+ id: getTranslation('custom-order.inactive'),
437
+ defaultMessage: 'Sort by order to move entries'
438
+ }),
439
+ children: /*#__PURE__*/ jsx(InactiveHandle, {
440
+ children: /*#__PURE__*/ jsx(Drag, {})
441
+ })
442
+ })
443
+ });
444
+ };
445
+ const Handle = styled.span`
446
+ display: flex;
447
+ align-items: center;
448
+ padding: ${({ theme })=>theme.spaces[1]};
449
+ color: ${({ theme })=>theme.colors.neutral500};
450
+ cursor: ${({ $isDragging })=>$isDragging ? 'grabbing' : 'grab'};
451
+ /* Lets a finger drag the row instead of scrolling the page */
452
+ touch-action: none;
453
+
454
+ &:hover {
455
+ color: ${({ theme })=>theme.colors.neutral700};
456
+ }
457
+ `;
458
+ const InactiveHandle = styled.span`
459
+ display: inline-flex;
460
+ align-items: center;
461
+ padding: ${({ theme })=>theme.spaces[1]};
462
+ color: ${({ theme })=>theme.colors.neutral300};
463
+ `;
464
+ const positionControl = css`
465
+ width: 4.8rem;
466
+ height: 3.2rem;
467
+ padding: 0 ${({ theme })=>theme.spaces[2]};
468
+ border: 1px solid transparent;
469
+ border-radius: ${({ theme })=>theme.borderRadius};
470
+ background: transparent;
471
+ color: ${({ theme })=>theme.colors.neutral800};
472
+ font-size: ${({ theme })=>theme.fontSizes[2]};
473
+ text-align: left;
474
+ `;
475
+ const PositionButton = styled.button`
476
+ ${positionControl}
477
+ cursor: text;
478
+
479
+ &:hover:not(:disabled),
480
+ &:focus-visible {
481
+ border-color: ${({ theme })=>theme.colors.neutral200};
482
+ background: ${({ theme })=>theme.colors.neutral0};
483
+ }
484
+
485
+ &:disabled {
486
+ cursor: default;
487
+ }
488
+ `;
489
+ const PositionInput = styled.input`
490
+ ${positionControl}
491
+ border-color: ${({ theme })=>theme.colors.primary600};
492
+ background: ${({ theme })=>theme.colors.neutral0};
493
+ outline: none;
494
+ box-shadow: ${({ theme })=>theme.colors.primary600} 0px 0px 0px 2px;
495
+ `;
496
+ /* -------------------------------------------------------------------------------------------------
497
+ * Row actions
498
+ * -----------------------------------------------------------------------------------------------*/ const MoveToTopAction = ({ documentId })=>{
499
+ const { formatMessage } = useIntl();
500
+ const { canReorder, isMoving, getPosition, moveToPosition } = React.useContext(CustomOrderContext);
501
+ if (!canReorder || !documentId) {
502
+ return null;
503
+ }
504
+ return {
505
+ disabled: isMoving || getPosition(documentId) === 1,
506
+ icon: /*#__PURE__*/ jsx(ArrowUp, {}),
507
+ label: formatMessage({
508
+ id: 'content-manager.actions.move-to-top.label',
509
+ defaultMessage: 'Move to top'
510
+ }),
511
+ position: 'table-row',
512
+ onClick: ()=>{
513
+ void moveToPosition(documentId, 1);
514
+ }
515
+ };
516
+ };
517
+ MoveToTopAction.position = 'table-row';
518
+ const MoveToBottomAction = ({ documentId })=>{
519
+ const { formatMessage } = useIntl();
520
+ const { canReorder, isMoving, total, getPosition, moveToPosition } = React.useContext(CustomOrderContext);
521
+ if (!canReorder || !documentId) {
522
+ return null;
523
+ }
524
+ return {
525
+ disabled: isMoving || getPosition(documentId) === total,
526
+ icon: /*#__PURE__*/ jsx(ArrowDown, {}),
527
+ label: formatMessage({
528
+ id: 'content-manager.actions.move-to-bottom.label',
529
+ defaultMessage: 'Move to bottom'
530
+ }),
531
+ position: 'table-row',
532
+ onClick: ()=>{
533
+ // Positions past the end are brought back to the last one
534
+ void moveToPosition(documentId, Number.MAX_SAFE_INTEGER);
535
+ }
536
+ };
537
+ };
538
+ MoveToBottomAction.position = 'table-row';
539
+ const CustomOrder = {
540
+ Root,
541
+ Row,
542
+ PositionCell
543
+ };
544
+
545
+ export { CustomOrder, MoveToBottomAction, MoveToTopAction, useCustomOrder };
546
+ //# sourceMappingURL=CustomOrder.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CustomOrder.mjs","sources":["../../../../../admin/src/pages/ListView/components/CustomOrder.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n DndContext,\n PointerSensor,\n closestCenter,\n useSensor,\n useSensors,\n type DragEndEvent,\n type Modifier,\n} from '@dnd-kit/core';\nimport {\n SortableContext,\n arrayMove,\n useSortable,\n verticalListSortingStrategy,\n} from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\nimport { QueryStatus } from '@reduxjs/toolkit/query';\nimport { Table, useAPIErrorHandler, useNotification } from '@strapi/admin/strapi-admin';\nimport { Flex, Td, Tooltip, Typography } from '@strapi/design-system';\nimport { ArrowDown, ArrowUp, Drag } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { useStore } from 'react-redux';\nimport { css, styled } from 'styled-components';\n\nimport { CUSTOM_ORDER_SORT } from '../../../constants/customOrder';\nimport { useLazyGetAllDocumentsQuery, useMoveDocumentMutation } from '../../../services/documents';\nimport { getTranslation } from '../../../utils/translations';\n\nimport type { DocumentActionComponent } from '../../../content-manager';\nimport type { Document } from '../../../hooks/useDocument';\nimport type { Store } from '@strapi/admin/strapi-admin';\n\n/* -------------------------------------------------------------------------------------------------\n * useCustomOrder\n * -----------------------------------------------------------------------------------------------*/\n\ninterface CustomOrderState {\n /** Custom order is turned on for the content type. */\n isAvailable: boolean;\n /** The list is sorted by its custom order, so the position of an entry means something. */\n isActive: boolean;\n /** The user is allowed to move entries, and the list is in a state where they can be moved. */\n canReorder: boolean;\n /**\n * A move is in progress: from the moment it is asked until the list shows its result.\n * No other move can start in the meantime.\n */\n isMoving: boolean;\n /** The entries of the page, in the order they should be displayed. */\n rows: Document[];\n /** Number of entries in the current view, all pages included. */\n total: number;\n /** 1-based position of an entry of the page in the current view. */\n getPosition: (documentId: string) => number | undefined;\n /** Moves an entry of the page to the place of another entry of the page. */\n moveToIndex: (from: number, to: number) => Promise<void>;\n /** Moves an entry of the page to a position of the current view, on this page or another. */\n moveToPosition: (documentId: string, position: number) => Promise<void>;\n}\n\ninterface UseCustomOrderOptions {\n model: string;\n isAvailable: boolean;\n canUpdate: boolean;\n sort?: string;\n /**\n * Params of the list request. Reused to find which entry sits at a given position\n * of the same view when it is not on the current page.\n */\n params: Record<string, unknown>;\n results: Document[];\n pagination?: { page: number; pageSize: number; total: number };\n /**\n * Not needed anymore: the hook fetches the list again itself after a move and knows when\n * that answer lands. Still accepted so that existing callers keep compiling.\n */\n fulfilledTimeStamp?: number;\n}\n\n/**\n * How many times the list is asked again after a move before giving up. Each attempt waits\n * for a whole request, so two are enough in practice (see `refetchList`).\n */\nconst MAX_REFETCH_ATTEMPTS = 3;\n\nconst useCustomOrder = ({\n model,\n isAvailable,\n canUpdate,\n sort,\n params,\n results,\n pagination,\n}: UseCustomOrderOptions): CustomOrderState => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);\n const [moveDocument] = useMoveDocumentMutation();\n const [fetchDocuments] = useLazyGetAllDocumentsQuery();\n const store = useStore<ReturnType<Store['getState']>>();\n\n const [isMoving, setIsMoving] = React.useState(false);\n // Same value for the handlers, which may run again before React has rendered the state\n const isMovingRef = React.useRef(false);\n /** Order to display until the move has landed, when it stays within the page. */\n const [pendingOrder, setPendingOrder] = React.useState<string[] | null>(null);\n\n const isActive = isAvailable && sort?.toUpperCase() === CUSTOM_ORDER_SORT.toUpperCase();\n\n /**\n * The list is fetched again after each move. Until that answer lands, the table keeps\n * showing its rows instead of a loading state, which would make every move blink.\n * Any other answer landing in the meantime does not touch the order shown.\n */\n const rows = React.useMemo(() => {\n if (!isMoving || !pendingOrder) {\n return results;\n }\n\n const rowsById = new Map(results.map((row) => [row.documentId, row]));\n\n return pendingOrder.flatMap((documentId) => rowsById.get(documentId) ?? []);\n }, [isMoving, pendingOrder, results]);\n\n const offset = pagination ? (pagination.page - 1) * pagination.pageSize : 0;\n const total = pagination?.total ?? results.length;\n const locale = typeof params.locale === 'string' ? params.locale : undefined;\n\n /**\n * Runs a move while blocking any other one: from the moment it is asked until the list\n * shows its result, the handles, the position inputs and the row actions are inert.\n */\n const runExclusively = async (run: () => Promise<void>) => {\n if (isMovingRef.current) {\n return;\n }\n\n isMovingRef.current = true;\n setIsMoving(true);\n\n try {\n await run();\n } finally {\n isMovingRef.current = false;\n setPendingOrder(null);\n setIsMoving(false);\n }\n };\n\n /**\n * Resolves once no request of the list is in flight anymore.\n */\n const waitForList = (queryCacheKey: string) =>\n new Promise<void>((resolve) => {\n const isSettled = () =>\n store.getState().adminApi.queries[queryCacheKey]?.status !== QueryStatus.pending;\n\n if (isSettled()) {\n resolve();\n\n return;\n }\n\n const unsubscribe = store.subscribe(() => {\n if (isSettled()) {\n unsubscribe();\n resolve();\n }\n });\n });\n\n /**\n * Waits for the list to be fetched again after a move. The mutation invalidates the list,\n * but RTK Query drops that refetch when another request is already in flight, and that\n * request may have started before the server applied the move. So the list is asked again\n * until a request started after the move was answered, otherwise the table could settle on\n * a stale snapshot. An attempt is dropped the same way when a request is in flight: it\n * then waits for that request, which is the one the mutation started most of the time.\n *\n * @param movedAt - When the server answered the move\n */\n const refetchList = async (movedAt: number) => {\n for (let attempt = 0; attempt < MAX_REFETCH_ATTEMPTS; attempt += 1) {\n const request = fetchDocuments({ model, params });\n const { requestId, startedTimeStamp = 0 } = await request;\n // The page subscribes to the list itself\n request.unsubscribe();\n\n if (requestId === request.requestId) {\n return;\n }\n\n await waitForList(request.queryCacheKey);\n\n if (startedTimeStamp >= movedAt) {\n return;\n }\n }\n };\n\n const move = async (\n documentId: string,\n anchorId: string,\n placement: 'before' | 'after',\n order?: string[]\n ) => {\n if (order) {\n setPendingOrder(order);\n }\n\n const mutation = moveDocument({\n model,\n id: documentId,\n body: placement === 'before' ? { before: anchorId } : { after: anchorId },\n params: { locale },\n });\n const res = await mutation;\n\n if ('error' in res) {\n setPendingOrder(null);\n toggleNotification({ type: 'danger', message: formatAPIError(res.error) });\n\n return false;\n }\n\n const { fulfilledTimeStamp: movedAt = Date.now() } =\n store.getState().adminApi.mutations[mutation.requestId] ?? {};\n\n await refetchList(movedAt);\n\n return true;\n };\n\n const moveWithinPage = (from: number, to: number) => {\n const moved = rows[from];\n const anchor = rows[to];\n\n return move(\n moved.documentId,\n anchor.documentId,\n to > from ? 'after' : 'before',\n arrayMove(rows, from, to).map((row) => row.documentId)\n );\n };\n\n const moveToIndex: CustomOrderState['moveToIndex'] = async (from, to) => {\n if (from === to || !rows[from] || !rows[to]) {\n return;\n }\n\n await runExclusively(async () => {\n await moveWithinPage(from, to);\n });\n };\n\n const moveToPosition: CustomOrderState['moveToPosition'] = async (documentId, position) => {\n const from = rows.findIndex((row) => row.documentId === documentId);\n\n if (from === -1 || total === 0) {\n return;\n }\n\n const currentPosition = offset + from + 1;\n const targetPosition = Math.min(Math.max(Math.trunc(position), 1), total);\n\n if (targetPosition === currentPosition) {\n return;\n }\n\n const to = targetPosition - offset - 1;\n\n await runExclusively(async () => {\n if (to >= 0 && to < rows.length) {\n await moveWithinPage(from, to);\n\n return;\n }\n\n // The destination is on another page: ask the server which entry sits there in this view\n const lookup = fetchDocuments({\n model,\n params: { ...params, page: String(targetPosition), pageSize: '1' },\n });\n const res = await lookup;\n // Otherwise every later invalidation of the list would fetch that entry again\n lookup.unsubscribe();\n\n if (res.error) {\n toggleNotification({ type: 'danger', message: formatAPIError(res.error) });\n\n return;\n }\n\n const anchor = res.data?.results[0];\n\n if (!anchor) {\n return;\n }\n\n const hasMoved = await move(\n documentId,\n anchor.documentId,\n targetPosition > currentPosition ? 'after' : 'before'\n );\n\n if (hasMoved) {\n toggleNotification({\n type: 'success',\n message: formatMessage(\n {\n id: getTranslation('custom-order.moved'),\n defaultMessage: 'Entry moved to position {position}',\n },\n { position: targetPosition }\n ),\n });\n }\n });\n };\n\n return {\n isAvailable,\n isActive,\n canReorder: isActive && canUpdate,\n isMoving,\n rows,\n total,\n getPosition(documentId) {\n const index = rows.findIndex((row) => row.documentId === documentId);\n\n return index === -1 ? undefined : offset + index + 1;\n },\n moveToIndex,\n moveToPosition,\n };\n};\n\nconst CustomOrderContext = React.createContext<CustomOrderState>({\n isAvailable: false,\n isActive: false,\n canReorder: false,\n isMoving: false,\n rows: [],\n total: 0,\n getPosition: () => undefined,\n moveToIndex: async () => {},\n moveToPosition: async () => {},\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\nconst restrictToVerticalAxis: Modifier = ({ transform }) => ({ ...transform, x: 0 });\n\ninterface RootProps {\n children: React.ReactNode;\n state: CustomOrderState;\n}\n\n/**\n * Has to wrap the whole table: the drag and drop context renders elements for screen\n * readers next to its children, and those are not valid inside a table.\n */\nconst Root = ({ children, state }: RootProps) => {\n // Entries are dragged with a pointer only. The grid owns the arrow keys, so the keyboard\n // goes through the position input and the row actions instead.\n const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 4 } }));\n const items = React.useMemo(() => state.rows.map((row) => row.documentId), [state.rows]);\n\n if (!state.isAvailable) {\n return children;\n }\n\n const handleDragEnd = ({ active, over }: DragEndEvent) => {\n if (!over || active.id === over.id) {\n return;\n }\n\n void state.moveToIndex(items.indexOf(String(active.id)), items.indexOf(String(over.id)));\n };\n\n return (\n <CustomOrderContext.Provider value={state}>\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n modifiers={[restrictToVerticalAxis]}\n onDragEnd={handleDragEnd}\n >\n <SortableContext\n items={items}\n strategy={verticalListSortingStrategy}\n disabled={!state.canReorder || state.isMoving}\n >\n {children}\n </SortableContext>\n </DndContext>\n </CustomOrderContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Row\n * -----------------------------------------------------------------------------------------------*/\n\ntype SortableRow = Pick<\n ReturnType<typeof useSortable>,\n 'setNodeRef' | 'setActivatorNodeRef' | 'listeners' | 'isDragging'\n>;\n\nconst SortableRowContext = React.createContext<SortableRow | null>(null);\n\ntype RowProps = React.ComponentProps<typeof Table.Row> & {\n documentId: string;\n};\n\n/**\n * A table row that can be dragged when the entries follow a custom order,\n * a regular table row otherwise.\n */\nconst Row = ({ documentId, ...props }: RowProps) => {\n const { isAvailable } = React.useContext(CustomOrderContext);\n\n if (!isAvailable) {\n return <Table.Row {...props} />;\n }\n\n return <DraggableRow documentId={documentId} {...props} />;\n};\n\nconst DraggableRow = ({ documentId, style, ...props }: RowProps) => {\n const { setNodeRef, setActivatorNodeRef, listeners, transform, transition, isDragging } =\n useSortable({ id: documentId });\n\n const sortableRow = React.useMemo(\n () => ({ setNodeRef, setActivatorNodeRef, listeners, isDragging }),\n [setNodeRef, setActivatorNodeRef, listeners, isDragging]\n );\n\n // The provider has to stay outside of the row, which only expects cells as children\n return (\n <SortableRowContext.Provider value={sortableRow}>\n <StyledRow\n {...props}\n $isDragging={isDragging}\n style={{ ...style, transform: CSS.Translate.toString(transform), transition }}\n />\n </SortableRowContext.Provider>\n );\n};\n\nconst StyledRow = styled(Table.Row)<{ $isDragging: boolean }>`\n ${({ $isDragging, theme }) =>\n $isDragging &&\n css`\n position: relative;\n z-index: 1;\n background: ${theme.colors.primary100};\n box-shadow: ${theme.shadows.tableShadow};\n `}\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * PositionCell\n * -----------------------------------------------------------------------------------------------*/\n\ntype PositionCellProps = React.ComponentProps<typeof Td> & {\n documentId: string;\n position: number;\n total: number;\n};\n\nconst PositionCell = ({ documentId, position, total, ...props }: PositionCellProps) => {\n const { formatMessage } = useIntl();\n const { isActive, canReorder, isMoving, moveToPosition } = React.useContext(CustomOrderContext);\n const sortableRow = React.useContext(SortableRowContext);\n const [isEditing, setIsEditing] = React.useState(false);\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n const shouldRestoreFocus = React.useRef(false);\n\n /**\n * Table rows don't forward their ref, so the row is reached through its cell.\n */\n const setRowNode = sortableRow?.setNodeRef;\n const setCellNode = React.useCallback(\n (node: HTMLTableCellElement | null) => {\n setRowNode?.(node?.parentElement ?? null);\n },\n [setRowNode]\n );\n\n /**\n * The button is disabled while the entry moves, and a disabled button cannot take the\n * focus: when the input was left to move the entry, the focus comes back once the move\n * is over.\n */\n React.useEffect(() => {\n if (!isEditing && !isMoving && shouldRestoreFocus.current) {\n shouldRestoreFocus.current = false;\n buttonRef.current?.focus();\n }\n }, [isEditing, isMoving]);\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n // Keeps the keys typed in the input away from the keyboard navigation of the grid\n e.stopPropagation();\n\n if (e.key === 'Enter') {\n e.preventDefault();\n shouldRestoreFocus.current = true;\n setIsEditing(false);\n\n const nextPosition = Number.parseInt(e.currentTarget.value, 10);\n\n if (!Number.isNaN(nextPosition)) {\n void moveToPosition(documentId, nextPosition);\n }\n } else if (e.key === 'Escape') {\n shouldRestoreFocus.current = true;\n setIsEditing(false);\n }\n };\n\n const renderPosition = () => {\n if (!canReorder) {\n return <Typography textColor=\"neutral800\">{position}</Typography>;\n }\n\n if (isEditing) {\n return (\n <PositionInput\n // eslint-disable-next-line jsx-a11y/no-autofocus -- the input replaces the button that was just activated\n autoFocus\n aria-label={formatMessage(\n {\n id: getTranslation('custom-order.position.input'),\n defaultMessage: 'New position, from 1 to {total}',\n },\n { total }\n )}\n defaultValue={position}\n inputMode=\"numeric\"\n onBlur={() => setIsEditing(false)}\n onFocus={(e) => e.currentTarget.select()}\n onKeyDown={handleKeyDown}\n />\n );\n }\n\n return (\n <PositionButton\n ref={buttonRef}\n type=\"button\"\n aria-label={formatMessage(\n {\n id: getTranslation('custom-order.position.button'),\n defaultMessage: 'Position {position} of {total}, change position',\n },\n { position, total }\n )}\n disabled={isMoving}\n onClick={() => setIsEditing(true)}\n >\n {position}\n </PositionButton>\n );\n };\n\n return (\n <Td ref={setCellNode} {...props} onClick={(e: React.MouseEvent) => e.stopPropagation()}>\n {isActive ? (\n <Flex gap={1} alignItems=\"center\">\n {canReorder ? (\n <Handle\n ref={sortableRow?.setActivatorNodeRef}\n {...sortableRow?.listeners}\n aria-hidden\n $isDragging={sortableRow?.isDragging ?? false}\n >\n <Drag />\n </Handle>\n ) : null}\n {renderPosition()}\n </Flex>\n ) : (\n <Tooltip\n label={formatMessage({\n id: getTranslation('custom-order.inactive'),\n defaultMessage: 'Sort by order to move entries',\n })}\n >\n <InactiveHandle>\n <Drag />\n </InactiveHandle>\n </Tooltip>\n )}\n </Td>\n );\n};\n\nconst Handle = styled.span<{ $isDragging: boolean }>`\n display: flex;\n align-items: center;\n padding: ${({ theme }) => theme.spaces[1]};\n color: ${({ theme }) => theme.colors.neutral500};\n cursor: ${({ $isDragging }) => ($isDragging ? 'grabbing' : 'grab')};\n /* Lets a finger drag the row instead of scrolling the page */\n touch-action: none;\n\n &:hover {\n color: ${({ theme }) => theme.colors.neutral700};\n }\n`;\n\nconst InactiveHandle = styled.span`\n display: inline-flex;\n align-items: center;\n padding: ${({ theme }) => theme.spaces[1]};\n color: ${({ theme }) => theme.colors.neutral300};\n`;\n\nconst positionControl = css`\n width: 4.8rem;\n height: 3.2rem;\n padding: 0 ${({ theme }) => theme.spaces[2]};\n border: 1px solid transparent;\n border-radius: ${({ theme }) => theme.borderRadius};\n background: transparent;\n color: ${({ theme }) => theme.colors.neutral800};\n font-size: ${({ theme }) => theme.fontSizes[2]};\n text-align: left;\n`;\n\nconst PositionButton = styled.button`\n ${positionControl}\n cursor: text;\n\n &:hover:not(:disabled),\n &:focus-visible {\n border-color: ${({ theme }) => theme.colors.neutral200};\n background: ${({ theme }) => theme.colors.neutral0};\n }\n\n &:disabled {\n cursor: default;\n }\n`;\n\nconst PositionInput = styled.input`\n ${positionControl}\n border-color: ${({ theme }) => theme.colors.primary600};\n background: ${({ theme }) => theme.colors.neutral0};\n outline: none;\n box-shadow: ${({ theme }) => theme.colors.primary600} 0px 0px 0px 2px;\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Row actions\n * -----------------------------------------------------------------------------------------------*/\n\nconst MoveToTopAction: DocumentActionComponent = ({ documentId }) => {\n const { formatMessage } = useIntl();\n const { canReorder, isMoving, getPosition, moveToPosition } =\n React.useContext(CustomOrderContext);\n\n if (!canReorder || !documentId) {\n return null;\n }\n\n return {\n disabled: isMoving || getPosition(documentId) === 1,\n icon: <ArrowUp />,\n label: formatMessage({\n id: 'content-manager.actions.move-to-top.label',\n defaultMessage: 'Move to top',\n }),\n position: 'table-row',\n onClick: () => {\n void moveToPosition(documentId, 1);\n },\n };\n};\n\nMoveToTopAction.position = 'table-row';\n\nconst MoveToBottomAction: DocumentActionComponent = ({ documentId }) => {\n const { formatMessage } = useIntl();\n const { canReorder, isMoving, total, getPosition, moveToPosition } =\n React.useContext(CustomOrderContext);\n\n if (!canReorder || !documentId) {\n return null;\n }\n\n return {\n disabled: isMoving || getPosition(documentId) === total,\n icon: <ArrowDown />,\n label: formatMessage({\n id: 'content-manager.actions.move-to-bottom.label',\n defaultMessage: 'Move to bottom',\n }),\n position: 'table-row',\n onClick: () => {\n // Positions past the end are brought back to the last one\n void moveToPosition(documentId, Number.MAX_SAFE_INTEGER);\n },\n };\n};\n\nMoveToBottomAction.position = 'table-row';\n\nconst CustomOrder = {\n Root,\n Row,\n PositionCell,\n};\n\nexport { CustomOrder, useCustomOrder, MoveToTopAction, MoveToBottomAction };\nexport type { CustomOrderState };\n"],"names":["MAX_REFETCH_ATTEMPTS","useCustomOrder","model","isAvailable","canUpdate","sort","params","results","pagination","formatMessage","useIntl","toggleNotification","useNotification","_unstableFormatAPIError","formatAPIError","useAPIErrorHandler","getTranslation","moveDocument","useMoveDocumentMutation","fetchDocuments","useLazyGetAllDocumentsQuery","store","useStore","isMoving","setIsMoving","React","useState","isMovingRef","useRef","pendingOrder","setPendingOrder","isActive","toUpperCase","CUSTOM_ORDER_SORT","rows","useMemo","rowsById","Map","map","row","documentId","flatMap","get","offset","page","pageSize","total","length","locale","undefined","runExclusively","run","current","waitForList","queryCacheKey","Promise","resolve","isSettled","getState","adminApi","queries","status","QueryStatus","pending","unsubscribe","subscribe","refetchList","movedAt","attempt","request","requestId","startedTimeStamp","move","anchorId","placement","order","mutation","id","body","before","after","res","type","message","error","fulfilledTimeStamp","Date","now","mutations","moveWithinPage","from","to","moved","anchor","arrayMove","moveToIndex","moveToPosition","position","findIndex","currentPosition","targetPosition","Math","min","max","trunc","lookup","String","data","hasMoved","defaultMessage","canReorder","getPosition","index","CustomOrderContext","createContext","restrictToVerticalAxis","transform","x","Root","children","state","sensors","useSensors","useSensor","PointerSensor","activationConstraint","distance","items","handleDragEnd","active","over","indexOf","_jsx","Provider","value","DndContext","collisionDetection","closestCenter","modifiers","onDragEnd","SortableContext","strategy","verticalListSortingStrategy","disabled","SortableRowContext","Row","props","useContext","Table","DraggableRow","style","setNodeRef","setActivatorNodeRef","listeners","transition","isDragging","useSortable","sortableRow","StyledRow","$isDragging","CSS","Translate","toString","styled","theme","css","colors","primary100","shadows","tableShadow","PositionCell","isEditing","setIsEditing","buttonRef","shouldRestoreFocus","setRowNode","setCellNode","useCallback","node","parentElement","useEffect","focus","handleKeyDown","e","stopPropagation","key","preventDefault","nextPosition","Number","parseInt","currentTarget","isNaN","renderPosition","Typography","textColor","PositionInput","autoFocus","aria-label","defaultValue","inputMode","onBlur","onFocus","select","onKeyDown","PositionButton","ref","onClick","Td","_jsxs","Flex","gap","alignItems","Handle","aria-hidden","Drag","Tooltip","label","InactiveHandle","span","spaces","neutral500","neutral700","neutral300","positionControl","borderRadius","neutral800","fontSizes","button","neutral200","neutral0","input","primary600","MoveToTopAction","icon","ArrowUp","MoveToBottomAction","ArrowDown","MAX_SAFE_INTEGER","CustomOrder"],"mappings":"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"}
@@ -15,6 +15,7 @@ var useDocumentActions = require('../../../hooks/useDocumentActions.js');
15
15
  var api = require('../../../utils/api.js');
16
16
  var DocumentActions = require('../../EditView/components/DocumentActions.js');
17
17
  var AutoCloneFailureModal = require('./AutoCloneFailureModal.js');
18
+ var CustomOrder = require('./CustomOrder.js');
18
19
 
19
20
  function _interopNamespace(e) {
20
21
  if (e && e.__esModule) return e;
@@ -257,7 +258,9 @@ CloneAction.position = 'table-row';
257
258
  const DEFAULT_TABLE_ROW_ACTIONS = [
258
259
  EditAction,
259
260
  OpenInNewTabAction,
260
- CloneAction
261
+ CloneAction,
262
+ CustomOrder.MoveToTopAction,
263
+ CustomOrder.MoveToBottomAction
261
264
  ];
262
265
 
263
266
  exports.DEFAULT_TABLE_ROW_ACTIONS = DEFAULT_TABLE_ROW_ACTIONS;