@strapi/content-manager 0.0.0-experimental.a65a85fdea97faae8679d3ffc5f9d79af61abd26 → 0.0.0-experimental.c3e9d4b26f9fd3d9eb530b5c11f9baa1d09b13ad

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 (176) hide show
  1. package/dist/_chunks/{CardDragPreview-DSVYodBX.js → CardDragPreview-C0QyJgRA.js} +10 -14
  2. package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -0
  3. package/dist/_chunks/{CardDragPreview-ikSG4M46.mjs → CardDragPreview-DOxamsuj.mjs} +7 -9
  4. package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -0
  5. package/dist/_chunks/{ComponentConfigurationPage--2aLCv-G.mjs → ComponentConfigurationPage-BMajAl1u.mjs} +3 -3
  6. package/dist/_chunks/{ComponentConfigurationPage--2aLCv-G.mjs.map → ComponentConfigurationPage-BMajAl1u.mjs.map} +1 -1
  7. package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js → ComponentConfigurationPage-y_7iLdmB.js} +3 -3
  8. package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js.map → ComponentConfigurationPage-y_7iLdmB.js.map} +1 -1
  9. package/dist/_chunks/{ComponentIcon-BBQsYCVn.js → ComponentIcon-BXdiCGQp.js} +8 -2
  10. package/dist/_chunks/ComponentIcon-BXdiCGQp.js.map +1 -0
  11. package/dist/_chunks/{ComponentIcon-BOFnK76n.mjs → ComponentIcon-u4bIXTFY.mjs} +9 -3
  12. package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -0
  13. package/dist/_chunks/{EditConfigurationPage-BfFzJ4Br.js → EditConfigurationPage-CPVB8Uqc.js} +3 -3
  14. package/dist/_chunks/{EditConfigurationPage-BfFzJ4Br.js.map → EditConfigurationPage-CPVB8Uqc.js.map} +1 -1
  15. package/dist/_chunks/{EditConfigurationPage-CUcGHHvQ.mjs → EditConfigurationPage-CcOoD26O.mjs} +3 -3
  16. package/dist/_chunks/{EditConfigurationPage-CUcGHHvQ.mjs.map → EditConfigurationPage-CcOoD26O.mjs.map} +1 -1
  17. package/dist/_chunks/{EditViewPage-CzOT5Kpj.js → EditViewPage-CTTDHKkQ.js} +7 -9
  18. package/dist/_chunks/EditViewPage-CTTDHKkQ.js.map +1 -0
  19. package/dist/_chunks/{EditViewPage-Bm8lgcm6.mjs → EditViewPage-DWb0DE7R.mjs} +6 -6
  20. package/dist/_chunks/EditViewPage-DWb0DE7R.mjs.map +1 -0
  21. package/dist/_chunks/{Field-Caef4JjM.js → Field-C5Z1Ivdv.js} +552 -661
  22. package/dist/_chunks/Field-C5Z1Ivdv.js.map +1 -0
  23. package/dist/_chunks/{Field-Dlh0uGnL.mjs → Field-DnStdvQw.mjs} +500 -608
  24. package/dist/_chunks/Field-DnStdvQw.mjs.map +1 -0
  25. package/dist/_chunks/{Form-BzuAjtRq.js → Form-B81OtW-k.js} +21 -19
  26. package/dist/_chunks/Form-B81OtW-k.js.map +1 -0
  27. package/dist/_chunks/{Form-EnaQL_6L.mjs → Form-DqGgE55Q.mjs} +21 -18
  28. package/dist/_chunks/Form-DqGgE55Q.mjs.map +1 -0
  29. package/dist/_chunks/{History-C17LiyRg.js → History-4NbOq2dX.js} +119 -49
  30. package/dist/_chunks/History-4NbOq2dX.js.map +1 -0
  31. package/dist/_chunks/{History-D6sbCJvo.mjs → History-DS6-HCYX.mjs} +119 -48
  32. package/dist/_chunks/History-DS6-HCYX.mjs.map +1 -0
  33. package/dist/_chunks/{ListConfigurationPage-Dks5SX6f.js → ListConfigurationPage-CpfstlYY.js} +17 -19
  34. package/dist/_chunks/ListConfigurationPage-CpfstlYY.js.map +1 -0
  35. package/dist/_chunks/{ListConfigurationPage-Ce4qs7qE.mjs → ListConfigurationPage-DQJJltko.mjs} +14 -14
  36. package/dist/_chunks/ListConfigurationPage-DQJJltko.mjs.map +1 -0
  37. package/dist/_chunks/{ListViewPage-BwrZrPsh.js → ListViewPage-CA3I75m5.js} +43 -51
  38. package/dist/_chunks/ListViewPage-CA3I75m5.js.map +1 -0
  39. package/dist/_chunks/{ListViewPage-Be7S5aKL.mjs → ListViewPage-nQrOQuVo.mjs} +37 -45
  40. package/dist/_chunks/ListViewPage-nQrOQuVo.mjs.map +1 -0
  41. package/dist/_chunks/{NoContentTypePage-CIPmYQMm.mjs → NoContentTypePage-DbnHE22g.mjs} +7 -7
  42. package/dist/_chunks/NoContentTypePage-DbnHE22g.mjs.map +1 -0
  43. package/dist/_chunks/{NoContentTypePage-Cu5r1-JT.js → NoContentTypePage-Dldu-_Mx.js} +5 -5
  44. package/dist/_chunks/NoContentTypePage-Dldu-_Mx.js.map +1 -0
  45. package/dist/_chunks/{NoPermissionsPage-C-j6TEUF.js → NoPermissionsPage-CO2MK200.js} +4 -5
  46. package/dist/_chunks/NoPermissionsPage-CO2MK200.js.map +1 -0
  47. package/dist/_chunks/{NoPermissionsPage-DhJ7LYrr.mjs → NoPermissionsPage-fOIkQM0v.mjs} +5 -6
  48. package/dist/_chunks/NoPermissionsPage-fOIkQM0v.mjs.map +1 -0
  49. package/dist/_chunks/{Relations-CY7AtkDA.mjs → Relations-BDRl99Ux.mjs} +66 -56
  50. package/dist/_chunks/Relations-BDRl99Ux.mjs.map +1 -0
  51. package/dist/_chunks/{Relations-Czs-uZ-s.js → Relations-DG2jnOcr.js} +70 -61
  52. package/dist/_chunks/Relations-DG2jnOcr.js.map +1 -0
  53. package/dist/_chunks/{en-MBPul9Su.mjs → en-Ux26r5pl.mjs} +7 -1
  54. package/dist/_chunks/{en-MBPul9Su.mjs.map → en-Ux26r5pl.mjs.map} +1 -1
  55. package/dist/_chunks/{en-C-V1_90f.js → en-fbKQxLGn.js} +7 -1
  56. package/dist/_chunks/{en-C-V1_90f.js.map → en-fbKQxLGn.js.map} +1 -1
  57. package/dist/_chunks/{index-X_2tafck.js → index-BZoNZMXL.js} +1556 -795
  58. package/dist/_chunks/index-BZoNZMXL.js.map +1 -0
  59. package/dist/_chunks/{index-DNVx8ssZ.mjs → index-Drt2DN7v.mjs} +1569 -807
  60. package/dist/_chunks/index-Drt2DN7v.mjs.map +1 -0
  61. package/dist/_chunks/{layout-Dnh0PNp9.mjs → layout-BzAbmoO6.mjs} +27 -22
  62. package/dist/_chunks/layout-BzAbmoO6.mjs.map +1 -0
  63. package/dist/_chunks/{layout-dBc7wN7L.js → layout-DEYBqgF1.js} +28 -25
  64. package/dist/_chunks/layout-DEYBqgF1.js.map +1 -0
  65. package/dist/_chunks/{relations-4pHtBrHJ.js → relations-D0eZ4VWw.js} +2 -2
  66. package/dist/_chunks/{relations-4pHtBrHJ.js.map → relations-D0eZ4VWw.js.map} +1 -1
  67. package/dist/_chunks/{relations-Dx7tMKJN.mjs → relations-D26zVRdi.mjs} +2 -2
  68. package/dist/_chunks/{relations-Dx7tMKJN.mjs.map → relations-D26zVRdi.mjs.map} +1 -1
  69. package/dist/_chunks/useDragAndDrop-DdHgKsqq.mjs.map +1 -1
  70. package/dist/_chunks/useDragAndDrop-J0TUUbR6.js.map +1 -1
  71. package/dist/_chunks/usePrev-B9w_-eYc.js +15 -0
  72. package/dist/_chunks/usePrev-B9w_-eYc.js.map +1 -0
  73. package/dist/_chunks/usePrev-DH6iah0A.mjs +16 -0
  74. package/dist/_chunks/usePrev-DH6iah0A.mjs.map +1 -0
  75. package/dist/admin/index.js +2 -1
  76. package/dist/admin/index.js.map +1 -1
  77. package/dist/admin/index.mjs +8 -7
  78. package/dist/admin/src/components/ComponentIcon.d.ts +6 -3
  79. package/dist/admin/src/content-manager.d.ts +3 -3
  80. package/dist/admin/src/exports.d.ts +1 -0
  81. package/dist/admin/src/history/components/VersionInputRenderer.d.ts +1 -1
  82. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  83. package/dist/admin/src/hooks/useDocument.d.ts +5 -8
  84. package/dist/admin/src/hooks/useDocumentActions.d.ts +24 -3
  85. package/dist/admin/src/hooks/useDocumentLayout.d.ts +2 -2
  86. package/dist/admin/src/hooks/useDragAndDrop.d.ts +4 -4
  87. package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +1 -1
  88. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +3 -1
  89. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +3 -3
  90. package/dist/admin/src/pages/EditView/components/FormInputs/Component/Input.d.ts +2 -2
  91. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.d.ts +3 -5
  92. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +1 -1
  93. package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +10 -18
  94. package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +2 -2
  95. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +3 -49
  96. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.d.ts +2 -2
  97. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +67 -52
  98. package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -10
  99. package/dist/admin/src/pages/ListView/components/BulkActions/PublishAction.d.ts +9 -26
  100. package/dist/admin/src/services/api.d.ts +2 -3
  101. package/dist/admin/src/services/components.d.ts +2 -2
  102. package/dist/admin/src/services/contentTypes.d.ts +5 -5
  103. package/dist/admin/src/services/documents.d.ts +29 -17
  104. package/dist/admin/src/services/init.d.ts +2 -2
  105. package/dist/admin/src/services/relations.d.ts +3 -3
  106. package/dist/admin/src/services/uid.d.ts +3 -3
  107. package/dist/admin/src/utils/api.d.ts +4 -18
  108. package/dist/admin/src/utils/validation.d.ts +1 -6
  109. package/dist/server/index.js +540 -414
  110. package/dist/server/index.js.map +1 -1
  111. package/dist/server/index.mjs +548 -422
  112. package/dist/server/index.mjs.map +1 -1
  113. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  114. package/dist/server/src/controllers/single-types.d.ts.map +1 -1
  115. package/dist/server/src/controllers/utils/metadata.d.ts +8 -0
  116. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -0
  117. package/dist/server/src/controllers/validation/dimensions.d.ts +9 -0
  118. package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -0
  119. package/dist/server/src/controllers/validation/index.d.ts +1 -1
  120. package/dist/server/src/history/services/history.d.ts +2 -4
  121. package/dist/server/src/history/services/history.d.ts.map +1 -1
  122. package/dist/server/src/history/services/index.d.ts +6 -2
  123. package/dist/server/src/history/services/index.d.ts.map +1 -1
  124. package/dist/server/src/history/services/lifecycles.d.ts +9 -0
  125. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -0
  126. package/dist/server/src/history/services/utils.d.ts +41 -9
  127. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  128. package/dist/server/src/history/utils.d.ts +6 -2
  129. package/dist/server/src/history/utils.d.ts.map +1 -1
  130. package/dist/server/src/index.d.ts +18 -39
  131. package/dist/server/src/index.d.ts.map +1 -1
  132. package/dist/server/src/services/document-manager.d.ts +13 -12
  133. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  134. package/dist/server/src/services/document-metadata.d.ts +8 -29
  135. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  136. package/dist/server/src/services/index.d.ts +18 -39
  137. package/dist/server/src/services/index.d.ts.map +1 -1
  138. package/dist/server/src/services/utils/populate.d.ts +8 -1
  139. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  140. package/dist/shared/contracts/collection-types.d.ts +14 -6
  141. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  142. package/dist/shared/contracts/relations.d.ts +2 -2
  143. package/dist/shared/contracts/relations.d.ts.map +1 -1
  144. package/package.json +13 -14
  145. package/dist/_chunks/CardDragPreview-DSVYodBX.js.map +0 -1
  146. package/dist/_chunks/CardDragPreview-ikSG4M46.mjs.map +0 -1
  147. package/dist/_chunks/ComponentIcon-BBQsYCVn.js.map +0 -1
  148. package/dist/_chunks/ComponentIcon-BOFnK76n.mjs.map +0 -1
  149. package/dist/_chunks/EditViewPage-Bm8lgcm6.mjs.map +0 -1
  150. package/dist/_chunks/EditViewPage-CzOT5Kpj.js.map +0 -1
  151. package/dist/_chunks/Field-Caef4JjM.js.map +0 -1
  152. package/dist/_chunks/Field-Dlh0uGnL.mjs.map +0 -1
  153. package/dist/_chunks/Form-BzuAjtRq.js.map +0 -1
  154. package/dist/_chunks/Form-EnaQL_6L.mjs.map +0 -1
  155. package/dist/_chunks/History-C17LiyRg.js.map +0 -1
  156. package/dist/_chunks/History-D6sbCJvo.mjs.map +0 -1
  157. package/dist/_chunks/ListConfigurationPage-Ce4qs7qE.mjs.map +0 -1
  158. package/dist/_chunks/ListConfigurationPage-Dks5SX6f.js.map +0 -1
  159. package/dist/_chunks/ListViewPage-Be7S5aKL.mjs.map +0 -1
  160. package/dist/_chunks/ListViewPage-BwrZrPsh.js.map +0 -1
  161. package/dist/_chunks/NoContentTypePage-CIPmYQMm.mjs.map +0 -1
  162. package/dist/_chunks/NoContentTypePage-Cu5r1-JT.js.map +0 -1
  163. package/dist/_chunks/NoPermissionsPage-C-j6TEUF.js.map +0 -1
  164. package/dist/_chunks/NoPermissionsPage-DhJ7LYrr.mjs.map +0 -1
  165. package/dist/_chunks/Relations-CY7AtkDA.mjs.map +0 -1
  166. package/dist/_chunks/Relations-Czs-uZ-s.js.map +0 -1
  167. package/dist/_chunks/index-DNVx8ssZ.mjs.map +0 -1
  168. package/dist/_chunks/index-X_2tafck.js.map +0 -1
  169. package/dist/_chunks/layout-Dnh0PNp9.mjs.map +0 -1
  170. package/dist/_chunks/layout-dBc7wN7L.js.map +0 -1
  171. package/dist/_chunks/urls-CbOsUOoW.mjs +0 -7
  172. package/dist/_chunks/urls-CbOsUOoW.mjs.map +0 -1
  173. package/dist/_chunks/urls-DzZya_gm.js +0 -6
  174. package/dist/_chunks/urls-DzZya_gm.js.map +0 -1
  175. package/dist/server/src/controllers/utils/dimensions.d.ts +0 -5
  176. package/dist/server/src/controllers/utils/dimensions.d.ts.map +0 -1
@@ -7,10 +7,8 @@ const reactIntl = require("react-intl");
7
7
  const reactRouterDom = require("react-router-dom");
8
8
  const React = require("react");
9
9
  const designSystem = require("@strapi/design-system");
10
- const styled = require("styled-components");
10
+ const styledComponents = require("styled-components");
11
11
  const yup = require("yup");
