@strapi/content-manager 5.0.0-beta.7 → 5.0.0-beta.8

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 (143) hide show
  1. package/dist/_chunks/{ComponentConfigurationPage-uTMkLI60.mjs → ComponentConfigurationPage-CuWgXugY.mjs} +3 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-uTMkLI60.mjs.map → ComponentConfigurationPage-CuWgXugY.mjs.map} +1 -1
  3. package/dist/_chunks/{ComponentConfigurationPage-DMq0wvcL.js → ComponentConfigurationPage-by0e_kNd.js} +3 -3
  4. package/dist/_chunks/{ComponentConfigurationPage-DMq0wvcL.js.map → ComponentConfigurationPage-by0e_kNd.js.map} +1 -1
  5. package/dist/_chunks/{ComponentIcon-BBQsYCVn.js → ComponentIcon-BXdiCGQp.js} +8 -2
  6. package/dist/_chunks/ComponentIcon-BXdiCGQp.js.map +1 -0
  7. package/dist/_chunks/{ComponentIcon-BOFnK76n.mjs → ComponentIcon-u4bIXTFY.mjs} +9 -3
  8. package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -0
  9. package/dist/_chunks/{EditConfigurationPage-BFpQwwbc.js → EditConfigurationPage-CqBeCPGH.js} +3 -3
  10. package/dist/_chunks/{EditConfigurationPage-BFpQwwbc.js.map → EditConfigurationPage-CqBeCPGH.js.map} +1 -1
  11. package/dist/_chunks/{EditConfigurationPage-B2HhCh-b.mjs → EditConfigurationPage-DbI4KMyz.mjs} +3 -3
  12. package/dist/_chunks/{EditConfigurationPage-B2HhCh-b.mjs.map → EditConfigurationPage-DbI4KMyz.mjs.map} +1 -1
  13. package/dist/_chunks/{EditViewPage-CXXue16T.js → EditViewPage-ChgloMyO.js} +5 -5
  14. package/dist/_chunks/{EditViewPage-CXXue16T.js.map → EditViewPage-ChgloMyO.js.map} +1 -1
  15. package/dist/_chunks/{EditViewPage-BVIrgjyG.mjs → EditViewPage-dFPBya9U.mjs} +5 -5
  16. package/dist/_chunks/{EditViewPage-BVIrgjyG.mjs.map → EditViewPage-dFPBya9U.mjs.map} +1 -1
  17. package/dist/_chunks/{Field-0_2h1vuK.mjs → Field-C1nUKcdS.mjs} +240 -357
  18. package/dist/_chunks/Field-C1nUKcdS.mjs.map +1 -0
  19. package/dist/_chunks/{Field-ZgzKlgxR.js → Field-dLk-vgLL.js} +240 -357
  20. package/dist/_chunks/Field-dLk-vgLL.js.map +1 -0
  21. package/dist/_chunks/{Form-DgTc2qkx.js → Form-CbXtmHC_.js} +9 -6
  22. package/dist/_chunks/Form-CbXtmHC_.js.map +1 -0
  23. package/dist/_chunks/{Form-B7TUnQDd.mjs → Form-DOlpi7Js.mjs} +9 -6
  24. package/dist/_chunks/Form-DOlpi7Js.mjs.map +1 -0
  25. package/dist/_chunks/{History-Dug_4HIA.mjs → History-BFNUAiGc.mjs} +8 -8
  26. package/dist/_chunks/{History-Dug_4HIA.mjs.map → History-BFNUAiGc.mjs.map} +1 -1
  27. package/dist/_chunks/{History-DtHjQuqM.js → History-BjDfohBr.js} +8 -8
  28. package/dist/_chunks/{History-DtHjQuqM.js.map → History-BjDfohBr.js.map} +1 -1
  29. package/dist/_chunks/{ListConfigurationPage-CmEeNg6T.mjs → ListConfigurationPage-DDi0KqFm.mjs} +2 -2
  30. package/dist/_chunks/{ListConfigurationPage-CmEeNg6T.mjs.map → ListConfigurationPage-DDi0KqFm.mjs.map} +1 -1
  31. package/dist/_chunks/{ListConfigurationPage-BuSdTjfa.js → ListConfigurationPage-IQBgWTaa.js} +2 -2
  32. package/dist/_chunks/{ListConfigurationPage-BuSdTjfa.js.map → ListConfigurationPage-IQBgWTaa.js.map} +1 -1
  33. package/dist/_chunks/{ListViewPage-Dsoa3wEA.mjs → ListViewPage-BPjljUsH.mjs} +8 -16
  34. package/dist/_chunks/ListViewPage-BPjljUsH.mjs.map +1 -0
  35. package/dist/_chunks/{ListViewPage-CExWwa4S.js → ListViewPage-CZYGqlvF.js} +11 -18
  36. package/dist/_chunks/ListViewPage-CZYGqlvF.js.map +1 -0
  37. package/dist/_chunks/{NoContentTypePage-DCUL8gVi.js → NoContentTypePage-BOAI6VZ1.js} +2 -2
  38. package/dist/_chunks/{NoContentTypePage-DCUL8gVi.js.map → NoContentTypePage-BOAI6VZ1.js.map} +1 -1
  39. package/dist/_chunks/{NoContentTypePage-Dh38hBXB.mjs → NoContentTypePage-DaWw67K-.mjs} +2 -2
  40. package/dist/_chunks/{NoContentTypePage-Dh38hBXB.mjs.map → NoContentTypePage-DaWw67K-.mjs.map} +1 -1
  41. package/dist/_chunks/{NoPermissionsPage-Dt2O40ey.mjs → NoPermissionsPage-CZrJH00p.mjs} +2 -2
  42. package/dist/_chunks/{NoPermissionsPage-Dt2O40ey.mjs.map → NoPermissionsPage-CZrJH00p.mjs.map} +1 -1
  43. package/dist/_chunks/{NoPermissionsPage-BK-XCpIy.js → NoPermissionsPage-cYEtLc_e.js} +2 -2
  44. package/dist/_chunks/{NoPermissionsPage-BK-XCpIy.js.map → NoPermissionsPage-cYEtLc_e.js.map} +1 -1
  45. package/dist/_chunks/{Relations-DZyjWZHl.mjs → Relations-DTowyge2.mjs} +7 -5
  46. package/dist/_chunks/{Relations-DZyjWZHl.mjs.map → Relations-DTowyge2.mjs.map} +1 -1
  47. package/dist/_chunks/{Relations-CNypkp-g.js → Relations-DU6B7irU.js} +7 -5
  48. package/dist/_chunks/{Relations-CNypkp-g.js.map → Relations-DU6B7irU.js.map} +1 -1
  49. package/dist/_chunks/{en-C-V1_90f.js → en-DTULi5-d.js} +3 -1
  50. package/dist/_chunks/{en-C-V1_90f.js.map → en-DTULi5-d.js.map} +1 -1
  51. package/dist/_chunks/{en-MBPul9Su.mjs → en-GCOTL6jR.mjs} +3 -1
  52. package/dist/_chunks/{en-MBPul9Su.mjs.map → en-GCOTL6jR.mjs.map} +1 -1
  53. package/dist/_chunks/{index-B3c-4it4.mjs → index-BaGHmIir.mjs} +488 -196
  54. package/dist/_chunks/index-BaGHmIir.mjs.map +1 -0
  55. package/dist/_chunks/{index-DFK7LwDW.js → index-CCJeB7Rw.js} +480 -188
  56. package/dist/_chunks/index-CCJeB7Rw.js.map +1 -0
  57. package/dist/_chunks/{layout-B5cm7cZj.mjs → layout-BinjszSQ.mjs} +6 -6
  58. package/dist/_chunks/layout-BinjszSQ.mjs.map +1 -0
  59. package/dist/_chunks/{layout-DLih5-_W.js → layout-ni_L9kT1.js} +6 -6
  60. package/dist/_chunks/layout-ni_L9kT1.js.map +1 -0
  61. package/dist/_chunks/{relations-CTvkuINQ.js → relations-CeJAJc5I.js} +2 -2
  62. package/dist/_chunks/{relations-CTvkuINQ.js.map → relations-CeJAJc5I.js.map} +1 -1
  63. package/dist/_chunks/{relations-BZkrMa2z.mjs → relations-c91ji5eR.mjs} +2 -2
  64. package/dist/_chunks/{relations-BZkrMa2z.mjs.map → relations-c91ji5eR.mjs.map} +1 -1
  65. package/dist/_chunks/usePrev-B9w_-eYc.js +15 -0
  66. package/dist/_chunks/usePrev-B9w_-eYc.js.map +1 -0
  67. package/dist/_chunks/usePrev-DH6iah0A.mjs +16 -0
  68. package/dist/_chunks/usePrev-DH6iah0A.mjs.map +1 -0
  69. package/dist/admin/index.js +2 -1
  70. package/dist/admin/index.js.map +1 -1
  71. package/dist/admin/index.mjs +5 -4
  72. package/dist/admin/src/components/ComponentIcon.d.ts +6 -3
  73. package/dist/admin/src/content-manager.d.ts +3 -3
  74. package/dist/admin/src/exports.d.ts +1 -0
  75. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  76. package/dist/admin/src/hooks/useDocument.d.ts +5 -8
  77. package/dist/admin/src/hooks/useDocumentActions.d.ts +24 -3
  78. package/dist/admin/src/hooks/useDocumentLayout.d.ts +1 -1
  79. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +3 -1
  80. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +3 -3
  81. package/dist/admin/src/pages/EditView/components/FormInputs/Component/Input.d.ts +2 -2
  82. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.d.ts +3 -5
  83. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +1 -1
  84. package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +2 -15
  85. package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +2 -2
  86. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.d.ts +2 -2
  87. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +56 -35
  88. package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -10
  89. package/dist/admin/src/services/api.d.ts +2 -3
  90. package/dist/admin/src/services/components.d.ts +2 -2
  91. package/dist/admin/src/services/contentTypes.d.ts +5 -5
  92. package/dist/admin/src/services/documents.d.ts +29 -17
  93. package/dist/admin/src/services/init.d.ts +2 -2
  94. package/dist/admin/src/services/relations.d.ts +3 -3
  95. package/dist/admin/src/services/uid.d.ts +3 -3
  96. package/dist/admin/src/utils/api.d.ts +4 -17
  97. package/dist/admin/src/utils/validation.d.ts +1 -6
  98. package/dist/server/index.js +232 -116
  99. package/dist/server/index.js.map +1 -1
  100. package/dist/server/index.mjs +234 -118
  101. package/dist/server/index.mjs.map +1 -1
  102. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  103. package/dist/server/src/controllers/single-types.d.ts.map +1 -1
  104. package/dist/server/src/controllers/utils/metadata.d.ts +8 -0
  105. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -0
  106. package/dist/server/src/controllers/validation/dimensions.d.ts +9 -0
  107. package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -0
  108. package/dist/server/src/history/services/history.d.ts.map +1 -1
  109. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  110. package/dist/server/src/index.d.ts +12 -33
  111. package/dist/server/src/index.d.ts.map +1 -1
  112. package/dist/server/src/services/document-manager.d.ts +6 -6
  113. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  114. package/dist/server/src/services/document-metadata.d.ts +8 -29
  115. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  116. package/dist/server/src/services/index.d.ts +12 -33
  117. package/dist/server/src/services/index.d.ts.map +1 -1
  118. package/dist/server/src/services/utils/populate.d.ts +8 -1
  119. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  120. package/dist/shared/contracts/collection-types.d.ts +11 -5
  121. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  122. package/dist/shared/contracts/relations.d.ts +2 -2
  123. package/dist/shared/contracts/relations.d.ts.map +1 -1
  124. package/package.json +11 -11
  125. package/dist/_chunks/ComponentIcon-BBQsYCVn.js.map +0 -1
  126. package/dist/_chunks/ComponentIcon-BOFnK76n.mjs.map +0 -1
  127. package/dist/_chunks/Field-0_2h1vuK.mjs.map +0 -1
  128. package/dist/_chunks/Field-ZgzKlgxR.js.map +0 -1
  129. package/dist/_chunks/Form-B7TUnQDd.mjs.map +0 -1
  130. package/dist/_chunks/Form-DgTc2qkx.js.map +0 -1
  131. package/dist/_chunks/ListViewPage-CExWwa4S.js.map +0 -1
  132. package/dist/_chunks/ListViewPage-Dsoa3wEA.mjs.map +0 -1
  133. package/dist/_chunks/index-B3c-4it4.mjs.map +0 -1
  134. package/dist/_chunks/index-DFK7LwDW.js.map +0 -1
  135. package/dist/_chunks/layout-B5cm7cZj.mjs.map +0 -1
  136. package/dist/_chunks/layout-DLih5-_W.js.map +0 -1
  137. package/dist/_chunks/urls-CbOsUOoW.mjs +0 -7
  138. package/dist/_chunks/urls-CbOsUOoW.mjs.map +0 -1
  139. package/dist/_chunks/urls-DzZya_gm.js +0 -6
  140. package/dist/_chunks/urls-DzZya_gm.js.map +0 -1
  141. package/dist/admin/src/pages/ListView/components/BulkActions/PublishAction.d.ts +0 -31
  142. package/dist/server/src/controllers/utils/dimensions.d.ts +0 -5
  143. package/dist/server/src/controllers/utils/dimensions.d.ts.map +0 -1
