@strapi/content-manager 0.0.0-experimental.e60ec1829240dae21c1e1d29076681c322288813 → 0.0.0-experimental.f31889311d753b5f7d95198ae84d8fce1d156cd6

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/LICENSE +18 -3
  2. package/dist/_chunks/{CardDragPreview-DSVYodBX.js → CardDragPreview-C0QyJgRA.js} +10 -14
  3. package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -0
  4. package/dist/_chunks/{CardDragPreview-ikSG4M46.mjs → CardDragPreview-DOxamsuj.mjs} +7 -9
  5. package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -0
  6. package/dist/_chunks/{ComponentConfigurationPage-DjWJdz6Y.js → ComponentConfigurationPage-BNxtMIfV.js} +3 -3
  7. package/dist/_chunks/{ComponentConfigurationPage-DjWJdz6Y.js.map → ComponentConfigurationPage-BNxtMIfV.js.map} +1 -1
  8. package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs → ComponentConfigurationPage-BWOQWCv2.mjs} +3 -3
  9. package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs.map → ComponentConfigurationPage-BWOQWCv2.mjs.map} +1 -1
  10. package/dist/_chunks/{ComponentIcon-BBQsYCVn.js → ComponentIcon-BXdiCGQp.js} +8 -2
  11. package/dist/_chunks/ComponentIcon-BXdiCGQp.js.map +1 -0
  12. package/dist/_chunks/{ComponentIcon-BOFnK76n.mjs → ComponentIcon-u4bIXTFY.mjs} +9 -3
  13. package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -0
  14. package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js → EditConfigurationPage-D340bYlT.js} +3 -3
  15. package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js.map → EditConfigurationPage-D340bYlT.js.map} +1 -1
  16. package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs → EditConfigurationPage-GTp-Ucnw.mjs} +3 -3
  17. package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs.map → EditConfigurationPage-GTp-Ucnw.mjs.map} +1 -1
  18. package/dist/_chunks/{EditViewPage-DDS6H9HO.mjs → EditViewPage-BVMS5hT-.mjs} +47 -47
  19. package/dist/_chunks/EditViewPage-BVMS5hT-.mjs.map +1 -0
  20. package/dist/_chunks/{EditViewPage-DvNpQkam.js → EditViewPage-CXkmnAvI.js} +46 -48
  21. package/dist/_chunks/EditViewPage-CXkmnAvI.js.map +1 -0
  22. package/dist/_chunks/{Field-DmVKIAOo.js → Field-Ibi32diw.js} +953 -782
  23. package/dist/_chunks/Field-Ibi32diw.js.map +1 -0
  24. package/dist/_chunks/{Field-6gvGdPBV.mjs → Field-nNgv5bpd.mjs} +901 -729
  25. package/dist/_chunks/Field-nNgv5bpd.mjs.map +1 -0
  26. package/dist/_chunks/{Form-CPZC9vWa.js → Form-Dhnh34ym.js} +39 -38
  27. package/dist/_chunks/Form-Dhnh34ym.js.map +1 -0
  28. package/dist/_chunks/{Form-DW6K1IH-.mjs → Form-DodJsI2A.mjs} +39 -37
  29. package/dist/_chunks/Form-DodJsI2A.mjs.map +1 -0
  30. package/dist/_chunks/{History-DeAPlvtv.js → History-C9auUkDi.js} +149 -56
  31. package/dist/_chunks/History-C9auUkDi.js.map +1 -0
  32. package/dist/_chunks/{History-Dmr9fmUA.mjs → History-CKCSQXz_.mjs} +148 -54
  33. package/dist/_chunks/History-CKCSQXz_.mjs.map +1 -0
  34. package/dist/_chunks/{ListConfigurationPage-DPCwW5Vr.js → ListConfigurationPage-Bg4rWUjX.js} +58 -59
  35. package/dist/_chunks/ListConfigurationPage-Bg4rWUjX.js.map +1 -0
  36. package/dist/_chunks/{ListConfigurationPage-DhwvYcNv.mjs → ListConfigurationPage-CKEC4ttG.mjs} +54 -54
  37. package/dist/_chunks/ListConfigurationPage-CKEC4ttG.mjs.map +1 -0
  38. package/dist/_chunks/{ListViewPage-BtAwuYLE.mjs → ListViewPage-B7_WJUjG.mjs} +93 -104
  39. package/dist/_chunks/ListViewPage-B7_WJUjG.mjs.map +1 -0
  40. package/dist/_chunks/{ListViewPage-5ySZ-VUs.js → ListViewPage-C2gIeYHG.js} +98 -109
  41. package/dist/_chunks/ListViewPage-C2gIeYHG.js.map +1 -0
  42. package/dist/_chunks/{NoContentTypePage-DSPxnxxp.mjs → NoContentTypePage-Ckem6Ll6.mjs} +3 -3
  43. package/dist/_chunks/NoContentTypePage-Ckem6Ll6.mjs.map +1 -0
  44. package/dist/_chunks/{NoContentTypePage-DOC_yWOf.js → NoContentTypePage-DqgdUfyn.js} +3 -3
  45. package/dist/_chunks/NoContentTypePage-DqgdUfyn.js.map +1 -0
  46. package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs → NoPermissionsPage-BO-GEjA4.mjs} +2 -2
  47. package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs.map → NoPermissionsPage-BO-GEjA4.mjs.map} +1 -1
  48. package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js → NoPermissionsPage-CF29Q-sW.js} +2 -2
  49. package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js.map → NoPermissionsPage-CF29Q-sW.js.map} +1 -1
  50. package/dist/_chunks/{Relations-CgWtgnPe.js → Relations-C0uC9J4f.js} +70 -61
  51. package/dist/_chunks/Relations-C0uC9J4f.js.map +1 -0
  52. package/dist/_chunks/{Relations-J8cscLlR.mjs → Relations-DItV5eow.mjs} +66 -56
  53. package/dist/_chunks/Relations-DItV5eow.mjs.map +1 -0
  54. package/dist/_chunks/{en-MBPul9Su.mjs → en-BrCTWlZv.mjs} +11 -4
  55. package/dist/_chunks/{en-MBPul9Su.mjs.map → en-BrCTWlZv.mjs.map} +1 -1
  56. package/dist/_chunks/{en-C-V1_90f.js → en-uOUIxfcQ.js} +11 -4
  57. package/dist/_chunks/{en-C-V1_90f.js.map → en-uOUIxfcQ.js.map} +1 -1
  58. package/dist/_chunks/{index-C6AH2hEl.js → index-Dd0nXyJF.js} +1649 -905
  59. package/dist/_chunks/index-Dd0nXyJF.js.map +1 -0
  60. package/dist/_chunks/{index-CwRRo1V9.mjs → index-DrNe6ctw.mjs} +1671 -926
  61. package/dist/_chunks/index-DrNe6ctw.mjs.map +1 -0
  62. package/dist/_chunks/{layout-jIDzX0Fp.mjs → layout-B3ez7kvr.mjs} +43 -26
  63. package/dist/_chunks/layout-B3ez7kvr.mjs.map +1 -0
  64. package/dist/_chunks/{layout-B_SXLhqf.js → layout-CLLtt_5O.js} +43 -28
  65. package/dist/_chunks/layout-CLLtt_5O.js.map +1 -0
  66. package/dist/_chunks/{relations-CuvIgCqI.mjs → relations-B0hlsUU_.mjs} +2 -2
  67. package/dist/_chunks/{relations-CuvIgCqI.mjs.map → relations-B0hlsUU_.mjs.map} +1 -1
  68. package/dist/_chunks/{relations-iBMa_OFG.js → relations-bRxcNv1q.js} +2 -2
  69. package/dist/_chunks/{relations-iBMa_OFG.js.map → relations-bRxcNv1q.js.map} +1 -1
  70. package/dist/_chunks/useDragAndDrop-DdHgKsqq.mjs.map +1 -1
  71. package/dist/_chunks/useDragAndDrop-J0TUUbR6.js.map +1 -1
  72. package/dist/_chunks/usePrev-B9w_-eYc.js +15 -0
  73. package/dist/_chunks/usePrev-B9w_-eYc.js.map +1 -0
  74. package/dist/_chunks/usePrev-DH6iah0A.mjs +16 -0
  75. package/dist/_chunks/usePrev-DH6iah0A.mjs.map +1 -0
  76. package/dist/admin/index.js +2 -1
  77. package/dist/admin/index.js.map +1 -1
  78. package/dist/admin/index.mjs +5 -4
  79. package/dist/admin/src/components/ComponentIcon.d.ts +6 -3
  80. package/dist/admin/src/content-manager.d.ts +3 -3
  81. package/dist/admin/src/exports.d.ts +1 -0
  82. package/dist/admin/src/history/components/VersionInputRenderer.d.ts +1 -1
  83. package/dist/admin/src/history/index.d.ts +3 -0
  84. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  85. package/dist/admin/src/hooks/useDocument.d.ts +5 -8
  86. package/dist/admin/src/hooks/useDocumentActions.d.ts +24 -3
  87. package/dist/admin/src/hooks/useDocumentLayout.d.ts +2 -2
  88. package/dist/admin/src/hooks/useDragAndDrop.d.ts +4 -4
  89. package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +1 -1
  90. package/dist/admin/src/index.d.ts +1 -0
  91. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +11 -4
  92. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +3 -3
  93. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
  94. package/dist/admin/src/pages/EditView/components/FormInputs/Component/Input.d.ts +2 -2
  95. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.d.ts +3 -5
  96. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +1 -1
  97. package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +30 -18
  98. package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +2 -2
  99. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +3 -49
  100. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.d.ts +2 -2
  101. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +59 -52
  102. package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -10
  103. package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
  104. package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
  105. package/dist/admin/src/pages/ListView/components/BulkActions/PublishAction.d.ts +9 -26
  106. package/dist/admin/src/services/api.d.ts +2 -3
  107. package/dist/admin/src/services/components.d.ts +2 -2
  108. package/dist/admin/src/services/contentTypes.d.ts +5 -5
  109. package/dist/admin/src/services/documents.d.ts +29 -17
  110. package/dist/admin/src/services/init.d.ts +2 -2
  111. package/dist/admin/src/services/relations.d.ts +3 -3
  112. package/dist/admin/src/services/uid.d.ts +3 -3
  113. package/dist/admin/src/utils/api.d.ts +4 -18
  114. package/dist/admin/src/utils/validation.d.ts +1 -6
  115. package/dist/server/index.js +392 -261
  116. package/dist/server/index.js.map +1 -1
  117. package/dist/server/index.mjs +400 -269
  118. package/dist/server/index.mjs.map +1 -1
  119. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  120. package/dist/server/src/controllers/single-types.d.ts.map +1 -1
  121. package/dist/server/src/controllers/uid.d.ts.map +1 -1
  122. package/dist/server/src/controllers/utils/metadata.d.ts +8 -0
  123. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -0
  124. package/dist/server/src/controllers/validation/dimensions.d.ts +11 -0
  125. package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -0
  126. package/dist/server/src/controllers/validation/index.d.ts +1 -1
  127. package/dist/server/src/history/services/history.d.ts.map +1 -1
  128. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  129. package/dist/server/src/history/services/utils.d.ts +1 -1
  130. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  131. package/dist/server/src/index.d.ts +18 -39
  132. package/dist/server/src/index.d.ts.map +1 -1
  133. package/dist/server/src/services/document-manager.d.ts +13 -12
  134. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  135. package/dist/server/src/services/document-metadata.d.ts +8 -29
  136. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  137. package/dist/server/src/services/index.d.ts +18 -39
  138. package/dist/server/src/services/index.d.ts.map +1 -1
  139. package/dist/server/src/services/utils/populate.d.ts +8 -1
  140. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  141. package/dist/shared/contracts/collection-types.d.ts +14 -6
  142. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  143. package/dist/shared/contracts/relations.d.ts +2 -2
  144. package/dist/shared/contracts/relations.d.ts.map +1 -1
  145. package/package.json +13 -14
  146. package/dist/_chunks/CardDragPreview-DSVYodBX.js.map +0 -1
  147. package/dist/_chunks/CardDragPreview-ikSG4M46.mjs.map +0 -1
  148. package/dist/_chunks/ComponentIcon-BBQsYCVn.js.map +0 -1
  149. package/dist/_chunks/ComponentIcon-BOFnK76n.mjs.map +0 -1
  150. package/dist/_chunks/EditViewPage-DDS6H9HO.mjs.map +0 -1
  151. package/dist/_chunks/EditViewPage-DvNpQkam.js.map +0 -1
  152. package/dist/_chunks/Field-6gvGdPBV.mjs.map +0 -1
  153. package/dist/_chunks/Field-DmVKIAOo.js.map +0 -1
  154. package/dist/_chunks/Form-CPZC9vWa.js.map +0 -1
  155. package/dist/_chunks/Form-DW6K1IH-.mjs.map +0 -1
  156. package/dist/_chunks/History-DeAPlvtv.js.map +0 -1
  157. package/dist/_chunks/History-Dmr9fmUA.mjs.map +0 -1
  158. package/dist/_chunks/ListConfigurationPage-DPCwW5Vr.js.map +0 -1
  159. package/dist/_chunks/ListConfigurationPage-DhwvYcNv.mjs.map +0 -1
  160. package/dist/_chunks/ListViewPage-5ySZ-VUs.js.map +0 -1
  161. package/dist/_chunks/ListViewPage-BtAwuYLE.mjs.map +0 -1
  162. package/dist/_chunks/NoContentTypePage-DOC_yWOf.js.map +0 -1
  163. package/dist/_chunks/NoContentTypePage-DSPxnxxp.mjs.map +0 -1
  164. package/dist/_chunks/Relations-CgWtgnPe.js.map +0 -1
  165. package/dist/_chunks/Relations-J8cscLlR.mjs.map +0 -1
  166. package/dist/_chunks/index-C6AH2hEl.js.map +0 -1
  167. package/dist/_chunks/index-CwRRo1V9.mjs.map +0 -1
  168. package/dist/_chunks/layout-B_SXLhqf.js.map +0 -1
  169. package/dist/_chunks/layout-jIDzX0Fp.mjs.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
@@ -2,17 +2,15 @@
2
2
  const Icons = require("@strapi/icons");
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const strapiAdmin = require("@strapi/admin/strapi-admin");
5
- const qs = require("qs");
6
- const reactIntl = require("react-intl");
7
- const reactRouterDom = require("react-router-dom");
8
5
  const React = require("react");
9
6
  const designSystem = require("@strapi/design-system");
10
- const styled = require("styled-components");
7
+ const reactIntl = require("react-intl");
8
+ const reactRouterDom = require("react-router-dom");
9
+ const styledComponents = require("styled-components");
11
10
  const yup = require("yup");
12
- const react = require("@reduxjs/toolkit/query/react");
13
- const axios = require("axios");
14
11
  const pipe = require("lodash/fp/pipe");
15
12
  const dateFns = require("date-fns");
13
+ const qs = require("qs");
16
14
  const toolkit = require("@reduxjs/toolkit");