12
- const react = require("@reduxjs/toolkit/query/react");
13
- const axios = require("axios");
14
12
  const pipe = require("lodash/fp/pipe");
15
13
  const dateFns = require("date-fns");
16
14
  const toolkit = require("@reduxjs/toolkit");
@@ -34,7 +32,6 @@ function _interopNamespace(e) {
34
32
  return Object.freeze(n);
35
33
  }
36
34
  const React__namespace = /* @__PURE__ */ _interopNamespace(React);
37
- const styled__default = /* @__PURE__ */ _interopDefault(styled);
38
35
  const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
39
36
  const pipe__default = /* @__PURE__ */ _interopDefault(pipe);
40
37
  const __variableDynamicImportRuntimeHelper = (glob, path) => {
@@ -179,9 +176,8 @@ const DocumentRBAC = ({ children, permissions }) => {
179
176
  const name = removeNumericalStrings(fieldName.split("."));
180
177
  const componentFieldNames = fieldsUserCanAction.filter((field) => field.split(".").length > 1);
181
178
  if (fieldType === "component") {
182
- const componentOrDynamicZoneFields = componentFieldNames.map((field) => field.split("."));
183
- return componentOrDynamicZoneFields.some((field) => {
184
- return field.includes(fieldName);
179
+ return componentFieldNames.some((field) => {
180
+ return field.includes(name.join("."));
185
181
  });
186
182
  }
187
183
  if (name.length > 1) {
@@ -211,78 +207,8 @@ const extractAndDedupeFields = (permissions = []) => permissions.flatMap((permis
211
207
  (field, index2, arr) => arr.indexOf(field) === index2 && typeof field === "string"
212
208
  );
213
209
  const removeNumericalStrings = (arr) => arr.filter((item) => isNaN(Number(item)));
214
- const buildValidParams = (query) => {
215
- if (!query)
216
- return query;
217
- const { plugins: _, ...validQueryParams } = {
218
- ...query,
219
- ...Object.values(query?.plugins ?? {}).reduce(
220
- (acc, current) => Object.assign(acc, current),
221
- {}
222
- )
223
- };
224
- if ("_q" in validQueryParams) {
225
- validQueryParams._q = encodeURIComponent(validQueryParams._q);
226
- }
227
- return validQueryParams;
228
- };
229
- const axiosBaseQuery = () => async (query, { signal }) => {
230
- try {
231
- const { get, post, del, put } = strapiAdmin.getFetchClient();
232
- if (typeof query === "string") {
233
- const result = await get(query, { signal });
234
- return { data: result.data };
235
- } else {
236
- const { url, method = "GET", data, config } = query;
237
- if (method === "POST") {
238
- const result2 = await post(url, data, { ...config, signal });
239
- return { data: result2.data };
240
- }
241
- if (method === "DELETE") {
242
- const result2 = await del(url, { ...config, signal });
243
- return { data: result2.data };
244
- }
245
- if (method === "PUT") {
246
- const result2 = await put(url, data, { ...config, signal });
247
- return { data: result2.data };
248
- }
249
- const result = await get(url, { ...config, signal });
250
- return { data: result.data };
251
- }
252
- } catch (err) {
253
- if (axios.isAxiosError(err)) {
254
- if (typeof err.response?.data === "object" && err.response?.data !== null && "error" in err.response?.data) {
255
- return { data: void 0, error: err.response?.data.error };
256
- } else {
257
- return {
258
- data: void 0,
259
- error: {
260
- name: "UnknownError",
261
- message: "There was an unknown error response from the API",
262
- details: err.response?.data,
263
- status: err.response?.status
264
- }
265
- };
266
- }
267
- }
268
- const error = err;
269
- return {
270
- data: void 0,
271
- error: {
272
- name: error.name,
273
- message: error.message,
274
- stack: error.stack
275
- }
276
- };
277
- }
278
- };
279
- const isBaseQueryError = (error) => {
280
- return error.name !== void 0;
281
- };
282
- const contentManagerApi = react.createApi({
283
- reducerPath: "contentManagerApi",
284
- baseQuery: axiosBaseQuery(),
285
- tagTypes: [
210
+ const contentManagerApi = strapiAdmin.adminApi.enhanceEndpoints({
211
+ addTagTypes: [
286
212
  "ComponentConfiguration",
287
213
  "ContentTypesConfiguration",
288
214
  "ContentTypeSettings",
@@ -290,8 +216,7 @@ const contentManagerApi = react.createApi({
290
216
  "InitialData",
291
217
  "HistoryVersion",
292
218
  "Relations"
293
- ],
294
- endpoints: () => ({})
219
+ ]
295
220
  });
296
221
  const documentApi = contentManagerApi.injectEndpoints({
297
222
  endpoints: (builder) => ({
@@ -347,12 +272,15 @@ const documentApi = contentManagerApi.injectEndpoints({
347
272
  ]
348
273
  }),
349
274
  deleteManyDocuments: builder.mutation({
350
- query: ({ model, ...body }) => ({
275
+ query: ({ model, params, ...body }) => ({
351
276
  url: `/content-manager/collection-types/${model}/actions/bulkDelete`,
352
277
  method: "POST",
353
- data: body
278
+ data: body,
279
+ config: {
280
+ params
281
+ }
354
282
  }),
355
- invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
283
+ invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
356
284
  }),
357
285
  discardDocument: builder.mutation({
358
286
  query: ({ collectionType, model, documentId, params }) => ({
@@ -463,10 +391,13 @@ const documentApi = contentManagerApi.injectEndpoints({
463
391
  }
464
392
  }),
465
393
  publishManyDocuments: builder.mutation({
466
- query: ({ model, ...body }) => ({
394
+ query: ({ model, params, ...body }) => ({
467
395
  url: `/content-manager/collection-types/${model}/actions/bulkPublish`,
468
396
  method: "POST",
469
- data: body
397
+ data: body,
398
+ config: {
399
+ params
400
+ }
470
401
  }),
471
402
  invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
472
403
  }),
@@ -508,10 +439,13 @@ const documentApi = contentManagerApi.injectEndpoints({
508
439
  }
509
440
  }),
510
441
  unpublishManyDocuments: builder.mutation({
511
- query: ({ model, ...body }) => ({
442
+ query: ({ model, params, ...body }) => ({
512
443
  url: `/content-manager/collection-types/${model}/actions/bulkUnpublish`,
513
444
  method: "POST",
514
- data: body
445
+ data: body,
446
+ config: {
447
+ params
448
+ }
515
449
  }),
516
450
  invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
517
451
  })
@@ -535,6 +469,24 @@ const {
535
469
  useUnpublishDocumentMutation,
536
470
  useUnpublishManyDocumentsMutation
537
471
  } = documentApi;
472
+ const buildValidParams = (query) => {
473
+ if (!query)
474
+ return query;
475
+ const { plugins: _, ...validQueryParams } = {
476
+ ...query,
477
+ ...Object.values(query?.plugins ?? {}).reduce(
478
+ (acc, current) => Object.assign(acc, current),
479
+ {}
480
+ )
481
+ };
482
+ if ("_q" in validQueryParams) {
483
+ validQueryParams._q = encodeURIComponent(validQueryParams._q);
484
+ }
485
+ return validQueryParams;
486
+ };
487
+ const isBaseQueryError = (error) => {
488
+ return error.name !== void 0;
489
+ };
538
490
  const createYupSchema = (attributes = {}, components = {}) => {
539
491
  const createModelSchema = (attributes2) => yup__namespace.object().shape(
540
492
  Object.entries(attributes2).reduce((acc, [name, attribute]) => {
@@ -574,10 +526,14 @@ const createYupSchema = (attributes = {}, components = {}) => {
574
526
  yup__namespace.array().of(
575
527
  yup__namespace.lazy(
576
528
  (data) => {
577
- const { attributes: attributes3 } = components[data.__component];
578
- return yup__namespace.object().shape({
529
+ const attributes3 = components?.[data?.__component]?.attributes;
530
+ const validation = yup__namespace.object().shape({
579
531
  __component: yup__namespace.string().required().oneOf(Object.keys(components))
580
- }).nullable(false).concat(createModelSchema(attributes3));
532
+ }).nullable(false);
533
+ if (!attributes3) {
534
+ return validation;
535
+ }
536
+ return validation.concat(createModelSchema(attributes3));
581
537
  }
582
538
  )
583
539
  )
@@ -587,11 +543,25 @@ const createYupSchema = (attributes = {}, components = {}) => {
587
543
  return {
588
544
  ...acc,
589
545
  [name]: transformSchema(
590
- yup__namespace.array().of(
591
- yup__namespace.object().shape({
592
- id: yup__namespace.string().required()
593
- })
594
- )
546
+ yup__namespace.lazy((value) => {
547
+ if (!value) {
548
+ return yup__namespace.mixed().nullable(true);
549
+ } else if (Array.isArray(value)) {
550
+ return yup__namespace.array().of(
551
+ yup__namespace.object().shape({
552
+ id: yup__namespace.string().required()
553
+ })
554
+ );
555
+ } else if (typeof value === "object") {
556
+ return yup__namespace.object();
557
+ } else {
558
+ return yup__namespace.mixed().test(
559
+ "type-error",
560
+ "Relation values must be either null, an array of objects with {id} or an object.",
561
+ () => false
562
+ );
563
+ }
564
+ })
595
565
  )
596
566
  };
597
567
  default:
@@ -656,7 +626,12 @@ const addRequiredValidation = (attribute) => (schema) => {
656
626
  defaultMessage: "This field is required."
657
627
  });
658
628
  }
659
- return schema.nullable();
629
+ return schema?.nullable ? schema.nullable() : (
630
+ // In some cases '.nullable' will not be available on the schema.
631
+ // e.g. when the schema has been built using yup.lazy (e.g. for relations).
632
+ // In these cases we should just return the schema as it is.
633
+ schema
634
+ );
660
635
  };
661
636
  const addMinLengthValidation = (attribute) => (schema) => {
662
637
  if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
@@ -728,24 +703,6 @@ const addRegexValidation = (attribute) => (schema) => {
728
703
  }
729
704
  return schema;
730
705
  };
731
- const extractValuesFromYupError = (errorType, errorParams) => {
732
- if (!errorType || !errorParams) {
733
- return {};
734
- }
735
- return {
736
- [errorType]: errorParams[errorType]
737
- };
738
- };
739
- const getInnerErrors = (error) => (error?.inner || []).reduce((acc, currentError) => {
740
- if (currentError.path) {
741
- acc[currentError.path.split("[").join(".").split("]").join("")] = {
742
- id: currentError.message,
743
- defaultMessage: currentError.message,
744
- values: extractValuesFromYupError(currentError?.type, currentError?.params)
745
- };
746
- }
747
- return acc;
748
- }, {});
749
706
  const initApi = contentManagerApi.injectEndpoints({
750
707
  endpoints: (builder) => ({
751
708
  getInitialData: builder.query({
@@ -759,27 +716,20 @@ const { useGetInitialDataQuery } = initApi;
759
716
  const useContentTypeSchema = (model) => {
760
717
  const { toggleNotification } = strapiAdmin.useNotification();
761
718
  const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
762
- const { components, contentType, contentTypes, error, isLoading, isFetching } = useGetInitialDataQuery(void 0, {
763
- selectFromResult: (res) => {
764
- const contentType2 = res.data?.contentTypes.find((ct) => ct.uid === model);
765
- const componentsByKey = res.data?.components.reduce(
766
- (acc, component) => {
767
- acc[component.uid] = component;
768
- return acc;
769
- },
770
- {}
771
- );
772
- const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
773
- return {
774
- isLoading: res.isLoading,
775
- isFetching: res.isFetching,
776
- error: res.error,
777
- components: Object.keys(components2).length === 0 ? void 0 : components2,
778
- contentType: contentType2,
779
- contentTypes: res.data?.contentTypes ?? []
780
- };
781
- }
782
- });
719
+ const { data, error, isLoading, isFetching } = useGetInitialDataQuery(void 0);
720
+ const { components, contentType, contentTypes } = React__namespace.useMemo(() => {
721
+ const contentType2 = data?.contentTypes.find((ct) => ct.uid === model);
722
+ const componentsByKey = data?.components.reduce((acc, component) => {
723
+ acc[component.uid] = component;
724
+ return acc;
725
+ }, {});
726
+ const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
727
+ return {
728
+ components: Object.keys(components2).length === 0 ? void 0 : components2,
729
+ contentType: contentType2,
730
+ contentTypes: data?.contentTypes ?? []
731
+ };
732
+ }, [model, data]);
783
733
  React__namespace.useEffect(() => {
784
734
  if (error) {
785
735
  toggleNotification({
@@ -862,7 +812,7 @@ const useDocument = (args, opts) => {
862
812
  return null;
863
813
  } catch (error2) {
864
814
  if (error2 instanceof yup.ValidationError) {
865
- return getInnerErrors(error2);
815
+ return strapiAdmin.getYupValidationErrors(error2);
866
816
  }
867
817
  throw error2;
868
818
  }
@@ -958,14 +908,53 @@ const useDocumentActions = () => {
958
908
  },
959
909
  [trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
960
910
  );
911
+ const [deleteManyDocuments] = useDeleteManyDocumentsMutation();
912
+ const deleteMany = React__namespace.useCallback(
913
+ async ({ model, documentIds, params }) => {
914
+ try {
915
+ trackUsage("willBulkDeleteEntries");
916
+ const res = await deleteManyDocuments({
917
+ model,
918
+ documentIds,
919
+ params
920
+ });
921
+ if ("error" in res) {
922
+ toggleNotification({
923
+ type: "danger",
924
+ message: formatAPIError(res.error)
925
+ });
926
+ return { error: res.error };
927
+ }
928
+ toggleNotification({
929
+ type: "success",
930
+ title: formatMessage({
931
+ id: getTranslation("success.records.delete"),
932
+ defaultMessage: "Successfully deleted."
933
+ }),
934
+ message: ""
935
+ });
936
+ trackUsage("didBulkDeleteEntries");
937
+ return res.data;
938
+ } catch (err) {
939
+ toggleNotification({
940
+ type: "danger",
941
+ message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
942
+ });
943
+ trackUsage("didNotBulkDeleteEntries");
944
+ throw err;
945
+ }
946
+ },
947
+ [trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
948
+ );
961
949
  const [discardDocument] = useDiscardDocumentMutation();
962
950
  const discard = React__namespace.useCallback(
963
- async ({ collectionType, model, documentId }) => {
951
+ async ({ collectionType, model, documentId, params }) => {
964
952
  try {
965
953
  const res = await discardDocument({
966
954
  collectionType,
967
955
  model,
968
- documentId
956
+ documentId,
957
+ params
969
958
  });
970
959
  if ("error" in res) {
971
960
  toggleNotification({
@@ -1027,6 +1016,43 @@ const useDocumentActions = () => {
1027
1016
  },
1028
1017
  [trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
1029
1018
  );
1019
+ const [publishManyDocuments] = usePublishManyDocumentsMutation();
1020
+ const publishMany = React__namespace.useCallback(
1021
+ async ({ model, documentIds, params }) => {
1022
+ try {
1023
+ const res = await publishManyDocuments({
1024
+ model,
1025
+ documentIds,
1026
+ params
1027
+ });
1028
+ if ("error" in res) {
1029
+ toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1030
+ return { error: res.error };
1031
+ }
1032
+ toggleNotification({
1033
+ type: "success",
1034
+ message: formatMessage({
1035
+ id: getTranslation("success.record.publish"),
1036
+ defaultMessage: "Published document"
1037
+ })
1038
+ });
1039
+ return res.data;
1040
+ } catch (err) {
1041
+ toggleNotification({
1042
+ type: "danger",
1043
+ message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1044
+ });
1045
+ throw err;
1046
+ }
1047
+ },
1048
+ [
1049
+ // trackUsage,
1050
+ publishManyDocuments,
1051
+ toggleNotification,
1052
+ formatMessage,
1053
+ formatAPIError
1054
+ ]
1055
+ );
1030
1056
  const [updateDocument] = useUpdateDocumentMutation();
1031
1057
  const update = React__namespace.useCallback(
1032
1058
  async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
@@ -1101,6 +1127,41 @@ const useDocumentActions = () => {
1101
1127
  },
1102
1128
  [trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
1103
1129
  );
1130
+ const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
1131
+ const unpublishMany = React__namespace.useCallback(
1132
+ async ({ model, documentIds, params }) => {
1133
+ try {
1134
+ trackUsage("willBulkUnpublishEntries");
1135
+ const res = await unpublishManyDocuments({
1136
+ model,
1137
+ documentIds,
1138
+ params
1139
+ });
1140
+ if ("error" in res) {
1141
+ toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1142
+ return { error: res.error };
1143
+ }
1144
+ trackUsage("didBulkUnpublishEntries");
1145
+ toggleNotification({
1146
+ type: "success",
1147
+ title: formatMessage({
1148
+ id: getTranslation("success.records.unpublish"),
1149
+ defaultMessage: "Successfully unpublished."
1150
+ }),
1151
+ message: ""
1152
+ });
1153
+ return res.data;
1154
+ } catch (err) {
1155
+ toggleNotification({
1156
+ type: "danger",
1157
+ message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1158
+ });
1159
+ trackUsage("didNotBulkUnpublishEntries");
1160
+ throw err;
1161
+ }
1162
+ },
1163
+ [trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
1164
+ );
1104
1165
  const [createDocument] = useCreateDocumentMutation();
1105
1166
  const create = React__namespace.useCallback(
1106
1167
  async ({ model, params }, data, trackerProperty) => {
@@ -1214,15 +1275,18 @@ const useDocumentActions = () => {
1214
1275
  clone,
1215
1276
  create,
1216
1277
  delete: _delete,
1278
+ deleteMany,
1217
1279
  discard,
1218
1280
  getDocument,
1219
1281
  publish,
1282
+ publishMany,
1220
1283
  unpublish,
1284
+ unpublishMany,
1221
1285
  update
1222
1286
  };
1223
1287
  };
1224
1288
  const ProtectedHistoryPage = React.lazy(
1225
- () => Promise.resolve().then(() => require("./History-C17LiyRg.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
1289
+ () => Promise.resolve().then(() => require("./History-4NbOq2dX.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
1226
1290
  );
1227
1291
  const routes$1 = [
1228
1292
  {
@@ -1235,31 +1299,31 @@ const routes$1 = [
1235
1299
  }
1236
1300
  ];
1237
1301
  const ProtectedEditViewPage = React.lazy(
1238
- () => Promise.resolve().then(() => require("./EditViewPage-CzOT5Kpj.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
1302
+ () => Promise.resolve().then(() => require("./EditViewPage-CTTDHKkQ.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
1239
1303
  );
1240
1304
  const ProtectedListViewPage = React.lazy(
1241
- () => Promise.resolve().then(() => require("./ListViewPage-BwrZrPsh.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
1305
+ () => Promise.resolve().then(() => require("./ListViewPage-CA3I75m5.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
1242
1306
  );
1243
1307
  const ProtectedListConfiguration = React.lazy(
1244
- () => Promise.resolve().then(() => require("./ListConfigurationPage-Dks5SX6f.js")).then((mod) => ({
1308
+ () => Promise.resolve().then(() => require("./ListConfigurationPage-CpfstlYY.js")).then((mod) => ({
1245
1309
  default: mod.ProtectedListConfiguration
1246
1310
  }))
1247
1311
  );
1248
1312
  const ProtectedEditConfigurationPage = React.lazy(
1249
- () => Promise.resolve().then(() => require("./EditConfigurationPage-BfFzJ4Br.js")).then((mod) => ({
1313
+ () => Promise.resolve().then(() => require("./EditConfigurationPage-CPVB8Uqc.js")).then((mod) => ({
1250
1314
  default: mod.ProtectedEditConfigurationPage
1251
1315
  }))
1252
1316
  );
1253
1317
  const ProtectedComponentConfigurationPage = React.lazy(
1254
- () => Promise.resolve().then(() => require("./ComponentConfigurationPage-43KmCNQE.js")).then((mod) => ({
1318
+ () => Promise.resolve().then(() => require("./ComponentConfigurationPage-y_7iLdmB.js")).then((mod) => ({
1255
1319
  default: mod.ProtectedComponentConfigurationPage
1256
1320
  }))
1257
1321
  );
1258
1322
  const NoPermissions = React.lazy(
1259
- () => Promise.resolve().then(() => require("./NoPermissionsPage-C-j6TEUF.js")).then((mod) => ({ default: mod.NoPermissions }))
1323
+ () => Promise.resolve().then(() => require("./NoPermissionsPage-CO2MK200.js")).then((mod) => ({ default: mod.NoPermissions }))
1260
1324
  );
1261
1325
  const NoContentType = React.lazy(
1262
- () => Promise.resolve().then(() => require("./NoContentTypePage-Cu5r1-JT.js")).then((mod) => ({ default: mod.NoContentType }))
1326
+ () => Promise.resolve().then(() => require("./NoContentTypePage-Dldu-_Mx.js")).then((mod) => ({ default: mod.NoContentType }))
1263
1327
  );
1264
1328
  const CollectionTypePages = () => {
1265
1329
  const { collectionType } = reactRouterDom.useParams();
@@ -1449,7 +1513,7 @@ const DocumentActionsMenu = ({
1449
1513
  variant,
1450
1514
  children: [
1451
1515
  /* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
1452
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { as: "span", children: label || formatMessage({
1516
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: label || formatMessage({
1453
1517
  id: "content-manager.containers.edit.panels.default.more-actions",
1454
1518
  defaultMessage: "More document actions"
1455
1519
  }) })
@@ -1465,7 +1529,7 @@ const DocumentActionsMenu = ({
1465
1529
  onSelect: handleClick(action),
1466
1530
  display: "block",
1467
1531
  children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: [
1468
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { color: convertActionVariantToColor(action.variant), gap: 2, as: "span", children: [
1532
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { color: convertActionVariantToColor(action.variant), gap: 2, tag: "span", children: [
1469
1533
  action.icon,
1470
1534
  action.label
1471
1535
  ] }),
@@ -1571,7 +1635,7 @@ const DocumentActionModal = ({
1571
1635
  title,
1572
1636
  onClose,
1573
1637
  footer: Footer,
1574
- content,
1638
+ content: Content,
1575
1639
  onModalClose
1576
1640
  }) => {
1577
1641
  const id = React__namespace.useId();
@@ -1585,8 +1649,8 @@ const DocumentActionModal = ({
1585
1649
  onModalClose();
1586
1650
  };
1587
1651
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
1588
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral800", as: "h2", id, children: title }) }),
1589
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalBody, { children: content }),
1652
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
1653
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalBody, { children: typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : Content }),
1590
1654
  /* @__PURE__ */ jsxRuntime.jsx(
1591
1655
  designSystem.Box,
1592
1656
  {
@@ -1603,7 +1667,7 @@ const DocumentActionModal = ({
1603
1667
  )
1604
1668
  ] });
1605
1669
  };
1606
- const PublishAction = ({
1670
+ const PublishAction$1 = ({
1607
1671
  activeTab,
1608
1672
  documentId,
1609
1673
  model,
@@ -1688,7 +1752,7 @@ const PublishAction = ({
1688
1752
  }
1689
1753
  };
1690
1754
  };
1691
- PublishAction.type = "publish";
1755
+ PublishAction$1.type = "publish";
1692
1756
  const UpdateAction = ({
1693
1757
  activeTab,
1694
1758
  documentId,
@@ -1803,7 +1867,7 @@ const UNPUBLISH_DRAFT_OPTIONS = {
1803
1867
  KEEP: "keep",
1804
1868
  DISCARD: "discard"
1805
1869
  };
1806
- const UnpublishAction = ({
1870
+ const UnpublishAction$1 = ({
1807
1871
  activeTab,
1808
1872
  documentId,
1809
1873
  model,
@@ -1866,7 +1930,7 @@ const UnpublishAction = ({
1866
1930
  content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "flex-start", direction: "column", gap: 6, children: [
1867
1931
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", direction: "column", gap: 2, children: [
1868
1932
  /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
1869
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "p", variant: "omega", textAlign: "center", children: formatMessage({
1933
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
1870
1934
  id: "content-manager.actions.unpublish.dialog.body",
1871
1935
  defaultMessage: "Are you sure?"
1872
1936
  }) })
@@ -1877,10 +1941,11 @@ const UnpublishAction = ({
1877
1941
  onChange: handleChange,
1878
1942
  direction: "column",
1879
1943
  alignItems: "flex-start",
1880
- as: "fieldset",
1944
+ tag: "fieldset",
1945
+ borderWidth: 0,
1881
1946
  gap: 3,
1882
1947
  children: [
1883
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { as: "legend" }),
1948
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "legend" }),
1884
1949
  /* @__PURE__ */ jsxRuntime.jsx(
1885
1950
  designSystem.Radio,
1886
1951
  {
@@ -1937,7 +2002,7 @@ const UnpublishAction = ({
1937
2002
  position: ["panel", "table-row"]
1938
2003
  };
1939
2004
  };
1940
- UnpublishAction.type = "unpublish";
2005
+ UnpublishAction$1.type = "unpublish";
1941
2006
  const DiscardAction = ({
1942
2007
  activeTab,
1943
2008
  documentId,
@@ -1971,7 +2036,7 @@ const DiscardAction = ({
1971
2036
  }),
1972
2037
  content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
1973
2038
  /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
1974
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "p", variant: "omega", textAlign: "center", children: formatMessage({
2039
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
1975
2040
  id: "content-manager.actions.discard.dialog.body",
1976
2041
  defaultMessage: "Are you sure?"
1977
2042
  }) })
@@ -1988,12 +2053,12 @@ const DiscardAction = ({
1988
2053
  };
1989
2054
  };
1990
2055
  DiscardAction.type = "discard";
1991
- const StyledCrossCircle = styled__default.default(Icons.CrossCircle)`
2056
+ const StyledCrossCircle = styledComponents.styled(Icons.CrossCircle)`
1992
2057
  path {
1993
2058
  fill: currentColor;
1994
2059
  }
1995
2060
  `;
1996
- const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction, DiscardAction];
2061
+ const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
1997
2062
  const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
1998
2063
  const RelativeTime = React__namespace.forwardRef(
1999
2064
  ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
@@ -2041,7 +2106,7 @@ const getDisplayName = ({
2041
2106
  const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2042
2107
  const DocumentStatus = ({ status = "draft", ...restProps }) => {
2043
2108
  const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
2044
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
2109
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
2045
2110
  };
2046
2111
  const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2047
2112
  const { formatMessage } = reactIntl.useIntl();
@@ -2061,7 +2126,7 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2061
2126
  gap: "80px",
2062
2127
  alignItems: "flex-start",
2063
2128
  children: [
2064
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", as: "h1", children: title }),
2129
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
2065
2130
  /* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
2066
2131
  ]
2067
2132
  }
@@ -2218,7 +2283,7 @@ const Information = ({ activeTab }) => {
2218
2283
  borderColor: "neutral150",
2219
2284
  direction: "column",
2220
2285
  marginTop: 2,
2221
- as: "dl",
2286
+ tag: "dl",
2222
2287
  padding: 5,
2223
2288
  gap: 3,
2224
2289
  alignItems: "flex-start",
@@ -2226,8 +2291,8 @@ const Information = ({ activeTab }) => {
2226
2291
  marginRight: "-0.4rem",
2227
2292
  width: "calc(100% + 8px)",
2228
2293
  children: information.map((info) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, direction: "column", alignItems: "flex-start", children: [
2229
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
2230
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "dd", variant: "pi", textColor: "neutral600", children: info.value })
2294
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
2295
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "dd", variant: "pi", textColor: "neutral600", children: info.value })
2231
2296
  ] }, info.label))
2232
2297
  }
2233
2298
  );
@@ -2260,7 +2325,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
2260
2325
  id: "app.links.configure-view",
2261
2326
  defaultMessage: "Configure the view"
2262
2327
  }),
2263
- icon: /* @__PURE__ */ jsxRuntime.jsx(StyledCog, {}),
2328
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ListPlus, {}),
2264
2329
  onClick: () => {
2265
2330
  navigate(`../${collectionType}/${model}/configurations/edit`);
2266
2331
  },
@@ -2268,11 +2333,6 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
2268
2333
  };
2269
2334
  };
2270
2335
  ConfigureTheViewAction.type = "configure-the-view";
2271
- const StyledCog = styled__default.default(Icons.Cog)`
2272
- path {
2273
- fill: currentColor;
2274
- }
2275
- `;
2276
2336
  const EditTheModelAction = ({ model }) => {
2277
2337
  const navigate = reactRouterDom.useNavigate();
2278
2338
  const { formatMessage } = reactIntl.useIntl();
@@ -2281,7 +2341,7 @@ const EditTheModelAction = ({ model }) => {
2281
2341
  id: "content-manager.link-to-ctb",
2282
2342
  defaultMessage: "Edit the model"
2283
2343
  }),
2284
- icon: /* @__PURE__ */ jsxRuntime.jsx(StyledPencil$1, {}),
2344
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, {}),
2285
2345
  onClick: () => {
2286
2346
  navigate(`/plugins/content-type-builder/content-types/${model}`);
2287
2347
  },
@@ -2289,12 +2349,7 @@ const EditTheModelAction = ({ model }) => {
2289
2349
  };
2290
2350
  };
2291
2351
  EditTheModelAction.type = "edit-the-model";
2292
- const StyledPencil$1 = styled__default.default(Icons.Pencil)`
2293
- path {
2294
- fill: currentColor;
2295
- }
2296
- `;
2297
- const DeleteAction = ({ documentId, model, collectionType, document }) => {
2352
+ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
2298
2353
  const navigate = reactRouterDom.useNavigate();
2299
2354
  const { formatMessage } = reactIntl.useIntl();
2300
2355
  const listViewPathMatch = reactRouterDom.useMatch(LIST_PATH);
@@ -2308,7 +2363,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
2308
2363
  id: "content-manager.actions.delete.label",
2309
2364
  defaultMessage: "Delete document"
2310
2365
  }),
2311
- icon: /* @__PURE__ */ jsxRuntime.jsx(StyledTrash, {}),
2366
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
2312
2367
  dialog: {
2313
2368
  type: "dialog",
2314
2369
  title: formatMessage({
@@ -2317,7 +2372,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
2317
2372
  }),
2318
2373
  content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
2319
2374
  /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
2320
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "p", variant: "omega", textAlign: "center", children: formatMessage({
2375
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
2321
2376
  id: "content-manager.actions.delete.dialog.body",
2322
2377
  defaultMessage: "Are you sure?"
2323
2378
  }) })
@@ -2362,13 +2417,8 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
2362
2417
  position: ["header", "table-row"]
2363
2418
  };
2364
2419
  };
2365
- DeleteAction.type = "delete";
2366
- const StyledTrash = styled__default.default(Icons.Trash)`
2367
- path {
2368
- fill: currentColor;
2369
- }
2370
- `;
2371
- const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction];
2420
+ DeleteAction$1.type = "delete";
2421
+ const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
2372
2422
  const Panels = () => {
2373
2423
  const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
2374
2424
  const [
@@ -2442,7 +2492,7 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
2442
2492
  designSystem.Flex,
2443
2493
  {
2444
2494
  ref,
2445
- as: "aside",
2495
+ tag: "aside",
2446
2496
  "aria-labelledby": "additional-information",
2447
2497
  background: "neutral0",
2448
2498
  borderColor: "neutral150",
@@ -2457,669 +2507,1378 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
2457
2507
  justifyContent: "stretch",
2458
2508
  alignItems: "flex-start",
2459
2509
  children: [
2460
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
2510
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
2461
2511
  children
2462
2512
  ]
2463
2513
  }
2464
2514
  );
2465
2515
  });
2466
- const DEFAULT_BULK_ACTIONS = [];
2467
- const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
2468
- const { formatMessage } = reactIntl.useIntl();
2469
- const getDefaultErrorMessage = (reason) => {
2470
- switch (reason) {
2471
- case "relation":
2472
- return "Duplicating the relation could remove it from the original entry.";
2473
- case "unique":
2474
- return "Identical values in a unique field are not allowed";
2475
- default:
2476
- return reason;
2477
- }
2478
- };
2479
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2480
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: formatMessage({
2481
- id: getTranslation("containers.list.autoCloneModal.title"),
2482
- defaultMessage: "This entry can't be duplicated directly."
2483
- }) }),
2484
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatMessage({
2485
- id: getTranslation("containers.list.autoCloneModal.description"),
2486
- defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
2487
- }) }) }),
2488
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxRuntime.jsxs(
2489
- designSystem.Flex,
2490
- {
2491
- direction: "column",
2492
- gap: 2,
2493
- alignItems: "flex-start",
2494
- borderColor: "neutral200",
2495
- hasRadius: true,
2496
- padding: 6,
2497
- children: [
2498
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "row", as: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { fontWeight: "semiBold", as: "li", children: [
2499
- pathSegment,
2500
- index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
2501
- Icons.ChevronRight,
2502
- {
2503
- fill: "neutral500",
2504
- height: "0.8rem",
2505
- width: "0.8rem",
2506
- style: { margin: "0 0.8rem" }
2507
- }
2508
- )
2509
- ] }, index2)) }),
2510
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "p", textColor: "neutral600", children: formatMessage({
2511
- id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
2512
- defaultMessage: getDefaultErrorMessage(reason)
2513
- }) })
2514
- ]
2515
- },
2516
- fieldPath.join()
2517
- )) })
2518
- ] });
2516
+ const HOOKS = {
2517
+ /**
2518
+ * Hook that allows to mutate the displayed headers of the list view table
2519
+ * @constant
2520
+ * @type {string}
2521
+ */
2522
+ INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
2523
+ /**
2524
+ * Hook that allows to mutate the CM's collection types links pre-set filters
2525
+ * @constant
2526
+ * @type {string}
2527
+ */
2528
+ MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
2529
+ /**
2530
+ * Hook that allows to mutate the CM's edit view layout
2531
+ * @constant
2532
+ * @type {string}
2533
+ */
2534
+ MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
2535
+ /**
2536
+ * Hook that allows to mutate the CM's single types links pre-set filters
2537
+ * @constant
2538
+ * @type {string}
2539
+ */
2540
+ MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
2519
2541
  };
2520
- const TableActions = ({ document }) => {
2521
- const { formatMessage } = reactIntl.useIntl();
2522
- const { model, collectionType } = useDoc();
2523
- const plugins = strapiAdmin.useStrapiApp("TableActions", (state) => state.plugins);
2524
- const props = {
2525
- activeTab: null,
2526
- model,
2527
- documentId: document.documentId,
2528
- collectionType,
2529
- document
2530
- };
2531
- return /* @__PURE__ */ jsxRuntime.jsx(
2532
- strapiAdmin.DescriptionComponentRenderer,
2533
- {
2534
- props,
2535
- descriptions: plugins["content-manager"].apis.getDocumentActions(),
2536
- children: (actions2) => {
2537
- const tableRowActions = actions2.filter((action) => {
2538
- const positions = Array.isArray(action.position) ? action.position : [action.position];
2539
- return positions.includes("table-row");
2540
- });
2541
- return /* @__PURE__ */ jsxRuntime.jsx(
2542
- DocumentActionsMenu,
2543
- {
2544
- actions: tableRowActions,
2545
- label: formatMessage({
2546
- id: "content-manager.containers.list.table.row-actions",
2547
- defaultMessage: "Row action"
2548
- }),
2549
- variant: "ghost"
2550
- }
2551
- );
2552
- }
2553
- }
2554
- );
2542
+ const contentTypesApi = contentManagerApi.injectEndpoints({
2543
+ endpoints: (builder) => ({
2544
+ getContentTypeConfiguration: builder.query({
2545
+ query: (uid) => ({
2546
+ url: `/content-manager/content-types/${uid}/configuration`,
2547
+ method: "GET"
2548
+ }),
2549
+ transformResponse: (response) => response.data,
2550
+ providesTags: (_result, _error, uid) => [
2551
+ { type: "ContentTypesConfiguration", id: uid },
2552
+ { type: "ContentTypeSettings", id: "LIST" }
2553
+ ]
2554
+ }),
2555
+ getAllContentTypeSettings: builder.query({
2556
+ query: () => "/content-manager/content-types-settings",
2557
+ transformResponse: (response) => response.data,
2558
+ providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
2559
+ }),
2560
+ updateContentTypeConfiguration: builder.mutation({
2561
+ query: ({ uid, ...body }) => ({
2562
+ url: `/content-manager/content-types/${uid}/configuration`,
2563
+ method: "PUT",
2564
+ data: body
2565
+ }),
2566
+ transformResponse: (response) => response.data,
2567
+ invalidatesTags: (_result, _error, { uid }) => [
2568
+ { type: "ContentTypesConfiguration", id: uid },
2569
+ { type: "ContentTypeSettings", id: "LIST" },
2570
+ // Is this necessary?
2571
+ { type: "InitialData" }
2572
+ ]
2573
+ })
2574
+ })
2575
+ });
2576
+ const {
2577
+ useGetContentTypeConfigurationQuery,
2578
+ useGetAllContentTypeSettingsQuery,
2579
+ useUpdateContentTypeConfigurationMutation
2580
+ } = contentTypesApi;
2581
+ const checkIfAttributeIsDisplayable = (attribute) => {
2582
+ const { type } = attribute;
2583
+ if (type === "relation") {
2584
+ return !attribute.relation.toLowerCase().includes("morph");
2585
+ }
2586
+ return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
2555
2587
  };
2556
- const EditAction = ({ documentId }) => {
2557
- const navigate = reactRouterDom.useNavigate();
2558
- const { formatMessage } = reactIntl.useIntl();
2559
- const { canRead } = useDocumentRBAC("EditAction", ({ canRead: canRead2 }) => ({ canRead: canRead2 }));
2560
- const { toggleNotification } = strapiAdmin.useNotification();
2561
- const [{ query }] = strapiAdmin.useQueryParams();
2588
+ const getMainField = (attribute, mainFieldName, { schemas, components }) => {
2589
+ if (!mainFieldName) {
2590
+ return void 0;
2591
+ }
2592
+ const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
2593
+ // @ts-expect-error `targetModel` does exist on the attribute for a relation.
2594
+ schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
2595
+ );
2562
2596
  return {
2563
- disabled: !canRead,
2564
- icon: /* @__PURE__ */ jsxRuntime.jsx(StyledPencil, {}),
2565
- label: formatMessage({
2566
- id: "content-manager.actions.edit.label",
2567
- defaultMessage: "Edit"
2568
- }),
2569
- position: "table-row",
2570
- onClick: async () => {
2571
- if (!documentId) {
2572
- console.error(
2573
- "You're trying to edit a document without an id, this is likely a bug with Strapi. Please open an issue."
2574
- );
2575
- toggleNotification({
2576
- message: formatMessage({
2577
- id: "content-manager.actions.edit.error",
2578
- defaultMessage: "An error occurred while trying to edit the document."
2579
- }),
2580
- type: "danger"
2581
- });
2582
- return;
2583
- }
2584
- navigate({
2585
- pathname: documentId,
2586
- search: qs.stringify({
2587
- plugins: query.plugins
2588
- })
2589
- });
2590
- }
2597
+ name: mainFieldName,
2598
+ type: mainFieldType ?? "string"
2591
2599
  };
2592
2600
  };
2593
- EditAction.type = "edit";
2594
- const StyledPencil = styled__default.default(Icons.Pencil)`
2595
- path {
2596
- fill: currentColor;
2597
- }
2598
- `;
2599
- const CloneAction = ({ model, documentId }) => {
2600
- const navigate = reactRouterDom.useNavigate();
2601
- const { formatMessage } = reactIntl.useIntl();
2602
- const { canCreate } = useDocumentRBAC("CloneAction", ({ canCreate: canCreate2 }) => ({ canCreate: canCreate2 }));
2601
+ const DEFAULT_SETTINGS = {
2602
+ bulkable: false,
2603
+ filterable: false,
2604
+ searchable: false,
2605
+ pagination: false,
2606
+ defaultSortBy: "",
2607
+ defaultSortOrder: "asc",
2608
+ mainField: "id",
2609
+ pageSize: 10
2610
+ };
2611
+ const useDocumentLayout = (model) => {
2612
+ const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
2613
+ const [{ query }] = strapiAdmin.useQueryParams();
2614
+ const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
2603
2615
  const { toggleNotification } = strapiAdmin.useNotification();
2604
- const { autoClone } = useDocumentActions();
2605
- const [prohibitedFields, setProhibitedFields] = React__namespace.useState([]);
2606
- return {
2607
- disabled: !canCreate,
2608
- icon: /* @__PURE__ */ jsxRuntime.jsx(StyledDuplicate, {}),
2609
- label: formatMessage({
2610
- id: "content-manager.actions.clone.label",
2611
- defaultMessage: "Duplicate"
2612
- }),
2613
- position: "table-row",
2614
- onClick: async () => {
2615
- if (!documentId) {
2616
- console.error(
2617
- "You're trying to clone a document in the table without an id, this is likely a bug with Strapi. Please open an issue."
2618
- );
2619
- toggleNotification({
2620
- message: formatMessage({
2621
- id: "content-manager.actions.clone.error",
2622
- defaultMessage: "An error occurred while trying to clone the document."
2623
- }),
2624
- type: "danger"
2625
- });
2626
- return;
2627
- }
2628
- const res = await autoClone({ model, sourceId: documentId });
2629
- if ("data" in res) {
2630
- navigate(res.data.documentId);
2631
- return true;
2632
- }
2633
- if (isBaseQueryError(res.error) && res.error.details && typeof res.error.details === "object" && "prohibitedFields" in res.error.details && Array.isArray(res.error.details.prohibitedFields)) {
2634
- const prohibitedFields2 = res.error.details.prohibitedFields;
2635
- setProhibitedFields(prohibitedFields2);
2636
- }
2637
- },
2638
- dialog: {
2639
- type: "modal",
2640
- title: formatMessage({
2641
- id: "content-manager.containers.list.autoCloneModal.header",
2642
- defaultMessage: "Duplicate"
2643
- }),
2644
- content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
2645
- footer: ({ onClose }) => {
2646
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", children: [
2647
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
2648
- id: "cancel",
2649
- defaultMessage: "Cancel"
2650
- }) }),
2651
- /* @__PURE__ */ jsxRuntime.jsx(
2652
- designSystem.LinkButton,
2653
- {
2654
- as: reactRouterDom.NavLink,
2655
- to: {
2656
- pathname: `clone/${documentId}`
2657
- },
2658
- children: formatMessage({
2659
- id: "content-manager.containers.list.autoCloneModal.create",
2660
- defaultMessage: "Create"
2661
- })
2662
- }
2663
- )
2664
- ] });
2665
- }
2616
+ const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
2617
+ const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
2618
+ const {
2619
+ data,
2620
+ isLoading: isLoadingConfigs,
2621
+ error,
2622
+ isFetching: isFetchingConfigs
2623
+ } = useGetContentTypeConfigurationQuery(model);
2624
+ const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
2625
+ React__namespace.useEffect(() => {
2626
+ if (error) {
2627
+ toggleNotification({
2628
+ type: "danger",
2629
+ message: formatAPIError(error)
2630
+ });
2666
2631
  }
2632
+ }, [error, formatAPIError, toggleNotification]);
2633
+ const editLayout = React__namespace.useMemo(
2634
+ () => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
2635
+ layout: [],
2636
+ components: {},
2637
+ metadatas: {},
2638
+ options: {},
2639
+ settings: DEFAULT_SETTINGS
2640
+ },
2641
+ [data, isLoading, schemas, schema, components]
2642
+ );
2643
+ const listLayout = React__namespace.useMemo(() => {
2644
+ return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
2645
+ layout: [],
2646
+ metadatas: {},
2647
+ options: {},
2648
+ settings: DEFAULT_SETTINGS
2649
+ };
2650
+ }, [data, isLoading, schemas, schema, components]);
2651
+ const { layout: edit } = React__namespace.useMemo(
2652
+ () => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
2653
+ layout: editLayout,
2654
+ query
2655
+ }),
2656
+ [editLayout, query, runHookWaterfall]
2657
+ );
2658
+ return {
2659
+ error,
2660
+ isLoading,
2661
+ edit,
2662
+ list: listLayout
2667
2663
  };
2668
2664
  };
2669
- CloneAction.type = "clone";
2670
- const StyledDuplicate = styled__default.default(Icons.Duplicate)`
2671
- path {
2672
- fill: currentColor;
2673
- }
2674
- `;
2675
- const DEFAULT_TABLE_ROW_ACTIONS = [EditAction, CloneAction];
2676
- class ContentManagerPlugin {
2677
- /**
2678
- * The following properties are the stored ones provided by any plugins registering with
2679
- * the content-manager. The function calls however, need to be called at runtime in the
2680
- * application, so instead we collate them and run them later with the complete list incl.
2681
- * ones already registered & the context of the view.
2682
- */
2683
- bulkActions = [...DEFAULT_BULK_ACTIONS];
2684
- documentActions = [
2685
- ...DEFAULT_ACTIONS,
2686
- ...DEFAULT_TABLE_ROW_ACTIONS,
2687
- ...DEFAULT_HEADER_ACTIONS,
2688
- HistoryAction
2689
- ];
2690
- editViewSidePanels = [ActionsPanel];
2691
- headerActions = [];
2692
- constructor() {
2693
- }
2694
- addEditViewSidePanel(panels) {
2695
- if (Array.isArray(panels)) {
2696
- this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
2697
- } else if (typeof panels === "function") {
2698
- this.editViewSidePanels = panels(this.editViewSidePanels);
2699
- } else {
2700
- throw new Error(
2701
- `Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
2702
- panels
2703
- )}`
2704
- );
2705
- }
2706
- }
2707
- addDocumentAction(actions2) {
2708
- if (Array.isArray(actions2)) {
2709
- this.documentActions = [...this.documentActions, ...actions2];
2710
- } else if (typeof actions2 === "function") {
2711
- this.documentActions = actions2(this.documentActions);
2712
- } else {
2713
- throw new Error(
2714
- `Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
2715
- actions2
2716
- )}`
2717
- );
2718
- }
2719
- }
2720
- addDocumentHeaderAction(actions2) {
2721
- if (Array.isArray(actions2)) {
2722
- this.headerActions = [...this.headerActions, ...actions2];
2723
- } else if (typeof actions2 === "function") {
2724
- this.headerActions = actions2(this.headerActions);
2725
- } else {
2726
- throw new Error(
2727
- `Expected the \`actions\` passed to \`addDocumentHeaderAction\` to be an array or a function, but received ${getPrintableType(
2728
- actions2
2729
- )}`
2730
- );
2731
- }
2732
- }
2733
- addBulkAction(actions2) {
2734
- if (Array.isArray(actions2)) {
2735
- this.bulkActions = [...this.bulkActions, ...actions2];
2736
- } else if (typeof actions2 === "function") {
2737
- this.bulkActions = actions2(this.bulkActions);
2665
+ const useDocLayout = () => {
2666
+ const { model } = useDoc();
2667
+ return useDocumentLayout(model);
2668
+ };
2669
+ const formatEditLayout = (data, {
2670
+ schemas,
2671
+ schema,
2672
+ components
2673
+ }) => {
2674
+ let currentPanelIndex = 0;
2675
+ const panelledEditAttributes = convertEditLayoutToFieldLayouts(
2676
+ data.contentType.layouts.edit,
2677
+ schema?.attributes,
2678
+ data.contentType.metadatas,
2679
+ { configurations: data.components, schemas: components },
2680
+ schemas
2681
+ ).reduce((panels, row) => {
2682
+ if (row.some((field) => field.type === "dynamiczone")) {
2683
+ panels.push([row]);
2684
+ currentPanelIndex += 2;
2738
2685
  } else {
2739
- throw new Error(
2740
- `Expected the \`actions\` passed to \`addBulkAction\` to be an array or a function, but received ${getPrintableType(
2741
- actions2
2742
- )}`
2743
- );
2744
- }
2745
- }
2746
- get config() {
2747
- return {
2748
- id: PLUGIN_ID,
2749
- name: "Content Manager",
2750
- injectionZones: INJECTION_ZONES,
2751
- apis: {
2752
- addBulkAction: this.addBulkAction.bind(this),
2753
- addDocumentAction: this.addDocumentAction.bind(this),
2754
- addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
2755
- addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
2756
- getBulkActions: () => this.bulkActions,
2757
- getDocumentActions: () => this.documentActions,
2758
- getEditViewSidePanels: () => this.editViewSidePanels,
2759
- getHeaderActions: () => this.headerActions
2686
+ if (!panels[currentPanelIndex]) {
2687
+ panels.push([]);
2760
2688
  }
2761
- };
2762
- }
2763
- }
2764
- const getPrintableType = (value) => {
2765
- const nativeType = typeof value;
2766
- if (nativeType === "object") {
2767
- if (value === null)
2768
- return "null";
2769
- if (Array.isArray(value))
2770
- return "array";
2771
- if (value instanceof Object && value.constructor.name !== "Object") {
2772
- return value.constructor.name;
2689
+ panels[currentPanelIndex].push(row);
2773
2690
  }
2774
- }
2775
- return nativeType;
2691
+ return panels;
2692
+ }, []);
2693
+ const componentEditAttributes = Object.entries(data.components).reduce(
2694
+ (acc, [uid, configuration]) => {
2695
+ acc[uid] = {
2696
+ layout: convertEditLayoutToFieldLayouts(
2697
+ configuration.layouts.edit,
2698
+ components[uid].attributes,
2699
+ configuration.metadatas
2700
+ ),
2701
+ settings: {
2702
+ ...configuration.settings,
2703
+ icon: components[uid].info.icon,
2704
+ displayName: components[uid].info.displayName
2705
+ }
2706
+ };
2707
+ return acc;
2708
+ },
2709
+ {}
2710
+ );
2711
+ const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
2712
+ (acc, [attribute, metadata]) => {
2713
+ return {
2714
+ ...acc,
2715
+ [attribute]: metadata.edit
2716
+ };
2717
+ },
2718
+ {}
2719
+ );
2720
+ return {
2721
+ layout: panelledEditAttributes,
2722
+ components: componentEditAttributes,
2723
+ metadatas: editMetadatas,
2724
+ settings: {
2725
+ ...data.contentType.settings,
2726
+ displayName: schema?.info.displayName
2727
+ },
2728
+ options: {
2729
+ ...schema?.options,
2730
+ ...schema?.pluginOptions,
2731
+ ...data.contentType.options
2732
+ }
2733
+ };
2776
2734
  };
2777
- const initialState = {
2778
- collectionTypeLinks: [],
2779
- components: [],
2780
- fieldSizes: {},
2781
- models: [],
2782
- singleTypeLinks: [],
2783
- isLoading: true
2735
+ const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
2736
+ return rows.map(
2737
+ (row) => row.map((field) => {
2738
+ const attribute = attributes[field.name];
2739
+ if (!attribute) {
2740
+ return null;
2741
+ }
2742
+ const { edit: metadata } = metadatas[field.name];
2743
+ const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
2744
+ return {
2745
+ attribute,
2746
+ disabled: !metadata.editable,
2747
+ hint: metadata.description,
2748
+ label: metadata.label ?? "",
2749
+ name: field.name,
2750
+ // @ts-expect-error – mainField does exist on the metadata for a relation.
2751
+ mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
2752
+ schemas,
2753
+ components: components?.schemas ?? {}
2754
+ }),
2755
+ placeholder: metadata.placeholder ?? "",
2756
+ required: attribute.required ?? false,
2757
+ size: field.size,
2758
+ unique: "unique" in attribute ? attribute.unique : false,
2759
+ visible: metadata.visible ?? true,
2760
+ type: attribute.type
2761
+ };
2762
+ }).filter((field) => field !== null)
2763
+ );
2784
2764
  };
2785
- const appSlice = toolkit.createSlice({
2786
- name: "app",
2787
- initialState,
2788
- reducers: {
2789
- setInitialData(state, action) {
2790
- const {
2791
- authorizedCollectionTypeLinks,
2792
- authorizedSingleTypeLinks,
2793
- components,
2794
- contentTypeSchemas,
2795
- fieldSizes
2796
- } = action.payload;
2797
- state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
2798
- ({ isDisplayed }) => isDisplayed
2799
- );
2800
- state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
2801
- state.components = components;
2802
- state.models = contentTypeSchemas;
2803
- state.fieldSizes = fieldSizes;
2804
- state.isLoading = false;
2765
+ const formatListLayout = (data, {
2766
+ schemas,
2767
+ schema,
2768
+ components
2769
+ }) => {
2770
+ const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
2771
+ (acc, [attribute, metadata]) => {
2772
+ return {
2773
+ ...acc,
2774
+ [attribute]: metadata.list
2775
+ };
2776
+ },
2777
+ {}
2778
+ );
2779
+ const listAttributes = convertListLayoutToFieldLayouts(
2780
+ data.contentType.layouts.list,
2781
+ schema?.attributes,
2782
+ listMetadatas,
2783
+ { configurations: data.components, schemas: components },
2784
+ schemas
2785
+ );
2786
+ return {
2787
+ layout: listAttributes,
2788
+ settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
2789
+ metadatas: listMetadatas,
2790
+ options: {
2791
+ ...schema?.options,
2792
+ ...schema?.pluginOptions,
2793
+ ...data.contentType.options
2805
2794
  }
2806
- }
2807
- });
2808
- const { actions, reducer: reducer$1 } = appSlice;
2809
- const { setInitialData } = actions;
2810
- const reducer = toolkit.combineReducers({
2811
- app: reducer$1
2812
- });
2813
- const HOOKS = {
2814
- /**
2815
- * Hook that allows to mutate the displayed headers of the list view table
2816
- * @constant
2817
- * @type {string}
2818
- */
2819
- INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
2820
- /**
2821
- * Hook that allows to mutate the CM's collection types links pre-set filters
2822
- * @constant
2823
- * @type {string}
2824
- */
2825
- MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
2826
- /**
2827
- * Hook that allows to mutate the CM's edit view layout
2828
- * @constant
2829
- * @type {string}
2830
- */
2831
- MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
2832
- /**
2833
- * Hook that allows to mutate the CM's single types links pre-set filters
2834
- * @constant
2835
- * @type {string}
2836
- */
2837
- MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
2795
+ };
2838
2796
  };
2839
- const contentTypesApi = contentManagerApi.injectEndpoints({
2840
- endpoints: (builder) => ({
2841
- getContentTypeConfiguration: builder.query({
2842
- query: (uid) => ({
2843
- url: `/content-manager/content-types/${uid}/configuration`,
2844
- method: "GET"
2797
+ const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
2798
+ return columns.map((name) => {
2799
+ const attribute = attributes[name];
2800
+ if (!attribute) {
2801
+ return null;
2802
+ }
2803
+ const metadata = metadatas[name];
2804
+ const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
2805
+ return {
2806
+ attribute,
2807
+ label: metadata.label ?? "",
2808
+ mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
2809
+ schemas,
2810
+ components: components?.schemas ?? {}
2845
2811
  }),
2846
- transformResponse: (response) => response.data,
2847
- providesTags: (_result, _error, uid) => [
2848
- { type: "ContentTypesConfiguration", id: uid },
2849
- { type: "ContentTypeSettings", id: "LIST" }
2850
- ]
2851
- }),
2852
- getAllContentTypeSettings: builder.query({
2853
- query: () => "/content-manager/content-types-settings",
2854
- transformResponse: (response) => response.data,
2855
- providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
2856
- }),
2857
- updateContentTypeConfiguration: builder.mutation({
2858
- query: ({ uid, ...body }) => ({
2859
- url: `/content-manager/content-types/${uid}/configuration`,
2860
- method: "PUT",
2861
- data: body
2812
+ name,
2813
+ searchable: metadata.searchable ?? true,
2814
+ sortable: metadata.sortable ?? true
2815
+ };
2816
+ }).filter((field) => field !== null);
2817
+ };
2818
+ const ConfirmBulkActionDialog = ({
2819
+ onToggleDialog,
2820
+ isOpen = false,
2821
+ dialogBody,
2822
+ endAction
2823
+ }) => {
2824
+ const { formatMessage } = reactIntl.useIntl();
2825
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2826
+ designSystem.Dialog,
2827
+ {
2828
+ onClose: onToggleDialog,
2829
+ title: formatMessage({
2830
+ id: "app.components.ConfirmDialog.title",
2831
+ defaultMessage: "Confirmation"
2862
2832
  }),
2863
- transformResponse: (response) => response.data,
2864
- invalidatesTags: (_result, _error, { uid }) => [
2865
- { type: "ContentTypesConfiguration", id: uid },
2866
- { type: "ContentTypeSettings", id: "LIST" },
2867
- // Is this necessary?
2868
- { type: "InitialData" }
2833
+ isOpen,
2834
+ children: [
2835
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.DialogBody, { icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, {}), children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: dialogBody }) }),
2836
+ /* @__PURE__ */ jsxRuntime.jsx(
2837
+ designSystem.DialogFooter,
2838
+ {
2839
+ startAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
2840
+ id: "app.components.Button.cancel",
2841
+ defaultMessage: "Cancel"
2842
+ }) }),
2843
+ endAction
2844
+ }
2845
+ )
2869
2846
  ]
2870
- })
2871
- })
2872
- });
2873
- const {
2874
- useGetContentTypeConfigurationQuery,
2875
- useGetAllContentTypeSettingsQuery,
2876
- useUpdateContentTypeConfigurationMutation
2877
- } = contentTypesApi;
2878
- const checkIfAttributeIsDisplayable = (attribute) => {
2879
- const { type } = attribute;
2880
- if (type === "relation") {
2881
- return !attribute.relation.toLowerCase().includes("morph");
2882
- }
2883
- return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
2847
+ }
2848
+ );
2884
2849
  };
2885
- const getMainField = (attribute, mainFieldName, { schemas, components }) => {
2886
- if (!mainFieldName) {
2887
- return void 0;
2850
+ const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
2851
+ const ConfirmDialogPublishAll = ({
2852
+ isOpen,
2853
+ onToggleDialog,
2854
+ isConfirmButtonLoading = false,
2855
+ onConfirm
2856
+ }) => {
2857
+ const { formatMessage } = reactIntl.useIntl();
2858
+ const selectedEntries = strapiAdmin.useTable("ConfirmDialogPublishAll", (state) => state.selectedRows);
2859
+ const { toggleNotification } = strapiAdmin.useNotification();
2860
+ const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
2861
+ const { model, schema } = useDoc();
2862
+ const [{ query }] = strapiAdmin.useQueryParams();
2863
+ const {
2864
+ data: countDraftRelations = 0,
2865
+ isLoading,
2866
+ error
2867
+ } = useGetManyDraftRelationCountQuery(
2868
+ {
2869
+ model,
2870
+ documentIds: selectedEntries.map((entry) => entry.documentId),
2871
+ locale: query?.plugins?.i18n?.locale
2872
+ },
2873
+ {
2874
+ skip: selectedEntries.length === 0
2875
+ }
2876
+ );
2877
+ React__namespace.useEffect(() => {
2878
+ if (error) {
2879
+ toggleNotification({ type: "danger", message: formatAPIError(error) });
2880
+ }
2881
+ }, [error, formatAPIError, toggleNotification]);
2882
+ if (error) {
2883
+ return null;
2888
2884
  }
2889
- const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
2890
- // @ts-expect-error – `targetModel` does exist on the attribute for a relation.
2891
- schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
2885
+ return /* @__PURE__ */ jsxRuntime.jsx(
2886
+ ConfirmBulkActionDialog,
2887
+ {
2888
+ isOpen: isOpen && !isLoading,
2889
+ onToggleDialog,
2890
+ dialogBody: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2891
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: [
2892
+ countDraftRelations > 0 && formatMessage(
2893
+ {
2894
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
2895
+ defaultMessage: "<b>{count} {count, plural, one { relation } other { relations } } out of {entities} { entities, plural, one { entry } other { entries } } {count, plural, one { is } other { are } }</b> not published yet and might lead to unexpected behavior. "
2896
+ },
2897
+ {
2898
+ b: BoldChunk$1,
2899
+ count: countDraftRelations,
2900
+ entities: selectedEntries.length
2901
+ }
2902
+ ),
2903
+ formatMessage({
2904
+ id: getTranslation("popUpWarning.bodyMessage.contentType.publish.all"),
2905
+ defaultMessage: "Are you sure you want to publish these entries?"
2906
+ })
2907
+ ] }),
2908
+ schema?.pluginOptions && "i18n" in schema.pluginOptions && schema?.pluginOptions.i18n && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", textAlign: "center", children: formatMessage(
2909
+ {
2910
+ id: getTranslation("Settings.list.actions.publishAdditionalInfos"),
2911
+ defaultMessage: "This will publish the active locale versions <em>(from Internationalization)</em>"
2912
+ },
2913
+ {
2914
+ em: Emphasis
2915
+ }
2916
+ ) })
2917
+ ] }),
2918
+ endAction: /* @__PURE__ */ jsxRuntime.jsx(
2919
+ designSystem.Button,
2920
+ {
2921
+ onClick: onConfirm,
2922
+ variant: "secondary",
2923
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Check, {}),
2924
+ loading: isConfirmButtonLoading,
2925
+ children: formatMessage({
2926
+ id: "app.utils.publish",
2927
+ defaultMessage: "Publish"
2928
+ })
2929
+ }
2930
+ )
2931
+ }
2892
2932
  );
2893
- return {
2894
- name: mainFieldName,
2895
- type: mainFieldType ?? "string"
2896
- };
2897
2933
  };
2898
- const DEFAULT_SETTINGS = {
2899
- bulkable: false,
2900
- filterable: false,
2901
- searchable: false,
2902
- pagination: false,
2903
- defaultSortBy: "",
2904
- defaultSortOrder: "asc",
2905
- mainField: "id",
2906
- pageSize: 10
2934
+ const TypographyMaxWidth = styledComponents.styled(designSystem.Typography)`
2935
+ max-width: 300px;
2936
+ `;
2937
+ const formatErrorMessages = (errors, parentKey, formatMessage) => {
2938
+ const messages = [];
2939
+ Object.entries(errors).forEach(([key, value]) => {
2940
+ const currentKey = parentKey ? `${parentKey}.${key}` : key;
2941
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
2942
+ if ("id" in value && "defaultMessage" in value) {
2943
+ messages.push(
2944
+ formatMessage(
2945
+ {
2946
+ id: `${value.id}.withField`,
2947
+ defaultMessage: value.defaultMessage
2948
+ },
2949
+ { field: currentKey }
2950
+ )
2951
+ );
2952
+ } else {
2953
+ messages.push(...formatErrorMessages(value, currentKey, formatMessage));
2954
+ }
2955
+ } else {
2956
+ messages.push(
2957
+ formatMessage(
2958
+ {
2959
+ id: `${value}.withField`,
2960
+ defaultMessage: value
2961
+ },
2962
+ { field: currentKey }
2963
+ )
2964
+ );
2965
+ }
2966
+ });
2967
+ return messages;
2907
2968
  };
2908
- const useDocumentLayout = (model) => {
2909
- const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
2910
- const [{ query }] = strapiAdmin.useQueryParams();
2911
- const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
2912
- const { toggleNotification } = strapiAdmin.useNotification();
2913
- const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
2914
- const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
2969
+ const EntryValidationText = ({ validationErrors, status }) => {
2970
+ const { formatMessage } = reactIntl.useIntl();
2971
+ if (validationErrors) {
2972
+ const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
2973
+ " "
2974
+ );
2975
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
2976
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.CrossCircle, { fill: "danger600" }),
2977
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
2978
+ ] });
2979
+ }
2980
+ if (status === "published") {
2981
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
2982
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
2983
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
2984
+ id: "content-manager.bulk-publish.already-published",
2985
+ defaultMessage: "Already Published"
2986
+ }) })
2987
+ ] });
2988
+ }
2989
+ if (status === "modified") {
2990
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
2991
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.ArrowsCounterClockwise, { fill: "alternative600" }),
2992
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
2993
+ id: "content-manager.bulk-publish.modified",
2994
+ defaultMessage: "Ready to publish changes"
2995
+ }) })
2996
+ ] });
2997
+ }
2998
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
2999
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
3000
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
3001
+ id: "app.utils.ready-to-publish",
3002
+ defaultMessage: "Ready to publish"
3003
+ }) })
3004
+ ] });
3005
+ };
3006
+ const TABLE_HEADERS = [
3007
+ { name: "id", label: "id" },
3008
+ { name: "name", label: "name" },
3009
+ { name: "status", label: "status" },
3010
+ { name: "publicationStatus", label: "Publication status" }
3011
+ ];
3012
+ const SelectedEntriesTableContent = ({
3013
+ isPublishing,
3014
+ rowsToDisplay = [],
3015
+ entriesToPublish = [],
3016
+ validationErrors = {}
3017
+ }) => {
3018
+ const { pathname } = reactRouterDom.useLocation();
3019
+ const { formatMessage } = reactIntl.useIntl();
2915
3020
  const {
2916
- data,
2917
- isLoading: isLoadingConfigs,
2918
- error,
2919
- isFetching: isFetchingConfigs
2920
- } = useGetContentTypeConfigurationQuery(model);
2921
- const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
2922
- React__namespace.useEffect(() => {
2923
- if (error) {
2924
- toggleNotification({
2925
- type: "danger",
2926
- message: formatAPIError(error)
2927
- });
3021
+ list: {
3022
+ settings: { mainField }
2928
3023
  }
2929
- }, [error, formatAPIError, toggleNotification]);
2930
- const editLayout = React__namespace.useMemo(
2931
- () => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
2932
- layout: [],
2933
- components: {},
2934
- metadatas: {},
2935
- options: {},
2936
- settings: DEFAULT_SETTINGS
3024
+ } = useDocLayout();
3025
+ const shouldDisplayMainField = mainField != null && mainField !== "id";
3026
+ return /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
3027
+ /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Head, { children: [
3028
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCheckboxCell, {}),
3029
+ TABLE_HEADERS.filter((head) => head.name !== "name" || shouldDisplayMainField).map(
3030
+ (head) => /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCell, { ...head }, head.name)
3031
+ )
3032
+ ] }),
3033
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Loading, {}),
3034
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Body, { children: rowsToDisplay.map((row, index2) => /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Row, { children: [
3035
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.CheckboxCell, { id: row.id }),
3036
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row.id }) }),
3037
+ shouldDisplayMainField && /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row[mainField] }) }),
3038
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: row.status, maxWidth: "min-content" }) }),
3039
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: isPublishing && entriesToPublish.includes(row.documentId) ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
3040
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
3041
+ id: "content-manager.success.record.publishing",
3042
+ defaultMessage: "Publishing..."
3043
+ }) }),
3044
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { small: true })
3045
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
3046
+ EntryValidationText,
3047
+ {
3048
+ validationErrors: validationErrors[row.documentId],
3049
+ status: row.status
3050
+ }
3051
+ ) }),
3052
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
3053
+ designSystem.IconButton,
3054
+ {
3055
+ tag: reactRouterDom.Link,
3056
+ to: {
3057
+ pathname: `${pathname}/${row.documentId}`,
3058
+ search: row.locale && `?plugins[i18n][locale]=${row.locale}`
3059
+ },
3060
+ state: { from: pathname },
3061
+ label: formatMessage(
3062
+ { id: "app.component.HelperPluginTable.edit", defaultMessage: "Edit {target}" },
3063
+ {
3064
+ target: formatMessage(
3065
+ {
3066
+ id: "content-manager.components.ListViewHelperPluginTable.row-line",
3067
+ defaultMessage: "item line {number}"
3068
+ },
3069
+ { number: index2 + 1 }
3070
+ )
3071
+ }
3072
+ ),
3073
+ target: "_blank",
3074
+ marginLeft: "auto",
3075
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, {})
3076
+ }
3077
+ ) })
3078
+ ] }, row.id)) })
3079
+ ] });
3080
+ };
3081
+ const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
3082
+ const SelectedEntriesModalContent = ({
3083
+ listViewSelectedEntries,
3084
+ toggleModal,
3085
+ setListViewSelectedDocuments,
3086
+ model
3087
+ }) => {
3088
+ const { formatMessage } = reactIntl.useIntl();
3089
+ const { schema, components } = useContentTypeSchema(model);
3090
+ const documentIds = listViewSelectedEntries.map(({ documentId }) => documentId);
3091
+ const [{ query }] = strapiAdmin.useQueryParams();
3092
+ const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
3093
+ const { data, isLoading, isFetching, refetch } = useGetAllDocumentsQuery(
3094
+ {
3095
+ model,
3096
+ params: {
3097
+ page: "1",
3098
+ pageSize: documentIds.length.toString(),
3099
+ sort: query.sort,
3100
+ filters: {
3101
+ documentId: {
3102
+ $in: documentIds
3103
+ }
3104
+ },
3105
+ locale: query.plugins?.i18n?.locale
3106
+ }
2937
3107
  },
2938
- [data, isLoading, schemas, schema, components]
3108
+ {
3109
+ selectFromResult: ({ data: data2, ...restRes }) => ({ data: data2?.results ?? [], ...restRes })
3110
+ }
2939
3111
  );
2940
- const listLayout = React__namespace.useMemo(() => {
2941
- return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
2942
- layout: [],
2943
- metadatas: {},
2944
- options: {},
2945
- settings: DEFAULT_SETTINGS
3112
+ const { rows, validationErrors } = React__namespace.useMemo(() => {
3113
+ if (data.length > 0 && schema) {
3114
+ const validate = createYupSchema(schema.attributes, components);
3115
+ const validationErrors2 = {};
3116
+ const rows2 = data.map((entry) => {
3117
+ try {
3118
+ validate.validateSync(entry, { abortEarly: false });
3119
+ return entry;
3120
+ } catch (e) {
3121
+ if (e instanceof yup.ValidationError) {
3122
+ validationErrors2[entry.documentId] = strapiAdmin.getYupValidationErrors(e);
3123
+ }
3124
+ return entry;
3125
+ }
3126
+ });
3127
+ return { rows: rows2, validationErrors: validationErrors2 };
3128
+ }
3129
+ return {
3130
+ rows: [],
3131
+ validationErrors: {}
2946
3132
  };
2947
- }, [data, isLoading, schemas, schema, components]);
2948
- const { layout: edit } = React__namespace.useMemo(
2949
- () => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
2950
- layout: editLayout,
2951
- query
2952
- }),
2953
- [editLayout, query, runHookWaterfall]
3133
+ }, [components, data, schema]);
3134
+ const [publishedCount, setPublishedCount] = React__namespace.useState(0);
3135
+ const [isDialogOpen, setIsDialogOpen] = React__namespace.useState(false);
3136
+ const { publishMany: bulkPublishAction } = useDocumentActions();
3137
+ const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
3138
+ const selectedRows = strapiAdmin.useTable("publishAction", (state) => state.selectedRows);
3139
+ const selectedEntries = rows.filter(
3140
+ (entry) => selectedRows.some((selectedEntry) => selectedEntry.documentId === entry.documentId)
2954
3141
  );
3142
+ const entriesToPublish = selectedEntries.filter((entry) => !validationErrors[entry.documentId]).map((entry) => entry.documentId);
3143
+ const selectedEntriesWithErrorsCount = selectedEntries.filter(
3144
+ ({ documentId }) => validationErrors[documentId]
3145
+ ).length;
3146
+ const selectedEntriesPublished = selectedEntries.filter(
3147
+ ({ status }) => status === "published"
3148
+ ).length;
3149
+ const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublished;
3150
+ const toggleDialog = () => setIsDialogOpen((prev) => !prev);
3151
+ const handleConfirmBulkPublish = async () => {
3152
+ toggleDialog();
3153
+ const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
3154
+ if (!("error" in res)) {
3155
+ setPublishedCount(res.count);
3156
+ const unpublishedEntries = rows.filter((row) => {
3157
+ return !entriesToPublish.includes(row.documentId);
3158
+ });
3159
+ setListViewSelectedDocuments(unpublishedEntries);
3160
+ }
3161
+ };
3162
+ const getFormattedCountMessage = () => {
3163
+ if (publishedCount) {
3164
+ return formatMessage(
3165
+ {
3166
+ id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
3167
+ defaultMessage: "<b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} published. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
3168
+ },
3169
+ {
3170
+ publishedCount,
3171
+ withErrorsCount: selectedEntriesWithErrorsCount,
3172
+ b: BoldChunk
3173
+ }
3174
+ );
3175
+ }
3176
+ return formatMessage(
3177
+ {
3178
+ id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
3179
+ defaultMessage: "<b>{alreadyPublishedCount}</b> {alreadyPublishedCount, plural, =0 {entries} one {entry} other {entries}} already published. <b>{readyToPublishCount}</b> {readyToPublishCount, plural, =0 {entries} one {entry} other {entries}} ready to publish. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
3180
+ },
3181
+ {
3182
+ readyToPublishCount: selectedEntriesWithNoErrorsCount,
3183
+ withErrorsCount: selectedEntriesWithErrorsCount,
3184
+ alreadyPublishedCount: selectedEntriesPublished,
3185
+ b: BoldChunk
3186
+ }
3187
+ );
3188
+ };
3189
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3190
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalBody, { children: [
3191
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
3192
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsx(
3193
+ SelectedEntriesTableContent,
3194
+ {
3195
+ isPublishing: isSubmittingForm,
3196
+ rowsToDisplay: rows,
3197
+ entriesToPublish,
3198
+ validationErrors
3199
+ }
3200
+ ) })
3201
+ ] }),
3202
+ /* @__PURE__ */ jsxRuntime.jsx(
3203
+ designSystem.ModalFooter,
3204
+ {
3205
+ startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
3206
+ id: "app.components.Button.cancel",
3207
+ defaultMessage: "Cancel"
3208
+ }) }),
3209
+ endActions: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
3210
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
3211
+ /* @__PURE__ */ jsxRuntime.jsx(
3212
+ designSystem.Button,
3213
+ {
3214
+ onClick: toggleDialog,
3215
+ disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
3216
+ loading: isSubmittingForm,
3217
+ children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
3218
+ }
3219
+ )
3220
+ ] })
3221
+ }
3222
+ ),
3223
+ /* @__PURE__ */ jsxRuntime.jsx(
3224
+ ConfirmDialogPublishAll,
3225
+ {
3226
+ isOpen: isDialogOpen,
3227
+ onToggleDialog: toggleDialog,
3228
+ isConfirmButtonLoading: isSubmittingForm,
3229
+ onConfirm: handleConfirmBulkPublish
3230
+ }
3231
+ )
3232
+ ] });
3233
+ };
3234
+ const PublishAction = ({ documents, model }) => {
3235
+ const { formatMessage } = reactIntl.useIntl();
3236
+ const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
3237
+ const showPublishButton = hasPublishPermission && documents.some(({ status }) => status !== "published");
3238
+ const setListViewSelectedDocuments = strapiAdmin.useTable("publishAction", (state) => state.selectRow);
3239
+ const refetchList = () => {
3240
+ contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
3241
+ };
3242
+ if (!showPublishButton)
3243
+ return null;
2955
3244
  return {
2956
- error,
2957
- isLoading,
2958
- edit,
2959
- list: listLayout
3245
+ actionType: "publish",
3246
+ variant: "tertiary",
3247
+ label: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" }),
3248
+ dialog: {
3249
+ type: "modal",
3250
+ title: formatMessage({
3251
+ id: getTranslation("containers.ListPage.selectedEntriesModal.title"),
3252
+ defaultMessage: "Publish entries"
3253
+ }),
3254
+ content: ({ onClose }) => {
3255
+ return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Root, { rows: documents, defaultSelectedRows: documents, headers: TABLE_HEADERS, children: /* @__PURE__ */ jsxRuntime.jsx(
3256
+ SelectedEntriesModalContent,
3257
+ {
3258
+ listViewSelectedEntries: documents,
3259
+ toggleModal: () => {
3260
+ onClose();
3261
+ refetchList();
3262
+ },
3263
+ setListViewSelectedDocuments,
3264
+ model
3265
+ }
3266
+ ) });
3267
+ },
3268
+ onClose: () => {
3269
+ refetchList();
3270
+ }
3271
+ }
3272
+ };
3273
+ };
3274
+ const BulkActionsRenderer = () => {
3275
+ const plugins = strapiAdmin.useStrapiApp("BulkActionsRenderer", (state) => state.plugins);
3276
+ const { model, collectionType } = useDoc();
3277
+ const { selectedRows } = strapiAdmin.useTable("BulkActionsRenderer", (state) => state);
3278
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
3279
+ strapiAdmin.DescriptionComponentRenderer,
3280
+ {
3281
+ props: {
3282
+ model,
3283
+ collectionType,
3284
+ documents: selectedRows
3285
+ },
3286
+ descriptions: plugins["content-manager"].apis.getBulkActions(),
3287
+ children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsxRuntime.jsx(BulkActionAction, { ...action }, action.id))
3288
+ }
3289
+ ) });
3290
+ };
3291
+ const BulkActionAction = (action) => {
3292
+ const [dialogId, setDialogId] = React__namespace.useState(null);
3293
+ const { toggleNotification } = strapiAdmin.useNotification();
3294
+ const handleClick = (action2) => (e) => {
3295
+ const { onClick, dialog, id } = action2;
3296
+ if (onClick) {
3297
+ onClick(e);
3298
+ }
3299
+ if (dialog) {
3300
+ switch (dialog.type) {
3301
+ case "notification":
3302
+ toggleNotification({
3303
+ title: dialog.title,
3304
+ message: dialog.content,
3305
+ type: dialog.status,
3306
+ timeout: dialog.timeout,
3307
+ onClose: dialog.onClose
3308
+ });
3309
+ break;
3310
+ case "dialog":
3311
+ case "modal": {
3312
+ e.preventDefault();
3313
+ setDialogId(id);
3314
+ }
3315
+ }
3316
+ }
3317
+ };
3318
+ const handleClose = () => {
3319
+ setDialogId(null);
3320
+ if (action.dialog?.type === "modal" && action.dialog?.onClose) {
3321
+ action.dialog.onClose();
3322
+ }
3323
+ };
3324
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3325
+ /* @__PURE__ */ jsxRuntime.jsx(
3326
+ designSystem.Button,
3327
+ {
3328
+ disabled: action.disabled,
3329
+ startIcon: action.icon,
3330
+ variant: action.variant,
3331
+ onClick: handleClick(action),
3332
+ children: action.label
3333
+ }
3334
+ ),
3335
+ action.dialog?.type === "dialog" ? /* @__PURE__ */ jsxRuntime.jsx(
3336
+ BulkActionConfirmDialog,
3337
+ {
3338
+ ...action.dialog,
3339
+ variant: action.variant,
3340
+ isOpen: dialogId === action.id,
3341
+ onClose: handleClose
3342
+ }
3343
+ ) : null,
3344
+ action.dialog?.type === "modal" ? /* @__PURE__ */ jsxRuntime.jsx(
3345
+ BulkActionModal,
3346
+ {
3347
+ ...action.dialog,
3348
+ onModalClose: handleClose,
3349
+ isOpen: dialogId === action.id
3350
+ }
3351
+ ) : null
3352
+ ] });
3353
+ };
3354
+ const BulkActionConfirmDialog = ({
3355
+ onClose,
3356
+ onCancel,
3357
+ onConfirm,
3358
+ title,
3359
+ content,
3360
+ confirmButton,
3361
+ isOpen,
3362
+ variant = "secondary"
3363
+ }) => {
3364
+ const { formatMessage } = reactIntl.useIntl();
3365
+ const handleClose = async () => {
3366
+ if (onCancel) {
3367
+ await onCancel();
3368
+ }
3369
+ onClose();
3370
+ };
3371
+ const handleConfirm = async () => {
3372
+ if (onConfirm) {
3373
+ await onConfirm();
3374
+ }
3375
+ onClose();
3376
+ };
3377
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog, { isOpen, title, onClose: handleClose, children: [
3378
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.DialogBody, { icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, {}), children: content }),
3379
+ /* @__PURE__ */ jsxRuntime.jsx(
3380
+ designSystem.DialogFooter,
3381
+ {
3382
+ startAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", children: formatMessage({
3383
+ id: "app.components.Button.cancel",
3384
+ defaultMessage: "Cancel"
3385
+ }) }),
3386
+ endAction: /* @__PURE__ */ jsxRuntime.jsx(
3387
+ designSystem.Button,
3388
+ {
3389
+ onClick: handleConfirm,
3390
+ variant: variant === "danger-light" ? variant : "secondary",
3391
+ startIcon: variant === "danger-light" ? /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}) : /* @__PURE__ */ jsxRuntime.jsx(Icons.Check, {}),
3392
+ children: confirmButton ? confirmButton : formatMessage({
3393
+ id: "app.components.Button.confirm",
3394
+ defaultMessage: "Confirm"
3395
+ })
3396
+ }
3397
+ )
3398
+ }
3399
+ )
3400
+ ] });
3401
+ };
3402
+ const BulkActionModal = ({
3403
+ isOpen,
3404
+ title,
3405
+ onClose,
3406
+ content: Content,
3407
+ onModalClose
3408
+ }) => {
3409
+ const id = React__namespace.useId();
3410
+ if (!isOpen) {
3411
+ return null;
3412
+ }
3413
+ const handleClose = () => {
3414
+ if (onClose) {
3415
+ onClose();
3416
+ }
3417
+ onModalClose();
2960
3418
  };
3419
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
3420
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
3421
+ /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose })
3422
+ ] });
2961
3423
  };
