@strapi/content-manager 0.0.0-experimental.dd3311938ac827f1fa8560c8840a9a394f5896c0 → 0.0.0-experimental.edc24aaa3bb5a90fa5fd4fee208167dd4e2e38d4

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 (102) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-y_7iLdmB.js → ComponentConfigurationPage-5ukroXAh.js} +3 -3
  3. package/dist/_chunks/{ComponentConfigurationPage-y_7iLdmB.js.map → ComponentConfigurationPage-5ukroXAh.js.map} +1 -1
  4. package/dist/_chunks/{ComponentConfigurationPage-BMajAl1u.mjs → ComponentConfigurationPage-BAgyHiMm.mjs} +3 -3
  5. package/dist/_chunks/{ComponentConfigurationPage-BMajAl1u.mjs.map → ComponentConfigurationPage-BAgyHiMm.mjs.map} +1 -1
  6. package/dist/_chunks/{EditConfigurationPage-CcOoD26O.mjs → EditConfigurationPage-DmoXawIh.mjs} +3 -3
  7. package/dist/_chunks/{EditConfigurationPage-CcOoD26O.mjs.map → EditConfigurationPage-DmoXawIh.mjs.map} +1 -1
  8. package/dist/_chunks/{EditConfigurationPage-CPVB8Uqc.js → EditConfigurationPage-Xp7lun0f.js} +3 -3
  9. package/dist/_chunks/{EditConfigurationPage-CPVB8Uqc.js.map → EditConfigurationPage-Xp7lun0f.js.map} +1 -1
  10. package/dist/_chunks/{EditViewPage-DWb0DE7R.mjs → EditViewPage-BLsjc5F-.mjs} +46 -46
  11. package/dist/_chunks/EditViewPage-BLsjc5F-.mjs.map +1 -0
  12. package/dist/_chunks/{EditViewPage-CTTDHKkQ.js → EditViewPage-C-ukDOB7.js} +45 -45
  13. package/dist/_chunks/EditViewPage-C-ukDOB7.js.map +1 -0
  14. package/dist/_chunks/{Field-C5Z1Ivdv.js → Field-Bfph5SOd.js} +421 -141
  15. package/dist/_chunks/Field-Bfph5SOd.js.map +1 -0
  16. package/dist/_chunks/{Field-DnStdvQw.mjs → Field-Cs7duwWd.mjs} +422 -142
  17. package/dist/_chunks/Field-Cs7duwWd.mjs.map +1 -0
  18. package/dist/_chunks/{Form-B81OtW-k.js → Form-CPYqIWDG.js} +25 -26
  19. package/dist/_chunks/Form-CPYqIWDG.js.map +1 -0
  20. package/dist/_chunks/{Form-DqGgE55Q.mjs → Form-Dg_GS5TQ.mjs} +27 -28
  21. package/dist/_chunks/Form-Dg_GS5TQ.mjs.map +1 -0
  22. package/dist/_chunks/{History-4NbOq2dX.js → History-DNQkXANT.js} +51 -28
  23. package/dist/_chunks/History-DNQkXANT.js.map +1 -0
  24. package/dist/_chunks/{History-DS6-HCYX.mjs → History-wrnHqf09.mjs} +52 -29
  25. package/dist/_chunks/History-wrnHqf09.mjs.map +1 -0
  26. package/dist/_chunks/{ListConfigurationPage-CpfstlYY.js → ListConfigurationPage-CUQxfpjT.js} +48 -47
  27. package/dist/_chunks/ListConfigurationPage-CUQxfpjT.js.map +1 -0
  28. package/dist/_chunks/{ListConfigurationPage-DQJJltko.mjs → ListConfigurationPage-DScmJVkW.mjs} +49 -49
  29. package/dist/_chunks/ListConfigurationPage-DScmJVkW.mjs.map +1 -0
  30. package/dist/_chunks/{ListViewPage-CA3I75m5.js → ListViewPage-BsLiH2-2.js} +59 -67
  31. package/dist/_chunks/ListViewPage-BsLiH2-2.js.map +1 -0
  32. package/dist/_chunks/{ListViewPage-nQrOQuVo.mjs → ListViewPage-C4IvrMgY.mjs} +60 -68
  33. package/dist/_chunks/ListViewPage-C4IvrMgY.mjs.map +1 -0
  34. package/dist/_chunks/{NoContentTypePage-Dldu-_Mx.js → NoContentTypePage-BZ-PnGAf.js} +2 -2
  35. package/dist/_chunks/{NoContentTypePage-Dldu-_Mx.js.map → NoContentTypePage-BZ-PnGAf.js.map} +1 -1
  36. package/dist/_chunks/{NoContentTypePage-DbnHE22g.mjs → NoContentTypePage-Djg8nPlj.mjs} +2 -2
  37. package/dist/_chunks/{NoContentTypePage-DbnHE22g.mjs.map → NoContentTypePage-Djg8nPlj.mjs.map} +1 -1
  38. package/dist/_chunks/{NoPermissionsPage-fOIkQM0v.mjs → NoPermissionsPage-DSP7R-hv.mjs} +2 -2
  39. package/dist/_chunks/{NoPermissionsPage-fOIkQM0v.mjs.map → NoPermissionsPage-DSP7R-hv.mjs.map} +1 -1
  40. package/dist/_chunks/{NoPermissionsPage-CO2MK200.js → NoPermissionsPage-_lUqjGW3.js} +2 -2
  41. package/dist/_chunks/{NoPermissionsPage-CO2MK200.js.map → NoPermissionsPage-_lUqjGW3.js.map} +1 -1
  42. package/dist/_chunks/{Relations-BDRl99Ux.mjs → Relations-BZr8tL0R.mjs} +3 -3
  43. package/dist/_chunks/Relations-BZr8tL0R.mjs.map +1 -0
  44. package/dist/_chunks/{Relations-DG2jnOcr.js → Relations-CtELXYIK.js} +3 -3
  45. package/dist/_chunks/Relations-CtELXYIK.js.map +1 -0
  46. package/dist/_chunks/{en-Ux26r5pl.mjs → en-BrCTWlZv.mjs} +5 -4
  47. package/dist/_chunks/{en-Ux26r5pl.mjs.map → en-BrCTWlZv.mjs.map} +1 -1
  48. package/dist/_chunks/{en-fbKQxLGn.js → en-uOUIxfcQ.js} +5 -4
  49. package/dist/_chunks/{en-fbKQxLGn.js.map → en-uOUIxfcQ.js.map} +1 -1
  50. package/dist/_chunks/{index-BZoNZMXL.js → index-OerGjbAN.js} +365 -375
  51. package/dist/_chunks/index-OerGjbAN.js.map +1 -0
  52. package/dist/_chunks/{index-Drt2DN7v.mjs → index-c_5DdJi-.mjs} +380 -390
  53. package/dist/_chunks/index-c_5DdJi-.mjs.map +1 -0
  54. package/dist/_chunks/{layout-DEYBqgF1.js → layout-Ci7qHlFb.js} +7 -7
  55. package/dist/_chunks/layout-Ci7qHlFb.js.map +1 -0
  56. package/dist/_chunks/{layout-BzAbmoO6.mjs → layout-oPBiO7RY.mjs} +8 -8
  57. package/dist/_chunks/layout-oPBiO7RY.mjs.map +1 -0
  58. package/dist/_chunks/{relations-D26zVRdi.mjs → relations-BIdWFjdq.mjs} +2 -2
  59. package/dist/_chunks/{relations-D26zVRdi.mjs.map → relations-BIdWFjdq.mjs.map} +1 -1
  60. package/dist/_chunks/{relations-D0eZ4VWw.js → relations-COBpStiF.js} +2 -2
  61. package/dist/_chunks/{relations-D0eZ4VWw.js.map → relations-COBpStiF.js.map} +1 -1
  62. package/dist/admin/index.js +1 -1
  63. package/dist/admin/index.mjs +4 -4
  64. package/dist/admin/src/history/index.d.ts +3 -0
  65. package/dist/admin/src/index.d.ts +1 -0
  66. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +8 -3
  67. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
  68. package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
  69. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +2 -10
  70. package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
  71. package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
  72. package/dist/server/index.js +41 -34
  73. package/dist/server/index.js.map +1 -1
  74. package/dist/server/index.mjs +41 -34
  75. package/dist/server/index.mjs.map +1 -1
  76. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  77. package/dist/server/src/controllers/uid.d.ts.map +1 -1
  78. package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
  79. package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
  80. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  81. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  82. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  83. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  84. package/package.json +8 -8
  85. package/dist/_chunks/EditViewPage-CTTDHKkQ.js.map +0 -1
  86. package/dist/_chunks/EditViewPage-DWb0DE7R.mjs.map +0 -1
  87. package/dist/_chunks/Field-C5Z1Ivdv.js.map +0 -1
  88. package/dist/_chunks/Field-DnStdvQw.mjs.map +0 -1
  89. package/dist/_chunks/Form-B81OtW-k.js.map +0 -1
  90. package/dist/_chunks/Form-DqGgE55Q.mjs.map +0 -1
  91. package/dist/_chunks/History-4NbOq2dX.js.map +0 -1
  92. package/dist/_chunks/History-DS6-HCYX.mjs.map +0 -1
  93. package/dist/_chunks/ListConfigurationPage-CpfstlYY.js.map +0 -1
  94. package/dist/_chunks/ListConfigurationPage-DQJJltko.mjs.map +0 -1
  95. package/dist/_chunks/ListViewPage-CA3I75m5.js.map +0 -1
  96. package/dist/_chunks/ListViewPage-nQrOQuVo.mjs.map +0 -1
  97. package/dist/_chunks/Relations-BDRl99Ux.mjs.map +0 -1
  98. package/dist/_chunks/Relations-DG2jnOcr.js.map +0 -1
  99. package/dist/_chunks/index-BZoNZMXL.js.map +0 -1
  100. package/dist/_chunks/index-Drt2DN7v.mjs.map +0 -1
  101. package/dist/_chunks/layout-BzAbmoO6.mjs.map +0 -1
  102. package/dist/_chunks/layout-DEYBqgF1.js.map +0 -1