@@ -1,6 +1,6 @@
1
- import { ClockCounterClockwise, CrossCircle, More, WarningCircle, Cog, Pencil, Trash, ChevronRight, Duplicate, Feather } from "@strapi/icons";
1
+ import { ClockCounterClockwise, CrossCircle, More, WarningCircle, ListPlus, Pencil, Trash, Check, ChevronRight, Duplicate, Feather } from "@strapi/icons";
2
2
  import { jsx, Fragment, jsxs } from "react/jsx-runtime";
3
- import { useStrapiApp, useQueryParams, createContext, useAuth, useRBAC, Page, getFetchClient, isFetchError, translatedErrors, useNotification, useAPIErrorHandler, useTracking, useForm, BackButton, DescriptionComponentRenderer } from "@strapi/admin/strapi-admin";
3
+ import { useStrapiApp, useQueryParams, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useTracking, useForm, BackButton, DescriptionComponentRenderer, useTable } from "@strapi/admin/strapi-admin";
4
4
  import { stringify } from "qs";
5
5
  import { useIntl } from "react-intl";
6
6
  import { useNavigate, useParams, Navigate, useMatch, NavLink } from "react-router-dom";
@@ -10,7 +10,6 @@ import { Menu, VisuallyHidden, Flex, Typography, Dialog, DialogBody, DialogFoote
10
10
  import { styled } from "styled-components";
11
11
  import * as yup from "yup";
12
12
  import { ValidationError } from "yup";
13
- import { createApi } from "@reduxjs/toolkit/query/react";
14
13
  import pipe from "lodash/fp/pipe";
15
14
  import { intervalToDuration, isPast } from "date-fns";
16
15
  import { createSlice, combineReducers } from "@reduxjs/toolkit";
@@ -156,9 +155,8 @@ const DocumentRBAC = ({ children, permissions }) => {
156
155
  const name = removeNumericalStrings(fieldName.split("."));
157
156
  const componentFieldNames = fieldsUserCanAction.filter((field) => field.split(".").length > 1);
158
157
  if (fieldType === "component") {
159
- const componentOrDynamicZoneFields = componentFieldNames.map((field) => field.split("."));
160
- return componentOrDynamicZoneFields.some((field) => {
161
- return field.includes(fieldName);
158
+ return componentFieldNames.some((field) => {
159
+ return field.includes(name.join("."));
162
160
  });
163
161
  }
164
162
  if (name.length > 1) {
@@ -188,92 +186,8 @@ const extractAndDedupeFields = (permissions = []) => permissions.flatMap((permis
188
186
  (field, index2, arr) => arr.indexOf(field) === index2 && typeof field === "string"
189
187
  );
190
188
  const removeNumericalStrings = (arr) => arr.filter((item) => isNaN(Number(item)));
191
- const buildValidParams = (query) => {
192
- if (!query)
193
- return query;
194
- const { plugins: _, ...validQueryParams } = {
195
- ...query,
196
- ...Object.values(query?.plugins ?? {}).reduce(
197
- (acc, current) => Object.assign(acc, current),
198
- {}
199
- )
200
- };
201
- if ("_q" in validQueryParams) {
202
- validQueryParams._q = encodeURIComponent(validQueryParams._q);
203
- }
204
- return validQueryParams;
205
- };
206
- const fetchBaseQuery = () => async (query, { signal }) => {
207
- try {
208
- const { get, post, del, put } = getFetchClient();
209
- if (typeof query === "string") {
210
- const result = await get(query, {
211
- signal
212
- });
213
- return { data: result.data };
214
- } else {
215
- const { url, method = "GET", data, config } = query;
216
- if (method === "POST") {
217
- const result2 = await post(url, data, {
218
- ...config,
219
- signal
220
- });
221
- return { data: result2.data };
222
- }
223
- if (method === "DELETE") {
224
- const result2 = await del(url, {
225
- ...config,
226
- signal
227
- });
228
- return { data: result2.data };
229
- }
230
- if (method === "PUT") {
231
- const result2 = await put(url, data, {
232
- ...config,
233
- signal
234
- });
235
- return { data: result2.data };
236
- }
237
- const result = await get(url, {
238
- ...config,
239
- signal
240
- });
241
- return { data: result.data };
242
- }
243
- } catch (err) {
244
- if (isFetchError(err)) {
245
- if (typeof err.response?.data === "object" && err.response?.data !== null && "error" in err.response?.data) {
246
- return { data: void 0, error: err.response?.data.error };
247
- } else {
248
- return {
249
- data: void 0,
250
- error: {
251
- name: "UnknownError",
252
- message: "There was an unknown error response from the API",
253
- details: err.response,
254
- status: err.status
255
- }
256
- };
257
- }
258
- }
259
- const error = err;
260
- return {
261
- data: void 0,
262
- error: {
263
- name: error.name,
264
- message: error.message,
265
- stack: error.stack
266
- }
267
- };
268
- }
269
- };
270
- const isBaseQueryError = (error) => {
271
- return error.name !== void 0;
272
- };
273
- const contentManagerApi = createApi({
274
- reducerPath: "contentManagerApi",
275
- baseQuery: fetchBaseQuery(),
276
- tagTypes: [
189
+ const contentManagerApi = adminApi.enhanceEndpoints({
190
+ addTagTypes: [
277
191
  "ComponentConfiguration",
278
192
  "ContentTypesConfiguration",
279
193
  "ContentTypeSettings",
@@ -281,8 +195,7 @@ const contentManagerApi = createApi({
281
195
  "InitialData",
282
196
  "HistoryVersion",
283
197
  "Relations"
284
- ],
285
- endpoints: () => ({})
198
+ ]
286
199
  });
287
200
  const documentApi = contentManagerApi.injectEndpoints({
288
201
  endpoints: (builder) => ({
@@ -338,12 +251,15 @@ const documentApi = contentManagerApi.injectEndpoints({
338
251
  ]
339
252
  }),
340
253
  deleteManyDocuments: builder.mutation({
341
- query: ({ model, ...body }) => ({
254
+ query: ({ model, params, ...body }) => ({
342
255
  url: `/content-manager/collection-types/${model}/actions/bulkDelete`,
343
256
  method: "POST",
344
- data: body
257
+ data: body,
258
+ config: {
259
+ params
260
+ }
345
261
  }),
346
- invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
262
+ invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
347
263
  }),
348
264
  discardDocument: builder.mutation({
349
265
  query: ({ collectionType, model, documentId, params }) => ({
@@ -454,10 +370,13 @@ const documentApi = contentManagerApi.injectEndpoints({
454
370
  }
455
371
  }),
456
372
  publishManyDocuments: builder.mutation({
457
- query: ({ model, ...body }) => ({
373
+ query: ({ model, params, ...body }) => ({
458
374
  url: `/content-manager/collection-types/${model}/actions/bulkPublish`,
459
375
  method: "POST",
460
- data: body
376
+ data: body,
377
+ config: {
378
+ params
379
+ }
461
380
  }),
462
381
  invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
463
382
  }),
@@ -499,10 +418,13 @@ const documentApi = contentManagerApi.injectEndpoints({
499
418
  }
500
419
  }),
501
420
  unpublishManyDocuments: builder.mutation({
502
- query: ({ model, ...body }) => ({
421
+ query: ({ model, params, ...body }) => ({
503
422
  url: `/content-manager/collection-types/${model}/actions/bulkUnpublish`,
504
423
  method: "POST",
505
- data: body
424
+ data: body,
425
+ config: {
426
+ params
427
+ }
506
428
  }),
507
429
  invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
508
430
  })
@@ -526,6 +448,24 @@ const {
526
448
  useUnpublishDocumentMutation,
527
449
  useUnpublishManyDocumentsMutation
528
450
  } = documentApi;
451
+ const buildValidParams = (query) => {
452
+ if (!query)
453
+ return query;
454
+ const { plugins: _, ...validQueryParams } = {
455
+ ...query,
456
+ ...Object.values(query?.plugins ?? {}).reduce(
457
+ (acc, current) => Object.assign(acc, current),
458
+ {}
459
+ )
460
+ };
461
+ if ("_q" in validQueryParams) {
462
+ validQueryParams._q = encodeURIComponent(validQueryParams._q);
463
+ }
464
+ return validQueryParams;
465
+ };
466
+ const isBaseQueryError = (error) => {
467
+ return error.name !== void 0;
468
+ };
529
469
  const createYupSchema = (attributes = {}, components = {}) => {
530
470
  const createModelSchema = (attributes2) => yup.object().shape(
531
471
  Object.entries(attributes2).reduce((acc, [name, attribute]) => {
@@ -565,10 +505,14 @@ const createYupSchema = (attributes = {}, components = {}) => {
565
505
  yup.array().of(
566
506
  yup.lazy(
567
507
  (data) => {
568
- const { attributes: attributes3 } = components[data.__component];
569
- return yup.object().shape({
508
+ const attributes3 = components?.[data?.__component]?.attributes;
509
+ const validation = yup.object().shape({
570
510
  __component: yup.string().required().oneOf(Object.keys(components))
571
- }).nullable(false).concat(createModelSchema(attributes3));
511
+ }).nullable(false);
512
+ if (!attributes3) {
513
+ return validation;
514
+ }
515
+ return validation.concat(createModelSchema(attributes3));
572
516
  }
573
517
  )
574
518
  )
@@ -578,11 +522,25 @@ const createYupSchema = (attributes = {}, components = {}) => {
578
522
  return {
579
523
  ...acc,
580
524
  [name]: transformSchema(
581
- yup.array().of(
582
- yup.object().shape({
583
- id: yup.string().required()
584
- })
585
- )
525
+ yup.lazy((value) => {
526
+ if (!value) {
527
+ return yup.mixed().nullable(true);
528
+ } else if (Array.isArray(value)) {
529
+ return yup.array().of(
530
+ yup.object().shape({
531
+ id: yup.string().required()
532
+ })
533
+ );
534
+ } else if (typeof value === "object") {
535
+ return yup.object();
536
+ } else {
537
+ return yup.mixed().test(
538
+ "type-error",
539
+ "Relation values must be either null, an array of objects with {id} or an object.",
540
+ () => false
541
+ );
542
+ }
543
+ })
586
544
  )
587
545
  };
588
546
  default:
@@ -647,7 +605,12 @@ const addRequiredValidation = (attribute) => (schema) => {
647
605
  defaultMessage: "This field is required."
648
606
  });
649
607
  }
650
- return schema.nullable();
608
+ return schema?.nullable ? schema.nullable() : (
609
+ // In some cases '.nullable' will not be available on the schema.
610
+ // e.g. when the schema has been built using yup.lazy (e.g. for relations).
611
+ // In these cases we should just return the schema as it is.
612
+ schema
613
+ );
651
614
  };
652
615
  const addMinLengthValidation = (attribute) => (schema) => {
653
616
  if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
@@ -719,24 +682,6 @@ const addRegexValidation = (attribute) => (schema) => {
719
682
  }
720
683
  return schema;
721
684
  };
722
- const extractValuesFromYupError = (errorType, errorParams) => {
723
- if (!errorType || !errorParams) {
724
- return {};
725
- }
726
- return {
727
- [errorType]: errorParams[errorType]
728
- };
729
- };
730
- const getInnerErrors = (error) => (error?.inner || []).reduce((acc, currentError) => {
731
- if (currentError.path) {
732
- acc[currentError.path.split("[").join(".").split("]").join("")] = {
733
- id: currentError.message,
734
- defaultMessage: currentError.message,
735
- values: extractValuesFromYupError(currentError?.type, currentError?.params)
736
- };
737
- }
738
- return acc;
739
- }, {});
740
685
  const initApi = contentManagerApi.injectEndpoints({
741
686
  endpoints: (builder) => ({
742
687
  getInitialData: builder.query({
@@ -750,27 +695,20 @@ const { useGetInitialDataQuery } = initApi;
750
695
  const useContentTypeSchema = (model) => {
751
696
  const { toggleNotification } = useNotification();
752
697
  const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
753
- const { components, contentType, contentTypes, error, isLoading, isFetching } = useGetInitialDataQuery(void 0, {
754
- selectFromResult: (res) => {
755
- const contentType2 = res.data?.contentTypes.find((ct) => ct.uid === model);
756
- const componentsByKey = res.data?.components.reduce(
757
- (acc, component) => {
758
- acc[component.uid] = component;
759
- return acc;
760
- },
761
- {}
762
- );
763
- const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
764
- return {
765
- isLoading: res.isLoading,
766
- isFetching: res.isFetching,
767
- error: res.error,
768
- components: Object.keys(components2).length === 0 ? void 0 : components2,
769
- contentType: contentType2,
770
- contentTypes: res.data?.contentTypes ?? []
771
- };
772
- }
773
- });
698
+ const { data, error, isLoading, isFetching } = useGetInitialDataQuery(void 0);
699
+ const { components, contentType, contentTypes } = React.useMemo(() => {
700
+ const contentType2 = data?.contentTypes.find((ct) => ct.uid === model);
701
+ const componentsByKey = data?.components.reduce((acc, component) => {
702
+ acc[component.uid] = component;
703
+ return acc;
704
+ }, {});
705
+ const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
706
+ return {
707
+ components: Object.keys(components2).length === 0 ? void 0 : components2,
708
+ contentType: contentType2,
709
+ contentTypes: data?.contentTypes ?? []
710
+ };
711
+ }, [model, data]);
774
712
  React.useEffect(() => {
775
713
  if (error) {
776
714
  toggleNotification({
@@ -853,7 +791,7 @@ const useDocument = (args, opts) => {
853
791
  return null;
854
792
  } catch (error2) {
855
793
  if (error2 instanceof ValidationError) {
856
- return getInnerErrors(error2);
794
+ return getYupValidationErrors(error2);
857
795
  }
858
796
  throw error2;
859
797
  }
@@ -949,6 +887,44 @@ const useDocumentActions = () => {
949
887
  },
950
888
  [trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
951
889
  );
890
+ const [deleteManyDocuments] = useDeleteManyDocumentsMutation();
891
+ const deleteMany = React.useCallback(
892
+ async ({ model, documentIds, params }) => {
893
+ try {
894
+ trackUsage("willBulkDeleteEntries");
895
+ const res = await deleteManyDocuments({
896
+ model,
897
+ documentIds,
898
+ params
899
+ });
900
+ if ("error" in res) {
901
+ toggleNotification({
902
+ type: "danger",
903
+ message: formatAPIError(res.error)
904
+ });
905
+ return { error: res.error };
906
+ }
907
+ toggleNotification({
908
+ type: "success",
909
+ title: formatMessage({
910
+ id: getTranslation("success.records.delete"),
911
+ defaultMessage: "Successfully deleted."
912
+ }),
913
+ message: ""
914
+ });
915
+ trackUsage("didBulkDeleteEntries");
916
+ return res.data;
917
+ } catch (err) {
918
+ toggleNotification({
919
+ type: "danger",
920
+ message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
921
+ });
922
+ trackUsage("didNotBulkDeleteEntries");
923
+ throw err;
924
+ }
925
+ },
926
+ [trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
927
+ );
952
928
  const [discardDocument] = useDiscardDocumentMutation();
953
929
  const discard = React.useCallback(
954
930
  async ({ collectionType, model, documentId }) => {
@@ -1018,6 +994,43 @@ const useDocumentActions = () => {
1018
994
  },
1019
995
  [trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
1020
996
  );
997
+ const [publishManyDocuments] = usePublishManyDocumentsMutation();
998
+ const publishMany = React.useCallback(
999
+ async ({ model, documentIds, params }) => {
1000
+ try {
1001
+ const res = await publishManyDocuments({
1002
+ model,
1003
+ documentIds,
1004
+ params
1005
+ });
1006
+ if ("error" in res) {
1007
+ toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1008
+ return { error: res.error };
1009
+ }
1010
+ toggleNotification({
1011
+ type: "success",
1012
+ message: formatMessage({
1013
+ id: getTranslation("success.record.publish"),
1014
+ defaultMessage: "Published document"
1015
+ })
1016
+ });
1017
+ return res.data;
1018
+ } catch (err) {
1019
+ toggleNotification({
1020
+ type: "danger",
1021
+ message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1022
+ });
1023
+ throw err;
1024
+ }
1025
+ },
1026
+ [
1027
+ // trackUsage,
1028
+ publishManyDocuments,
1029
+ toggleNotification,
1030
+ formatMessage,
1031
+ formatAPIError
1032
+ ]
1033
+ );
1021
1034
  const [updateDocument] = useUpdateDocumentMutation();
1022
1035
  const update = React.useCallback(
1023
1036
  async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
@@ -1092,6 +1105,41 @@ const useDocumentActions = () => {
1092
1105
  },
1093
1106
  [trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
1094
1107
  );
1108
+ const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
1109
+ const unpublishMany = React.useCallback(
1110
+ async ({ model, documentIds, params }) => {
1111
+ try {
1112
+ trackUsage("willBulkUnpublishEntries");
1113
+ const res = await unpublishManyDocuments({
1114
+ model,
1115
+ documentIds,
1116
+ params
1117
+ });
1118
+ if ("error" in res) {
1119
+ toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1120
+ return { error: res.error };
1121
+ }
1122
+ trackUsage("didBulkUnpublishEntries");
1123
+ toggleNotification({
1124
+ type: "success",
1125
+ title: formatMessage({
1126
+ id: getTranslation("success.records.unpublish"),
1127
+ defaultMessage: "Successfully unpublished."
1128
+ }),
1129
+ message: ""
1130
+ });
1131
+ return res.data;
1132
+ } catch (err) {
1133
+ toggleNotification({
1134
+ type: "danger",
1135
+ message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1136
+ });
1137
+ trackUsage("didNotBulkUnpublishEntries");
1138
+ throw err;
1139
+ }
1140
+ },
1141
+ [trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
1142
+ );
1095
1143
  const [createDocument] = useCreateDocumentMutation();
1096
1144
  const create = React.useCallback(
1097
1145
  async ({ model, params }, data, trackerProperty) => {
@@ -1205,15 +1253,18 @@ const useDocumentActions = () => {
1205
1253
  clone,
1206
1254
  create,
1207
1255
  delete: _delete,
1256
+ deleteMany,
1208
1257
  discard,
1209
1258
  getDocument,
1210
1259
  publish,
1260
+ publishMany,
1211
1261
  unpublish,
1262
+ unpublishMany,
1212
1263
  update
1213
1264
  };
1214
1265
  };
1215
1266
  const ProtectedHistoryPage = lazy(
1216
- () => import("./History-Dug_4HIA.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1267
+ () => import("./History-BFNUAiGc.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1217
1268
  );
1218
1269
  const routes$1 = [
1219
1270
  {
@@ -1226,31 +1277,31 @@ const routes$1 = [
1226
1277
  }
1227
1278
  ];
1228
1279
  const ProtectedEditViewPage = lazy(
1229
- () => import("./EditViewPage-BVIrgjyG.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1280
+ () => import("./EditViewPage-dFPBya9U.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1230
1281
  );
1231
1282
  const ProtectedListViewPage = lazy(
1232
- () => import("./ListViewPage-Dsoa3wEA.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1283
+ () => import("./ListViewPage-BPjljUsH.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1233
1284
  );
1234
1285
  const ProtectedListConfiguration = lazy(
1235
- () => import("./ListConfigurationPage-CmEeNg6T.mjs").then((mod) => ({
1286
+ () => import("./ListConfigurationPage-DDi0KqFm.mjs").then((mod) => ({
1236
1287
  default: mod.ProtectedListConfiguration
1237
1288
  }))
1238
1289
  );
1239
1290
  const ProtectedEditConfigurationPage = lazy(
1240
- () => import("./EditConfigurationPage-B2HhCh-b.mjs").then((mod) => ({
1291
+ () => import("./EditConfigurationPage-DbI4KMyz.mjs").then((mod) => ({
1241
1292
  default: mod.ProtectedEditConfigurationPage
1242
1293
  }))
1243
1294
  );
1244
1295
  const ProtectedComponentConfigurationPage = lazy(
1245
- () => import("./ComponentConfigurationPage-uTMkLI60.mjs").then((mod) => ({
1296
+ () => import("./ComponentConfigurationPage-CuWgXugY.mjs").then((mod) => ({
1246
1297
  default: mod.ProtectedComponentConfigurationPage
1247
1298
  }))
1248
1299
  );
1249
1300
  const NoPermissions = lazy(
1250
- () => import("./NoPermissionsPage-Dt2O40ey.mjs").then((mod) => ({ default: mod.NoPermissions }))
1301
+ () => import("./NoPermissionsPage-CZrJH00p.mjs").then((mod) => ({ default: mod.NoPermissions }))
1251
1302
  );
1252
1303
  const NoContentType = lazy(
1253
- () => import("./NoContentTypePage-Dh38hBXB.mjs").then((mod) => ({ default: mod.NoContentType }))
1304
+ () => import("./NoContentTypePage-DaWw67K-.mjs").then((mod) => ({ default: mod.NoContentType }))
1254
1305
  );
1255
1306
  const CollectionTypePages = () => {
1256
1307
  const { collectionType } = useParams();
@@ -1562,7 +1613,7 @@ const DocumentActionModal = ({
1562
1613
  title,
1563
1614
  onClose,
1564
1615
  footer: Footer,
1565
- content,
1616
+ content: Content,
1566
1617
  onModalClose
1567
1618
  }) => {
1568
1619
  const id = React.useId();
@@ -1577,7 +1628,7 @@ const DocumentActionModal = ({
1577
1628
  };
1578
1629
  return /* @__PURE__ */ jsxs(ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
1579
1630
  /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
1580
- /* @__PURE__ */ jsx(ModalBody, { children: content }),
1631
+ /* @__PURE__ */ jsx(ModalBody, { children: typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content }),
1581
1632
  /* @__PURE__ */ jsx(
1582
1633
  Box,
1583
1634
  {
@@ -1794,7 +1845,7 @@ const UNPUBLISH_DRAFT_OPTIONS = {
1794
1845
  KEEP: "keep",
1795
1846
  DISCARD: "discard"
1796
1847
  };
1797
- const UnpublishAction = ({
1848
+ const UnpublishAction$1 = ({
1798
1849
  activeTab,
1799
1850
  documentId,
1800
1851
  model,
@@ -1869,6 +1920,7 @@ const UnpublishAction = ({
1869
1920
  direction: "column",
1870
1921
  alignItems: "flex-start",
1871
1922
  tag: "fieldset",
1923
+ borderWidth: 0,
1872
1924
  gap: 3,
1873
1925
  children: [
1874
1926
  /* @__PURE__ */ jsx(VisuallyHidden, { tag: "legend" }),
@@ -1928,7 +1980,7 @@ const UnpublishAction = ({
1928
1980
  position: ["panel", "table-row"]
1929
1981
  };
1930
1982
  };
1931
- UnpublishAction.type = "unpublish";
1983
+ UnpublishAction$1.type = "unpublish";
1932
1984
  const DiscardAction = ({
1933
1985
  activeTab,
1934
1986
  documentId,
@@ -1984,7 +2036,7 @@ const StyledCrossCircle = styled(CrossCircle)`
1984
2036
  fill: currentColor;
1985
2037
  }
1986
2038
  `;
1987
- const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction, DiscardAction];
2039
+ const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction$1, DiscardAction];
1988
2040
  const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
1989
2041
  const RelativeTime = React.forwardRef(
1990
2042
  ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
@@ -2251,7 +2303,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
2251
2303
  id: "app.links.configure-view",
2252
2304
  defaultMessage: "Configure the view"
2253
2305
  }),
2254
- icon: /* @__PURE__ */ jsx(StyledCog, {}),
2306
+ icon: /* @__PURE__ */ jsx(ListPlus, {}),
2255
2307
  onClick: () => {
2256
2308
  navigate(`../${collectionType}/${model}/configurations/edit`);
2257
2309
  },
@@ -2259,11 +2311,6 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
2259
2311
  };
2260
2312
  };
2261
2313
  ConfigureTheViewAction.type = "configure-the-view";
2262
- const StyledCog = styled(Cog)`
2263
- path {
2264
- fill: currentColor;
2265
- }
2266
- `;
2267
2314
  const EditTheModelAction = ({ model }) => {
2268
2315
  const navigate = useNavigate();
2269
2316
  const { formatMessage } = useIntl();
@@ -2272,7 +2319,7 @@ const EditTheModelAction = ({ model }) => {
2272
2319
  id: "content-manager.link-to-ctb",
2273
2320
  defaultMessage: "Edit the model"
2274
2321
  }),
2275
- icon: /* @__PURE__ */ jsx(StyledPencil$1, {}),
2322
+ icon: /* @__PURE__ */ jsx(Pencil, {}),
2276
2323
  onClick: () => {
2277
2324
  navigate(`/plugins/content-type-builder/content-types/${model}`);
2278
2325
  },
@@ -2280,12 +2327,7 @@ const EditTheModelAction = ({ model }) => {
2280
2327
  };
2281
2328
  };
2282
2329
  EditTheModelAction.type = "edit-the-model";
2283
- const StyledPencil$1 = styled(Pencil)`
2284
- path {
2285
- fill: currentColor;
2286
- }
2287
- `;
2288
- const DeleteAction = ({ documentId, model, collectionType, document }) => {
2330
+ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
2289
2331
  const navigate = useNavigate();
2290
2332
  const { formatMessage } = useIntl();
2291
2333
  const listViewPathMatch = useMatch(LIST_PATH);
@@ -2299,7 +2341,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
2299
2341
  id: "content-manager.actions.delete.label",
2300
2342
  defaultMessage: "Delete document"
2301
2343
  }),
2302
- icon: /* @__PURE__ */ jsx(StyledTrash, {}),
2344
+ icon: /* @__PURE__ */ jsx(Trash, {}),
2303
2345
  dialog: {
2304
2346
  type: "dialog",
2305
2347
  title: formatMessage({
@@ -2353,13 +2395,8 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
2353
2395
  position: ["header", "table-row"]
2354
2396
  };
2355
2397
  };
2356
- DeleteAction.type = "delete";
2357
- const StyledTrash = styled(Trash)`
2358
- path {
2359
- fill: currentColor;
2360
- }
2361
- `;
2362
- const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction];
2398
+ DeleteAction$1.type = "delete";
2399
+ const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
2363
2400
  const Panels = () => {
2364
2401
  const isCloning = useMatch(CLONE_PATH) !== null;
2365
2402
  const [
@@ -2454,7 +2491,262 @@ const Panel = React.forwardRef(({ children, title }, ref) => {
2454
2491
  }
2455
2492
  );
2456
2493
  });
2457
- const DEFAULT_BULK_ACTIONS = [];
2494
+ const BulkActionsRenderer = () => {
2495
+ const plugins = useStrapiApp("BulkActionsRenderer", (state) => state.plugins);
2496
+ const { model, collectionType } = useDoc();
2497
+ const { selectedRows } = useTable("BulkActionsRenderer", (state) => state);
2498
+ return /* @__PURE__ */ jsx(Flex, { gap: 2, children: /* @__PURE__ */ jsx(
2499
+ DescriptionComponentRenderer,
2500
+ {
2501
+ props: {
2502
+ model,
2503
+ collectionType,
2504
+ documents: selectedRows
2505
+ },
2506
+ descriptions: plugins["content-manager"].apis.getBulkActions(),
2507
+ children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(BulkActionAction, { ...action }, action.id))
2508
+ }
2509
+ ) });
2510
+ };
2511
+ const BulkActionAction = (action) => {
2512
+ const [dialogId, setDialogId] = React.useState(null);
2513
+ const { toggleNotification } = useNotification();
2514
+ const handleClick = (action2) => (e) => {
2515
+ const { onClick, dialog, id } = action2;
2516
+ if (onClick) {
2517
+ onClick(e);
2518
+ }
2519
+ if (dialog) {
2520
+ switch (dialog.type) {
2521
+ case "notification":
2522
+ toggleNotification({
2523
+ title: dialog.title,
2524
+ message: dialog.content,
2525
+ type: dialog.status,
2526
+ timeout: dialog.timeout,
2527
+ onClose: dialog.onClose
2528
+ });
2529
+ break;
2530
+ case "dialog":
2531
+ case "modal": {
2532
+ e.preventDefault();
2533
+ setDialogId(id);
2534
+ }
2535
+ }
2536
+ }
2537
+ };
2538
+ const handleClose = () => {
2539
+ setDialogId(null);
2540
+ if (action.dialog?.type === "modal" && action.dialog?.onClose) {
2541
+ action.dialog.onClose();
2542
+ }
2543
+ };
2544
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2545
+ /* @__PURE__ */ jsx(
2546
+ Button,
2547
+ {
2548
+ disabled: action.disabled,
2549
+ startIcon: action.icon,
2550
+ variant: action.variant,
2551
+ onClick: handleClick(action),
2552
+ children: action.label
2553
+ }
2554
+ ),
2555
+ action.dialog?.type === "dialog" ? /* @__PURE__ */ jsx(
2556
+ BulkActionConfirmDialog,
2557
+ {
2558
+ ...action.dialog,
2559
+ variant: action.variant,
2560
+ isOpen: dialogId === action.id,
2561
+ onClose: handleClose
2562
+ }
2563
+ ) : null,
2564
+ action.dialog?.type === "modal" ? /* @__PURE__ */ jsx(
2565
+ BulkActionModal,
2566
+ {
2567
+ ...action.dialog,
2568
+ onModalClose: handleClose,
2569
+ isOpen: dialogId === action.id
2570
+ }
2571
+ ) : null
2572
+ ] });
2573
+ };
2574
+ const BulkActionConfirmDialog = ({
2575
+ onClose,
2576
+ onCancel,
2577
+ onConfirm,
2578
+ title,
2579
+ content,
2580
+ confirmButton,
2581
+ isOpen,
2582
+ variant = "secondary"
2583
+ }) => {
2584
+ const { formatMessage } = useIntl();
2585
+ const handleClose = async () => {
2586
+ if (onCancel) {
2587
+ await onCancel();
2588
+ }
2589
+ onClose();
2590
+ };
2591
+ const handleConfirm = async () => {
2592
+ if (onConfirm) {
2593
+ await onConfirm();
2594
+ }
2595
+ onClose();
2596
+ };
2597
+ return /* @__PURE__ */ jsxs(Dialog, { isOpen, title, onClose: handleClose, children: [
2598
+ /* @__PURE__ */ jsx(DialogBody, { icon: /* @__PURE__ */ jsx(WarningCircle, {}), children: content }),
2599
+ /* @__PURE__ */ jsx(
2600
+ DialogFooter,
2601
+ {
2602
+ startAction: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", children: formatMessage({
2603
+ id: "app.components.Button.cancel",
2604
+ defaultMessage: "Cancel"
2605
+ }) }),
2606
+ endAction: /* @__PURE__ */ jsx(
2607
+ Button,
2608
+ {
2609
+ onClick: handleConfirm,
2610
+ variant: variant === "danger-light" ? variant : "secondary",
2611
+ startIcon: variant === "danger-light" ? /* @__PURE__ */ jsx(Trash, {}) : /* @__PURE__ */ jsx(Check, {}),
2612
+ children: confirmButton ? confirmButton : formatMessage({
2613
+ id: "app.components.Button.confirm",
2614
+ defaultMessage: "Confirm"
2615
+ })
2616
+ }
2617
+ )
2618
+ }
2619
+ )
2620
+ ] });
2621
+ };
2622
+ const BulkActionModal = ({
2623
+ isOpen,
2624
+ title,
2625
+ onClose,
2626
+ content: Content,
2627
+ onModalClose
2628
+ }) => {
2629
+ const id = React.useId();
2630
+ if (!isOpen) {
2631
+ return null;
2632
+ }
2633
+ const handleClose = () => {
2634
+ if (onClose) {
2635
+ onClose();
2636
+ }
2637
+ onModalClose();
2638
+ };
2639
+ return /* @__PURE__ */ jsxs(ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
2640
+ /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
2641
+ /* @__PURE__ */ jsx(Content, { onClose: handleClose })
2642
+ ] });
2643
+ };
2644
+ const DeleteAction = ({ documents, model }) => {
2645
+ const { formatMessage } = useIntl();
2646
+ const { schema: contentType } = useDoc();
2647
+ const selectRow = useTable("DeleteAction", (state) => state.selectRow);
2648
+ const hasI18nEnabled = Boolean(contentType?.pluginOptions?.i18n);
2649
+ const [{ query }] = useQueryParams();
2650
+ const params = React.useMemo(() => buildValidParams(query), [query]);
2651
+ const hasDeletePermission = useDocumentRBAC("deleteAction", (state) => state.canDelete);
2652
+ const { deleteMany: bulkDeleteAction } = useDocumentActions();
2653
+ const documentIds = documents.map(({ documentId }) => documentId);
2654
+ const handleConfirmBulkDelete = async () => {
2655
+ const res = await bulkDeleteAction({
2656
+ documentIds,
2657
+ model,
2658
+ params
2659
+ });
2660
+ if (!("error" in res)) {
2661
+ selectRow([]);
2662
+ }
2663
+ };
2664
+ if (!hasDeletePermission)
2665
+ return null;
2666
+ return {
2667
+ variant: "danger-light",
2668
+ label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
2669
+ dialog: {
2670
+ type: "dialog",
2671
+ title: formatMessage({
2672
+ id: "app.components.ConfirmDialog.title",
2673
+ defaultMessage: "Confirmation"
2674
+ }),
2675
+ content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
2676
+ /* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
2677
+ id: "popUpWarning.bodyMessage.contentType.delete.all",
2678
+ defaultMessage: "Are you sure you want to delete these entries?"
2679
+ }) }),
2680
+ hasI18nEnabled && /* @__PURE__ */ jsx(Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsx(Typography, { textColor: "danger500", children: formatMessage(
2681
+ {
2682
+ id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
2683
+ defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
2684
+ },
2685
+ {
2686
+ em: Emphasis
2687
+ }
2688
+ ) }) })
2689
+ ] }),
2690
+ onConfirm: handleConfirmBulkDelete
2691
+ }
2692
+ };
2693
+ };
2694
+ DeleteAction.type = "delete";
2695
+ const UnpublishAction = ({ documents, model }) => {
2696
+ const { formatMessage } = useIntl();
2697
+ const { schema } = useDoc();
2698
+ const selectRow = useTable("UnpublishAction", (state) => state.selectRow);
2699
+ const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
2700
+ const hasI18nEnabled = Boolean(schema?.pluginOptions?.i18n);
2701
+ const hasDraftAndPublishEnabled = Boolean(schema?.options?.draftAndPublish);
2702
+ const { unpublishMany: bulkUnpublishAction } = useDocumentActions();
2703
+ const documentIds = documents.map(({ documentId }) => documentId);
2704
+ const [{ query }] = useQueryParams();
2705
+ const params = React.useMemo(() => buildValidParams(query), [query]);
2706
+ const handleConfirmBulkUnpublish = async () => {
2707
+ const data = await bulkUnpublishAction({ documentIds, model, params });
2708
+ if (!("error" in data)) {
2709
+ selectRow([]);
2710
+ }
2711
+ };
2712
+ const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published");
2713
+ if (!showUnpublishButton)
2714
+ return null;
2715
+ return {
2716
+ variant: "tertiary",
2717
+ label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
2718
+ dialog: {
2719
+ type: "dialog",
2720
+ title: formatMessage({
2721
+ id: "app.components.ConfirmDialog.title",
2722
+ defaultMessage: "Confirmation"
2723
+ }),
2724
+ content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
2725
+ /* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
2726
+ id: "popUpWarning.bodyMessage.contentType.unpublish.all",
2727
+ defaultMessage: "Are you sure you want to unpublish these entries?"
2728
+ }) }),
2729
+ hasI18nEnabled && /* @__PURE__ */ jsx(Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsx(Typography, { textColor: "danger500", children: formatMessage(
2730
+ {
2731
+ id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
2732
+ defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
2733
+ },
2734
+ {
2735
+ em: Emphasis
2736
+ }
2737
+ ) }) })
2738
+ ] }),
2739
+ confirmButton: formatMessage({
2740
+ id: "app.utils.unpublish",
2741
+ defaultMessage: "Unpublish"
2742
+ }),
2743
+ onConfirm: handleConfirmBulkUnpublish
2744
+ }
2745
+ };
2746
+ };
2747
+ UnpublishAction.type = "unpublish";
2748
+ const Emphasis = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
2749
+ const DEFAULT_BULK_ACTIONS = [UnpublishAction, DeleteAction];
2458
2750
  const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
2459
2751
  const { formatMessage } = useIntl();
2460
2752
  const getDefaultErrorMessage = (reason) => {
@@ -3107,10 +3399,8 @@ const index = {
3107
3399
  register(app) {
3108
3400
  const cm = new ContentManagerPlugin();
3109
3401
  app.addReducers({
3110
- [contentManagerApi.reducerPath]: contentManagerApi.reducer,
3111
3402
  [PLUGIN_ID]: reducer
3112
3403
  });
3113
- app.addMiddlewares([() => contentManagerApi.middleware]);
3114
3404
  app.addMenuLink({
3115
3405
  to: PLUGIN_ID,
3116
3406
  icon: Feather,
@@ -3119,14 +3409,15 @@ const index = {
3119
3409
  defaultMessage: "Content Manager"
3120
3410
  },
3121
3411
  permissions: [],
3122
- Component: () => import("./layout-B5cm7cZj.mjs").then((mod) => ({ default: mod.Layout }))
3412
+ Component: () => import("./layout-BinjszSQ.mjs").then((mod) => ({ default: mod.Layout })),
3413
+ position: 1
3123
3414
  });
3124
3415
  app.registerPlugin(cm.config);
3125
3416
  },
3126
3417
  async registerTrads({ locales }) {
3127
3418
  const importedTrads = await Promise.all(
3128
3419
  locales.map((locale) => {
3129
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-MBPul9Su.mjs"), "./translations/es.json": () => import("./es-CeXiYflN.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr-CD9VFbPM.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-CtsUxOvk.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
3420
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-GCOTL6jR.mjs"), "./translations/es.json": () => import("./es-CeXiYflN.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr-CD9VFbPM.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-CtsUxOvk.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
3130
3421
  return {
3131
3422
  data: prefixPluginTranslations(data, PLUGIN_ID),
3132
3423
  locale
@@ -3144,16 +3435,17 @@ const index = {
3144
3435
  };
3145
3436
  export {
3146
3437
  ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD as A,
3147
- extractContentTypeComponents as B,
3438
+ BulkActionsRenderer as B,
3148
3439
  COLLECTION_TYPES as C,
3149
3440
  DocumentStatus as D,
3150
- DEFAULT_SETTINGS as E,
3151
- convertEditLayoutToFieldLayouts as F,
3152
- useDocument as G,
3441
+ extractContentTypeComponents as E,
3442
+ DEFAULT_SETTINGS as F,
3443
+ convertEditLayoutToFieldLayouts as G,
3153
3444
  HOOKS as H,
3154
3445
  InjectionZone as I,
3155
- index as J,
3156
- useDocumentActions as K,
3446
+ useDocument as J,
3447
+ index as K,
3448
+ useDocumentActions as L,
3157
3449
  Panels as P,
3158
3450
  RelativeTime as R,
3159
3451
  SINGLE_TYPES as S,
@@ -3185,4 +3477,4 @@ export {
3185
3477
  capitalise as y,
3186
3478
  useUpdateContentTypeConfigurationMutation as z
3187
3479
  };
3188
- //# sourceMappingURL=index-B3c-4it4.mjs.map
3480
+ //# sourceMappingURL=index-BaGHmIir.mjs.map