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

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 (133) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-BMajAl1u.mjs → ComponentConfigurationPage-7-qB29e7.mjs} +3 -3
  3. package/dist/_chunks/{ComponentConfigurationPage-BMajAl1u.mjs.map → ComponentConfigurationPage-7-qB29e7.mjs.map} +1 -1
  4. package/dist/_chunks/{ComponentConfigurationPage-y_7iLdmB.js → ComponentConfigurationPage-DP7AC0UU.js} +3 -3
  5. package/dist/_chunks/{ComponentConfigurationPage-y_7iLdmB.js.map → ComponentConfigurationPage-DP7AC0UU.js.map} +1 -1
  6. package/dist/_chunks/{EditConfigurationPage-CcOoD26O.mjs → EditConfigurationPage-CI4XoymK.mjs} +3 -3
  7. package/dist/_chunks/{EditConfigurationPage-CcOoD26O.mjs.map → EditConfigurationPage-CI4XoymK.mjs.map} +1 -1
  8. package/dist/_chunks/{EditConfigurationPage-CPVB8Uqc.js → EditConfigurationPage-DITVliEI.js} +3 -3
  9. package/dist/_chunks/{EditConfigurationPage-CPVB8Uqc.js.map → EditConfigurationPage-DITVliEI.js.map} +1 -1
  10. package/dist/_chunks/{EditViewPage-CTTDHKkQ.js → EditViewPage-CUS2EAhB.js} +62 -47
  11. package/dist/_chunks/EditViewPage-CUS2EAhB.js.map +1 -0
  12. package/dist/_chunks/{EditViewPage-DWb0DE7R.mjs → EditViewPage-Dzpno8xI.mjs} +63 -48
  13. package/dist/_chunks/EditViewPage-Dzpno8xI.mjs.map +1 -0
  14. package/dist/_chunks/{Field-DnStdvQw.mjs → Field-B_jG_EV9.mjs} +541 -221
  15. package/dist/_chunks/Field-B_jG_EV9.mjs.map +1 -0
  16. package/dist/_chunks/{Field-C5Z1Ivdv.js → Field-CtUU1Fg8.js} +543 -223
  17. package/dist/_chunks/Field-CtUU1Fg8.js.map +1 -0
  18. package/dist/_chunks/{Form-DqGgE55Q.mjs → Form-BXHao2mZ.mjs} +53 -35
  19. package/dist/_chunks/Form-BXHao2mZ.mjs.map +1 -0
  20. package/dist/_chunks/{Form-B81OtW-k.js → Form-DTqO0ymI.js} +51 -33
  21. package/dist/_chunks/Form-DTqO0ymI.js.map +1 -0
  22. package/dist/_chunks/{History-DS6-HCYX.mjs → History-2Ah2CQ4T.mjs} +52 -29
  23. package/dist/_chunks/History-2Ah2CQ4T.mjs.map +1 -0
  24. package/dist/_chunks/{History-4NbOq2dX.js → History-C_uSGzO5.js} +51 -28
  25. package/dist/_chunks/History-C_uSGzO5.js.map +1 -0
  26. package/dist/_chunks/{ListConfigurationPage-DQJJltko.mjs → ListConfigurationPage-BjSJlaoC.mjs} +58 -48
  27. package/dist/_chunks/ListConfigurationPage-BjSJlaoC.mjs.map +1 -0
  28. package/dist/_chunks/{ListConfigurationPage-CpfstlYY.js → ListConfigurationPage-nyuP7OSy.js} +57 -46
  29. package/dist/_chunks/ListConfigurationPage-nyuP7OSy.js.map +1 -0
  30. package/dist/_chunks/{ListViewPage-nQrOQuVo.mjs → ListViewPage-B75x3nz2.mjs} +103 -102
  31. package/dist/_chunks/ListViewPage-B75x3nz2.mjs.map +1 -0
  32. package/dist/_chunks/{ListViewPage-CA3I75m5.js → ListViewPage-DHgHD8Xg.js} +105 -104
  33. package/dist/_chunks/ListViewPage-DHgHD8Xg.js.map +1 -0
  34. package/dist/_chunks/{NoContentTypePage-Dldu-_Mx.js → NoContentTypePage-CDUKdZ7d.js} +2 -2
  35. package/dist/_chunks/{NoContentTypePage-Dldu-_Mx.js.map → NoContentTypePage-CDUKdZ7d.js.map} +1 -1
  36. package/dist/_chunks/{NoContentTypePage-DbnHE22g.mjs → NoContentTypePage-DUacQSyF.mjs} +2 -2
  37. package/dist/_chunks/{NoContentTypePage-DbnHE22g.mjs.map → NoContentTypePage-DUacQSyF.mjs.map} +1 -1
  38. package/dist/_chunks/{NoPermissionsPage-fOIkQM0v.mjs → NoPermissionsPage-SFllMekk.mjs} +2 -2
  39. package/dist/_chunks/{NoPermissionsPage-fOIkQM0v.mjs.map → NoPermissionsPage-SFllMekk.mjs.map} +1 -1
  40. package/dist/_chunks/{NoPermissionsPage-CO2MK200.js → NoPermissionsPage-zwIZydDI.js} +2 -2
  41. package/dist/_chunks/{NoPermissionsPage-CO2MK200.js.map → NoPermissionsPage-zwIZydDI.js.map} +1 -1
  42. package/dist/_chunks/{Relations-BDRl99Ux.mjs → Relations-D2NRW8fC.mjs} +14 -10
  43. package/dist/_chunks/Relations-D2NRW8fC.mjs.map +1 -0
  44. package/dist/_chunks/{Relations-DG2jnOcr.js → Relations-NFLaRNPr.js} +14 -10
  45. package/dist/_chunks/Relations-NFLaRNPr.js.map +1 -0
  46. package/dist/_chunks/{en-fbKQxLGn.js → en-BlhnxQfj.js} +11 -9
  47. package/dist/_chunks/{en-fbKQxLGn.js.map → en-BlhnxQfj.js.map} +1 -1
  48. package/dist/_chunks/{en-Ux26r5pl.mjs → en-C8YBvRrK.mjs} +11 -9
  49. package/dist/_chunks/{en-Ux26r5pl.mjs.map → en-C8YBvRrK.mjs.map} +1 -1
  50. package/dist/_chunks/{index-Drt2DN7v.mjs → index-C9HxCo5R.mjs} +1008 -867
  51. package/dist/_chunks/index-C9HxCo5R.mjs.map +1 -0
  52. package/dist/_chunks/{index-BZoNZMXL.js → index-ovJRE1FM.js} +998 -857
  53. package/dist/_chunks/index-ovJRE1FM.js.map +1 -0
  54. package/dist/_chunks/{layout-BzAbmoO6.mjs → layout-DaUjDiWQ.mjs} +27 -14
  55. package/dist/_chunks/layout-DaUjDiWQ.mjs.map +1 -0
  56. package/dist/_chunks/{layout-DEYBqgF1.js → layout-UNWstw_s.js} +25 -12
  57. package/dist/_chunks/layout-UNWstw_s.js.map +1 -0
  58. package/dist/_chunks/{relations-D26zVRdi.mjs → relations-D8iFAeRu.mjs} +2 -2
  59. package/dist/_chunks/{relations-D26zVRdi.mjs.map → relations-D8iFAeRu.mjs.map} +1 -1
  60. package/dist/_chunks/{relations-D0eZ4VWw.js → relations-NN3coOG5.js} +2 -2
  61. package/dist/_chunks/{relations-D0eZ4VWw.js.map → relations-NN3coOG5.js.map} +1 -1
  62. package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
  63. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
  64. package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
  65. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
  66. package/dist/admin/index.js +2 -1
  67. package/dist/admin/index.js.map +1 -1
  68. package/dist/admin/index.mjs +3 -2
  69. package/dist/admin/src/exports.d.ts +1 -1
  70. package/dist/admin/src/history/index.d.ts +3 -0
  71. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  72. package/dist/admin/src/hooks/useDocument.d.ts +32 -1
  73. package/dist/admin/src/index.d.ts +1 -0
  74. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +8 -3
  75. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
  76. package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
  77. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
  78. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
  79. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +6 -58
  80. package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
  81. package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
  82. package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
  83. package/dist/admin/src/services/api.d.ts +1 -1
  84. package/dist/admin/src/services/components.d.ts +2 -2
  85. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  86. package/dist/admin/src/services/documents.d.ts +19 -17
  87. package/dist/admin/src/services/init.d.ts +1 -1
  88. package/dist/admin/src/services/relations.d.ts +2 -2
  89. package/dist/admin/src/services/uid.d.ts +3 -3
  90. package/dist/admin/src/utils/validation.d.ts +4 -1
  91. package/dist/server/index.js +191 -110
  92. package/dist/server/index.js.map +1 -1
  93. package/dist/server/index.mjs +192 -111
  94. package/dist/server/index.mjs.map +1 -1
  95. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  96. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  97. package/dist/server/src/controllers/uid.d.ts.map +1 -1
  98. package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
  99. package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
  100. package/dist/server/src/history/services/history.d.ts.map +1 -1
  101. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  102. package/dist/server/src/history/services/utils.d.ts +2 -1
  103. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  104. package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
  105. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  106. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  107. package/dist/server/src/services/permission-checker.d.ts.map +1 -1
  108. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  109. package/dist/shared/contracts/collection-types.d.ts +3 -1
  110. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  111. package/package.json +11 -11
  112. package/dist/_chunks/EditViewPage-CTTDHKkQ.js.map +0 -1
  113. package/dist/_chunks/EditViewPage-DWb0DE7R.mjs.map +0 -1
  114. package/dist/_chunks/Field-C5Z1Ivdv.js.map +0 -1
  115. package/dist/_chunks/Field-DnStdvQw.mjs.map +0 -1
  116. package/dist/_chunks/Form-B81OtW-k.js.map +0 -1
  117. package/dist/_chunks/Form-DqGgE55Q.mjs.map +0 -1
  118. package/dist/_chunks/History-4NbOq2dX.js.map +0 -1
  119. package/dist/_chunks/History-DS6-HCYX.mjs.map +0 -1
  120. package/dist/_chunks/ListConfigurationPage-CpfstlYY.js.map +0 -1
  121. package/dist/_chunks/ListConfigurationPage-DQJJltko.mjs.map +0 -1
  122. package/dist/_chunks/ListViewPage-CA3I75m5.js.map +0 -1
  123. package/dist/_chunks/ListViewPage-nQrOQuVo.mjs.map +0 -1
  124. package/dist/_chunks/Relations-BDRl99Ux.mjs.map +0 -1
  125. package/dist/_chunks/Relations-DG2jnOcr.js.map +0 -1
  126. package/dist/_chunks/index-BZoNZMXL.js.map +0 -1
  127. package/dist/_chunks/index-Drt2DN7v.mjs.map +0 -1
  128. package/dist/_chunks/layout-BzAbmoO6.mjs.map +0 -1
  129. package/dist/_chunks/layout-DEYBqgF1.js.map +0 -1
  130. package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
  131. package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
  132. package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
  133. package/strapi-server.js +0 -3
@@ -1,17 +1,17 @@
1
- import { ClockCounterClockwise, CrossCircle, More, WarningCircle, ListPlus, Pencil, Trash, Check, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, Feather } from "@strapi/icons";
1
+ import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check, CrossCircle, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
2
2
  import { jsx, Fragment, jsxs } from "react/jsx-runtime";