@@ -2,15 +2,15 @@
2
2
  const Icons = require("@strapi/icons");
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const strapiAdmin = require("@strapi/admin/strapi-admin");
5
- const qs = require("qs");
6
- const reactIntl = require("react-intl");
7
- const reactRouterDom = require("react-router-dom");
8
5
  const React = require("react");
9
6
  const designSystem = require("@strapi/design-system");
7
+ const reactIntl = require("react-intl");
8
+ const reactRouterDom = require("react-router-dom");
10
9
  const styledComponents = require("styled-components");
11
10
  const yup = require("yup");
12
11
  const pipe = require("lodash/fp/pipe");
13
12
  const dateFns = require("date-fns");
13
+ const qs = require("qs");
14
14
  const toolkit = require("@reduxjs/toolkit");
15
15
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
16
16
  function _interopNamespace(e) {
@@ -70,42 +70,6 @@ const useInjectionZone = (area) => {
70
70
  const [page, position] = area.split(".");
71
71
  return contentManagerPlugin.getInjectedComponents(page, position);
72
72
  };
73
- const HistoryAction = ({ model, document }) => {
74
- const { formatMessage } = reactIntl.useIntl();
75
- const [{ query }] = strapiAdmin.useQueryParams();
76
- const navigate = reactRouterDom.useNavigate();
77
- const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
78
- if (!window.strapi.features.isEnabled("cms-content-history")) {
79
- return null;
80
- }
81
- return {
82
- icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
83
- label: formatMessage({
84
- id: "content-manager.history.document-action",
85
- defaultMessage: "Content History"
86
- }),
87
- onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
88
- disabled: (
89
- /**
90
- * The user is creating a new document.
91
- * It hasn't been saved yet, so there's no history to go to
92
- */
93
- !document || /**
94
- * The document has been created but the current dimension has never been saved.
95
- * For example, the user is creating a new locale in an existing document,
96
- * so there's no history for the document in that locale
97
- */
98
- !document.id || /**
99
- * History is only available for content types created by the user.
100
- * These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
101
- * which start with `admin::` or `plugin::`
102
- */
103
- !model.startsWith("api::")
104
- ),
105
- position: "header"
106
- };
107
- };
108
- HistoryAction.type = "history";
109
73
  const ID = "id";
110
74
  const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
111
75
  const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
@@ -219,6 +183,7 @@ const contentManagerApi = strapiAdmin.adminApi.enhanceEndpoints({
219
183
  ]
220
184
  });
