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

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 (175) 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-CYqQv0ne.mjs} +3 -3
  6. package/dist/_chunks/{ComponentConfigurationPage--2aLCv-G.mjs.map → ComponentConfigurationPage-CYqQv0ne.mjs.map} +1 -1
  7. package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js → ComponentConfigurationPage-DiigqkCf.js} +3 -3
  8. package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js.map → ComponentConfigurationPage-DiigqkCf.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-CUcGHHvQ.mjs → EditConfigurationPage-BArY-b8_.mjs} +3 -3
  14. package/dist/_chunks/{EditConfigurationPage-CUcGHHvQ.mjs.map → EditConfigurationPage-BArY-b8_.mjs.map} +1 -1
  15. package/dist/_chunks/{EditConfigurationPage-BfFzJ4Br.js → EditConfigurationPage-BeeGw2RI.js} +3 -3
  16. package/dist/_chunks/{EditConfigurationPage-BfFzJ4Br.js.map → EditConfigurationPage-BeeGw2RI.js.map} +1 -1
  17. package/dist/_chunks/{EditViewPage-Bm8lgcm6.mjs → EditViewPage-B8ETGsFo.mjs} +6 -6
  18. package/dist/_chunks/EditViewPage-B8ETGsFo.mjs.map +1 -0
  19. package/dist/_chunks/{EditViewPage-CzOT5Kpj.js → EditViewPage-DZPDqo_G.js} +7 -9
  20. package/dist/_chunks/EditViewPage-DZPDqo_G.js.map +1 -0
  21. package/dist/_chunks/{Field-Dlh0uGnL.mjs → Field-Dn4ThnFB.mjs} +500 -608
  22. package/dist/_chunks/Field-Dn4ThnFB.mjs.map +1 -0
  23. package/dist/_chunks/{Field-Caef4JjM.js → Field-DnJMS8cB.js} +552 -661
  24. package/dist/_chunks/Field-DnJMS8cB.js.map +1 -0
  25. package/dist/_chunks/{Form-EnaQL_6L.mjs → Form-DY721B6y.mjs} +21 -18
  26. package/dist/_chunks/Form-DY721B6y.mjs.map +1 -0
  27. package/dist/_chunks/{Form-BzuAjtRq.js → Form-DiTmWq2k.js} +21 -19
  28. package/dist/_chunks/Form-DiTmWq2k.js.map +1 -0
  29. package/dist/_chunks/{History-D6sbCJvo.mjs → History-CwWN_uNp.mjs} +33 -43
  30. package/dist/_chunks/History-CwWN_uNp.mjs.map +1 -0
  31. package/dist/_chunks/{History-C17LiyRg.js → History-DShoVAh0.js} +33 -44
  32. package/dist/_chunks/History-DShoVAh0.js.map +1 -0
  33. package/dist/_chunks/{ListConfigurationPage-Dks5SX6f.js → ListConfigurationPage-COIRGF5b.js} +17 -19
  34. package/dist/_chunks/ListConfigurationPage-COIRGF5b.js.map +1 -0
  35. package/dist/_chunks/{ListConfigurationPage-Ce4qs7qE.mjs → ListConfigurationPage-D062TiTL.mjs} +14 -14
  36. package/dist/_chunks/ListConfigurationPage-D062TiTL.mjs.map +1 -0
  37. package/dist/_chunks/{ListViewPage-Be7S5aKL.mjs → ListViewPage-BeHTsIr5.mjs} +25 -45
  38. package/dist/_chunks/ListViewPage-BeHTsIr5.mjs.map +1 -0
  39. package/dist/_chunks/{ListViewPage-BwrZrPsh.js → ListViewPage-CFuXPZ_r.js} +31 -51
  40. package/dist/_chunks/ListViewPage-CFuXPZ_r.js.map +1 -0
  41. package/dist/_chunks/{NoContentTypePage-CIPmYQMm.mjs → NoContentTypePage-B_KLijrG.mjs} +7 -7
  42. package/dist/_chunks/NoContentTypePage-B_KLijrG.mjs.map +1 -0
  43. package/dist/_chunks/{NoContentTypePage-Cu5r1-JT.js → NoContentTypePage-rdH0Zp0A.js} +5 -5
  44. package/dist/_chunks/NoContentTypePage-rdH0Zp0A.js.map +1 -0
  45. package/dist/_chunks/{NoPermissionsPage-DhJ7LYrr.mjs → NoPermissionsPage-BPU-v48V.mjs} +5 -6
  46. package/dist/_chunks/NoPermissionsPage-BPU-v48V.mjs.map +1 -0
  47. package/dist/_chunks/{NoPermissionsPage-C-j6TEUF.js → NoPermissionsPage-D8gbX1Y_.js} +4 -5
  48. package/dist/_chunks/NoPermissionsPage-D8gbX1Y_.js.map +1 -0
  49. package/dist/_chunks/{Relations-CY7AtkDA.mjs → Relations-Bbz90ZWv.mjs} +66 -56
  50. package/dist/_chunks/Relations-Bbz90ZWv.mjs.map +1 -0
  51. package/dist/_chunks/{Relations-Czs-uZ-s.js → Relations-wHyjWWT5.js} +70 -61
  52. package/dist/_chunks/Relations-wHyjWWT5.js.map +1 -0
  53. package/dist/_chunks/{en-C-V1_90f.js → en-BN1bvFK7.js} +4 -1
  54. package/dist/_chunks/{en-C-V1_90f.js.map → en-BN1bvFK7.js.map} +1 -1
  55. package/dist/_chunks/{en-MBPul9Su.mjs → en-Dzv55oQw.mjs} +4 -1
  56. package/dist/_chunks/{en-MBPul9Su.mjs.map → en-Dzv55oQw.mjs.map} +1 -1
  57. package/dist/_chunks/{index-X_2tafck.js → index-BRHpg0az.js} +1535 -789
  58. package/dist/_chunks/index-BRHpg0az.js.map +1 -0
  59. package/dist/_chunks/{index-DNVx8ssZ.mjs → index-Dv4oDn11.mjs} +1538 -791
  60. package/dist/_chunks/index-Dv4oDn11.mjs.map +1 -0
  61. package/dist/_chunks/{layout-Dnh0PNp9.mjs → layout-hInnLBbA.mjs} +13 -13
  62. package/dist/_chunks/layout-hInnLBbA.mjs.map +1 -0
  63. package/dist/_chunks/{layout-dBc7wN7L.js → layout-pZc2Q3bK.js} +14 -16
  64. package/dist/_chunks/layout-pZc2Q3bK.js.map +1 -0
  65. package/dist/_chunks/{relations-Dx7tMKJN.mjs → relations-BcPI8XhI.mjs} +2 -2
  66. package/dist/_chunks/{relations-Dx7tMKJN.mjs.map → relations-BcPI8XhI.mjs.map} +1 -1
  67. package/dist/_chunks/{relations-4pHtBrHJ.js → relations-CVE30dYt.js} +2 -2
  68. package/dist/_chunks/{relations-4pHtBrHJ.js.map → relations-CVE30dYt.js.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 +5 -4
  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/services/historyVersion.d.ts +1 -1
  82. package/dist/admin/src/hooks/useDocument.d.ts +5 -8
  83. package/dist/admin/src/hooks/useDocumentActions.d.ts +24 -3
  84. package/dist/admin/src/hooks/useDocumentLayout.d.ts +2 -2
  85. package/dist/admin/src/hooks/useDragAndDrop.d.ts +4 -4
  86. package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +1 -1
  87. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +3 -1
  88. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +3 -3
  89. package/dist/admin/src/pages/EditView/components/FormInputs/Component/Input.d.ts +2 -2
  90. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.d.ts +3 -5
  91. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +1 -1
  92. package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +10 -18
  93. package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +2 -2
  94. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +3 -49
  95. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.d.ts +2 -2
  96. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +67 -52
  97. package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -10
  98. package/dist/admin/src/pages/ListView/components/BulkActions/PublishAction.d.ts +9 -26
  99. package/dist/admin/src/services/api.d.ts +2 -3
  100. package/dist/admin/src/services/components.d.ts +2 -2
  101. package/dist/admin/src/services/contentTypes.d.ts +5 -5
  102. package/dist/admin/src/services/documents.d.ts +29 -17
  103. package/dist/admin/src/services/init.d.ts +2 -2
  104. package/dist/admin/src/services/relations.d.ts +3 -3
  105. package/dist/admin/src/services/uid.d.ts +3 -3
  106. package/dist/admin/src/utils/api.d.ts +4 -18
  107. package/dist/admin/src/utils/validation.d.ts +1 -6
  108. package/dist/server/index.js +529 -407
  109. package/dist/server/index.js.map +1 -1
  110. package/dist/server/index.mjs +537 -415
  111. package/dist/server/index.mjs.map +1 -1
  112. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  113. package/dist/server/src/controllers/single-types.d.ts.map +1 -1
  114. package/dist/server/src/controllers/utils/metadata.d.ts +8 -0
  115. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -0
  116. package/dist/server/src/controllers/validation/dimensions.d.ts +9 -0
  117. package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -0
  118. package/dist/server/src/controllers/validation/index.d.ts +1 -1
  119. package/dist/server/src/history/services/history.d.ts +2 -4
  120. package/dist/server/src/history/services/history.d.ts.map +1 -1
  121. package/dist/server/src/history/services/index.d.ts +6 -2
  122. package/dist/server/src/history/services/index.d.ts.map +1 -1
  123. package/dist/server/src/history/services/lifecycles.d.ts +9 -0
  124. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -0
  125. package/dist/server/src/history/services/utils.d.ts +41 -9
  126. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  127. package/dist/server/src/history/utils.d.ts +6 -2
  128. package/dist/server/src/history/utils.d.ts.map +1 -1
  129. package/dist/server/src/index.d.ts +18 -39
  130. package/dist/server/src/index.d.ts.map +1 -1
  131. package/dist/server/src/services/document-manager.d.ts +13 -12
  132. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  133. package/dist/server/src/services/document-metadata.d.ts +8 -29
  134. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  135. package/dist/server/src/services/index.d.ts +18 -39
  136. package/dist/server/src/services/index.d.ts.map +1 -1
  137. package/dist/server/src/services/utils/populate.d.ts +8 -1
  138. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  139. package/dist/shared/contracts/collection-types.d.ts +14 -6
  140. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  141. package/dist/shared/contracts/relations.d.ts +2 -2
  142. package/dist/shared/contracts/relations.d.ts.map +1 -1
  143. package/package.json +13 -14
  144. package/dist/_chunks/CardDragPreview-DSVYodBX.js.map +0 -1
  145. package/dist/_chunks/CardDragPreview-ikSG4M46.mjs.map +0 -1
  146. package/dist/_chunks/ComponentIcon-BBQsYCVn.js.map +0 -1
  147. package/dist/_chunks/ComponentIcon-BOFnK76n.mjs.map +0 -1
  148. package/dist/_chunks/EditViewPage-Bm8lgcm6.mjs.map +0 -1
  149. package/dist/_chunks/EditViewPage-CzOT5Kpj.js.map +0 -1
  150. package/dist/_chunks/Field-Caef4JjM.js.map +0 -1
  151. package/dist/_chunks/Field-Dlh0uGnL.mjs.map +0 -1
  152. package/dist/_chunks/Form-BzuAjtRq.js.map +0 -1
  153. package/dist/_chunks/Form-EnaQL_6L.mjs.map +0 -1
  154. package/dist/_chunks/History-C17LiyRg.js.map +0 -1
  155. package/dist/_chunks/History-D6sbCJvo.mjs.map +0 -1
  156. package/dist/_chunks/ListConfigurationPage-Ce4qs7qE.mjs.map +0 -1
  157. package/dist/_chunks/ListConfigurationPage-Dks5SX6f.js.map +0 -1
  158. package/dist/_chunks/ListViewPage-Be7S5aKL.mjs.map +0 -1
  159. package/dist/_chunks/ListViewPage-BwrZrPsh.js.map +0 -1
  160. package/dist/_chunks/NoContentTypePage-CIPmYQMm.mjs.map +0 -1
  161. package/dist/_chunks/NoContentTypePage-Cu5r1-JT.js.map +0 -1
  162. package/dist/_chunks/NoPermissionsPage-C-j6TEUF.js.map +0 -1
  163. package/dist/_chunks/NoPermissionsPage-DhJ7LYrr.mjs.map +0 -1
  164. package/dist/_chunks/Relations-CY7AtkDA.mjs.map +0 -1
  165. package/dist/_chunks/Relations-Czs-uZ-s.js.map +0 -1
  166. package/dist/_chunks/index-DNVx8ssZ.mjs.map +0 -1
  167. package/dist/_chunks/index-X_2tafck.js.map +0 -1
  168. package/dist/_chunks/layout-Dnh0PNp9.mjs.map +0 -1
  169. package/dist/_chunks/layout-dBc7wN7L.js.map +0 -1
  170. package/dist/_chunks/urls-CbOsUOoW.mjs +0 -7
  171. package/dist/_chunks/urls-CbOsUOoW.mjs.map +0 -1
  172. package/dist/_chunks/urls-DzZya_gm.js +0 -6
  173. package/dist/_chunks/urls-DzZya_gm.js.map +0 -1
  174. package/dist/server/src/controllers/utils/dimensions.d.ts +0 -5
  175. package/dist/server/src/controllers/utils/dimensions.d.ts.map +0 -1
@@ -1,17 +1,15 @@
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, CheckCircle, 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, 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, Table } from "@strapi/admin/strapi-admin";
4
4
  import { stringify } from "qs";
5
5
  import { useIntl } from "react-intl";