2962
- const useDocLayout = () => {
2963
- const { model } = useDoc();
2964
- return useDocumentLayout(model);
3424
+ const DeleteAction = ({ documents, model }) => {
3425
+ const { formatMessage } = reactIntl.useIntl();
3426
+ const { schema: contentType } = useDoc();
3427
+ const selectRow = strapiAdmin.useTable("DeleteAction", (state) => state.selectRow);
3428
+ const hasI18nEnabled = Boolean(contentType?.pluginOptions?.i18n);
3429
+ const [{ query }] = strapiAdmin.useQueryParams();
3430
+ const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
3431
+ const hasDeletePermission = useDocumentRBAC("deleteAction", (state) => state.canDelete);
3432
+ const { deleteMany: bulkDeleteAction } = useDocumentActions();
3433
+ const documentIds = documents.map(({ documentId }) => documentId);
3434
+ const handleConfirmBulkDelete = async () => {
3435
+ const res = await bulkDeleteAction({
3436
+ documentIds,
3437
+ model,
3438
+ params
3439
+ });
3440
+ if (!("error" in res)) {
3441
+ selectRow([]);
3442
+ }
3443
+ };
3444
+ if (!hasDeletePermission)
3445
+ return null;
3446
+ return {
3447
+ variant: "danger-light",
3448
+ label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
3449
+ dialog: {
3450
+ type: "dialog",
3451
+ title: formatMessage({
3452
+ id: "app.components.ConfirmDialog.title",
3453
+ defaultMessage: "Confirmation"
3454
+ }),
3455
+ content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3456
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3457
+ id: "popUpWarning.bodyMessage.contentType.delete.all",
3458
+ defaultMessage: "Are you sure you want to delete these entries?"
3459
+ }) }),
3460
+ hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
3461
+ {
3462
+ id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
3463
+ defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
3464
+ },
3465
+ {
3466
+ em: Emphasis
3467
+ }
3468
+ ) }) })
3469
+ ] }),
3470
+ onConfirm: handleConfirmBulkDelete
3471
+ }
3472
+ };
2965
3473
  };