221
185
  const documentApi = contentManagerApi.injectEndpoints({
186
+ overrideExisting: true,
222
187
  endpoints: (builder) => ({
223
188
  autoCloneDocument: builder.mutation({
224
189
  query: ({ model, sourceId, query }) => ({
@@ -228,7 +193,12 @@ const documentApi = contentManagerApi.injectEndpoints({
228
193
  params: query
229
194
  }
230
195
  }),
231
- invalidatesTags: (_result, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
196
+ invalidatesTags: (_result, error, { model }) => {
197
+ if (error) {
198
+ return [];
199
+ }
200
+ return [{ type: "Document", id: `${model}_LIST` }];
201
+ }
232
202
  }),
233
203
  cloneDocument: builder.mutation({
234
204
  query: ({ model, sourceId, data, params }) => ({
@@ -418,6 +388,18 @@ const documentApi = contentManagerApi.injectEndpoints({
418
388
  },
419
389
  "Relations"
420
390
  ];
391
+ },
392
+ async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
393
+ const patchResult = dispatch(
394
+ documentApi.util.updateQueryData("getDocument", patch, (draft) => {
395
+ Object.assign(draft.data, data);
396
+ })
397
+ );
398
+ try {
399
+ await queryFulfilled;
400
+ } catch {
401
+ patchResult.undo();
402
+ }
421
403
  }
422
404
  }),
423
405
  unpublishDocument: builder.mutation({
@@ -620,11 +602,11 @@ const createAttributeSchema = (attribute) => {
620
602
  }
621
603
  };
622
604
  const addRequiredValidation = (attribute) => (schema) => {
623
- if (attribute.required) {
624
- return schema.required({
625
- id: strapiAdmin.translatedErrors.required.id,
626
- defaultMessage: "This field is required."
627
- });
605
+ if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
606
+ return schema.min(1, strapiAdmin.translatedErrors.required);
607
+ }
608
+ if (attribute.required && attribute.type !== "relation") {
609
+ return schema.required(strapiAdmin.translatedErrors.required);
628
610
  }
629
611
  return schema?.nullable ? schema.nullable() : (
630
612
  // In some cases '.nullable' will not be available on the schema.
@@ -658,6 +640,28 @@ const addMaxLengthValidation = (attribute) => (schema) => {
658
640
  const addMinValidation = (attribute) => (schema) => {
659
641
  if ("min" in attribute) {
660
642
  const min = toInteger(attribute.min);
643
+ if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
644
+ if (!attribute.required && "test" in schema && min) {
645
+ return schema.test(
646
+ "custom-min",
647
+ {
648
+ ...strapiAdmin.translatedErrors.min,
649
+ values: {
650
+ min: attribute.min
651
+ }
652
+ },
653
+ (value) => {
654
+ if (!value) {
655
+ return true;
656
+ }
657
+ if (Array.isArray(value) && value.length === 0) {
658
+ return true;
659
+ }
660
+ return value.length >= min;
661
+ }
662
+ );
663
+ }
664
+ }
661
665
  if ("min" in schema && min) {
662
666
  return schema.min(min, {
663
667
  ...strapiAdmin.translatedErrors.min,
@@ -784,7 +788,10 @@ const useDocument = (args, opts) => {
784
788
  isLoading: isLoadingDocument,
785
789
  isFetching: isFetchingDocument,
786
790
  error
787
- } = useGetDocumentQuery(args, opts);
791
+ } = useGetDocumentQuery(args, {
792
+ ...opts,
793
+ skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
794
+ });
788
795
  const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
789
796
  React__namespace.useEffect(() => {
790
797
  if (error) {
@@ -1205,7 +1212,6 @@ const useDocumentActions = () => {
1205
1212
  sourceId
1206
1213
  });
1207
1214
  if ("error" in res) {
1208
- toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1209
1215
  return { error: res.error };
1210
1216
  }
1211
1217
  toggleNotification({
@@ -1286,7 +1292,7 @@ const useDocumentActions = () => {
1286
1292
  };
1287
1293
  };
1288
1294
  const ProtectedHistoryPage = React.lazy(
1289
- () => Promise.resolve().then(() => require("./History-4NbOq2dX.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
1295
+ () => Promise.resolve().then(() => require("./History-DNQkXANT.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
1290
1296
  );
1291
1297
  const routes$1 = [
1292
1298
  {
@@ -1299,31 +1305,31 @@ const routes$1 = [
1299
1305
  }
1300
1306
  ];
1301
1307
  const ProtectedEditViewPage = React.lazy(
1302
- () => Promise.resolve().then(() => require("./EditViewPage-CTTDHKkQ.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
1308
+ () => Promise.resolve().then(() => require("./EditViewPage-C-ukDOB7.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
1303
1309
  );
1304
1310
  const ProtectedListViewPage = React.lazy(
1305
- () => Promise.resolve().then(() => require("./ListViewPage-CA3I75m5.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
1311
+ () => Promise.resolve().then(() => require("./ListViewPage-BsLiH2-2.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
1306
1312
  );
1307
1313
  const ProtectedListConfiguration = React.lazy(
1308
- () => Promise.resolve().then(() => require("./ListConfigurationPage-CpfstlYY.js")).then((mod) => ({
1314
+ () => Promise.resolve().then(() => require("./ListConfigurationPage-CUQxfpjT.js")).then((mod) => ({
1309
1315
  default: mod.ProtectedListConfiguration
1310
1316
  }))
1311
1317
  );
1312
1318
  const ProtectedEditConfigurationPage = React.lazy(
1313
- () => Promise.resolve().then(() => require("./EditConfigurationPage-CPVB8Uqc.js")).then((mod) => ({
1319
+ () => Promise.resolve().then(() => require("./EditConfigurationPage-Xp7lun0f.js")).then((mod) => ({
1314
1320
  default: mod.ProtectedEditConfigurationPage
1315
1321
  }))
1316
1322
  );
1317
1323
  const ProtectedComponentConfigurationPage = React.lazy(
1318
- () => Promise.resolve().then(() => require("./ComponentConfigurationPage-y_7iLdmB.js")).then((mod) => ({
1324
+ () => Promise.resolve().then(() => require("./ComponentConfigurationPage-5ukroXAh.js")).then((mod) => ({
1319
1325
  default: mod.ProtectedComponentConfigurationPage
1320
1326
  }))
1321
1327
  );
1322
1328
  const NoPermissions = React.lazy(
1323
- () => Promise.resolve().then(() => require("./NoPermissionsPage-CO2MK200.js")).then((mod) => ({ default: mod.NoPermissions }))
1329
+ () => Promise.resolve().then(() => require("./NoPermissionsPage-_lUqjGW3.js")).then((mod) => ({ default: mod.NoPermissions }))
1324
1330
  );
1325
1331
  const NoContentType = React.lazy(
1326
- () => Promise.resolve().then(() => require("./NoContentTypePage-Dldu-_Mx.js")).then((mod) => ({ default: mod.NoContentType }))
1332
+ () => Promise.resolve().then(() => require("./NoContentTypePage-BZ-PnGAf.js")).then((mod) => ({ default: mod.NoContentType }))
1327
1333
  );
1328
1334
  const CollectionTypePages = () => {
1329
1335
  const { collectionType } = reactRouterDom.useParams();
@@ -1450,7 +1456,7 @@ const DocumentActionButton = (action) => {
1450
1456
  DocumentActionConfirmDialog,
1451
1457
  {
1452
1458
  ...action.dialog,
1453
- variant: action.variant,
1459
+ variant: action.dialog?.variant ?? action.variant,
1454
1460
  isOpen: dialogId === action.id,
1455
1461
  onClose: handleClose
1456
1462
  }
@@ -1530,7 +1536,7 @@ const DocumentActionsMenu = ({
1530
1536
  display: "block",
1531
1537
  children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: [
1532
1538
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { color: convertActionVariantToColor(action.variant), gap: 2, tag: "span", children: [
1533
- action.icon,
1539
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { tag: "span", color: convertActionVariantToIconColor(action.variant), children: action.icon }),
1534
1540
  action.label
1535
1541
  ] }),
1536
1542
  action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsxRuntime.jsx(
@@ -1591,6 +1597,18 @@ const convertActionVariantToColor = (variant = "secondary") => {
1591
1597
  return "primary600";
1592
1598
  }
1593
1599
  };
1600
+ const convertActionVariantToIconColor = (variant = "secondary") => {
1601
+ switch (variant) {
1602
+ case "danger":
1603
+ return "danger600";
1604
+ case "secondary":
1605
+ return "neutral500";
1606
+ case "success":
1607
+ return "success600";
1608
+ default:
1609
+ return "primary600";
1610
+ }
1611
+ };
1594
1612
  const DocumentActionConfirmDialog = ({
1595
1613
  onClose,
1596
1614
  onCancel,
@@ -1613,22 +1631,20 @@ const DocumentActionConfirmDialog = ({
1613
1631
  }
1614
1632
  onClose();
1615
1633
  };
1616
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog, { isOpen, title, onClose: handleClose, children: [
1617
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.DialogBody, { children: content }),
1618
- /* @__PURE__ */ jsxRuntime.jsx(
1619
- designSystem.DialogFooter,
1620
- {
1621
- startAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", children: formatMessage({
1622
- id: "app.components.Button.cancel",
1623
- defaultMessage: "Cancel"
1624
- }) }),
1625
- endAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, children: formatMessage({
1626
- id: "app.components.Button.confirm",
1627
- defaultMessage: "Confirm"
1628
- }) })
1629
- }
1630
- )
1631
- ] });
1634
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
1635
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
1636
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
1637
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
1638
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
1639
+ id: "app.components.Button.cancel",
1640
+ defaultMessage: "Cancel"
1641
+ }) }) }),
1642
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, children: formatMessage({
1643
+ id: "app.components.Button.confirm",
1644
+ defaultMessage: "Confirm"
1645
+ }) })
1646
+ ] })
1647
+ ] }) });
1632
1648
  };
1633
1649
  const DocumentActionModal = ({
1634
1650
  isOpen,
@@ -1638,34 +1654,17 @@ const DocumentActionModal = ({
1638
1654
  content: Content,
1639
1655
  onModalClose
1640
1656
  }) => {
1641
- const id = React__namespace.useId();
1642
- if (!isOpen) {
1643
- return null;
1644
- }
1645
1657
  const handleClose = () => {
1646
1658
  if (onClose) {
1647
1659
  onClose();
1648
1660
  }
1649
1661
  onModalClose();
1650
1662
  };
1651
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
1652
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
1653
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalBody, { children: typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : Content }),
1654
- /* @__PURE__ */ jsxRuntime.jsx(
1655
- designSystem.Box,
1656
- {
1657
- paddingTop: 4,
1658
- paddingBottom: 4,
1659
- paddingLeft: 5,
1660
- paddingRight: 5,
1661
- borderWidth: "1px 0 0 0",
1662
- borderStyle: "solid",
1663
- borderColor: "neutral150",
1664
- background: "neutral100",
1665
- children: typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
1666
- }
1667
- )
1668
- ] });
1663
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
1664
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: title }) }),
1665
+ typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: Content }),
1666
+ typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
1667
+ ] }) });
1669
1668
  };
1670
1669
  const PublishAction$1 = ({
1671
1670
  activeTab,
@@ -1686,6 +1685,12 @@ const PublishAction$1 = ({
1686
1685
  ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
1687
1686
  );
1688
1687
  const { publish } = useDocumentActions();
1688
+ const [
1689
+ countDraftRelations,
1690
+ { isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
1691
+ ] = useLazyGetDraftRelationCountQuery();
1692
+ const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React__namespace.useState(0);
1693
+ const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React__namespace.useState(0);
1689
1694
  const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
1690
1695
  const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
1691
1696
  const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
@@ -1694,10 +1699,101 @@ const PublishAction$1 = ({
1694
1699
  const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
1695
1700
  const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
1696
1701
  const formValues = strapiAdmin.useForm("PublishAction", ({ values }) => values);
1702
+ React__namespace.useEffect(() => {
1703
+ if (isErrorDraftRelations) {
1704
+ toggleNotification({
1705
+ type: "danger",
1706
+ message: formatMessage({
1707
+ id: getTranslation("error.records.fetch-draft-relatons"),
1708
+ defaultMessage: "An error occurred while fetching draft relations on this document."
1709
+ })
1710
+ });
1711
+ }
1712
+ }, [isErrorDraftRelations, toggleNotification, formatMessage]);
1713
+ React__namespace.useEffect(() => {
1714
+ const localDraftRelations = /* @__PURE__ */ new Set();
1715
+ const extractDraftRelations = (data) => {
1716
+ const relations = data.connect || [];
1717
+ relations.forEach((relation) => {
1718
+ if (relation.status === "draft") {
1719
+ localDraftRelations.add(relation.id);
1720
+ }
1721
+ });
1722
+ };
1723
+ const traverseAndExtract = (data) => {
1724
+ Object.entries(data).forEach(([key, value]) => {
1725
+ if (key === "connect" && Array.isArray(value)) {
1726
+ extractDraftRelations({ connect: value });
1727
+ } else if (typeof value === "object" && value !== null) {
1728
+ traverseAndExtract(value);
1729
+ }
1730
+ });
1731
+ };
1732
+ if (!documentId || modified) {
1733
+ traverseAndExtract(formValues);
1734
+ setLocalCountOfDraftRelations(localDraftRelations.size);
1735
+ }
1736
+ }, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
1737
+ React__namespace.useEffect(() => {
1738
+ if (documentId) {
1739
+ const fetchDraftRelationsCount = async () => {
1740
+ const { data, error } = await countDraftRelations({
1741
+ collectionType,
1742
+ model,
1743
+ documentId,
1744
+ params
1745
+ });
1746
+ if (error) {
1747
+ throw error;
1748
+ }
1749
+ if (data) {
1750
+ setServerCountOfDraftRelations(data.data);
1751
+ }
1752
+ };
1753
+ fetchDraftRelationsCount();
1754
+ }
1755
+ }, [documentId, countDraftRelations, collectionType, model, params]);
1697
1756
  const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
1698
1757
  if (!schema?.options?.draftAndPublish) {
1699
1758
  return null;
1700
1759
  }
1760
+ const performPublish = async () => {
1761
+ setSubmitting(true);
1762
+ try {
1763
+ const { errors } = await validate();
1764
+ if (errors) {
1765
+ toggleNotification({
1766
+ type: "danger",
1767
+ message: formatMessage({
1768
+ id: "content-manager.validation.error",
1769
+ defaultMessage: "There are validation errors in your document. Please fix them before saving."
1770
+ })
1771
+ });
1772
+ return;
1773
+ }
1774
+ const res = await publish(
1775
+ {
1776
+ collectionType,
1777
+ model,
1778
+ documentId,
1779
+ params
1780
+ },
1781
+ formValues
1782
+ );
1783
+ if ("data" in res && collectionType !== SINGLE_TYPES) {
1784
+ navigate({
1785
+ pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1786
+ search: rawQuery
1787
+ });
1788
+ } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1789
+ setErrors(formatValidationErrors(res.error));
1790
+ }
1791
+ } finally {
1792
+ setSubmitting(false);
1793
+ }
1794
+ };
1795
+ const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
1796
+ const hasDraftRelations = totalDraftRelations > 0;
1701
1797
  return {
1702
1798
  /**
1703
1799
  * Disabled when:
@@ -1710,46 +1806,38 @@ const PublishAction$1 = ({
1710
1806
  * - the user doesn't have the permission to create a new document
1711
1807
  * - the user doesn't have the permission to update the document
1712
1808
  */
1713
- disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
1809
+ disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
1714
1810
  label: formatMessage({
1715
1811
  id: "app.utils.publish",
1716
1812
  defaultMessage: "Publish"
1717
1813
  }),
1718
1814
  onClick: async () => {
1719
- setSubmitting(true);
1720
- try {
1721
- const { errors } = await validate();
1722
- if (errors) {
1723
- toggleNotification({
1724
- type: "danger",
1725
- message: formatMessage({
1726
- id: "content-manager.validation.error",
1727
- defaultMessage: "There are validation errors in your document. Please fix them before saving."
1728
- })
1729
- });
1730
- return;
1731
- }
1732
- const res = await publish(
1733
- {
1734
- collectionType,
1735
- model,
1736
- documentId,
1737
- params
1738
- },
1739
- formValues
1740
- );
1741
- if ("data" in res && collectionType !== SINGLE_TYPES) {
1742
- navigate({
1743
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1744
- search: rawQuery
1745
- });
1746
- } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1747
- setErrors(formatValidationErrors(res.error));
1815
+ if (hasDraftRelations) {
1816
+ return;
1817
+ }
1818
+ await performPublish();
1819
+ },
1820
+ dialog: hasDraftRelations ? {
1821
+ type: "dialog",
1822
+ variant: "danger",
1823
+ footer: null,
1824
+ title: formatMessage({
1825
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
1826
+ defaultMessage: "Confirmation"
1827
+ }),
1828
+ content: formatMessage(
1829
+ {
1830
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
1831
+ defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
1832
+ },
1833
+ {
1834
+ count: totalDraftRelations
1748
1835
  }
1749
- } finally {
1750
- setSubmitting(false);
1836
+ ),
1837
+ onConfirm: async () => {
1838
+ await performPublish();
1751
1839
  }
1752
- }
1840
+ } : void 0
1753
1841
  };
1754
1842
  };
1755
1843
  PublishAction$1.type = "publish";
@@ -1817,10 +1905,13 @@ const UpdateAction = ({
1817
1905
  document
1818
1906
  );
1819
1907
  if ("data" in res) {
1820
- navigate({
1821
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1822
- search: rawQuery
1823
- });
1908
+ navigate(
1909
+ {
1910
+ pathname: `../${res.data.documentId}`,
1911
+ search: rawQuery
1912
+ },
1913
+ { relative: "path" }
1914
+ );
1824
1915
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1825
1916
  setErrors(formatValidationErrors(res.error));
1826
1917
  }
@@ -1848,10 +1939,13 @@ const UpdateAction = ({
1848
1939
  document
1849
1940
  );
1850
1941
  if ("data" in res && collectionType !== SINGLE_TYPES) {
1851
- navigate({
1852
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1853
- search: rawQuery
1854
- });
1942
+ navigate(
1943
+ {
1944
+ pathname: `../${res.data.documentId}`,
1945
+ search: rawQuery
1946
+ },
1947
+ { replace: true, relative: "path" }
1948
+ );
1855
1949
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1856
1950
  setErrors(formatValidationErrors(res.error));
1857
1951
  }
@@ -1883,10 +1977,8 @@ const UnpublishAction$1 = ({
1883
1977
  const { toggleNotification } = strapiAdmin.useNotification();
1884
1978
  const [shouldKeepDraft, setShouldKeepDraft] = React__namespace.useState(true);
1885
1979
  const isDocumentModified = document?.status === "modified";
1886
- const handleChange = (e) => {
1887
- if ("value" in e.target) {
1888
- setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
1889
- }
1980
+ const handleChange = (value) => {
1981
+ setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
1890
1982
  };
1891
1983
  if (!schema?.options?.draftAndPublish) {
1892
1984
  return null;
@@ -1936,40 +2028,24 @@ const UnpublishAction$1 = ({
1936
2028
  }) })
1937
2029
  ] }),
1938
2030
  /* @__PURE__ */ jsxRuntime.jsxs(
1939
- designSystem.Flex,
2031
+ designSystem.Radio.Group,
1940
2032
  {
1941
- onChange: handleChange,
1942
- direction: "column",
1943
- alignItems: "flex-start",
1944
- tag: "fieldset",
1945
- borderWidth: 0,
1946
- gap: 3,
2033
+ defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
2034
+ name: "discard-options",
2035
+ "aria-label": formatMessage({
2036
+ id: "content-manager.actions.unpublish.dialog.radio-label",
2037
+ defaultMessage: "Choose an option to unpublish the document."
2038
+ }),
2039
+ onValueChange: handleChange,
1947
2040
  children: [
1948
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "legend" }),
1949
- /* @__PURE__ */ jsxRuntime.jsx(
1950
- designSystem.Radio,
1951
- {
1952
- checked: shouldKeepDraft,
1953
- value: UNPUBLISH_DRAFT_OPTIONS.KEEP,
1954
- name: "discard-options",
1955
- children: formatMessage({
1956
- id: "content-manager.actions.unpublish.dialog.option.keep-draft",
1957
- defaultMessage: "Keep draft"
1958
- })
1959
- }
1960
- ),
1961
- /* @__PURE__ */ jsxRuntime.jsx(
1962
- designSystem.Radio,
1963
- {
1964
- checked: !shouldKeepDraft,
1965
- value: UNPUBLISH_DRAFT_OPTIONS.DISCARD,
1966
- name: "discard-options",
1967
- children: formatMessage({
1968
- id: "content-manager.actions.unpublish.dialog.option.replace-draft",
1969
- defaultMessage: "Replace draft"
1970
- })
1971
- }
1972
- )
2041
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
2042
+ id: "content-manager.actions.unpublish.dialog.option.keep-draft",
2043
+ defaultMessage: "Keep draft"
2044
+ }) }),
2045
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
2046
+ id: "content-manager.actions.unpublish.dialog.option.replace-draft",
2047
+ defaultMessage: "Replace draft"
2048
+ }) })
1973
2049
  ]
1974
2050
  }
1975
2051
  )
@@ -2115,23 +2191,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2115
2191
  id: "content-manager.containers.edit.title.new",
2116
2192
  defaultMessage: "Create an entry"
2117
2193
  }) : documentTitle;