3
- import { useStrapiApp, useQueryParams, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useTracking, useForm, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
4
- import { stringify } from "qs";
5
- import { useIntl } from "react-intl";
6
- import { useNavigate, useParams, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
3
+ import { useStrapiApp, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, useQueryParams, getYupValidationErrors, useForm, useTracking, useGuidedTour, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
7
4
  import * as React from "react";
8
5
  import { lazy } from "react";
9
- import { Menu, VisuallyHidden, Flex, Typography, Dialog, DialogBody, DialogFooter, Button, ModalLayout, ModalHeader, ModalBody, Box, Radio, Status, SingleSelect, SingleSelectOption, ModalFooter, Loader, IconButton, Tooltip, LinkButton } from "@strapi/design-system";
10
- import { styled } from "styled-components";
6
+ import { Button, Menu, VisuallyHidden, Flex, Typography, Dialog, Modal, Radio, Status, Box, SingleSelect, SingleSelectOption, IconButton, Loader, Tooltip, LinkButton } from "@strapi/design-system";
7
+ import { useIntl } from "react-intl";
8
+ import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
11
9
  import * as yup from "yup";
12
10
  import { ValidationError } from "yup";
13
11
  import pipe from "lodash/fp/pipe";
14
12
  import { intervalToDuration, isPast } from "date-fns";
13
+ import { styled } from "styled-components";
14
+ import { stringify } from "qs";
15
15
  import { createSlice, combineReducers } from "@reduxjs/toolkit";
16
16
  const __variableDynamicImportRuntimeHelper = (glob, path) => {
17
17
  const v = glob[path];
@@ -49,42 +49,6 @@ const useInjectionZone = (area) => {
49
49
  const [page, position] = area.split(".");
50
50
  return contentManagerPlugin.getInjectedComponents(page, position);
51
51
  };
52
- const HistoryAction = ({ model, document }) => {
53
- const { formatMessage } = useIntl();
54
- const [{ query }] = useQueryParams();
55
- const navigate = useNavigate();
56
- const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
57
- if (!window.strapi.features.isEnabled("cms-content-history")) {
58
- return null;
59
- }
60
- return {
61
- icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
62
- label: formatMessage({
63
- id: "content-manager.history.document-action",
64
- defaultMessage: "Content History"
65
- }),
66
- onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
67
- disabled: (
68
- /**
69
- * The user is creating a new document.
70
- * It hasn't been saved yet, so there's no history to go to
71
- */
72
- !document || /**
73
- * The document has been created but the current dimension has never been saved.
74
- * For example, the user is creating a new locale in an existing document,
75
- * so there's no history for the document in that locale
76
- */
77
- !document.id || /**
78
- * History is only available for content types created by the user.
79
- * These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
80
- * which start with `admin::` or `plugin::`
81
- */
82
- !model.startsWith("api::")
83
- ),
84
- position: "header"
85
- };
86
- };
87
- HistoryAction.type = "history";
88
52
  const ID = "id";
89
53
  const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
90
54
  const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
@@ -194,10 +158,12 @@ const contentManagerApi = adminApi.enhanceEndpoints({
194
158
  "Document",
195
159
  "InitialData",
196
160
  "HistoryVersion",
197
- "Relations"
161
+ "Relations",
162
+ "UidAvailability"
198
163
  ]
199
164
  });
200
165
  const documentApi = contentManagerApi.injectEndpoints({
166
+ overrideExisting: true,
201
167
  endpoints: (builder) => ({
202
168
  autoCloneDocument: builder.mutation({
203
169
  query: ({ model, sourceId, query }) => ({
@@ -207,7 +173,12 @@ const documentApi = contentManagerApi.injectEndpoints({
207
173
  params: query
208
174
  }
209
175
  }),
210
- invalidatesTags: (_result, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
176
+ invalidatesTags: (_result, error, { model }) => {
177
+ if (error) {
178
+ return [];
179
+ }
180
+ return [{ type: "Document", id: `${model}_LIST` }];
181
+ }
211
182
  }),
212
183
  cloneDocument: builder.mutation({
213
184
  query: ({ model, sourceId, data, params }) => ({
@@ -218,7 +189,10 @@ const documentApi = contentManagerApi.injectEndpoints({
218
189
  params
219
190
  }
220
191
  }),
221
- invalidatesTags: (_result, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
192
+ invalidatesTags: (_result, _error, { model }) => [
193
+ { type: "Document", id: `${model}_LIST` },
194
+ { type: "UidAvailability", id: model }
195
+ ]
222
196
  }),
223
197
  /**
224
198
  * Creates a new collection-type document. This should ONLY be used for collection-types.
@@ -235,7 +209,8 @@ const documentApi = contentManagerApi.injectEndpoints({
235
209
  }),
236
210
  invalidatesTags: (result, _error, { model }) => [
237
211
  { type: "Document", id: `${model}_LIST` },
238
- "Relations"
212
+ "Relations",
213
+ { type: "UidAvailability", id: model }
239
214
  ]
240
215
  }),
241
216
  deleteDocument: builder.mutation({
@@ -276,7 +251,8 @@ const documentApi = contentManagerApi.injectEndpoints({
276
251
  id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
277
252
  },
278
253
  { type: "Document", id: `${model}_LIST` },
279
- "Relations"
254
+ "Relations",
255
+ { type: "UidAvailability", id: model }
280
256
  ];
281
257
  }
282
258
  }),
@@ -294,6 +270,7 @@ const documentApi = contentManagerApi.injectEndpoints({
294
270
  }),
295
271
  providesTags: (result, _error, arg) => {
296
272
  return [
273
+ { type: "Document", id: `ALL_LIST` },
297
274
  { type: "Document", id: `${arg.model}_LIST` },
298
275
  ...result?.results.map(({ documentId }) => ({
299
276
  type: "Document",
@@ -332,6 +309,11 @@ const documentApi = contentManagerApi.injectEndpoints({
332
309
  {
333
310
  type: "Document",
334
311
  id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
312
+ },
313
+ // Make it easy to invalidate all individual documents queries for a model
314
+ {
315
+ type: "Document",
316
+ id: `${model}_ALL_ITEMS`
335
317
  }
336
318
  ];
337
319
  }
@@ -395,8 +377,21 @@ const documentApi = contentManagerApi.injectEndpoints({
395
377
  type: "Document",
396
378
  id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
397
379
  },
398
- "Relations"
380
+ "Relations",
381
+ { type: "UidAvailability", id: model }
399
382
  ];
383
+ },
384
+ async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
385
+ const patchResult = dispatch(
386
+ documentApi.util.updateQueryData("getDocument", patch, (draft) => {
387
+ Object.assign(draft.data, data);
388
+ })
389
+ );
390
+ try {
391
+ await queryFulfilled;
392
+ } catch {
393
+ patchResult.undo();
394
+ }
400
395
  }
401
396
  }),
402
397
  unpublishDocument: builder.mutation({
@@ -466,7 +461,7 @@ const buildValidParams = (query) => {
466
461
  const isBaseQueryError = (error) => {
467
462
  return error.name !== void 0;
468
463
  };
469
- const createYupSchema = (attributes = {}, components = {}) => {
464
+ const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
470
465
  const createModelSchema = (attributes2) => yup.object().shape(
471
466
  Object.entries(attributes2).reduce((acc, [name, attribute]) => {
472
467
  if (DOCUMENT_META_FIELDS.includes(name)) {
@@ -479,7 +474,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
479
474
  addMinValidation,
480
475
  addMaxValidation,
481
476
  addRegexValidation
482
- ].map((fn) => fn(attribute));
477
+ ].map((fn) => fn(attribute, options));
483
478
  const transformSchema = pipe(...validations);
484
479
  switch (attribute.type) {
485
480
  case "component": {
@@ -528,7 +523,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
528
523
  } else if (Array.isArray(value)) {
529
524
  return yup.array().of(
530
525
  yup.object().shape({
531
- id: yup.string().required()
526
+ id: yup.number().required()
532
527
  })
533
528
  );
534
529
  } else if (typeof value === "object") {
@@ -580,6 +575,14 @@ const createAttributeSchema = (attribute) => {
580
575
  if (!value || typeof value === "string" && value.length === 0) {
581
576
  return true;
582
577
  }
578
+ if (typeof value === "object") {
579
+ try {
580
+ JSON.stringify(value);
581
+ return true;
582
+ } catch (err) {
583
+ return false;
584
+ }
585
+ }
583
586
  try {
584
587
  JSON.parse(value);
585
588
  return true;
@@ -598,13 +601,7 @@ const createAttributeSchema = (attribute) => {
598
601
  return yup.mixed();
599
602
  }
600
603
  };
601
- const addRequiredValidation = (attribute) => (schema) => {
602
- if (attribute.required) {
603
- return schema.required({
604
- id: translatedErrors.required.id,
605
- defaultMessage: "This field is required."
606
- });
607
- }
604
+ const nullableSchema = (schema) => {
608
605
  return schema?.nullable ? schema.nullable() : (
609
606
  // In some cases '.nullable' will not be available on the schema.
610
607
  // e.g. when the schema has been built using yup.lazy (e.g. for relations).
@@ -612,7 +609,22 @@ const addRequiredValidation = (attribute) => (schema) => {
612
609
  schema
613
610
  );
614
611
  };
615
- const addMinLengthValidation = (attribute) => (schema) => {
612
+ const addRequiredValidation = (attribute, options) => (schema) => {
613
+ if (options.status === "draft") {
614
+ return nullableSchema(schema);
615
+ }
616
+ if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
617
+ return schema.min(1, translatedErrors.required);
618
+ }
619
+ if (attribute.required && attribute.type !== "relation") {
620
+ return schema.required(translatedErrors.required);
621
+ }
622
+ return nullableSchema(schema);
623
+ };
624
+ const addMinLengthValidation = (attribute, options) => (schema) => {
625
+ if (options.status === "draft") {
626
+ return schema;
627
+ }
616
628
  if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
617
629
  return schema.min(attribute.minLength, {
618
630
  ...translatedErrors.minLength,
@@ -634,9 +646,31 @@ const addMaxLengthValidation = (attribute) => (schema) => {
634
646
  }
635
647
  return schema;
636
648
  };
637
- const addMinValidation = (attribute) => (schema) => {
649
+ const addMinValidation = (attribute, options) => (schema) => {
638
650
  if ("min" in attribute) {
639
651
  const min = toInteger(attribute.min);
652
+ if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
653
+ if (options.status !== "draft" && !attribute.required && "test" in schema && min) {
654
+ return schema.test(
655
+ "custom-min",
656
+ {
657
+ ...translatedErrors.min,
658
+ values: {
659
+ min: attribute.min
660
+ }
661
+ },
662
+ (value) => {
663
+ if (!value) {
664
+ return true;
665
+ }
666
+ if (Array.isArray(value) && value.length === 0) {
667
+ return true;
668
+ }
669
+ return value.length >= min;
670
+ }
671
+ );
672
+ }
673
+ }
640
674
  if ("min" in schema && min) {
641
675
  return schema.min(min, {
642
676
  ...translatedErrors.min,
@@ -755,16 +789,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
755
789
  }, {});
756
790
  return componentsByKey;
757
791
  };
758
- const useDocument = (args, opts) => {
792
+ const HOOKS = {
793
+ /**
794
+ * Hook that allows to mutate the displayed headers of the list view table
795
+ * @constant
796
+ * @type {string}
797
+ */
798
+ INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
799
+ /**
800
+ * Hook that allows to mutate the CM's collection types links pre-set filters
801
+ * @constant
802
+ * @type {string}
803
+ */
804
+ MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
805
+ /**
806
+ * Hook that allows to mutate the CM's edit view layout
807
+ * @constant
808
+ * @type {string}
809
+ */
810
+ MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
811
+ /**
812
+ * Hook that allows to mutate the CM's single types links pre-set filters
813
+ * @constant
814
+ * @type {string}
815
+ */
816
+ MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
817
+ };
818
+ const contentTypesApi = contentManagerApi.injectEndpoints({
819
+ endpoints: (builder) => ({
820
+ getContentTypeConfiguration: builder.query({
821
+ query: (uid) => ({
822
+ url: `/content-manager/content-types/${uid}/configuration`,
823
+ method: "GET"
824
+ }),
825
+ transformResponse: (response) => response.data,
826
+ providesTags: (_result, _error, uid) => [
827
+ { type: "ContentTypesConfiguration", id: uid },
828
+ { type: "ContentTypeSettings", id: "LIST" }
829
+ ]
830
+ }),
831
+ getAllContentTypeSettings: builder.query({
832
+ query: () => "/content-manager/content-types-settings",
833
+ transformResponse: (response) => response.data,
834
+ providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
835
+ }),
836
+ updateContentTypeConfiguration: builder.mutation({
837
+ query: ({ uid, ...body }) => ({
838
+ url: `/content-manager/content-types/${uid}/configuration`,
839
+ method: "PUT",
840
+ data: body
841
+ }),
842
+ transformResponse: (response) => response.data,
843
+ invalidatesTags: (_result, _error, { uid }) => [
844
+ { type: "ContentTypesConfiguration", id: uid },
845
+ { type: "ContentTypeSettings", id: "LIST" },
846
+ // Is this necessary?
847
+ { type: "InitialData" }
848
+ ]
849
+ })
850
+ })
851
+ });
852
+ const {
853
+ useGetContentTypeConfigurationQuery,
854
+ useGetAllContentTypeSettingsQuery,
855
+ useUpdateContentTypeConfigurationMutation
856
+ } = contentTypesApi;
857
+ const checkIfAttributeIsDisplayable = (attribute) => {
858
+ const { type } = attribute;
859
+ if (type === "relation") {
860
+ return !attribute.relation.toLowerCase().includes("morph");
861
+ }
862
+ return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
863
+ };
864
+ const getMainField = (attribute, mainFieldName, { schemas, components }) => {
865
+ if (!mainFieldName) {
866
+ return void 0;
867
+ }
868
+ const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
869
+ // @ts-expect-error – `targetModel` does exist on the attribute for a relation.
870
+ schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
871
+ );
872
+ return {
873
+ name: mainFieldName,
874
+ type: mainFieldType ?? "string"
875
+ };
876
+ };
877
+ const DEFAULT_SETTINGS = {
878
+ bulkable: false,
879
+ filterable: false,
880
+ searchable: false,
881
+ pagination: false,
882
+ defaultSortBy: "",
883
+ defaultSortOrder: "asc",
884
+ mainField: "id",
885
+ pageSize: 10
886
+ };
887
+ const useDocumentLayout = (model) => {
888
+ const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
889
+ const [{ query }] = useQueryParams();
890
+ const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
759
891
  const { toggleNotification } = useNotification();
760
892
  const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
893
+ const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
761
894
  const {
762
- currentData: data,
763
- isLoading: isLoadingDocument,
764
- isFetching: isFetchingDocument,
765
- error
766
- } = useGetDocumentQuery(args, opts);
767
- const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
895
+ data,
896
+ isLoading: isLoadingConfigs,
897
+ error,
898
+ isFetching: isFetchingConfigs
899
+ } = useGetContentTypeConfigurationQuery(model);
900
+ const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
768
901
  React.useEffect(() => {
769
902
  if (error) {
770
903
  toggleNotification({
@@ -772,56 +905,271 @@ const useDocument = (args, opts) => {
772
905
  message: formatAPIError(error)
773
906
  });
774
907
  }
775
- }, [toggleNotification, error, formatAPIError, args.collectionType]);
776
- const validationSchema = React.useMemo(() => {
777
- if (!schema) {
778
- return null;
779
- }
780
- return createYupSchema(schema.attributes, components);
781
- }, [schema, components]);
782
- const validate = React.useCallback(
783
- (document) => {
784
- if (!validationSchema) {
785
- throw new Error(
786
- "There is no validation schema generated, this is likely due to the schema not being loaded yet."
787
- );
788
- }
789
- try {
790
- validationSchema.validateSync(document, { abortEarly: false, strict: true });
791
- return null;
792
- } catch (error2) {
793
- if (error2 instanceof ValidationError) {
794
- return getYupValidationErrors(error2);
795
- }
796
- throw error2;
797
- }
908
+ }, [error, formatAPIError, toggleNotification]);
909
+ const editLayout = React.useMemo(
910
+ () => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
911
+ layout: [],
912
+ components: {},
913
+ metadatas: {},
914
+ options: {},
915
+ settings: DEFAULT_SETTINGS
798
916
  },
799
- [validationSchema]
917
+ [data, isLoading, schemas, schema, components]
918
+ );
919
+ const listLayout = React.useMemo(() => {
920
+ return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
921
+ layout: [],
922
+ metadatas: {},
923
+ options: {},
924
+ settings: DEFAULT_SETTINGS
925
+ };
926
+ }, [data, isLoading, schemas, schema, components]);
927
+ const { layout: edit } = React.useMemo(
928
+ () => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
929
+ layout: editLayout,
930
+ query
931
+ }),
932
+ [editLayout, query, runHookWaterfall]
800
933
  );
801
- const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
802
934
  return {
803
- components,
804
- document: data?.data,
805
- meta: data?.meta,
935
+ error,
806
936
  isLoading,
807
- schema,
808
- validate
937
+ edit,
938
+ list: listLayout
809
939
  };
810
940
  };
811
- const useDoc = () => {
812
- const { id, slug, collectionType, origin } = useParams();
813
- const [{ query }] = useQueryParams();
814
- const params = React.useMemo(() => buildValidParams(query), [query]);
815
- if (!collectionType) {
816
- throw new Error("Could not find collectionType in url params");
817
- }
818
- if (!slug) {
819
- throw new Error("Could not find model in url params");
820
- }
821
- return {
822
- collectionType,
823
- model: slug,
824
- id: origin || id === "create" ? void 0 : id,
941
+ const useDocLayout = () => {
942
+ const { model } = useDoc();
943
+ return useDocumentLayout(model);
944
+ };
945
+ const formatEditLayout = (data, {
946
+ schemas,
947
+ schema,
948
+ components
949
+ }) => {
950
+ let currentPanelIndex = 0;
951
+ const panelledEditAttributes = convertEditLayoutToFieldLayouts(
952
+ data.contentType.layouts.edit,
953
+ schema?.attributes,
954
+ data.contentType.metadatas,
955
+ { configurations: data.components, schemas: components },
956
+ schemas
957
+ ).reduce((panels, row) => {
958
+ if (row.some((field) => field.type === "dynamiczone")) {
959
+ panels.push([row]);
960
+ currentPanelIndex += 2;
961
+ } else {
962
+ if (!panels[currentPanelIndex]) {
963
+ panels.push([]);
964
+ }
965
+ panels[currentPanelIndex].push(row);
966
+ }
967
+ return panels;
968
+ }, []);
969
+ const componentEditAttributes = Object.entries(data.components).reduce(
970
+ (acc, [uid, configuration]) => {
971
+ acc[uid] = {
972
+ layout: convertEditLayoutToFieldLayouts(
973
+ configuration.layouts.edit,
974
+ components[uid].attributes,
975
+ configuration.metadatas,
976
+ { configurations: data.components, schemas: components }
977
+ ),
978
+ settings: {
979
+ ...configuration.settings,
980
+ icon: components[uid].info.icon,
981
+ displayName: components[uid].info.displayName
982
+ }
983
+ };
984
+ return acc;
985
+ },
986
+ {}
987
+ );
988
+ const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
989
+ (acc, [attribute, metadata]) => {
990
+ return {
991
+ ...acc,
992
+ [attribute]: metadata.edit
993
+ };
994
+ },
995
+ {}
996
+ );
997
+ return {
998
+ layout: panelledEditAttributes,
999
+ components: componentEditAttributes,
1000
+ metadatas: editMetadatas,
1001
+ settings: {
1002
+ ...data.contentType.settings,
1003
+ displayName: schema?.info.displayName
1004
+ },
1005
+ options: {
1006
+ ...schema?.options,
1007
+ ...schema?.pluginOptions,
1008
+ ...data.contentType.options
1009
+ }
1010
+ };
1011
+ };
1012
+ const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
1013
+ return rows.map(
1014
+ (row) => row.map((field) => {
1015
+ const attribute = attributes[field.name];
1016
+ if (!attribute) {
1017
+ return null;
1018
+ }
1019
+ const { edit: metadata } = metadatas[field.name];
1020
+ const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
1021
+ return {
1022
+ attribute,
1023
+ disabled: !metadata.editable,
1024
+ hint: metadata.description,
1025
+ label: metadata.label ?? "",
1026
+ name: field.name,
1027
+ // @ts-expect-error – mainField does exist on the metadata for a relation.
1028
+ mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
1029
+ schemas,
1030
+ components: components?.schemas ?? {}
1031
+ }),
1032
+ placeholder: metadata.placeholder ?? "",
1033
+ required: attribute.required ?? false,
1034
+ size: field.size,
1035
+ unique: "unique" in attribute ? attribute.unique : false,
1036
+ visible: metadata.visible ?? true,
1037
+ type: attribute.type
1038
+ };
1039
+ }).filter((field) => field !== null)
1040
+ );
1041
+ };
1042
+ const formatListLayout = (data, {
1043
+ schemas,
1044
+ schema,
1045
+ components
1046
+ }) => {
1047
+ const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
1048
+ (acc, [attribute, metadata]) => {
1049
+ return {
1050
+ ...acc,
1051
+ [attribute]: metadata.list
1052
+ };
1053
+ },
1054
+ {}
1055
+ );
1056
+ const listAttributes = convertListLayoutToFieldLayouts(
1057
+ data.contentType.layouts.list,
1058
+ schema?.attributes,
1059
+ listMetadatas,
1060
+ { configurations: data.components, schemas: components },
1061
+ schemas
1062
+ );
1063
+ return {
1064
+ layout: listAttributes,
1065
+ settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
1066
+ metadatas: listMetadatas,
1067
+ options: {
1068
+ ...schema?.options,
1069
+ ...schema?.pluginOptions,
1070
+ ...data.contentType.options
1071
+ }
1072
+ };
1073
+ };
1074
+ const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
1075
+ return columns.map((name) => {
1076
+ const attribute = attributes[name];
1077
+ if (!attribute) {
1078
+ return null;
1079
+ }
1080
+ const metadata = metadatas[name];
1081
+ const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
1082
+ return {
1083
+ attribute,
1084
+ label: metadata.label ?? "",
1085
+ mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
1086
+ schemas,
1087
+ components: components?.schemas ?? {}
1088
+ }),
1089
+ name,
1090
+ searchable: metadata.searchable ?? true,
1091
+ sortable: metadata.sortable ?? true
1092
+ };
1093
+ }).filter((field) => field !== null);
1094
+ };
1095
+ const useDocument = (args, opts) => {
1096
+ const { toggleNotification } = useNotification();
1097
+ const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
1098
+ const {
1099
+ currentData: data,
1100
+ isLoading: isLoadingDocument,
1101
+ isFetching: isFetchingDocument,
1102
+ error
1103
+ } = useGetDocumentQuery(args, {
1104
+ ...opts,
1105
+ skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
1106
+ });
1107
+ const {
1108
+ components,
1109
+ schema,
1110
+ schemas,
1111
+ isLoading: isLoadingSchema
1112
+ } = useContentTypeSchema(args.model);
1113
+ React.useEffect(() => {
1114
+ if (error) {
1115
+ toggleNotification({
1116
+ type: "danger",
1117
+ message: formatAPIError(error)
1118
+ });
1119
+ }
1120
+ }, [toggleNotification, error, formatAPIError, args.collectionType]);
1121
+ const validationSchema = React.useMemo(() => {
1122
+ if (!schema) {
1123
+ return null;
1124
+ }
1125
+ return createYupSchema(schema.attributes, components);
1126
+ }, [schema, components]);
1127
+ const validate = React.useCallback(
1128
+ (document) => {
1129
+ if (!validationSchema) {
1130
+ throw new Error(
1131
+ "There is no validation schema generated, this is likely due to the schema not being loaded yet."
1132
+ );
1133
+ }
1134
+ try {
1135
+ validationSchema.validateSync(document, { abortEarly: false, strict: true });
1136
+ return null;
1137
+ } catch (error2) {
1138
+ if (error2 instanceof ValidationError) {
1139
+ return getYupValidationErrors(error2);
1140
+ }
1141
+ throw error2;
1142
+ }
1143
+ },
1144
+ [validationSchema]
1145
+ );
1146
+ const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
1147
+ const hasError = !!error;
1148
+ return {
1149
+ components,
1150
+ document: data?.data,
1151
+ meta: data?.meta,
1152
+ isLoading,
1153
+ hasError,
1154
+ schema,
1155
+ schemas,
1156
+ validate
1157
+ };
1158
+ };
1159
+ const useDoc = () => {
1160
+ const { id, slug, collectionType, origin } = useParams();
1161
+ const [{ query }] = useQueryParams();
1162
+ const params = React.useMemo(() => buildValidParams(query), [query]);
1163
+ if (!collectionType) {
1164
+ throw new Error("Could not find collectionType in url params");
1165
+ }
1166
+ if (!slug) {
1167
+ throw new Error("Could not find model in url params");
1168
+ }
1169
+ return {
1170
+ collectionType,
1171
+ model: slug,
1172
+ id: origin || id === "create" ? void 0 : id,
825
1173
  ...useDocument(
826
1174
  { documentId: origin || id, model: slug, collectionType, params },
827
1175
  {
@@ -830,6 +1178,45 @@ const useDoc = () => {
830
1178
  )
831
1179
  };
832
1180
  };
1181
+ const useContentManagerContext = () => {
1182
+ const {
1183
+ collectionType,
1184
+ model,
1185
+ id,
1186
+ components,
1187
+ isLoading: isLoadingDoc,
1188
+ schema,
1189
+ schemas
1190
+ } = useDoc();
1191
+ const layout = useDocumentLayout(model);
1192
+ const form = useForm("useContentManagerContext", (state) => state);
1193
+ const isSingleType = collectionType === SINGLE_TYPES;
1194
+ const slug = model;
1195
+ const isCreatingEntry = id === "create";
1196
+ useContentTypeSchema();
1197
+ const isLoading = isLoadingDoc || layout.isLoading;
1198
+ const error = layout.error;
1199
+ return {
1200
+ error,
1201
+ isLoading,
1202
+ // Base metadata
1203
+ model,
1204
+ collectionType,
1205
+ id,
1206
+ slug,
1207
+ isCreatingEntry,
1208
+ isSingleType,
1209
+ hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
1210
+ // All schema infos
1211
+ components,
1212
+ contentType: schema,
1213
+ contentTypes: schemas,
1214
+ // Form state
1215
+ form,
1216
+ // layout infos
1217
+ layout
1218
+ };
1219
+ };
833
1220
  const prefixPluginTranslations = (trad, pluginId) => {
834
1221
  if (!pluginId) {
835
1222
  throw new TypeError("pluginId can't be empty");
@@ -849,6 +1236,8 @@ const useDocumentActions = () => {
849
1236
  const { formatMessage } = useIntl();
850
1237
  const { trackUsage } = useTracking();
851
1238
  const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
1239
+ const navigate = useNavigate();
1240
+ const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
852
1241
  const [deleteDocument] = useDeleteDocumentMutation();
853
1242
  const _delete = React.useCallback(
854
1243
  async ({ collectionType, model, documentId, params }, trackerProperty) => {
@@ -1163,6 +1552,7 @@ const useDocumentActions = () => {
1163
1552
  defaultMessage: "Saved document"
1164
1553
  })
1165
1554
  });
1555
+ setCurrentStep("contentManager.success");
1166
1556
  return res.data;
1167
1557
  } catch (err) {
1168
1558
  toggleNotification({
@@ -1184,7 +1574,6 @@ const useDocumentActions = () => {
1184
1574
  sourceId
1185
1575
  });
1186
1576
  if ("error" in res) {
1187
- toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1188
1577
  return { error: res.error };
1189
1578
  }
1190
1579
  toggleNotification({
@@ -1203,7 +1592,7 @@ const useDocumentActions = () => {
1203
1592
  throw err;
1204
1593
  }
1205
1594
  },
1206
- [autoCloneDocument, formatAPIError, formatMessage, toggleNotification]
1595
+ [autoCloneDocument, formatMessage, toggleNotification]
1207
1596
  );
1208
1597
  const [cloneDocument] = useCloneDocumentMutation();
1209
1598
  const clone = React.useCallback(
@@ -1229,6 +1618,7 @@ const useDocumentActions = () => {
1229
1618
  defaultMessage: "Cloned document"
1230
1619
  })
1231
1620
  });
1621
+ navigate(`../../${res.data.data.documentId}`, { relative: "path" });
1232
1622
  return res.data;
1233
1623
  } catch (err) {
1234
1624
  toggleNotification({
@@ -1239,7 +1629,7 @@ const useDocumentActions = () => {
1239
1629
  throw err;
1240
1630
  }
1241
1631
  },
1242
- [cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
1632
+ [cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
1243
1633
  );
1244
1634
  const [getDoc] = useLazyGetDocumentQuery();
1245
1635
  const getDocument = React.useCallback(
@@ -1265,7 +1655,7 @@ const useDocumentActions = () => {
1265
1655
  };
1266
1656
  };
1267
1657
  const ProtectedHistoryPage = lazy(
1268
- () => import("./History-DS6-HCYX.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1658
+ () => import("./History-2Ah2CQ4T.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1269
1659
  );
1270
1660
  const routes$1 = [
1271
1661
  {
@@ -1278,31 +1668,31 @@ const routes$1 = [
1278
1668
  }
1279
1669
  ];
1280
1670
  const ProtectedEditViewPage = lazy(
1281
- () => import("./EditViewPage-DWb0DE7R.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1671
+ () => import("./EditViewPage-Dzpno8xI.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1282
1672
  );
1283
1673
  const ProtectedListViewPage = lazy(
1284
- () => import("./ListViewPage-nQrOQuVo.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1674
+ () => import("./ListViewPage-B75x3nz2.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1285
1675
  );
1286
1676
  const ProtectedListConfiguration = lazy(
1287
- () => import("./ListConfigurationPage-DQJJltko.mjs").then((mod) => ({
1677
+ () => import("./ListConfigurationPage-BjSJlaoC.mjs").then((mod) => ({
1288
1678
  default: mod.ProtectedListConfiguration
1289
1679
  }))
1290
1680
  );
1291
1681
  const ProtectedEditConfigurationPage = lazy(
1292
- () => import("./EditConfigurationPage-CcOoD26O.mjs").then((mod) => ({
1682
+ () => import("./EditConfigurationPage-CI4XoymK.mjs").then((mod) => ({
1293
1683
  default: mod.ProtectedEditConfigurationPage
1294
1684
  }))
1295
1685
  );
1296
1686
  const ProtectedComponentConfigurationPage = lazy(
1297
- () => import("./ComponentConfigurationPage-BMajAl1u.mjs").then((mod) => ({
1687
+ () => import("./ComponentConfigurationPage-7-qB29e7.mjs").then((mod) => ({
1298
1688
  default: mod.ProtectedComponentConfigurationPage
1299
1689
  }))
1300
1690
  );
1301
1691
  const NoPermissions = lazy(
1302
- () => import("./NoPermissionsPage-fOIkQM0v.mjs").then((mod) => ({ default: mod.NoPermissions }))
1692
+ () => import("./NoPermissionsPage-SFllMekk.mjs").then((mod) => ({ default: mod.NoPermissions }))
1303
1693
  );
1304
1694
  const NoContentType = lazy(
1305
- () => import("./NoContentTypePage-DbnHE22g.mjs").then((mod) => ({ default: mod.NoContentType }))
1695
+ () => import("./NoContentTypePage-DUacQSyF.mjs").then((mod) => ({ default: mod.NoContentType }))
1306
1696
  );
1307
1697
  const CollectionTypePages = () => {
1308
1698
  const { collectionType } = useParams();
@@ -1416,12 +1806,14 @@ const DocumentActionButton = (action) => {
1416
1806
  /* @__PURE__ */ jsx(
1417
1807
  Button,
1418
1808
  {
1419
- flex: 1,
1809
+ flex: "auto",
1420
1810
  startIcon: action.icon,
1421
1811
  disabled: action.disabled,
1422
1812
  onClick: handleClick(action),
1423
1813
  justifyContent: "center",
1424
1814
  variant: action.variant || "default",
1815
+ paddingTop: "7px",
1816
+ paddingBottom: "7px",
1425
1817
  children: action.label
1426
1818
  }
1427
1819
  ),
@@ -1429,7 +1821,7 @@ const DocumentActionButton = (action) => {
1429
1821
  DocumentActionConfirmDialog,
1430
1822
  {
1431
1823
  ...action.dialog,
1432
- variant: action.variant,
1824
+ variant: action.dialog?.variant ?? action.variant,
1433
1825
  isOpen: dialogId === action.id,
1434
1826
  onClose: handleClose
1435
1827
  }
@@ -1486,9 +1878,9 @@ const DocumentActionsMenu = ({
1486
1878
  disabled: isDisabled,
1487
1879
  size: "S",
1488
1880
  endIcon: null,
1489
- paddingTop: "7px",
1490
- paddingLeft: "9px",
1491
- paddingRight: "9px",
1881
+ paddingTop: "4px",
1882
+ paddingLeft: "7px",
1883
+ paddingRight: "7px",
1492
1884
  variant,
1493
1885
  children: [
1494
1886
  /* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
@@ -1499,7 +1891,7 @@ const DocumentActionsMenu = ({
1499
1891
  ]
1500
1892
  }
1501
1893
  ),
1502
- /* @__PURE__ */ jsxs(Menu.Content, { top: "4px", maxHeight: void 0, popoverPlacement: "bottom-end", children: [
1894
+ /* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
1503
1895
  actions2.map((action) => {
1504
1896
  return /* @__PURE__ */ jsx(
1505
1897
  Menu.Item,
@@ -1508,10 +1900,25 @@ const DocumentActionsMenu = ({
1508
1900
  onSelect: handleClick(action),
1509
1901
  display: "block",
1510
1902
  children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
1511
- /* @__PURE__ */ jsxs(Flex, { color: convertActionVariantToColor(action.variant), gap: 2, tag: "span", children: [
1512
- action.icon,
1513
- action.label
1514
- ] }),
1903
+ /* @__PURE__ */ jsxs(
1904
+ Flex,
1905
+ {
1906
+ color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
1907
+ gap: 2,
1908
+ tag: "span",
1909
+ children: [
1910
+ /* @__PURE__ */ jsx(
1911
+ Flex,
1912
+ {
1913
+ tag: "span",
1914
+ color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
1915
+ children: action.icon
1916
+ }
1917
+ ),
1918
+ action.label
1919
+ ]
1920
+ }
1921
+ ),
1515
1922
  action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
1516
1923
  Flex,
1517
1924
  {
@@ -1570,6 +1977,18 @@ const convertActionVariantToColor = (variant = "secondary") => {
1570
1977
  return "primary600";
1571
1978
  }
1572
1979
  };
1980
+ const convertActionVariantToIconColor = (variant = "secondary") => {
1981
+ switch (variant) {
1982
+ case "danger":
1983
+ return "danger600";
1984
+ case "secondary":
1985
+ return "neutral500";
1986
+ case "success":
1987
+ return "success600";
1988
+ default:
1989
+ return "primary600";
1990
+ }
1991
+ };
1573
1992
  const DocumentActionConfirmDialog = ({
1574
1993
  onClose,
1575
1994
  onCancel,
@@ -1592,22 +2011,20 @@ const DocumentActionConfirmDialog = ({
1592
2011
  }
1593
2012
  onClose();
1594
2013
  };
1595
- return /* @__PURE__ */ jsxs(Dialog, { isOpen, title, onClose: handleClose, children: [
1596
- /* @__PURE__ */ jsx(DialogBody, { children: content }),
1597
- /* @__PURE__ */ jsx(
1598
- DialogFooter,
1599
- {
1600
- startAction: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", children: formatMessage({
1601
- id: "app.components.Button.cancel",
1602
- defaultMessage: "Cancel"
1603
- }) }),
1604
- endAction: /* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
1605
- id: "app.components.Button.confirm",
1606
- defaultMessage: "Confirm"
1607
- }) })
1608
- }
1609
- )
1610
- ] });
2014
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
2015
+ /* @__PURE__ */ jsx(Dialog.Header, { children: title }),
2016
+ /* @__PURE__ */ jsx(Dialog.Body, { children: content }),
2017
+ /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
2018
+ /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
2019
+ id: "app.components.Button.cancel",
2020
+ defaultMessage: "Cancel"
2021
+ }) }) }),
2022
+ /* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
2023
+ id: "app.components.Button.confirm",
2024
+ defaultMessage: "Confirm"
2025
+ }) })
2026
+ ] })
2027
+ ] }) });
1611
2028
  };
1612
2029
  const DocumentActionModal = ({
1613
2030
  isOpen,
@@ -1617,34 +2034,17 @@ const DocumentActionModal = ({
1617
2034
  content: Content,
1618
2035
  onModalClose
1619
2036
  }) => {
1620
- const id = React.useId();
1621
- if (!isOpen) {
1622
- return null;
1623
- }
1624
2037
  const handleClose = () => {
1625
2038
  if (onClose) {
1626
2039
  onClose();
1627
2040
  }
1628
2041
  onModalClose();
1629
2042
  };
1630
- return /* @__PURE__ */ jsxs(ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
1631
- /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
1632
- /* @__PURE__ */ jsx(ModalBody, { children: typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content }),
1633
- /* @__PURE__ */ jsx(
1634
- Box,
1635
- {
1636
- paddingTop: 4,
1637
- paddingBottom: 4,
1638
- paddingLeft: 5,
1639
- paddingRight: 5,
1640
- borderWidth: "1px 0 0 0",
1641
- borderStyle: "solid",
1642
- borderColor: "neutral150",
1643
- background: "neutral100",
1644
- children: typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
1645
- }
1646
- )
1647
- ] });
2043
+ return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
2044
+ /* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
2045
+ typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
2046
+ typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
2047
+ ] }) });
1648
2048
  };
1649
2049
  const PublishAction$1 = ({
1650
2050
  activeTab,
@@ -1658,13 +2058,17 @@ const PublishAction$1 = ({
1658
2058
  const navigate = useNavigate();
1659
2059
  const { toggleNotification } = useNotification();
1660
2060
  const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
2061
+ const isListView = useMatch(LIST_PATH) !== null;
1661
2062
  const isCloning = useMatch(CLONE_PATH) !== null;
1662
2063
  const { formatMessage } = useIntl();
1663
- const { canPublish, canCreate, canUpdate } = useDocumentRBAC(
1664
- "PublishAction",
1665
- ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
1666
- );
2064
+ const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
1667
2065
  const { publish } = useDocumentActions();
2066
+ const [
2067
+ countDraftRelations,
2068
+ { isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
2069
+ ] = useLazyGetDraftRelationCountQuery();
2070
+ const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
2071
+ const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
1668
2072
  const [{ query, rawQuery }] = useQueryParams();
1669
2073
  const params = React.useMemo(() => buildValidParams(query), [query]);
1670
2074
  const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
@@ -1673,10 +2077,103 @@ const PublishAction$1 = ({
1673
2077
  const validate = useForm("PublishAction", (state) => state.validate);
1674
2078
  const setErrors = useForm("PublishAction", (state) => state.setErrors);
1675
2079
  const formValues = useForm("PublishAction", ({ values }) => values);
2080
+ React.useEffect(() => {
2081
+ if (isErrorDraftRelations) {
2082
+ toggleNotification({
2083
+ type: "danger",
2084
+ message: formatMessage({
2085
+ id: getTranslation("error.records.fetch-draft-relatons"),
2086
+ defaultMessage: "An error occurred while fetching draft relations on this document."
2087
+ })
2088
+ });
2089
+ }
2090
+ }, [isErrorDraftRelations, toggleNotification, formatMessage]);
2091
+ React.useEffect(() => {
2092
+ const localDraftRelations = /* @__PURE__ */ new Set();
2093
+ const extractDraftRelations = (data) => {
2094
+ const relations = data.connect || [];
2095
+ relations.forEach((relation) => {
2096
+ if (relation.status === "draft") {
2097
+ localDraftRelations.add(relation.id);
2098
+ }
2099
+ });
2100
+ };
2101
+ const traverseAndExtract = (data) => {
2102
+ Object.entries(data).forEach(([key, value]) => {
2103
+ if (key === "connect" && Array.isArray(value)) {
2104
+ extractDraftRelations({ connect: value });
2105
+ } else if (typeof value === "object" && value !== null) {
2106
+ traverseAndExtract(value);
2107
+ }
2108
+ });
2109
+ };
2110
+ if (!documentId || modified) {
2111
+ traverseAndExtract(formValues);
2112
+ setLocalCountOfDraftRelations(localDraftRelations.size);
2113
+ }
2114
+ }, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
2115
+ React.useEffect(() => {
2116
+ if (!document || !document.documentId || isListView) {
2117
+ return;
2118
+ }
2119
+ const fetchDraftRelationsCount = async () => {
2120
+ const { data, error } = await countDraftRelations({
2121
+ collectionType,
2122
+ model,
2123
+ documentId,
2124
+ params
2125
+ });
2126
+ if (error) {
2127
+ throw error;
2128
+ }
2129
+ if (data) {
2130
+ setServerCountOfDraftRelations(data.data);
2131
+ }
2132
+ };
2133
+ fetchDraftRelationsCount();
2134
+ }, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
1676
2135
  const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
1677
2136
  if (!schema?.options?.draftAndPublish) {
1678
2137
  return null;
1679
2138
  }
2139
+ const performPublish = async () => {
2140
+ setSubmitting(true);
2141
+ try {
2142
+ const { errors } = await validate();
2143
+ if (errors) {
2144
+ toggleNotification({
2145
+ type: "danger",
2146
+ message: formatMessage({
2147
+ id: "content-manager.validation.error",
2148
+ defaultMessage: "There are validation errors in your document. Please fix them before saving."
2149
+ })
2150
+ });
2151
+ return;
2152
+ }
2153
+ const res = await publish(
2154
+ {
2155
+ collectionType,
2156
+ model,
2157
+ documentId,
2158
+ params
2159
+ },
2160
+ formValues
2161
+ );
2162
+ if ("data" in res && collectionType !== SINGLE_TYPES) {
2163
+ navigate({
2164
+ pathname: `../${collectionType}/${model}/${res.data.documentId}`,
2165
+ search: rawQuery
2166
+ });
2167
+ } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2168
+ setErrors(formatValidationErrors(res.error));
2169
+ }
2170
+ } finally {
2171
+ setSubmitting(false);
2172
+ }
2173
+ };
2174
+ const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
2175
+ const enableDraftRelationsCount = false;
2176
+ const hasDraftRelations = enableDraftRelationsCount;
1680
2177
  return {
1681
2178
  /**
1682
2179
  * Disabled when:
@@ -1686,49 +2183,36 @@ const PublishAction$1 = ({
1686
2183
  * - the document is already published & not modified
1687
2184
  * - the document is being created & not modified
1688
2185
  * - the user doesn't have the permission to publish
1689
- * - the user doesn't have the permission to create a new document
1690
- * - the user doesn't have the permission to update the document
1691
2186
  */
1692
- disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
2187
+ disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
1693
2188
  label: formatMessage({
1694
2189
  id: "app.utils.publish",
1695
2190
  defaultMessage: "Publish"
1696
2191
  }),
1697
2192
  onClick: async () => {
1698
- setSubmitting(true);
1699
- try {
1700
- const { errors } = await validate();
1701
- if (errors) {
1702
- toggleNotification({
1703
- type: "danger",
1704
- message: formatMessage({
1705
- id: "content-manager.validation.error",
1706
- defaultMessage: "There are validation errors in your document. Please fix them before saving."
1707
- })
1708
- });
1709
- return;
1710
- }
1711
- const res = await publish(
1712
- {
1713
- collectionType,
1714
- model,
1715
- documentId,
1716
- params
1717
- },
1718
- formValues
1719
- );
1720
- if ("data" in res && collectionType !== SINGLE_TYPES) {
1721
- navigate({
1722
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1723
- search: rawQuery
1724
- });
1725
- } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1726
- setErrors(formatValidationErrors(res.error));
2193
+ await performPublish();
2194
+ },
2195
+ dialog: hasDraftRelations ? {
2196
+ type: "dialog",
2197
+ variant: "danger",
2198
+ footer: null,
2199
+ title: formatMessage({
2200
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
2201
+ defaultMessage: "Confirmation"
2202
+ }),
2203
+ content: formatMessage(
2204
+ {
2205
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
2206
+ defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
2207
+ },
2208
+ {
2209
+ count: totalDraftRelations
1727
2210
  }
1728
- } finally {
1729
- setSubmitting(false);
2211
+ ),
2212
+ onConfirm: async () => {
2213
+ await performPublish();
1730
2214
  }
1731
- }
2215
+ } : void 0
1732
2216
  };
1733
2217
  };
1734
2218
  PublishAction$1.type = "publish";
@@ -1744,10 +2228,6 @@ const UpdateAction = ({
1744
2228
  const cloneMatch = useMatch(CLONE_PATH);
1745
2229
  const isCloning = cloneMatch !== null;
1746
2230
  const { formatMessage } = useIntl();
1747
- const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
1748
- canCreate: canCreate2,
1749
- canUpdate: canUpdate2
1750
- }));
1751
2231
  const { create, update, clone } = useDocumentActions();
1752
2232
  const [{ query, rawQuery }] = useQueryParams();
1753
2233
  const params = React.useMemo(() => buildValidParams(query), [query]);
@@ -1764,10 +2244,8 @@ const UpdateAction = ({
1764
2244
  * - the form is submitting
1765
2245
  * - the document is not modified & we're not cloning (you can save a clone entity straight away)
1766
2246
  * - the active tab is the published tab
1767
- * - the user doesn't have the permission to create a new document
1768
- * - the user doesn't have the permission to update the document
1769
2247
  */
1770
- disabled: isSubmitting || !modified && !isCloning || activeTab === "published" || Boolean(!documentId && !canCreate || documentId && !canUpdate),
2248
+ disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
1771
2249
  label: formatMessage({
1772
2250
  id: "content-manager.containers.Edit.save",
1773
2251
  defaultMessage: "Save"
@@ -1775,16 +2253,18 @@ const UpdateAction = ({
1775
2253
  onClick: async () => {
1776
2254
  setSubmitting(true);
1777
2255
  try {
1778
- const { errors } = await validate();
1779
- if (errors) {
1780
- toggleNotification({
1781
- type: "danger",
1782
- message: formatMessage({
1783
- id: "content-manager.validation.error",
1784
- defaultMessage: "There are validation errors in your document. Please fix them before saving."
1785
- })
1786
- });
1787
- return;
2256
+ if (activeTab !== "draft") {
2257
+ const { errors } = await validate();
2258
+ if (errors) {
2259
+ toggleNotification({
2260
+ type: "danger",
2261
+ message: formatMessage({
2262
+ id: "content-manager.validation.error",
2263
+ defaultMessage: "There are validation errors in your document. Please fix them before saving."
2264
+ })
2265
+ });
2266
+ return;
2267
+ }
1788
2268
  }
1789
2269
  if (isCloning) {
1790
2270
  const res = await clone(
@@ -1796,10 +2276,13 @@ const UpdateAction = ({
1796
2276
  document
1797
2277
  );
1798
2278
  if ("data" in res) {
1799
- navigate({
1800
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1801
- search: rawQuery
1802
- });
2279
+ navigate(
2280
+ {
2281
+ pathname: `../${res.data.documentId}`,
2282
+ search: rawQuery
2283
+ },
2284
+ { relative: "path" }
2285
+ );
1803
2286
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1804
2287
  setErrors(formatValidationErrors(res.error));
1805
2288
  }
@@ -1827,10 +2310,13 @@ const UpdateAction = ({
1827
2310
  document
1828
2311
  );
1829
2312
  if ("data" in res && collectionType !== SINGLE_TYPES) {
1830
- navigate({
1831
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1832
- search: rawQuery
1833
- });
2313
+ navigate(
2314
+ {
2315
+ pathname: `../${res.data.documentId}`,
2316
+ search: rawQuery
2317
+ },
2318
+ { replace: true, relative: "path" }
2319
+ );
1834
2320
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1835
2321
  setErrors(formatValidationErrors(res.error));
1836
2322
  }
@@ -1862,10 +2348,8 @@ const UnpublishAction$1 = ({
1862
2348
  const { toggleNotification } = useNotification();
1863
2349
  const [shouldKeepDraft, setShouldKeepDraft] = React.useState(true);
1864
2350
  const isDocumentModified = document?.status === "modified";
1865
- const handleChange = (e) => {
1866
- if ("value" in e.target) {
1867
- setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
1868
- }
2351
+ const handleChange = (value) => {
2352
+ setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
1869
2353
  };
1870
2354
  if (!schema?.options?.draftAndPublish) {
1871
2355
  return null;
@@ -1876,7 +2360,7 @@ const UnpublishAction$1 = ({
1876
2360
  id: "app.utils.unpublish",
1877
2361
  defaultMessage: "Unpublish"
1878
2362
  }),
1879
- icon: /* @__PURE__ */ jsx(StyledCrossCircle, {}),
2363
+ icon: /* @__PURE__ */ jsx(Cross, {}),
1880
2364
  onClick: async () => {
1881
2365
  if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
1882
2366
  if (!documentId) {
@@ -1915,40 +2399,24 @@ const UnpublishAction$1 = ({
1915
2399
  }) })
1916
2400
  ] }),
1917
2401
  /* @__PURE__ */ jsxs(
1918
- Flex,
2402
+ Radio.Group,
1919
2403
  {
1920
- onChange: handleChange,
1921
- direction: "column",
1922
- alignItems: "flex-start",
1923
- tag: "fieldset",
1924
- borderWidth: 0,
1925
- gap: 3,
2404
+ defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
2405
+ name: "discard-options",
2406
+ "aria-label": formatMessage({
2407
+ id: "content-manager.actions.unpublish.dialog.radio-label",
2408
+ defaultMessage: "Choose an option to unpublish the document."
2409
+ }),
2410
+ onValueChange: handleChange,
1926
2411
  children: [
1927
- /* @__PURE__ */ jsx(VisuallyHidden, { tag: "legend" }),
1928
- /* @__PURE__ */ jsx(
1929
- Radio,
1930
- {
1931
- checked: shouldKeepDraft,
1932
- value: UNPUBLISH_DRAFT_OPTIONS.KEEP,
1933
- name: "discard-options",
1934
- children: formatMessage({
1935
- id: "content-manager.actions.unpublish.dialog.option.keep-draft",
1936
- defaultMessage: "Keep draft"
1937
- })
1938
- }
1939
- ),
1940
- /* @__PURE__ */ jsx(
1941
- Radio,
1942
- {
1943
- checked: !shouldKeepDraft,
1944
- value: UNPUBLISH_DRAFT_OPTIONS.DISCARD,
1945
- name: "discard-options",
1946
- children: formatMessage({
1947
- id: "content-manager.actions.unpublish.dialog.option.replace-draft",
1948
- defaultMessage: "Replace draft"
1949
- })
1950
- }
1951
- )
2412
+ /* @__PURE__ */ jsx(Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
2413
+ id: "content-manager.actions.unpublish.dialog.option.keep-draft",
2414
+ defaultMessage: "Keep draft"
2415
+ }) }),
2416
+ /* @__PURE__ */ jsx(Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
2417
+ id: "content-manager.actions.unpublish.dialog.option.replace-draft",
2418
+ defaultMessage: "Replace draft"
2419
+ }) })
1952
2420
  ]
1953
2421
  }
1954
2422
  )
@@ -2004,7 +2472,7 @@ const DiscardAction = ({
2004
2472
  id: "content-manager.actions.discard.label",
2005
2473
  defaultMessage: "Discard changes"
2006
2474
  }),
2007
- icon: /* @__PURE__ */ jsx(StyledCrossCircle, {}),
2475
+ icon: /* @__PURE__ */ jsx(Cross, {}),
2008
2476
  position: ["panel", "table-row"],
2009
2477
  variant: "danger",
2010
2478
  dialog: {
@@ -2032,11 +2500,6 @@ const DiscardAction = ({
2032
2500
  };
2033
2501
  };
2034
2502
  DiscardAction.type = "discard";
2035
- const StyledCrossCircle = styled(CrossCircle)`
2036
- path {
2037
- fill: currentColor;
2038
- }
2039
- `;
2040
2503
  const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
2041
2504
  const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
2042
2505
  const RelativeTime = React.forwardRef(
@@ -2084,7 +2547,7 @@ const getDisplayName = ({
2084
2547
  };
2085
2548
  const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2086
2549
  const DocumentStatus = ({ status = "draft", ...restProps }) => {
2087
- const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
2550
+ const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
2088
2551
  return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
2089
2552
  };
2090
2553
  const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
@@ -2094,23 +2557,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2094
2557
  id: "content-manager.containers.edit.title.new",
2095
2558
  defaultMessage: "Create an entry"
2096
2559
  }) : documentTitle;
2097
- return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 8, paddingBottom: 4, gap: 3, children: [
2560
+ return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
2098
2561
  /* @__PURE__ */ jsx(BackButton, {}),
2099
- /* @__PURE__ */ jsxs(
2100
- Flex,
2101
- {
2102
- width: "100%",
2103
- justifyContent: "space-between",
2104
- paddingTop: 1,
2105
- gap: "80px",
2106
- alignItems: "flex-start",
2107
- children: [
2108
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
2109
- /* @__PURE__ */ jsx(HeaderToolbar, {})
2110
- ]
2111
- }
2112
- ),
2113
- status ? /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
2562
+ /* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
2563
+ /* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
2564
+ /* @__PURE__ */ jsx(HeaderToolbar, {})
2565
+ ] }),
2566
+ status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
2114
2567
  ] });
2115
2568
  };
2116
2569
  const HeaderToolbar = () => {
@@ -2277,25 +2730,77 @@ const Information = ({ activeTab }) => {
2277
2730
  );
2278
2731
  };
2279
2732
  const HeaderActions = ({ actions: actions2 }) => {
2280
- return /* @__PURE__ */ jsx(Flex, { children: actions2.map((action) => {
2281
- if ("options" in action) {
2733
+ const [dialogId, setDialogId] = React.useState(null);
2734
+ const handleClick = (action) => async (e) => {
2735
+ if (!("options" in action)) {
2736
+ const { onClick = () => false, dialog, id } = action;
2737
+ const muteDialog = await onClick(e);
2738
+ if (dialog && !muteDialog) {
2739
+ e.preventDefault();
2740
+ setDialogId(id);
2741
+ }
2742
+ }
2743
+ };
2744
+ const handleClose = () => {
2745
+ setDialogId(null);
2746
+ };
2747
+ return /* @__PURE__ */ jsx(Flex, { gap: 1, children: actions2.map((action) => {
2748
+ if (action.options) {
2282
2749
  return /* @__PURE__ */ jsx(
2283
2750
  SingleSelect,
2284
2751
  {
2285
2752
  size: "S",
2286
- disabled: action.disabled,
2287
- "aria-label": action.label,
2288
2753
  onChange: action.onSelect,
2289
- value: action.value,
2754
+ "aria-label": action.label,
2755
+ ...action,
2290
2756
  children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
2291
2757
  },
2292
2758
  action.id
2293
2759
  );
2294
2760
  } else {
2295
- return null;
2761
+ if (action.type === "icon") {
2762
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
2763
+ /* @__PURE__ */ jsx(
2764
+ IconButton,
2765
+ {
2766
+ disabled: action.disabled,
2767
+ label: action.label,
2768
+ size: "S",
2769
+ onClick: handleClick(action),
2770
+ children: action.icon
2771
+ }
2772
+ ),
2773
+ action.dialog ? /* @__PURE__ */ jsx(
2774
+ HeaderActionDialog,
2775
+ {
2776
+ ...action.dialog,
2777
+ isOpen: dialogId === action.id,
2778
+ onClose: handleClose
2779
+ }
2780
+ ) : null
2781
+ ] }, action.id);
2782
+ }
2296
2783
  }
2297
2784
  }) });
2298
2785
  };
2786
+ const HeaderActionDialog = ({
2787
+ onClose,
2788
+ onCancel,
2789
+ title,
2790
+ content: Content,
2791
+ isOpen
2792
+ }) => {
2793
+ const handleClose = async () => {
2794
+ if (onCancel) {
2795
+ await onCancel();
2796
+ }
2797
+ onClose();
2798
+ };
2799
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
2800
+ /* @__PURE__ */ jsx(Dialog.Header, { children: title }),
2801
+ typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content
2802
+ ] }) });
2803
+ };
2299
2804
  const ConfigureTheViewAction = ({ collectionType, model }) => {
2300
2805
  const navigate = useNavigate();
2301
2806
  const { formatMessage } = useIntl();
@@ -2336,12 +2841,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
2336
2841
  const { delete: deleteAction } = useDocumentActions();
2337
2842
  const { toggleNotification } = useNotification();
2338
2843
  const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
2844
+ const isLocalized = document?.locale != null;
2339
2845
  return {
2340
2846
  disabled: !canDelete || !document,
2341
- label: formatMessage({
2342
- id: "content-manager.actions.delete.label",
2343
- defaultMessage: "Delete document"
2344
- }),
2847
+ label: formatMessage(
2848
+ {
2849
+ id: "content-manager.actions.delete.label",
2850
+ defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
2851
+ },
2852
+ { isLocalized }
2853
+ ),
2345
2854
  icon: /* @__PURE__ */ jsx(Trash, {}),
2346
2855
  dialog: {
2347
2856
  type: "dialog",
@@ -2427,373 +2936,71 @@ const Panels = () => {
2427
2936
  ) });
2428
2937
  };
2429
2938
  const ActionsPanel = () => {
2430
- const { formatMessage } = useIntl();
2431
- return {
2432
- title: formatMessage({
2433
- id: "content-manager.containers.edit.panels.default.title",
2434
- defaultMessage: "Document"
2435
- }),
2436
- content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
2437
- };
2438
- };
2439
- ActionsPanel.type = "actions";
2440
- const ActionsPanelContent = () => {
2441
- const isCloning = useMatch(CLONE_PATH) !== null;
2442
- const [
2443
- {
2444
- query: { status = "draft" }
2445
- }
2446
- ] = useQueryParams();
2447
- const { model, id, document, meta, collectionType } = useDoc();
2448
- const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
2449
- const props = {
2450
- activeTab: status,
2451
- model,
2452
- documentId: id,
2453
- document: isCloning ? void 0 : document,
2454
- meta: isCloning ? void 0 : meta,
2455
- collectionType
2456
- };
2457
- return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
2458
- /* @__PURE__ */ jsx(
2459
- DescriptionComponentRenderer,
2460
- {
2461
- props,
2462
- descriptions: plugins["content-manager"].apis.getDocumentActions(),
2463
- children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
2464
- }
2465
- ),
2466
- /* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
2467
- ] });
2468
- };
2469
- const Panel = React.forwardRef(({ children, title }, ref) => {
2470
- return /* @__PURE__ */ jsxs(
2471
- Flex,
2472
- {
2473
- ref,
2474
- tag: "aside",
2475
- "aria-labelledby": "additional-information",
2476
- background: "neutral0",
2477
- borderColor: "neutral150",
2478
- hasRadius: true,
2479
- paddingBottom: 4,
2480
- paddingLeft: 4,
2481
- paddingRight: 4,
2482
- paddingTop: 4,
2483
- shadow: "tableShadow",
2484
- gap: 3,
2485
- direction: "column",
2486
- justifyContent: "stretch",
2487
- alignItems: "flex-start",
2488
- children: [
2489
- /* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
2490
- children
2491
- ]
2492
- }
2493
- );
2494
- });
2495
- const HOOKS = {
2496
- /**
2497
- * Hook that allows to mutate the displayed headers of the list view table
2498
- * @constant
2499
- * @type {string}
2500
- */
2501
- INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
2502
- /**
2503
- * Hook that allows to mutate the CM's collection types links pre-set filters
2504
- * @constant
2505
- * @type {string}
2506
- */
2507
- MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
2508
- /**
2509
- * Hook that allows to mutate the CM's edit view layout
2510
- * @constant
2511
- * @type {string}
2512
- */
2513
- MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
2514
- /**
2515
- * Hook that allows to mutate the CM's single types links pre-set filters
2516
- * @constant
2517
- * @type {string}
2518
- */
2519
- MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
2520
- };
2521
- const contentTypesApi = contentManagerApi.injectEndpoints({
2522
- endpoints: (builder) => ({
2523
- getContentTypeConfiguration: builder.query({
2524
- query: (uid) => ({
2525
- url: `/content-manager/content-types/${uid}/configuration`,
2526
- method: "GET"
2527
- }),
2528
- transformResponse: (response) => response.data,
2529
- providesTags: (_result, _error, uid) => [
2530
- { type: "ContentTypesConfiguration", id: uid },
2531
- { type: "ContentTypeSettings", id: "LIST" }
2532
- ]
2533
- }),
2534
- getAllContentTypeSettings: builder.query({
2535
- query: () => "/content-manager/content-types-settings",
2536
- transformResponse: (response) => response.data,
2537
- providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
2538
- }),
2539
- updateContentTypeConfiguration: builder.mutation({
2540
- query: ({ uid, ...body }) => ({
2541
- url: `/content-manager/content-types/${uid}/configuration`,
2542
- method: "PUT",
2543
- data: body
2544
- }),
2545
- transformResponse: (response) => response.data,
2546
- invalidatesTags: (_result, _error, { uid }) => [
2547
- { type: "ContentTypesConfiguration", id: uid },
2548
- { type: "ContentTypeSettings", id: "LIST" },
2549
- // Is this necessary?
2550
- { type: "InitialData" }
2551
- ]
2552
- })
2553
- })
2554
- });
2555
- const {
2556
- useGetContentTypeConfigurationQuery,
2557
- useGetAllContentTypeSettingsQuery,
2558
- useUpdateContentTypeConfigurationMutation
2559
- } = contentTypesApi;
2560
- const checkIfAttributeIsDisplayable = (attribute) => {
2561
- const { type } = attribute;
2562
- if (type === "relation") {
2563
- return !attribute.relation.toLowerCase().includes("morph");
2564
- }
2565
- return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
2566
- };
2567
- const getMainField = (attribute, mainFieldName, { schemas, components }) => {
2568
- if (!mainFieldName) {
2569
- return void 0;
2570
- }
2571
- const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
2572
- // @ts-expect-error – `targetModel` does exist on the attribute for a relation.
2573
- schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
2574
- );
2575
- return {
2576
- name: mainFieldName,
2577
- type: mainFieldType ?? "string"
2578
- };
2579
- };
2580
- const DEFAULT_SETTINGS = {
2581
- bulkable: false,
2582
- filterable: false,
2583
- searchable: false,
2584
- pagination: false,
2585
- defaultSortBy: "",
2586
- defaultSortOrder: "asc",
2587
- mainField: "id",
2588
- pageSize: 10
2589
- };
2590
- const useDocumentLayout = (model) => {
2591
- const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
2592
- const [{ query }] = useQueryParams();
2593
- const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
2594
- const { toggleNotification } = useNotification();
2595
- const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
2596
- const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
2597
- const {
2598
- data,
2599
- isLoading: isLoadingConfigs,
2600
- error,
2601
- isFetching: isFetchingConfigs
2602
- } = useGetContentTypeConfigurationQuery(model);
2603
- const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
2604
- React.useEffect(() => {
2605
- if (error) {
2606
- toggleNotification({
2607
- type: "danger",
2608
- message: formatAPIError(error)
2609
- });
2610
- }
2611
- }, [error, formatAPIError, toggleNotification]);
2612
- const editLayout = React.useMemo(
2613
- () => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
2614
- layout: [],
2615
- components: {},
2616
- metadatas: {},
2617
- options: {},
2618
- settings: DEFAULT_SETTINGS
2619
- },
2620
- [data, isLoading, schemas, schema, components]
2621
- );
2622
- const listLayout = React.useMemo(() => {
2623
- return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
2624
- layout: [],
2625
- metadatas: {},
2626
- options: {},
2627
- settings: DEFAULT_SETTINGS
2628
- };
2629
- }, [data, isLoading, schemas, schema, components]);
2630
- const { layout: edit } = React.useMemo(
2631
- () => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
2632
- layout: editLayout,
2633
- query
2634
- }),
2635
- [editLayout, query, runHookWaterfall]
2636
- );
2637
- return {
2638
- error,
2639
- isLoading,
2640
- edit,
2641
- list: listLayout
2642
- };
2643
- };
2644
- const useDocLayout = () => {
2645
- const { model } = useDoc();
2646
- return useDocumentLayout(model);
2647
- };
2648
- const formatEditLayout = (data, {
2649
- schemas,
2650
- schema,
2651
- components
2652
- }) => {
2653
- let currentPanelIndex = 0;
2654
- const panelledEditAttributes = convertEditLayoutToFieldLayouts(
2655
- data.contentType.layouts.edit,
2656
- schema?.attributes,
2657
- data.contentType.metadatas,
2658
- { configurations: data.components, schemas: components },
2659
- schemas
2660
- ).reduce((panels, row) => {
2661
- if (row.some((field) => field.type === "dynamiczone")) {
2662
- panels.push([row]);
2663
- currentPanelIndex += 2;
2664
- } else {
2665
- if (!panels[currentPanelIndex]) {
2666
- panels.push([]);
2667
- }
2668
- panels[currentPanelIndex].push(row);
2669
- }
2670
- return panels;
2671
- }, []);
2672
- const componentEditAttributes = Object.entries(data.components).reduce(
2673
- (acc, [uid, configuration]) => {
2674
- acc[uid] = {
2675
- layout: convertEditLayoutToFieldLayouts(
2676
- configuration.layouts.edit,
2677
- components[uid].attributes,
2678
- configuration.metadatas
2679
- ),
2680
- settings: {
2681
- ...configuration.settings,
2682
- icon: components[uid].info.icon,
2683
- displayName: components[uid].info.displayName
2684
- }
2685
- };
2686
- return acc;
2687
- },
2688
- {}
2689
- );
2690
- const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
2691
- (acc, [attribute, metadata]) => {
2692
- return {
2693
- ...acc,
2694
- [attribute]: metadata.edit
2695
- };
2696
- },
2697
- {}
2698
- );
2699
- return {
2700
- layout: panelledEditAttributes,
2701
- components: componentEditAttributes,
2702
- metadatas: editMetadatas,
2703
- settings: {
2704
- ...data.contentType.settings,
2705
- displayName: schema?.info.displayName
2706
- },
2707
- options: {
2708
- ...schema?.options,
2709
- ...schema?.pluginOptions,
2710
- ...data.contentType.options
2711
- }
2712
- };
2713
- };
2714
- const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
2715
- return rows.map(
2716
- (row) => row.map((field) => {
2717
- const attribute = attributes[field.name];
2718
- if (!attribute) {
2719
- return null;
2720
- }
2721
- const { edit: metadata } = metadatas[field.name];
2722
- const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
2723
- return {
2724
- attribute,
2725
- disabled: !metadata.editable,
2726
- hint: metadata.description,
2727
- label: metadata.label ?? "",
2728
- name: field.name,
2729
- // @ts-expect-error – mainField does exist on the metadata for a relation.
2730
- mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
2731
- schemas,
2732
- components: components?.schemas ?? {}
2733
- }),
2734
- placeholder: metadata.placeholder ?? "",
2735
- required: attribute.required ?? false,
2736
- size: field.size,
2737
- unique: "unique" in attribute ? attribute.unique : false,
2738
- visible: metadata.visible ?? true,
2739
- type: attribute.type
2740
- };
2741
- }).filter((field) => field !== null)
2742
- );
2743
- };
2744
- const formatListLayout = (data, {
2745
- schemas,
2746
- schema,
2747
- components
2748
- }) => {
2749
- const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
2750
- (acc, [attribute, metadata]) => {
2751
- return {
2752
- ...acc,
2753
- [attribute]: metadata.list
2754
- };
2755
- },
2756
- {}
2757
- );
2758
- const listAttributes = convertListLayoutToFieldLayouts(
2759
- data.contentType.layouts.list,
2760
- schema?.attributes,
2761
- listMetadatas,
2762
- { configurations: data.components, schemas: components },
2763
- schemas
2764
- );
2765
- return {
2766
- layout: listAttributes,
2767
- settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
2768
- metadatas: listMetadatas,
2769
- options: {
2770
- ...schema?.options,
2771
- ...schema?.pluginOptions,
2772
- ...data.contentType.options
2773
- }
2939
+ const { formatMessage } = useIntl();
2940
+ return {
2941
+ title: formatMessage({
2942
+ id: "content-manager.containers.edit.panels.default.title",
2943
+ defaultMessage: "Entry"
2944
+ }),
2945
+ content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
2774
2946
  };
2775
2947
  };
2776
- const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
2777
- return columns.map((name) => {
2778
- const attribute = attributes[name];
2779
- if (!attribute) {
2780
- return null;
2948
+ ActionsPanel.type = "actions";
2949
+ const ActionsPanelContent = () => {
2950
+ const isCloning = useMatch(CLONE_PATH) !== null;
2951
+ const [
2952
+ {
2953
+ query: { status = "draft" }
2781
2954
  }
2782
- const metadata = metadatas[name];
2783
- const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
2784
- return {
2785
- attribute,
2786
- label: metadata.label ?? "",
2787
- mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
2788
- schemas,
2789
- components: components?.schemas ?? {}
2790
- }),
2791
- name,
2792
- searchable: metadata.searchable ?? true,
2793
- sortable: metadata.sortable ?? true
2794
- };
2795
- }).filter((field) => field !== null);
2955
+ ] = useQueryParams();
2956
+ const { model, id, document, meta, collectionType } = useDoc();
2957
+ const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
2958
+ const props = {
2959
+ activeTab: status,
2960
+ model,
2961
+ documentId: id,
2962
+ document: isCloning ? void 0 : document,
2963
+ meta: isCloning ? void 0 : meta,
2964
+ collectionType
2965
+ };
2966
+ return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
2967
+ /* @__PURE__ */ jsx(
2968
+ DescriptionComponentRenderer,
2969
+ {
2970
+ props,
2971
+ descriptions: plugins["content-manager"].apis.getDocumentActions(),
2972
+ children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
2973
+ }
2974
+ ),
2975
+ /* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
2976
+ ] });
2796
2977
  };
2978
+ const Panel = React.forwardRef(({ children, title }, ref) => {
2979
+ return /* @__PURE__ */ jsxs(
2980
+ Flex,
2981
+ {
2982
+ ref,
2983
+ tag: "aside",
2984
+ "aria-labelledby": "additional-information",
2985
+ background: "neutral0",
2986
+ borderColor: "neutral150",
2987
+ hasRadius: true,
2988
+ paddingBottom: 4,
2989
+ paddingLeft: 4,
2990
+ paddingRight: 4,
2991
+ paddingTop: 4,
2992
+ shadow: "tableShadow",
2993
+ gap: 3,
2994
+ direction: "column",
2995
+ justifyContent: "stretch",
2996
+ alignItems: "flex-start",
2997
+ children: [
2998
+ /* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
2999
+ children
3000
+ ]
3001
+ }
3002
+ );
3003
+ });
2797
3004
  const ConfirmBulkActionDialog = ({
2798
3005
  onToggleDialog,
2799
3006
  isOpen = false,
@@ -2801,30 +3008,23 @@ const ConfirmBulkActionDialog = ({
2801
3008
  endAction
2802
3009
  }) => {
2803
3010
  const { formatMessage } = useIntl();
2804
- return /* @__PURE__ */ jsxs(
2805
- Dialog,
2806
- {
2807
- onClose: onToggleDialog,
2808
- title: formatMessage({
2809
- id: "app.components.ConfirmDialog.title",
2810
- defaultMessage: "Confirmation"
2811
- }),
2812
- isOpen,
2813
- children: [
2814
- /* @__PURE__ */ jsx(DialogBody, { icon: /* @__PURE__ */ jsx(WarningCircle, {}), children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: dialogBody }) }),
2815
- /* @__PURE__ */ jsx(
2816
- DialogFooter,
2817
- {
2818
- startAction: /* @__PURE__ */ jsx(Button, { onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
2819
- id: "app.components.Button.cancel",
2820
- defaultMessage: "Cancel"
2821
- }) }),
2822
- endAction
2823
- }
2824
- )
2825
- ]
2826
- }
2827
- );
3011
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
3012
+ /* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
3013
+ id: "app.components.ConfirmDialog.title",
3014
+ defaultMessage: "Confirmation"
3015
+ }) }),
3016
+ /* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3017
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3018
+ dialogBody
3019
+ ] }) }),
3020
+ /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
3021
+ /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
3022
+ id: "app.components.Button.cancel",
3023
+ defaultMessage: "Cancel"
3024
+ }) }) }),
3025
+ endAction
3026
+ ] })
3027
+ ] }) });
2828
3028
  };
2829
3029
  const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
2830
3030
  const ConfirmDialogPublishAll = ({
@@ -2839,6 +3039,7 @@ const ConfirmDialogPublishAll = ({
2839
3039
  const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
2840
3040
  const { model, schema } = useDoc();
2841
3041
  const [{ query }] = useQueryParams();
3042
+ const enableDraftRelationsCount = false;
2842
3043
  const {
2843
3044
  data: countDraftRelations = 0,
2844
3045
  isLoading,
@@ -2850,7 +3051,7 @@ const ConfirmDialogPublishAll = ({
2850
3051
  locale: query?.plugins?.i18n?.locale
2851
3052
  },
2852
3053
  {
2853
- skip: selectedEntries.length === 0
3054
+ skip: !enableDraftRelationsCount
2854
3055
  }
2855
3056
  );
2856
3057
  React.useEffect(() => {
@@ -2929,7 +3130,14 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
2929
3130
  )
2930
3131
  );
2931
3132
  } else {
2932
- messages.push(...formatErrorMessages(value, currentKey, formatMessage));
3133
+ messages.push(
3134
+ ...formatErrorMessages(
3135
+ // @ts-expect-error TODO: check why value is not compatible with FormErrors
3136
+ value,
3137
+ currentKey,
3138
+ formatMessage
3139
+ )
3140
+ );
2933
3141
  }
2934
3142
  } else {
2935
3143
  messages.push(
@@ -3028,7 +3236,7 @@ const SelectedEntriesTableContent = ({
3028
3236
  status: row.status
3029
3237
  }
3030
3238
  ) }),
3031
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
3239
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
3032
3240
  IconButton,
3033
3241
  {
3034
3242
  tag: Link,
@@ -3051,9 +3259,10 @@ const SelectedEntriesTableContent = ({
3051
3259
  ),
3052
3260
  target: "_blank",
3053
3261
  marginLeft: "auto",
3054
- children: /* @__PURE__ */ jsx(Pencil, {})
3262
+ variant: "ghost",
3263
+ children: /* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" })
3055
3264
  }
3056
- ) })
3265
+ ) }) })
3057
3266
  ] }, row.id)) })
3058
3267
  ] });
3059
3268
  };
@@ -3090,7 +3299,13 @@ const SelectedEntriesModalContent = ({
3090
3299
  );
3091
3300
  const { rows, validationErrors } = React.useMemo(() => {
3092
3301
  if (data.length > 0 && schema) {
3093
- const validate = createYupSchema(schema.attributes, components);
3302
+ const validate = createYupSchema(
3303
+ schema.attributes,
3304
+ components,
3305
+ // Since this is the "Publish" action, the validation
3306
+ // schema must enforce the rules for published entities
3307
+ { status: "published" }
3308
+ );
3094
3309
  const validationErrors2 = {};
3095
3310
  const rows2 = data.map((entry) => {
3096
3311
  try {
@@ -3166,7 +3381,7 @@ const SelectedEntriesModalContent = ({
3166
3381
  );
3167
3382
  };
3168
3383
  return /* @__PURE__ */ jsxs(Fragment, { children: [
3169
- /* @__PURE__ */ jsxs(ModalBody, { children: [
3384
+ /* @__PURE__ */ jsxs(Modal.Body, { children: [
3170
3385
  /* @__PURE__ */ jsx(Typography, { children: getFormattedCountMessage() }),
3171
3386
  /* @__PURE__ */ jsx(Box, { marginTop: 5, children: /* @__PURE__ */ jsx(
3172
3387
  SelectedEntriesTableContent,
@@ -3178,27 +3393,24 @@ const SelectedEntriesModalContent = ({
3178
3393
  }
3179
3394
  ) })
3180
3395
  ] }),
3181
- /* @__PURE__ */ jsx(
3182
- ModalFooter,
3183
- {
3184
- startActions: /* @__PURE__ */ jsx(Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
3185
- id: "app.components.Button.cancel",
3186
- defaultMessage: "Cancel"
3187
- }) }),
3188
- endActions: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3189
- /* @__PURE__ */ jsx(Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
3190
- /* @__PURE__ */ jsx(
3191
- Button,
3192
- {
3193
- onClick: toggleDialog,
3194
- disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
3195
- loading: isSubmittingForm,
3196
- children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
3197
- }
3198
- )
3199
- ] })
3200
- }
3201
- ),
3396
+ /* @__PURE__ */ jsxs(Modal.Footer, { children: [
3397
+ /* @__PURE__ */ jsx(Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
3398
+ id: "app.components.Button.cancel",
3399
+ defaultMessage: "Cancel"
3400
+ }) }),
3401
+ /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3402
+ /* @__PURE__ */ jsx(Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
3403
+ /* @__PURE__ */ jsx(
3404
+ Button,
3405
+ {
3406
+ onClick: toggleDialog,
3407
+ disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
3408
+ loading: isSubmittingForm,
3409
+ children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
3410
+ }
3411
+ )
3412
+ ] })
3413
+ ] }),
3202
3414
  /* @__PURE__ */ jsx(
3203
3415
  ConfirmDialogPublishAll,
3204
3416
  {
@@ -3263,143 +3475,10 @@ const BulkActionsRenderer = () => {
3263
3475
  documents: selectedRows
3264
3476
  },
3265
3477
  descriptions: plugins["content-manager"].apis.getBulkActions(),
3266
- children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(BulkActionAction, { ...action }, action.id))
3478
+ children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(DocumentActionButton, { ...action }, action.id))
3267
3479
  }
3268
3480
  ) });
3269
3481
  };
3270
- const BulkActionAction = (action) => {
3271
- const [dialogId, setDialogId] = React.useState(null);
3272
- const { toggleNotification } = useNotification();
3273
- const handleClick = (action2) => (e) => {
3274
- const { onClick, dialog, id } = action2;
3275
- if (onClick) {
3276
- onClick(e);
3277
- }
3278
- if (dialog) {
3279
- switch (dialog.type) {
3280
- case "notification":
3281
- toggleNotification({
3282
- title: dialog.title,
3283
- message: dialog.content,
3284
- type: dialog.status,
3285
- timeout: dialog.timeout,
3286
- onClose: dialog.onClose
3287
- });
3288
- break;
3289
- case "dialog":
3290
- case "modal": {
3291
- e.preventDefault();
3292
- setDialogId(id);
3293
- }
3294
- }
3295
- }
3296
- };
3297
- const handleClose = () => {
3298
- setDialogId(null);
3299
- if (action.dialog?.type === "modal" && action.dialog?.onClose) {
3300
- action.dialog.onClose();
3301
- }
3302
- };
3303
- return /* @__PURE__ */ jsxs(Fragment, { children: [
3304
- /* @__PURE__ */ jsx(
3305
- Button,
3306
- {
3307
- disabled: action.disabled,
3308
- startIcon: action.icon,
3309
- variant: action.variant,
3310
- onClick: handleClick(action),
3311
- children: action.label
3312
- }
3313
- ),
3314
- action.dialog?.type === "dialog" ? /* @__PURE__ */ jsx(
3315
- BulkActionConfirmDialog,
3316
- {
3317
- ...action.dialog,
3318
- variant: action.variant,
3319
- isOpen: dialogId === action.id,
3320
- onClose: handleClose
3321
- }
3322
- ) : null,
3323
- action.dialog?.type === "modal" ? /* @__PURE__ */ jsx(
3324
- BulkActionModal,
3325
- {
3326
- ...action.dialog,
3327
- onModalClose: handleClose,
3328
- isOpen: dialogId === action.id
3329
- }
3330
- ) : null
3331
- ] });
3332
- };
3333
- const BulkActionConfirmDialog = ({
3334
- onClose,
3335
- onCancel,
3336
- onConfirm,
3337
- title,
3338
- content,
3339
- confirmButton,
3340
- isOpen,
3341
- variant = "secondary"
3342
- }) => {
3343
- const { formatMessage } = useIntl();
3344
- const handleClose = async () => {
3345
- if (onCancel) {
3346
- await onCancel();
3347
- }
3348
- onClose();
3349
- };
3350
- const handleConfirm = async () => {
3351
- if (onConfirm) {
3352
- await onConfirm();
3353
- }
3354
- onClose();
3355
- };
3356
- return /* @__PURE__ */ jsxs(Dialog, { isOpen, title, onClose: handleClose, children: [
3357
- /* @__PURE__ */ jsx(DialogBody, { icon: /* @__PURE__ */ jsx(WarningCircle, {}), children: content }),
3358
- /* @__PURE__ */ jsx(
3359
- DialogFooter,
3360
- {
3361
- startAction: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", children: formatMessage({
3362
- id: "app.components.Button.cancel",
3363
- defaultMessage: "Cancel"
3364
- }) }),
3365
- endAction: /* @__PURE__ */ jsx(
3366
- Button,
3367
- {
3368
- onClick: handleConfirm,
3369
- variant: variant === "danger-light" ? variant : "secondary",
3370
- startIcon: variant === "danger-light" ? /* @__PURE__ */ jsx(Trash, {}) : /* @__PURE__ */ jsx(Check, {}),
3371
- children: confirmButton ? confirmButton : formatMessage({
3372
- id: "app.components.Button.confirm",
3373
- defaultMessage: "Confirm"
3374
- })
3375
- }
3376
- )
3377
- }
3378
- )
3379
- ] });
3380
- };
3381
- const BulkActionModal = ({
3382
- isOpen,
3383
- title,
3384
- onClose,
3385
- content: Content,
3386
- onModalClose
3387
- }) => {
3388
- const id = React.useId();
3389
- if (!isOpen) {
3390
- return null;
3391
- }
3392
- const handleClose = () => {
3393
- if (onClose) {
3394
- onClose();
3395
- }
3396
- onModalClose();
3397
- };
3398
- return /* @__PURE__ */ jsxs(ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
3399
- /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
3400
- /* @__PURE__ */ jsx(Content, { onClose: handleClose })
3401
- ] });
3402
- };
3403
3482
  const DeleteAction = ({ documents, model }) => {
3404
3483
  const { formatMessage } = useIntl();
3405
3484
  const { schema: contentType } = useDoc();
@@ -3432,6 +3511,7 @@ const DeleteAction = ({ documents, model }) => {
3432
3511
  defaultMessage: "Confirmation"
3433
3512
  }),
3434
3513
  content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3514
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3435
3515
  /* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3436
3516
  id: "popUpWarning.bodyMessage.contentType.delete.all",
3437
3517
  defaultMessage: "Are you sure you want to delete these entries?"
@@ -3481,6 +3561,7 @@ const UnpublishAction = ({ documents, model }) => {
3481
3561
  defaultMessage: "Confirmation"
3482
3562
  }),
3483
3563
  content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3564
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3484
3565
  /* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3485
3566
  id: "popUpWarning.bodyMessage.contentType.unpublish.all",
3486
3567
  defaultMessage: "Are you sure you want to unpublish these entries?"
@@ -3574,7 +3655,7 @@ const TableActions = ({ document }) => {
3574
3655
  DescriptionComponentRenderer,
3575
3656
  {
3576
3657
  props,
3577
- descriptions: plugins["content-manager"].apis.getDocumentActions(),
3658
+ descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
3578
3659
  children: (actions2) => {
3579
3660
  const tableRowActions = actions2.filter((action) => {
3580
3661
  const positions = Array.isArray(action.position) ? action.position : [action.position];
@@ -3685,7 +3766,7 @@ const CloneAction = ({ model, documentId }) => {
3685
3766
  }),
3686
3767
  content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
3687
3768
  footer: ({ onClose }) => {
3688
- return /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", children: [
3769
+ return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
3689
3770
  /* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
3690
3771
  id: "cancel",
3691
3772
  defaultMessage: "Cancel"
@@ -3726,8 +3807,7 @@ class ContentManagerPlugin {
3726
3807
  documentActions = [
3727
3808
  ...DEFAULT_ACTIONS,
3728
3809
  ...DEFAULT_TABLE_ROW_ACTIONS,
3729
- ...DEFAULT_HEADER_ACTIONS,
3730
- HistoryAction
3810
+ ...DEFAULT_HEADER_ACTIONS
3731
3811
  ];
3732
3812
  editViewSidePanels = [ActionsPanel];
3733
3813
  headerActions = [];
@@ -3816,6 +3896,52 @@ const getPrintableType = (value) => {
3816
3896
  }
3817
3897
  return nativeType;
3818
3898
  };
3899
+ const HistoryAction = ({ model, document }) => {
3900
+ const { formatMessage } = useIntl();
3901
+ const [{ query }] = useQueryParams();
3902
+ const navigate = useNavigate();
3903
+ const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
3904
+ if (!window.strapi.features.isEnabled("cms-content-history")) {
3905
+ return null;
3906
+ }
3907
+ return {
3908
+ icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
3909
+ label: formatMessage({
3910
+ id: "content-manager.history.document-action",
3911
+ defaultMessage: "Content History"
3912
+ }),
3913
+ onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
3914
+ disabled: (
3915
+ /**
3916
+ * The user is creating a new document.
3917
+ * It hasn't been saved yet, so there's no history to go to
3918
+ */
3919
+ !document || /**
3920
+ * The document has been created but the current dimension has never been saved.
3921
+ * For example, the user is creating a new locale in an existing document,
3922
+ * so there's no history for the document in that locale
3923
+ */
3924
+ !document.id || /**
3925
+ * History is only available for content types created by the user.
3926
+ * These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
3927
+ * which start with `admin::` or `plugin::`
3928
+ */
3929
+ !model.startsWith("api::")
3930
+ ),
3931
+ position: "header"
3932
+ };
3933
+ };
3934
+ HistoryAction.type = "history";
3935
+ const historyAdmin = {
3936
+ bootstrap(app) {
3937
+ const { addDocumentAction } = app.getPlugin("content-manager").apis;
3938
+ addDocumentAction((actions2) => {
3939
+ const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
3940
+ actions2.splice(indexOfDeleteAction, 0, HistoryAction);
3941
+ return actions2;
3942
+ });
3943
+ }
3944
+ };
3819
3945
  const initialState = {
3820
3946
  collectionTypeLinks: [],
3821
3947
  components: [],
@@ -3866,15 +3992,29 @@ const index = {
3866
3992
  defaultMessage: "Content Manager"
3867
3993
  },
3868
3994
  permissions: [],
3869
- Component: () => import("./layout-BzAbmoO6.mjs").then((mod) => ({ default: mod.Layout })),
3870
3995
  position: 1
3871
3996
  });