2966
- const formatEditLayout = (data, {
2967
- schemas,
2968
- schema,
2969
- components
2970
- }) => {
2971
- let currentPanelIndex = 0;
2972
- const panelledEditAttributes = convertEditLayoutToFieldLayouts(
2973
- data.contentType.layouts.edit,
2974
- schema?.attributes,
2975
- data.contentType.metadatas,
2976
- { configurations: data.components, schemas: components },
2977
- schemas
2978
- ).reduce((panels, row) => {
2979
- if (row.some((field) => field.type === "dynamiczone")) {
2980
- panels.push([row]);
2981
- currentPanelIndex += 2;
2982
- } else {
2983
- if (!panels[currentPanelIndex]) {
2984
- panels.push([]);
2985
- }
2986
- panels[currentPanelIndex].push(row);
3474
+ DeleteAction.type = "delete";
3475
+ const UnpublishAction = ({ documents, model }) => {
3476
+ const { formatMessage } = reactIntl.useIntl();
3477
+ const { schema } = useDoc();
3478
+ const selectRow = strapiAdmin.useTable("UnpublishAction", (state) => state.selectRow);
3479
+ const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
3480
+ const hasI18nEnabled = Boolean(schema?.pluginOptions?.i18n);
3481
+ const hasDraftAndPublishEnabled = Boolean(schema?.options?.draftAndPublish);
3482
+ const { unpublishMany: bulkUnpublishAction } = useDocumentActions();
3483
+ const documentIds = documents.map(({ documentId }) => documentId);
3484
+ const [{ query }] = strapiAdmin.useQueryParams();
3485
+ const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
3486
+ const handleConfirmBulkUnpublish = async () => {
3487
+ const data = await bulkUnpublishAction({ documentIds, model, params });
3488
+ if (!("error" in data)) {
3489
+ selectRow([]);
2987
3490
  }
2988
- return panels;
2989
- }, []);
2990
- const componentEditAttributes = Object.entries(data.components).reduce(
2991
- (acc, [uid, configuration]) => {
2992
- acc[uid] = {
2993
- layout: convertEditLayoutToFieldLayouts(
2994
- configuration.layouts.edit,
2995
- components[uid].attributes,
2996
- configuration.metadatas
2997
- ),
2998
- settings: {
2999
- ...configuration.settings,
3000
- icon: components[uid].info.icon,
3001
- displayName: components[uid].info.displayName
3002
- }
3003
- };
3004
- return acc;
3005
- },
3006
- {}
3007
- );
3008
- const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
3009
- (acc, [attribute, metadata]) => {
3010
- return {
3011
- ...acc,
3012
- [attribute]: metadata.edit
3013
- };
3014
- },
3015
- {}
3016
- );
3491
+ };
3492
+ const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
3493
+ if (!showUnpublishButton)
3494
+ return null;
3017
3495
  return {
3018
- layout: panelledEditAttributes,
3019
- components: componentEditAttributes,
3020
- metadatas: editMetadatas,
3021
- settings: {
3022
- ...data.contentType.settings,
3023
- displayName: schema?.info.displayName
3024
- },
3025
- options: {
3026
- ...schema?.options,
3027
- ...schema?.pluginOptions,
3028
- ...data.contentType.options
3496
+ variant: "tertiary",
3497
+ label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
3498
+ dialog: {
3499
+ type: "dialog",
3500
+ title: formatMessage({
3501
+ id: "app.components.ConfirmDialog.title",
3502
+ defaultMessage: "Confirmation"
3503
+ }),
3504
+ content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3505
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3506
+ id: "popUpWarning.bodyMessage.contentType.unpublish.all",
3507
+ defaultMessage: "Are you sure you want to unpublish these entries?"
3508
+ }) }),
3509
+ hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
3510
+ {
3511
+ id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
3512
+ defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
3513
+ },
3514
+ {
3515
+ em: Emphasis
3516
+ }
3517
+ ) }) })
3518
+ ] }),
3519
+ confirmButton: formatMessage({
3520
+ id: "app.utils.unpublish",
3521
+ defaultMessage: "Unpublish"
3522
+ }),
3523
+ onConfirm: handleConfirmBulkUnpublish
3029
3524
  }