2118
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 8, paddingBottom: 4, gap: 3, children: [
2194
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
2119
2195
  /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.BackButton, {}),
2120
- /* @__PURE__ */ jsxRuntime.jsxs(
2121
- designSystem.Flex,
2122
- {
2123
- width: "100%",
2124
- justifyContent: "space-between",
2125
- paddingTop: 1,
2126
- gap: "80px",
2127
- alignItems: "flex-start",
2128
- children: [
2129
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
2130
- /* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
2131
- ]
2132
- }
2133
- ),
2134
- status ? /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
2196
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
2197
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
2198
+ /* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
2199
+ ] }),
2200
+ status ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
2135
2201
  ] });
2136
2202
  };
2137
2203
  const HeaderToolbar = () => {
@@ -2822,30 +2888,23 @@ const ConfirmBulkActionDialog = ({
2822
2888
  endAction
2823
2889
  }) => {
2824
2890
  const { formatMessage } = reactIntl.useIntl();
2825
- return /* @__PURE__ */ jsxRuntime.jsxs(
2826
- designSystem.Dialog,
2827
- {
2828
- onClose: onToggleDialog,
2829
- title: formatMessage({
2830
- id: "app.components.ConfirmDialog.title",
2831
- defaultMessage: "Confirmation"
2832
- }),
2833
- isOpen,
2834
- children: [
2835
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.DialogBody, { icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, {}), children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: dialogBody }) }),
2836
- /* @__PURE__ */ jsxRuntime.jsx(
2837
- designSystem.DialogFooter,
2838
- {
2839
- startAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
2840
- id: "app.components.Button.cancel",
2841
- defaultMessage: "Cancel"
2842
- }) }),
2843
- endAction
2844
- }
2845
- )
2846
- ]
2847
- }
2848
- );
2891
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
2892
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
2893
+ id: "app.components.ConfirmDialog.title",
2894
+ defaultMessage: "Confirmation"
2895
+ }) }),
2896
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
2897
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
2898
+ dialogBody
2899
+ ] }) }),
2900
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
2901
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
2902
+ id: "app.components.Button.cancel",
2903
+ defaultMessage: "Cancel"
2904
+ }) }) }),
2905
+ endAction
2906
+ ] })
2907
+ ] }) });
2849
2908
  };