3997
+ app.router.addRoute({
3998
+ path: "content-manager/*",
3999
+ lazy: async () => {
4000
+ const { Layout } = await import("./layout-DaUjDiWQ.mjs");
4001
+ return {
4002
+ Component: Layout
4003
+ };
4004
+ },
4005
+ children: routes
4006
+ });
3872
4007
  app.registerPlugin(cm.config);
3873
4008
  },
4009
+ bootstrap(app) {
4010
+ if (typeof historyAdmin.bootstrap === "function") {
4011
+ historyAdmin.bootstrap(app);
4012
+ }
4013
+ },
3874
4014
  async registerTrads({ locales }) {
3875
4015
  const importedTrads = await Promise.all(
3876
4016
  locales.map((locale) => {
3877
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-Ux26r5pl.mjs"), "./translations/es.json": () => import("./es-CeXiYflN.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr-CD9VFbPM.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-CtsUxOvk.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
4017
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-C8YBvRrK.mjs"), "./translations/es.json": () => import("./es-CeXiYflN.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr-CD9VFbPM.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-CtsUxOvk.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
3878
4018
  return {
3879
4019
  data: prefixPluginTranslations(data, PLUGIN_ID),
3880
4020
  locale
@@ -3902,7 +4042,8 @@ export {
3902
4042
  InjectionZone as I,
3903
4043
  useDocument as J,
3904
4044
  index as K,
3905
- useDocumentActions as L,
4045
+ useContentManagerContext as L,
4046
+ useDocumentActions as M,
3906
4047
  Panels as P,
3907
4048
  RelativeTime as R,
3908
4049
  SINGLE_TYPES as S,
@@ -3920,11 +4061,11 @@ export {
3920
4061
  PERMISSIONS as k,
3921
4062
  DocumentRBAC as l,
3922
4063
  DOCUMENT_META_FIELDS as m,
3923
- useDocLayout as n,
3924
- useGetContentTypeConfigurationQuery as o,
3925
- CREATOR_FIELDS as p,
3926
- getMainField as q,
3927
- routes as r,
4064
+ CLONE_PATH as n,
4065
+ useDocLayout as o,
4066
+ useGetContentTypeConfigurationQuery as p,
4067
+ CREATOR_FIELDS as q,
4068
+ getMainField as r,
3928
4069
  setInitialData as s,
3929
4070
  getDisplayName as t,
3930
4071
  useContentTypeSchema as u,
@@ -3934,4 +4075,4 @@ export {
3934
4075
  capitalise as y,
3935
4076
  useUpdateContentTypeConfigurationMutation as z
3936
4077
  };
3937
- //# sourceMappingURL=index-Drt2DN7v.mjs.map
4078
+ //# sourceMappingURL=index-C9HxCo5R.mjs.map