3030
3525
  };
3031
3526
  };
3032
- const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
3033
- return rows.map(
3034
- (row) => row.map((field) => {
3035
- const attribute = attributes[field.name];
3036
- if (!attribute) {
3037
- return null;
3527
+ UnpublishAction.type = "unpublish";
3528
+ const Emphasis = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
3529
+ const DEFAULT_BULK_ACTIONS = [PublishAction, UnpublishAction, DeleteAction];
3530
+ const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
3531
+ const { formatMessage } = reactIntl.useIntl();
3532
+ const getDefaultErrorMessage = (reason) => {
3533
+ switch (reason) {
3534
+ case "relation":
3535
+ return "Duplicating the relation could remove it from the original entry.";
3536
+ case "unique":
3537
+ return "Identical values in a unique field are not allowed";
3538
+ default:
3539
+ return reason;
3540
+ }
3541
+ };
3542
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3543
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: formatMessage({
3544
+ id: getTranslation("containers.list.autoCloneModal.title"),
3545
+ defaultMessage: "This entry can't be duplicated directly."
3546
+ }) }),
3547
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatMessage({
3548
+ id: getTranslation("containers.list.autoCloneModal.description"),
3549
+ defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
3550
+ }) }) }),
3551
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxRuntime.jsxs(
3552
+ designSystem.Flex,
3553
+ {
3554
+ direction: "column",
3555
+ gap: 2,
3556
+ alignItems: "flex-start",
3557
+ borderColor: "neutral200",
3558
+ hasRadius: true,
3559
+ padding: 6,
3560
+ children: [
3561
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "row", tag: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { fontWeight: "semiBold", tag: "li", children: [
3562
+ pathSegment,
3563
+ index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
3564
+ Icons.ChevronRight,
3565
+ {
3566
+ fill: "neutral500",
3567
+ height: "0.8rem",
3568
+ width: "0.8rem",
3569
+ style: { margin: "0 0.8rem" }
3570
+ }
3571
+ )
3572
+ ] }, index2)) }),
3573
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", textColor: "neutral600", children: formatMessage({
3574
+ id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
3575
+ defaultMessage: getDefaultErrorMessage(reason)
3576
+ }) })
3577
+ ]
3578
+ },
3579
+ fieldPath.join()
3580
+ )) })
3581
+ ] });
3582
+ };
3583
+ const TableActions = ({ document }) => {
3584
+ const { formatMessage } = reactIntl.useIntl();
3585
+ const { model, collectionType } = useDoc();
3586
+ const plugins = strapiAdmin.useStrapiApp("TableActions", (state) => state.plugins);
3587
+ const props = {
3588
+ activeTab: null,
3589
+ model,
3590
+ documentId: document.documentId,
3591
+ collectionType,
3592
+ document
3593
+ };
3594
+ return /* @__PURE__ */ jsxRuntime.jsx(
3595
+ strapiAdmin.DescriptionComponentRenderer,
3596
+ {
3597
+ props,
3598
+ descriptions: plugins["content-manager"].apis.getDocumentActions(),
3599
+ children: (actions2) => {
3600
+ const tableRowActions = actions2.filter((action) => {
3601
+ const positions = Array.isArray(action.position) ? action.position : [action.position];
3602
+ return positions.includes("table-row");
3603
+ });
3604
+ return /* @__PURE__ */ jsxRuntime.jsx(
3605
+ DocumentActionsMenu,
3606
+ {
3607
+ actions: tableRowActions,
3608
+ label: formatMessage({
3609
+ id: "content-manager.containers.list.table.row-actions",
3610
+ defaultMessage: "Row action"
3611
+ }),
3612
+ variant: "ghost"
3613
+ }
3614
+ );
3038
3615
  }
3039
- const { edit: metadata } = metadatas[field.name];
3040
- const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
3041
- return {
3042
- attribute,
3043
- disabled: !metadata.editable,
3044
- hint: metadata.description,
3045
- label: metadata.label ?? "",
3046
- name: field.name,
3047
- // @ts-expect-error – mainField does exist on the metadata for a relation.
3048
- mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
3049
- schemas,
3050
- components: components?.schemas ?? {}
3051
- }),
3052
- placeholder: metadata.placeholder ?? "",
3053
- required: attribute.required ?? false,
3054
- size: field.size,
3055
- unique: "unique" in attribute ? attribute.unique : false,
3056
- visible: metadata.visible ?? true,
3057
- type: attribute.type
3058
- };
3059
- }).filter((field) => field !== null)
3616
+ }
3060
3617
  );