2850
2909
  const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
2851
2910
  const ConfirmDialogPublishAll = ({
@@ -2950,7 +3009,14 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
2950
3009
  )
2951
3010
  );
2952
3011
  } else {
2953
- messages.push(...formatErrorMessages(value, currentKey, formatMessage));
3012
+ messages.push(
3013
+ ...formatErrorMessages(
3014
+ // @ts-expect-error TODO: check why value is not compatible with FormErrors
3015
+ value,
3016
+ currentKey,
3017
+ formatMessage
3018
+ )
3019
+ );
2954
3020
  }
2955
3021
  } else {
2956
3022
  messages.push(
@@ -3187,7 +3253,7 @@ const SelectedEntriesModalContent = ({
3187
3253
  );
3188
3254
  };
3189
3255
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3190
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalBody, { children: [
3256
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
3191
3257
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
3192
3258
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsx(
3193
3259
  SelectedEntriesTableContent,
@@ -3199,27 +3265,24 @@ const SelectedEntriesModalContent = ({
3199
3265
  }
3200
3266
  ) })
3201
3267
  ] }),
3202
- /* @__PURE__ */ jsxRuntime.jsx(
3203
- designSystem.ModalFooter,
3204
- {
3205
- startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
3206
- id: "app.components.Button.cancel",
3207
- defaultMessage: "Cancel"
3208
- }) }),
3209
- endActions: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
3210
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
3211
- /* @__PURE__ */ jsxRuntime.jsx(
3212
- designSystem.Button,
3213
- {
3214
- onClick: toggleDialog,
3215
- disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
3216
- loading: isSubmittingForm,
3217
- children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
3218
- }
3219
- )
3220
- ] })
3221
- }
3222
- ),
3268
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
3269
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
3270
+ id: "app.components.Button.cancel",
3271
+ defaultMessage: "Cancel"
3272
+ }) }),
3273
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
3274
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
3275
+ /* @__PURE__ */ jsxRuntime.jsx(
3276
+ designSystem.Button,
3277
+ {
3278
+ onClick: toggleDialog,
3279
+ disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
3280
+ loading: isSubmittingForm,
3281
+ children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
3282
+ }
3283
+ )
3284
+ ] })
3285
+ ] }),
3223
3286
  /* @__PURE__ */ jsxRuntime.jsx(
3224
3287
  ConfirmDialogPublishAll,
3225
3288
  {
@@ -3284,143 +3347,10 @@ const BulkActionsRenderer = () => {
3284
3347
  documents: selectedRows
3285
3348
  },
3286
3349
  descriptions: plugins["content-manager"].apis.getBulkActions(),
3287
- children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsxRuntime.jsx(BulkActionAction, { ...action }, action.id))
3350
+ children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActionButton, { ...action }, action.id))
3288
3351
  }
