@strapi/content-manager 0.0.0-experimental.a53a4b1c8f7981a689823cdd719105671e1c6392 → 0.0.0-experimental.a9a5a36dd73072c19eadeff5f387e8286b2a4d22

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 (87) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-DmwmiFQy.mjs → ComponentConfigurationPage-B1bIXVuX.mjs} +3 -3
  3. package/dist/_chunks/{ComponentConfigurationPage-DmwmiFQy.mjs.map → ComponentConfigurationPage-B1bIXVuX.mjs.map} +1 -1
  4. package/dist/_chunks/{ComponentConfigurationPage-C-49MccQ.js → ComponentConfigurationPage-Bqgx7Mes.js} +3 -3
  5. package/dist/_chunks/{ComponentConfigurationPage-C-49MccQ.js.map → ComponentConfigurationPage-Bqgx7Mes.js.map} +1 -1
  6. package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js → EditConfigurationPage-BFEwvdMW.js} +3 -3
  7. package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js.map → EditConfigurationPage-BFEwvdMW.js.map} +1 -1
  8. package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs → EditConfigurationPage-ZO0vOO8q.mjs} +3 -3
  9. package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs.map → EditConfigurationPage-ZO0vOO8q.mjs.map} +1 -1
  10. package/dist/_chunks/{EditViewPage-zT3fBr4Y.js → EditViewPage-DA95Ha6J.js} +3 -3
  11. package/dist/_chunks/{EditViewPage-zT3fBr4Y.js.map → EditViewPage-DA95Ha6J.js.map} +1 -1
  12. package/dist/_chunks/{EditViewPage-CPj61RMh.mjs → EditViewPage-DlLEyUL6.mjs} +3 -3
  13. package/dist/_chunks/{EditViewPage-CPj61RMh.mjs.map → EditViewPage-DlLEyUL6.mjs.map} +1 -1
  14. package/dist/_chunks/{Field-Boxf9Ajp.js → Field-CnK8dO8N.js} +74 -49
  15. package/dist/_chunks/Field-CnK8dO8N.js.map +1 -0
  16. package/dist/_chunks/{Field-dha5VnIQ.mjs → Field-Dq7bDnuh.mjs} +74 -49
  17. package/dist/_chunks/Field-Dq7bDnuh.mjs.map +1 -0
  18. package/dist/_chunks/{Form-DHrru2AV.mjs → Form-B_JE0dbz.mjs} +2 -2
  19. package/dist/_chunks/{Form-DHrru2AV.mjs.map → Form-B_JE0dbz.mjs.map} +1 -1
  20. package/dist/_chunks/{Form-y5g1SRsh.js → Form-BpiR4piS.js} +2 -2
  21. package/dist/_chunks/{Form-y5g1SRsh.js.map → Form-BpiR4piS.js.map} +1 -1
  22. package/dist/_chunks/{History-Bru_KoeP.mjs → History-CBNGU7a-.mjs} +27 -12
  23. package/dist/_chunks/History-CBNGU7a-.mjs.map +1 -0
  24. package/dist/_chunks/{History-CqN6K7SX.js → History-DdIstl8b.js} +27 -12
  25. package/dist/_chunks/History-DdIstl8b.js.map +1 -0
  26. package/dist/_chunks/{ListConfigurationPage-D8wGABj0.mjs → ListConfigurationPage-5dr4qpue.mjs} +8 -6
  27. package/dist/_chunks/ListConfigurationPage-5dr4qpue.mjs.map +1 -0
  28. package/dist/_chunks/{ListConfigurationPage-R_p-SbHZ.js → ListConfigurationPage-DkKRparB.js} +8 -6
  29. package/dist/_chunks/ListConfigurationPage-DkKRparB.js.map +1 -0
  30. package/dist/_chunks/{ListViewPage-SID6TRb9.mjs → ListViewPage-DecLrYV6.mjs} +15 -6
  31. package/dist/_chunks/ListViewPage-DecLrYV6.mjs.map +1 -0
  32. package/dist/_chunks/{ListViewPage-pEw_zug9.js → ListViewPage-wE0lXqoD.js} +15 -6
  33. package/dist/_chunks/ListViewPage-wE0lXqoD.js.map +1 -0
  34. package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs → NoContentTypePage-CiIcfYsd.mjs} +2 -2
  35. package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs.map → NoContentTypePage-CiIcfYsd.mjs.map} +1 -1
  36. package/dist/_chunks/{NoContentTypePage-C5dcQojD.js → NoContentTypePage-DEKR6tf9.js} +2 -2
  37. package/dist/_chunks/{NoContentTypePage-C5dcQojD.js.map → NoContentTypePage-DEKR6tf9.js.map} +1 -1
  38. package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs → NoPermissionsPage-CM5UD8ee.mjs} +2 -2
  39. package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs.map → NoPermissionsPage-CM5UD8ee.mjs.map} +1 -1
  40. package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js → NoPermissionsPage-DmNfF2Bb.js} +2 -2
  41. package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js.map → NoPermissionsPage-DmNfF2Bb.js.map} +1 -1
  42. package/dist/_chunks/{Relations-B9Crnhnn.mjs → Relations-Dqz0C1fz.mjs} +3 -3
  43. package/dist/_chunks/Relations-Dqz0C1fz.mjs.map +1 -0
  44. package/dist/_chunks/{Relations-DjTQ5kGB.js → Relations-L0xYRoSQ.js} +3 -3
  45. package/dist/_chunks/Relations-L0xYRoSQ.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-DJXJw9V5.mjs → index-BSn97i8U.mjs} +246 -118
  51. package/dist/_chunks/index-BSn97i8U.mjs.map +1 -0
  52. package/dist/_chunks/{index-DVPWZkbS.js → index-DyvUPg1a.js} +244 -116
  53. package/dist/_chunks/index-DyvUPg1a.js.map +1 -0
  54. package/dist/_chunks/{layout-Bau7ZfLV.mjs → layout-DPaHUusj.mjs} +6 -6
  55. package/dist/_chunks/layout-DPaHUusj.mjs.map +1 -0
  56. package/dist/_chunks/{layout-Dm6fbiQj.js → layout-TPqF2oJ5.js} +6 -6
  57. package/dist/_chunks/layout-TPqF2oJ5.js.map +1 -0
  58. package/dist/_chunks/{relations-CKnpRgrN.js → relations-BWYS9gkn.js} +2 -2
  59. package/dist/_chunks/{relations-CKnpRgrN.js.map → relations-BWYS9gkn.js.map} +1 -1
  60. package/dist/_chunks/{relations-BH_kBSJ0.mjs → relations-Ck7-ecDT.mjs} +2 -2
  61. package/dist/_chunks/{relations-BH_kBSJ0.mjs.map → relations-Ck7-ecDT.mjs.map} +1 -1
  62. package/dist/admin/index.js +1 -1
  63. package/dist/admin/index.mjs +1 -1
  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 +1 -0
  67. package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
  68. package/dist/server/index.js +4 -0
  69. package/dist/server/index.js.map +1 -1
  70. package/dist/server/index.mjs +4 -0
  71. package/dist/server/index.mjs.map +1 -1
  72. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  73. package/package.json +6 -6
  74. package/dist/_chunks/Field-Boxf9Ajp.js.map +0 -1
  75. package/dist/_chunks/Field-dha5VnIQ.mjs.map +0 -1
  76. package/dist/_chunks/History-Bru_KoeP.mjs.map +0 -1
  77. package/dist/_chunks/History-CqN6K7SX.js.map +0 -1
  78. package/dist/_chunks/ListConfigurationPage-D8wGABj0.mjs.map +0 -1
  79. package/dist/_chunks/ListConfigurationPage-R_p-SbHZ.js.map +0 -1
  80. package/dist/_chunks/ListViewPage-SID6TRb9.mjs.map +0 -1
  81. package/dist/_chunks/ListViewPage-pEw_zug9.js.map +0 -1
  82. package/dist/_chunks/Relations-B9Crnhnn.mjs.map +0 -1
  83. package/dist/_chunks/Relations-DjTQ5kGB.js.map +0 -1
  84. package/dist/_chunks/index-DJXJw9V5.mjs.map +0 -1
  85. package/dist/_chunks/index-DVPWZkbS.js.map +0 -1
  86. package/dist/_chunks/layout-Bau7ZfLV.mjs.map +0 -1
  87. package/dist/_chunks/layout-Dm6fbiQj.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";