3061
3618
  };
3062
- const formatListLayout = (data, {
3063
- schemas,
3064
- schema,
3065
- components
3066
- }) => {
3067
- const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
3068
- (acc, [attribute, metadata]) => {
3069
- return {
3070
- ...acc,
3071
- [attribute]: metadata.list
3072
- };
3073
- },
3074
- {}
3075
- );
3076
- const listAttributes = convertListLayoutToFieldLayouts(
3077
- data.contentType.layouts.list,
3078
- schema?.attributes,
3079
- listMetadatas,
3080
- { configurations: data.components, schemas: components },
3081
- schemas
3082
- );
3619
+ const EditAction = ({ documentId }) => {
3620
+ const navigate = reactRouterDom.useNavigate();
3621
+ const { formatMessage } = reactIntl.useIntl();
3622
+ const { canRead } = useDocumentRBAC("EditAction", ({ canRead: canRead2 }) => ({ canRead: canRead2 }));
3623
+ const { toggleNotification } = strapiAdmin.useNotification();
3624
+ const [{ query }] = strapiAdmin.useQueryParams();
3625
+ return {
3626
+ disabled: !canRead,
3627
+ icon: /* @__PURE__ */ jsxRuntime.jsx(StyledPencil, {}),
3628
+ label: formatMessage({
3629
+ id: "content-manager.actions.edit.label",
3630
+ defaultMessage: "Edit"
3631
+ }),
3632
+ position: "table-row",
3633
+ onClick: async () => {
3634
+ if (!documentId) {
3635
+ console.error(
3636
+ "You're trying to edit a document without an id, this is likely a bug with Strapi. Please open an issue."
3637
+ );
3638
+ toggleNotification({
3639
+ message: formatMessage({
3640
+ id: "content-manager.actions.edit.error",
3641
+ defaultMessage: "An error occurred while trying to edit the document."
3642
+ }),
3643
+ type: "danger"
3644
+ });
3645
+ return;
3646
+ }
3647
+ navigate({
3648
+ pathname: documentId,
3649
+ search: qs.stringify({
3650
+ plugins: query.plugins
3651
+ })
3652
+ });
3653
+ }
3654
+ };
3655
+ };
3656
+ EditAction.type = "edit";
3657
+ const StyledPencil = styledComponents.styled(Icons.Pencil)`
3658
+ path {
3659
+ fill: currentColor;
3660
+ }
3661
+ `;
3662
+ const CloneAction = ({ model, documentId }) => {
3663
+ const navigate = reactRouterDom.useNavigate();
3664
+ const { formatMessage } = reactIntl.useIntl();
3665
+ const { canCreate } = useDocumentRBAC("CloneAction", ({ canCreate: canCreate2 }) => ({ canCreate: canCreate2 }));
3666
+ const { toggleNotification } = strapiAdmin.useNotification();
3667
+ const { autoClone } = useDocumentActions();
3668
+ const [prohibitedFields, setProhibitedFields] = React__namespace.useState([]);
3083
3669
  return {
3084
- layout: listAttributes,
3085
- settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
3086
- metadatas: listMetadatas,
3087
- options: {
3088
- ...schema?.options,
3089
- ...schema?.pluginOptions,
3090
- ...data.contentType.options
3670
+ disabled: !canCreate,
3671
+ icon: /* @__PURE__ */ jsxRuntime.jsx(StyledDuplicate, {}),
3672
+ label: formatMessage({
3673
+ id: "content-manager.actions.clone.label",
3674
+ defaultMessage: "Duplicate"
3675
+ }),
3676
+ position: "table-row",
3677
+ onClick: async () => {
3678
+ if (!documentId) {
3679
+ console.error(
3680
+ "You're trying to clone a document in the table without an id, this is likely a bug with Strapi. Please open an issue."
3681
+ );
3682
+ toggleNotification({
3683
+ message: formatMessage({
3684
+ id: "content-manager.actions.clone.error",
3685
+ defaultMessage: "An error occurred while trying to clone the document."
3686
+ }),
3687
+ type: "danger"
3688
+ });
3689
+ return;
3690
+ }
3691
+ const res = await autoClone({ model, sourceId: documentId });
3692
+ if ("data" in res) {
3693
+ navigate(res.data.documentId);
3694
+ return true;
3695
+ }
3696
+ if (isBaseQueryError(res.error) && res.error.details && typeof res.error.details === "object" && "prohibitedFields" in res.error.details && Array.isArray(res.error.details.prohibitedFields)) {
3697
+ const prohibitedFields2 = res.error.details.prohibitedFields;
3698
+ setProhibitedFields(prohibitedFields2);
3699
+ }
3700
+ },
3701
+ dialog: {
3702
+ type: "modal",
3703
+ title: formatMessage({
3704
+ id: "content-manager.containers.list.autoCloneModal.header",
3705
+ defaultMessage: "Duplicate"
3706
+ }),
3707
+ content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
3708
+ footer: ({ onClose }) => {
3709
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", children: [
3710
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
3711
+ id: "cancel",
3712
+ defaultMessage: "Cancel"
3713
+ }) }),
3714
+ /* @__PURE__ */ jsxRuntime.jsx(
3715
+ designSystem.LinkButton,
3716
+ {
3717
+ tag: reactRouterDom.NavLink,
3718
+ to: {
3719
+ pathname: `clone/${documentId}`
3720
+ },
3721
+ children: formatMessage({
3722
+ id: "content-manager.containers.list.autoCloneModal.create",
3723
+ defaultMessage: "Create"
3724
+ })
3725
+ }
3726
+ )
3727
+ ] });
3728
+ }
3091
3729
  }