6
- import { useNavigate, useParams, Navigate, useMatch, NavLink } from "react-router-dom";
6
+ import { useNavigate, useParams, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
7
7
  import * as React from "react";
8
8
  import { lazy } from "react";
9
- import { Menu, VisuallyHidden, Flex, Typography, Dialog, DialogBody, DialogFooter, Button, ModalLayout, ModalHeader, ModalBody, Box, Radio, Status, SingleSelect, SingleSelectOption, LinkButton } from "@strapi/design-system";
10
- import styled from "styled-components";
9
+ import { Menu, VisuallyHidden, Flex, Typography, Dialog, DialogBody, DialogFooter, Button, ModalLayout, ModalHeader, ModalBody, Box, Radio, Status, SingleSelect, SingleSelectOption, ModalFooter, Loader, IconButton, Tooltip, LinkButton } from "@strapi/design-system";
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
- import { isAxiosError } from "axios";
15
13
  import pipe from "lodash/fp/pipe";
16
14
  import { intervalToDuration, isPast } from "date-fns";
17
15
  import { createSlice, combineReducers } from "@reduxjs/toolkit";
@@ -157,9 +155,8 @@ const DocumentRBAC = ({ children, permissions }) => {
157
155
  const name = removeNumericalStrings(fieldName.split("."));
158
156
  const componentFieldNames = fieldsUserCanAction.filter((field) => field.split(".").length > 1);
159
157
  if (fieldType === "component") {
160
- const componentOrDynamicZoneFields = componentFieldNames.map((field) => field.split("."));
161
- return componentOrDynamicZoneFields.some((field) => {
162
- return field.includes(fieldName);
158
+ return componentFieldNames.some((field) => {
159
+ return field.includes(name.join("."));
163
160
  });
164
161
  }
165
162
  if (name.length > 1) {
@@ -189,78 +186,8 @@ const extractAndDedupeFields = (permissions = []) => permissions.flatMap((permis
189
186
  (field, index2, arr) => arr.indexOf(field) === index2 && typeof field === "string"
190
187
  );
191
188
  const removeNumericalStrings = (arr) => arr.filter((item) => isNaN(Number(item)));
192
- const buildValidParams = (query) => {
193
- if (!query)
194
- return query;
195
- const { plugins: _, ...validQueryParams } = {
196
- ...query,
197
- ...Object.values(query?.plugins ?? {}).reduce(
198
- (acc, current) => Object.assign(acc, current),
199
- {}
200
- )
201
- };
202
- if ("_q" in validQueryParams) {
203
- validQueryParams._q = encodeURIComponent(validQueryParams._q);
204
- }
205
- return validQueryParams;
206
- };
207
- const axiosBaseQuery = () => async (query, { signal }) => {
208
- try {
209
- const { get, post, del, put } = getFetchClient();
210
- if (typeof query === "string") {
211
- const result = await get(query, { signal });
212
- return { data: result.data };
213
- } else {
214
- const { url, method = "GET", data, config } = query;
215
- if (method === "POST") {
216
- const result2 = await post(url, data, { ...config, signal });
217
- return { data: result2.data };
218
- }
219
- if (method === "DELETE") {
220
- const result2 = await del(url, { ...config, signal });
221
- return { data: result2.data };
222
- }
223
- if (method === "PUT") {
224
- const result2 = await put(url, data, { ...config, signal });
225
- return { data: result2.data };
226
- }
227
- const result = await get(url, { ...config, signal });
228
- return { data: result.data };
229
- }
230
- } catch (err) {
231
- if (isAxiosError(err)) {
232
- if (typeof err.response?.data === "object" && err.response?.data !== null && "error" in err.response?.data) {
233
- return { data: void 0, error: err.response?.data.error };
234
- } else {
235
- return {
236
- data: void 0,
237
- error: {
238
- name: "UnknownError",
239
- message: "There was an unknown error response from the API",
240
- details: err.response?.data,
241
- status: err.response?.status
242
- }
243
- };
244
- }
245
- }
246
- const error = err;
247
- return {
248
- data: void 0,
249
- error: {
250
- name: error.name,
251
- message: error.message,
252
- stack: error.stack
253
- }
254
- };
255
- }
256
- };
257
- const isBaseQueryError = (error) => {
258
- return error.name !== void 0;
259
- };
260
- const contentManagerApi = createApi({
261
- reducerPath: "contentManagerApi",
262
- baseQuery: axiosBaseQuery(),
263
- tagTypes: [
189
+ const contentManagerApi = adminApi.enhanceEndpoints({
190
+ addTagTypes: [
264
191
  "ComponentConfiguration",
265
192
  "ContentTypesConfiguration",
266
193
  "ContentTypeSettings",
@@ -268,8 +195,7 @@ const contentManagerApi = createApi({
268
195
  "InitialData",
269
196
  "HistoryVersion",
270
197
  "Relations"
271
- ],
272
- endpoints: () => ({})
198
+ ]
273
199
  });
274
200
  const documentApi = contentManagerApi.injectEndpoints({
275
201
  endpoints: (builder) => ({
@@ -325,12 +251,15 @@ const documentApi = contentManagerApi.injectEndpoints({
325
251
  ]
326
252
  }),
327
253
  deleteManyDocuments: builder.mutation({
328
- query: ({ model, ...body }) => ({
254
+ query: ({ model, params, ...body }) => ({
329
255
  url: `/content-manager/collection-types/${model}/actions/bulkDelete`,
330
256
  method: "POST",
331
- data: body
257
+ data: body,
258
+ config: {
259
+ params
260
+ }
332
261
  }),
333
- invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
262
+ invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
334
263
  }),
335
264
  discardDocument: builder.mutation({
336
265
  query: ({ collectionType, model, documentId, params }) => ({
@@ -441,10 +370,13 @@ const documentApi = contentManagerApi.injectEndpoints({
441
370
  }
442
371
  }),
443
372
  publishManyDocuments: builder.mutation({
444
- query: ({ model, ...body }) => ({
373
+ query: ({ model, params, ...body }) => ({
445
374
  url: `/content-manager/collection-types/${model}/actions/bulkPublish`,
446
375
  method: "POST",
447
- data: body
376
+ data: body,
377
+ config: {
378
+ params
379
+ }
448
380
  }),
449
381
  invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
450
382
  }),
@@ -486,10 +418,13 @@ const documentApi = contentManagerApi.injectEndpoints({
486
418
  }
487
419
  }),
488
420
  unpublishManyDocuments: builder.mutation({
489
- query: ({ model, ...body }) => ({
421
+ query: ({ model, params, ...body }) => ({
490
422
  url: `/content-manager/collection-types/${model}/actions/bulkUnpublish`,
491
423
  method: "POST",
492
- data: body
424
+ data: body,
425
+ config: {
426
+ params
427
+ }
493
428
  }),
494
429
  invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
495
430
  })
@@ -513,6 +448,24 @@ const {
513
448
  useUnpublishDocumentMutation,
514
449
  useUnpublishManyDocumentsMutation
515
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
+ };
516
469
  const createYupSchema = (attributes = {}, components = {}) => {
517
470
  const createModelSchema = (attributes2) => yup.object().shape(
518
471
  Object.entries(attributes2).reduce((acc, [name, attribute]) => {
@@ -552,10 +505,14 @@ const createYupSchema = (attributes = {}, components = {}) => {
552
505
  yup.array().of(
553
506
  yup.lazy(
554
507
  (data) => {
555
- const { attributes: attributes3 } = components[data.__component];
556
- return yup.object().shape({
508
+ const attributes3 = components?.[data?.__component]?.attributes;
509
+ const validation = yup.object().shape({
557
510
  __component: yup.string().required().oneOf(Object.keys(components))
558
- }).nullable(false).concat(createModelSchema(attributes3));
511
+ }).nullable(false);
512
+ if (!attributes3) {
513
+ return validation;
514
+ }
515
+ return validation.concat(createModelSchema(attributes3));
559
516
  }
560
517
  )
561
518
  )
@@ -565,11 +522,25 @@ const createYupSchema = (attributes = {}, components = {}) => {
565
522
  return {
566
523
  ...acc,
567
524
  [name]: transformSchema(
568
- yup.array().of(
569
- yup.object().shape({
570
- id: yup.string().required()
571
- })
572
- )
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
+ })
573
544
  )
574
545
  };
575
546
  default:
@@ -634,7 +605,12 @@ const addRequiredValidation = (attribute) => (schema) => {
634
605
  defaultMessage: "This field is required."
635
606
  });
636
607
  }
637
- 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
+ );
638
614
  };
639
615
  const addMinLengthValidation = (attribute) => (schema) => {
640
616
  if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
@@ -706,24 +682,6 @@ const addRegexValidation = (attribute) => (schema) => {
706
682
  }
707
683
  return schema;
708
684
  };
709
- const extractValuesFromYupError = (errorType, errorParams) => {
710
- if (!errorType || !errorParams) {
711
- return {};
712
- }
713
- return {
714
- [errorType]: errorParams[errorType]
715
- };
716
- };
717
- const getInnerErrors = (error) => (error?.inner || []).reduce((acc, currentError) => {
718
- if (currentError.path) {
719
- acc[currentError.path.split("[").join(".").split("]").join("")] = {
720
- id: currentError.message,
721
- defaultMessage: currentError.message,
722
- values: extractValuesFromYupError(currentError?.type, currentError?.params)
723
- };
724
- }
725
- return acc;
726
- }, {});
727
685
  const initApi = contentManagerApi.injectEndpoints({
728
686
  endpoints: (builder) => ({
729
687
  getInitialData: builder.query({
@@ -737,27 +695,20 @@ const { useGetInitialDataQuery } = initApi;
737
695
  const useContentTypeSchema = (model) => {
738
696
  const { toggleNotification } = useNotification();
739
697
  const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
740
- const { components, contentType, contentTypes, error, isLoading, isFetching } = useGetInitialDataQuery(void 0, {
741
- selectFromResult: (res) => {
742
- const contentType2 = res.data?.contentTypes.find((ct) => ct.uid === model);
743
- const componentsByKey = res.data?.components.reduce(
744
- (acc, component) => {
745
- acc[component.uid] = component;
746
- return acc;
747
- },
748
- {}
749
- );
750
- const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
751
- return {
752
- isLoading: res.isLoading,
753
- isFetching: res.isFetching,
754
- error: res.error,
755
- components: Object.keys(components2).length === 0 ? void 0 : components2,
756
- contentType: contentType2,
757
- contentTypes: res.data?.contentTypes ?? []
758
- };
759
- }
760
- });
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]);
761
712
  React.useEffect(() => {
762
713
  if (error) {
763
714
  toggleNotification({
@@ -840,7 +791,7 @@ const useDocument = (args, opts) => {
840
791
  return null;
841
792
  } catch (error2) {
842
793
  if (error2 instanceof ValidationError) {
843
- return getInnerErrors(error2);
794
+ return getYupValidationErrors(error2);
844
795
  }
845
796
  throw error2;
846
797
  }
@@ -936,6 +887,44 @@ const useDocumentActions = () => {
936
887
  },
937
888
  [trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
938
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
+ );
939
928
  const [discardDocument] = useDiscardDocumentMutation();
940
929
  const discard = React.useCallback(
941
930
  async ({ collectionType, model, documentId }) => {
@@ -1005,6 +994,43 @@ const useDocumentActions = () => {
1005
994
  },
1006
995
  [trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
1007
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
+ );
1008
1034
  const [updateDocument] = useUpdateDocumentMutation();
1009
1035
  const update = React.useCallback(
1010
1036
  async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
@@ -1079,6 +1105,41 @@ const useDocumentActions = () => {
1079
1105
  },
1080
1106
  [trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
1081
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
+ );
1082
1143
  const [createDocument] = useCreateDocumentMutation();
1083
1144
  const create = React.useCallback(
1084
1145
  async ({ model, params }, data, trackerProperty) => {
@@ -1192,15 +1253,18 @@ const useDocumentActions = () => {
1192
1253
  clone,
1193
1254
  create,
1194
1255
  delete: _delete,
1256
+ deleteMany,
1195
1257
  discard,
1196
1258
  getDocument,
1197
1259
  publish,
1260
+ publishMany,
1198
1261
  unpublish,
1262
+ unpublishMany,
1199
1263
  update
1200
1264
  };
1201
1265
  };
1202
1266
  const ProtectedHistoryPage = lazy(
1203
- () => import("./History-D6sbCJvo.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1267
+ () => import("./History-CwWN_uNp.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1204
1268
  );
1205
1269
  const routes$1 = [
1206
1270
  {
@@ -1213,31 +1277,31 @@ const routes$1 = [
1213
1277
  }
1214
1278
  ];
1215
1279
  const ProtectedEditViewPage = lazy(
1216
- () => import("./EditViewPage-Bm8lgcm6.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1280
+ () => import("./EditViewPage-B8ETGsFo.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1217
1281
  );
1218
1282
  const ProtectedListViewPage = lazy(
1219
- () => import("./ListViewPage-Be7S5aKL.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1283
+ () => import("./ListViewPage-BeHTsIr5.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1220
1284
  );
1221
1285
  const ProtectedListConfiguration = lazy(
1222
- () => import("./ListConfigurationPage-Ce4qs7qE.mjs").then((mod) => ({
1286
+ () => import("./ListConfigurationPage-D062TiTL.mjs").then((mod) => ({
1223
1287
  default: mod.ProtectedListConfiguration
1224
1288
  }))
1225
1289
  );
1226
1290
  const ProtectedEditConfigurationPage = lazy(
1227
- () => import("./EditConfigurationPage-CUcGHHvQ.mjs").then((mod) => ({
1291
+ () => import("./EditConfigurationPage-BArY-b8_.mjs").then((mod) => ({
1228
1292
  default: mod.ProtectedEditConfigurationPage
1229
1293
  }))
1230
1294
  );
1231
1295
  const ProtectedComponentConfigurationPage = lazy(
1232
- () => import("./ComponentConfigurationPage--2aLCv-G.mjs").then((mod) => ({
1296
+ () => import("./ComponentConfigurationPage-CYqQv0ne.mjs").then((mod) => ({
1233
1297
  default: mod.ProtectedComponentConfigurationPage
1234
1298
  }))
1235
1299
  );
1236
1300
  const NoPermissions = lazy(
1237
- () => import("./NoPermissionsPage-DhJ7LYrr.mjs").then((mod) => ({ default: mod.NoPermissions }))
1301
+ () => import("./NoPermissionsPage-BPU-v48V.mjs").then((mod) => ({ default: mod.NoPermissions }))
1238
1302
  );
1239
1303
  const NoContentType = lazy(
1240
- () => import("./NoContentTypePage-CIPmYQMm.mjs").then((mod) => ({ default: mod.NoContentType }))
1304
+ () => import("./NoContentTypePage-B_KLijrG.mjs").then((mod) => ({ default: mod.NoContentType }))
1241
1305
  );
1242
1306
  const CollectionTypePages = () => {
1243
1307
  const { collectionType } = useParams();
@@ -1427,7 +1491,7 @@ const DocumentActionsMenu = ({
1427
1491
  variant,
1428
1492
  children: [
1429
1493
  /* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
1430
- /* @__PURE__ */ jsx(VisuallyHidden, { as: "span", children: label || formatMessage({
1494
+ /* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: label || formatMessage({
1431
1495
  id: "content-manager.containers.edit.panels.default.more-actions",
1432
1496
  defaultMessage: "More document actions"
1433
1497
  }) })
@@ -1443,7 +1507,7 @@ const DocumentActionsMenu = ({
1443
1507
  onSelect: handleClick(action),
1444
1508
  display: "block",
1445
1509
  children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
1446
- /* @__PURE__ */ jsxs(Flex, { color: convertActionVariantToColor(action.variant), gap: 2, as: "span", children: [
1510
+ /* @__PURE__ */ jsxs(Flex, { color: convertActionVariantToColor(action.variant), gap: 2, tag: "span", children: [
1447
1511
  action.icon,
1448
1512
  action.label
1449
1513
  ] }),
@@ -1549,7 +1613,7 @@ const DocumentActionModal = ({
1549
1613
  title,
1550
1614
  onClose,
1551
1615
  footer: Footer,
1552
- content,
1616
+ content: Content,
1553
1617
  onModalClose
1554
1618
  }) => {
1555
1619
  const id = React.useId();
@@ -1563,8 +1627,8 @@ const DocumentActionModal = ({
1563
1627
  onModalClose();
1564
1628
  };
1565
1629
  return /* @__PURE__ */ jsxs(ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
1566
- /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral800", as: "h2", id, children: title }) }),
1567
- /* @__PURE__ */ jsx(ModalBody, { children: content }),
1630
+ /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
1631
+ /* @__PURE__ */ jsx(ModalBody, { children: typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content }),
1568
1632
  /* @__PURE__ */ jsx(
1569
1633
  Box,
1570
1634
  {
@@ -1581,7 +1645,7 @@ const DocumentActionModal = ({
1581
1645
  )
1582
1646
  ] });
1583
1647
  };
1584
- const PublishAction = ({
1648
+ const PublishAction$1 = ({
1585
1649
  activeTab,
1586
1650
  documentId,
1587
1651
  model,
@@ -1666,7 +1730,7 @@ const PublishAction = ({
1666
1730
  }
1667
1731
  };
1668
1732
  };
1669
- PublishAction.type = "publish";
1733
+ PublishAction$1.type = "publish";
1670
1734
  const UpdateAction = ({
1671
1735
  activeTab,
1672
1736
  documentId,
@@ -1781,7 +1845,7 @@ const UNPUBLISH_DRAFT_OPTIONS = {
1781
1845
  KEEP: "keep",
1782
1846
  DISCARD: "discard"
1783
1847
  };
1784
- const UnpublishAction = ({
1848
+ const UnpublishAction$1 = ({
1785
1849
  activeTab,
1786
1850
  documentId,
1787
1851
  model,
@@ -1844,7 +1908,7 @@ const UnpublishAction = ({
1844
1908
  content: /* @__PURE__ */ jsxs(Flex, { alignItems: "flex-start", direction: "column", gap: 6, children: [
1845
1909
  /* @__PURE__ */ jsxs(Flex, { width: "100%", direction: "column", gap: 2, children: [
1846
1910
  /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
1847
- /* @__PURE__ */ jsx(Typography, { as: "p", variant: "omega", textAlign: "center", children: formatMessage({
1911
+ /* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
1848
1912
  id: "content-manager.actions.unpublish.dialog.body",
1849
1913
  defaultMessage: "Are you sure?"
1850
1914
  }) })
@@ -1855,10 +1919,11 @@ const UnpublishAction = ({
1855
1919
  onChange: handleChange,
1856
1920
  direction: "column",
1857
1921
  alignItems: "flex-start",
1858
- as: "fieldset",
1922
+ tag: "fieldset",
1923
+ borderWidth: 0,
1859
1924
  gap: 3,
1860
1925
  children: [
1861
- /* @__PURE__ */ jsx(VisuallyHidden, { as: "legend" }),
1926
+ /* @__PURE__ */ jsx(VisuallyHidden, { tag: "legend" }),
1862
1927
  /* @__PURE__ */ jsx(
1863
1928
  Radio,
1864
1929
  {
@@ -1915,7 +1980,7 @@ const UnpublishAction = ({
1915
1980
  position: ["panel", "table-row"]
1916
1981
  };
1917
1982
  };
1918
- UnpublishAction.type = "unpublish";
1983
+ UnpublishAction$1.type = "unpublish";
1919
1984
  const DiscardAction = ({
1920
1985
  activeTab,
1921
1986
  documentId,
@@ -1949,7 +2014,7 @@ const DiscardAction = ({
1949
2014
  }),
1950
2015
  content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
1951
2016
  /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
1952
- /* @__PURE__ */ jsx(Typography, { as: "p", variant: "omega", textAlign: "center", children: formatMessage({
2017
+ /* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
1953
2018
  id: "content-manager.actions.discard.dialog.body",
1954
2019
  defaultMessage: "Are you sure?"
1955
2020
  }) })
@@ -1971,7 +2036,7 @@ const StyledCrossCircle = styled(CrossCircle)`
1971
2036
  fill: currentColor;
1972
2037
  }
1973
2038
  `;
1974
- const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction, DiscardAction];
2039
+ const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
1975
2040
  const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
1976
2041
  const RelativeTime = React.forwardRef(
1977
2042
  ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
@@ -2019,7 +2084,7 @@ const getDisplayName = ({
2019
2084
  const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2020
2085
  const DocumentStatus = ({ status = "draft", ...restProps }) => {
2021
2086
  const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
2022
- return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { as: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
2087
+ return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
2023
2088
  };
2024
2089
  const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2025
2090
  const { formatMessage } = useIntl();
@@ -2039,7 +2104,7 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2039
2104
  gap: "80px",
2040
2105
  alignItems: "flex-start",
2041
2106
  children: [
2042
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", as: "h1", children: title }),
2107
+ /* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
2043
2108
  /* @__PURE__ */ jsx(HeaderToolbar, {})
2044
2109
  ]
2045
2110
  }
@@ -2196,7 +2261,7 @@ const Information = ({ activeTab }) => {
2196
2261
  borderColor: "neutral150",
2197
2262
  direction: "column",
2198
2263
  marginTop: 2,
2199
- as: "dl",
2264
+ tag: "dl",
2200
2265
  padding: 5,
2201
2266
  gap: 3,
2202
2267
  alignItems: "flex-start",
@@ -2204,8 +2269,8 @@ const Information = ({ activeTab }) => {
2204
2269
  marginRight: "-0.4rem",
2205
2270
  width: "calc(100% + 8px)",
2206
2271
  children: information.map((info) => /* @__PURE__ */ jsxs(Flex, { gap: 1, direction: "column", alignItems: "flex-start", children: [
2207
- /* @__PURE__ */ jsx(Typography, { as: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
2208
- /* @__PURE__ */ jsx(Typography, { as: "dd", variant: "pi", textColor: "neutral600", children: info.value })
2272
+ /* @__PURE__ */ jsx(Typography, { tag: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
2273
+ /* @__PURE__ */ jsx(Typography, { tag: "dd", variant: "pi", textColor: "neutral600", children: info.value })
2209
2274
  ] }, info.label))
2210
2275
  }
2211
2276
  );
@@ -2238,7 +2303,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
2238
2303
  id: "app.links.configure-view",
2239
2304
  defaultMessage: "Configure the view"
2240
2305
  }),
2241
- icon: /* @__PURE__ */ jsx(StyledCog, {}),
2306
+ icon: /* @__PURE__ */ jsx(ListPlus, {}),
2242
2307
  onClick: () => {
2243
2308
  navigate(`../${collectionType}/${model}/configurations/edit`);
2244
2309
  },
@@ -2246,11 +2311,6 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
2246
2311
  };
2247
2312
  };
2248
2313
  ConfigureTheViewAction.type = "configure-the-view";
2249
- const StyledCog = styled(Cog)`
2250
- path {
2251
- fill: currentColor;
2252
- }
2253
- `;
2254
2314
  const EditTheModelAction = ({ model }) => {
2255
2315
  const navigate = useNavigate();
2256
2316
  const { formatMessage } = useIntl();
@@ -2259,7 +2319,7 @@ const EditTheModelAction = ({ model }) => {
2259
2319
  id: "content-manager.link-to-ctb",
2260
2320
  defaultMessage: "Edit the model"
2261
2321
  }),
2262
- icon: /* @__PURE__ */ jsx(StyledPencil$1, {}),
2322
+ icon: /* @__PURE__ */ jsx(Pencil, {}),
2263
2323
  onClick: () => {
2264
2324
  navigate(`/plugins/content-type-builder/content-types/${model}`);
2265
2325
  },
@@ -2267,12 +2327,7 @@ const EditTheModelAction = ({ model }) => {
2267
2327
  };
2268
2328
  };
2269
2329
  EditTheModelAction.type = "edit-the-model";
2270
- const StyledPencil$1 = styled(Pencil)`
2271
- path {
2272
- fill: currentColor;
2273
- }
2274
- `;
2275
- const DeleteAction = ({ documentId, model, collectionType, document }) => {
2330
+ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
2276
2331
  const navigate = useNavigate();
2277
2332
  const { formatMessage } = useIntl();
2278
2333
  const listViewPathMatch = useMatch(LIST_PATH);
@@ -2286,7 +2341,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
2286
2341
  id: "content-manager.actions.delete.label",
2287
2342
  defaultMessage: "Delete document"
2288
2343
  }),
2289
- icon: /* @__PURE__ */ jsx(StyledTrash, {}),
2344
+ icon: /* @__PURE__ */ jsx(Trash, {}),
2290
2345
  dialog: {
2291
2346
  type: "dialog",
2292
2347
  title: formatMessage({
@@ -2295,7 +2350,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
2295
2350
  }),
2296
2351
  content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
2297
2352
  /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
2298
- /* @__PURE__ */ jsx(Typography, { as: "p", variant: "omega", textAlign: "center", children: formatMessage({
2353
+ /* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
2299
2354
  id: "content-manager.actions.delete.dialog.body",
2300
2355
  defaultMessage: "Are you sure?"
2301
2356
  }) })
@@ -2340,13 +2395,8 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
2340
2395
  position: ["header", "table-row"]
2341
2396
  };
2342
2397
  };
2343
- DeleteAction.type = "delete";
2344
- const StyledTrash = styled(Trash)`
2345
- path {
2346
- fill: currentColor;
2347
- }
2348
- `;
2349
- const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction];
2398
+ DeleteAction$1.type = "delete";
2399
+ const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
2350
2400
  const Panels = () => {
2351
2401
  const isCloning = useMatch(CLONE_PATH) !== null;
2352
2402
  const [
@@ -2420,7 +2470,7 @@ const Panel = React.forwardRef(({ children, title }, ref) => {
2420
2470
  Flex,
2421
2471
  {
2422
2472
  ref,
2423
- as: "aside",
2473
+ tag: "aside",
2424
2474
  "aria-labelledby": "additional-information",
2425
2475
  background: "neutral0",
2426
2476
  borderColor: "neutral150",
@@ -2435,669 +2485,1364 @@ const Panel = React.forwardRef(({ children, title }, ref) => {
2435
2485
  justifyContent: "stretch",
2436
2486
  alignItems: "flex-start",
2437
2487
  children: [
2438
- /* @__PURE__ */ jsx(Typography, { as: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
2488
+ /* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
2439
2489
  children
2440
2490
  ]
2441
2491
  }
2442
2492
  );
2443
2493
  });
2444
- const DEFAULT_BULK_ACTIONS = [];
2445
- const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
2446
- const { formatMessage } = useIntl();
2447
- const getDefaultErrorMessage = (reason) => {
2448
- switch (reason) {
2449
- case "relation":
2450
- return "Duplicating the relation could remove it from the original entry.";
2451
- case "unique":
2452
- return "Identical values in a unique field are not allowed";
2453
- default:
2454
- return reason;
2455
- }
2456
- };
2457
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2458
- /* @__PURE__ */ jsx(Typography, { variant: "beta", children: formatMessage({
2459
- id: getTranslation("containers.list.autoCloneModal.title"),
2460
- defaultMessage: "This entry can't be duplicated directly."
2461
- }) }),
2462
- /* @__PURE__ */ jsx(Box, { marginTop: 2, children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: formatMessage({
2463
- id: getTranslation("containers.list.autoCloneModal.description"),
2464
- defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
2465
- }) }) }),
2466
- /* @__PURE__ */ jsx(Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxs(
2467
- Flex,
2468
- {
2469
- direction: "column",
2470
- gap: 2,
2471
- alignItems: "flex-start",
2472
- borderColor: "neutral200",
2473
- hasRadius: true,
2474
- padding: 6,
2475
- children: [
2476
- /* @__PURE__ */ jsx(Flex, { direction: "row", as: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxs(Typography, { fontWeight: "semiBold", as: "li", children: [
2477
- pathSegment,
2478
- index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsx(
2479
- ChevronRight,
2480
- {
2481
- fill: "neutral500",
2482
- height: "0.8rem",
2483
- width: "0.8rem",
2484
- style: { margin: "0 0.8rem" }
2485
- }
2486
- )
2487
- ] }, index2)) }),
2488
- /* @__PURE__ */ jsx(Typography, { as: "p", textColor: "neutral600", children: formatMessage({
2489
- id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
2490
- defaultMessage: getDefaultErrorMessage(reason)
2491
- }) })
2492
- ]
2493
- },
2494
- fieldPath.join()
2495
- )) })
2496
- ] });
2494
+ const HOOKS = {
2495
+ /**
2496
+ * Hook that allows to mutate the displayed headers of the list view table
2497
+ * @constant
2498
+ * @type {string}
2499
+ */
2500
+ INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
2501
+ /**
2502
+ * Hook that allows to mutate the CM's collection types links pre-set filters
2503
+ * @constant
2504
+ * @type {string}
2505
+ */
2506
+ MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
2507
+ /**
2508
+ * Hook that allows to mutate the CM's edit view layout
2509
+ * @constant
2510
+ * @type {string}
2511
+ */
2512
+ MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
2513
+ /**
2514
+ * Hook that allows to mutate the CM's single types links pre-set filters
2515
+ * @constant
2516
+ * @type {string}
2517
+ */
2518
+ MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
2497
2519
  };
2498
- const TableActions = ({ document }) => {
2499
- const { formatMessage } = useIntl();
2500
- const { model, collectionType } = useDoc();
2501
- const plugins = useStrapiApp("TableActions", (state) => state.plugins);
2502
- const props = {
2503
- activeTab: null,
2504
- model,
2505
- documentId: document.documentId,
2506
- collectionType,
2507
- document
2520
+ const contentTypesApi = contentManagerApi.injectEndpoints({
2521
+ endpoints: (builder) => ({
2522
+ getContentTypeConfiguration: builder.query({
2523
+ query: (uid) => ({
2524
+ url: `/content-manager/content-types/${uid}/configuration`,
2525
+ method: "GET"
2526
+ }),
2527
+ transformResponse: (response) => response.data,
2528
+ providesTags: (_result, _error, uid) => [
2529
+ { type: "ContentTypesConfiguration", id: uid },
2530
+ { type: "ContentTypeSettings", id: "LIST" }
2531
+ ]
2532
+ }),
2533
+ getAllContentTypeSettings: builder.query({
2534
+ query: () => "/content-manager/content-types-settings",
2535
+ transformResponse: (response) => response.data,
2536
+ providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
2537
+ }),
2538
+ updateContentTypeConfiguration: builder.mutation({
2539
+ query: ({ uid, ...body }) => ({
2540
+ url: `/content-manager/content-types/${uid}/configuration`,
2541
+ method: "PUT",
2542
+ data: body
2543
+ }),
2544
+ transformResponse: (response) => response.data,
2545
+ invalidatesTags: (_result, _error, { uid }) => [
2546
+ { type: "ContentTypesConfiguration", id: uid },
2547
+ { type: "ContentTypeSettings", id: "LIST" },
2548
+ // Is this necessary?
2549
+ { type: "InitialData" }
2550
+ ]
2551
+ })
2552
+ })
2553
+ });
2554
+ const {
2555
+ useGetContentTypeConfigurationQuery,
2556
+ useGetAllContentTypeSettingsQuery,
2557
+ useUpdateContentTypeConfigurationMutation
2558
+ } = contentTypesApi;
2559
+ const checkIfAttributeIsDisplayable = (attribute) => {
2560
+ const { type } = attribute;
2561
+ if (type === "relation") {
2562
+ return !attribute.relation.toLowerCase().includes("morph");
2563
+ }
2564
+ return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
2565
+ };
2566
+ const getMainField = (attribute, mainFieldName, { schemas, components }) => {
2567
+ if (!mainFieldName) {
2568
+ return void 0;
2569
+ }
2570
+ const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
2571
+ // @ts-expect-error – `targetModel` does exist on the attribute for a relation.
2572
+ schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
2573
+ );
2574
+ return {
2575
+ name: mainFieldName,
2576
+ type: mainFieldType ?? "string"
2508
2577
  };
2509
- return /* @__PURE__ */ jsx(
2510
- DescriptionComponentRenderer,
2578
+ };
2579
+ const DEFAULT_SETTINGS = {
2580
+ bulkable: false,
2581
+ filterable: false,
2582
+ searchable: false,
2583
+ pagination: false,
2584
+ defaultSortBy: "",
2585
+ defaultSortOrder: "asc",
2586
+ mainField: "id",
2587
+ pageSize: 10
2588
+ };
2589
+ const useDocumentLayout = (model) => {
2590
+ const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
2591
+ const [{ query }] = useQueryParams();
2592
+ const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
2593
+ const { toggleNotification } = useNotification();
2594
+ const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
2595
+ const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
2596
+ const {
2597
+ data,
2598
+ isLoading: isLoadingConfigs,
2599
+ error,
2600
+ isFetching: isFetchingConfigs
2601
+ } = useGetContentTypeConfigurationQuery(model);
2602
+ const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
2603
+ React.useEffect(() => {
2604
+ if (error) {
2605
+ toggleNotification({
2606
+ type: "danger",
2607
+ message: formatAPIError(error)
2608
+ });
2609
+ }
2610
+ }, [error, formatAPIError, toggleNotification]);
2611
+ const editLayout = React.useMemo(
2612
+ () => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
2613
+ layout: [],
2614
+ components: {},
2615
+ metadatas: {},
2616
+ options: {},
2617
+ settings: DEFAULT_SETTINGS
2618
+ },
2619
+ [data, isLoading, schemas, schema, components]
2620
+ );
2621
+ const listLayout = React.useMemo(() => {
2622
+ return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
2623
+ layout: [],
2624
+ metadatas: {},
2625
+ options: {},
2626
+ settings: DEFAULT_SETTINGS
2627
+ };
2628
+ }, [data, isLoading, schemas, schema, components]);
2629
+ const { layout: edit } = React.useMemo(
2630
+ () => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
2631
+ layout: editLayout,
2632
+ query
2633
+ }),
2634
+ [editLayout, query, runHookWaterfall]
2635
+ );
2636
+ return {
2637
+ error,
2638
+ isLoading,
2639
+ edit,
2640
+ list: listLayout
2641
+ };
2642
+ };
2643
+ const useDocLayout = () => {
2644
+ const { model } = useDoc();
2645
+ return useDocumentLayout(model);
2646
+ };
2647
+ const formatEditLayout = (data, {
2648
+ schemas,
2649
+ schema,
2650
+ components
2651
+ }) => {
2652
+ let currentPanelIndex = 0;
2653
+ const panelledEditAttributes = convertEditLayoutToFieldLayouts(
2654
+ data.contentType.layouts.edit,
2655
+ schema?.attributes,
2656
+ data.contentType.metadatas,
2657
+ { configurations: data.components, schemas: components },
2658
+ schemas
2659
+ ).reduce((panels, row) => {
2660
+ if (row.some((field) => field.type === "dynamiczone")) {
2661
+ panels.push([row]);
2662
+ currentPanelIndex += 2;
2663
+ } else {
2664
+ if (!panels[currentPanelIndex]) {
2665
+ panels.push([]);
2666
+ }
2667
+ panels[currentPanelIndex].push(row);
2668
+ }
2669
+ return panels;
2670
+ }, []);
2671
+ const componentEditAttributes = Object.entries(data.components).reduce(
2672
+ (acc, [uid, configuration]) => {
2673
+ acc[uid] = {
2674
+ layout: convertEditLayoutToFieldLayouts(
2675
+ configuration.layouts.edit,
2676
+ components[uid].attributes,
2677
+ configuration.metadatas
2678
+ ),
2679
+ settings: {
2680
+ ...configuration.settings,
2681
+ icon: components[uid].info.icon,
2682
+ displayName: components[uid].info.displayName
2683
+ }
2684
+ };
2685
+ return acc;
2686
+ },
2687
+ {}
2688
+ );
2689
+ const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
2690
+ (acc, [attribute, metadata]) => {
2691
+ return {
2692
+ ...acc,
2693
+ [attribute]: metadata.edit
2694
+ };
2695
+ },
2696
+ {}
2697
+ );
2698
+ return {
2699
+ layout: panelledEditAttributes,
2700
+ components: componentEditAttributes,
2701
+ metadatas: editMetadatas,
2702
+ settings: {
2703
+ ...data.contentType.settings,
2704
+ displayName: schema?.info.displayName
2705
+ },
2706
+ options: {
2707
+ ...schema?.options,
2708
+ ...schema?.pluginOptions,
2709
+ ...data.contentType.options
2710
+ }
2711
+ };
2712
+ };
2713
+ const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
2714
+ return rows.map(
2715
+ (row) => row.map((field) => {
2716
+ const attribute = attributes[field.name];
2717
+ if (!attribute) {
2718
+ return null;
2719
+ }
2720
+ const { edit: metadata } = metadatas[field.name];
2721
+ const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
2722
+ return {
2723
+ attribute,
2724
+ disabled: !metadata.editable,
2725
+ hint: metadata.description,
2726
+ label: metadata.label ?? "",
2727
+ name: field.name,
2728
+ // @ts-expect-error – mainField does exist on the metadata for a relation.
2729
+ mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
2730
+ schemas,
2731
+ components: components?.schemas ?? {}
2732
+ }),
2733
+ placeholder: metadata.placeholder ?? "",
2734
+ required: attribute.required ?? false,
2735
+ size: field.size,
2736
+ unique: "unique" in attribute ? attribute.unique : false,
2737
+ visible: metadata.visible ?? true,
2738
+ type: attribute.type
2739
+ };
2740
+ }).filter((field) => field !== null)
2741
+ );
2742
+ };
2743
+ const formatListLayout = (data, {
2744
+ schemas,
2745
+ schema,
2746
+ components
2747
+ }) => {
2748
+ const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
2749
+ (acc, [attribute, metadata]) => {
2750
+ return {
2751
+ ...acc,
2752
+ [attribute]: metadata.list
2753
+ };
2754
+ },
2755
+ {}
2756
+ );
2757
+ const listAttributes = convertListLayoutToFieldLayouts(
2758
+ data.contentType.layouts.list,
2759
+ schema?.attributes,
2760
+ listMetadatas,
2761
+ { configurations: data.components, schemas: components },
2762
+ schemas
2763
+ );
2764
+ return {
2765
+ layout: listAttributes,
2766
+ settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
2767
+ metadatas: listMetadatas,
2768
+ options: {
2769
+ ...schema?.options,
2770
+ ...schema?.pluginOptions,
2771
+ ...data.contentType.options
2772
+ }
2773
+ };
2774
+ };
2775
+ const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
2776
+ return columns.map((name) => {
2777
+ const attribute = attributes[name];
2778
+ if (!attribute) {
2779
+ return null;
2780
+ }
2781
+ const metadata = metadatas[name];
2782
+ const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
2783
+ return {
2784
+ attribute,
2785
+ label: metadata.label ?? "",
2786
+ mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
2787
+ schemas,
2788
+ components: components?.schemas ?? {}
2789
+ }),
2790
+ name,
2791
+ searchable: metadata.searchable ?? true,
2792
+ sortable: metadata.sortable ?? true
2793
+ };
2794
+ }).filter((field) => field !== null);
2795
+ };
2796
+ const ConfirmBulkActionDialog = ({
2797
+ onToggleDialog,
2798
+ isOpen = false,
2799
+ dialogBody,
2800
+ endAction
2801
+ }) => {
2802
+ const { formatMessage } = useIntl();
2803
+ return /* @__PURE__ */ jsxs(
2804
+ Dialog,
2511
2805
  {
2512
- props,
2513
- descriptions: plugins["content-manager"].apis.getDocumentActions(),
2514
- children: (actions2) => {
2515
- const tableRowActions = actions2.filter((action) => {
2516
- const positions = Array.isArray(action.position) ? action.position : [action.position];
2517
- return positions.includes("table-row");
2518
- });
2519
- return /* @__PURE__ */ jsx(
2520
- DocumentActionsMenu,
2806
+ onClose: onToggleDialog,
2807
+ title: formatMessage({
2808
+ id: "app.components.ConfirmDialog.title",
2809
+ defaultMessage: "Confirmation"
2810
+ }),
2811
+ isOpen,
2812
+ children: [
2813
+ /* @__PURE__ */ jsx(DialogBody, { icon: /* @__PURE__ */ jsx(WarningCircle, {}), children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: dialogBody }) }),
2814
+ /* @__PURE__ */ jsx(
2815
+ DialogFooter,
2521
2816
  {
2522
- actions: tableRowActions,
2523
- label: formatMessage({
2524
- id: "content-manager.containers.list.table.row-actions",
2525
- defaultMessage: "Row action"
2526
- }),
2527
- variant: "ghost"
2817
+ startAction: /* @__PURE__ */ jsx(Button, { onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
2818
+ id: "app.components.Button.cancel",
2819
+ defaultMessage: "Cancel"
2820
+ }) }),
2821
+ endAction
2528
2822
  }
2529
- );
2530
- }
2823
+ )
2824
+ ]
2531
2825
  }
2532
2826
  );
2533
2827
  };
2534
- const EditAction = ({ documentId }) => {
2535
- const navigate = useNavigate();
2828
+ const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
2829
+ const ConfirmDialogPublishAll = ({
2830
+ isOpen,
2831
+ onToggleDialog,
2832
+ isConfirmButtonLoading = false,
2833
+ onConfirm
2834
+ }) => {
2536
2835
  const { formatMessage } = useIntl();
2537
- const { canRead } = useDocumentRBAC("EditAction", ({ canRead: canRead2 }) => ({ canRead: canRead2 }));
2836
+ const selectedEntries = useTable("ConfirmDialogPublishAll", (state) => state.selectedRows);
2538
2837
  const { toggleNotification } = useNotification();
2838
+ const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
2839
+ const { model, schema } = useDoc();
2539
2840
  const [{ query }] = useQueryParams();
2540
- return {
2541
- disabled: !canRead,
2542
- icon: /* @__PURE__ */ jsx(StyledPencil, {}),
2543
- label: formatMessage({
2544
- id: "content-manager.actions.edit.label",
2545
- defaultMessage: "Edit"
2546
- }),
2547
- position: "table-row",
2548
- onClick: async () => {
2549
- if (!documentId) {
2550
- console.error(
2551
- "You're trying to edit a document without an id, this is likely a bug with Strapi. Please open an issue."
2841
+ const {
2842
+ data: countDraftRelations = 0,
2843
+ isLoading,
2844
+ error
2845
+ } = useGetManyDraftRelationCountQuery(
2846
+ {
2847
+ model,
2848
+ documentIds: selectedEntries.map((entry) => entry.documentId),
2849
+ locale: query?.plugins?.i18n?.locale
2850
+ },
2851
+ {
2852
+ skip: selectedEntries.length === 0
2853
+ }
2854
+ );
2855
+ React.useEffect(() => {
2856
+ if (error) {
2857
+ toggleNotification({ type: "danger", message: formatAPIError(error) });
2858
+ }
2859
+ }, [error, formatAPIError, toggleNotification]);
2860
+ if (error) {
2861
+ return null;
2862
+ }
2863
+ return /* @__PURE__ */ jsx(
2864
+ ConfirmBulkActionDialog,
2865
+ {
2866
+ isOpen: isOpen && !isLoading,
2867
+ onToggleDialog,
2868
+ dialogBody: /* @__PURE__ */ jsxs(Fragment, { children: [
2869
+ /* @__PURE__ */ jsxs(Typography, { id: "confirm-description", textAlign: "center", children: [
2870
+ countDraftRelations > 0 && formatMessage(
2871
+ {
2872
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
2873
+ 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. "
2874
+ },
2875
+ {
2876
+ b: BoldChunk$1,
2877
+ count: countDraftRelations,
2878
+ entities: selectedEntries.length
2879
+ }
2880
+ ),
2881
+ formatMessage({
2882
+ id: getTranslation("popUpWarning.bodyMessage.contentType.publish.all"),
2883
+ defaultMessage: "Are you sure you want to publish these entries?"
2884
+ })
2885
+ ] }),
2886
+ schema?.pluginOptions && "i18n" in schema.pluginOptions && schema?.pluginOptions.i18n && /* @__PURE__ */ jsx(Typography, { textColor: "danger500", children: formatMessage(
2887
+ {
2888
+ id: getTranslation("Settings.list.actions.publishAdditionalInfos"),
2889
+ defaultMessage: "This will publish the active locale versions <em>(from Internationalization)</em>"
2890
+ },
2891
+ {
2892
+ em: Emphasis
2893
+ }
2894
+ ) })
2895
+ ] }),
2896
+ endAction: /* @__PURE__ */ jsx(
2897
+ Button,
2898
+ {
2899
+ onClick: onConfirm,
2900
+ variant: "secondary",
2901
+ startIcon: /* @__PURE__ */ jsx(Check, {}),
2902
+ loading: isConfirmButtonLoading,
2903
+ children: formatMessage({
2904
+ id: "app.utils.publish",
2905
+ defaultMessage: "Publish"
2906
+ })
2907
+ }
2908
+ )
2909
+ }
2910
+ );
2911
+ };
2912
+ const TypographyMaxWidth = styled(Typography)`
2913
+ max-width: 300px;
2914
+ `;
2915
+ const formatErrorMessages = (errors, parentKey, formatMessage) => {
2916
+ const messages = [];
2917
+ Object.entries(errors).forEach(([key, value]) => {
2918
+ const currentKey = parentKey ? `${parentKey}.${key}` : key;
2919
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
2920
+ if ("id" in value && "defaultMessage" in value) {
2921
+ messages.push(
2922
+ formatMessage(
2923
+ {
2924
+ id: `${value.id}.withField`,
2925
+ defaultMessage: value.defaultMessage
2926
+ },
2927
+ { field: currentKey }
2928
+ )
2552
2929
  );
2553
- toggleNotification({
2554
- message: formatMessage({
2555
- id: "content-manager.actions.edit.error",
2556
- defaultMessage: "An error occurred while trying to edit the document."
2557
- }),
2558
- type: "danger"
2559
- });
2560
- return;
2930
+ } else {
2931
+ messages.push(...formatErrorMessages(value, currentKey, formatMessage));
2932
+ }
2933
+ }
2934
+ });
2935
+ return messages;
2936
+ };
2937
+ const EntryValidationText = ({
2938
+ validationErrors,
2939
+ isPublished = false
2940
+ }) => {
2941
+ const { formatMessage } = useIntl();
2942
+ if (validationErrors) {
2943
+ const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
2944
+ " "
2945
+ );
2946
+ return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
2947
+ /* @__PURE__ */ jsx(CrossCircle, { fill: "danger600" }),
2948
+ /* @__PURE__ */ jsx(Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
2949
+ ] });
2950
+ }
2951
+ if (isPublished) {
2952
+ return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
2953
+ /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
2954
+ /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
2955
+ id: "content-manager.bulk-publish.already-published",
2956
+ defaultMessage: "Already Published"
2957
+ }) })
2958
+ ] });
2959
+ }
2960
+ return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
2961
+ /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
2962
+ /* @__PURE__ */ jsx(Typography, { children: formatMessage({
2963
+ id: "app.utils.ready-to-publish",
2964
+ defaultMessage: "Ready to publish"
2965
+ }) })
2966
+ ] });
2967
+ };
2968
+ const TABLE_HEADERS = [
2969
+ { name: "id", label: "id" },
2970
+ { name: "name", label: "name" },
2971
+ { name: "status", label: "status" },
2972
+ { name: "publicationStatus", label: "Publication status" }
2973
+ ];
2974
+ const SelectedEntriesTableContent = ({
2975
+ isPublishing,
2976
+ rowsToDisplay = [],
2977
+ entriesToPublish = [],
2978
+ validationErrors = {}
2979
+ }) => {
2980
+ const { pathname } = useLocation();
2981
+ const { formatMessage } = useIntl();
2982
+ const {
2983
+ list: {
2984
+ settings: { mainField }
2985
+ }
2986
+ } = useDocLayout();
2987
+ const shouldDisplayMainField = mainField != null && mainField !== "id";
2988
+ return /* @__PURE__ */ jsxs(Table.Content, { children: [
2989
+ /* @__PURE__ */ jsxs(Table.Head, { children: [
2990
+ /* @__PURE__ */ jsx(Table.HeaderCheckboxCell, {}),
2991
+ TABLE_HEADERS.filter((head) => head.name !== "name" || shouldDisplayMainField).map(
2992
+ (head) => /* @__PURE__ */ jsx(Table.HeaderCell, { ...head }, head.name)
2993
+ )
2994
+ ] }),
2995
+ /* @__PURE__ */ jsx(Table.Loading, {}),
2996
+ /* @__PURE__ */ jsx(Table.Body, { children: rowsToDisplay.map((row, index2) => /* @__PURE__ */ jsxs(Table.Row, { children: [
2997
+ /* @__PURE__ */ jsx(Table.CheckboxCell, { id: row.id }),
2998
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row.id }) }),
2999
+ shouldDisplayMainField && /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row[mainField] }) }),
3000
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(DocumentStatus, { status: row.status, maxWidth: "min-content" }) }),
3001
+ /* @__PURE__ */ jsx(Table.Cell, { children: isPublishing && entriesToPublish.includes(row.documentId) ? /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3002
+ /* @__PURE__ */ jsx(Typography, { children: formatMessage({
3003
+ id: "content-manager.success.record.publishing",
3004
+ defaultMessage: "Publishing..."
3005
+ }) }),
3006
+ /* @__PURE__ */ jsx(Loader, { small: true })
3007
+ ] }) : /* @__PURE__ */ jsx(
3008
+ EntryValidationText,
3009
+ {
3010
+ validationErrors: validationErrors[row.documentId],
3011
+ isPublished: row.publishedAt !== null
3012
+ }
3013
+ ) }),
3014
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
3015
+ IconButton,
3016
+ {
3017
+ tag: Link,
3018
+ to: {
3019
+ pathname: `${pathname}/${row.documentId}`,
3020
+ search: row.locale && `?plugins[i18n][locale]=${row.locale}`
3021
+ },
3022
+ state: { from: pathname },
3023
+ label: formatMessage(
3024
+ { id: "app.component.HelperPluginTable.edit", defaultMessage: "Edit {target}" },
3025
+ {
3026
+ target: formatMessage(
3027
+ {
3028
+ id: "content-manager.components.ListViewHelperPluginTable.row-line",
3029
+ defaultMessage: "item line {number}"
3030
+ },
3031
+ { number: index2 + 1 }
3032
+ )
3033
+ }
3034
+ ),
3035
+ target: "_blank",
3036
+ marginLeft: "auto",
3037
+ children: /* @__PURE__ */ jsx(Pencil, {})
3038
+ }
3039
+ ) })
3040
+ ] }, row.id)) })
3041
+ ] });
3042
+ };
3043
+ const BoldChunk = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
3044
+ const SelectedEntriesModalContent = ({
3045
+ listViewSelectedEntries,
3046
+ toggleModal,
3047
+ setListViewSelectedDocuments,
3048
+ model
3049
+ }) => {
3050
+ const { formatMessage } = useIntl();
3051
+ const { schema, components } = useContentTypeSchema(model);
3052
+ const documentIds = listViewSelectedEntries.map(({ documentId }) => documentId);
3053
+ const [{ query }] = useQueryParams();
3054
+ const params = React.useMemo(() => buildValidParams(query), [query]);
3055
+ const { data, isLoading, isFetching, refetch } = useGetAllDocumentsQuery(
3056
+ {
3057
+ model,
3058
+ params: {
3059
+ page: "1",
3060
+ pageSize: documentIds.length.toString(),
3061
+ sort: query.sort,
3062
+ filters: {
3063
+ documentId: {
3064
+ $in: documentIds
3065
+ }
3066
+ },
3067
+ locale: query.plugins?.i18n?.locale
2561
3068
  }
2562
- navigate({
2563
- pathname: documentId,
2564
- search: stringify({
2565
- plugins: query.plugins
2566
- })
3069
+ },
3070
+ {
3071
+ selectFromResult: ({ data: data2, ...restRes }) => ({ data: data2?.results ?? [], ...restRes })
3072
+ }
3073
+ );
3074
+ const { rows, validationErrors } = React.useMemo(() => {
3075
+ if (data.length > 0 && schema) {
3076
+ const validate = createYupSchema(schema.attributes, components);
3077
+ const validationErrors2 = {};
3078
+ const rows2 = data.map((entry) => {
3079
+ try {
3080
+ validate.validateSync(entry, { abortEarly: false });
3081
+ return entry;
3082
+ } catch (e) {
3083
+ if (e instanceof ValidationError) {
3084
+ validationErrors2[entry.documentId] = getYupValidationErrors(e);
3085
+ }
3086
+ return entry;
3087
+ }
3088
+ });
3089
+ return { rows: rows2, validationErrors: validationErrors2 };
3090
+ }
3091
+ return {
3092
+ rows: [],
3093
+ validationErrors: {}
3094
+ };
3095
+ }, [components, data, schema]);
3096
+ const [publishedCount, setPublishedCount] = React.useState(0);
3097
+ const [isDialogOpen, setIsDialogOpen] = React.useState(false);
3098
+ const { publishMany: bulkPublishAction } = useDocumentActions();
3099
+ const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
3100
+ const selectedEntries = useTable("publishAction", (state) => state.selectedRows);
3101
+ const entriesToPublish = selectedEntries.reduce((acc, entry) => {
3102
+ if (!validationErrors[entry.documentId]) {
3103
+ acc.push(entry.documentId);
3104
+ }
3105
+ return acc;
3106
+ }, []);
3107
+ const selectedEntriesWithErrorsCount = selectedEntries.filter(
3108
+ ({ documentId }) => validationErrors[documentId]
3109
+ ).length;
3110
+ const selectedEntriesPublished = selectedEntries.filter(
3111
+ ({ publishedAt }) => !!publishedAt
3112
+ ).length;
3113
+ const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublished;
3114
+ const toggleDialog = () => setIsDialogOpen((prev) => !prev);
3115
+ const handleConfirmBulkPublish = async () => {
3116
+ toggleDialog();
3117
+ const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
3118
+ if (!("error" in res)) {
3119
+ setPublishedCount(res.count);
3120
+ const unpublishedEntries = rows.filter((row) => {
3121
+ return !entriesToPublish.includes(row.documentId);
2567
3122
  });
3123
+ setListViewSelectedDocuments(unpublishedEntries);
2568
3124
  }
2569
3125
  };
2570
- };
2571
- EditAction.type = "edit";
2572
- const StyledPencil = styled(Pencil)`
2573
- path {
2574
- fill: currentColor;
2575
- }
2576
- `;
2577
- const CloneAction = ({ model, documentId }) => {
2578
- const navigate = useNavigate();
2579
- const { formatMessage } = useIntl();
2580
- const { canCreate } = useDocumentRBAC("CloneAction", ({ canCreate: canCreate2 }) => ({ canCreate: canCreate2 }));
2581
- const { toggleNotification } = useNotification();
2582
- const { autoClone } = useDocumentActions();
2583
- const [prohibitedFields, setProhibitedFields] = React.useState([]);
2584
- return {
2585
- disabled: !canCreate,
2586
- icon: /* @__PURE__ */ jsx(StyledDuplicate, {}),
2587
- label: formatMessage({
2588
- id: "content-manager.actions.clone.label",
2589
- defaultMessage: "Duplicate"
2590
- }),
2591
- position: "table-row",
2592
- onClick: async () => {
2593
- if (!documentId) {
2594
- console.error(
2595
- "You're trying to clone a document in the table without an id, this is likely a bug with Strapi. Please open an issue."
2596
- );
2597
- toggleNotification({
2598
- message: formatMessage({
2599
- id: "content-manager.actions.clone.error",
2600
- defaultMessage: "An error occurred while trying to clone the document."
2601
- }),
2602
- type: "danger"
2603
- });
2604
- return;
3126
+ const getFormattedCountMessage = () => {
3127
+ if (publishedCount) {
3128
+ return formatMessage(
3129
+ {
3130
+ id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
3131
+ 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."
3132
+ },
3133
+ {
3134
+ publishedCount,
3135
+ withErrorsCount: selectedEntriesWithErrorsCount,
3136
+ b: BoldChunk
3137
+ }
3138
+ );
3139
+ }
3140
+ return formatMessage(
3141
+ {
3142
+ id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
3143
+ 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."
3144
+ },
3145
+ {
3146
+ readyToPublishCount: selectedEntriesWithNoErrorsCount,
3147
+ withErrorsCount: selectedEntriesWithErrorsCount,
3148
+ alreadyPublishedCount: selectedEntriesPublished,
3149
+ b: BoldChunk
2605
3150
  }
2606
- const res = await autoClone({ model, sourceId: documentId });
2607
- if ("data" in res) {
2608
- navigate(res.data.documentId);
2609
- return true;
3151
+ );
3152
+ };
3153
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3154
+ /* @__PURE__ */ jsxs(ModalBody, { children: [
3155
+ /* @__PURE__ */ jsx(Typography, { children: getFormattedCountMessage() }),
3156
+ /* @__PURE__ */ jsx(Box, { marginTop: 5, children: /* @__PURE__ */ jsx(
3157
+ SelectedEntriesTableContent,
3158
+ {
3159
+ isPublishing: isSubmittingForm,
3160
+ rowsToDisplay: rows,
3161
+ entriesToPublish,
3162
+ validationErrors
3163
+ }
3164
+ ) })
3165
+ ] }),
3166
+ /* @__PURE__ */ jsx(
3167
+ ModalFooter,
3168
+ {
3169
+ startActions: /* @__PURE__ */ jsx(Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
3170
+ id: "app.components.Button.cancel",
3171
+ defaultMessage: "Cancel"
3172
+ }) }),
3173
+ endActions: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3174
+ /* @__PURE__ */ jsx(Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
3175
+ /* @__PURE__ */ jsx(
3176
+ Button,
3177
+ {
3178
+ onClick: toggleDialog,
3179
+ disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || isLoading,
3180
+ loading: isSubmittingForm,
3181
+ children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
3182
+ }
3183
+ )
3184
+ ] })
2610
3185
  }
2611
- if (isBaseQueryError(res.error) && res.error.details && typeof res.error.details === "object" && "prohibitedFields" in res.error.details && Array.isArray(res.error.details.prohibitedFields)) {
2612
- const prohibitedFields2 = res.error.details.prohibitedFields;
2613
- setProhibitedFields(prohibitedFields2);
3186
+ ),
3187
+ /* @__PURE__ */ jsx(
3188
+ ConfirmDialogPublishAll,
3189
+ {
3190
+ isOpen: isDialogOpen,
3191
+ onToggleDialog: toggleDialog,
3192
+ isConfirmButtonLoading: isSubmittingForm,
3193
+ onConfirm: handleConfirmBulkPublish
2614
3194
  }
2615
- },
3195
+ )
3196
+ ] });
3197
+ };
3198
+ const PublishAction = ({ documents, model }) => {
3199
+ const { formatMessage } = useIntl();
3200
+ const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
3201
+ const showPublishButton = hasPublishPermission && documents.some(({ status }) => status !== "published");
3202
+ const setListViewSelectedDocuments = useTable("publishAction", (state) => state.selectRow);
3203
+ const refetchList = () => {
3204
+ contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
3205
+ };
3206
+ if (!showPublishButton)
3207
+ return null;
3208
+ return {
3209
+ actionType: "publish",
3210
+ variant: "tertiary",
3211
+ label: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" }),
2616
3212
  dialog: {
2617
3213
  type: "modal",
2618
3214
  title: formatMessage({
2619
- id: "content-manager.containers.list.autoCloneModal.header",
2620
- defaultMessage: "Duplicate"
3215
+ id: getTranslation("containers.ListPage.selectedEntriesModal.title"),
3216
+ defaultMessage: "Publish entries"
2621
3217
  }),
2622
- content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
2623
- footer: ({ onClose }) => {
2624
- return /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", children: [
2625
- /* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
2626
- id: "cancel",
2627
- defaultMessage: "Cancel"
2628
- }) }),
2629
- /* @__PURE__ */ jsx(
2630
- LinkButton,
2631
- {
2632
- as: NavLink,
2633
- to: {
2634
- pathname: `clone/${documentId}`
2635
- },
2636
- children: formatMessage({
2637
- id: "content-manager.containers.list.autoCloneModal.create",
2638
- defaultMessage: "Create"
2639
- })
2640
- }
2641
- )
2642
- ] });
3218
+ content: ({ onClose }) => {
3219
+ return /* @__PURE__ */ jsx(Table.Root, { rows: documents, defaultSelectedRows: documents, headers: TABLE_HEADERS, children: /* @__PURE__ */ jsx(
3220
+ SelectedEntriesModalContent,
3221
+ {
3222
+ listViewSelectedEntries: documents,
3223
+ toggleModal: () => {
3224
+ onClose();
3225
+ refetchList();
3226
+ },
3227
+ setListViewSelectedDocuments,
3228
+ model
3229
+ }
3230
+ ) });
3231
+ },
3232
+ onClose: () => {
3233
+ refetchList();
2643
3234
  }
2644
3235
  }
2645
3236
  };
2646
3237
  };
2647
- CloneAction.type = "clone";
2648
- const StyledDuplicate = styled(Duplicate)`
2649
- path {
2650
- fill: currentColor;
2651
- }
2652
- `;
2653
- const DEFAULT_TABLE_ROW_ACTIONS = [EditAction, CloneAction];
2654
- class ContentManagerPlugin {
2655
- /**
2656
- * The following properties are the stored ones provided by any plugins registering with
2657
- * the content-manager. The function calls however, need to be called at runtime in the
2658
- * application, so instead we collate them and run them later with the complete list incl.
2659
- * ones already registered & the context of the view.
2660
- */
2661
- bulkActions = [...DEFAULT_BULK_ACTIONS];
2662
- documentActions = [
2663
- ...DEFAULT_ACTIONS,
2664
- ...DEFAULT_TABLE_ROW_ACTIONS,
2665
- ...DEFAULT_HEADER_ACTIONS,
2666
- HistoryAction
2667
- ];
2668
- editViewSidePanels = [ActionsPanel];
2669
- headerActions = [];
2670
- constructor() {
2671
- }
2672
- addEditViewSidePanel(panels) {
2673
- if (Array.isArray(panels)) {
2674
- this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
2675
- } else if (typeof panels === "function") {
2676
- this.editViewSidePanels = panels(this.editViewSidePanels);
2677
- } else {
2678
- throw new Error(
2679
- `Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
2680
- panels
2681
- )}`
2682
- );
3238
+ const BulkActionsRenderer = () => {
3239
+ const plugins = useStrapiApp("BulkActionsRenderer", (state) => state.plugins);
3240
+ const { model, collectionType } = useDoc();
3241
+ const { selectedRows } = useTable("BulkActionsRenderer", (state) => state);
3242
+ return /* @__PURE__ */ jsx(Flex, { gap: 2, children: /* @__PURE__ */ jsx(
3243
+ DescriptionComponentRenderer,
3244
+ {
3245
+ props: {
3246
+ model,
3247
+ collectionType,
3248
+ documents: selectedRows
3249
+ },
3250
+ descriptions: plugins["content-manager"].apis.getBulkActions(),
3251
+ children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(BulkActionAction, { ...action }, action.id))
2683
3252
  }
2684
- }
2685
- addDocumentAction(actions2) {
2686
- if (Array.isArray(actions2)) {
2687
- this.documentActions = [...this.documentActions, ...actions2];
2688
- } else if (typeof actions2 === "function") {
2689
- this.documentActions = actions2(this.documentActions);
2690
- } else {
2691
- throw new Error(
2692
- `Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
2693
- actions2
2694
- )}`
2695
- );
3253
+ ) });
3254
+ };
3255
+ const BulkActionAction = (action) => {
3256
+ const [dialogId, setDialogId] = React.useState(null);
3257
+ const { toggleNotification } = useNotification();
3258
+ const handleClick = (action2) => (e) => {
3259
+ const { onClick, dialog, id } = action2;
3260
+ if (onClick) {
3261
+ onClick(e);
2696
3262
  }
2697
- }
2698
- addDocumentHeaderAction(actions2) {
2699
- if (Array.isArray(actions2)) {
2700
- this.headerActions = [...this.headerActions, ...actions2];
2701
- } else if (typeof actions2 === "function") {
2702
- this.headerActions = actions2(this.headerActions);
2703
- } else {
2704
- throw new Error(
2705
- `Expected the \`actions\` passed to \`addDocumentHeaderAction\` to be an array or a function, but received ${getPrintableType(
2706
- actions2
2707
- )}`
2708
- );
3263
+ if (dialog) {
3264
+ switch (dialog.type) {
3265
+ case "notification":
3266
+ toggleNotification({
3267
+ title: dialog.title,
3268
+ message: dialog.content,
3269
+ type: dialog.status,
3270
+ timeout: dialog.timeout,
3271
+ onClose: dialog.onClose
3272
+ });
3273
+ break;
3274
+ case "dialog":
3275
+ case "modal": {
3276
+ e.preventDefault();
3277
+ setDialogId(id);
3278
+ }
3279
+ }
3280
+ }
3281
+ };
3282
+ const handleClose = () => {
3283
+ setDialogId(null);
3284
+ if (action.dialog?.type === "modal" && action.dialog?.onClose) {
3285
+ action.dialog.onClose();
3286
+ }
3287
+ };
3288
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3289
+ /* @__PURE__ */ jsx(
3290
+ Button,
3291
+ {
3292
+ disabled: action.disabled,
3293
+ startIcon: action.icon,
3294
+ variant: action.variant,
3295
+ onClick: handleClick(action),
3296
+ children: action.label
3297
+ }
3298
+ ),
3299
+ action.dialog?.type === "dialog" ? /* @__PURE__ */ jsx(
3300
+ BulkActionConfirmDialog,
3301
+ {
3302
+ ...action.dialog,
3303
+ variant: action.variant,
3304
+ isOpen: dialogId === action.id,
3305
+ onClose: handleClose
3306
+ }
3307
+ ) : null,
3308
+ action.dialog?.type === "modal" ? /* @__PURE__ */ jsx(
3309
+ BulkActionModal,
3310
+ {
3311
+ ...action.dialog,
3312
+ onModalClose: handleClose,
3313
+ isOpen: dialogId === action.id
3314
+ }
3315
+ ) : null
3316
+ ] });
3317
+ };
3318
+ const BulkActionConfirmDialog = ({
3319
+ onClose,
3320
+ onCancel,
3321
+ onConfirm,
3322
+ title,
3323
+ content,
3324
+ confirmButton,
3325
+ isOpen,
3326
+ variant = "secondary"
3327
+ }) => {
3328
+ const { formatMessage } = useIntl();
3329
+ const handleClose = async () => {
3330
+ if (onCancel) {
3331
+ await onCancel();
2709
3332
  }
2710
- }
2711
- addBulkAction(actions2) {
2712
- if (Array.isArray(actions2)) {
2713
- this.bulkActions = [...this.bulkActions, ...actions2];
2714
- } else if (typeof actions2 === "function") {
2715
- this.bulkActions = actions2(this.bulkActions);
2716
- } else {
2717
- throw new Error(
2718
- `Expected the \`actions\` passed to \`addBulkAction\` to be an array or a function, but received ${getPrintableType(
2719
- actions2
2720
- )}`
2721
- );
3333
+ onClose();
3334
+ };
3335
+ const handleConfirm = async () => {
3336
+ if (onConfirm) {
3337
+ await onConfirm();
2722
3338
  }
2723
- }
2724
- get config() {
2725
- return {
2726
- id: PLUGIN_ID,
2727
- name: "Content Manager",
2728
- injectionZones: INJECTION_ZONES,
2729
- apis: {
2730
- addBulkAction: this.addBulkAction.bind(this),
2731
- addDocumentAction: this.addDocumentAction.bind(this),
2732
- addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
2733
- addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
2734
- getBulkActions: () => this.bulkActions,
2735
- getDocumentActions: () => this.documentActions,
2736
- getEditViewSidePanels: () => this.editViewSidePanels,
2737
- getHeaderActions: () => this.headerActions
3339
+ onClose();
3340
+ };
3341
+ return /* @__PURE__ */ jsxs(Dialog, { isOpen, title, onClose: handleClose, children: [
3342
+ /* @__PURE__ */ jsx(DialogBody, { icon: /* @__PURE__ */ jsx(WarningCircle, {}), children: content }),
3343
+ /* @__PURE__ */ jsx(
3344
+ DialogFooter,
3345
+ {
3346
+ startAction: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", children: formatMessage({
3347
+ id: "app.components.Button.cancel",
3348
+ defaultMessage: "Cancel"
3349
+ }) }),
3350
+ endAction: /* @__PURE__ */ jsx(
3351
+ Button,
3352
+ {
3353
+ onClick: handleConfirm,
3354
+ variant: variant === "danger-light" ? variant : "secondary",
3355
+ startIcon: variant === "danger-light" ? /* @__PURE__ */ jsx(Trash, {}) : /* @__PURE__ */ jsx(Check, {}),
3356
+ children: confirmButton ? confirmButton : formatMessage({
3357
+ id: "app.components.Button.confirm",
3358
+ defaultMessage: "Confirm"
3359
+ })
3360
+ }
3361
+ )
2738
3362
  }
2739
- };
3363
+ )
3364
+ ] });
3365
+ };
3366
+ const BulkActionModal = ({
3367
+ isOpen,
3368
+ title,
3369
+ onClose,
3370
+ content: Content,
3371
+ onModalClose
3372
+ }) => {
3373
+ const id = React.useId();
3374
+ if (!isOpen) {
3375
+ return null;
2740
3376
  }
2741
- }
2742
- const getPrintableType = (value) => {
2743
- const nativeType = typeof value;
2744
- if (nativeType === "object") {
2745
- if (value === null)
2746
- return "null";
2747
- if (Array.isArray(value))
2748
- return "array";
2749
- if (value instanceof Object && value.constructor.name !== "Object") {
2750
- return value.constructor.name;
3377
+ const handleClose = () => {
3378
+ if (onClose) {
3379
+ onClose();
2751
3380
  }
2752
- }
2753
- return nativeType;
2754
- };
2755
- const initialState = {
2756
- collectionTypeLinks: [],
2757
- components: [],
2758
- fieldSizes: {},
2759
- models: [],
2760
- singleTypeLinks: [],
2761
- isLoading: true
3381
+ onModalClose();
3382
+ };
3383
+ return /* @__PURE__ */ jsxs(ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
3384
+ /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
3385
+ /* @__PURE__ */ jsx(Content, { onClose: handleClose })
3386
+ ] });
2762
3387
  };
2763
- const appSlice = createSlice({
2764
- name: "app",
2765
- initialState,
2766
- reducers: {
2767
- setInitialData(state, action) {
2768
- const {
2769
- authorizedCollectionTypeLinks,
2770
- authorizedSingleTypeLinks,
2771
- components,
2772
- contentTypeSchemas,
2773
- fieldSizes
2774
- } = action.payload;
2775
- state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
2776
- ({ isDisplayed }) => isDisplayed
2777
- );
2778
- state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
2779
- state.components = components;
2780
- state.models = contentTypeSchemas;
2781
- state.fieldSizes = fieldSizes;
2782
- state.isLoading = false;
3388
+ const DeleteAction = ({ documents, model }) => {
3389
+ const { formatMessage } = useIntl();
3390
+ const { schema: contentType } = useDoc();
3391
+ const selectRow = useTable("DeleteAction", (state) => state.selectRow);
3392
+ const hasI18nEnabled = Boolean(contentType?.pluginOptions?.i18n);
3393
+ const [{ query }] = useQueryParams();
3394
+ const params = React.useMemo(() => buildValidParams(query), [query]);
3395
+ const hasDeletePermission = useDocumentRBAC("deleteAction", (state) => state.canDelete);
3396
+ const { deleteMany: bulkDeleteAction } = useDocumentActions();
3397
+ const documentIds = documents.map(({ documentId }) => documentId);
3398
+ const handleConfirmBulkDelete = async () => {
3399
+ const res = await bulkDeleteAction({
3400
+ documentIds,
3401
+ model,
3402
+ params
3403
+ });
3404
+ if (!("error" in res)) {
3405
+ selectRow([]);
2783
3406
  }
2784
- }
2785
- });
2786
- const { actions, reducer: reducer$1 } = appSlice;
2787
- const { setInitialData } = actions;
2788
- const reducer = combineReducers({
2789
- app: reducer$1
2790
- });
2791
- const HOOKS = {
2792
- /**
2793
- * Hook that allows to mutate the displayed headers of the list view table
2794
- * @constant
2795
- * @type {string}
2796
- */
2797
- INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
2798
- /**
2799
- * Hook that allows to mutate the CM's collection types links pre-set filters
2800
- * @constant
2801
- * @type {string}
2802
- */
2803
- MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
2804
- /**
2805
- * Hook that allows to mutate the CM's edit view layout
2806
- * @constant
2807
- * @type {string}
2808
- */
2809
- MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
2810
- /**
2811
- * Hook that allows to mutate the CM's single types links pre-set filters
2812
- * @constant
2813
- * @type {string}
2814
- */
2815
- MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
2816
- };
2817
- const contentTypesApi = contentManagerApi.injectEndpoints({
2818
- endpoints: (builder) => ({
2819
- getContentTypeConfiguration: builder.query({
2820
- query: (uid) => ({
2821
- url: `/content-manager/content-types/${uid}/configuration`,
2822
- method: "GET"
2823
- }),
2824
- transformResponse: (response) => response.data,
2825
- providesTags: (_result, _error, uid) => [
2826
- { type: "ContentTypesConfiguration", id: uid },
2827
- { type: "ContentTypeSettings", id: "LIST" }
2828
- ]
2829
- }),
2830
- getAllContentTypeSettings: builder.query({
2831
- query: () => "/content-manager/content-types-settings",
2832
- transformResponse: (response) => response.data,
2833
- providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
2834
- }),
2835
- updateContentTypeConfiguration: builder.mutation({
2836
- query: ({ uid, ...body }) => ({
2837
- url: `/content-manager/content-types/${uid}/configuration`,
2838
- method: "PUT",
2839
- data: body
2840
- }),
2841
- transformResponse: (response) => response.data,
2842
- invalidatesTags: (_result, _error, { uid }) => [
2843
- { type: "ContentTypesConfiguration", id: uid },
2844
- { type: "ContentTypeSettings", id: "LIST" },
2845
- // Is this necessary?
2846
- { type: "InitialData" }
2847
- ]
2848
- })
2849
- })
2850
- });
2851
- const {
2852
- useGetContentTypeConfigurationQuery,
2853
- useGetAllContentTypeSettingsQuery,
2854
- useUpdateContentTypeConfigurationMutation
2855
- } = contentTypesApi;
2856
- const checkIfAttributeIsDisplayable = (attribute) => {
2857
- const { type } = attribute;
2858
- if (type === "relation") {
2859
- return !attribute.relation.toLowerCase().includes("morph");
2860
- }
2861
- return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
2862
- };
2863
- const getMainField = (attribute, mainFieldName, { schemas, components }) => {
2864
- if (!mainFieldName) {
2865
- return void 0;
2866
- }
2867
- const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
2868
- // @ts-expect-error – `targetModel` does exist on the attribute for a relation.
2869
- schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
2870
- );
3407
+ };
3408
+ if (!hasDeletePermission)
3409
+ return null;
2871
3410
  return {
2872
- name: mainFieldName,
2873
- type: mainFieldType ?? "string"
3411
+ variant: "danger-light",
3412
+ label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
3413
+ dialog: {
3414
+ type: "dialog",
3415
+ title: formatMessage({
3416
+ id: "app.components.ConfirmDialog.title",
3417
+ defaultMessage: "Confirmation"
3418
+ }),
3419
+ content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3420
+ /* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3421
+ id: "popUpWarning.bodyMessage.contentType.delete.all",
3422
+ defaultMessage: "Are you sure you want to delete these entries?"
3423
+ }) }),
3424
+ hasI18nEnabled && /* @__PURE__ */ jsx(Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsx(Typography, { textColor: "danger500", children: formatMessage(
3425
+ {
3426
+ id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
3427
+ defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
3428
+ },
3429
+ {
3430
+ em: Emphasis
3431
+ }
3432
+ ) }) })
3433
+ ] }),
3434
+ onConfirm: handleConfirmBulkDelete
3435
+ }
2874
3436
  };
2875
3437
  };
2876
- const DEFAULT_SETTINGS = {
2877
- bulkable: false,
2878
- filterable: false,
2879
- searchable: false,
2880
- pagination: false,
2881
- defaultSortBy: "",
2882
- defaultSortOrder: "asc",
2883
- mainField: "id",
2884
- pageSize: 10
2885
- };
2886
- const useDocumentLayout = (model) => {
2887
- const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
3438
+ DeleteAction.type = "delete";
3439
+ const UnpublishAction = ({ documents, model }) => {
3440
+ const { formatMessage } = useIntl();
3441
+ const { schema } = useDoc();
3442
+ const selectRow = useTable("UnpublishAction", (state) => state.selectRow);
3443
+ const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
3444
+ const hasI18nEnabled = Boolean(schema?.pluginOptions?.i18n);
3445
+ const hasDraftAndPublishEnabled = Boolean(schema?.options?.draftAndPublish);
3446
+ const { unpublishMany: bulkUnpublishAction } = useDocumentActions();
3447
+ const documentIds = documents.map(({ documentId }) => documentId);
2888
3448
  const [{ query }] = useQueryParams();
2889
- const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
2890
- const { toggleNotification } = useNotification();
2891
- const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
2892
- const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
2893
- const {
2894
- data,
2895
- isLoading: isLoadingConfigs,
2896
- error,
2897
- isFetching: isFetchingConfigs
2898
- } = useGetContentTypeConfigurationQuery(model);
2899
- const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
2900
- React.useEffect(() => {
2901
- if (error) {
2902
- toggleNotification({
2903
- type: "danger",
2904
- message: formatAPIError(error)
2905
- });
3449
+ const params = React.useMemo(() => buildValidParams(query), [query]);
3450
+ const handleConfirmBulkUnpublish = async () => {
3451
+ const data = await bulkUnpublishAction({ documentIds, model, params });
3452
+ if (!("error" in data)) {
3453
+ selectRow([]);
2906
3454
  }
2907
- }, [error, formatAPIError, toggleNotification]);
2908
- const editLayout = React.useMemo(
2909
- () => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
2910
- layout: [],
2911
- components: {},
2912
- metadatas: {},
2913
- options: {},
2914
- settings: DEFAULT_SETTINGS
2915
- },
2916
- [data, isLoading, schemas, schema, components]
2917
- );
2918
- const listLayout = React.useMemo(() => {
2919
- return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
2920
- layout: [],
2921
- metadatas: {},
2922
- options: {},
2923
- settings: DEFAULT_SETTINGS
2924
- };
2925
- }, [data, isLoading, schemas, schema, components]);
2926
- const { layout: edit } = React.useMemo(
2927
- () => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
2928
- layout: editLayout,
2929
- query
2930
- }),
2931
- [editLayout, query, runHookWaterfall]
2932
- );
3455
+ };
3456
+ const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published");
3457
+ if (!showUnpublishButton)
3458
+ return null;
2933
3459
  return {
2934
- error,
2935
- isLoading,
2936
- edit,
2937
- list: listLayout
3460
+ variant: "tertiary",
3461
+ label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
3462
+ dialog: {
3463
+ type: "dialog",
3464
+ title: formatMessage({
3465
+ id: "app.components.ConfirmDialog.title",
3466
+ defaultMessage: "Confirmation"
3467
+ }),
3468
+ content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3469
+ /* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3470
+ id: "popUpWarning.bodyMessage.contentType.unpublish.all",
3471
+ defaultMessage: "Are you sure you want to unpublish these entries?"
3472
+ }) }),
3473
+ hasI18nEnabled && /* @__PURE__ */ jsx(Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsx(Typography, { textColor: "danger500", children: formatMessage(
3474
+ {
3475
+ id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
3476
+ defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
3477
+ },
3478
+ {
3479
+ em: Emphasis
3480
+ }
3481
+ ) }) })
3482
+ ] }),
3483
+ confirmButton: formatMessage({
3484
+ id: "app.utils.unpublish",
3485
+ defaultMessage: "Unpublish"
3486
+ }),
3487
+ onConfirm: handleConfirmBulkUnpublish
3488
+ }
2938
3489
  };
2939
3490
  };
2940
- const useDocLayout = () => {
2941
- const { model } = useDoc();
2942
- return useDocumentLayout(model);
3491
+ UnpublishAction.type = "unpublish";
3492
+ const Emphasis = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
3493
+ const DEFAULT_BULK_ACTIONS = [PublishAction, UnpublishAction, DeleteAction];
3494
+ const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
3495
+ const { formatMessage } = useIntl();
3496
+ const getDefaultErrorMessage = (reason) => {
3497
+ switch (reason) {
3498
+ case "relation":
3499
+ return "Duplicating the relation could remove it from the original entry.";
3500
+ case "unique":
3501
+ return "Identical values in a unique field are not allowed";
3502
+ default:
3503
+ return reason;
3504
+ }
3505
+ };
3506
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3507
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", children: formatMessage({
3508
+ id: getTranslation("containers.list.autoCloneModal.title"),
3509
+ defaultMessage: "This entry can't be duplicated directly."
3510
+ }) }),
3511
+ /* @__PURE__ */ jsx(Box, { marginTop: 2, children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: formatMessage({
3512
+ id: getTranslation("containers.list.autoCloneModal.description"),
3513
+ defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
3514
+ }) }) }),
3515
+ /* @__PURE__ */ jsx(Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxs(
3516
+ Flex,
3517
+ {
3518
+ direction: "column",
3519
+ gap: 2,
3520
+ alignItems: "flex-start",
3521
+ borderColor: "neutral200",
3522
+ hasRadius: true,
3523
+ padding: 6,
3524
+ children: [
3525
+ /* @__PURE__ */ jsx(Flex, { direction: "row", tag: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxs(Typography, { fontWeight: "semiBold", tag: "li", children: [
3526
+ pathSegment,
3527
+ index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsx(
3528
+ ChevronRight,
3529
+ {
3530
+ fill: "neutral500",
3531
+ height: "0.8rem",
3532
+ width: "0.8rem",
3533
+ style: { margin: "0 0.8rem" }
3534
+ }
3535
+ )
3536
+ ] }, index2)) }),
3537
+ /* @__PURE__ */ jsx(Typography, { tag: "p", textColor: "neutral600", children: formatMessage({
3538
+ id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
3539
+ defaultMessage: getDefaultErrorMessage(reason)
3540
+ }) })
3541
+ ]
3542
+ },
3543
+ fieldPath.join()
3544
+ )) })
3545
+ ] });
2943
3546
  };
2944
- const formatEditLayout = (data, {
2945
- schemas,
2946
- schema,
2947
- components
2948
- }) => {
2949
- let currentPanelIndex = 0;
2950
- const panelledEditAttributes = convertEditLayoutToFieldLayouts(
2951
- data.contentType.layouts.edit,
2952
- schema?.attributes,
2953
- data.contentType.metadatas,
2954
- { configurations: data.components, schemas: components },
2955
- schemas
2956
- ).reduce((panels, row) => {
2957
- if (row.some((field) => field.type === "dynamiczone")) {
2958
- panels.push([row]);
2959
- currentPanelIndex += 2;
2960
- } else {
2961
- if (!panels[currentPanelIndex]) {
2962
- panels.push([]);
3547
+ const TableActions = ({ document }) => {
3548
+ const { formatMessage } = useIntl();
3549
+ const { model, collectionType } = useDoc();
3550
+ const plugins = useStrapiApp("TableActions", (state) => state.plugins);
3551
+ const props = {
3552
+ activeTab: null,
3553
+ model,
3554
+ documentId: document.documentId,
3555
+ collectionType,
3556
+ document
3557
+ };
3558
+ return /* @__PURE__ */ jsx(
3559
+ DescriptionComponentRenderer,
3560
+ {
3561
+ props,
3562
+ descriptions: plugins["content-manager"].apis.getDocumentActions(),
3563
+ children: (actions2) => {
3564
+ const tableRowActions = actions2.filter((action) => {
3565
+ const positions = Array.isArray(action.position) ? action.position : [action.position];
3566
+ return positions.includes("table-row");
3567
+ });
3568
+ return /* @__PURE__ */ jsx(
3569
+ DocumentActionsMenu,
3570
+ {
3571
+ actions: tableRowActions,
3572
+ label: formatMessage({
3573
+ id: "content-manager.containers.list.table.row-actions",
3574
+ defaultMessage: "Row action"
3575
+ }),
3576
+ variant: "ghost"
3577
+ }
3578
+ );
2963
3579
  }
2964
- panels[currentPanelIndex].push(row);
2965
3580
  }
2966
- return panels;
2967
- }, []);
2968
- const componentEditAttributes = Object.entries(data.components).reduce(
2969
- (acc, [uid, configuration]) => {
2970
- acc[uid] = {
2971
- layout: convertEditLayoutToFieldLayouts(
2972
- configuration.layouts.edit,
2973
- components[uid].attributes,
2974
- configuration.metadatas
2975
- ),
2976
- settings: {
2977
- ...configuration.settings,
2978
- icon: components[uid].info.icon,
2979
- displayName: components[uid].info.displayName
2980
- }
2981
- };
2982
- return acc;
2983
- },
2984
- {}
2985
- );
2986
- const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
2987
- (acc, [attribute, metadata]) => {
2988
- return {
2989
- ...acc,
2990
- [attribute]: metadata.edit
2991
- };
2992
- },
2993
- {}
2994
3581
  );
3582
+ };
3583
+ const EditAction = ({ documentId }) => {
3584
+ const navigate = useNavigate();
3585
+ const { formatMessage } = useIntl();
3586
+ const { canRead } = useDocumentRBAC("EditAction", ({ canRead: canRead2 }) => ({ canRead: canRead2 }));
3587
+ const { toggleNotification } = useNotification();
3588
+ const [{ query }] = useQueryParams();
2995
3589
  return {
2996
- layout: panelledEditAttributes,
2997
- components: componentEditAttributes,
2998
- metadatas: editMetadatas,
2999
- settings: {
3000
- ...data.contentType.settings,
3001
- displayName: schema?.info.displayName
3002
- },
3003
- options: {
3004
- ...schema?.options,
3005
- ...schema?.pluginOptions,
3006
- ...data.contentType.options
3590
+ disabled: !canRead,
3591
+ icon: /* @__PURE__ */ jsx(StyledPencil, {}),
3592
+ label: formatMessage({
3593
+ id: "content-manager.actions.edit.label",
3594
+ defaultMessage: "Edit"
3595
+ }),
3596
+ position: "table-row",
3597
+ onClick: async () => {
3598
+ if (!documentId) {
3599
+ console.error(
3600
+ "You're trying to edit a document without an id, this is likely a bug with Strapi. Please open an issue."
3601
+ );
3602
+ toggleNotification({
3603
+ message: formatMessage({
3604
+ id: "content-manager.actions.edit.error",
3605
+ defaultMessage: "An error occurred while trying to edit the document."
3606
+ }),
3607
+ type: "danger"
3608
+ });
3609
+ return;
3610
+ }
3611
+ navigate({
3612
+ pathname: documentId,
3613
+ search: stringify({
3614
+ plugins: query.plugins
3615
+ })
3616
+ });
3007
3617
  }
3008
3618
  };
3009
3619
  };
3010
- const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
3011
- return rows.map(
3012
- (row) => row.map((field) => {
3013
- const attribute = attributes[field.name];
3014
- if (!attribute) {
3015
- return null;
3016
- }
3017
- const { edit: metadata } = metadatas[field.name];
3018
- const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
3019
- return {
3020
- attribute,
3021
- disabled: !metadata.editable,
3022
- hint: metadata.description,
3023
- label: metadata.label ?? "",
3024
- name: field.name,
3025
- // @ts-expect-error – mainField does exist on the metadata for a relation.
3026
- mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
3027
- schemas,
3028
- components: components?.schemas ?? {}
3029
- }),
3030
- placeholder: metadata.placeholder ?? "",
3031
- required: attribute.required ?? false,
3032
- size: field.size,
3033
- unique: "unique" in attribute ? attribute.unique : false,
3034
- visible: metadata.visible ?? true,
3035
- type: attribute.type
3036
- };
3037
- }).filter((field) => field !== null)
3038
- );
3039
- };
3040
- const formatListLayout = (data, {
3041
- schemas,
3042
- schema,
3043
- components
3044
- }) => {
3045
- const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
3046
- (acc, [attribute, metadata]) => {
3047
- return {
3048
- ...acc,
3049
- [attribute]: metadata.list
3050
- };
3051
- },
3052
- {}
3053
- );
3054
- const listAttributes = convertListLayoutToFieldLayouts(
3055
- data.contentType.layouts.list,
3056
- schema?.attributes,
3057
- listMetadatas,
3058
- { configurations: data.components, schemas: components },
3059
- schemas
3060
- );
3620
+ EditAction.type = "edit";
3621
+ const StyledPencil = styled(Pencil)`
3622
+ path {
3623
+ fill: currentColor;
3624
+ }
3625
+ `;
3626
+ const CloneAction = ({ model, documentId }) => {
3627
+ const navigate = useNavigate();
3628
+ const { formatMessage } = useIntl();
3629
+ const { canCreate } = useDocumentRBAC("CloneAction", ({ canCreate: canCreate2 }) => ({ canCreate: canCreate2 }));
3630
+ const { toggleNotification } = useNotification();
3631
+ const { autoClone } = useDocumentActions();
3632
+ const [prohibitedFields, setProhibitedFields] = React.useState([]);
3061
3633
  return {
3062
- layout: listAttributes,
3063
- settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
3064
- metadatas: listMetadatas,
3065
- options: {
3066
- ...schema?.options,
3067
- ...schema?.pluginOptions,
3068
- ...data.contentType.options
3634
+ disabled: !canCreate,
3635
+ icon: /* @__PURE__ */ jsx(StyledDuplicate, {}),
3636
+ label: formatMessage({
3637
+ id: "content-manager.actions.clone.label",
3638
+ defaultMessage: "Duplicate"
3639
+ }),
3640
+ position: "table-row",
3641
+ onClick: async () => {
3642
+ if (!documentId) {
3643
+ console.error(
3644
+ "You're trying to clone a document in the table without an id, this is likely a bug with Strapi. Please open an issue."
3645
+ );
3646
+ toggleNotification({
3647
+ message: formatMessage({
3648
+ id: "content-manager.actions.clone.error",
3649
+ defaultMessage: "An error occurred while trying to clone the document."
3650
+ }),
3651
+ type: "danger"
3652
+ });
3653
+ return;
3654
+ }
3655
+ const res = await autoClone({ model, sourceId: documentId });
3656
+ if ("data" in res) {
3657
+ navigate(res.data.documentId);
3658
+ return true;
3659
+ }
3660
+ if (isBaseQueryError(res.error) && res.error.details && typeof res.error.details === "object" && "prohibitedFields" in res.error.details && Array.isArray(res.error.details.prohibitedFields)) {
3661
+ const prohibitedFields2 = res.error.details.prohibitedFields;
3662
+ setProhibitedFields(prohibitedFields2);
3663
+ }
3664
+ },
3665
+ dialog: {
3666
+ type: "modal",
3667
+ title: formatMessage({
3668
+ id: "content-manager.containers.list.autoCloneModal.header",
3669
+ defaultMessage: "Duplicate"
3670
+ }),
3671
+ content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
3672
+ footer: ({ onClose }) => {
3673
+ return /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", children: [
3674
+ /* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
3675
+ id: "cancel",
3676
+ defaultMessage: "Cancel"
3677
+ }) }),
3678
+ /* @__PURE__ */ jsx(
3679
+ LinkButton,
3680
+ {
3681
+ tag: NavLink,
3682
+ to: {
3683
+ pathname: `clone/${documentId}`
3684
+ },
3685
+ children: formatMessage({
3686
+ id: "content-manager.containers.list.autoCloneModal.create",
3687
+ defaultMessage: "Create"
3688
+ })
3689
+ }
3690
+ )
3691
+ ] });
3692
+ }
3069
3693
  }
3070
3694
  };
3071
3695
  };
3072
- const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
3073
- return columns.map((name) => {
3074
- const attribute = attributes[name];
3075
- if (!attribute) {
3076
- return null;
3696
+ CloneAction.type = "clone";
3697
+ const StyledDuplicate = styled(Duplicate)`
3698
+ path {
3699
+ fill: currentColor;
3700
+ }
3701
+ `;
3702
+ const DEFAULT_TABLE_ROW_ACTIONS = [EditAction, CloneAction];
3703
+ class ContentManagerPlugin {
3704
+ /**
3705
+ * The following properties are the stored ones provided by any plugins registering with
3706
+ * the content-manager. The function calls however, need to be called at runtime in the
3707
+ * application, so instead we collate them and run them later with the complete list incl.
3708
+ * ones already registered & the context of the view.
3709
+ */
3710
+ bulkActions = [...DEFAULT_BULK_ACTIONS];
3711
+ documentActions = [
3712
+ ...DEFAULT_ACTIONS,
3713
+ ...DEFAULT_TABLE_ROW_ACTIONS,
3714
+ ...DEFAULT_HEADER_ACTIONS,
3715
+ HistoryAction
3716
+ ];
3717
+ editViewSidePanels = [ActionsPanel];
3718
+ headerActions = [];
3719
+ constructor() {
3720
+ }
3721
+ addEditViewSidePanel(panels) {
3722
+ if (Array.isArray(panels)) {
3723
+ this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
3724
+ } else if (typeof panels === "function") {
3725
+ this.editViewSidePanels = panels(this.editViewSidePanels);
3726
+ } else {
3727
+ throw new Error(
3728
+ `Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
3729
+ panels
3730
+ )}`
3731
+ );
3077
3732
  }
3078
- const metadata = metadatas[name];
3079
- const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
3733
+ }
3734
+ addDocumentAction(actions2) {
3735
+ if (Array.isArray(actions2)) {
3736
+ this.documentActions = [...this.documentActions, ...actions2];
3737
+ } else if (typeof actions2 === "function") {
3738
+ this.documentActions = actions2(this.documentActions);
3739
+ } else {
3740
+ throw new Error(
3741
+ `Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
3742
+ actions2
3743
+ )}`
3744
+ );
3745
+ }
3746
+ }
3747
+ addDocumentHeaderAction(actions2) {
3748
+ if (Array.isArray(actions2)) {
3749
+ this.headerActions = [...this.headerActions, ...actions2];
3750
+ } else if (typeof actions2 === "function") {
3751
+ this.headerActions = actions2(this.headerActions);
3752
+ } else {
3753
+ throw new Error(
3754
+ `Expected the \`actions\` passed to \`addDocumentHeaderAction\` to be an array or a function, but received ${getPrintableType(
3755
+ actions2
3756
+ )}`
3757
+ );
3758
+ }
3759
+ }
3760
+ addBulkAction(actions2) {
3761
+ if (Array.isArray(actions2)) {
3762
+ this.bulkActions = [...this.bulkActions, ...actions2];
3763
+ } else if (typeof actions2 === "function") {
3764
+ this.bulkActions = actions2(this.bulkActions);
3765
+ } else {
3766
+ throw new Error(
3767
+ `Expected the \`actions\` passed to \`addBulkAction\` to be an array or a function, but received ${getPrintableType(
3768
+ actions2
3769
+ )}`
3770
+ );
3771
+ }
3772
+ }
3773
+ get config() {
3080
3774
  return {
3081
- attribute,
3082
- label: metadata.label ?? "",
3083
- mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
3084
- schemas,
3085
- components: components?.schemas ?? {}
3086
- }),
3087
- name,
3088
- searchable: metadata.searchable ?? true,
3089
- sortable: metadata.sortable ?? true
3775
+ id: PLUGIN_ID,
3776
+ name: "Content Manager",
3777
+ injectionZones: INJECTION_ZONES,
3778
+ apis: {
3779
+ addBulkAction: this.addBulkAction.bind(this),
3780
+ addDocumentAction: this.addDocumentAction.bind(this),
3781
+ addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
3782
+ addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
3783
+ getBulkActions: () => this.bulkActions,
3784
+ getDocumentActions: () => this.documentActions,
3785
+ getEditViewSidePanels: () => this.editViewSidePanels,
3786
+ getHeaderActions: () => this.headerActions
3787
+ }
3090
3788
  };
3091
- }).filter((field) => field !== null);
3789
+ }
3790
+ }
3791
+ const getPrintableType = (value) => {
3792
+ const nativeType = typeof value;
3793
+ if (nativeType === "object") {
3794
+ if (value === null)
3795
+ return "null";
3796
+ if (Array.isArray(value))
3797
+ return "array";
3798
+ if (value instanceof Object && value.constructor.name !== "Object") {
3799
+ return value.constructor.name;
3800
+ }
3801
+ }
3802
+ return nativeType;
3803
+ };
3804
+ const initialState = {
3805
+ collectionTypeLinks: [],
3806
+ components: [],
3807
+ fieldSizes: {},
3808
+ models: [],
3809
+ singleTypeLinks: [],
3810
+ isLoading: true
3092
3811
  };
3812
+ const appSlice = createSlice({
3813
+ name: "app",
3814
+ initialState,
3815
+ reducers: {
3816
+ setInitialData(state, action) {
3817
+ const {
3818
+ authorizedCollectionTypeLinks,
3819
+ authorizedSingleTypeLinks,
3820
+ components,
3821
+ contentTypeSchemas,
3822
+ fieldSizes
3823
+ } = action.payload;
3824
+ state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
3825
+ ({ isDisplayed }) => isDisplayed
3826
+ );
3827
+ state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
3828
+ state.components = components;
3829
+ state.models = contentTypeSchemas;
3830
+ state.fieldSizes = fieldSizes;
3831
+ state.isLoading = false;
3832
+ }
3833
+ }
3834
+ });
3835
+ const { actions, reducer: reducer$1 } = appSlice;
3836
+ const { setInitialData } = actions;
3837
+ const reducer = combineReducers({
3838
+ app: reducer$1
3839
+ });
3093
3840
  const index = {
3094
3841
  register(app) {
3095
3842
  const cm = new ContentManagerPlugin();
3096
3843
  app.addReducers({
3097
- [contentManagerApi.reducerPath]: contentManagerApi.reducer,
3098
3844
  [PLUGIN_ID]: reducer
3099
3845
  });
3100
- app.addMiddlewares([() => contentManagerApi.middleware]);
3101
3846
  app.addMenuLink({
3102
3847
  to: PLUGIN_ID,
3103
3848
  icon: Feather,
@@ -3106,14 +3851,15 @@ const index = {
3106
3851
  defaultMessage: "Content Manager"
3107
3852
  },
3108
3853
  permissions: [],
3109
- Component: () => import("./layout-Dnh0PNp9.mjs").then((mod) => ({ default: mod.Layout }))
3854
+ Component: () => import("./layout-hInnLBbA.mjs").then((mod) => ({ default: mod.Layout })),
3855
+ position: 1
3110
3856
  });
3111
3857
  app.registerPlugin(cm.config);
3112
3858
  },
3113
3859
  async registerTrads({ locales }) {
3114
3860
  const importedTrads = await Promise.all(
3115
3861
  locales.map((locale) => {
3116
- 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 }) => {
3862
+ 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-Dzv55oQw.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 }) => {
3117
3863
  return {
3118
3864
  data: prefixPluginTranslations(data, PLUGIN_ID),
3119
3865
  locale
@@ -3131,16 +3877,17 @@ const index = {
3131
3877
  };
3132
3878
  export {
3133
3879
  ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD as A,
3134
- extractContentTypeComponents as B,
3880
+ BulkActionsRenderer as B,
3135
3881
  COLLECTION_TYPES as C,
3136
3882
  DocumentStatus as D,
3137
- DEFAULT_SETTINGS as E,
3138
- convertEditLayoutToFieldLayouts as F,
3139
- useDocument as G,
3883
+ extractContentTypeComponents as E,
3884
+ DEFAULT_SETTINGS as F,
3885
+ convertEditLayoutToFieldLayouts as G,
3140
3886
  HOOKS as H,
3141
3887
  InjectionZone as I,
3142
- index as J,
3143
- useDocumentActions as K,
3888
+ useDocument as J,
3889
+ index as K,
3890
+ useDocumentActions as L,
3144
3891
  Panels as P,
3145
3892
  RelativeTime as R,
3146
3893
  SINGLE_TYPES as S,
@@ -3172,4 +3919,4 @@ export {
3172
3919
  capitalise as y,
3173
3920
  useUpdateContentTypeConfigurationMutation as z
3174
3921
  };
3175
- //# sourceMappingURL=index-DNVx8ssZ.mjs.map
3922
+ //# sourceMappingURL=index-Dv4oDn11.mjs.map