@@ -621,11 +585,11 @@ const createAttributeSchema = (attribute) => {
621
585
  }
622
586
  };
623
587
  const addRequiredValidation = (attribute) => (schema) => {
624
- if (attribute.required) {
625
- return schema.required({
626
- id: strapiAdmin.translatedErrors.required.id,
627
- defaultMessage: "This field is required."
628
- });
588
+ if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
589
+ return schema.min(1, strapiAdmin.translatedErrors.required);
590
+ }
591
+ if (attribute.required && attribute.type !== "relation") {
592
+ return schema.required(strapiAdmin.translatedErrors.required);
629
593
  }
630
594
  return schema?.nullable ? schema.nullable() : (
631
595
  // In some cases '.nullable' will not be available on the schema.
@@ -659,6 +623,28 @@ const addMaxLengthValidation = (attribute) => (schema) => {
659
623
  const addMinValidation = (attribute) => (schema) => {
660
624
  if ("min" in attribute) {
661
625
  const min = toInteger(attribute.min);
626
+ if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
627
+ if (!attribute.required && "test" in schema && min) {
628
+ return schema.test(
629
+ "custom-min",
630
+ {
631
+ ...strapiAdmin.translatedErrors.min,
632
+ values: {
633
+ min: attribute.min
634
+ }
635
+ },
636
+ (value) => {
637
+ if (!value) {
638
+ return true;
639
+ }
640
+ if (Array.isArray(value) && value.length === 0) {
641
+ return true;
642
+ }
643
+ return value.length >= min;
644
+ }
645
+ );
646
+ }
647
+ }
662
648
  if ("min" in schema && min) {
663
649
  return schema.min(min, {
664
650
  ...strapiAdmin.translatedErrors.min,
@@ -785,7 +771,10 @@ const useDocument = (args, opts) => {
785
771
  isLoading: isLoadingDocument,
786
772
  isFetching: isFetchingDocument,
787
773
  error
788
- } = useGetDocumentQuery(args, opts);
774
+ } = useGetDocumentQuery(args, {
775
+ ...opts,
776
+ skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
777
+ });
789
778
  const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
790
779
  React__namespace.useEffect(() => {
791
780
  if (error) {
@@ -1287,7 +1276,7 @@ const useDocumentActions = () => {
1287
1276
  };
1288
1277
  };
1289
1278
  const ProtectedHistoryPage = React.lazy(
1290
- () => Promise.resolve().then(() => require("./History-CqN6K7SX.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
1279
+ () => Promise.resolve().then(() => require("./History-DdIstl8b.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
1291
1280
  );
1292
1281
  const routes$1 = [
1293
1282
  {
@@ -1300,31 +1289,31 @@ const routes$1 = [
1300
1289
  }
1301
1290
  ];
1302
1291
  const ProtectedEditViewPage = React.lazy(
1303
- () => Promise.resolve().then(() => require("./EditViewPage-zT3fBr4Y.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
1292
+ () => Promise.resolve().then(() => require("./EditViewPage-DA95Ha6J.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
1304
1293
  );
1305
1294
  const ProtectedListViewPage = React.lazy(
1306
- () => Promise.resolve().then(() => require("./ListViewPage-pEw_zug9.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
1295
+ () => Promise.resolve().then(() => require("./ListViewPage-wE0lXqoD.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
1307
1296
  );
1308
1297
  const ProtectedListConfiguration = React.lazy(
1309
- () => Promise.resolve().then(() => require("./ListConfigurationPage-R_p-SbHZ.js")).then((mod) => ({
1298
+ () => Promise.resolve().then(() => require("./ListConfigurationPage-DkKRparB.js")).then((mod) => ({
1310
1299
  default: mod.ProtectedListConfiguration
1311
1300
  }))
1312
1301
  );
1313
1302
  const ProtectedEditConfigurationPage = React.lazy(
1314
- () => Promise.resolve().then(() => require("./EditConfigurationPage-DjFJw56M.js")).then((mod) => ({
1303
+ () => Promise.resolve().then(() => require("./EditConfigurationPage-BFEwvdMW.js")).then((mod) => ({
1315
1304
  default: mod.ProtectedEditConfigurationPage
1316
1305
  }))
1317
1306
  );
1318
1307
  const ProtectedComponentConfigurationPage = React.lazy(
1319
- () => Promise.resolve().then(() => require("./ComponentConfigurationPage-C-49MccQ.js")).then((mod) => ({
1308
+ () => Promise.resolve().then(() => require("./ComponentConfigurationPage-Bqgx7Mes.js")).then((mod) => ({
1320
1309
  default: mod.ProtectedComponentConfigurationPage
1321
1310
  }))
1322
1311
  );
1323
1312
  const NoPermissions = React.lazy(
1324
- () => Promise.resolve().then(() => require("./NoPermissionsPage-BtPrImPP.js")).then((mod) => ({ default: mod.NoPermissions }))
1313
+ () => Promise.resolve().then(() => require("./NoPermissionsPage-DmNfF2Bb.js")).then((mod) => ({ default: mod.NoPermissions }))
1325
1314
  );
1326
1315
  const NoContentType = React.lazy(
1327
- () => Promise.resolve().then(() => require("./NoContentTypePage-C5dcQojD.js")).then((mod) => ({ default: mod.NoContentType }))
1316
+ () => Promise.resolve().then(() => require("./NoContentTypePage-DEKR6tf9.js")).then((mod) => ({ default: mod.NoContentType }))
1328
1317
  );
1329
1318
  const CollectionTypePages = () => {
1330
1319
  const { collectionType } = reactRouterDom.useParams();
@@ -1451,7 +1440,7 @@ const DocumentActionButton = (action) => {
1451
1440
  DocumentActionConfirmDialog,
1452
1441
  {
1453
1442
  ...action.dialog,
1454
- variant: action.variant,
1443
+ variant: action.dialog?.variant ?? action.variant,
1455
1444
  isOpen: dialogId === action.id,
1456
1445
  onClose: handleClose
1457
1446
  }
@@ -1657,8 +1646,8 @@ const DocumentActionModal = ({
1657
1646
  };
1658
1647
  return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
1659
1648
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: title }) }),
1660
- typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: Content }),
1661
- typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
1649
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : Content }),
1650
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Footer, { children: typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer })
1662
1651
  ] }) });
1663
1652
  };
1664
1653
  const PublishAction$1 = ({
@@ -1680,6 +1669,12 @@ const PublishAction$1 = ({
1680
1669
  ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
1681
1670
  );
1682
1671
  const { publish } = useDocumentActions();
1672
+ const [
1673
+ countDraftRelations,
1674
+ { isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
1675
+ ] = useLazyGetDraftRelationCountQuery();
1676
+ const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React__namespace.useState(0);
1677
+ const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React__namespace.useState(0);
1683
1678
  const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
1684
1679
  const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
1685
1680
  const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
@@ -1688,10 +1683,101 @@ const PublishAction$1 = ({
1688
1683
  const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
1689
1684
  const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
1690
1685
  const formValues = strapiAdmin.useForm("PublishAction", ({ values }) => values);
1686
+ React__namespace.useEffect(() => {
1687
+ if (isErrorDraftRelations) {
1688
+ toggleNotification({
1689
+ type: "danger",
1690
+ message: formatMessage({
1691
+ id: getTranslation("error.records.fetch-draft-relatons"),
1692
+ defaultMessage: "An error occurred while fetching draft relations on this document."
1693
+ })
1694
+ });
1695
+ }
1696
+ }, [isErrorDraftRelations, toggleNotification, formatMessage]);
1697
+ React__namespace.useEffect(() => {
1698
+ const localDraftRelations = /* @__PURE__ */ new Set();
1699
+ const extractDraftRelations = (data) => {
1700
+ const relations = data.connect || [];
1701
+ relations.forEach((relation) => {
1702
+ if (relation.status === "draft") {
1703
+ localDraftRelations.add(relation.id);
1704
+ }
1705
+ });
1706
+ };
1707
+ const traverseAndExtract = (data) => {
1708
+ Object.entries(data).forEach(([key, value]) => {
1709
+ if (key === "connect" && Array.isArray(value)) {
1710
+ extractDraftRelations({ connect: value });
1711
+ } else if (typeof value === "object" && value !== null) {
1712
+ traverseAndExtract(value);
1713
+ }
1714
+ });
1715
+ };
1716
+ if (!documentId || modified) {
1717
+ traverseAndExtract(formValues);
1718
+ setLocalCountOfDraftRelations(localDraftRelations.size);
1719
+ }
1720
+ }, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
1721
+ React__namespace.useEffect(() => {
1722
+ if (documentId) {
1723
+ const fetchDraftRelationsCount = async () => {
1724
+ const { data, error } = await countDraftRelations({
1725
+ collectionType,
1726
+ model,
1727
+ documentId,
1728
+ params
1729
+ });
1730
+ if (error) {
1731
+ throw error;
1732
+ }
1733
+ if (data) {
1734
+ setServerCountOfDraftRelations(data.data);
1735
+ }
1736
+ };
1737
+ fetchDraftRelationsCount();
1738
+ }
1739
+ }, [documentId, countDraftRelations, collectionType, model, params]);
1691
1740
  const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
1692
1741
  if (!schema?.options?.draftAndPublish) {
1693
1742
  return null;
1694
1743
  }
1744
+ const performPublish = async () => {
1745
+ setSubmitting(true);
1746
+ try {
1747
+ const { errors } = await validate();
1748
+ if (errors) {
1749
+ toggleNotification({
1750
+ type: "danger",
1751
+ message: formatMessage({
1752
+ id: "content-manager.validation.error",
1753
+ defaultMessage: "There are validation errors in your document. Please fix them before saving."
1754
+ })
1755
+ });
1756
+ return;
1757
+ }
1758
+ const res = await publish(
1759
+ {
1760
+ collectionType,
1761
+ model,
1762
+ documentId,
1763
+ params
1764
+ },
1765
+ formValues
1766
+ );
1767
+ if ("data" in res && collectionType !== SINGLE_TYPES) {
1768
+ navigate({
1769
+ pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1770
+ search: rawQuery
1771
+ });
1772
+ } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1773
+ setErrors(formatValidationErrors(res.error));
1774
+ }
1775
+ } finally {
1776
+ setSubmitting(false);
1777
+ }
1778
+ };
1779
+ const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
1780
+ const hasDraftRelations = totalDraftRelations > 0;
1695
1781
  return {
1696
1782
  /**
1697
1783
  * Disabled when:
@@ -1704,46 +1790,38 @@ const PublishAction$1 = ({
1704
1790
  * - the user doesn't have the permission to create a new document
1705
1791
  * - the user doesn't have the permission to update the document
1706
1792
  */
1707
- disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
1793
+ disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
1708
1794
  label: formatMessage({
1709
1795
  id: "app.utils.publish",
1710
1796
  defaultMessage: "Publish"
1711
1797
  }),
1712
1798
  onClick: async () => {
1713
- setSubmitting(true);
1714
- try {
1715
- const { errors } = await validate();
1716
- if (errors) {
1717
- toggleNotification({
1718
- type: "danger",
1719
- message: formatMessage({
1720
- id: "content-manager.validation.error",
1721
- defaultMessage: "There are validation errors in your document. Please fix them before saving."
1722
- })
1723
- });
1724
- return;
1725
- }
1726
- const res = await publish(
1727
- {
1728
- collectionType,
1729
- model,
1730
- documentId,
1731
- params
1732
- },
1733
- formValues
1734
- );
1735
- if ("data" in res && collectionType !== SINGLE_TYPES) {
1736
- navigate({
1737
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1738
- search: rawQuery
1739
- });
1740
- } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1741
- setErrors(formatValidationErrors(res.error));
1799
+ if (hasDraftRelations) {
1800
+ return;
1801
+ }
1802
+ await performPublish();
1803
+ },
1804
+ dialog: hasDraftRelations ? {
1805
+ type: "dialog",
1806
+ variant: "danger",
1807
+ footer: null,
1808
+ title: formatMessage({
1809
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
1810
+ defaultMessage: "Confirmation"
1811
+ }),
1812
+ content: formatMessage(
1813
+ {
1814
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
1815
+ defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
1816
+ },
1817
+ {
1818
+ count: totalDraftRelations
1742
1819
  }
1743
- } finally {
1744
- setSubmitting(false);
1820
+ ),
1821
+ onConfirm: async () => {
1822
+ await performPublish();
1745
1823
  }
1746
- }
1824
+ } : void 0
1747
1825
  };
1748
1826
  };
1749
1827
  PublishAction$1.type = "publish";
@@ -1842,10 +1920,13 @@ const UpdateAction = ({
1842
1920
  document
1843
1921
  );
1844
1922
  if ("data" in res && collectionType !== SINGLE_TYPES) {
1845
- navigate({
1846
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1847
- search: rawQuery
1848
- });
1923
+ navigate(
1924
+ {
1925
+ pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1926
+ search: rawQuery
1927
+ },
1928
+ { replace: true }
1929
+ );
1849
1930
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1850
1931
  setErrors(formatValidationErrors(res.error));
1851
1932
  }
@@ -2091,23 +2172,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2091
2172
  id: "content-manager.containers.edit.title.new",
2092
2173
  defaultMessage: "Create an entry"
2093
2174
  }) : documentTitle;
2094
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 8, paddingBottom: 4, gap: 3, children: [
2175
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
2095
2176
  /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.BackButton, {}),
2096
- /* @__PURE__ */ jsxRuntime.jsxs(
2097
- designSystem.Flex,
2098
- {
2099
- width: "100%",
2100
- justifyContent: "space-between",
2101
- paddingTop: 1,
2102
- gap: "80px",
2103
- alignItems: "flex-start",
2104
- children: [
2105
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
2106
- /* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
2107
- ]
2108
- }
2109
- ),
2110
- status ? /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
2177
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
2178
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
2179
+ /* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
2180
+ ] }),
2181
+ status ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
2111
2182
  ] });
2112
2183
  };
2113
2184
  const HeaderToolbar = () => {
@@ -2798,7 +2869,7 @@ const ConfirmBulkActionDialog = ({
2798
2869
  endAction
2799
2870
  }) => {
2800
2871
  const { formatMessage } = reactIntl.useIntl();
2801
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { onOpenChange: onToggleDialog, open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
2872
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
2802
2873
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
2803
2874
  id: "app.components.ConfirmDialog.title",
2804
2875
  defaultMessage: "Confirmation"
@@ -2919,7 +2990,14 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
2919
2990
  )
2920
2991
  );
2921
2992
  } else {
2922
- messages.push(...formatErrorMessages(value, currentKey, formatMessage));
2993
+ messages.push(
2994
+ ...formatErrorMessages(
2995
+ // @ts-expect-error TODO: check why value is not compatible with FormErrors
2996
+ value,
2997
+ currentKey,
2998
+ formatMessage
2999
+ )
3000
+ );
2923
3001
  }
2924
3002
  } else {
2925
3003
  messages.push(
@@ -3582,8 +3660,7 @@ class ContentManagerPlugin {
3582
3660
  documentActions = [
3583
3661
  ...DEFAULT_ACTIONS,
3584
3662
  ...DEFAULT_TABLE_ROW_ACTIONS,
3585
- ...DEFAULT_HEADER_ACTIONS,
3586
- HistoryAction
3663
+ ...DEFAULT_HEADER_ACTIONS
3587
3664
  ];
3588
3665
  editViewSidePanels = [ActionsPanel];
3589
3666
  headerActions = [];
@@ -3672,6 +3749,52 @@ const getPrintableType = (value) => {
3672
3749
  }
3673
3750
  return nativeType;
3674
3751
  };
3752
+ const HistoryAction = ({ model, document }) => {
3753
+ const { formatMessage } = reactIntl.useIntl();
3754
+ const [{ query }] = strapiAdmin.useQueryParams();
3755
+ const navigate = reactRouterDom.useNavigate();
3756
+ const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
3757
+ if (!window.strapi.features.isEnabled("cms-content-history")) {
3758
+ return null;
3759
+ }
3760
+ return {
3761
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
3762
+ label: formatMessage({
3763
+ id: "content-manager.history.document-action",
3764
+ defaultMessage: "Content History"
3765
+ }),
3766
+ onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
3767
+ disabled: (
3768
+ /**
3769
+ * The user is creating a new document.
3770
+ * It hasn't been saved yet, so there's no history to go to
3771
+ */
3772
+ !document || /**
3773
+ * The document has been created but the current dimension has never been saved.
3774
+ * For example, the user is creating a new locale in an existing document,
3775
+ * so there's no history for the document in that locale
3776
+ */
3777
+ !document.id || /**
3778
+ * History is only available for content types created by the user.
3779
+ * These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
3780
+ * which start with `admin::` or `plugin::`
3781
+ */
3782
+ !model.startsWith("api::")
3783
+ ),
3784
+ position: "header"
3785
+ };
3786
+ };
3787
+ HistoryAction.type = "history";
3788
+ const historyAdmin = {
3789
+ bootstrap(app) {
3790
+ const { addDocumentAction } = app.getPlugin("content-manager").apis;
3791
+ addDocumentAction((actions2) => {
3792
+ const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
3793
+ actions2.splice(indexOfDeleteAction, 0, HistoryAction);
3794
+ return actions2;
3795
+ });
3796
+ }
3797
+ };
3675
3798
  const initialState = {
3676
3799
  collectionTypeLinks: [],
3677
3800
  components: [],
@@ -3727,7 +3850,7 @@ const index = {
3727
3850
  app.router.addRoute({
3728
3851
  path: "content-manager/*",
3729
3852
  lazy: async () => {
3730
- const { Layout } = await Promise.resolve().then(() => require("./layout-Dm6fbiQj.js"));
3853
+ const { Layout } = await Promise.resolve().then(() => require("./layout-TPqF2oJ5.js"));
3731
3854
  return {
3732
3855
  Component: Layout
3733
3856
  };
@@ -3736,10 +3859,15 @@ const index = {
3736
3859
  });
3737
3860
  app.registerPlugin(cm.config);
3738
3861
  },
3862
+ bootstrap(app) {
3863
+ if (typeof historyAdmin.bootstrap === "function") {
3864
+ historyAdmin.bootstrap(app);
3865
+ }
3866
+ },
3739
3867
  async registerTrads({ locales }) {
3740
3868
  const importedTrads = await Promise.all(
3741
3869
  locales.map((locale) => {
3742
- 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 }) => {
3870
+ 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 }) => {
3743
3871
  return {
3744
3872
  data: prefixPluginTranslations(data, PLUGIN_ID),
3745
3873
  locale
@@ -3796,4 +3924,4 @@ exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
3796
3924
  exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
3797
3925
  exports.useGetInitialDataQuery = useGetInitialDataQuery;
3798
3926
  exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
3799
- //# sourceMappingURL=index-DVPWZkbS.js.map
3927
+ //# sourceMappingURL=index-DyvUPg1a.js.map