3289
3352
  ) });
3290
3353
  };
3291
- const BulkActionAction = (action) => {
3292
- const [dialogId, setDialogId] = React__namespace.useState(null);
3293
- const { toggleNotification } = strapiAdmin.useNotification();
3294
- const handleClick = (action2) => (e) => {
3295
- const { onClick, dialog, id } = action2;
3296
- if (onClick) {
3297
- onClick(e);
3298
- }
3299
- if (dialog) {
3300
- switch (dialog.type) {
3301
- case "notification":
3302
- toggleNotification({
3303
- title: dialog.title,
3304
- message: dialog.content,
3305
- type: dialog.status,
3306
- timeout: dialog.timeout,
3307
- onClose: dialog.onClose
3308
- });
3309
- break;
3310
- case "dialog":
3311
- case "modal": {
3312
- e.preventDefault();
3313
- setDialogId(id);
3314
- }
3315
- }
3316
- }
3317
- };
3318
- const handleClose = () => {
3319
- setDialogId(null);
3320
- if (action.dialog?.type === "modal" && action.dialog?.onClose) {
3321
- action.dialog.onClose();
3322
- }
3323
- };
3324
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3325
- /* @__PURE__ */ jsxRuntime.jsx(
3326
- designSystem.Button,
3327
- {
3328
- disabled: action.disabled,
3329
- startIcon: action.icon,
3330
- variant: action.variant,
3331
- onClick: handleClick(action),
3332
- children: action.label
3333
- }
3334
- ),
3335
- action.dialog?.type === "dialog" ? /* @__PURE__ */ jsxRuntime.jsx(
3336
- BulkActionConfirmDialog,
3337
- {
3338
- ...action.dialog,
3339
- variant: action.variant,
3340
- isOpen: dialogId === action.id,
3341
- onClose: handleClose
3342
- }
3343
- ) : null,
3344
- action.dialog?.type === "modal" ? /* @__PURE__ */ jsxRuntime.jsx(
3345
- BulkActionModal,
3346
- {
3347
- ...action.dialog,
3348
- onModalClose: handleClose,
3349
- isOpen: dialogId === action.id
3350
- }
3351
- ) : null
3352
- ] });
3353
- };
3354
- const BulkActionConfirmDialog = ({
3355
- onClose,
3356
- onCancel,
3357
- onConfirm,
3358
- title,
3359
- content,
3360
- confirmButton,
3361
- isOpen,
3362
- variant = "secondary"
3363
- }) => {
3364
- const { formatMessage } = reactIntl.useIntl();
3365
- const handleClose = async () => {
3366
- if (onCancel) {
3367
- await onCancel();
3368
- }
3369
- onClose();
3370
- };
3371
- const handleConfirm = async () => {
3372
- if (onConfirm) {
3373
- await onConfirm();
3374
- }
3375
- onClose();
3376
- };
3377
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog, { isOpen, title, onClose: handleClose, children: [
3378
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.DialogBody, { icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, {}), children: content }),
3379
- /* @__PURE__ */ jsxRuntime.jsx(
3380
- designSystem.DialogFooter,
3381
- {
3382
- startAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", children: formatMessage({
3383
- id: "app.components.Button.cancel",
3384
- defaultMessage: "Cancel"
3385
- }) }),
3386
- endAction: /* @__PURE__ */ jsxRuntime.jsx(
3387
- designSystem.Button,
3388
- {
3389
- onClick: handleConfirm,
3390
- variant: variant === "danger-light" ? variant : "secondary",
3391
- startIcon: variant === "danger-light" ? /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}) : /* @__PURE__ */ jsxRuntime.jsx(Icons.Check, {}),
3392
- children: confirmButton ? confirmButton : formatMessage({
3393
- id: "app.components.Button.confirm",
3394
- defaultMessage: "Confirm"
3395
- })
3396
- }
3397
- )
3398
- }
3399
- )
3400
- ] });
3401
- };
3402
- const BulkActionModal = ({
3403
- isOpen,
3404
- title,
3405
- onClose,
3406
- content: Content,
3407
- onModalClose
3408
- }) => {
3409
- const id = React__namespace.useId();
3410
- if (!isOpen) {
3411
- return null;
3412
- }
3413
- const handleClose = () => {
3414
- if (onClose) {
3415
- onClose();
3416
- }
3417
- onModalClose();
3418
- };
3419
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
3420
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
3421
- /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose })
3422
- ] });
3423
- };
3424
3354
  const DeleteAction = ({ documents, model }) => {
3425
3355
  const { formatMessage } = reactIntl.useIntl();
3426
3356
  const { schema: contentType } = useDoc();
@@ -3453,6 +3383,7 @@ const DeleteAction = ({ documents, model }) => {
3453
3383
  defaultMessage: "Confirmation"
3454
3384
  }),
