@strapi/content-manager 5.61.1 → 5.62.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 (260) hide show
  1. package/dist/admin/components/ConfigurationForm/Fields.js +1 -1
  2. package/dist/admin/components/ConfigurationForm/Fields.js.map +1 -1
  3. package/dist/admin/components/ConfigurationForm/Fields.mjs +3 -3
  4. package/dist/admin/components/ConfigurationForm/Fields.mjs.map +1 -1
  5. package/dist/admin/features/I18nSharedFieldsLock.js +54 -0
  6. package/dist/admin/features/I18nSharedFieldsLock.js.map +1 -0
  7. package/dist/admin/features/I18nSharedFieldsLock.mjs +31 -0
  8. package/dist/admin/features/I18nSharedFieldsLock.mjs.map +1 -0
  9. package/dist/admin/history/components/VersionInputRenderer.js +7 -2
  10. package/dist/admin/history/components/VersionInputRenderer.js.map +1 -1
  11. package/dist/admin/history/components/VersionInputRenderer.mjs +7 -3
  12. package/dist/admin/history/components/VersionInputRenderer.mjs.map +1 -1
  13. package/dist/admin/hooks/useContentManagerInitData.js +27 -8
  14. package/dist/admin/hooks/useContentManagerInitData.js.map +1 -1
  15. package/dist/admin/hooks/useContentManagerInitData.mjs +29 -10
  16. package/dist/admin/hooks/useContentManagerInitData.mjs.map +1 -1
  17. package/dist/admin/hooks/useDocument.js +11 -13
  18. package/dist/admin/hooks/useDocument.js.map +1 -1
  19. package/dist/admin/hooks/useDocument.mjs +11 -13
  20. package/dist/admin/hooks/useDocument.mjs.map +1 -1
  21. package/dist/admin/hooks/useI18nFieldLock.js +169 -0
  22. package/dist/admin/hooks/useI18nFieldLock.js.map +1 -0
  23. package/dist/admin/hooks/useI18nFieldLock.mjs +140 -0
  24. package/dist/admin/hooks/useI18nFieldLock.mjs.map +1 -0
  25. package/dist/admin/hooks/usePersistentQueryParams.js +16 -3
  26. package/dist/admin/hooks/usePersistentQueryParams.js.map +1 -1
  27. package/dist/admin/hooks/usePersistentQueryParams.mjs +16 -3
  28. package/dist/admin/hooks/usePersistentQueryParams.mjs.map +1 -1
  29. package/dist/admin/index.js +5 -0
  30. package/dist/admin/index.js.map +1 -1
  31. package/dist/admin/index.mjs +2 -0
  32. package/dist/admin/index.mjs.map +1 -1
  33. package/dist/admin/modules/app.js +8 -1
  34. package/dist/admin/modules/app.js.map +1 -1
  35. package/dist/admin/modules/app.mjs +8 -2
  36. package/dist/admin/modules/app.mjs.map +1 -1
  37. package/dist/admin/pages/EditView/EditViewPage.js +129 -127
  38. package/dist/admin/pages/EditView/EditViewPage.js.map +1 -1
  39. package/dist/admin/pages/EditView/EditViewPage.mjs +129 -127
  40. package/dist/admin/pages/EditView/EditViewPage.mjs.map +1 -1
  41. package/dist/admin/pages/EditView/components/DocumentActions.js +11 -4
  42. package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
  43. package/dist/admin/pages/EditView/components/DocumentActions.mjs +12 -5
  44. package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
  45. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.js +31 -21
  46. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.js.map +1 -1
  47. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.mjs +32 -22
  48. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/EditorLayout.mjs.map +1 -1
  49. package/dist/admin/pages/EditView/components/FormInputs/Component/AddComponentMenu.js +98 -0
  50. package/dist/admin/pages/EditView/components/FormInputs/Component/AddComponentMenu.js.map +1 -0
  51. package/dist/admin/pages/EditView/components/FormInputs/Component/AddComponentMenu.mjs +96 -0
  52. package/dist/admin/pages/EditView/components/FormInputs/Component/AddComponentMenu.mjs.map +1 -0
  53. package/dist/admin/pages/EditView/components/FormInputs/Component/ComponentCopyModal.js +1103 -0
  54. package/dist/admin/pages/EditView/components/FormInputs/Component/ComponentCopyModal.js.map +1 -0
  55. package/dist/admin/pages/EditView/components/FormInputs/Component/ComponentCopyModal.mjs +1077 -0
  56. package/dist/admin/pages/EditView/components/FormInputs/Component/ComponentCopyModal.mjs.map +1 -0
  57. package/dist/admin/pages/EditView/components/FormInputs/Component/CopiedComponents.js +211 -0
  58. package/dist/admin/pages/EditView/components/FormInputs/Component/CopiedComponents.js.map +1 -0
  59. package/dist/admin/pages/EditView/components/FormInputs/Component/CopiedComponents.mjs +183 -0
  60. package/dist/admin/pages/EditView/components/FormInputs/Component/CopiedComponents.mjs.map +1 -0
  61. package/dist/admin/pages/EditView/components/FormInputs/Component/Initializer.js +84 -41
  62. package/dist/admin/pages/EditView/components/FormInputs/Component/Initializer.js.map +1 -1
  63. package/dist/admin/pages/EditView/components/FormInputs/Component/Initializer.mjs +86 -43
  64. package/dist/admin/pages/EditView/components/FormInputs/Component/Initializer.mjs.map +1 -1
  65. package/dist/admin/pages/EditView/components/FormInputs/Component/Input.js +86 -20
  66. package/dist/admin/pages/EditView/components/FormInputs/Component/Input.js.map +1 -1
  67. package/dist/admin/pages/EditView/components/FormInputs/Component/Input.mjs +89 -23
  68. package/dist/admin/pages/EditView/components/FormInputs/Component/Input.mjs.map +1 -1
  69. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js +5 -2
  70. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js.map +1 -1
  71. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs +5 -2
  72. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs.map +1 -1
  73. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js +142 -22
  74. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js.map +1 -1
  75. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs +143 -23
  76. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs.map +1 -1
  77. package/dist/admin/pages/EditView/components/FormInputs/Component/utils/componentCopy.js +402 -0
  78. package/dist/admin/pages/EditView/components/FormInputs/Component/utils/componentCopy.js.map +1 -0
  79. package/dist/admin/pages/EditView/components/FormInputs/Component/utils/componentCopy.mjs +389 -0
  80. package/dist/admin/pages/EditView/components/FormInputs/Component/utils/componentCopy.mjs.map +1 -0
  81. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.js +84 -33
  82. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.js.map +1 -1
  83. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.mjs +85 -34
  84. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.mjs.map +1 -1
  85. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentPicker.js +5 -1
  86. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentPicker.js.map +1 -1
  87. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentPicker.mjs +5 -1
  88. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentPicker.mjs.map +1 -1
  89. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js +17 -4
  90. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js.map +1 -1
  91. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs +18 -5
  92. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs.map +1 -1
  93. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.js +54 -6
  94. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.js.map +1 -1
  95. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.mjs +54 -6
  96. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.mjs.map +1 -1
  97. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js +11 -9
  98. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js.map +1 -1
  99. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs +12 -10
  100. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs.map +1 -1
  101. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +9 -4
  102. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
  103. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +9 -4
  104. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
  105. package/dist/admin/pages/EditView/components/FormLayout.js +66 -63
  106. package/dist/admin/pages/EditView/components/FormLayout.js.map +1 -1
  107. package/dist/admin/pages/EditView/components/FormLayout.mjs +66 -63
  108. package/dist/admin/pages/EditView/components/FormLayout.mjs.map +1 -1
  109. package/dist/admin/pages/EditView/components/InputRenderer.js +7 -1
  110. package/dist/admin/pages/EditView/components/InputRenderer.js.map +1 -1
  111. package/dist/admin/pages/EditView/components/InputRenderer.mjs +7 -1
  112. package/dist/admin/pages/EditView/components/InputRenderer.mjs.map +1 -1
  113. package/dist/admin/pages/EditView/utils/data.js +14 -9
  114. package/dist/admin/pages/EditView/utils/data.js.map +1 -1
  115. package/dist/admin/pages/EditView/utils/data.mjs +14 -9
  116. package/dist/admin/pages/EditView/utils/data.mjs.map +1 -1
  117. package/dist/admin/pages/EditView/utils/forms.js +34 -0
  118. package/dist/admin/pages/EditView/utils/forms.js.map +1 -1
  119. package/dist/admin/pages/EditView/utils/forms.mjs +34 -1
  120. package/dist/admin/pages/EditView/utils/forms.mjs.map +1 -1
  121. package/dist/admin/pages/ListConfiguration/components/DraggableCard.js +2 -1
  122. package/dist/admin/pages/ListConfiguration/components/DraggableCard.js.map +1 -1
  123. package/dist/admin/pages/ListConfiguration/components/DraggableCard.mjs +2 -1
  124. package/dist/admin/pages/ListConfiguration/components/DraggableCard.mjs.map +1 -1
  125. package/dist/admin/pages/ListConfiguration/components/EditFieldForm.js +7 -6
  126. package/dist/admin/pages/ListConfiguration/components/EditFieldForm.js.map +1 -1
  127. package/dist/admin/pages/ListConfiguration/components/EditFieldForm.mjs +7 -6
  128. package/dist/admin/pages/ListConfiguration/components/EditFieldForm.mjs.map +1 -1
  129. package/dist/admin/pages/ListView/ListViewPage.js +11 -2
  130. package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
  131. package/dist/admin/pages/ListView/ListViewPage.mjs +13 -4
  132. package/dist/admin/pages/ListView/ListViewPage.mjs.map +1 -1
  133. package/dist/admin/pages/ListView/components/Filters.js +15 -5
  134. package/dist/admin/pages/ListView/components/Filters.js.map +1 -1
  135. package/dist/admin/pages/ListView/components/Filters.mjs +16 -7
  136. package/dist/admin/pages/ListView/components/Filters.mjs.map +1 -1
  137. package/dist/admin/preview/components/InputPopover.js +18 -8
  138. package/dist/admin/preview/components/InputPopover.js.map +1 -1
  139. package/dist/admin/preview/components/InputPopover.mjs +19 -9
  140. package/dist/admin/preview/components/InputPopover.mjs.map +1 -1
  141. package/dist/admin/preview/pages/Preview.js +5 -16
  142. package/dist/admin/preview/pages/Preview.js.map +1 -1
  143. package/dist/admin/preview/pages/Preview.mjs +5 -16
  144. package/dist/admin/preview/pages/Preview.mjs.map +1 -1
  145. package/dist/admin/preview/utils/fieldUtils.js +2 -0
  146. package/dist/admin/preview/utils/fieldUtils.js.map +1 -1
  147. package/dist/admin/preview/utils/fieldUtils.mjs +2 -1
  148. package/dist/admin/preview/utils/fieldUtils.mjs.map +1 -1
  149. package/dist/admin/services/api.js +2 -1
  150. package/dist/admin/services/api.js.map +1 -1
  151. package/dist/admin/services/api.mjs +2 -1
  152. package/dist/admin/services/api.mjs.map +1 -1
  153. package/dist/admin/services/documents.js +21 -1
  154. package/dist/admin/services/documents.js.map +1 -1
  155. package/dist/admin/services/documents.mjs +21 -2
  156. package/dist/admin/services/documents.mjs.map +1 -1
  157. package/dist/admin/services/relations.js +47 -1
  158. package/dist/admin/services/relations.js.map +1 -1
  159. package/dist/admin/services/relations.mjs +47 -2
  160. package/dist/admin/services/relations.mjs.map +1 -1
  161. package/dist/admin/src/exports.d.ts +2 -0
  162. package/dist/admin/src/features/I18nSharedFieldsLock.d.ts +22 -0
  163. package/dist/admin/src/history/components/VersionInputRenderer.d.ts +7 -1
  164. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  165. package/dist/admin/src/hooks/useI18nFieldLock.d.ts +61 -0
  166. package/dist/admin/src/modules/app.d.ts +4 -1
  167. package/dist/admin/src/pages/EditView/components/FormInputs/Component/AddComponentMenu.d.ts +15 -0
  168. package/dist/admin/src/pages/EditView/components/FormInputs/Component/ComponentCopyModal.d.ts +58 -0
  169. package/dist/admin/src/pages/EditView/components/FormInputs/Component/CopiedComponents.d.ts +41 -0
  170. package/dist/admin/src/pages/EditView/components/FormInputs/Component/Initializer.d.ts +7 -3
  171. package/dist/admin/src/pages/EditView/components/FormInputs/Component/NonRepeatable.d.ts +1 -1
  172. package/dist/admin/src/pages/EditView/components/FormInputs/Component/Repeatable.d.ts +2 -2
  173. package/dist/admin/src/pages/EditView/components/FormInputs/Component/utils/componentCopy.d.ts +115 -0
  174. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.d.ts +6 -3
  175. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/ComponentPicker.d.ts +2 -1
  176. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.d.ts +5 -1
  177. package/dist/admin/src/pages/EditView/utils/forms.d.ts +13 -2
  178. package/dist/admin/src/pages/ListView/components/Filters.d.ts +12 -3
  179. package/dist/admin/src/preview/services/preview.d.ts +1 -1
  180. package/dist/admin/src/preview/utils/fieldUtils.d.ts +1 -0
  181. package/dist/admin/src/services/api.d.ts +1 -1
  182. package/dist/admin/src/services/components.d.ts +2 -2
  183. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  184. package/dist/admin/src/services/documents.d.ts +25 -21
  185. package/dist/admin/src/services/homepage.d.ts +1 -1
  186. package/dist/admin/src/services/init.d.ts +1 -1
  187. package/dist/admin/src/services/relations.d.ts +5 -3
  188. package/dist/admin/src/services/uid.d.ts +3 -3
  189. package/dist/admin/translations/en.json.js +41 -0
  190. package/dist/admin/translations/en.json.js.map +1 -1
  191. package/dist/admin/translations/en.json.mjs +41 -0
  192. package/dist/admin/translations/en.json.mjs.map +1 -1
  193. package/dist/server/controllers/relations.js +4 -2
  194. package/dist/server/controllers/relations.js.map +1 -1
  195. package/dist/server/controllers/relations.mjs +4 -2
  196. package/dist/server/controllers/relations.mjs.map +1 -1
  197. package/dist/server/controllers/utils/metadata.js +3 -1
  198. package/dist/server/controllers/utils/metadata.js.map +1 -1
  199. package/dist/server/controllers/utils/metadata.mjs +3 -1
  200. package/dist/server/controllers/utils/metadata.mjs.map +1 -1
  201. package/dist/server/history/services/utils.js +3 -1
  202. package/dist/server/history/services/utils.js.map +1 -1
  203. package/dist/server/history/services/utils.mjs +3 -1
  204. package/dist/server/history/services/utils.mjs.map +1 -1
  205. package/dist/server/homepage/services/homepage-query-utils.js +14 -0
  206. package/dist/server/homepage/services/homepage-query-utils.js.map +1 -1
  207. package/dist/server/homepage/services/homepage-query-utils.mjs +14 -1
  208. package/dist/server/homepage/services/homepage-query-utils.mjs.map +1 -1
  209. package/dist/server/homepage/services/homepage.js +1 -1
  210. package/dist/server/homepage/services/homepage.js.map +1 -1
  211. package/dist/server/homepage/services/homepage.mjs +2 -2
  212. package/dist/server/homepage/services/homepage.mjs.map +1 -1
  213. package/dist/server/mcp/sanitizers/shape-relations.js +1 -3
  214. package/dist/server/mcp/sanitizers/shape-relations.js.map +1 -1
  215. package/dist/server/mcp/sanitizers/shape-relations.mjs +1 -3
  216. package/dist/server/mcp/sanitizers/shape-relations.mjs.map +1 -1
  217. package/dist/server/mcp/schemas/output-schemas.js +2 -1
  218. package/dist/server/mcp/schemas/output-schemas.js.map +1 -1
  219. package/dist/server/mcp/schemas/output-schemas.mjs +2 -1
  220. package/dist/server/mcp/schemas/output-schemas.mjs.map +1 -1
  221. package/dist/server/services/document-manager.js +3 -2
  222. package/dist/server/services/document-manager.js.map +1 -1
  223. package/dist/server/services/document-manager.mjs +3 -2
  224. package/dist/server/services/document-manager.mjs.map +1 -1
  225. package/dist/server/services/document-metadata.js +92 -4
  226. package/dist/server/services/document-metadata.js.map +1 -1
  227. package/dist/server/services/document-metadata.mjs +92 -4
  228. package/dist/server/services/document-metadata.mjs.map +1 -1
  229. package/dist/server/services/permission-checker.js +20 -8
  230. package/dist/server/services/permission-checker.js.map +1 -1
  231. package/dist/server/services/permission-checker.mjs +20 -8
  232. package/dist/server/services/permission-checker.mjs.map +1 -1
  233. package/dist/server/services/uid.js +2 -1
  234. package/dist/server/services/uid.js.map +1 -1
  235. package/dist/server/services/uid.mjs +2 -1
  236. package/dist/server/services/uid.mjs.map +1 -1
  237. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  238. package/dist/server/src/controllers/utils/metadata.d.ts +1 -0
  239. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  240. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  241. package/dist/server/src/homepage/services/homepage-query-utils.d.ts +6 -0
  242. package/dist/server/src/homepage/services/homepage-query-utils.d.ts.map +1 -1
  243. package/dist/server/src/homepage/services/homepage.d.ts.map +1 -1
  244. package/dist/server/src/index.d.ts +21 -7
  245. package/dist/server/src/index.d.ts.map +1 -1
  246. package/dist/server/src/mcp/sanitizers/shape-relations.d.ts.map +1 -1
  247. package/dist/server/src/mcp/schemas/output-schemas.d.ts.map +1 -1
  248. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  249. package/dist/server/src/services/document-metadata.d.ts +5 -1
  250. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  251. package/dist/server/src/services/index.d.ts +21 -7
  252. package/dist/server/src/services/index.d.ts.map +1 -1
  253. package/dist/server/src/services/permission-checker.d.ts +6 -5
  254. package/dist/server/src/services/permission-checker.d.ts.map +1 -1
  255. package/dist/server/src/services/uid.d.ts.map +1 -1
  256. package/dist/shared/contracts/collection-types.d.ts +7 -0
  257. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  258. package/dist/shared/contracts/single-types.d.ts +4 -0
  259. package/dist/shared/contracts/single-types.d.ts.map +1 -1
  260. package/package.json +9 -9