3092
3730
  };
3093
3731
  };
3094
- const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
3095
- return columns.map((name) => {
3096
- const attribute = attributes[name];
3097
- if (!attribute) {
3098
- return null;
3732
+ CloneAction.type = "clone";
3733
+ const StyledDuplicate = styledComponents.styled(Icons.Duplicate)`
3734
+ path {
3735
+ fill: currentColor;
3736
+ }
3737
+ `;
3738
+ const DEFAULT_TABLE_ROW_ACTIONS = [EditAction, CloneAction];
3739
+ class ContentManagerPlugin {
3740
+ /**
3741
+ * The following properties are the stored ones provided by any plugins registering with
3742
+ * the content-manager. The function calls however, need to be called at runtime in the
3743
+ * application, so instead we collate them and run them later with the complete list incl.
3744
+ * ones already registered & the context of the view.
3745
+ */
3746
+ bulkActions = [...DEFAULT_BULK_ACTIONS];
3747
+ documentActions = [
3748
+ ...DEFAULT_ACTIONS,
3749
+ ...DEFAULT_TABLE_ROW_ACTIONS,
3750
+ ...DEFAULT_HEADER_ACTIONS,
3751
+ HistoryAction
3752
+ ];
3753
+ editViewSidePanels = [ActionsPanel];
3754
+ headerActions = [];
3755
+ constructor() {
3756
+ }
3757
+ addEditViewSidePanel(panels) {
3758
+ if (Array.isArray(panels)) {
3759
+ this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
3760
+ } else if (typeof panels === "function") {
3761
+ this.editViewSidePanels = panels(this.editViewSidePanels);
3762
+ } else {
3763
+ throw new Error(
3764
+ `Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
3765
+ panels
3766
+ )}`
3767
+ );
3099
3768
  }
3100
- const metadata = metadatas[name];
3101
- const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
3769
+ }
3770
+ addDocumentAction(actions2) {
3771
+ if (Array.isArray(actions2)) {
3772
+ this.documentActions = [...this.documentActions, ...actions2];
3773
+ } else if (typeof actions2 === "function") {
3774
+ this.documentActions = actions2(this.documentActions);
3775
+ } else {
3776
+ throw new Error(
3777
+ `Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
3778
+ actions2
3779
+ )}`
3780
+ );
3781
+ }
3782
+ }
3783
+ addDocumentHeaderAction(actions2) {
3784
+ if (Array.isArray(actions2)) {
3785
+ this.headerActions = [...this.headerActions, ...actions2];
3786
+ } else if (typeof actions2 === "function") {
3787
+ this.headerActions = actions2(this.headerActions);
3788
+ } else {
3789
+ throw new Error(
3790
+ `Expected the \`actions\` passed to \`addDocumentHeaderAction\` to be an array or a function, but received ${getPrintableType(
3791
+ actions2
3792
+ )}`
3793
+ );
3794
+ }
3795
+ }
3796
+ addBulkAction(actions2) {
3797
+ if (Array.isArray(actions2)) {
3798
+ this.bulkActions = [...this.bulkActions, ...actions2];
3799
+ } else if (typeof actions2 === "function") {
3800
+ this.bulkActions = actions2(this.bulkActions);
3801
+ } else {
3802
+ throw new Error(
3803
+ `Expected the \`actions\` passed to \`addBulkAction\` to be an array or a function, but received ${getPrintableType(
3804
+ actions2
3805
+ )}`
3806
+ );
3807
+ }
3808
+ }
3809
+ get config() {
3102
3810
  return {
3103
- attribute,
3104
- label: metadata.label ?? "",
3105
- mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
3106
- schemas,
3107
- components: components?.schemas ?? {}
3108
- }),
3109
- name,
3110
- searchable: metadata.searchable ?? true,
3111
- sortable: metadata.sortable ?? true
3811
+ id: PLUGIN_ID,
3812
+ name: "Content Manager",
3813
+ injectionZones: INJECTION_ZONES,
3814
+ apis: {
3815
+ addBulkAction: this.addBulkAction.bind(this),
3816
+ addDocumentAction: this.addDocumentAction.bind(this),
3817
+ addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
3818
+ addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
3819
+ getBulkActions: () => this.bulkActions,
3820
+ getDocumentActions: () => this.documentActions,
3821
+ getEditViewSidePanels: () => this.editViewSidePanels,
3822
+ getHeaderActions: () => this.headerActions
3823
+ }
3112
3824
  };
3113
- }).filter((field) => field !== null);
3825
+ }
3826
+ }
3827
+ const getPrintableType = (value) => {
3828
+ const nativeType = typeof value;
3829
+ if (nativeType === "object") {
3830
+ if (value === null)
3831
+ return "null";
3832
+ if (Array.isArray(value))
3833
+ return "array";
3834
+ if (value instanceof Object && value.constructor.name !== "Object") {
3835
+ return value.constructor.name;
3836
+ }
3837
+ }
3838
+ return nativeType;
3839
+ };
3840
+ const initialState = {
3841
+ collectionTypeLinks: [],
3842
+ components: [],
3843
+ fieldSizes: {},
3844
+ models: [],
3845
+ singleTypeLinks: [],
3846
+ isLoading: true
3114
3847
  };