3455
3385
  content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3386
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3456
3387
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3457
3388
  id: "popUpWarning.bodyMessage.contentType.delete.all",
3458
3389
  defaultMessage: "Are you sure you want to delete these entries?"
@@ -3502,6 +3433,7 @@ const UnpublishAction = ({ documents, model }) => {
3502
3433
  defaultMessage: "Confirmation"
3503
3434
  }),
3504
3435
  content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3436
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3505
3437
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3506
3438
  id: "popUpWarning.bodyMessage.contentType.unpublish.all",
3507
3439
  defaultMessage: "Are you sure you want to unpublish these entries?"
@@ -3747,8 +3679,7 @@ class ContentManagerPlugin {
3747
3679
  documentActions = [
3748
3680
  ...DEFAULT_ACTIONS,
3749
3681
  ...DEFAULT_TABLE_ROW_ACTIONS,
3750
- ...DEFAULT_HEADER_ACTIONS,
3751
- HistoryAction
3682
+ ...DEFAULT_HEADER_ACTIONS
3752
3683
  ];
3753
3684
  editViewSidePanels = [ActionsPanel];
3754
3685
  headerActions = [];
@@ -3837,6 +3768,52 @@ const getPrintableType = (value) => {
3837
3768
  }
3838
3769
  return nativeType;
3839
3770
  };
3771
+ const HistoryAction = ({ model, document }) => {
3772
+ const { formatMessage } = reactIntl.useIntl();
3773
+ const [{ query }] = strapiAdmin.useQueryParams();
3774
+ const navigate = reactRouterDom.useNavigate();
3775
+ const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
3776
+ if (!window.strapi.features.isEnabled("cms-content-history")) {
3777
+ return null;
3778
+ }
3779
+ return {
3780
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
3781
+ label: formatMessage({
3782
+ id: "content-manager.history.document-action",
3783
+ defaultMessage: "Content History"
3784
+ }),
3785
+ onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
3786
+ disabled: (
3787
+ /**
3788
+ * The user is creating a new document.
3789
+ * It hasn't been saved yet, so there's no history to go to
3790
+ */
3791
+ !document || /**
3792
+ * The document has been created but the current dimension has never been saved.
3793
+ * For example, the user is creating a new locale in an existing document,
3794
+ * so there's no history for the document in that locale
3795
+ */
3796
+ !document.id || /**
3797
+ * History is only available for content types created by the user.
3798
+ * These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
3799
+ * which start with `admin::` or `plugin::`
3800
+ */
3801
+ !model.startsWith("api::")
3802
+ ),
3803
+ position: "header"
3804
+ };
3805
+ };
3806
+ HistoryAction.type = "history";
3807
+ const historyAdmin = {
3808
+ bootstrap(app) {
3809
+ const { addDocumentAction } = app.getPlugin("content-manager").apis;
3810
+ addDocumentAction((actions2) => {
3811
+ const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
3812
+ actions2.splice(indexOfDeleteAction, 0, HistoryAction);
3813
+ return actions2;
3814
+ });
3815
+ }
3816
+ };
3840
3817
  const initialState = {
3841
3818
  collectionTypeLinks: [],
3842
3819
  components: [],
@@ -3887,15 +3864,29 @@ const index = {
3887
3864
  defaultMessage: "Content Manager"
3888
3865
  },
3889
3866
  permissions: [],
3890
- Component: () => Promise.resolve().then(() => require("./layout-DEYBqgF1.js")).then((mod) => ({ default: mod.Layout })),
3891
3867
  position: 1
3892
3868
  });