@@ -1,6 +1,11 @@
1
1
  import { generateNKeysBetween } from 'fractional-indexing';
2
2
  import { contentManagerApi } from './api.mjs';
3
3
 
4
+ /**
5
+ * The relations API loads the main field of the relations with a second query that isn't
6
+ * paginated, so it's capped at the default page size of the database layer: 10 rows. Past that
7
+ * number in a page, relations come back without their label.
8
+ */ const ALL_RELATIONS_PAGE_SIZE = 10;
4
9
  const relationsApi = contentManagerApi.injectEndpoints({
5
10
  endpoints: (build)=>({
6
11
  getRelations: build.query({
@@ -65,6 +70,46 @@ const relationsApi = contentManagerApi.injectEndpoints({
65
70
  'Relations'
66
71
  ]
67
72
  }),
73
+ /**
74
+ * Loads every existing relation of a field, in the order they're displayed.
75
+ * `getRelations` is paginated for the relations input, this one is meant for
76
+ * copying the relations of an entry.
77
+ */ getAllRelations: build.query({
78
+ queryFn: async ({ model, id, targetField, params }, _api, _extraOpts, baseQuery)=>{
79
+ const relations = [];
80
+ let page = 1;
81
+ let pageCount = 1;
82
+ while(page <= pageCount){
83
+ const res = await baseQuery({
84
+ url: `/content-manager/relations/${model}/${id}/${targetField}`,
85
+ method: 'GET',
86
+ config: {
87
+ params: {
88
+ ...params,
89
+ page,
90
+ pageSize: ALL_RELATIONS_PAGE_SIZE
91
+ }
92
+ }
93
+ });
94
+ if (res.error) {
95
+ return {
96
+ error: res.error
97
+ };
98
+ }
99
+ const { results = [], pagination } = res.data;
100
+ relations.push(...results);
101
+ pageCount = pagination?.pageCount ?? 1;
102
+ page += 1;
103
+ }
104
+ // The API returns the latest relations first.
105
+ return {
106
+ data: relations.toReversed()
107
+ };
108
+ },
109
+ providesTags: [
110
+ 'Relations'
111
+ ]
112
+ }),
68
113
  searchRelations: build.query({
69
114
  query: ({ model, targetField, params })=>{
70
115
  return {
@@ -138,7 +183,7 @@ const relationsApi = contentManagerApi.injectEndpoints({
138
183
  __temp_key__: keys[index]
139
184
  }));
140
185
  };
141
- const { useGetRelationsQuery, useLazySearchRelationsQuery } = relationsApi;
186
+ const { useGetRelationsQuery, useLazyGetAllRelationsQuery, useLazySearchRelationsQuery } = relationsApi;
142
187
 
143
- export { useGetRelationsQuery, useLazySearchRelationsQuery };
188
+ export { useGetRelationsQuery, useLazyGetAllRelationsQuery, useLazySearchRelationsQuery };
144
189
  //# sourceMappingURL=relations.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"relations.mjs","sources":["../../../admin/src/services/relations.ts"],"sourcesContent":["import { generateNKeysBetween } from 'fractional-indexing';\n\nimport {\n RelationResult as RelResult,\n FindAvailable,\n FindExisting,\n} from '../../../shared/contracts/relations';\n\nimport { contentManagerApi } from './api';\n\nimport type { Modules } from '@strapi/types';\nimport type { errors } from '@strapi/utils';\n\ninterface RelationResult extends RelResult {\n __temp_key__: string;\n}\n\ntype GetRelationsResponse =\n | {\n results: Array<RelationResult>;\n pagination: {\n page: NonNullable<Modules.EntityService.Params.Pagination.PageNotation['page']>;\n pageSize: NonNullable<Modules.EntityService.Params.Pagination.PageNotation['pageSize']>;\n pageCount: number;\n total: number;\n } | null;\n error?: never;\n }\n | {\n results?: never;\n pagination?: never;\n error: errors.ApplicationError | errors.YupValidationError;\n };\n\nconst relationsApi = contentManagerApi.injectEndpoints({\n endpoints: (build) => ({\n getRelations: build.query<\n GetRelationsResponse,\n FindExisting.Params & {\n params?: FindExisting.Request['query'];\n }\n >({\n query: ({ model, id, targetField, params }) => {\n return {\n url: `/content-manager/relations/${model}/${id}/${targetField}`,\n method: 'GET',\n config: {\n params,\n },\n };\n },\n serializeQueryArgs: (args) => {\n const { endpointName, queryArgs } = args;\n return {\n endpointName,\n model: queryArgs.model,\n id: queryArgs.id,\n targetField: queryArgs.targetField,\n locale: queryArgs.params?.locale,\n status: queryArgs.params?.status,\n };\n },\n merge: (currentCache, newItems) => {\n if (currentCache.pagination && newItems.pagination) {\n if (currentCache.pagination.page < newItems.pagination.page) {\n /**\n * Relations will always have unique IDs, so we can therefore assume\n * that we only need to push the new items to the cache.\n *\n * Push new items at the beginning as latest items are shown first\n */\n currentCache.results = [\n ...prepareTempKeys(newItems.results, currentCache.results),\n ...currentCache.results,\n ];\n currentCache.pagination = newItems.pagination;\n } else if (newItems.pagination.page === 1) {\n /**\n * We're resetting the relations\n */\n currentCache.results = prepareTempKeys(newItems.results);\n currentCache.pagination = newItems.pagination;\n }\n }\n },\n forceRefetch({ currentArg, previousArg }) {\n if (!currentArg?.params && !previousArg?.params) {\n return false;\n }\n\n return (\n currentArg?.params?.page !== previousArg?.params?.page ||\n currentArg?.params?.pageSize !== previousArg?.params?.pageSize\n );\n },\n transformResponse: (response: FindExisting.Response) => {\n if ('results' in response && response.results) {\n return {\n ...response,\n results: prepareTempKeys(response.results.toReversed()),\n };\n } else {\n return response;\n }\n },\n providesTags: ['Relations'],\n }),\n searchRelations: build.query<\n FindAvailable.Response,\n FindAvailable.Params & {\n params?: FindAvailable.Request['query'];\n }\n >({\n query: ({ model, targetField, params }) => {\n return {\n url: `/content-manager/relations/${model}/${targetField}`,\n method: 'GET',\n config: {\n params,\n },\n };\n },\n serializeQueryArgs: (args) => {\n const { endpointName, queryArgs } = args;\n return {\n endpointName,\n model: queryArgs.model,\n targetField: queryArgs.targetField,\n id: queryArgs.params?.id,\n locale: queryArgs.params?.locale,\n status: queryArgs.params?.status,\n _q: queryArgs.params?._q,\n idsToOmit: queryArgs.params?.idsToOmit,\n idsToInclude: queryArgs.params?.idsToInclude,\n };\n },\n merge: (currentCache, newItems) => {\n if (currentCache.pagination && newItems.pagination) {\n if (currentCache.pagination.page < newItems.pagination.page) {\n /**\n * Relations will always have unique IDs, so we can therefore assume\n * that we only need to push the new items to the cache.\n */\n const existingIds = new Set(currentCache.results.map((item) => item.documentId));\n const uniqueNewItems = newItems.results.filter(\n (item) => !existingIds.has(item.documentId)\n );\n currentCache.results.push(...uniqueNewItems);\n currentCache.pagination = newItems.pagination;\n } else if (newItems.pagination.page === 1) {\n /**\n * We're resetting the relations\n */\n currentCache.results = newItems.results;\n currentCache.pagination = newItems.pagination;\n }\n }\n },\n forceRefetch({ currentArg, previousArg }) {\n if (!currentArg?.params && !previousArg?.params) {\n return false;\n }\n\n return (\n currentArg?.params?.page !== previousArg?.params?.page ||\n currentArg?.params?.pageSize !== previousArg?.params?.pageSize\n );\n },\n transformResponse: (response: FindAvailable.Response) => {\n if (response.results) {\n return {\n ...response,\n results: response.results,\n };\n } else {\n return response;\n }\n },\n }),\n }),\n});\n\n/**\n * @internal\n * @description Adds a `__temp_key__` to each relation item. This gives us\n * a stable identifier regardless of it's ids etc. that we can then use for drag and drop.\n */\nconst prepareTempKeys = (relations: RelResult[], existingRelations: RelationResult[] = []) => {\n const [firstItem] = existingRelations.slice(0);\n const keys = generateNKeysBetween(null, firstItem?.__temp_key__ ?? null, relations.length);\n\n return relations.map((datum, index) => ({\n ...datum,\n __temp_key__: keys[index],\n }));\n};\n\nconst { useGetRelationsQuery, useLazySearchRelationsQuery } = relationsApi;\n\nexport { useGetRelationsQuery, useLazySearchRelationsQuery };\nexport type { RelationResult };\n"],"names":["relationsApi","contentManagerApi","injectEndpoints","endpoints","build","getRelations","query","model","id","targetField","params","url","method","config","serializeQueryArgs","args","endpointName","queryArgs","locale","status","merge","currentCache","newItems","pagination","page","results","prepareTempKeys","forceRefetch","currentArg","previousArg","pageSize","transformResponse","response","toReversed","providesTags","searchRelations","_q","idsToOmit","idsToInclude","existingIds","Set","map","item","documentId","uniqueNewItems","filter","has","push","relations","existingRelations","firstItem","slice","keys","generateNKeysBetween","__temp_key__","length","datum","index","useGetRelationsQuery","useLazySearchRelationsQuery"],"mappings":"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"}
1
+ {"version":3,"file":"relations.mjs","sources":["../../../admin/src/services/relations.ts"],"sourcesContent":["import { generateNKeysBetween } from 'fractional-indexing';\n\nimport {\n RelationResult as RelResult,\n FindAvailable,\n FindExisting,\n} from '../../../shared/contracts/relations';\n\nimport { contentManagerApi } from './api';\n\nimport type { Modules } from '@strapi/types';\nimport type { errors } from '@strapi/utils';\n\ninterface RelationResult extends RelResult {\n __temp_key__: string;\n}\n\ntype GetRelationsResponse =\n | {\n results: Array<RelationResult>;\n pagination: {\n page: NonNullable<Modules.EntityService.Params.Pagination.PageNotation['page']>;\n pageSize: NonNullable<Modules.EntityService.Params.Pagination.PageNotation['pageSize']>;\n pageCount: number;\n total: number;\n } | null;\n error?: never;\n }\n | {\n results?: never;\n pagination?: never;\n error: errors.ApplicationError | errors.YupValidationError;\n };\n\n/**\n * The relations API loads the main field of the relations with a second query that isn't\n * paginated, so it's capped at the default page size of the database layer: 10 rows. Past that\n * number in a page, relations come back without their label.\n */\nconst ALL_RELATIONS_PAGE_SIZE = 10;\n\nconst relationsApi = contentManagerApi.injectEndpoints({\n endpoints: (build) => ({\n getRelations: build.query<\n GetRelationsResponse,\n FindExisting.Params & {\n params?: FindExisting.Request['query'];\n }\n >({\n query: ({ model, id, targetField, params }) => {\n return {\n url: `/content-manager/relations/${model}/${id}/${targetField}`,\n method: 'GET',\n config: {\n params,\n },\n };\n },\n serializeQueryArgs: (args) => {\n const { endpointName, queryArgs } = args;\n return {\n endpointName,\n model: queryArgs.model,\n id: queryArgs.id,\n targetField: queryArgs.targetField,\n locale: queryArgs.params?.locale,\n status: queryArgs.params?.status,\n };\n },\n merge: (currentCache, newItems) => {\n if (currentCache.pagination && newItems.pagination) {\n if (currentCache.pagination.page < newItems.pagination.page) {\n /**\n * Relations will always have unique IDs, so we can therefore assume\n * that we only need to push the new items to the cache.\n *\n * Push new items at the beginning as latest items are shown first\n */\n currentCache.results = [\n ...prepareTempKeys(newItems.results, currentCache.results),\n ...currentCache.results,\n ];\n currentCache.pagination = newItems.pagination;\n } else if (newItems.pagination.page === 1) {\n /**\n * We're resetting the relations\n */\n currentCache.results = prepareTempKeys(newItems.results);\n currentCache.pagination = newItems.pagination;\n }\n }\n },\n forceRefetch({ currentArg, previousArg }) {\n if (!currentArg?.params && !previousArg?.params) {\n return false;\n }\n\n return (\n currentArg?.params?.page !== previousArg?.params?.page ||\n currentArg?.params?.pageSize !== previousArg?.params?.pageSize\n );\n },\n transformResponse: (response: FindExisting.Response) => {\n if ('results' in response && response.results) {\n return {\n ...response,\n results: prepareTempKeys(response.results.toReversed()),\n };\n } else {\n return response;\n }\n },\n providesTags: ['Relations'],\n }),\n /**\n * Loads every existing relation of a field, in the order they're displayed.\n * `getRelations` is paginated for the relations input, this one is meant for\n * copying the relations of an entry.\n */\n getAllRelations: build.query<\n RelResult[],\n FindExisting.Params & {\n params?: Omit<FindExisting.Request['query'], 'page' | 'pageSize'>;\n }\n >({\n queryFn: async ({ model, id, targetField, params }, _api, _extraOpts, baseQuery) => {\n const relations: RelResult[] = [];\n let page = 1;\n let pageCount = 1;\n\n while (page <= pageCount) {\n const res = await baseQuery({\n url: `/content-manager/relations/${model}/${id}/${targetField}`,\n method: 'GET',\n config: {\n params: { ...params, page, pageSize: ALL_RELATIONS_PAGE_SIZE },\n },\n });\n\n if (res.error) {\n return { error: res.error };\n }\n\n const { results = [], pagination } = res.data as FindExisting.Response;\n\n relations.push(...results);\n pageCount = pagination?.pageCount ?? 1;\n page += 1;\n }\n\n // The API returns the latest relations first.\n return { data: relations.toReversed() };\n },\n providesTags: ['Relations'],\n }),\n searchRelations: build.query<\n FindAvailable.Response,\n FindAvailable.Params & {\n params?: FindAvailable.Request['query'];\n }\n >({\n query: ({ model, targetField, params }) => {\n return {\n url: `/content-manager/relations/${model}/${targetField}`,\n method: 'GET',\n config: {\n params,\n },\n };\n },\n serializeQueryArgs: (args) => {\n const { endpointName, queryArgs } = args;\n return {\n endpointName,\n model: queryArgs.model,\n targetField: queryArgs.targetField,\n id: queryArgs.params?.id,\n locale: queryArgs.params?.locale,\n status: queryArgs.params?.status,\n _q: queryArgs.params?._q,\n idsToOmit: queryArgs.params?.idsToOmit,\n idsToInclude: queryArgs.params?.idsToInclude,\n };\n },\n merge: (currentCache, newItems) => {\n if (currentCache.pagination && newItems.pagination) {\n if (currentCache.pagination.page < newItems.pagination.page) {\n /**\n * Relations will always have unique IDs, so we can therefore assume\n * that we only need to push the new items to the cache.\n */\n const existingIds = new Set(currentCache.results.map((item) => item.documentId));\n const uniqueNewItems = newItems.results.filter(\n (item) => !existingIds.has(item.documentId)\n );\n currentCache.results.push(...uniqueNewItems);\n currentCache.pagination = newItems.pagination;\n } else if (newItems.pagination.page === 1) {\n /**\n * We're resetting the relations\n */\n currentCache.results = newItems.results;\n currentCache.pagination = newItems.pagination;\n }\n }\n },\n forceRefetch({ currentArg, previousArg }) {\n if (!currentArg?.params && !previousArg?.params) {\n return false;\n }\n\n return (\n currentArg?.params?.page !== previousArg?.params?.page ||\n currentArg?.params?.pageSize !== previousArg?.params?.pageSize\n );\n },\n transformResponse: (response: FindAvailable.Response) => {\n if (response.results) {\n return {\n ...response,\n results: response.results,\n };\n } else {\n return response;\n }\n },\n }),\n }),\n});\n\n/**\n * @internal\n * @description Adds a `__temp_key__` to each relation item. This gives us\n * a stable identifier regardless of it's ids etc. that we can then use for drag and drop.\n */\nconst prepareTempKeys = (relations: RelResult[], existingRelations: RelationResult[] = []) => {\n const [firstItem] = existingRelations.slice(0);\n const keys = generateNKeysBetween(null, firstItem?.__temp_key__ ?? null, relations.length);\n\n return relations.map((datum, index) => ({\n ...datum,\n __temp_key__: keys[index],\n }));\n};\n\nconst { useGetRelationsQuery, useLazyGetAllRelationsQuery, useLazySearchRelationsQuery } =\n relationsApi;\n\nexport { useGetRelationsQuery, useLazyGetAllRelationsQuery, useLazySearchRelationsQuery };\nexport type { RelationResult };\n"],"names":["ALL_RELATIONS_PAGE_SIZE","relationsApi","contentManagerApi","injectEndpoints","endpoints","build","getRelations","query","model","id","targetField","params","url","method","config","serializeQueryArgs","args","endpointName","queryArgs","locale","status","merge","currentCache","newItems","pagination","page","results","prepareTempKeys","forceRefetch","currentArg","previousArg","pageSize","transformResponse","response","toReversed","providesTags","getAllRelations","queryFn","_api","_extraOpts","baseQuery","relations","pageCount","res","error","data","push","searchRelations","_q","idsToOmit","idsToInclude","existingIds","Set","map","item","documentId","uniqueNewItems","filter","has","existingRelations","firstItem","slice","keys","generateNKeysBetween","__temp_key__","length","datum","index","useGetRelationsQuery","useLazyGetAllRelationsQuery","useLazySearchRelationsQuery"],"mappings":"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"}
@@ -7,10 +7,12 @@ export { buildValidParams } from './utils/api';
7
7
  export { RelativeTime } from './components/RelativeTime';
8
8
  export { DocumentStatus } from './pages/EditView/components/DocumentStatus';
9
9
  export { useDocument as unstable_useDocument, useContentManagerContext as unstable_useContentManagerContext, } from './hooks/useDocument';
10
+ export { isSharedI18nAttribute as unstable_isSharedI18nAttribute, useHasDefaultLocaleEntry as unstable_useHasDefaultLocaleEntry, } from './hooks/useI18nFieldLock';
10
11
  export { useDocumentActions as unstable_useDocumentActions } from './hooks/useDocumentActions';
11
12
  export { useDocumentLayout as unstable_useDocumentLayout } from './hooks/useDocumentLayout';
12
13
  export type { EditFieldLayout, EditLayout, ListCellMeta, ListFieldLayout, ListLayout, } from './hooks/useDocumentLayout';
13
14
  export type { InjectableListViewFilter } from './constants/hooks';
14
15
  export * from './features/DocumentRBAC';
16
+ export { useI18nSharedFieldsLock as unstable_useI18nSharedFieldsLock } from './features/I18nSharedFieldsLock';
15
17
  export type { EditViewContext, ListViewContext, BulkActionComponent, BulkActionComponentProps, BulkActionDescription, ContentManagerPlugin, DescriptionComponent, DescriptionReducer, PanelComponentProps, PanelComponent, PanelDescription, DocumentActionComponent, DocumentActionDescription, DocumentActionProps, HeaderActionComponent, HeaderActionDescription, HeaderActionProps, } from './content-manager';
16
18
  export type { RichTextBlocksStore, SelectorBlock, NonSelectorBlock, } from './pages/EditView/components/FormInputs/BlocksInput/BlocksEditor';
@@ -0,0 +1,22 @@
1
+ import * as React from 'react';
2
+ interface I18nSharedFieldsLockContextValue {
3
+ isUnlocked: boolean;
4
+ unlock: () => void;
5
+ relock: () => void;
6
+ }
7
+ /**
8
+ * @alpha
9
+ * @public
10
+ * Reads or changes whether the editor unlocked shared fields on a secondary locale.
11
+ */
12
+ declare const useI18nSharedFieldsLock: <Selected, ShouldThrow extends boolean = true>(consumerName: string, selector: (value: I18nSharedFieldsLockContextValue) => Selected, shouldThrowOnMissingContext?: ShouldThrow | undefined) => ShouldThrow extends true ? Selected : Selected | undefined;
13
+ /**
14
+ * Holds whether the editor accepted the warning to edit non-localized fields
15
+ * on a secondary locale. Always starts locked: key the provider by document
16
+ * and locale so a locale switch or a different entry relocks.
17
+ */
18
+ declare const I18nSharedFieldsLock: ({ children }: {
19
+ children: React.ReactNode;
20
+ }) => import("react/jsx-runtime").JSX.Element;
21
+ export { I18nSharedFieldsLock, useI18nSharedFieldsLock };
22
+ export type { I18nSharedFieldsLockContextValue };
@@ -1,3 +1,4 @@
1
+ import * as React from 'react';
1
2
  import type { EditFieldLayout } from '../../hooks/useDocumentLayout';
2
3
  import type { RelationsFieldProps } from '../../pages/EditView/components/FormInputs/Relations/Relations';
3
4
  import type { DistributiveOmit } from 'react-redux';
@@ -11,6 +12,11 @@ type VersionInputRendererProps = DistributiveOmit<EditFieldLayout, 'size'> & {
11
12
  /** Passed down by component and dynamic zone layouts; not used here. */
12
13
  size?: number;
13
14
  };
15
+ /**
16
+ * Checks if the i18n plugin added a label action to the field and modifies it
17
+ * to adapt the wording for the history page.
18
+ */
19
+ declare const getLabelAction: (labelAction: VersionInputRendererProps["labelAction"]) => string | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined;
14
20
  /**
15
21
  * Resolve the layout, configuration metadata and schema attributes needed to
16
22
  * render a component field on the history page. Returns `null` when any of
@@ -44,4 +50,4 @@ declare const resolveComponentRenderResources: (componentUID: string, components
44
50
  */
45
51
  declare const VersionInputRenderer: ({ visible, hint: providedHint, shouldIgnoreRBAC, labelAction, size: _size, ...props }: VersionInputRendererProps) => import("react/jsx-runtime").JSX.Element | null;
46
52
  export type { VersionInputRendererProps };
47
- export { VersionInputRenderer, CustomRelationInput, resolveComponentRenderResources };
53
+ export { VersionInputRenderer, CustomRelationInput, getLabelAction, resolveComponentRenderResources, };
@@ -8,5 +8,5 @@ declare const useGetHistoryVersionsQuery: import("@reduxjs/toolkit/dist/query/re
8
8
  contentType: import("@strapi/types/dist/uid/index.js").ContentType;
9
9
  documentId?: Data.ID;
10
10
  locale?: string;
11
- } & Partial<Pick<import("../../../../shared/contracts/history-versions").Pagination, "page" | "pageSize">>, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("@strapi/admin/strapi-admin").QueryArguments, unknown, import("@strapi/admin/strapi-admin").BaseQueryError | import("@reduxjs/toolkit").SerializedError, {}, {}>, "GuidedTourMeta" | "HomepageKeyStatistics" | "AiUsage" | "AiFeatureConfig" | "ComponentConfiguration" | "ContentTypesConfiguration" | "ContentTypeSettings" | "Document" | "InitialData" | "HistoryVersion" | "Relations" | "UidAvailability" | "RecentDocumentList" | "CountDocuments" | "UpcomingReleasesList" | "AILocalizationJobs", GetHistoryVersions.Response, "adminApi">>, useRestoreVersionMutation: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseMutation<import("@reduxjs/toolkit/query").MutationDefinition<RestoreVersion, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("@strapi/admin/strapi-admin").QueryArguments, unknown, import("@strapi/admin/strapi-admin").BaseQueryError | import("@reduxjs/toolkit").SerializedError, {}, {}>, "GuidedTourMeta" | "HomepageKeyStatistics" | "AiUsage" | "AiFeatureConfig" | "ComponentConfiguration" | "ContentTypesConfiguration" | "ContentTypeSettings" | "Document" | "InitialData" | "HistoryVersion" | "Relations" | "UidAvailability" | "RecentDocumentList" | "CountDocuments" | "UpcomingReleasesList" | "AILocalizationJobs", RestoreHistoryVersion.Response, "adminApi">>;
11
+ } & Partial<Pick<import("../../../../shared/contracts/history-versions").Pagination, "page" | "pageSize">>, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("@strapi/admin/strapi-admin").QueryArguments, unknown, import("@strapi/admin/strapi-admin").BaseQueryError | import("@reduxjs/toolkit").SerializedError, {}, {}>, "GuidedTourMeta" | "HomepageKeyStatistics" | "AiUsage" | "AiFeatureConfig" | "ComponentConfiguration" | "ContentTypesConfiguration" | "ContentTypeSettings" | "Document" | "InitialData" | "HistoryVersion" | "Relations" | "UidAvailability" | "RecentDocumentList" | "CountDocuments" | "UpcomingReleasesList" | "AILocalizationJobs" | "Locale", GetHistoryVersions.Response, "adminApi">>, useRestoreVersionMutation: import("@reduxjs/toolkit/dist/query/react/buildHooks").UseMutation<import("@reduxjs/toolkit/query").MutationDefinition<RestoreVersion, import("@reduxjs/toolkit/query").BaseQueryFn<string | import("@strapi/admin/strapi-admin").QueryArguments, unknown, import("@strapi/admin/strapi-admin").BaseQueryError | import("@reduxjs/toolkit").SerializedError, {}, {}>, "GuidedTourMeta" | "HomepageKeyStatistics" | "AiUsage" | "AiFeatureConfig" | "ComponentConfiguration" | "ContentTypesConfiguration" | "ContentTypeSettings" | "Document" | "InitialData" | "HistoryVersion" | "Relations" | "UidAvailability" | "RecentDocumentList" | "CountDocuments" | "UpcomingReleasesList" | "AILocalizationJobs" | "Locale", RestoreHistoryVersion.Response, "adminApi">>;
12
12
  export { useGetHistoryVersionsQuery, useRestoreVersionMutation };
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @internal
3
+ * Whether the Content Manager edit view is on the i18n default locale.
4
+ *
5
+ * Returns `true` when i18n is not enabled on the content type, when the active
6
+ * or default locale cannot be determined yet, or when they match.
7
+ *
8
+ * Prefers `meta.defaultLocale` from the document metadata response — NOT
9
+ * `availableLocales[0]`. That list excludes the currently viewed locale, so
10
+ * when editing the default locale `[0]` is a sibling and would incorrectly
11
+ * report "not default" and lock shared fields.
12
+ *
13
+ * On create (`/create?locale=`), document metadata is not fetched, so
14
+ * `meta.defaultLocale` is missing. Fall back to the i18n locales list to tell
15
+ * whether the active locale is the default. Locking still requires a
16
+ * default-locale document entry (`useHasDefaultLocaleEntry`).
17
+ */
18
+ declare const useIsEditingDefaultLocale: () => boolean;
19
+ /**
20
+ * @alpha
21
+ * @public
22
+ * Whether the document being edited has a default-locale entry.
23
+ *
24
+ * `availableLocales` excludes the locale currently open, so a match is a sibling
25
+ * in the default locale. Brand-new creates have no document metadata. A document
26
+ * that exists only in a secondary locale has none either. Shared fields stay
27
+ * editable in both cases: there is no default-locale entry to edit them in.
28
+ */
29
+ declare const useHasDefaultLocaleEntry: () => boolean;
30
+ /**
31
+ * @alpha
32
+ * @public
33
+ * Whether an attribute holds a value shared by every locale of the entry.
34
+ */
35
+ declare const isSharedI18nAttribute: (attribute: {
36
+ pluginOptions?: object;
37
+ type?: string;
38
+ } | undefined) => boolean;
39
+ /**
40
+ * @internal
41
+ * True when a field should be locked because it is not locale-specific and the
42
+ * editor is on a non-default locale that already has a default-locale entry.
43
+ * Root-level only — nested component fields inherit disable from their parent
44
+ * component input.
45
+ */
46
+ declare const useShouldLockNonLocalizedField: (attribute: {
47
+ pluginOptions?: object;
48
+ type?: string;
49
+ } | undefined, options?: {
50
+ isInsideComponent?: boolean;
51
+ }) => boolean;
52
+ /**
53
+ * @internal
54
+ * Returns a function that removes locked shared fields from the payload that
55
+ * creates a missing locale, so the server copies them whole from the default
56
+ * locale. The form only holds a prefilled copy of them, and relations nested
57
+ * in components or dynamic zones are not carried in that copy. Once the editor
58
+ * unlocks shared fields, the ones they changed are kept.
59
+ */
60
+ declare const useOmitLockedSharedFieldsOnLocaleCreate: () => <TData extends Record<string, unknown>>(data: TData) => TData;
61
+ export { isSharedI18nAttribute, useHasDefaultLocaleEntry, useIsEditingDefaultLocale, useOmitLockedSharedFieldsOnLocaleCreate, useShouldLockNonLocalizedField, };
@@ -1,6 +1,7 @@
1
1
  import { GetInitData } from '../../../shared/contracts/init';
2
2
  import type { ContentManagerLink } from '../hooks/useContentManagerInitData';
3
3
  interface AppState {
4
+ adminUserId?: string | number;
4
5
  collectionTypeLinks: ContentManagerLink[];
5
6
  components: GetInitData.Response['data']['components'];
6
7
  contentStructure?: GetInitData.Response['data']['contentStructure'];
@@ -9,8 +10,10 @@ interface AppState {
9
10
  singleTypeLinks: ContentManagerLink[];
10
11
  isLoading: boolean;
11
12
  }
13
+ declare const initialState: AppState;
12
14
  declare const reducer: import("redux").Reducer<AppState>;
13
15
  declare const setInitialData: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
16
+ adminUserId?: AppState["adminUserId"];
14
17
  authorizedCollectionTypeLinks: AppState["collectionTypeLinks"];
15
18
  authorizedSingleTypeLinks: AppState["singleTypeLinks"];
16
19
  components: AppState["components"];
@@ -18,5 +21,5 @@ declare const setInitialData: import("@reduxjs/toolkit").ActionCreatorWithPayloa
18
21
  contentTypeSchemas: AppState["models"];
19
22
  fieldSizes: AppState["fieldSizes"];
20
23
  }, "app/setInitialData">;
21
- export { reducer, setInitialData };
24
+ export { initialState, reducer, setInitialData };
22
25
  export type { AppState };
@@ -0,0 +1,15 @@
1
+ interface AddComponentMenuContentProps {
2
+ /**
3
+ * What the menu adds: an entry of a component field, or a component of a dynamic zone.
4
+ */
5
+ kind: 'entry' | 'component';
6
+ onAddEmpty: () => void;
7
+ onCopy: () => void;
8
+ }
9
+ /**
10
+ * The choices offered when adding a component to a field that can also copy one from another
11
+ * entry: start from blank fields, or pick existing content.
12
+ */
13
+ declare const AddComponentMenuContent: ({ kind, onAddEmpty, onCopy }: AddComponentMenuContentProps) => import("react/jsx-runtime").JSX.Element;
14
+ export { AddComponentMenuContent };
15
+ export type { AddComponentMenuContentProps };
@@ -0,0 +1,58 @@
1
+ import { type IntlFormatters } from 'react-intl';
2
+ import { type AnyData } from '../../../utils/data';
3
+ import { type ComponentCopyMode } from './utils/componentCopy';
4
+ type ComponentCopySelection = 'single' | 'multiple';
5
+ interface ComponentCopyModalProps {
6
+ componentUid: string;
7
+ /**
8
+ * The label of the field the copies land in, as it's displayed in the form.
9
+ */
10
+ fieldLabel: string;
11
+ /**
12
+ * How many components the field can still take. The selection can't exceed it.
13
+ */
14
+ maxSelection?: number;
15
+ mode: ComponentCopyMode;
16
+ onClose: () => void;
17
+ /**
18
+ * Inserts the copies in the field. Returns `false` when the field turns them down, e.g. because
19
+ * it already holds its maximum number of components. The field then reports it to the user itself.
20
+ */
21
+ onInsert: (components: AnyData[]) => boolean;
22
+ /**
23
+ * Whether the field already holds content the copy is going to replace. Only applies to a
24
+ * `single` selection.
25
+ */
26
+ replacesContent?: boolean;
27
+ /**
28
+ * A field holding one component takes a single copy, a repeatable component or a dynamic zone
29
+ * take several at once.
30
+ */
31
+ selection: ComponentCopySelection;
32
+ sourceFieldName: string;
33
+ }
34
+ interface GetEntryMetaArgs {
35
+ /**
36
+ * How many components of the wanted kind the entry holds, `undefined` when it isn't known yet.
37
+ */
38
+ count: number | undefined;
39
+ fieldLabel: string;
40
+ /**
41
+ * The label of the only component of the entry, when it holds a single one.
42
+ */
43
+ firstInstanceLabel?: string;
44
+ formatMessage: IntlFormatters['formatMessage'];
45
+ isCurrent: boolean;
46
+ isFormModified: boolean;
47
+ selection: ComponentCopySelection;
48
+ }
49
+ /**
50
+ * The line of text shown under the title of an entry in the list.
51
+ */
52
+ declare const getEntryMeta: ({ count, fieldLabel, firstInstanceLabel, formatMessage, isCurrent, isFormModified, selection, }: GetEntryMetaArgs) => string | undefined;
53
+ /**
54
+ * The modal is mounted while it's open and unmounted when it's closed.
55
+ */
56
+ declare const ComponentCopyModal: ({ componentUid, fieldLabel, maxSelection, mode, onClose, onInsert, replacesContent, selection, sourceFieldName, }: ComponentCopyModalProps) => import("react/jsx-runtime").JSX.Element;
57
+ export { ComponentCopyModal, getEntryMeta };
58
+ export type { ComponentCopyModalProps, ComponentCopySelection };
@@ -0,0 +1,41 @@
1
+ import * as React from 'react';
2
+ import type { AnyData } from '../../../utils/data';
3
+ /**
4
+ * @description Turns the name of a field into its key path: `blocks.1.dishes` becomes
5
+ * `blocks.[a1].dishes`, `a1` being the temp key of the second block.
6
+ */
7
+ declare const getFieldKeyPath: (values: unknown, name: string) => string;
8
+ /**
9
+ * @description Tells whether the form still holds the component at the given key path.
10
+ */
11
+ declare const hasComponentAt: (values: unknown, keyPath: string) => boolean;
12
+ interface CopiedComponentsProviderProps {
13
+ children: React.ReactNode;
14
+ }
15
+ /**
16
+ * Remembers which components of the form were copied from another entry, so that they can be
17
+ * flagged until the entry is saved. The state lives above the fields: a field nested in a block
18
+ * is unmounted when the block collapses and would lose it otherwise. Must be rendered in a `Form`.
19
+ */
20
+ declare const CopiedComponentsProvider: ({ children }: CopiedComponentsProviderProps) => import("react/jsx-runtime").JSX.Element;
21
+ /**
22
+ * @description Inserts copied components in a repeatable component or a dynamic zone field and
23
+ * tells which of its rows are copies. Without a `CopiedComponentsProvider` the copies are still
24
+ * inserted, they're just not flagged.
25
+ */
26
+ declare const useCopiedComponents: (name: string) => {
27
+ isCopied: (tempKey: string) => boolean;
28
+ insertCopies: (items: AnyData[]) => void;
29
+ };
30
+ /**
31
+ * @description Puts a copied component in a non-repeatable component field and tells whether the
32
+ * field holds a copy. The flag is set on the field itself: resetting the field drops it, so a
33
+ * component added afterwards isn't flagged. Without a `CopiedComponentsProvider` the copy is still
34
+ * put in place, it's just not flagged.
35
+ */
36
+ declare const useCopiedComponent: (name: string) => {
37
+ isCopied: boolean;
38
+ insertCopy: (item: AnyData) => void;
39
+ };
40
+ export { CopiedComponentsProvider, useCopiedComponents, useCopiedComponent, getFieldKeyPath, hasComponentAt, };
41
+ export type { CopiedComponentsProviderProps };
@@ -1,9 +1,13 @@
1
- import * as React from 'react';
2
1
  interface InitializerProps {
3
2
  disabled?: boolean;
4
3
  name: string;
5
- onClick?: React.MouseEventHandler<HTMLButtonElement> & React.MouseEventHandler<HTMLDivElement>;
4
+ onClick?: () => void;
5
+ /**
6
+ * When set, clicking the placeholder offers to start with an empty component or to copy
7
+ * existing content, instead of adding an empty component right away.
8
+ */
9
+ onCopyClick?: () => void;
6
10
  }
7
- declare const Initializer: ({ disabled, name, onClick }: InitializerProps) => import("react/jsx-runtime").JSX.Element;
11
+ declare const Initializer: ({ disabled, name, onClick, onCopyClick }: InitializerProps) => import("react/jsx-runtime").JSX.Element;
8
12
  export { Initializer };
9
13
  export type { InitializerProps };
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import type { ComponentInputProps } from './Input';
3
3
  type NonRepeatableComponentProps = Omit<ComponentInputProps, 'required' | 'label'>;
4
- declare const MemoizedNonRepeatableComponent: React.MemoExoticComponent<({ attribute, name, children, layout, }: NonRepeatableComponentProps) => import("react/jsx-runtime").JSX.Element>;
4
+ declare const MemoizedNonRepeatableComponent: React.MemoExoticComponent<({ attribute, name, children, layout, disabled, }: NonRepeatableComponentProps) => import("react/jsx-runtime").JSX.Element>;
5
5
  export { MemoizedNonRepeatableComponent as NonRepeatableComponent };
6
6
  export type { NonRepeatableComponentProps };
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import type { ComponentInputProps } from './Input';
3
- type RepeatableComponentProps = Omit<ComponentInputProps, 'required' | 'label'>;
4
- declare const MemoizedRepeatableComponent: React.MemoExoticComponent<({ attribute, disabled, name, mainField, children, layout, }: RepeatableComponentProps) => import("react/jsx-runtime").JSX.Element>;
3
+ type RepeatableComponentProps = Omit<ComponentInputProps, 'required'>;
4
+ declare const MemoizedRepeatableComponent: React.MemoExoticComponent<({ attribute, disabled, label, name, mainField, children, layout, }: RepeatableComponentProps) => import("react/jsx-runtime").JSX.Element>;
5
5
  export { MemoizedRepeatableComponent as RepeatableComponent };
6
6
  export type { RepeatableComponentProps };
@@ -0,0 +1,115 @@
1
+ import { type AnyData } from '../../../../utils/data';
2
+ import type { RelationResult } from '../../../../../../../../shared/contracts/relations';
3
+ import type { ComponentsDictionary, Document, Schema } from '../../../../../../hooks/useDocument';
4
+ import type { Schema as StrapiSchema } from '@strapi/types';
5
+ type ComponentCopyMode = 'component' | 'dynamiczone';
6
+ interface ComponentInstance {
7
+ /**
8
+ * The component as it's stored on the source entry. It still has its ids,
9
+ * they're needed to load its relations.
10
+ */
11
+ source: AnyData;
12
+ label: string;
13
+ /**
14
+ * Label of the block holding the field, when the field is nested
15
+ * in a repeatable component or in a dynamic zone.
16
+ */
17
+ parentLabel?: string;
18
+ /**
19
+ * Where the component sits in the source entry, e.g. `dynamiczone.2.dish.0`.
20
+ */
21
+ sourcePath: string;
22
+ }
23
+ interface RelationToCopy {
24
+ /**
25
+ * The uid & id of the component holding the relation on the source entry.
26
+ */
27
+ model: string;
28
+ id: RelationResult['id'];
29
+ targetField: string;
30
+ /**
31
+ * Path of the relation field from the root of the copied component.
32
+ */
33
+ path: string[];
34
+ }
35
+ /**
36
+ * @description Creates a standalone copy of a component: ids and temp keys are removed
37
+ * (the component and the ones nested in it will be created as new ones), `uid` and `unique`
38
+ * values are blanked and the data is prepared for the form, where relations start empty,
39
+ * see `connectRelations`.
40
+ */
41
+ declare const cloneComponentData: (value: unknown, componentUid: string, components: ComponentsDictionary) => AnyData;
42
+ interface GetComponentInstancesArgs {
43
+ componentUid: string;
44
+ components: ComponentsDictionary;
45
+ getMainField: (componentUid: string) => string | undefined;
46
+ mode: ComponentCopyMode;
47
+ /**
48
+ * The schema of the content-type the entries belong to.
49
+ */
50
+ schema?: Schema;
51
+ sourceDocument: Document;
52
+ /**
53
+ * The path of the field in the entry being edited, e.g. `dynamiczone.1.dish`
54
+ */
55
+ sourceFieldName: string;
56
+ /**
57
+ * The values of the entry being edited.
58
+ */
59
+ targetValues: unknown;
60
+ }
61
+ /**
62
+ * @description Finds the components of the source entry that can be copied into a field.
63
+ *
64
+ * When the field is nested in a block of a repeatable component or of a dynamic zone, every block
65
+ * of the same kind is searched and not only the one at the same position: blocks are freely
66
+ * reordered from one entry to another, their position tells nothing about what they hold.
67
+ */
68
+ declare const getComponentInstances: ({ componentUid, components, getMainField, mode, schema, sourceDocument, sourceFieldName, targetValues, }: GetComponentInstancesArgs) => ComponentInstance[];
69
+ interface ComponentPreviewField {
70
+ name: string;
71
+ label: string;
72
+ type: StrapiSchema.Attribute.Kind;
73
+ value: unknown;
74
+ }
75
+ /**
76
+ * @description Lists the filled scalar fields of a component, in the order of the given fields
77
+ * (typically the edit layout of the component) or of the schema. The fields whose value isn't
78
+ * copied (`uid`, `unique`) are left out.
79
+ */
80
+ declare const getComponentPreview: (source: unknown, componentUid: string, components: ComponentsDictionary, fields?: Array<{
81
+ name: string;
82
+ label: string;
83
+ }>) => ComponentPreviewField[];
84
+ /**
85
+ * @description Finds the stored version of the component at `name` in the document as the server
86
+ * sent it, following the ids of the rows on the way rather than their indexes (rows are
87
+ * reordered in the form). Returns `undefined` when the component, or a row holding it, isn't
88
+ * stored yet.
89
+ */
90
+ declare const getSavedComponent: (document: unknown, values: unknown, name: string) => AnyData | undefined;
91
+ /**
92
+ * @description Tells whether a component holds any content, i.e. whether copying into it would
93
+ * replace something. A value still equal to the default of its attribute isn't content: a
94
+ * component that was just added is filled with its defaults. Nested components are looked into,
95
+ * a boolean set to `false` is content when its attribute defaults to `true`.
96
+ *
97
+ * The form doesn't hold the saved relations of a component, only the ones being connected or
98
+ * disconnected: pass the stored version of the component (`saved`, see `getSavedComponent`)
99
+ * so that they're counted.
100
+ */
101
+ declare const isComponentBlank: (value: unknown, componentUid: string, components: ComponentsDictionary, saved?: AnyData) => boolean;
102
+ /**
103
+ * @description Lists the relations of a component of the source entry, including the ones of the
104
+ * components nested in it. An entry only holds the count of its relations, they have to be
105
+ * loaded to be copied. Relation fields the user isn't allowed to read aren't part of the entry
106
+ * and are left out.
107
+ */
108
+ declare const getRelationsToCopy: (source: unknown, componentUid: string, components: ComponentsDictionary, path?: string[]) => RelationToCopy[];
109
+ /**
110
+ * @description Connects relations loaded from the source entry to the relation field at `path`
111
+ * of a copied component, in the shape the relations input works with.
112
+ */
113
+ declare const connectRelations: (data: AnyData, path: string[], relations: RelationResult[]) => AnyData;
114
+ export { cloneComponentData, connectRelations, getComponentInstances, getComponentPreview, getRelationsToCopy, getSavedComponent, isComponentBlank, };
115
+ export type { ComponentCopyMode, ComponentInstance, ComponentPreviewField, RelationToCopy };
@@ -1,4 +1,3 @@
1
- import * as React from 'react';
2
1
  import { Accordion } from '@strapi/design-system';
3
2
  import type { Struct } from '@strapi/types';
4
3
  interface ComponentCategoryProps {
@@ -9,9 +8,13 @@ interface ComponentCategoryProps {
9
8
  icon?: string;
10
9
  preview?: Struct.PreviewImageValue;
11
10
  }>;
12
- onAddComponent: (componentUid: string) => React.MouseEventHandler<HTMLButtonElement> & React.MouseEventHandler<HTMLDivElement>;
11
+ onAddComponent: (componentUid: string) => () => void;
12
+ /**
13
+ * When set, picking a component offers to add it empty or to copy it from another entry.
14
+ */
15
+ onCopyComponent?: (componentUid: string) => () => void;
13
16
  variant?: Accordion.Variant;
14
17
  }
15
- declare const ComponentCategory: ({ category, components, variant, onAddComponent, }: ComponentCategoryProps) => import("react/jsx-runtime").JSX.Element;
18
+ declare const ComponentCategory: ({ category, components, variant, onAddComponent, onCopyComponent, }: ComponentCategoryProps) => import("react/jsx-runtime").JSX.Element;
16
19
  export { ComponentCategory };
17
20
  export type { ComponentCategoryProps };
@@ -3,7 +3,8 @@ interface ComponentPickerProps {
3
3
  dynamicComponentsByCategory?: Record<string, NonNullable<ComponentCategoryProps['components']>>;
4
4
  isOpen?: boolean;
5
5
  onClickAddComponent: (componentUid: string) => void;
6
+ onClickCopyComponent?: (componentUid: string) => void;
6
7
  }
7
- declare const ComponentPicker: ({ dynamicComponentsByCategory, isOpen, onClickAddComponent, }: ComponentPickerProps) => import("react/jsx-runtime").JSX.Element | null;
8
+ declare const ComponentPicker: ({ dynamicComponentsByCategory, isOpen, onClickAddComponent, onClickCopyComponent, }: ComponentPickerProps) => import("react/jsx-runtime").JSX.Element | null;
8
9
  export { ComponentPicker };
9
10
  export type { ComponentPickerProps };
@@ -22,7 +22,11 @@ interface DynamicComponentProps extends Pick<UseDragAndDropOptions, 'onGrabItem'
22
22
  * so the parent can clear the forced state.
23
23
  */
24
24
  onForceOpenHandled?: () => void;
25
+ /**
26
+ * Whether the component was copied from another entry and not saved yet.
27
+ */
28
+ isCopied?: boolean;
25
29
  }
26
- declare const MemoizedDynamicComponent: React.MemoExoticComponent<({ componentUid, disabled, index, name, onRemoveComponentClick, onMoveComponent, onGrabItem, onDropItem, onCancel, dynamicComponentsByCategory, onAddComponent, totalLength, children, forceOpen, onForceOpenHandled, }: DynamicComponentProps) => import("react/jsx-runtime").JSX.Element>;
30
+ declare const MemoizedDynamicComponent: React.MemoExoticComponent<({ componentUid, disabled, index, name, onRemoveComponentClick, onMoveComponent, onGrabItem, onDropItem, onCancel, dynamicComponentsByCategory, onAddComponent, totalLength, children, forceOpen, onForceOpenHandled, isCopied, }: DynamicComponentProps) => import("react/jsx-runtime").JSX.Element>;
27
31
  export { MemoizedDynamicComponent as DynamicComponent };
28
32
  export type { DynamicComponentProps };