17
15
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
18
16
  function _interopNamespace(e) {
@@ -34,7 +32,6 @@ function _interopNamespace(e) {
34
32
  return Object.freeze(n);
35
33
  }
36
34
  const React__namespace = /* @__PURE__ */ _interopNamespace(React);
37
- const styled__default = /* @__PURE__ */ _interopDefault(styled);
38
35
  const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
39
36
  const pipe__default = /* @__PURE__ */ _interopDefault(pipe);
40
37
  const __variableDynamicImportRuntimeHelper = (glob, path) => {
@@ -73,42 +70,6 @@ const useInjectionZone = (area) => {
73
70
  const [page, position] = area.split(".");
74
71
  return contentManagerPlugin.getInjectedComponents(page, position);
75
72
  };
76
- const HistoryAction = ({ model, document }) => {
77
- const { formatMessage } = reactIntl.useIntl();
78
- const [{ query }] = strapiAdmin.useQueryParams();
79
- const navigate = reactRouterDom.useNavigate();
80
- const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
81
- if (!window.strapi.features.isEnabled("cms-content-history")) {
82
- return null;
83
- }
84
- return {
85
- icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
86
- label: formatMessage({
87
- id: "content-manager.history.document-action",
88
- defaultMessage: "Content History"
89
- }),
90
- onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
91
- disabled: (
92
- /**
93
- * The user is creating a new document.
94
- * It hasn't been saved yet, so there's no history to go to
95
- */
96
- !document || /**
97
- * The document has been created but the current dimension has never been saved.
98
- * For example, the user is creating a new locale in an existing document,
99
- * so there's no history for the document in that locale
100
- */
101
- !document.id || /**
102
- * History is only available for content types created by the user.
103
- * These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
104
- * which start with `admin::` or `plugin::`
105
- */
106
- !model.startsWith("api::")
107
- ),
108
- position: "header"
109
- };
110
- };
111
- HistoryAction.type = "history";
112
73
  const ID = "id";
113
74
  const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
114
75
  const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
@@ -179,9 +140,8 @@ const DocumentRBAC = ({ children, permissions }) => {
179
140
  const name = removeNumericalStrings(fieldName.split("."));
180
141
  const componentFieldNames = fieldsUserCanAction.filter((field) => field.split(".").length > 1);
181
142
  if (fieldType === "component") {
182
- const componentOrDynamicZoneFields = componentFieldNames.map((field) => field.split("."));
183
- return componentOrDynamicZoneFields.some((field) => {
184
- return field.includes(fieldName);
143
+ return componentFieldNames.some((field) => {
144
+ return field.includes(name.join("."));
185
145
  });
186
146
  }
187
147
  if (name.length > 1) {
@@ -211,78 +171,8 @@ const extractAndDedupeFields = (permissions = []) => permissions.flatMap((permis
211
171
  (field, index2, arr) => arr.indexOf(field) === index2 && typeof field === "string"
212
172
  );
213
173
  const removeNumericalStrings = (arr) => arr.filter((item) => isNaN(Number(item)));
214
- const buildValidParams = (query) => {
215
- if (!query)
216
- return query;
217
- const { plugins: _, ...validQueryParams } = {
218
- ...query,
219
- ...Object.values(query?.plugins ?? {}).reduce(
220
- (acc, current) => Object.assign(acc, current),
221
- {}
222
- )
223
- };
224
- if ("_q" in validQueryParams) {
225
- validQueryParams._q = encodeURIComponent(validQueryParams._q);
226
- }
227
- return validQueryParams;
228
- };
229
- const axiosBaseQuery = () => async (query, { signal }) => {
230
- try {
231
- const { get, post, del, put } = strapiAdmin.getFetchClient();
232
- if (typeof query === "string") {
233
- const result = await get(query, { signal });
234
- return { data: result.data };
235
- } else {
236
- const { url, method = "GET", data, config } = query;
237
- if (method === "POST") {
238
- const result2 = await post(url, data, { ...config, signal });
239
- return { data: result2.data };
240
- }
241
- if (method === "DELETE") {
242
- const result2 = await del(url, { ...config, signal });
243
- return { data: result2.data };
244
- }
245
- if (method === "PUT") {
246
- const result2 = await put(url, data, { ...config, signal });
247
- return { data: result2.data };
248
- }
249
- const result = await get(url, { ...config, signal });
250
- return { data: result.data };
251
- }
252
- } catch (err) {
253
- if (axios.isAxiosError(err)) {
254
- if (typeof err.response?.data === "object" && err.response?.data !== null && "error" in err.response?.data) {
255
- return { data: void 0, error: err.response?.data.error };
256
- } else {
257
- return {
258
- data: void 0,
259
- error: {
260
- name: "UnknownError",
261
- message: "There was an unknown error response from the API",
262
- details: err.response?.data,
263
- status: err.response?.status
264
- }
265
- };
266
- }
267
- }
268
- const error = err;
269
- return {
270
- data: void 0,
271
- error: {
272
- name: error.name,
273
- message: error.message,
274
- stack: error.stack
275
- }
276
- };
277
- }
278
- };
279
- const isBaseQueryError = (error) => {
280
- return error.name !== void 0;
281
- };
282
- const contentManagerApi = react.createApi({
283
- reducerPath: "contentManagerApi",
284
- baseQuery: axiosBaseQuery(),
285
- tagTypes: [
174
+ const contentManagerApi = strapiAdmin.adminApi.enhanceEndpoints({
175
+ addTagTypes: [
286
176
  "ComponentConfiguration",
287
177
  "ContentTypesConfiguration",
288
178
  "ContentTypeSettings",
@@ -290,10 +180,10 @@ const contentManagerApi = react.createApi({
290
180
  "InitialData",
291
181
  "HistoryVersion",
292
182
  "Relations"
293
- ],
294
- endpoints: () => ({})
183
+ ]
295
184
  });
296
185
  const documentApi = contentManagerApi.injectEndpoints({
186
+ overrideExisting: true,
297
187
  endpoints: (builder) => ({
298
188
  autoCloneDocument: builder.mutation({
299
189
  query: ({ model, sourceId, query }) => ({
@@ -303,7 +193,12 @@ const documentApi = contentManagerApi.injectEndpoints({
303
193
  params: query
304
194
  }
305
195
  }),
306
- invalidatesTags: (_result, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
196
+ invalidatesTags: (_result, error, { model }) => {
197
+ if (error) {
198
+ return [];
199
+ }
200
+ return [{ type: "Document", id: `${model}_LIST` }];
201
+ }
307
202
  }),
308
203
  cloneDocument: builder.mutation({
309
204
  query: ({ model, sourceId, data, params }) => ({
@@ -347,12 +242,15 @@ const documentApi = contentManagerApi.injectEndpoints({
347
242
  ]
348
243
  }),
349
244
  deleteManyDocuments: builder.mutation({
350
- query: ({ model, ...body }) => ({
245
+ query: ({ model, params, ...body }) => ({
351
246
  url: `/content-manager/collection-types/${model}/actions/bulkDelete`,
352
247
  method: "POST",
353
- data: body
248
+ data: body,
249
+ config: {
250
+ params
251
+ }
354
252
  }),
355
- invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
253
+ invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
356
254
  }),
357
255
  discardDocument: builder.mutation({
358
256
  query: ({ collectionType, model, documentId, params }) => ({
@@ -387,6 +285,7 @@ const documentApi = contentManagerApi.injectEndpoints({
387
285
  }),
388
286
  providesTags: (result, _error, arg) => {
389
287
  return [
288
+ { type: "Document", id: `ALL_LIST` },
390
289
  { type: "Document", id: `${arg.model}_LIST` },
391
290
  ...result?.results.map(({ documentId }) => ({
392
291
  type: "Document",
@@ -463,10 +362,13 @@ const documentApi = contentManagerApi.injectEndpoints({
463
362
  }
464
363
  }),
465
364
  publishManyDocuments: builder.mutation({
466
- query: ({ model, ...body }) => ({
365
+ query: ({ model, params, ...body }) => ({
467
366
  url: `/content-manager/collection-types/${model}/actions/bulkPublish`,
468
367
  method: "POST",
469
- data: body
368
+ data: body,
369
+ config: {
370
+ params
371
+ }
470
372
  }),
471
373
  invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
472
374
  }),
@@ -487,6 +389,18 @@ const documentApi = contentManagerApi.injectEndpoints({
487
389
  },
488
390
  "Relations"
489
391
  ];
392
+ },
393
+ async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
394
+ const patchResult = dispatch(
395
+ documentApi.util.updateQueryData("getDocument", patch, (draft) => {
396
+ Object.assign(draft.data, data);
397
+ })
398
+ );
399
+ try {
400
+ await queryFulfilled;
401
+ } catch {
402
+ patchResult.undo();
403
+ }
490
404
  }
491
405
  }),
492
406
  unpublishDocument: builder.mutation({
@@ -508,10 +422,13 @@ const documentApi = contentManagerApi.injectEndpoints({
508
422
  }
509
423
  }),
510
424
  unpublishManyDocuments: builder.mutation({
511
- query: ({ model, ...body }) => ({
425
+ query: ({ model, params, ...body }) => ({
512
426
  url: `/content-manager/collection-types/${model}/actions/bulkUnpublish`,
513
427
  method: "POST",
514
- data: body
428
+ data: body,
429
+ config: {
430
+ params
431
+ }
515
432
  }),
516
433
  invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
517
434
  })
@@ -535,6 +452,24 @@ const {
535
452
  useUnpublishDocumentMutation,
536
453
  useUnpublishManyDocumentsMutation
537
454
  } = documentApi;
455
+ const buildValidParams = (query) => {
456
+ if (!query)
457
+ return query;
458
+ const { plugins: _, ...validQueryParams } = {
459
+ ...query,
460
+ ...Object.values(query?.plugins ?? {}).reduce(
461
+ (acc, current) => Object.assign(acc, current),
462
+ {}
463
+ )
464
+ };
465
+ if ("_q" in validQueryParams) {
466
+ validQueryParams._q = encodeURIComponent(validQueryParams._q);
467
+ }
468
+ return validQueryParams;
469
+ };
470
+ const isBaseQueryError = (error) => {
471
+ return error.name !== void 0;
472
+ };
538
473
  const createYupSchema = (attributes = {}, components = {}) => {
539
474
  const createModelSchema = (attributes2) => yup__namespace.object().shape(
540
475
  Object.entries(attributes2).reduce((acc, [name, attribute]) => {
@@ -574,10 +509,14 @@ const createYupSchema = (attributes = {}, components = {}) => {
574
509
  yup__namespace.array().of(
575
510
  yup__namespace.lazy(
576
511
  (data) => {
577
- const { attributes: attributes3 } = components[data.__component];
578
- return yup__namespace.object().shape({
512
+ const attributes3 = components?.[data?.__component]?.attributes;
513
+ const validation = yup__namespace.object().shape({
579
514
  __component: yup__namespace.string().required().oneOf(Object.keys(components))
580
- }).nullable(false).concat(createModelSchema(attributes3));
515
+ }).nullable(false);
516
+ if (!attributes3) {
517
+ return validation;
518
+ }
519
+ return validation.concat(createModelSchema(attributes3));
581
520
  }
582
521
  )
583
522
  )
@@ -587,11 +526,25 @@ const createYupSchema = (attributes = {}, components = {}) => {
587
526
  return {
588
527
  ...acc,
589
528
  [name]: transformSchema(
590
- yup__namespace.array().of(
591
- yup__namespace.object().shape({
592
- id: yup__namespace.string().required()
593
- })
594
- )
529
+ yup__namespace.lazy((value) => {
530
+ if (!value) {
531
+ return yup__namespace.mixed().nullable(true);
532
+ } else if (Array.isArray(value)) {
533
+ return yup__namespace.array().of(
534
+ yup__namespace.object().shape({
535
+ id: yup__namespace.string().required()
536
+ })
537
+ );
538
+ } else if (typeof value === "object") {
539
+ return yup__namespace.object();
540
+ } else {
541
+ return yup__namespace.mixed().test(
542
+ "type-error",
543
+ "Relation values must be either null, an array of objects with {id} or an object.",
544
+ () => false
545
+ );
546
+ }
547
+ })
595
548
  )
596
549
  };
597
550
  default:
@@ -650,13 +603,18 @@ const createAttributeSchema = (attribute) => {
650
603
  }
651
604
  };
652
605
  const addRequiredValidation = (attribute) => (schema) => {
653
- if (attribute.required) {
654
- return schema.required({
655
- id: strapiAdmin.translatedErrors.required.id,
656
- defaultMessage: "This field is required."
657
- });
606
+ if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
607
+ return schema.min(1, strapiAdmin.translatedErrors.required);
658
608
  }
659
- return schema.nullable();
609
+ if (attribute.required && attribute.type !== "relation") {
610
+ return schema.required(strapiAdmin.translatedErrors.required);
611
+ }
612
+ return schema?.nullable ? schema.nullable() : (
613
+ // In some cases '.nullable' will not be available on the schema.
614
+ // e.g. when the schema has been built using yup.lazy (e.g. for relations).
615
+ // In these cases we should just return the schema as it is.
616
+ schema
617
+ );
660
618
  };
661
619
  const addMinLengthValidation = (attribute) => (schema) => {
662
620
  if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
@@ -683,6 +641,28 @@ const addMaxLengthValidation = (attribute) => (schema) => {
683
641
  const addMinValidation = (attribute) => (schema) => {
684
642
  if ("min" in attribute) {
685
643
  const min = toInteger(attribute.min);
644
+ if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
645
+ if (!attribute.required && "test" in schema && min) {
646
+ return schema.test(
647
+ "custom-min",
648
+ {
649
+ ...strapiAdmin.translatedErrors.min,
650
+ values: {
651
+ min: attribute.min
652
+ }
653
+ },
654
+ (value) => {
655
+ if (!value) {
656
+ return true;
657
+ }
658
+ if (Array.isArray(value) && value.length === 0) {
659
+ return true;
660
+ }
661
+ return value.length >= min;
662
+ }
663
+ );
664
+ }
665
+ }
686
666
  if ("min" in schema && min) {
687
667
  return schema.min(min, {
688
668
  ...strapiAdmin.translatedErrors.min,
@@ -728,24 +708,6 @@ const addRegexValidation = (attribute) => (schema) => {
728
708
  }
729
709
  return schema;
730
710
  };
731
- const extractValuesFromYupError = (errorType, errorParams) => {
732
- if (!errorType || !errorParams) {
733
- return {};
734
- }
735
- return {
736
- [errorType]: errorParams[errorType]
737
- };
738
- };
739
- const getInnerErrors = (error) => (error?.inner || []).reduce((acc, currentError) => {
740
- if (currentError.path) {
741
- acc[currentError.path.split("[").join(".").split("]").join("")] = {
742
- id: currentError.message,
743
- defaultMessage: currentError.message,
744
- values: extractValuesFromYupError(currentError?.type, currentError?.params)
745
- };
746
- }
747
- return acc;
748
- }, {});
749
711
  const initApi = contentManagerApi.injectEndpoints({
750
712
  endpoints: (builder) => ({
751
713
  getInitialData: builder.query({
@@ -759,27 +721,20 @@ const { useGetInitialDataQuery } = initApi;
759
721
  const useContentTypeSchema = (model) => {
760
722
  const { toggleNotification } = strapiAdmin.useNotification();
761
723
  const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
762
- const { components, contentType, contentTypes, error, isLoading, isFetching } = useGetInitialDataQuery(void 0, {
763
- selectFromResult: (res) => {
764
- const contentType2 = res.data?.contentTypes.find((ct) => ct.uid === model);
765
- const componentsByKey = res.data?.components.reduce(
766
- (acc, component) => {
767
- acc[component.uid] = component;
768
- return acc;
769
- },
770
- {}
771
- );
772
- const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
773
- return {
774
- isLoading: res.isLoading,
775
- isFetching: res.isFetching,
776
- error: res.error,
777
- components: Object.keys(components2).length === 0 ? void 0 : components2,
778
- contentType: contentType2,
779
- contentTypes: res.data?.contentTypes ?? []
780
- };
781
- }
782
- });
724
+ const { data, error, isLoading, isFetching } = useGetInitialDataQuery(void 0);
725
+ const { components, contentType, contentTypes } = React__namespace.useMemo(() => {
726
+ const contentType2 = data?.contentTypes.find((ct) => ct.uid === model);
727
+ const componentsByKey = data?.components.reduce((acc, component) => {
728
+ acc[component.uid] = component;
729
+ return acc;
730
+ }, {});
731
+ const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
732
+ return {
733
+ components: Object.keys(components2).length === 0 ? void 0 : components2,
734
+ contentType: contentType2,
735
+ contentTypes: data?.contentTypes ?? []
736
+ };
737
+ }, [model, data]);
783
738
  React__namespace.useEffect(() => {
784
739
  if (error) {
785
740
  toggleNotification({
@@ -834,7 +789,10 @@ const useDocument = (args, opts) => {
834
789
  isLoading: isLoadingDocument,
835
790
  isFetching: isFetchingDocument,
836
791
  error
837
- } = useGetDocumentQuery(args, opts);
792
+ } = useGetDocumentQuery(args, {
793
+ ...opts,
794
+ skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
795
+ });
838
796
  const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
839
797
  React__namespace.useEffect(() => {
840
798
  if (error) {
@@ -862,7 +820,7 @@ const useDocument = (args, opts) => {
862
820
  return null;
863
821
  } catch (error2) {
864
822
  if (error2 instanceof yup.ValidationError) {
865
- return getInnerErrors(error2);
823
+ return strapiAdmin.getYupValidationErrors(error2);
866
824
  }
867
825
  throw error2;
868
826
  }
@@ -958,14 +916,53 @@ const useDocumentActions = () => {
958
916
  },
959
917
  [trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
960
918
  );
919
+ const [deleteManyDocuments] = useDeleteManyDocumentsMutation();
920
+ const deleteMany = React__namespace.useCallback(
921
+ async ({ model, documentIds, params }) => {
922
+ try {
923
+ trackUsage("willBulkDeleteEntries");
924
+ const res = await deleteManyDocuments({
925
+ model,
926
+ documentIds,
927
+ params
928
+ });
929
+ if ("error" in res) {
930
+ toggleNotification({
931
+ type: "danger",
932
+ message: formatAPIError(res.error)
933
+ });
934
+ return { error: res.error };
935
+ }
936
+ toggleNotification({
937
+ type: "success",
938
+ title: formatMessage({
939
+ id: getTranslation("success.records.delete"),
940
+ defaultMessage: "Successfully deleted."
941
+ }),
942
+ message: ""
943
+ });
944
+ trackUsage("didBulkDeleteEntries");
945
+ return res.data;
946
+ } catch (err) {
947
+ toggleNotification({
948
+ type: "danger",
949
+ message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
950
+ });
951
+ trackUsage("didNotBulkDeleteEntries");
952
+ throw err;
953
+ }
954
+ },
955
+ [trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
956
+ );
961
957
  const [discardDocument] = useDiscardDocumentMutation();
962
958
  const discard = React__namespace.useCallback(
963
- async ({ collectionType, model, documentId }) => {
959
+ async ({ collectionType, model, documentId, params }) => {
964
960
  try {
965
961
  const res = await discardDocument({
966
962
  collectionType,
967
963
  model,
968
- documentId
964
+ documentId,
965
+ params
969
966
  });
970
967
  if ("error" in res) {
971
968
  toggleNotification({
@@ -1027,6 +1024,43 @@ const useDocumentActions = () => {
1027
1024
  },
1028
1025
  [trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
1029
1026
  );
1027
+ const [publishManyDocuments] = usePublishManyDocumentsMutation();
1028
+ const publishMany = React__namespace.useCallback(
1029
+ async ({ model, documentIds, params }) => {
1030
+ try {
1031
+ const res = await publishManyDocuments({
1032
+ model,
1033
+ documentIds,
1034
+ params
1035
+ });
1036
+ if ("error" in res) {
1037
+ toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1038
+ return { error: res.error };
1039
+ }
1040
+ toggleNotification({
1041
+ type: "success",
1042
+ message: formatMessage({
1043
+ id: getTranslation("success.record.publish"),
1044
+ defaultMessage: "Published document"
1045
+ })
1046
+ });
1047
+ return res.data;
1048
+ } catch (err) {
1049
+ toggleNotification({
1050
+ type: "danger",
1051
+ message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1052
+ });
1053
+ throw err;
1054
+ }
1055
+ },
1056
+ [
1057
+ // trackUsage,
1058
+ publishManyDocuments,
1059
+ toggleNotification,
1060
+ formatMessage,
1061
+ formatAPIError
1062
+ ]
1063
+ );
1030
1064
  const [updateDocument] = useUpdateDocumentMutation();
1031
1065
  const update = React__namespace.useCallback(
1032
1066
  async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
@@ -1101,6 +1135,41 @@ const useDocumentActions = () => {
1101
1135
  },
1102
1136
  [trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
1103
1137
  );
1138
+ const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
1139
+ const unpublishMany = React__namespace.useCallback(
1140
+ async ({ model, documentIds, params }) => {
1141
+ try {
1142
+ trackUsage("willBulkUnpublishEntries");
1143
+ const res = await unpublishManyDocuments({
1144
+ model,
1145
+ documentIds,
1146
+ params
1147
+ });
1148
+ if ("error" in res) {
1149
+ toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1150
+ return { error: res.error };
1151
+ }
1152
+ trackUsage("didBulkUnpublishEntries");
1153
+ toggleNotification({
1154
+ type: "success",
1155
+ title: formatMessage({
1156
+ id: getTranslation("success.records.unpublish"),
1157
+ defaultMessage: "Successfully unpublished."
1158
+ }),
1159
+ message: ""
1160
+ });
1161
+ return res.data;
1162
+ } catch (err) {
1163
+ toggleNotification({
1164
+ type: "danger",
1165
+ message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1166
+ });
1167
+ trackUsage("didNotBulkUnpublishEntries");
1168
+ throw err;
1169
+ }
1170
+ },
1171
+ [trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
1172
+ );
1104
1173
  const [createDocument] = useCreateDocumentMutation();
1105
1174
  const create = React__namespace.useCallback(
1106
1175
  async ({ model, params }, data, trackerProperty) => {
@@ -1144,7 +1213,6 @@ const useDocumentActions = () => {
1144
1213
  sourceId
1145
1214
  });
1146
1215
  if ("error" in res) {
1147
- toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1148
1216
  return { error: res.error };
1149
1217
  }
1150
1218
  toggleNotification({
@@ -1214,15 +1282,18 @@ const useDocumentActions = () => {
1214
1282
  clone,
1215
1283
  create,
1216
1284
  delete: _delete,
1285
+ deleteMany,
1217
1286
  discard,
1218
1287
  getDocument,
1219
1288
  publish,
1289
+ publishMany,
1220
1290
  unpublish,
1291
+ unpublishMany,
1221
1292
  update
1222
1293
  };
1223
1294
  };
1224
1295
  const ProtectedHistoryPage = React.lazy(
1225
- () => Promise.resolve().then(() => require("./History-DeAPlvtv.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
1296
+ () => Promise.resolve().then(() => require("./History-C9auUkDi.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
1226
1297
  );
1227
1298
  const routes$1 = [
1228
1299
  {
@@ -1235,31 +1306,31 @@ const routes$1 = [
1235
1306
  }
1236
1307
  ];
1237
1308
  const ProtectedEditViewPage = React.lazy(
1238
- () => Promise.resolve().then(() => require("./EditViewPage-DvNpQkam.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
1309
+ () => Promise.resolve().then(() => require("./EditViewPage-CXkmnAvI.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
1239
1310
  );
1240
1311
  const ProtectedListViewPage = React.lazy(
1241
- () => Promise.resolve().then(() => require("./ListViewPage-5ySZ-VUs.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
1312
+ () => Promise.resolve().then(() => require("./ListViewPage-C2gIeYHG.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
1242
1313
  );
1243
1314
  const ProtectedListConfiguration = React.lazy(
1244
- () => Promise.resolve().then(() => require("./ListConfigurationPage-DPCwW5Vr.js")).then((mod) => ({
1315
+ () => Promise.resolve().then(() => require("./ListConfigurationPage-Bg4rWUjX.js")).then((mod) => ({
1245
1316
  default: mod.ProtectedListConfiguration
1246
1317
  }))
1247
1318
  );
1248
1319
  const ProtectedEditConfigurationPage = React.lazy(
1249
- () => Promise.resolve().then(() => require("./EditConfigurationPage-Dmv83RlS.js")).then((mod) => ({
1320
+ () => Promise.resolve().then(() => require("./EditConfigurationPage-D340bYlT.js")).then((mod) => ({
1250
1321
  default: mod.ProtectedEditConfigurationPage
1251
1322
  }))
1252
1323
  );
1253
1324
  const ProtectedComponentConfigurationPage = React.lazy(
1254
- () => Promise.resolve().then(() => require("./ComponentConfigurationPage-DjWJdz6Y.js")).then((mod) => ({
1325
+ () => Promise.resolve().then(() => require("./ComponentConfigurationPage-BNxtMIfV.js")).then((mod) => ({
1255
1326
  default: mod.ProtectedComponentConfigurationPage
1256
1327
  }))
1257
1328
  );
1258
1329
  const NoPermissions = React.lazy(
1259
- () => Promise.resolve().then(() => require("./NoPermissionsPage-Dwu8rRJu.js")).then((mod) => ({ default: mod.NoPermissions }))
1330
+ () => Promise.resolve().then(() => require("./NoPermissionsPage-CF29Q-sW.js")).then((mod) => ({ default: mod.NoPermissions }))
1260
1331
  );
1261
1332
  const NoContentType = React.lazy(
1262
- () => Promise.resolve().then(() => require("./NoContentTypePage-DOC_yWOf.js")).then((mod) => ({ default: mod.NoContentType }))
1333
+ () => Promise.resolve().then(() => require("./NoContentTypePage-DqgdUfyn.js")).then((mod) => ({ default: mod.NoContentType }))
1263
1334
  );
1264
1335
  const CollectionTypePages = () => {
1265
1336
  const { collectionType } = reactRouterDom.useParams();
@@ -1386,7 +1457,7 @@ const DocumentActionButton = (action) => {
1386
1457
  DocumentActionConfirmDialog,
1387
1458
  {
1388
1459
  ...action.dialog,
1389
- variant: action.variant,
1460
+ variant: action.dialog?.variant ?? action.variant,
1390
1461
  isOpen: dialogId === action.id,
1391
1462
  onClose: handleClose
1392
1463
  }
@@ -1443,13 +1514,13 @@ const DocumentActionsMenu = ({
1443
1514
  disabled: isDisabled,
1444
1515
  size: "S",
1445
1516
  endIcon: null,
1446
- paddingTop: "7px",
1447
- paddingLeft: "9px",
1448
- paddingRight: "9px",
1517
+ paddingTop: "4px",
1518
+ paddingLeft: "7px",
1519
+ paddingRight: "7px",
1449
1520
  variant,
1450
1521
  children: [
1451
1522
  /* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
1452
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { as: "span", children: label || formatMessage({
1523
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: label || formatMessage({
1453
1524
  id: "content-manager.containers.edit.panels.default.more-actions",
1454
1525
  defaultMessage: "More document actions"
1455
1526
  }) })
@@ -1465,10 +1536,18 @@ const DocumentActionsMenu = ({
1465
1536
  onSelect: handleClick(action),
1466
1537
  display: "block",
1467
1538
  children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: [
1468
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { color: convertActionVariantToColor(action.variant), gap: 2, as: "span", children: [
1469
- action.icon,
1470
- action.label
1471
- ] }),
1539
+ /* @__PURE__ */ jsxRuntime.jsxs(
1540
+ designSystem.Flex,
1541
+ {
1542
+ color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
1543
+ gap: 2,
1544
+ tag: "span",
1545
+ children: [
1546
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: action.icon }),
1547
+ action.label
1548
+ ]
1549
+ }
1550
+ ),
1472
1551
  action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsxRuntime.jsx(
1473
1552
  designSystem.Flex,
1474
1553
  {
@@ -1549,61 +1628,42 @@ const DocumentActionConfirmDialog = ({
1549
1628
  }
1550
1629
  onClose();
1551
1630
  };
1552
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog, { isOpen, title, onClose: handleClose, children: [
1553
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.DialogBody, { children: content }),
1554
- /* @__PURE__ */ jsxRuntime.jsx(
1555
- designSystem.DialogFooter,
1556
- {
1557
- startAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", children: formatMessage({
1558
- id: "app.components.Button.cancel",
1559
- defaultMessage: "Cancel"
1560
- }) }),
1561
- endAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, children: formatMessage({
1562
- id: "app.components.Button.confirm",
1563
- defaultMessage: "Confirm"
1564
- }) })
1565
- }
1566
- )
1567
- ] });
1631
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
1632
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
1633
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
1634
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
1635
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
1636
+ id: "app.components.Button.cancel",
1637
+ defaultMessage: "Cancel"
1638
+ }) }) }),
1639
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, children: formatMessage({
1640
+ id: "app.components.Button.confirm",
1641
+ defaultMessage: "Confirm"
1642
+ }) })
1643
+ ] })
1644
+ ] }) });
1568
1645
  };
1569
1646
  const DocumentActionModal = ({
1570
1647
  isOpen,
1571
1648
  title,
1572
1649
  onClose,
1573
1650
  footer: Footer,
1574
- content,
1651
+ content: Content,
1575
1652
  onModalClose
1576
1653
  }) => {
1577
- const id = React__namespace.useId();
1578
- if (!isOpen) {
1579
- return null;
1580
- }
1581
1654
  const handleClose = () => {
1582
1655
  if (onClose) {
1583
1656
  onClose();
1584
1657
  }
1585
1658
  onModalClose();
1586
1659
  };
1587
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
1588
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral800", as: "h2", id, children: title }) }),
1589
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalBody, { children: content }),
1590
- /* @__PURE__ */ jsxRuntime.jsx(
1591
- designSystem.Box,
1592
- {
1593
- paddingTop: 4,
1594
- paddingBottom: 4,
1595
- paddingLeft: 5,
1596
- paddingRight: 5,
1597
- borderWidth: "1px 0 0 0",
1598
- borderStyle: "solid",
1599
- borderColor: "neutral150",
1600
- background: "neutral100",
1601
- children: typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
1602
- }
1603
- )
1604
- ] });
1660
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
1661
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: title }) }),
1662
+ typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: Content }),
1663
+ typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
1664
+ ] }) });
1605
1665
  };
1606
- const PublishAction = ({
1666
+ const PublishAction$1 = ({
1607
1667
  activeTab,
1608
1668
  documentId,
1609
1669
  model,
@@ -1622,6 +1682,12 @@ const PublishAction = ({
1622
1682
  ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
1623
1683
  );
1624
1684
  const { publish } = useDocumentActions();
1685
+ const [
1686
+ countDraftRelations,
1687
+ { isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
1688
+ ] = useLazyGetDraftRelationCountQuery();
1689
+ const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React__namespace.useState(0);
1690
+ const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React__namespace.useState(0);
1625
1691
  const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
1626
1692
  const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
1627
1693
  const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
@@ -1630,65 +1696,146 @@ const PublishAction = ({
1630
1696
  const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
1631
1697
  const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
1632
1698
  const formValues = strapiAdmin.useForm("PublishAction", ({ values }) => values);
1633
- const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
1634
- if (!schema?.options?.draftAndPublish) {
1635
- return null;
1636
- }
1637
- return {
1638
- /**
1639
- * Disabled when:
1640
- * - currently if you're cloning a document we don't support publish & clone at the same time.
1641
- * - the form is submitting
1642
- * - the active tab is the published tab
1643
- * - the document is already published & not modified
1644
- * - the document is being created & not modified
1645
- * - the user doesn't have the permission to publish
1646
- * - the user doesn't have the permission to create a new document
1647
- * - the user doesn't have the permission to update the document
1699
+ React__namespace.useEffect(() => {
1700
+ if (isErrorDraftRelations) {
1701
+ toggleNotification({
1702
+ type: "danger",
1703
+ message: formatMessage({
1704
+ id: getTranslation("error.records.fetch-draft-relatons"),
1705
+ defaultMessage: "An error occurred while fetching draft relations on this document."
1706
+ })
1707
+ });
1708
+ }
1709
+ }, [isErrorDraftRelations, toggleNotification, formatMessage]);
1710
+ React__namespace.useEffect(() => {
1711
+ const localDraftRelations = /* @__PURE__ */ new Set();
1712
+ const extractDraftRelations = (data) => {
1713
+ const relations = data.connect || [];
1714
+ relations.forEach((relation) => {
1715
+ if (relation.status === "draft") {
1716
+ localDraftRelations.add(relation.id);
1717
+ }
1718
+ });
1719
+ };
1720
+ const traverseAndExtract = (data) => {
1721
+ Object.entries(data).forEach(([key, value]) => {
1722
+ if (key === "connect" && Array.isArray(value)) {
1723
+ extractDraftRelations({ connect: value });
1724
+ } else if (typeof value === "object" && value !== null) {
1725
+ traverseAndExtract(value);
1726
+ }
1727
+ });
1728
+ };
1729
+ if (!documentId || modified) {
1730
+ traverseAndExtract(formValues);
1731
+ setLocalCountOfDraftRelations(localDraftRelations.size);
1732
+ }
1733
+ }, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
1734
+ React__namespace.useEffect(() => {
1735
+ if (documentId) {
1736
+ const fetchDraftRelationsCount = async () => {
1737
+ const { data, error } = await countDraftRelations({
1738
+ collectionType,
1739
+ model,
1740
+ documentId,
1741
+ params
1742
+ });
1743
+ if (error) {
1744
+ throw error;
1745
+ }
1746
+ if (data) {
1747
+ setServerCountOfDraftRelations(data.data);
1748
+ }
1749
+ };
1750
+ fetchDraftRelationsCount();
1751
+ }
1752
+ }, [documentId, countDraftRelations, collectionType, model, params]);
1753
+ const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
1754
+ if (!schema?.options?.draftAndPublish) {
1755
+ return null;
1756
+ }
1757
+ const performPublish = async () => {
1758
+ setSubmitting(true);
1759
+ try {
1760
+ const { errors } = await validate();
1761
+ if (errors) {
1762
+ toggleNotification({
1763
+ type: "danger",
1764
+ message: formatMessage({
1765
+ id: "content-manager.validation.error",
1766
+ defaultMessage: "There are validation errors in your document. Please fix them before saving."
1767
+ })
1768
+ });
1769
+ return;
1770
+ }
1771
+ const res = await publish(
1772
+ {
1773
+ collectionType,
1774
+ model,
1775
+ documentId,
1776
+ params
1777
+ },
1778
+ formValues
1779
+ );
1780
+ if ("data" in res && collectionType !== SINGLE_TYPES) {
1781
+ navigate({
1782
+ pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1783
+ search: rawQuery
1784
+ });
1785
+ } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1786
+ setErrors(formatValidationErrors(res.error));
1787
+ }
1788
+ } finally {
1789
+ setSubmitting(false);
1790
+ }
1791
+ };
1792
+ const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
1793
+ const hasDraftRelations = totalDraftRelations > 0;
1794
+ return {
1795
+ /**
1796
+ * Disabled when:
1797
+ * - currently if you're cloning a document we don't support publish & clone at the same time.
1798
+ * - the form is submitting
1799
+ * - the active tab is the published tab
1800
+ * - the document is already published & not modified
1801
+ * - the document is being created & not modified
1802
+ * - the user doesn't have the permission to publish
1648
1803
  */
1649
- disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
1804
+ disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
1650
1805
  label: formatMessage({
1651
1806
  id: "app.utils.publish",
1652
1807
  defaultMessage: "Publish"
1653
1808
  }),
1654
1809
  onClick: async () => {
1655
- setSubmitting(true);
1656
- try {
1657
- const { errors } = await validate();
1658
- if (errors) {
1659
- toggleNotification({
1660
- type: "danger",
1661
- message: formatMessage({
1662
- id: "content-manager.validation.error",
1663
- defaultMessage: "There are validation errors in your document. Please fix them before saving."
1664
- })
1665
- });
1666
- return;
1667
- }
1668
- const res = await publish(
1669
- {
1670
- collectionType,
1671
- model,
1672
- documentId,
1673
- params
1674
- },
1675
- formValues
1676
- );
1677
- if ("data" in res && collectionType !== SINGLE_TYPES) {
1678
- navigate({
1679
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1680
- search: rawQuery
1681
- });
1682
- } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1683
- setErrors(formatValidationErrors(res.error));
1810
+ if (hasDraftRelations) {
1811
+ return;
1812
+ }
1813
+ await performPublish();
1814
+ },
1815
+ dialog: hasDraftRelations ? {
1816
+ type: "dialog",
1817
+ variant: "danger",
1818
+ footer: null,
1819
+ title: formatMessage({
1820
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
1821
+ defaultMessage: "Confirmation"
1822
+ }),
1823
+ content: formatMessage(
1824
+ {
1825
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
1826
+ defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
1827
+ },
1828
+ {
1829
+ count: totalDraftRelations
1684
1830
  }
1685
- } finally {
1686
- setSubmitting(false);
1831
+ ),
1832
+ onConfirm: async () => {
1833
+ await performPublish();
1687
1834
  }
1688
- }
1835
+ } : void 0
1689
1836
  };
1690
1837
  };
1691
- PublishAction.type = "publish";
1838
+ PublishAction$1.type = "publish";
1692
1839
  const UpdateAction = ({
1693
1840
  activeTab,
1694
1841
  documentId,
@@ -1701,7 +1848,7 @@ const UpdateAction = ({
1701
1848
  const cloneMatch = reactRouterDom.useMatch(CLONE_PATH);
1702
1849
  const isCloning = cloneMatch !== null;
1703
1850
  const { formatMessage } = reactIntl.useIntl();
1704
- const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
1851
+ useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
1705
1852
  canCreate: canCreate2,
1706
1853
  canUpdate: canUpdate2
1707
1854
  }));
@@ -1721,10 +1868,8 @@ const UpdateAction = ({
1721
1868
  * - the form is submitting
1722
1869
  * - the document is not modified & we're not cloning (you can save a clone entity straight away)
1723
1870
  * - the active tab is the published tab
1724
- * - the user doesn't have the permission to create a new document
1725
- * - the user doesn't have the permission to update the document
1726
1871
  */
1727
- disabled: isSubmitting || !modified && !isCloning || activeTab === "published" || Boolean(!documentId && !canCreate || documentId && !canUpdate),
1872
+ disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
1728
1873
  label: formatMessage({
1729
1874
  id: "content-manager.containers.Edit.save",
1730
1875
  defaultMessage: "Save"
@@ -1753,10 +1898,13 @@ const UpdateAction = ({
1753
1898
  document
1754
1899
  );
1755
1900
  if ("data" in res) {
1756
- navigate({
1757
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1758
- search: rawQuery
1759
- });
1901
+ navigate(
1902
+ {
1903
+ pathname: `../${res.data.documentId}`,
1904
+ search: rawQuery
1905
+ },
1906
+ { relative: "path" }
1907
+ );
1760
1908
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1761
1909
  setErrors(formatValidationErrors(res.error));
1762
1910
  }
@@ -1784,10 +1932,13 @@ const UpdateAction = ({
1784
1932
  document
1785
1933
  );
1786
1934
  if ("data" in res && collectionType !== SINGLE_TYPES) {
1787
- navigate({
1788
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1789
- search: rawQuery
1790
- });
1935
+ navigate(
1936
+ {
1937
+ pathname: `../${res.data.documentId}`,
1938
+ search: rawQuery
1939
+ },
1940
+ { replace: true, relative: "path" }
1941
+ );
1791
1942
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1792
1943
  setErrors(formatValidationErrors(res.error));
1793
1944
  }
@@ -1803,7 +1954,7 @@ const UNPUBLISH_DRAFT_OPTIONS = {
1803
1954
  KEEP: "keep",
1804
1955
  DISCARD: "discard"
1805
1956
  };
1806
- const UnpublishAction = ({
1957
+ const UnpublishAction$1 = ({
1807
1958
  activeTab,
1808
1959
  documentId,
1809
1960
  model,
@@ -1819,10 +1970,8 @@ const UnpublishAction = ({
1819
1970
  const { toggleNotification } = strapiAdmin.useNotification();
1820
1971
  const [shouldKeepDraft, setShouldKeepDraft] = React__namespace.useState(true);
1821
1972
  const isDocumentModified = document?.status === "modified";
1822
- const handleChange = (e) => {
1823
- if ("value" in e.target) {
1824
- setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
1825
- }
1973
+ const handleChange = (value) => {
1974
+ setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
1826
1975
  };
1827
1976
  if (!schema?.options?.draftAndPublish) {
1828
1977
  return null;
@@ -1866,45 +2015,30 @@ const UnpublishAction = ({
1866
2015
  content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "flex-start", direction: "column", gap: 6, children: [
1867
2016
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", direction: "column", gap: 2, children: [
1868
2017
  /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
1869
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "p", variant: "omega", textAlign: "center", children: formatMessage({
2018
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
1870
2019
  id: "content-manager.actions.unpublish.dialog.body",
1871
2020
  defaultMessage: "Are you sure?"
1872
2021
  }) })
1873
2022
  ] }),
1874
2023
  /* @__PURE__ */ jsxRuntime.jsxs(
1875
- designSystem.Flex,
2024
+ designSystem.Radio.Group,
1876
2025
  {
1877
- onChange: handleChange,
1878
- direction: "column",
1879
- alignItems: "flex-start",
1880
- as: "fieldset",
1881
- gap: 3,
2026
+ defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
2027
+ name: "discard-options",
2028
+ "aria-label": formatMessage({
2029
+ id: "content-manager.actions.unpublish.dialog.radio-label",
2030
+ defaultMessage: "Choose an option to unpublish the document."
2031
+ }),
2032
+ onValueChange: handleChange,
1882
2033
  children: [
1883
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { as: "legend" }),
1884
- /* @__PURE__ */ jsxRuntime.jsx(
1885
- designSystem.Radio,
1886
- {
1887
- checked: shouldKeepDraft,
1888
- value: UNPUBLISH_DRAFT_OPTIONS.KEEP,
1889
- name: "discard-options",
1890
- children: formatMessage({
1891
- id: "content-manager.actions.unpublish.dialog.option.keep-draft",
1892
- defaultMessage: "Keep draft"
1893
- })
1894
- }
1895
- ),
1896
- /* @__PURE__ */ jsxRuntime.jsx(
1897
- designSystem.Radio,
1898
- {
1899
- checked: !shouldKeepDraft,
1900
- value: UNPUBLISH_DRAFT_OPTIONS.DISCARD,
1901
- name: "discard-options",
1902
- children: formatMessage({
1903
- id: "content-manager.actions.unpublish.dialog.option.replace-draft",
1904
- defaultMessage: "Replace draft"
1905
- })
1906
- }
1907
- )
2034
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
2035
+ id: "content-manager.actions.unpublish.dialog.option.keep-draft",
2036
+ defaultMessage: "Keep draft"
2037
+ }) }),
2038
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
2039
+ id: "content-manager.actions.unpublish.dialog.option.replace-draft",
2040
+ defaultMessage: "Replace draft"
2041
+ }) })
1908
2042
  ]
1909
2043
  }
1910
2044
  )
@@ -1937,7 +2071,7 @@ const UnpublishAction = ({
1937
2071
  position: ["panel", "table-row"]
1938
2072
  };
1939
2073
  };
1940
- UnpublishAction.type = "unpublish";
2074
+ UnpublishAction$1.type = "unpublish";
1941
2075
  const DiscardAction = ({
1942
2076
  activeTab,
1943
2077
  documentId,
@@ -1971,7 +2105,7 @@ const DiscardAction = ({
1971
2105
  }),
1972
2106
  content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
1973
2107
  /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
1974
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "p", variant: "omega", textAlign: "center", children: formatMessage({
2108
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
1975
2109
  id: "content-manager.actions.discard.dialog.body",
1976
2110
  defaultMessage: "Are you sure?"
1977
2111
  }) })
@@ -1988,12 +2122,12 @@ const DiscardAction = ({
1988
2122
  };
1989
2123
  };
1990
2124
  DiscardAction.type = "discard";
1991
- const StyledCrossCircle = styled__default.default(Icons.CrossCircle)`
2125
+ const StyledCrossCircle = styledComponents.styled(Icons.CrossCircle)`
1992
2126
  path {
1993
2127
  fill: currentColor;
1994
2128
  }
1995
2129
  `;
1996
- const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction, DiscardAction];
2130
+ const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
1997
2131
  const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
1998
2132
  const RelativeTime = React__namespace.forwardRef(
1999
2133
  ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
@@ -2041,7 +2175,7 @@ const getDisplayName = ({
2041
2175
  const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2042
2176
  const DocumentStatus = ({ status = "draft", ...restProps }) => {
2043
2177
  const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
2044
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
2178
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
2045
2179
  };
2046
2180
  const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2047
2181
  const { formatMessage } = reactIntl.useIntl();
@@ -2050,23 +2184,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2050
2184
  id: "content-manager.containers.edit.title.new",
2051
2185
  defaultMessage: "Create an entry"
2052
2186
  }) : documentTitle;
2053
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 8, paddingBottom: 4, gap: 3, children: [
2187
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
2054
2188
  /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.BackButton, {}),
2055
- /* @__PURE__ */ jsxRuntime.jsxs(
2056
- designSystem.Flex,
2057
- {
2058
- width: "100%",
2059
- justifyContent: "space-between",
2060
- paddingTop: 1,
2061
- gap: "80px",
2062
- alignItems: "flex-start",
2063
- children: [
2064
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", as: "h1", children: title }),
2065
- /* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
2066
- ]
2067
- }
2068
- ),
2069
- status ? /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
2189
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
2190
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
2191
+ /* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
2192
+ ] }),
2193
+ status ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
2070
2194
  ] });
2071
2195
  };
2072
2196
  const HeaderToolbar = () => {
@@ -2218,7 +2342,7 @@ const Information = ({ activeTab }) => {
2218
2342
  borderColor: "neutral150",
2219
2343
  direction: "column",
2220
2344
  marginTop: 2,
2221
- as: "dl",
2345
+ tag: "dl",
2222
2346
  padding: 5,
2223
2347
  gap: 3,
2224
2348
  alignItems: "flex-start",
@@ -2226,8 +2350,8 @@ const Information = ({ activeTab }) => {
2226
2350
  marginRight: "-0.4rem",
2227
2351
  width: "calc(100% + 8px)",
2228
2352
  children: information.map((info) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, direction: "column", alignItems: "flex-start", children: [
2229
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
2230
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "dd", variant: "pi", textColor: "neutral600", children: info.value })
2353
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
2354
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "dd", variant: "pi", textColor: "neutral600", children: info.value })
2231
2355
  ] }, info.label))
2232
2356
  }
2233
2357
  );
@@ -2260,7 +2384,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
2260
2384
  id: "app.links.configure-view",
2261
2385
  defaultMessage: "Configure the view"
2262
2386
  }),
2263
- icon: /* @__PURE__ */ jsxRuntime.jsx(StyledCog, {}),
2387
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ListPlus, {}),
2264
2388
  onClick: () => {
2265
2389
  navigate(`../${collectionType}/${model}/configurations/edit`);
2266
2390
  },
@@ -2268,11 +2392,6 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
2268
2392
  };
2269
2393
  };
2270
2394
  ConfigureTheViewAction.type = "configure-the-view";
2271
- const StyledCog = styled__default.default(Icons.Cog)`
2272
- path {
2273
- fill: currentColor;
2274
- }
2275
- `;
2276
2395
  const EditTheModelAction = ({ model }) => {
2277
2396
  const navigate = reactRouterDom.useNavigate();
2278
2397
  const { formatMessage } = reactIntl.useIntl();
@@ -2281,7 +2400,7 @@ const EditTheModelAction = ({ model }) => {
2281
2400
  id: "content-manager.link-to-ctb",
2282
2401
  defaultMessage: "Edit the model"
2283
2402
  }),
2284
- icon: /* @__PURE__ */ jsxRuntime.jsx(StyledPencil$1, {}),
2403
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, {}),
2285
2404
  onClick: () => {
2286
2405
  navigate(`/plugins/content-type-builder/content-types/${model}`);
2287
2406
  },
@@ -2289,12 +2408,7 @@ const EditTheModelAction = ({ model }) => {
2289
2408
  };
2290
2409
  };
2291
2410
  EditTheModelAction.type = "edit-the-model";
2292
- const StyledPencil$1 = styled__default.default(Icons.Pencil)`
2293
- path {
2294
- fill: currentColor;
2295
- }
2296
- `;
2297
- const DeleteAction = ({ documentId, model, collectionType, document }) => {
2411
+ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
2298
2412
  const navigate = reactRouterDom.useNavigate();
2299
2413
  const { formatMessage } = reactIntl.useIntl();
2300
2414
  const listViewPathMatch = reactRouterDom.useMatch(LIST_PATH);
@@ -2308,7 +2422,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
2308
2422
  id: "content-manager.actions.delete.label",
2309
2423
  defaultMessage: "Delete document"
2310
2424
  }),
2311
- icon: /* @__PURE__ */ jsxRuntime.jsx(StyledTrash, {}),
2425
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
2312
2426
  dialog: {
2313
2427
  type: "dialog",
2314
2428
  title: formatMessage({
@@ -2317,7 +2431,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
2317
2431
  }),
2318
2432
  content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
2319
2433
  /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
2320
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "p", variant: "omega", textAlign: "center", children: formatMessage({
2434
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
2321
2435
  id: "content-manager.actions.delete.dialog.body",
2322
2436
  defaultMessage: "Are you sure?"
2323
2437
  }) })
@@ -2362,13 +2476,8 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
2362
2476
  position: ["header", "table-row"]
2363
2477
  };
2364
2478
  };
2365
- DeleteAction.type = "delete";
2366
- const StyledTrash = styled__default.default(Icons.Trash)`
2367
- path {
2368
- fill: currentColor;
2369
- }
2370
- `;
2371
- const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction];
2479
+ DeleteAction$1.type = "delete";
2480
+ const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
2372
2481
  const Panels = () => {
2373
2482
  const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
2374
2483
  const [
@@ -2442,7 +2551,7 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
2442
2551
  designSystem.Flex,
2443
2552
  {
2444
2553
  ref,
2445
- as: "aside",
2554
+ tag: "aside",
2446
2555
  "aria-labelledby": "additional-information",
2447
2556
  background: "neutral0",
2448
2557
  borderColor: "neutral150",
@@ -2457,118 +2566,997 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
2457
2566
  justifyContent: "stretch",
2458
2567
  alignItems: "flex-start",
2459
2568
  children: [
2460
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
2569
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
2461
2570
  children
2462
2571
  ]
2463
2572
  }
2464
2573
  );
2465
2574
  });
2466
- const DEFAULT_BULK_ACTIONS = [];
2467
- const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
2468
- const { formatMessage } = reactIntl.useIntl();
2469
- const getDefaultErrorMessage = (reason) => {
2470
- switch (reason) {
2471
- case "relation":
2472
- return "Duplicating the relation could remove it from the original entry.";
2473
- case "unique":
2474
- return "Identical values in a unique field are not allowed";
2475
- default:
2476
- return reason;
2477
- }
2478
- };
2479
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2480
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: formatMessage({
2481
- id: getTranslation("containers.list.autoCloneModal.title"),
2482
- defaultMessage: "This entry can't be duplicated directly."
2483
- }) }),
2484
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatMessage({
2485
- id: getTranslation("containers.list.autoCloneModal.description"),
2486
- defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
2487
- }) }) }),
2488
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxRuntime.jsxs(
2489
- designSystem.Flex,
2490
- {
2491
- direction: "column",
2492
- gap: 2,
2493
- alignItems: "flex-start",
2494
- borderColor: "neutral200",
2495
- hasRadius: true,
2496
- padding: 6,
2497
- children: [
2498
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "row", as: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { fontWeight: "semiBold", as: "li", children: [
2499
- pathSegment,
2500
- index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
2501
- Icons.ChevronRight,
2502
- {
2503
- fill: "neutral500",
2504
- height: "0.8rem",
2505
- width: "0.8rem",
2506
- style: { margin: "0 0.8rem" }
2507
- }
2508
- )
2509
- ] }, index2)) }),
2510
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "p", textColor: "neutral600", children: formatMessage({
2511
- id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
2512
- defaultMessage: getDefaultErrorMessage(reason)
2513
- }) })
2514
- ]
2515
- },
2516
- fieldPath.join()
2517
- )) })
2518
- ] });
2519
- };
2520
- const TableActions = ({ document }) => {
2521
- const { formatMessage } = reactIntl.useIntl();
2522
- const { model, collectionType } = useDoc();
2523
- const plugins = strapiAdmin.useStrapiApp("TableActions", (state) => state.plugins);
2524
- const props = {
2525
- activeTab: null,
2526
- model,
2527
- documentId: document.documentId,
2528
- collectionType,
2529
- document
2530
- };
2531
- return /* @__PURE__ */ jsxRuntime.jsx(
2532
- strapiAdmin.DescriptionComponentRenderer,
2533
- {
2534
- props,
2535
- descriptions: plugins["content-manager"].apis.getDocumentActions(),
2536
- children: (actions2) => {
2537
- const tableRowActions = actions2.filter((action) => {
2538
- const positions = Array.isArray(action.position) ? action.position : [action.position];
2539
- return positions.includes("table-row");
2540
- });
2541
- return /* @__PURE__ */ jsxRuntime.jsx(
2542
- DocumentActionsMenu,
2543
- {
2544
- actions: tableRowActions,
2545
- label: formatMessage({
2546
- id: "content-manager.containers.list.table.row-actions",
2547
- defaultMessage: "Row action"
2548
- }),
2549
- variant: "ghost"
2550
- }
2551
- );
2552
- }
2553
- }
2554
- );
2575
+ const HOOKS = {
2576
+ /**
2577
+ * Hook that allows to mutate the displayed headers of the list view table
2578
+ * @constant
2579
+ * @type {string}
2580
+ */
2581
+ INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
2582
+ /**
2583
+ * Hook that allows to mutate the CM's collection types links pre-set filters
2584
+ * @constant
2585
+ * @type {string}
2586
+ */
2587
+ MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
2588
+ /**
2589
+ * Hook that allows to mutate the CM's edit view layout
2590
+ * @constant
2591
+ * @type {string}
2592
+ */
2593
+ MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
2594
+ /**
2595
+ * Hook that allows to mutate the CM's single types links pre-set filters
2596
+ * @constant
2597
+ * @type {string}
2598
+ */
2599
+ MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
2555
2600
  };
2556
- const EditAction = ({ documentId }) => {
2557
- const navigate = reactRouterDom.useNavigate();
2558
- const { formatMessage } = reactIntl.useIntl();
2559
- const { canRead } = useDocumentRBAC("EditAction", ({ canRead: canRead2 }) => ({ canRead: canRead2 }));
2560
- const { toggleNotification } = strapiAdmin.useNotification();
2561
- const [{ query }] = strapiAdmin.useQueryParams();
2562
- return {
2563
- disabled: !canRead,
2564
- icon: /* @__PURE__ */ jsxRuntime.jsx(StyledPencil, {}),
2565
- label: formatMessage({
2566
- id: "content-manager.actions.edit.label",
2567
- defaultMessage: "Edit"
2568
- }),
2569
- position: "table-row",
2570
- onClick: async () => {
2571
- if (!documentId) {
2601
+ const contentTypesApi = contentManagerApi.injectEndpoints({
2602
+ endpoints: (builder) => ({
2603
+ getContentTypeConfiguration: builder.query({
2604
+ query: (uid) => ({
2605
+ url: `/content-manager/content-types/${uid}/configuration`,
2606
+ method: "GET"
2607
+ }),
2608
+ transformResponse: (response) => response.data,
2609
+ providesTags: (_result, _error, uid) => [
2610
+ { type: "ContentTypesConfiguration", id: uid },
2611
+ { type: "ContentTypeSettings", id: "LIST" }
2612
+ ]
2613
+ }),
2614
+ getAllContentTypeSettings: builder.query({
2615
+ query: () => "/content-manager/content-types-settings",
2616
+ transformResponse: (response) => response.data,
2617
+ providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
2618
+ }),
2619
+ updateContentTypeConfiguration: builder.mutation({
2620
+ query: ({ uid, ...body }) => ({
2621
+ url: `/content-manager/content-types/${uid}/configuration`,
2622
+ method: "PUT",
2623
+ data: body
2624
+ }),
2625
+ transformResponse: (response) => response.data,
2626
+ invalidatesTags: (_result, _error, { uid }) => [
2627
+ { type: "ContentTypesConfiguration", id: uid },
2628
+ { type: "ContentTypeSettings", id: "LIST" },
2629
+ // Is this necessary?
2630
+ { type: "InitialData" }
2631
+ ]
2632
+ })
2633
+ })
2634
+ });
2635
+ const {
2636
+ useGetContentTypeConfigurationQuery,
2637
+ useGetAllContentTypeSettingsQuery,
2638
+ useUpdateContentTypeConfigurationMutation
2639
+ } = contentTypesApi;
2640
+ const checkIfAttributeIsDisplayable = (attribute) => {
2641
+ const { type } = attribute;
2642
+ if (type === "relation") {
2643
+ return !attribute.relation.toLowerCase().includes("morph");
2644
+ }
2645
+ return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
2646
+ };
2647
+ const getMainField = (attribute, mainFieldName, { schemas, components }) => {
2648
+ if (!mainFieldName) {
2649
+ return void 0;
2650
+ }
2651
+ const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
2652
+ // @ts-expect-error – `targetModel` does exist on the attribute for a relation.
2653
+ schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
2654
+ );
2655
+ return {
2656
+ name: mainFieldName,
2657
+ type: mainFieldType ?? "string"
2658
+ };
2659
+ };
2660
+ const DEFAULT_SETTINGS = {
2661
+ bulkable: false,
2662
+ filterable: false,
2663
+ searchable: false,
2664
+ pagination: false,
2665
+ defaultSortBy: "",
2666
+ defaultSortOrder: "asc",
2667
+ mainField: "id",
2668
+ pageSize: 10
2669
+ };
2670
+ const useDocumentLayout = (model) => {
2671
+ const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
2672
+ const [{ query }] = strapiAdmin.useQueryParams();
2673
+ const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
2674
+ const { toggleNotification } = strapiAdmin.useNotification();
2675
+ const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
2676
+ const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
2677
+ const {
2678
+ data,
2679
+ isLoading: isLoadingConfigs,
2680
+ error,
2681
+ isFetching: isFetchingConfigs
2682
+ } = useGetContentTypeConfigurationQuery(model);
2683
+ const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
2684
+ React__namespace.useEffect(() => {
2685
+ if (error) {
2686
+ toggleNotification({
2687
+ type: "danger",
2688
+ message: formatAPIError(error)
2689
+ });
2690
+ }
2691
+ }, [error, formatAPIError, toggleNotification]);
2692
+ const editLayout = React__namespace.useMemo(
2693
+ () => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
2694
+ layout: [],
2695
+ components: {},
2696
+ metadatas: {},
2697
+ options: {},
2698
+ settings: DEFAULT_SETTINGS
2699
+ },
2700
+ [data, isLoading, schemas, schema, components]
2701
+ );
2702
+ const listLayout = React__namespace.useMemo(() => {
2703
+ return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
2704
+ layout: [],
2705
+ metadatas: {},
2706
+ options: {},
2707
+ settings: DEFAULT_SETTINGS
2708
+ };
2709
+ }, [data, isLoading, schemas, schema, components]);
2710
+ const { layout: edit } = React__namespace.useMemo(
2711
+ () => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
2712
+ layout: editLayout,
2713
+ query
2714
+ }),
2715
+ [editLayout, query, runHookWaterfall]
2716
+ );
2717
+ return {
2718
+ error,
2719
+ isLoading,
2720
+ edit,
2721
+ list: listLayout
2722
+ };
2723
+ };
2724
+ const useDocLayout = () => {
2725
+ const { model } = useDoc();
2726
+ return useDocumentLayout(model);
2727
+ };
2728
+ const formatEditLayout = (data, {
2729
+ schemas,
2730
+ schema,
2731
+ components
2732
+ }) => {
2733
+ let currentPanelIndex = 0;
2734
+ const panelledEditAttributes = convertEditLayoutToFieldLayouts(
2735
+ data.contentType.layouts.edit,
2736
+ schema?.attributes,
2737
+ data.contentType.metadatas,
2738
+ { configurations: data.components, schemas: components },
2739
+ schemas
2740
+ ).reduce((panels, row) => {
2741
+ if (row.some((field) => field.type === "dynamiczone")) {
2742
+ panels.push([row]);
2743
+ currentPanelIndex += 2;
2744
+ } else {
2745
+ if (!panels[currentPanelIndex]) {
2746
+ panels.push([]);
2747
+ }
2748
+ panels[currentPanelIndex].push(row);
2749
+ }
2750
+ return panels;
2751
+ }, []);
2752
+ const componentEditAttributes = Object.entries(data.components).reduce(
2753
+ (acc, [uid, configuration]) => {
2754
+ acc[uid] = {
2755
+ layout: convertEditLayoutToFieldLayouts(
2756
+ configuration.layouts.edit,
2757
+ components[uid].attributes,
2758
+ configuration.metadatas
2759
+ ),
2760
+ settings: {
2761
+ ...configuration.settings,
2762
+ icon: components[uid].info.icon,
2763
+ displayName: components[uid].info.displayName
2764
+ }
2765
+ };
2766
+ return acc;
2767
+ },
2768
+ {}
2769
+ );
2770
+ const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
2771
+ (acc, [attribute, metadata]) => {
2772
+ return {
2773
+ ...acc,
2774
+ [attribute]: metadata.edit
2775
+ };
2776
+ },
2777
+ {}
2778
+ );
2779
+ return {
2780
+ layout: panelledEditAttributes,
2781
+ components: componentEditAttributes,
2782
+ metadatas: editMetadatas,
2783
+ settings: {
2784
+ ...data.contentType.settings,
2785
+ displayName: schema?.info.displayName
2786
+ },
2787
+ options: {
2788
+ ...schema?.options,
2789
+ ...schema?.pluginOptions,
2790
+ ...data.contentType.options
2791
+ }
2792
+ };
2793
+ };
2794
+ const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
2795
+ return rows.map(
2796
+ (row) => row.map((field) => {
2797
+ const attribute = attributes[field.name];
2798
+ if (!attribute) {
2799
+ return null;
2800
+ }
2801
+ const { edit: metadata } = metadatas[field.name];
2802
+ const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
2803
+ return {
2804
+ attribute,
2805
+ disabled: !metadata.editable,
2806
+ hint: metadata.description,
2807
+ label: metadata.label ?? "",
2808
+ name: field.name,
2809
+ // @ts-expect-error – mainField does exist on the metadata for a relation.
2810
+ mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
2811
+ schemas,
2812
+ components: components?.schemas ?? {}
2813
+ }),
2814
+ placeholder: metadata.placeholder ?? "",
2815
+ required: attribute.required ?? false,
2816
+ size: field.size,
2817
+ unique: "unique" in attribute ? attribute.unique : false,
2818
+ visible: metadata.visible ?? true,
2819
+ type: attribute.type
2820
+ };
2821
+ }).filter((field) => field !== null)
2822
+ );
2823
+ };
2824
+ const formatListLayout = (data, {
2825
+ schemas,
2826
+ schema,
2827
+ components
2828
+ }) => {
2829
+ const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
2830
+ (acc, [attribute, metadata]) => {
2831
+ return {
2832
+ ...acc,
2833
+ [attribute]: metadata.list
2834
+ };
2835
+ },
2836
+ {}
2837
+ );
2838
+ const listAttributes = convertListLayoutToFieldLayouts(
2839
+ data.contentType.layouts.list,
2840
+ schema?.attributes,
2841
+ listMetadatas,
2842
+ { configurations: data.components, schemas: components },
2843
+ schemas
2844
+ );
2845
+ return {
2846
+ layout: listAttributes,
2847
+ settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
2848
+ metadatas: listMetadatas,
2849
+ options: {
2850
+ ...schema?.options,
2851
+ ...schema?.pluginOptions,
2852
+ ...data.contentType.options
2853
+ }
2854
+ };
2855
+ };
2856
+ const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
2857
+ return columns.map((name) => {
2858
+ const attribute = attributes[name];
2859
+ if (!attribute) {
2860
+ return null;
2861
+ }
2862
+ const metadata = metadatas[name];
2863
+ const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
2864
+ return {
2865
+ attribute,
2866
+ label: metadata.label ?? "",
2867
+ mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
2868
+ schemas,
2869
+ components: components?.schemas ?? {}
2870
+ }),
2871
+ name,
2872
+ searchable: metadata.searchable ?? true,
2873
+ sortable: metadata.sortable ?? true
2874
+ };
2875
+ }).filter((field) => field !== null);
2876
+ };
2877
+ const ConfirmBulkActionDialog = ({
2878
+ onToggleDialog,
2879
+ isOpen = false,
2880
+ dialogBody,
2881
+ endAction
2882
+ }) => {
2883
+ const { formatMessage } = reactIntl.useIntl();
2884
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
2885
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
2886
+ id: "app.components.ConfirmDialog.title",
2887
+ defaultMessage: "Confirmation"
2888
+ }) }),
2889
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
2890
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
2891
+ dialogBody
2892
+ ] }) }),
2893
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
2894
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
2895
+ id: "app.components.Button.cancel",
2896
+ defaultMessage: "Cancel"
2897
+ }) }) }),
2898
+ endAction
2899
+ ] })
2900
+ ] }) });
2901
+ };
2902
+ const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
2903
+ const ConfirmDialogPublishAll = ({
2904
+ isOpen,
2905
+ onToggleDialog,
2906
+ isConfirmButtonLoading = false,
2907
+ onConfirm
2908
+ }) => {
2909
+ const { formatMessage } = reactIntl.useIntl();
2910
+ const selectedEntries = strapiAdmin.useTable("ConfirmDialogPublishAll", (state) => state.selectedRows);
2911
+ const { toggleNotification } = strapiAdmin.useNotification();
2912
+ const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
2913
+ const { model, schema } = useDoc();
2914
+ const [{ query }] = strapiAdmin.useQueryParams();
2915
+ const {
2916
+ data: countDraftRelations = 0,
2917
+ isLoading,
2918
+ error
2919
+ } = useGetManyDraftRelationCountQuery(
2920
+ {
2921
+ model,
2922
+ documentIds: selectedEntries.map((entry) => entry.documentId),
2923
+ locale: query?.plugins?.i18n?.locale
2924
+ },
2925
+ {
2926
+ skip: selectedEntries.length === 0
2927
+ }
2928
+ );
2929
+ React__namespace.useEffect(() => {
2930
+ if (error) {
2931
+ toggleNotification({ type: "danger", message: formatAPIError(error) });
2932
+ }
2933
+ }, [error, formatAPIError, toggleNotification]);
2934
+ if (error) {
2935
+ return null;
2936
+ }
2937
+ return /* @__PURE__ */ jsxRuntime.jsx(
2938
+ ConfirmBulkActionDialog,
2939
+ {
2940
+ isOpen: isOpen && !isLoading,
2941
+ onToggleDialog,
2942
+ dialogBody: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2943
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: [
2944
+ countDraftRelations > 0 && formatMessage(
2945
+ {
2946
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
2947
+ 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. "
2948
+ },
2949
+ {
2950
+ b: BoldChunk$1,
2951
+ count: countDraftRelations,
2952
+ entities: selectedEntries.length
2953
+ }
2954
+ ),
2955
+ formatMessage({
2956
+ id: getTranslation("popUpWarning.bodyMessage.contentType.publish.all"),
2957
+ defaultMessage: "Are you sure you want to publish these entries?"
2958
+ })
2959
+ ] }),
2960
+ schema?.pluginOptions && "i18n" in schema.pluginOptions && schema?.pluginOptions.i18n && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", textAlign: "center", children: formatMessage(
2961
+ {
2962
+ id: getTranslation("Settings.list.actions.publishAdditionalInfos"),
2963
+ defaultMessage: "This will publish the active locale versions <em>(from Internationalization)</em>"
2964
+ },
2965
+ {
2966
+ em: Emphasis
2967
+ }
2968
+ ) })
2969
+ ] }),
2970
+ endAction: /* @__PURE__ */ jsxRuntime.jsx(
2971
+ designSystem.Button,
2972
+ {
2973
+ onClick: onConfirm,
2974
+ variant: "secondary",
2975
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Check, {}),
2976
+ loading: isConfirmButtonLoading,
2977
+ children: formatMessage({
2978
+ id: "app.utils.publish",
2979
+ defaultMessage: "Publish"
2980
+ })
2981
+ }
2982
+ )
2983
+ }
2984
+ );
2985
+ };
2986
+ const TypographyMaxWidth = styledComponents.styled(designSystem.Typography)`
2987
+ max-width: 300px;
2988
+ `;
2989
+ const formatErrorMessages = (errors, parentKey, formatMessage) => {
2990
+ const messages = [];
2991
+ Object.entries(errors).forEach(([key, value]) => {
2992
+ const currentKey = parentKey ? `${parentKey}.${key}` : key;
2993
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
2994
+ if ("id" in value && "defaultMessage" in value) {
2995
+ messages.push(
2996
+ formatMessage(
2997
+ {
2998
+ id: `${value.id}.withField`,
2999
+ defaultMessage: value.defaultMessage
3000
+ },
3001
+ { field: currentKey }
3002
+ )
3003
+ );
3004
+ } else {
3005
+ messages.push(
3006
+ ...formatErrorMessages(
3007
+ // @ts-expect-error TODO: check why value is not compatible with FormErrors
3008
+ value,
3009
+ currentKey,
3010
+ formatMessage
3011
+ )
3012
+ );
3013
+ }
3014
+ } else {
3015
+ messages.push(
3016
+ formatMessage(
3017
+ {
3018
+ id: `${value}.withField`,
3019
+ defaultMessage: value
3020
+ },
3021
+ { field: currentKey }
3022
+ )
3023
+ );
3024
+ }
3025
+ });
3026
+ return messages;
3027
+ };
3028
+ const EntryValidationText = ({ validationErrors, status }) => {
3029
+ const { formatMessage } = reactIntl.useIntl();
3030
+ if (validationErrors) {
3031
+ const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
3032
+ " "
3033
+ );
3034
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
3035
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.CrossCircle, { fill: "danger600" }),
3036
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
3037
+ ] });
3038
+ }
3039
+ if (status === "published") {
3040
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
3041
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
3042
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
3043
+ id: "content-manager.bulk-publish.already-published",
3044
+ defaultMessage: "Already Published"
3045
+ }) })
3046
+ ] });
3047
+ }
3048
+ if (status === "modified") {
3049
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
3050
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.ArrowsCounterClockwise, { fill: "alternative600" }),
3051
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
3052
+ id: "content-manager.bulk-publish.modified",
3053
+ defaultMessage: "Ready to publish changes"
3054
+ }) })
3055
+ ] });
3056
+ }
3057
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
3058
+ /* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
3059
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
3060
+ id: "app.utils.ready-to-publish",
3061
+ defaultMessage: "Ready to publish"
3062
+ }) })
3063
+ ] });
3064
+ };
3065
+ const TABLE_HEADERS = [
3066
+ { name: "id", label: "id" },
3067
+ { name: "name", label: "name" },
3068
+ { name: "status", label: "status" },
3069
+ { name: "publicationStatus", label: "Publication status" }
3070
+ ];
3071
+ const SelectedEntriesTableContent = ({
3072
+ isPublishing,
3073
+ rowsToDisplay = [],
3074
+ entriesToPublish = [],
3075
+ validationErrors = {}
3076
+ }) => {
3077
+ const { pathname } = reactRouterDom.useLocation();
3078
+ const { formatMessage } = reactIntl.useIntl();
3079
+ const {
3080
+ list: {
3081
+ settings: { mainField }
3082
+ }
3083
+ } = useDocLayout();
3084
+ const shouldDisplayMainField = mainField != null && mainField !== "id";
3085
+ return /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
3086
+ /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Head, { children: [
3087
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCheckboxCell, {}),
3088
+ TABLE_HEADERS.filter((head) => head.name !== "name" || shouldDisplayMainField).map(
3089
+ (head) => /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCell, { ...head }, head.name)
3090
+ )
3091
+ ] }),
3092
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Loading, {}),
3093
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Body, { children: rowsToDisplay.map((row, index2) => /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Row, { children: [
3094
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.CheckboxCell, { id: row.id }),
3095
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row.id }) }),
3096
+ shouldDisplayMainField && /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row[mainField] }) }),
3097
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: row.status, maxWidth: "min-content" }) }),
3098
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: isPublishing && entriesToPublish.includes(row.documentId) ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
3099
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
3100
+ id: "content-manager.success.record.publishing",
3101
+ defaultMessage: "Publishing..."
3102
+ }) }),
3103
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { small: true })
3104
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
3105
+ EntryValidationText,
3106
+ {
3107
+ validationErrors: validationErrors[row.documentId],
3108
+ status: row.status
3109
+ }
3110
+ ) }),
3111
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
3112
+ designSystem.IconButton,
3113
+ {
3114
+ tag: reactRouterDom.Link,
3115
+ to: {
3116
+ pathname: `${pathname}/${row.documentId}`,
3117
+ search: row.locale && `?plugins[i18n][locale]=${row.locale}`
3118
+ },
3119
+ state: { from: pathname },
3120
+ label: formatMessage(
3121
+ { id: "app.component.HelperPluginTable.edit", defaultMessage: "Edit {target}" },
3122
+ {
3123
+ target: formatMessage(
3124
+ {
3125
+ id: "content-manager.components.ListViewHelperPluginTable.row-line",
3126
+ defaultMessage: "item line {number}"
3127
+ },
3128
+ { number: index2 + 1 }
3129
+ )
3130
+ }
3131
+ ),
3132
+ target: "_blank",
3133
+ marginLeft: "auto",
3134
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, {})
3135
+ }
3136
+ ) })
3137
+ ] }, row.id)) })
3138
+ ] });
3139
+ };
3140
+ const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
3141
+ const SelectedEntriesModalContent = ({
3142
+ listViewSelectedEntries,
3143
+ toggleModal,
3144
+ setListViewSelectedDocuments,
3145
+ model
3146
+ }) => {
3147
+ const { formatMessage } = reactIntl.useIntl();
3148
+ const { schema, components } = useContentTypeSchema(model);
3149
+ const documentIds = listViewSelectedEntries.map(({ documentId }) => documentId);
3150
+ const [{ query }] = strapiAdmin.useQueryParams();
3151
+ const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
3152
+ const { data, isLoading, isFetching, refetch } = useGetAllDocumentsQuery(
3153
+ {
3154
+ model,
3155
+ params: {
3156
+ page: "1",
3157
+ pageSize: documentIds.length.toString(),
3158
+ sort: query.sort,
3159
+ filters: {
3160
+ documentId: {
3161
+ $in: documentIds
3162
+ }
3163
+ },
3164
+ locale: query.plugins?.i18n?.locale
3165
+ }
3166
+ },
3167
+ {
3168
+ selectFromResult: ({ data: data2, ...restRes }) => ({ data: data2?.results ?? [], ...restRes })
3169
+ }
3170
+ );
3171
+ const { rows, validationErrors } = React__namespace.useMemo(() => {
3172
+ if (data.length > 0 && schema) {
3173
+ const validate = createYupSchema(schema.attributes, components);
3174
+ const validationErrors2 = {};
3175
+ const rows2 = data.map((entry) => {
3176
+ try {
3177
+ validate.validateSync(entry, { abortEarly: false });
3178
+ return entry;
3179
+ } catch (e) {
3180
+ if (e instanceof yup.ValidationError) {
3181
+ validationErrors2[entry.documentId] = strapiAdmin.getYupValidationErrors(e);
3182
+ }
3183
+ return entry;
3184
+ }
3185
+ });
3186
+ return { rows: rows2, validationErrors: validationErrors2 };
3187
+ }
3188
+ return {
3189
+ rows: [],
3190
+ validationErrors: {}
3191
+ };
3192
+ }, [components, data, schema]);
3193
+ const [publishedCount, setPublishedCount] = React__namespace.useState(0);
3194
+ const [isDialogOpen, setIsDialogOpen] = React__namespace.useState(false);
3195
+ const { publishMany: bulkPublishAction } = useDocumentActions();
3196
+ const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
3197
+ const selectedRows = strapiAdmin.useTable("publishAction", (state) => state.selectedRows);
3198
+ const selectedEntries = rows.filter(
3199
+ (entry) => selectedRows.some((selectedEntry) => selectedEntry.documentId === entry.documentId)
3200
+ );
3201
+ const entriesToPublish = selectedEntries.filter((entry) => !validationErrors[entry.documentId]).map((entry) => entry.documentId);
3202
+ const selectedEntriesWithErrorsCount = selectedEntries.filter(
3203
+ ({ documentId }) => validationErrors[documentId]
3204
+ ).length;
3205
+ const selectedEntriesPublished = selectedEntries.filter(
3206
+ ({ status }) => status === "published"
3207
+ ).length;
3208
+ const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublished;
3209
+ const toggleDialog = () => setIsDialogOpen((prev) => !prev);
3210
+ const handleConfirmBulkPublish = async () => {
3211
+ toggleDialog();
3212
+ const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
3213
+ if (!("error" in res)) {
3214
+ setPublishedCount(res.count);
3215
+ const unpublishedEntries = rows.filter((row) => {
3216
+ return !entriesToPublish.includes(row.documentId);
3217
+ });
3218
+ setListViewSelectedDocuments(unpublishedEntries);
3219
+ }
3220
+ };
3221
+ const getFormattedCountMessage = () => {
3222
+ if (publishedCount) {
3223
+ return formatMessage(
3224
+ {
3225
+ id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
3226
+ 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."
3227
+ },
3228
+ {
3229
+ publishedCount,
3230
+ withErrorsCount: selectedEntriesWithErrorsCount,
3231
+ b: BoldChunk
3232
+ }
3233
+ );
3234
+ }
3235
+ return formatMessage(
3236
+ {
3237
+ id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
3238
+ 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."
3239
+ },
3240
+ {
3241
+ readyToPublishCount: selectedEntriesWithNoErrorsCount,
3242
+ withErrorsCount: selectedEntriesWithErrorsCount,
3243
+ alreadyPublishedCount: selectedEntriesPublished,
3244
+ b: BoldChunk
3245
+ }
3246
+ );
3247
+ };
3248
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3249
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
3250
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
3251
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsx(
3252
+ SelectedEntriesTableContent,
3253
+ {
3254
+ isPublishing: isSubmittingForm,
3255
+ rowsToDisplay: rows,
3256
+ entriesToPublish,
3257
+ validationErrors
3258
+ }
3259
+ ) })
3260
+ ] }),
3261
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
3262
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
3263
+ id: "app.components.Button.cancel",
3264
+ defaultMessage: "Cancel"
3265
+ }) }),
3266
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
3267
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
3268
+ /* @__PURE__ */ jsxRuntime.jsx(
3269
+ designSystem.Button,
3270
+ {
3271
+ onClick: toggleDialog,
3272
+ disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
3273
+ loading: isSubmittingForm,
3274
+ children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
3275
+ }
3276
+ )
3277
+ ] })
3278
+ ] }),
3279
+ /* @__PURE__ */ jsxRuntime.jsx(
3280
+ ConfirmDialogPublishAll,
3281
+ {
3282
+ isOpen: isDialogOpen,
3283
+ onToggleDialog: toggleDialog,
3284
+ isConfirmButtonLoading: isSubmittingForm,
3285
+ onConfirm: handleConfirmBulkPublish
3286
+ }
3287
+ )
3288
+ ] });
3289
+ };
3290
+ const PublishAction = ({ documents, model }) => {
3291
+ const { formatMessage } = reactIntl.useIntl();
3292
+ const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
3293
+ const showPublishButton = hasPublishPermission && documents.some(({ status }) => status !== "published");
3294
+ const setListViewSelectedDocuments = strapiAdmin.useTable("publishAction", (state) => state.selectRow);
3295
+ const refetchList = () => {
3296
+ contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
3297
+ };
3298
+ if (!showPublishButton)
3299
+ return null;
3300
+ return {
3301
+ actionType: "publish",
3302
+ variant: "tertiary",
3303
+ label: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" }),
3304
+ dialog: {
3305
+ type: "modal",
3306
+ title: formatMessage({
3307
+ id: getTranslation("containers.ListPage.selectedEntriesModal.title"),
3308
+ defaultMessage: "Publish entries"
3309
+ }),
3310
+ content: ({ onClose }) => {
3311
+ return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Root, { rows: documents, defaultSelectedRows: documents, headers: TABLE_HEADERS, children: /* @__PURE__ */ jsxRuntime.jsx(
3312
+ SelectedEntriesModalContent,
3313
+ {
3314
+ listViewSelectedEntries: documents,
3315
+ toggleModal: () => {
3316
+ onClose();
3317
+ refetchList();
3318
+ },
3319
+ setListViewSelectedDocuments,
3320
+ model
3321
+ }
3322
+ ) });
3323
+ },
3324
+ onClose: () => {
3325
+ refetchList();
3326
+ }
3327
+ }
3328
+ };
3329
+ };
3330
+ const BulkActionsRenderer = () => {
3331
+ const plugins = strapiAdmin.useStrapiApp("BulkActionsRenderer", (state) => state.plugins);
3332
+ const { model, collectionType } = useDoc();
3333
+ const { selectedRows } = strapiAdmin.useTable("BulkActionsRenderer", (state) => state);
3334
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
3335
+ strapiAdmin.DescriptionComponentRenderer,
3336
+ {
3337
+ props: {
3338
+ model,
3339
+ collectionType,
3340
+ documents: selectedRows
3341
+ },
3342
+ descriptions: plugins["content-manager"].apis.getBulkActions(),
3343
+ children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActionButton, { ...action }, action.id))
3344
+ }
3345
+ ) });
3346
+ };
3347
+ const DeleteAction = ({ documents, model }) => {
3348
+ const { formatMessage } = reactIntl.useIntl();
3349
+ const { schema: contentType } = useDoc();
3350
+ const selectRow = strapiAdmin.useTable("DeleteAction", (state) => state.selectRow);
3351
+ const hasI18nEnabled = Boolean(contentType?.pluginOptions?.i18n);
3352
+ const [{ query }] = strapiAdmin.useQueryParams();
3353
+ const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
3354
+ const hasDeletePermission = useDocumentRBAC("deleteAction", (state) => state.canDelete);
3355
+ const { deleteMany: bulkDeleteAction } = useDocumentActions();
3356
+ const documentIds = documents.map(({ documentId }) => documentId);
3357
+ const handleConfirmBulkDelete = async () => {
3358
+ const res = await bulkDeleteAction({
3359
+ documentIds,
3360
+ model,
3361
+ params
3362
+ });
3363
+ if (!("error" in res)) {
3364
+ selectRow([]);
3365
+ }
3366
+ };
3367
+ if (!hasDeletePermission)
3368
+ return null;
3369
+ return {
3370
+ variant: "danger-light",
3371
+ label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
3372
+ dialog: {
3373
+ type: "dialog",
3374
+ title: formatMessage({
3375
+ id: "app.components.ConfirmDialog.title",
3376
+ defaultMessage: "Confirmation"
3377
+ }),
3378
+ content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3379
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3380
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3381
+ id: "popUpWarning.bodyMessage.contentType.delete.all",
3382
+ defaultMessage: "Are you sure you want to delete these entries?"
3383
+ }) }),
3384
+ hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
3385
+ {
3386
+ id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
3387
+ defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
3388
+ },
3389
+ {
3390
+ em: Emphasis
3391
+ }
3392
+ ) }) })
3393
+ ] }),
3394
+ onConfirm: handleConfirmBulkDelete
3395
+ }
3396
+ };
3397
+ };
3398
+ DeleteAction.type = "delete";
3399
+ const UnpublishAction = ({ documents, model }) => {
3400
+ const { formatMessage } = reactIntl.useIntl();
3401
+ const { schema } = useDoc();
3402
+ const selectRow = strapiAdmin.useTable("UnpublishAction", (state) => state.selectRow);
3403
+ const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
3404
+ const hasI18nEnabled = Boolean(schema?.pluginOptions?.i18n);
3405
+ const hasDraftAndPublishEnabled = Boolean(schema?.options?.draftAndPublish);
3406
+ const { unpublishMany: bulkUnpublishAction } = useDocumentActions();
3407
+ const documentIds = documents.map(({ documentId }) => documentId);
3408
+ const [{ query }] = strapiAdmin.useQueryParams();
3409
+ const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
3410
+ const handleConfirmBulkUnpublish = async () => {
3411
+ const data = await bulkUnpublishAction({ documentIds, model, params });
3412
+ if (!("error" in data)) {
3413
+ selectRow([]);
3414
+ }
3415
+ };
3416
+ const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
3417
+ if (!showUnpublishButton)
3418
+ return null;
3419
+ return {
3420
+ variant: "tertiary",
3421
+ label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
3422
+ dialog: {
3423
+ type: "dialog",
3424
+ title: formatMessage({
3425
+ id: "app.components.ConfirmDialog.title",
3426
+ defaultMessage: "Confirmation"
3427
+ }),
3428
+ content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3429
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3430
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3431
+ id: "popUpWarning.bodyMessage.contentType.unpublish.all",
3432
+ defaultMessage: "Are you sure you want to unpublish these entries?"
3433
+ }) }),
3434
+ hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
3435
+ {
3436
+ id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
3437
+ defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
3438
+ },
3439
+ {
3440
+ em: Emphasis
3441
+ }
3442
+ ) }) })
3443
+ ] }),
3444
+ confirmButton: formatMessage({
3445
+ id: "app.utils.unpublish",
3446
+ defaultMessage: "Unpublish"
3447
+ }),
3448
+ onConfirm: handleConfirmBulkUnpublish
3449
+ }
3450
+ };
3451
+ };
3452
+ UnpublishAction.type = "unpublish";
3453
+ const Emphasis = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
3454
+ const DEFAULT_BULK_ACTIONS = [PublishAction, UnpublishAction, DeleteAction];
3455
+ const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
3456
+ const { formatMessage } = reactIntl.useIntl();
3457
+ const getDefaultErrorMessage = (reason) => {
3458
+ switch (reason) {
3459
+ case "relation":
3460
+ return "Duplicating the relation could remove it from the original entry.";
3461
+ case "unique":
3462
+ return "Identical values in a unique field are not allowed";
3463
+ default:
3464
+ return reason;
3465
+ }
3466
+ };
3467
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3468
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: formatMessage({
3469
+ id: getTranslation("containers.list.autoCloneModal.title"),
3470
+ defaultMessage: "This entry can't be duplicated directly."
3471
+ }) }),
3472
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatMessage({
3473
+ id: getTranslation("containers.list.autoCloneModal.description"),
3474
+ defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
3475
+ }) }) }),
3476
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxRuntime.jsxs(
3477
+ designSystem.Flex,
3478
+ {
3479
+ direction: "column",
3480
+ gap: 2,
3481
+ alignItems: "flex-start",
3482
+ borderColor: "neutral200",
3483
+ hasRadius: true,
3484
+ padding: 6,
3485
+ children: [
3486
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "row", tag: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { fontWeight: "semiBold", tag: "li", children: [
3487
+ pathSegment,
3488
+ index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
3489
+ Icons.ChevronRight,
3490
+ {
3491
+ fill: "neutral500",
3492
+ height: "0.8rem",
3493
+ width: "0.8rem",
3494
+ style: { margin: "0 0.8rem" }
3495
+ }
3496
+ )
3497
+ ] }, index2)) }),
3498
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", textColor: "neutral600", children: formatMessage({
3499
+ id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
3500
+ defaultMessage: getDefaultErrorMessage(reason)
3501
+ }) })
3502
+ ]
3503
+ },
3504
+ fieldPath.join()
3505
+ )) })
3506
+ ] });
3507
+ };
3508
+ const TableActions = ({ document }) => {
3509
+ const { formatMessage } = reactIntl.useIntl();
3510
+ const { model, collectionType } = useDoc();
3511
+ const plugins = strapiAdmin.useStrapiApp("TableActions", (state) => state.plugins);
3512
+ const props = {
3513
+ activeTab: null,
3514
+ model,
3515
+ documentId: document.documentId,
3516
+ collectionType,
3517
+ document
3518
+ };
3519
+ return /* @__PURE__ */ jsxRuntime.jsx(
3520
+ strapiAdmin.DescriptionComponentRenderer,
3521
+ {
3522
+ props,
3523
+ descriptions: plugins["content-manager"].apis.getDocumentActions(),
3524
+ children: (actions2) => {
3525
+ const tableRowActions = actions2.filter((action) => {
3526
+ const positions = Array.isArray(action.position) ? action.position : [action.position];
3527
+ return positions.includes("table-row");
3528
+ });
3529
+ return /* @__PURE__ */ jsxRuntime.jsx(
3530
+ DocumentActionsMenu,
3531
+ {
3532
+ actions: tableRowActions,
3533
+ label: formatMessage({
3534
+ id: "content-manager.containers.list.table.row-actions",
3535
+ defaultMessage: "Row action"
3536
+ }),
3537
+ variant: "ghost"
3538
+ }
3539
+ );
3540
+ }
3541
+ }
3542
+ );
3543
+ };
3544
+ const EditAction = ({ documentId }) => {
3545
+ const navigate = reactRouterDom.useNavigate();
3546
+ const { formatMessage } = reactIntl.useIntl();
3547
+ const { canRead } = useDocumentRBAC("EditAction", ({ canRead: canRead2 }) => ({ canRead: canRead2 }));
3548
+ const { toggleNotification } = strapiAdmin.useNotification();
3549
+ const [{ query }] = strapiAdmin.useQueryParams();
3550
+ return {
3551
+ disabled: !canRead,
3552
+ icon: /* @__PURE__ */ jsxRuntime.jsx(StyledPencil, {}),
3553
+ label: formatMessage({
3554
+ id: "content-manager.actions.edit.label",
3555
+ defaultMessage: "Edit"
3556
+ }),
3557
+ position: "table-row",
3558
+ onClick: async () => {
3559
+ if (!documentId) {
2572
3560
  console.error(
2573
3561
  "You're trying to edit a document without an id, this is likely a bug with Strapi. Please open an issue."
2574
3562
  );
@@ -2591,7 +3579,7 @@ const EditAction = ({ documentId }) => {
2591
3579
  };
2592
3580
  };
2593
3581
  EditAction.type = "edit";
2594
- const StyledPencil = styled__default.default(Icons.Pencil)`
3582
+ const StyledPencil = styledComponents.styled(Icons.Pencil)`
2595
3583
  path {
2596
3584
  fill: currentColor;
2597
3585
  }
@@ -2651,7 +3639,7 @@ const CloneAction = ({ model, documentId }) => {
2651
3639
  /* @__PURE__ */ jsxRuntime.jsx(
2652
3640
  designSystem.LinkButton,
2653
3641
  {
2654
- as: reactRouterDom.NavLink,
3642
+ tag: reactRouterDom.NavLink,
2655
3643
  to: {
2656
3644
  pathname: `clone/${documentId}`
2657
3645
  },
@@ -2667,7 +3655,7 @@ const CloneAction = ({ model, documentId }) => {
2667
3655
  };
2668
3656
  };
2669
3657
  CloneAction.type = "clone";
2670
- const StyledDuplicate = styled__default.default(Icons.Duplicate)`
3658
+ const StyledDuplicate = styledComponents.styled(Icons.Duplicate)`
2671
3659
  path {
2672
3660
  fill: currentColor;
2673
3661
  }
@@ -2684,442 +3672,183 @@ class ContentManagerPlugin {
2684
3672
  documentActions = [
2685
3673
  ...DEFAULT_ACTIONS,
2686
3674
  ...DEFAULT_TABLE_ROW_ACTIONS,
2687
- ...DEFAULT_HEADER_ACTIONS,
2688
- HistoryAction
3675
+ ...DEFAULT_HEADER_ACTIONS
2689
3676
  ];
2690
3677
  editViewSidePanels = [ActionsPanel];
2691
3678
  headerActions = [];
2692
3679
  constructor() {
2693
3680
  }
2694
- addEditViewSidePanel(panels) {
2695
- if (Array.isArray(panels)) {
2696
- this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
2697
- } else if (typeof panels === "function") {
2698
- this.editViewSidePanels = panels(this.editViewSidePanels);
2699
- } else {
2700
- throw new Error(
2701
- `Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
2702
- panels
2703
- )}`
2704
- );
2705
- }
2706
- }
2707
- addDocumentAction(actions2) {
2708
- if (Array.isArray(actions2)) {
2709
- this.documentActions = [...this.documentActions, ...actions2];
2710
- } else if (typeof actions2 === "function") {
2711
- this.documentActions = actions2(this.documentActions);
2712
- } else {
2713
- throw new Error(
2714
- `Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
2715
- actions2
2716
- )}`
2717
- );
2718
- }
2719
- }
2720
- addDocumentHeaderAction(actions2) {
2721
- if (Array.isArray(actions2)) {
2722
- this.headerActions = [...this.headerActions, ...actions2];
2723
- } else if (typeof actions2 === "function") {
2724
- this.headerActions = actions2(this.headerActions);
3681
+ addEditViewSidePanel(panels) {
3682
+ if (Array.isArray(panels)) {
3683
+ this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
3684
+ } else if (typeof panels === "function") {
3685
+ this.editViewSidePanels = panels(this.editViewSidePanels);
2725
3686
  } else {
2726
3687
  throw new Error(
2727
- `Expected the \`actions\` passed to \`addDocumentHeaderAction\` to be an array or a function, but received ${getPrintableType(
2728
- actions2
3688
+ `Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
3689
+ panels
2729
3690
  )}`
2730
3691
  );
2731
3692
  }
2732
3693
  }
2733
- addBulkAction(actions2) {
3694
+ addDocumentAction(actions2) {
2734
3695
  if (Array.isArray(actions2)) {
2735
- this.bulkActions = [...this.bulkActions, ...actions2];
3696
+ this.documentActions = [...this.documentActions, ...actions2];
2736
3697
  } else if (typeof actions2 === "function") {
2737
- this.bulkActions = actions2(this.bulkActions);
3698
+ this.documentActions = actions2(this.documentActions);
2738
3699
  } else {
2739
3700
  throw new Error(
2740
- `Expected the \`actions\` passed to \`addBulkAction\` to be an array or a function, but received ${getPrintableType(
3701
+ `Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
2741
3702
  actions2
2742
3703
  )}`
2743
- );
2744
- }
2745
- }
2746
- get config() {
2747
- return {
2748
- id: PLUGIN_ID,
2749
- name: "Content Manager",
2750
- injectionZones: INJECTION_ZONES,
2751
- apis: {
2752
- addBulkAction: this.addBulkAction.bind(this),
2753
- addDocumentAction: this.addDocumentAction.bind(this),
2754
- addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
2755
- addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
2756
- getBulkActions: () => this.bulkActions,
2757
- getDocumentActions: () => this.documentActions,
2758
- getEditViewSidePanels: () => this.editViewSidePanels,
2759
- getHeaderActions: () => this.headerActions
2760
- }
2761
- };
2762
- }
2763
- }
2764
- const getPrintableType = (value) => {
2765
- const nativeType = typeof value;
2766
- if (nativeType === "object") {
2767
- if (value === null)
2768
- return "null";
2769
- if (Array.isArray(value))
2770
- return "array";
2771
- if (value instanceof Object && value.constructor.name !== "Object") {
2772
- return value.constructor.name;
2773
- }
2774
- }
2775
- return nativeType;
2776
- };
2777
- const initialState = {
2778
- collectionTypeLinks: [],
2779
- components: [],
2780
- fieldSizes: {},
2781
- models: [],
2782
- singleTypeLinks: [],
2783
- isLoading: true
2784
- };
2785
- const appSlice = toolkit.createSlice({
2786
- name: "app",
2787
- initialState,
2788
- reducers: {
2789
- setInitialData(state, action) {
2790
- const {
2791
- authorizedCollectionTypeLinks,
2792
- authorizedSingleTypeLinks,
2793
- components,
2794
- contentTypeSchemas,
2795
- fieldSizes
2796
- } = action.payload;
2797
- state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
2798
- ({ isDisplayed }) => isDisplayed
2799
- );
2800
- state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
2801
- state.components = components;
2802
- state.models = contentTypeSchemas;
2803
- state.fieldSizes = fieldSizes;
2804
- state.isLoading = false;
2805
- }
2806
- }
2807
- });
2808
- const { actions, reducer: reducer$1 } = appSlice;
2809
- const { setInitialData } = actions;
2810
- const reducer = toolkit.combineReducers({
2811
- app: reducer$1
2812
- });
2813
- const HOOKS = {
2814
- /**
2815
- * Hook that allows to mutate the displayed headers of the list view table
2816
- * @constant
2817
- * @type {string}
2818
- */
2819
- INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
2820
- /**
2821
- * Hook that allows to mutate the CM's collection types links pre-set filters
2822
- * @constant
2823
- * @type {string}
2824
- */
2825
- MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
2826
- /**
2827
- * Hook that allows to mutate the CM's edit view layout
2828
- * @constant
2829
- * @type {string}
2830
- */
2831
- MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
2832
- /**
2833
- * Hook that allows to mutate the CM's single types links pre-set filters
2834
- * @constant
2835
- * @type {string}
2836
- */
2837
- MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
2838
- };
2839
- const contentTypesApi = contentManagerApi.injectEndpoints({
2840
- endpoints: (builder) => ({
2841
- getContentTypeConfiguration: builder.query({
2842
- query: (uid) => ({
2843
- url: `/content-manager/content-types/${uid}/configuration`,
2844
- method: "GET"
2845
- }),
2846
- transformResponse: (response) => response.data,
2847
- providesTags: (_result, _error, uid) => [
2848
- { type: "ContentTypesConfiguration", id: uid },
2849
- { type: "ContentTypeSettings", id: "LIST" }
2850
- ]
2851
- }),
2852
- getAllContentTypeSettings: builder.query({
2853
- query: () => "/content-manager/content-types-settings",
2854
- transformResponse: (response) => response.data,
2855
- providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
2856
- }),
2857
- updateContentTypeConfiguration: builder.mutation({
2858
- query: ({ uid, ...body }) => ({
2859
- url: `/content-manager/content-types/${uid}/configuration`,
2860
- method: "PUT",
2861
- data: body
2862
- }),
2863
- transformResponse: (response) => response.data,
2864
- invalidatesTags: (_result, _error, { uid }) => [
2865
- { type: "ContentTypesConfiguration", id: uid },
2866
- { type: "ContentTypeSettings", id: "LIST" },
2867
- // Is this necessary?
2868
- { type: "InitialData" }
2869
- ]
2870
- })
2871
- })
2872
- });
2873
- const {
2874
- useGetContentTypeConfigurationQuery,
2875
- useGetAllContentTypeSettingsQuery,
2876
- useUpdateContentTypeConfigurationMutation
2877
- } = contentTypesApi;
2878
- const checkIfAttributeIsDisplayable = (attribute) => {
2879
- const { type } = attribute;
2880
- if (type === "relation") {
2881
- return !attribute.relation.toLowerCase().includes("morph");
2882
- }
2883
- return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
2884
- };
2885
- const getMainField = (attribute, mainFieldName, { schemas, components }) => {
2886
- if (!mainFieldName) {
2887
- return void 0;
2888
- }
2889
- const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
2890
- // @ts-expect-error – `targetModel` does exist on the attribute for a relation.
2891
- schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
2892
- );
2893
- return {
2894
- name: mainFieldName,
2895
- type: mainFieldType ?? "string"
2896
- };
2897
- };
2898
- const DEFAULT_SETTINGS = {
2899
- bulkable: false,
2900
- filterable: false,
2901
- searchable: false,
2902
- pagination: false,
2903
- defaultSortBy: "",
2904
- defaultSortOrder: "asc",
2905
- mainField: "id",
2906
- pageSize: 10
2907
- };
2908
- const useDocumentLayout = (model) => {
2909
- const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
2910
- const [{ query }] = strapiAdmin.useQueryParams();
2911
- const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
2912
- const { toggleNotification } = strapiAdmin.useNotification();
2913
- const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
2914
- const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
2915
- const {
2916
- data,
2917
- isLoading: isLoadingConfigs,
2918
- error,
2919
- isFetching: isFetchingConfigs
2920
- } = useGetContentTypeConfigurationQuery(model);
2921
- const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
2922
- React__namespace.useEffect(() => {
2923
- if (error) {
2924
- toggleNotification({
2925
- type: "danger",
2926
- message: formatAPIError(error)
2927
- });
2928
- }
2929
- }, [error, formatAPIError, toggleNotification]);
2930
- const editLayout = React__namespace.useMemo(
2931
- () => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
2932
- layout: [],
2933
- components: {},
2934
- metadatas: {},
2935
- options: {},
2936
- settings: DEFAULT_SETTINGS
2937
- },
2938
- [data, isLoading, schemas, schema, components]
2939
- );
2940
- const listLayout = React__namespace.useMemo(() => {
2941
- return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
2942
- layout: [],
2943
- metadatas: {},
2944
- options: {},
2945
- settings: DEFAULT_SETTINGS
2946
- };
2947
- }, [data, isLoading, schemas, schema, components]);
2948
- const { layout: edit } = React__namespace.useMemo(
2949
- () => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
2950
- layout: editLayout,
2951
- query
2952
- }),
2953
- [editLayout, query, runHookWaterfall]
2954
- );
2955
- return {
2956
- error,
2957
- isLoading,
2958
- edit,
2959
- list: listLayout
2960
- };
2961
- };
2962
- const useDocLayout = () => {
2963
- const { model } = useDoc();
2964
- return useDocumentLayout(model);
2965
- };
2966
- const formatEditLayout = (data, {
2967
- schemas,
2968
- schema,
2969
- components
2970
- }) => {
2971
- let currentPanelIndex = 0;
2972
- const panelledEditAttributes = convertEditLayoutToFieldLayouts(
2973
- data.contentType.layouts.edit,
2974
- schema?.attributes,
2975
- data.contentType.metadatas,
2976
- { configurations: data.components, schemas: components },
2977
- schemas
2978
- ).reduce((panels, row) => {
2979
- if (row.some((field) => field.type === "dynamiczone")) {
2980
- panels.push([row]);
2981
- currentPanelIndex += 2;
3704
+ );
3705
+ }
3706
+ }
3707
+ addDocumentHeaderAction(actions2) {
3708
+ if (Array.isArray(actions2)) {
3709
+ this.headerActions = [...this.headerActions, ...actions2];
3710
+ } else if (typeof actions2 === "function") {
3711
+ this.headerActions = actions2(this.headerActions);
2982
3712
  } else {
2983
- if (!panels[currentPanelIndex]) {
2984
- panels.push([]);
2985
- }
2986
- panels[currentPanelIndex].push(row);
3713
+ throw new Error(
3714
+ `Expected the \`actions\` passed to \`addDocumentHeaderAction\` to be an array or a function, but received ${getPrintableType(
3715
+ actions2
3716
+ )}`
3717
+ );
2987
3718
  }
2988
- return panels;
2989
- }, []);
2990
- const componentEditAttributes = Object.entries(data.components).reduce(
2991
- (acc, [uid, configuration]) => {
2992
- acc[uid] = {
2993
- layout: convertEditLayoutToFieldLayouts(
2994
- configuration.layouts.edit,
2995
- components[uid].attributes,
2996
- configuration.metadatas
2997
- ),
2998
- settings: {
2999
- ...configuration.settings,
3000
- icon: components[uid].info.icon,
3001
- displayName: components[uid].info.displayName
3002
- }
3003
- };
3004
- return acc;
3005
- },
3006
- {}
3007
- );
3008
- const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
3009
- (acc, [attribute, metadata]) => {
3010
- return {
3011
- ...acc,
3012
- [attribute]: metadata.edit
3013
- };
3014
- },
3015
- {}
3016
- );
3017
- return {
3018
- layout: panelledEditAttributes,
3019
- components: componentEditAttributes,
3020
- metadatas: editMetadatas,
3021
- settings: {
3022
- ...data.contentType.settings,
3023
- displayName: schema?.info.displayName
3024
- },
3025
- options: {
3026
- ...schema?.options,
3027
- ...schema?.pluginOptions,
3028
- ...data.contentType.options
3719
+ }
3720
+ addBulkAction(actions2) {
3721
+ if (Array.isArray(actions2)) {
3722
+ this.bulkActions = [...this.bulkActions, ...actions2];
3723
+ } else if (typeof actions2 === "function") {
3724
+ this.bulkActions = actions2(this.bulkActions);
3725
+ } else {
3726
+ throw new Error(
3727
+ `Expected the \`actions\` passed to \`addBulkAction\` to be an array or a function, but received ${getPrintableType(
3728
+ actions2
3729
+ )}`
3730
+ );
3029
3731
  }
3030
- };
3031
- };
3032
- const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
3033
- return rows.map(
3034
- (row) => row.map((field) => {
3035
- const attribute = attributes[field.name];
3036
- if (!attribute) {
3037
- return null;
3732
+ }
3733
+ get config() {
3734
+ return {
3735
+ id: PLUGIN_ID,
3736
+ name: "Content Manager",
3737
+ injectionZones: INJECTION_ZONES,
3738
+ apis: {
3739
+ addBulkAction: this.addBulkAction.bind(this),
3740
+ addDocumentAction: this.addDocumentAction.bind(this),
3741
+ addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
3742
+ addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
3743
+ getBulkActions: () => this.bulkActions,
3744
+ getDocumentActions: () => this.documentActions,
3745
+ getEditViewSidePanels: () => this.editViewSidePanels,
3746
+ getHeaderActions: () => this.headerActions
3038
3747
  }
3039
- const { edit: metadata } = metadatas[field.name];
3040
- const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
3041
- return {
3042
- attribute,
3043
- disabled: !metadata.editable,
3044
- hint: metadata.description,
3045
- label: metadata.label ?? "",
3046
- name: field.name,
3047
- // @ts-expect-error – mainField does exist on the metadata for a relation.
3048
- mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
3049
- schemas,
3050
- components: components?.schemas ?? {}
3051
- }),
3052
- placeholder: metadata.placeholder ?? "",
3053
- required: attribute.required ?? false,
3054
- size: field.size,
3055
- unique: "unique" in attribute ? attribute.unique : false,
3056
- visible: metadata.visible ?? true,
3057
- type: attribute.type
3058
- };
3059
- }).filter((field) => field !== null)
3060
- );
3748
+ };
3749
+ }
3750
+ }
3751
+ const getPrintableType = (value) => {
3752
+ const nativeType = typeof value;
3753
+ if (nativeType === "object") {
3754
+ if (value === null)
3755
+ return "null";
3756
+ if (Array.isArray(value))
3757
+ return "array";
3758
+ if (value instanceof Object && value.constructor.name !== "Object") {
3759
+ return value.constructor.name;
3760
+ }
3761
+ }
3762
+ return nativeType;
3061
3763
  };
3062
- const formatListLayout = (data, {
3063
- schemas,
3064
- schema,
3065
- components
3066
- }) => {
3067
- const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
3068
- (acc, [attribute, metadata]) => {
3069
- return {
3070
- ...acc,
3071
- [attribute]: metadata.list
3072
- };
3073
- },
3074
- {}
3075
- );
3076
- const listAttributes = convertListLayoutToFieldLayouts(
3077
- data.contentType.layouts.list,
3078
- schema?.attributes,
3079
- listMetadatas,
3080
- { configurations: data.components, schemas: components },
3081
- schemas
3082
- );
3764
+ const HistoryAction = ({ model, document }) => {
3765
+ const { formatMessage } = reactIntl.useIntl();
3766
+ const [{ query }] = strapiAdmin.useQueryParams();
3767
+ const navigate = reactRouterDom.useNavigate();
3768
+ const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
3769
+ if (!window.strapi.features.isEnabled("cms-content-history")) {
3770
+ return null;
3771
+ }
3083
3772
  return {
3084
- layout: listAttributes,
3085
- settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
3086
- metadatas: listMetadatas,
3087
- options: {
3088
- ...schema?.options,
3089
- ...schema?.pluginOptions,
3090
- ...data.contentType.options
3091
- }
3773
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
3774
+ label: formatMessage({
3775
+ id: "content-manager.history.document-action",
3776
+ defaultMessage: "Content History"
3777
+ }),
3778
+ onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
3779
+ disabled: (
3780
+ /**
3781
+ * The user is creating a new document.
3782
+ * It hasn't been saved yet, so there's no history to go to
3783
+ */
3784
+ !document || /**
3785
+ * The document has been created but the current dimension has never been saved.
3786
+ * For example, the user is creating a new locale in an existing document,
3787
+ * so there's no history for the document in that locale
3788
+ */
3789
+ !document.id || /**
3790
+ * History is only available for content types created by the user.
3791
+ * These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
3792
+ * which start with `admin::` or `plugin::`
3793
+ */
3794
+ !model.startsWith("api::")
3795
+ ),
3796
+ position: "header"
3092
3797
  };
3093
3798
  };
3094
- const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
3095
- return columns.map((name) => {
3096
- const attribute = attributes[name];
3097
- if (!attribute) {
3098
- return null;
3099
- }
3100
- const metadata = metadatas[name];
3101
- const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
3102
- return {
3103
- attribute,
3104
- label: metadata.label ?? "",
3105
- mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
3106
- schemas,
3107
- components: components?.schemas ?? {}
3108
- }),
3109
- name,
3110
- searchable: metadata.searchable ?? true,
3111
- sortable: metadata.sortable ?? true
3112
- };
3113
- }).filter((field) => field !== null);
3799
+ HistoryAction.type = "history";
3800
+ const historyAdmin = {
3801
+ bootstrap(app) {
3802
+ const { addDocumentAction } = app.getPlugin("content-manager").apis;
3803
+ addDocumentAction((actions2) => {
3804
+ const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
3805
+ actions2.splice(indexOfDeleteAction, 0, HistoryAction);
3806
+ return actions2;
3807
+ });
3808
+ }
3809
+ };
3810
+ const initialState = {
3811
+ collectionTypeLinks: [],
3812
+ components: [],
3813
+ fieldSizes: {},
3814
+ models: [],
3815
+ singleTypeLinks: [],
3816
+ isLoading: true
3114
3817
  };
3818
+ const appSlice = toolkit.createSlice({
3819
+ name: "app",
3820
+ initialState,
3821
+ reducers: {
3822
+ setInitialData(state, action) {
3823
+ const {
3824
+ authorizedCollectionTypeLinks,
3825
+ authorizedSingleTypeLinks,
3826
+ components,
3827
+ contentTypeSchemas,
3828
+ fieldSizes
3829
+ } = action.payload;
3830
+ state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
3831
+ ({ isDisplayed }) => isDisplayed
3832
+ );
3833
+ state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
3834
+ state.components = components;
3835
+ state.models = contentTypeSchemas;
3836
+ state.fieldSizes = fieldSizes;
3837
+ state.isLoading = false;
3838
+ }
3839
+ }
3840
+ });
3841
+ const { actions, reducer: reducer$1 } = appSlice;
3842
+ const { setInitialData } = actions;
3843
+ const reducer = toolkit.combineReducers({
3844
+ app: reducer$1
3845
+ });
3115
3846
  const index = {
3116
3847
  register(app) {
3117
3848
  const cm = new ContentManagerPlugin();
3118
3849
  app.addReducers({
3119
- [contentManagerApi.reducerPath]: contentManagerApi.reducer,
3120
3850
  [PLUGIN_ID]: reducer
3121
3851
  });
3122
- app.addMiddlewares([() => contentManagerApi.middleware]);
3123
3852
  app.addMenuLink({
3124
3853
  to: PLUGIN_ID,
3125
3854
  icon: Icons.Feather,
@@ -3128,14 +3857,29 @@ const index = {
3128
3857
  defaultMessage: "Content Manager"
3129
3858
  },
3130
3859
  permissions: [],
3131
- Component: () => Promise.resolve().then(() => require("./layout-B_SXLhqf.js")).then((mod) => ({ default: mod.Layout }))
3860
+ position: 1
3861
+ });
3862
+ app.router.addRoute({
3863
+ path: "content-manager/*",
3864
+ lazy: async () => {
3865
+ const { Layout } = await Promise.resolve().then(() => require("./layout-CLLtt_5O.js"));
3866
+ return {
3867
+ Component: Layout
3868
+ };
3869
+ },
3870
+ children: routes
3132
3871
  });
3133
3872
  app.registerPlugin(cm.config);
3134
3873
  },
3874
+ bootstrap(app) {
3875
+ if (typeof historyAdmin.bootstrap === "function") {
3876
+ historyAdmin.bootstrap(app);
3877
+ }
3878
+ },
3135
3879
  async registerTrads({ locales }) {
3136
3880
  const importedTrads = await Promise.all(
3137
3881
  locales.map((locale) => {
3138
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-C-V1_90f.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-EUonQTon.js")), "./translations/eu.json": () => Promise.resolve().then(() => require("./eu-VDH-3ovk.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-B7kGGg3E.js")), "./translations/gu.json": () => Promise.resolve().then(() => require("./gu-BRmF601H.js")), "./translations/hi.json": () => Promise.resolve().then(() => require("./hi-CCJBptSq.js")), "./translations/hu.json": () => Promise.resolve().then(() => require("./hu-sNV_yLYy.js")), "./translations/id.json": () => Promise.resolve().then(() => require("./id-B5Ser98A.js")), "./translations/it.json": () => Promise.resolve().then(() => require("./it-DkBIs7vD.js")), "./translations/ja.json": () => Promise.resolve().then(() => require("./ja-CcFe8diO.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-woFZPmLk.js")), "./translations/ml.json": () => Promise.resolve().then(() => require("./ml-C2W8N8k1.js")), "./translations/ms.json": () => Promise.resolve().then(() => require("./ms-BuFotyP_.js")), "./translations/nl.json": () => Promise.resolve().then(() => require("./nl-bbEOHChV.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-uzwG-hk7.js")), "./translations/pt-BR.json": () => Promise.resolve().then(() => require("./pt-BR-BiOz37D9.js")), "./translations/pt.json": () => Promise.resolve().then(() => require("./pt-CeXQuq50.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BT3ybNny.js")), "./translations/sa.json": () => Promise.resolve().then(() => require("./sa-CcvkYInH.js")), "./translations/sk.json": () => Promise.resolve().then(() => require("./sk-CvY09Xjv.js")), "./translations/sv.json": () => Promise.resolve().then(() => require("./sv-MYDuzgvT.js")), "./translations/th.json": () => Promise.resolve().then(() => require("./th-D9_GfAjc.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-D9UH-O_R.js")), "./translations/uk.json": () => Promise.resolve().then(() => require("./uk-C8EiqJY7.js")), "./translations/vi.json": () => Promise.resolve().then(() => require("./vi-CJlYDheJ.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-9kOncHGw.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CQQfszqR.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
3882
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-uOUIxfcQ.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-EUonQTon.js")), "./translations/eu.json": () => Promise.resolve().then(() => require("./eu-VDH-3ovk.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-B7kGGg3E.js")), "./translations/gu.json": () => Promise.resolve().then(() => require("./gu-BRmF601H.js")), "./translations/hi.json": () => Promise.resolve().then(() => require("./hi-CCJBptSq.js")), "./translations/hu.json": () => Promise.resolve().then(() => require("./hu-sNV_yLYy.js")), "./translations/id.json": () => Promise.resolve().then(() => require("./id-B5Ser98A.js")), "./translations/it.json": () => Promise.resolve().then(() => require("./it-DkBIs7vD.js")), "./translations/ja.json": () => Promise.resolve().then(() => require("./ja-CcFe8diO.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-woFZPmLk.js")), "./translations/ml.json": () => Promise.resolve().then(() => require("./ml-C2W8N8k1.js")), "./translations/ms.json": () => Promise.resolve().then(() => require("./ms-BuFotyP_.js")), "./translations/nl.json": () => Promise.resolve().then(() => require("./nl-bbEOHChV.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-uzwG-hk7.js")), "./translations/pt-BR.json": () => Promise.resolve().then(() => require("./pt-BR-BiOz37D9.js")), "./translations/pt.json": () => Promise.resolve().then(() => require("./pt-CeXQuq50.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BT3ybNny.js")), "./translations/sa.json": () => Promise.resolve().then(() => require("./sa-CcvkYInH.js")), "./translations/sk.json": () => Promise.resolve().then(() => require("./sk-CvY09Xjv.js")), "./translations/sv.json": () => Promise.resolve().then(() => require("./sv-MYDuzgvT.js")), "./translations/th.json": () => Promise.resolve().then(() => require("./th-D9_GfAjc.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-D9UH-O_R.js")), "./translations/uk.json": () => Promise.resolve().then(() => require("./uk-C8EiqJY7.js")), "./translations/vi.json": () => Promise.resolve().then(() => require("./vi-CJlYDheJ.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-9kOncHGw.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CQQfszqR.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
3139
3883
  return {
3140
3884
  data: prefixPluginTranslations(data, PLUGIN_ID),
3141
3885
  locale
@@ -3152,6 +3896,7 @@ const index = {
3152
3896
  }
3153
3897
  };
3154
3898
  exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
3899
+ exports.BulkActionsRenderer = BulkActionsRenderer;
3155
3900
  exports.COLLECTION_TYPES = COLLECTION_TYPES;
3156
3901
  exports.CREATOR_FIELDS = CREATOR_FIELDS;
3157
3902
  exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
@@ -3178,7 +3923,6 @@ exports.getDisplayName = getDisplayName;
3178
3923
  exports.getMainField = getMainField;
3179
3924
  exports.getTranslation = getTranslation;
3180
3925
  exports.index = index;
3181
- exports.routes = routes;
3182
3926
  exports.setInitialData = setInitialData;
3183
3927
  exports.useContentTypeSchema = useContentTypeSchema;
3184
3928
  exports.useDoc = useDoc;
@@ -3192,4 +3936,4 @@ exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
3192
3936
  exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
3193
3937
  exports.useGetInitialDataQuery = useGetInitialDataQuery;
3194
3938
  exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
3195
- //# sourceMappingURL=index-C6AH2hEl.js.map
3939
+ //# sourceMappingURL=index-Dd0nXyJF.js.map