3869
+ app.router.addRoute({
3870
+ path: "content-manager/*",
3871
+ lazy: async () => {
3872
+ const { Layout } = await Promise.resolve().then(() => require("./layout-Ci7qHlFb.js"));
3873
+ return {
3874
+ Component: Layout
3875
+ };
3876
+ },
3877
+ children: routes
3878
+ });
3893
3879
  app.registerPlugin(cm.config);
3894
3880
  },
3881
+ bootstrap(app) {
3882
+ if (typeof historyAdmin.bootstrap === "function") {
3883
+ historyAdmin.bootstrap(app);
3884
+ }
3885
+ },
3895
3886
  async registerTrads({ locales }) {
3896
3887
  const importedTrads = await Promise.all(
3897
3888
  locales.map((locale) => {
3898
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-fbKQxLGn.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-EUonQTon.js")), "./translations/eu.json": () => Promise.resolve().then(() => require("./eu-VDH-3ovk.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-B7kGGg3E.js")), "./translations/gu.json": () => Promise.resolve().then(() => require("./gu-BRmF601H.js")), "./translations/hi.json": () => Promise.resolve().then(() => require("./hi-CCJBptSq.js")), "./translations/hu.json": () => Promise.resolve().then(() => require("./hu-sNV_yLYy.js")), "./translations/id.json": () => Promise.resolve().then(() => require("./id-B5Ser98A.js")), "./translations/it.json": () => Promise.resolve().then(() => require("./it-DkBIs7vD.js")), "./translations/ja.json": () => Promise.resolve().then(() => require("./ja-CcFe8diO.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-woFZPmLk.js")), "./translations/ml.json": () => Promise.resolve().then(() => require("./ml-C2W8N8k1.js")), "./translations/ms.json": () => Promise.resolve().then(() => require("./ms-BuFotyP_.js")), "./translations/nl.json": () => Promise.resolve().then(() => require("./nl-bbEOHChV.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-uzwG-hk7.js")), "./translations/pt-BR.json": () => Promise.resolve().then(() => require("./pt-BR-BiOz37D9.js")), "./translations/pt.json": () => Promise.resolve().then(() => require("./pt-CeXQuq50.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BT3ybNny.js")), "./translations/sa.json": () => Promise.resolve().then(() => require("./sa-CcvkYInH.js")), "./translations/sk.json": () => Promise.resolve().then(() => require("./sk-CvY09Xjv.js")), "./translations/sv.json": () => Promise.resolve().then(() => require("./sv-MYDuzgvT.js")), "./translations/th.json": () => Promise.resolve().then(() => require("./th-D9_GfAjc.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-D9UH-O_R.js")), "./translations/uk.json": () => Promise.resolve().then(() => require("./uk-C8EiqJY7.js")), "./translations/vi.json": () => Promise.resolve().then(() => require("./vi-CJlYDheJ.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-9kOncHGw.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CQQfszqR.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
3889
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-uOUIxfcQ.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-EUonQTon.js")), "./translations/eu.json": () => Promise.resolve().then(() => require("./eu-VDH-3ovk.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-B7kGGg3E.js")), "./translations/gu.json": () => Promise.resolve().then(() => require("./gu-BRmF601H.js")), "./translations/hi.json": () => Promise.resolve().then(() => require("./hi-CCJBptSq.js")), "./translations/hu.json": () => Promise.resolve().then(() => require("./hu-sNV_yLYy.js")), "./translations/id.json": () => Promise.resolve().then(() => require("./id-B5Ser98A.js")), "./translations/it.json": () => Promise.resolve().then(() => require("./it-DkBIs7vD.js")), "./translations/ja.json": () => Promise.resolve().then(() => require("./ja-CcFe8diO.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-woFZPmLk.js")), "./translations/ml.json": () => Promise.resolve().then(() => require("./ml-C2W8N8k1.js")), "./translations/ms.json": () => Promise.resolve().then(() => require("./ms-BuFotyP_.js")), "./translations/nl.json": () => Promise.resolve().then(() => require("./nl-bbEOHChV.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-uzwG-hk7.js")), "./translations/pt-BR.json": () => Promise.resolve().then(() => require("./pt-BR-BiOz37D9.js")), "./translations/pt.json": () => Promise.resolve().then(() => require("./pt-CeXQuq50.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BT3ybNny.js")), "./translations/sa.json": () => Promise.resolve().then(() => require("./sa-CcvkYInH.js")), "./translations/sk.json": () => Promise.resolve().then(() => require("./sk-CvY09Xjv.js")), "./translations/sv.json": () => Promise.resolve().then(() => require("./sv-MYDuzgvT.js")), "./translations/th.json": () => Promise.resolve().then(() => require("./th-D9_GfAjc.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-D9UH-O_R.js")), "./translations/uk.json": () => Promise.resolve().then(() => require("./uk-C8EiqJY7.js")), "./translations/vi.json": () => Promise.resolve().then(() => require("./vi-CJlYDheJ.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-9kOncHGw.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CQQfszqR.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
3899
3890
  return {
3900
3891
  data: prefixPluginTranslations(data, PLUGIN_ID),
3901
3892
  locale
@@ -3939,7 +3930,6 @@ exports.getDisplayName = getDisplayName;
3939
3930
  exports.getMainField = getMainField;
3940
3931
  exports.getTranslation = getTranslation;
3941
3932
  exports.index = index;
3942
- exports.routes = routes;
3943
3933
  exports.setInitialData = setInitialData;
3944
3934
  exports.useContentTypeSchema = useContentTypeSchema;
3945
3935
  exports.useDoc = useDoc;
@@ -3953,4 +3943,4 @@ exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
3953
3943
  exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
3954
3944
  exports.useGetInitialDataQuery = useGetInitialDataQuery;
3955
3945
  exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
3956
- //# sourceMappingURL=index-BZoNZMXL.js.map
3946
+ //# sourceMappingURL=index-OerGjbAN.js.map