3848
+ const appSlice = toolkit.createSlice({
3849
+ name: "app",
3850
+ initialState,
3851
+ reducers: {
3852
+ setInitialData(state, action) {
3853
+ const {
3854
+ authorizedCollectionTypeLinks,
3855
+ authorizedSingleTypeLinks,
3856
+ components,
3857
+ contentTypeSchemas,
3858
+ fieldSizes
3859
+ } = action.payload;
3860
+ state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
3861
+ ({ isDisplayed }) => isDisplayed
3862
+ );
3863
+ state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
3864
+ state.components = components;
3865
+ state.models = contentTypeSchemas;
3866
+ state.fieldSizes = fieldSizes;
3867
+ state.isLoading = false;
3868
+ }
3869
+ }
3870
+ });
3871
+ const { actions, reducer: reducer$1 } = appSlice;
3872
+ const { setInitialData } = actions;
3873
+ const reducer = toolkit.combineReducers({
3874
+ app: reducer$1
3875
+ });
3115
3876
  const index = {
3116
3877
  register(app) {
3117
3878
  const cm = new ContentManagerPlugin();
3118
3879
  app.addReducers({
3119
- [contentManagerApi.reducerPath]: contentManagerApi.reducer,
3120
3880
  [PLUGIN_ID]: reducer
3121
3881
  });
3122
- app.addMiddlewares([() => contentManagerApi.middleware]);
3123
3882
  app.addMenuLink({
3124
3883
  to: PLUGIN_ID,
3125
3884
  icon: Icons.Feather,
@@ -3128,14 +3887,15 @@ const index = {
3128
3887
  defaultMessage: "Content Manager"
3129
3888
  },
3130
3889
  permissions: [],
3131
- Component: () => Promise.resolve().then(() => require("./layout-dBc7wN7L.js")).then((mod) => ({ default: mod.Layout }))
3890
+ Component: () => Promise.resolve().then(() => require("./layout-DEYBqgF1.js")).then((mod) => ({ default: mod.Layout })),
3891
+ position: 1
3132
3892
  });
3133
3893
  app.registerPlugin(cm.config);
3134
3894
  },
3135
3895
  async registerTrads({ locales }) {
3136
3896
  const importedTrads = await Promise.all(
3137
3897
  locales.map((locale) => {
3138
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-C-V1_90f.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-EUonQTon.js")), "./translations/eu.json": () => Promise.resolve().then(() => require("./eu-VDH-3ovk.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-B7kGGg3E.js")), "./translations/gu.json": () => Promise.resolve().then(() => require("./gu-BRmF601H.js")), "./translations/hi.json": () => Promise.resolve().then(() => require("./hi-CCJBptSq.js")), "./translations/hu.json": () => Promise.resolve().then(() => require("./hu-sNV_yLYy.js")), "./translations/id.json": () => Promise.resolve().then(() => require("./id-B5Ser98A.js")), "./translations/it.json": () => Promise.resolve().then(() => require("./it-DkBIs7vD.js")), "./translations/ja.json": () => Promise.resolve().then(() => require("./ja-CcFe8diO.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-woFZPmLk.js")), "./translations/ml.json": () => Promise.resolve().then(() => require("./ml-C2W8N8k1.js")), "./translations/ms.json": () => Promise.resolve().then(() => require("./ms-BuFotyP_.js")), "./translations/nl.json": () => Promise.resolve().then(() => require("./nl-bbEOHChV.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-uzwG-hk7.js")), "./translations/pt-BR.json": () => Promise.resolve().then(() => require("./pt-BR-BiOz37D9.js")), "./translations/pt.json": () => Promise.resolve().then(() => require("./pt-CeXQuq50.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BT3ybNny.js")), "./translations/sa.json": () => Promise.resolve().then(() => require("./sa-CcvkYInH.js")), "./translations/sk.json": () => Promise.resolve().then(() => require("./sk-CvY09Xjv.js")), "./translations/sv.json": () => Promise.resolve().then(() => require("./sv-MYDuzgvT.js")), "./translations/th.json": () => Promise.resolve().then(() => require("./th-D9_GfAjc.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-D9UH-O_R.js")), "./translations/uk.json": () => Promise.resolve().then(() => require("./uk-C8EiqJY7.js")), "./translations/vi.json": () => Promise.resolve().then(() => require("./vi-CJlYDheJ.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-9kOncHGw.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CQQfszqR.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
3898
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-fbKQxLGn.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-EUonQTon.js")), "./translations/eu.json": () => Promise.resolve().then(() => require("./eu-VDH-3ovk.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-B7kGGg3E.js")), "./translations/gu.json": () => Promise.resolve().then(() => require("./gu-BRmF601H.js")), "./translations/hi.json": () => Promise.resolve().then(() => require("./hi-CCJBptSq.js")), "./translations/hu.json": () => Promise.resolve().then(() => require("./hu-sNV_yLYy.js")), "./translations/id.json": () => Promise.resolve().then(() => require("./id-B5Ser98A.js")), "./translations/it.json": () => Promise.resolve().then(() => require("./it-DkBIs7vD.js")), "./translations/ja.json": () => Promise.resolve().then(() => require("./ja-CcFe8diO.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-woFZPmLk.js")), "./translations/ml.json": () => Promise.resolve().then(() => require("./ml-C2W8N8k1.js")), "./translations/ms.json": () => Promise.resolve().then(() => require("./ms-BuFotyP_.js")), "./translations/nl.json": () => Promise.resolve().then(() => require("./nl-bbEOHChV.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-uzwG-hk7.js")), "./translations/pt-BR.json": () => Promise.resolve().then(() => require("./pt-BR-BiOz37D9.js")), "./translations/pt.json": () => Promise.resolve().then(() => require("./pt-CeXQuq50.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BT3ybNny.js")), "./translations/sa.json": () => Promise.resolve().then(() => require("./sa-CcvkYInH.js")), "./translations/sk.json": () => Promise.resolve().then(() => require("./sk-CvY09Xjv.js")), "./translations/sv.json": () => Promise.resolve().then(() => require("./sv-MYDuzgvT.js")), "./translations/th.json": () => Promise.resolve().then(() => require("./th-D9_GfAjc.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-D9UH-O_R.js")), "./translations/uk.json": () => Promise.resolve().then(() => require("./uk-C8EiqJY7.js")), "./translations/vi.json": () => Promise.resolve().then(() => require("./vi-CJlYDheJ.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-9kOncHGw.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CQQfszqR.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
3139
3899
  return {
3140
3900
  data: prefixPluginTranslations(data, PLUGIN_ID),
3141
3901
  locale
@@ -3152,6 +3912,7 @@ const index = {
3152
3912
  }
3153
3913
  };
3154
3914
  exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
3915
+ exports.BulkActionsRenderer = BulkActionsRenderer;
3155
3916
  exports.COLLECTION_TYPES = COLLECTION_TYPES;
3156
3917
  exports.CREATOR_FIELDS = CREATOR_FIELDS;
3157
3918
  exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
@@ -3192,4 +3953,4 @@ exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
3192
3953
  exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
3193
3954
  exports.useGetInitialDataQuery = useGetInitialDataQuery;
3194
3955
  exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
3195
- //# sourceMappingURL=index-X_2tafck.js.map
3956
+ //# sourceMappingURL=index-BZoNZMXL.js.map