@strapi/content-manager 5.0.0-beta.9 → 5.0.0-rc.1

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 (97) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-y_7iLdmB.js → ComponentConfigurationPage-D8RyVgJC.js} +3 -3
  3. package/dist/_chunks/{ComponentConfigurationPage-y_7iLdmB.js.map → ComponentConfigurationPage-D8RyVgJC.js.map} +1 -1
  4. package/dist/_chunks/{ComponentConfigurationPage-BMajAl1u.mjs → ComponentConfigurationPage-DLuACgva.mjs} +3 -3
  5. package/dist/_chunks/{ComponentConfigurationPage-BMajAl1u.mjs.map → ComponentConfigurationPage-DLuACgva.mjs.map} +1 -1
  6. package/dist/_chunks/{EditConfigurationPage-CcOoD26O.mjs → EditConfigurationPage-CuCAsHWR.mjs} +3 -3
  7. package/dist/_chunks/{EditConfigurationPage-CcOoD26O.mjs.map → EditConfigurationPage-CuCAsHWR.mjs.map} +1 -1
  8. package/dist/_chunks/{EditConfigurationPage-CPVB8Uqc.js → EditConfigurationPage-fOm5AebB.js} +3 -3
  9. package/dist/_chunks/{EditConfigurationPage-CPVB8Uqc.js.map → EditConfigurationPage-fOm5AebB.js.map} +1 -1
  10. package/dist/_chunks/{EditViewPage-DWb0DE7R.mjs → EditViewPage-BqDlT9w0.mjs} +46 -46
  11. package/dist/_chunks/EditViewPage-BqDlT9w0.mjs.map +1 -0
  12. package/dist/_chunks/{EditViewPage-CTTDHKkQ.js → EditViewPage-Or0fpTwh.js} +45 -45
  13. package/dist/_chunks/EditViewPage-Or0fpTwh.js.map +1 -0
  14. package/dist/_chunks/{Field-C5Z1Ivdv.js → Field-Bix2HU_O.js} +421 -141
  15. package/dist/_chunks/Field-Bix2HU_O.js.map +1 -0
  16. package/dist/_chunks/{Field-DnStdvQw.mjs → Field-OfBJ6x59.mjs} +422 -142
  17. package/dist/_chunks/Field-OfBJ6x59.mjs.map +1 -0
  18. package/dist/_chunks/{Form-B81OtW-k.js → Form-Bv5ABnqE.js} +25 -26
  19. package/dist/_chunks/Form-Bv5ABnqE.js.map +1 -0
  20. package/dist/_chunks/{Form-DqGgE55Q.mjs → Form-DyMXqj_v.mjs} +27 -28
  21. package/dist/_chunks/Form-DyMXqj_v.mjs.map +1 -0
  22. package/dist/_chunks/{History-4NbOq2dX.js → History-fnln26gA.js} +51 -28
  23. package/dist/_chunks/History-fnln26gA.js.map +1 -0
  24. package/dist/_chunks/{History-DS6-HCYX.mjs → History-rvLnluF0.mjs} +52 -29
  25. package/dist/_chunks/History-rvLnluF0.mjs.map +1 -0
  26. package/dist/_chunks/{ListConfigurationPage-CpfstlYY.js → ListConfigurationPage-BtCBP_L_.js} +48 -47
  27. package/dist/_chunks/ListConfigurationPage-BtCBP_L_.js.map +1 -0
  28. package/dist/_chunks/{ListConfigurationPage-DQJJltko.mjs → ListConfigurationPage-DdKfJRdq.mjs} +49 -49
  29. package/dist/_chunks/ListConfigurationPage-DdKfJRdq.mjs.map +1 -0
  30. package/dist/_chunks/{ListViewPage-nQrOQuVo.mjs → ListViewPage-B8cPO1bK.mjs} +60 -68
  31. package/dist/_chunks/ListViewPage-B8cPO1bK.mjs.map +1 -0
  32. package/dist/_chunks/{ListViewPage-CA3I75m5.js → ListViewPage-CGZWD2qn.js} +59 -67
  33. package/dist/_chunks/ListViewPage-CGZWD2qn.js.map +1 -0
  34. package/dist/_chunks/{NoContentTypePage-DbnHE22g.mjs → NoContentTypePage-CVqYTeML.mjs} +2 -2
  35. package/dist/_chunks/{NoContentTypePage-DbnHE22g.mjs.map → NoContentTypePage-CVqYTeML.mjs.map} +1 -1
  36. package/dist/_chunks/{NoContentTypePage-Dldu-_Mx.js → NoContentTypePage-oJxX0WCQ.js} +2 -2
  37. package/dist/_chunks/{NoContentTypePage-Dldu-_Mx.js.map → NoContentTypePage-oJxX0WCQ.js.map} +1 -1
  38. package/dist/_chunks/{NoPermissionsPage-CO2MK200.js → NoPermissionsPage-BB11jqM_.js} +2 -2
  39. package/dist/_chunks/{NoPermissionsPage-CO2MK200.js.map → NoPermissionsPage-BB11jqM_.js.map} +1 -1
  40. package/dist/_chunks/{NoPermissionsPage-fOIkQM0v.mjs → NoPermissionsPage-mlXqh8p6.mjs} +2 -2
  41. package/dist/_chunks/{NoPermissionsPage-fOIkQM0v.mjs.map → NoPermissionsPage-mlXqh8p6.mjs.map} +1 -1
  42. package/dist/_chunks/{Relations-DG2jnOcr.js → Relations-6xIumgbN.js} +3 -3
  43. package/dist/_chunks/Relations-6xIumgbN.js.map +1 -0
  44. package/dist/_chunks/{Relations-BDRl99Ux.mjs → Relations-DWscdjKO.mjs} +3 -3
  45. package/dist/_chunks/Relations-DWscdjKO.mjs.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-BzUwgKUj.js} +347 -373
  51. package/dist/_chunks/index-BzUwgKUj.js.map +1 -0
  52. package/dist/_chunks/{index-Drt2DN7v.mjs → index-JSJrqmB9.mjs} +362 -388
  53. package/dist/_chunks/index-JSJrqmB9.mjs.map +1 -0
  54. package/dist/_chunks/{layout-BzAbmoO6.mjs → layout-Dewoec1b.mjs} +8 -8
  55. package/dist/_chunks/layout-Dewoec1b.mjs.map +1 -0
  56. package/dist/_chunks/{layout-DEYBqgF1.js → layout-U4xJd8Oi.js} +7 -7
  57. package/dist/_chunks/layout-U4xJd8Oi.js.map +1 -0
  58. package/dist/_chunks/{relations-D0eZ4VWw.js → relations-BifGhhuo.js} +2 -2
  59. package/dist/_chunks/{relations-D0eZ4VWw.js.map → relations-BifGhhuo.js.map} +1 -1
  60. package/dist/_chunks/{relations-D26zVRdi.mjs → relations-DMxeUp5V.mjs} +2 -2
  61. package/dist/_chunks/{relations-D26zVRdi.mjs.map → relations-DMxeUp5V.mjs.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 +15 -6
  73. package/dist/server/index.js.map +1 -1
  74. package/dist/server/index.mjs +15 -6
  75. package/dist/server/index.mjs.map +1 -1
  76. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  77. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  78. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  79. package/package.json +8 -8
  80. package/dist/_chunks/EditViewPage-CTTDHKkQ.js.map +0 -1
  81. package/dist/_chunks/EditViewPage-DWb0DE7R.mjs.map +0 -1
  82. package/dist/_chunks/Field-C5Z1Ivdv.js.map +0 -1
  83. package/dist/_chunks/Field-DnStdvQw.mjs.map +0 -1
  84. package/dist/_chunks/Form-B81OtW-k.js.map +0 -1
  85. package/dist/_chunks/Form-DqGgE55Q.mjs.map +0 -1
  86. package/dist/_chunks/History-4NbOq2dX.js.map +0 -1
  87. package/dist/_chunks/History-DS6-HCYX.mjs.map +0 -1
  88. package/dist/_chunks/ListConfigurationPage-CpfstlYY.js.map +0 -1
  89. package/dist/_chunks/ListConfigurationPage-DQJJltko.mjs.map +0 -1
  90. package/dist/_chunks/ListViewPage-CA3I75m5.js.map +0 -1
  91. package/dist/_chunks/ListViewPage-nQrOQuVo.mjs.map +0 -1
  92. package/dist/_chunks/Relations-BDRl99Ux.mjs.map +0 -1
  93. package/dist/_chunks/Relations-DG2jnOcr.js.map +0 -1
  94. package/dist/_chunks/index-BZoNZMXL.js.map +0 -1
  95. package/dist/_chunks/index-Drt2DN7v.mjs.map +0 -1
  96. package/dist/_chunks/layout-BzAbmoO6.mjs.map +0 -1
  97. package/dist/_chunks/layout-DEYBqgF1.js.map +0 -1
@@ -1,17 +1,17 @@
1
- import { ClockCounterClockwise, CrossCircle, More, WarningCircle, ListPlus, Pencil, Trash, Check, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, Feather } from "@strapi/icons";
1
+ import { CrossCircle, More, WarningCircle, ListPlus, Pencil, Trash, Check, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
2
2
  import { jsx, Fragment, jsxs } from "react/jsx-runtime";
3
- import { useStrapiApp, useQueryParams, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useTracking, useForm, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
4
- import { stringify } from "qs";
5
- import { useIntl } from "react-intl";
6
- import { useNavigate, useParams, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
3
+ import { useStrapiApp, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useQueryParams, useTracking, useForm, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
7
4
  import * as React from "react";
8
5
  import { lazy } from "react";
9
- import { Menu, VisuallyHidden, Flex, Typography, Dialog, DialogBody, DialogFooter, Button, ModalLayout, ModalHeader, ModalBody, Box, Radio, Status, SingleSelect, SingleSelectOption, ModalFooter, Loader, IconButton, Tooltip, LinkButton } from "@strapi/design-system";
6
+ import { Button, Menu, VisuallyHidden, Flex, Box, Typography, Dialog, Modal, Radio, Status, SingleSelect, SingleSelectOption, Loader, IconButton, Tooltip, LinkButton } from "@strapi/design-system";
7
+ import { useIntl } from "react-intl";
8
+ import { useParams, Navigate, useNavigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
10
9
  import { styled } from "styled-components";
11
10
  import * as yup from "yup";
12
11
  import { ValidationError } from "yup";
13
12
  import pipe from "lodash/fp/pipe";
14
13
  import { intervalToDuration, isPast } from "date-fns";
14
+ import { stringify } from "qs";
15
15
  import { createSlice, combineReducers } from "@reduxjs/toolkit";
16
16
  const __variableDynamicImportRuntimeHelper = (glob, path) => {
17
17
  const v = glob[path];
@@ -49,42 +49,6 @@ const useInjectionZone = (area) => {
49
49
  const [page, position] = area.split(".");
50
50
  return contentManagerPlugin.getInjectedComponents(page, position);
51
51
  };
52
- const HistoryAction = ({ model, document }) => {
53
- const { formatMessage } = useIntl();
54
- const [{ query }] = useQueryParams();
55
- const navigate = useNavigate();
56
- const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
57
- if (!window.strapi.features.isEnabled("cms-content-history")) {
58
- return null;
59
- }
60
- return {
61
- icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
62
- label: formatMessage({
63
- id: "content-manager.history.document-action",
64
- defaultMessage: "Content History"
65
- }),
66
- onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
67
- disabled: (
68
- /**
69
- * The user is creating a new document.
70
- * It hasn't been saved yet, so there's no history to go to
71
- */
72
- !document || /**
73
- * The document has been created but the current dimension has never been saved.
74
- * For example, the user is creating a new locale in an existing document,
75
- * so there's no history for the document in that locale
76
- */
77
- !document.id || /**
78
- * History is only available for content types created by the user.
79
- * These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
80
- * which start with `admin::` or `plugin::`
81
- */
82
- !model.startsWith("api::")
83
- ),
84
- position: "header"
85
- };
86
- };
87
- HistoryAction.type = "history";
88
52
  const ID = "id";
89
53
  const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
90
54
  const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
@@ -198,6 +162,7 @@ const contentManagerApi = adminApi.enhanceEndpoints({
198
162
  ]
199
163
  });
200
164
  const documentApi = contentManagerApi.injectEndpoints({
165
+ overrideExisting: true,
201
166
  endpoints: (builder) => ({
202
167
  autoCloneDocument: builder.mutation({
203
168
  query: ({ model, sourceId, query }) => ({
@@ -599,11 +564,11 @@ const createAttributeSchema = (attribute) => {
599
564
  }
600
565
  };
601
566
  const addRequiredValidation = (attribute) => (schema) => {
602
- if (attribute.required) {
603
- return schema.required({
604
- id: translatedErrors.required.id,
605
- defaultMessage: "This field is required."
606
- });
567
+ if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
568
+ return schema.min(1, translatedErrors.required);
569
+ }
570
+ if (attribute.required && attribute.type !== "relation") {
571
+ return schema.required(translatedErrors.required);
607
572
  }
608
573
  return schema?.nullable ? schema.nullable() : (
609
574
  // In some cases '.nullable' will not be available on the schema.
@@ -637,6 +602,28 @@ const addMaxLengthValidation = (attribute) => (schema) => {
637
602
  const addMinValidation = (attribute) => (schema) => {
638
603
  if ("min" in attribute) {
639
604
  const min = toInteger(attribute.min);
605
+ if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
606
+ if (!attribute.required && "test" in schema && min) {
607
+ return schema.test(
608
+ "custom-min",
609
+ {
610
+ ...translatedErrors.min,
611
+ values: {
612
+ min: attribute.min
613
+ }
614
+ },
615
+ (value) => {
616
+ if (!value) {
617
+ return true;
618
+ }
619
+ if (Array.isArray(value) && value.length === 0) {
620
+ return true;
621
+ }
622
+ return value.length >= min;
623
+ }
624
+ );
625
+ }
626
+ }
640
627
  if ("min" in schema && min) {
641
628
  return schema.min(min, {
642
629
  ...translatedErrors.min,
@@ -763,7 +750,10 @@ const useDocument = (args, opts) => {
763
750
  isLoading: isLoadingDocument,
764
751
  isFetching: isFetchingDocument,
765
752
  error
766
- } = useGetDocumentQuery(args, opts);
753
+ } = useGetDocumentQuery(args, {
754
+ ...opts,
755
+ skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
756
+ });
767
757
  const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
768
758
  React.useEffect(() => {
769
759
  if (error) {
@@ -1265,7 +1255,7 @@ const useDocumentActions = () => {
1265
1255
  };
1266
1256
  };
1267
1257
  const ProtectedHistoryPage = lazy(
1268
- () => import("./History-DS6-HCYX.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1258
+ () => import("./History-rvLnluF0.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1269
1259
  );
1270
1260
  const routes$1 = [
1271
1261
  {
@@ -1278,31 +1268,31 @@ const routes$1 = [
1278
1268
  }
1279
1269
  ];
1280
1270
  const ProtectedEditViewPage = lazy(
1281
- () => import("./EditViewPage-DWb0DE7R.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1271
+ () => import("./EditViewPage-BqDlT9w0.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1282
1272
  );
1283
1273
  const ProtectedListViewPage = lazy(
1284
- () => import("./ListViewPage-nQrOQuVo.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1274
+ () => import("./ListViewPage-B8cPO1bK.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1285
1275
  );
1286
1276
  const ProtectedListConfiguration = lazy(
1287
- () => import("./ListConfigurationPage-DQJJltko.mjs").then((mod) => ({
1277
+ () => import("./ListConfigurationPage-DdKfJRdq.mjs").then((mod) => ({
1288
1278
  default: mod.ProtectedListConfiguration
1289
1279
  }))
1290
1280
  );
1291
1281
  const ProtectedEditConfigurationPage = lazy(
1292
- () => import("./EditConfigurationPage-CcOoD26O.mjs").then((mod) => ({
1282
+ () => import("./EditConfigurationPage-CuCAsHWR.mjs").then((mod) => ({
1293
1283
  default: mod.ProtectedEditConfigurationPage
1294
1284
  }))
1295
1285
  );
1296
1286
  const ProtectedComponentConfigurationPage = lazy(
1297
- () => import("./ComponentConfigurationPage-BMajAl1u.mjs").then((mod) => ({
1287
+ () => import("./ComponentConfigurationPage-DLuACgva.mjs").then((mod) => ({
1298
1288
  default: mod.ProtectedComponentConfigurationPage
1299
1289
  }))
1300
1290
  );
1301
1291
  const NoPermissions = lazy(
1302
- () => import("./NoPermissionsPage-fOIkQM0v.mjs").then((mod) => ({ default: mod.NoPermissions }))
1292
+ () => import("./NoPermissionsPage-mlXqh8p6.mjs").then((mod) => ({ default: mod.NoPermissions }))
1303
1293
  );
1304
1294
  const NoContentType = lazy(
1305
- () => import("./NoContentTypePage-DbnHE22g.mjs").then((mod) => ({ default: mod.NoContentType }))
1295
+ () => import("./NoContentTypePage-CVqYTeML.mjs").then((mod) => ({ default: mod.NoContentType }))
1306
1296
  );
1307
1297
  const CollectionTypePages = () => {
1308
1298
  const { collectionType } = useParams();
@@ -1429,7 +1419,7 @@ const DocumentActionButton = (action) => {
1429
1419
  DocumentActionConfirmDialog,
1430
1420
  {
1431
1421
  ...action.dialog,
1432
- variant: action.variant,
1422
+ variant: action.dialog?.variant ?? action.variant,
1433
1423
  isOpen: dialogId === action.id,
1434
1424
  onClose: handleClose
1435
1425
  }
@@ -1509,7 +1499,7 @@ const DocumentActionsMenu = ({
1509
1499
  display: "block",
1510
1500
  children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
1511
1501
  /* @__PURE__ */ jsxs(Flex, { color: convertActionVariantToColor(action.variant), gap: 2, tag: "span", children: [
1512
- action.icon,
1502
+ /* @__PURE__ */ jsx(Box, { tag: "span", color: convertActionVariantToIconColor(action.variant), children: action.icon }),
1513
1503
  action.label
1514
1504
  ] }),
1515
1505
  action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
@@ -1570,6 +1560,18 @@ const convertActionVariantToColor = (variant = "secondary") => {
1570
1560
  return "primary600";
1571
1561
  }
1572
1562
  };
1563
+ const convertActionVariantToIconColor = (variant = "secondary") => {
1564
+ switch (variant) {
1565
+ case "danger":
1566
+ return "danger600";
1567
+ case "secondary":
1568
+ return "neutral500";
1569
+ case "success":
1570
+ return "success600";
1571
+ default:
1572
+ return "primary600";
1573
+ }
1574
+ };
1573
1575
  const DocumentActionConfirmDialog = ({
1574
1576
  onClose,
1575
1577
  onCancel,
@@ -1592,22 +1594,20 @@ const DocumentActionConfirmDialog = ({
1592
1594
  }
1593
1595
  onClose();
1594
1596
  };
1595
- return /* @__PURE__ */ jsxs(Dialog, { isOpen, title, onClose: handleClose, children: [
1596
- /* @__PURE__ */ jsx(DialogBody, { children: content }),
1597
- /* @__PURE__ */ jsx(
1598
- DialogFooter,
1599
- {
1600
- startAction: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", children: formatMessage({
1601
- id: "app.components.Button.cancel",
1602
- defaultMessage: "Cancel"
1603
- }) }),
1604
- endAction: /* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
1605
- id: "app.components.Button.confirm",
1606
- defaultMessage: "Confirm"
1607
- }) })
1608
- }
1609
- )
1610
- ] });
1597
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
1598
+ /* @__PURE__ */ jsx(Dialog.Header, { children: title }),
1599
+ /* @__PURE__ */ jsx(Dialog.Body, { children: content }),
1600
+ /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
1601
+ /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
1602
+ id: "app.components.Button.cancel",
1603
+ defaultMessage: "Cancel"
1604
+ }) }) }),
1605
+ /* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
1606
+ id: "app.components.Button.confirm",
1607
+ defaultMessage: "Confirm"
1608
+ }) })
1609
+ ] })
1610
+ ] }) });
1611
1611
  };
1612
1612
  const DocumentActionModal = ({
1613
1613
  isOpen,
@@ -1617,34 +1617,17 @@ const DocumentActionModal = ({
1617
1617
  content: Content,
1618
1618
  onModalClose
1619
1619
  }) => {
1620
- const id = React.useId();
1621
- if (!isOpen) {
1622
- return null;
1623
- }
1624
1620
  const handleClose = () => {
1625
1621
  if (onClose) {
1626
1622
  onClose();
1627
1623
  }
1628
1624
  onModalClose();
1629
1625
  };
1630
- return /* @__PURE__ */ jsxs(ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
1631
- /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
1632
- /* @__PURE__ */ jsx(ModalBody, { children: typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content }),
1633
- /* @__PURE__ */ jsx(
1634
- Box,
1635
- {
1636
- paddingTop: 4,
1637
- paddingBottom: 4,
1638
- paddingLeft: 5,
1639
- paddingRight: 5,
1640
- borderWidth: "1px 0 0 0",
1641
- borderStyle: "solid",
1642
- borderColor: "neutral150",
1643
- background: "neutral100",
1644
- children: typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
1645
- }
1646
- )
1647
- ] });
1626
+ return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
1627
+ /* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
1628
+ /* @__PURE__ */ jsx(Modal.Body, { children: typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content }),
1629
+ /* @__PURE__ */ jsx(Modal.Footer, { children: typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer })
1630
+ ] }) });
1648
1631
  };
1649
1632
  const PublishAction$1 = ({
1650
1633
  activeTab,
@@ -1665,6 +1648,12 @@ const PublishAction$1 = ({
1665
1648
  ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
1666
1649
  );
1667
1650
  const { publish } = useDocumentActions();
1651
+ const [
1652
+ countDraftRelations,
1653
+ { isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
1654
+ ] = useLazyGetDraftRelationCountQuery();
1655
+ const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
1656
+ const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
1668
1657
  const [{ query, rawQuery }] = useQueryParams();
1669
1658
  const params = React.useMemo(() => buildValidParams(query), [query]);
1670
1659
  const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
@@ -1673,10 +1662,101 @@ const PublishAction$1 = ({
1673
1662
  const validate = useForm("PublishAction", (state) => state.validate);
1674
1663
  const setErrors = useForm("PublishAction", (state) => state.setErrors);
1675
1664
  const formValues = useForm("PublishAction", ({ values }) => values);
1665
+ React.useEffect(() => {
1666
+ if (isErrorDraftRelations) {
1667
+ toggleNotification({
1668
+ type: "danger",
1669
+ message: formatMessage({
1670
+ id: getTranslation("error.records.fetch-draft-relatons"),
1671
+ defaultMessage: "An error occurred while fetching draft relations on this document."
1672
+ })
1673
+ });
1674
+ }
1675
+ }, [isErrorDraftRelations, toggleNotification, formatMessage]);
1676
+ React.useEffect(() => {
1677
+ const localDraftRelations = /* @__PURE__ */ new Set();
1678
+ const extractDraftRelations = (data) => {
1679
+ const relations = data.connect || [];
1680
+ relations.forEach((relation) => {
1681
+ if (relation.status === "draft") {
1682
+ localDraftRelations.add(relation.id);
1683
+ }
1684
+ });
1685
+ };
1686
+ const traverseAndExtract = (data) => {
1687
+ Object.entries(data).forEach(([key, value]) => {
1688
+ if (key === "connect" && Array.isArray(value)) {
1689
+ extractDraftRelations({ connect: value });
1690
+ } else if (typeof value === "object" && value !== null) {
1691
+ traverseAndExtract(value);
1692
+ }
1693
+ });
1694
+ };
1695
+ if (!documentId || modified) {
1696
+ traverseAndExtract(formValues);
1697
+ setLocalCountOfDraftRelations(localDraftRelations.size);
1698
+ }
1699
+ }, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
1700
+ React.useEffect(() => {
1701
+ if (documentId) {
1702
+ const fetchDraftRelationsCount = async () => {
1703
+ const { data, error } = await countDraftRelations({
1704
+ collectionType,
1705
+ model,
1706
+ documentId,
1707
+ params
1708
+ });
1709
+ if (error) {
1710
+ throw error;
1711
+ }
1712
+ if (data) {
1713
+ setServerCountOfDraftRelations(data.data);
1714
+ }
1715
+ };
1716
+ fetchDraftRelationsCount();
1717
+ }
1718
+ }, [documentId, countDraftRelations, collectionType, model, params]);
1676
1719
  const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
1677
1720
  if (!schema?.options?.draftAndPublish) {
1678
1721
  return null;
1679
1722
  }
1723
+ const performPublish = async () => {
1724
+ setSubmitting(true);
1725
+ try {
1726
+ const { errors } = await validate();
1727
+ if (errors) {
1728
+ toggleNotification({
1729
+ type: "danger",
1730
+ message: formatMessage({
1731
+ id: "content-manager.validation.error",
1732
+ defaultMessage: "There are validation errors in your document. Please fix them before saving."
1733
+ })
1734
+ });
1735
+ return;
1736
+ }
1737
+ const res = await publish(
1738
+ {
1739
+ collectionType,
1740
+ model,
1741
+ documentId,
1742
+ params
1743
+ },
1744
+ formValues
1745
+ );
1746
+ if ("data" in res && collectionType !== SINGLE_TYPES) {
1747
+ navigate({
1748
+ pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1749
+ search: rawQuery
1750
+ });
1751
+ } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1752
+ setErrors(formatValidationErrors(res.error));
1753
+ }
1754
+ } finally {
1755
+ setSubmitting(false);
1756
+ }
1757
+ };
1758
+ const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
1759
+ const hasDraftRelations = totalDraftRelations > 0;
1680
1760
  return {
1681
1761
  /**
1682
1762
  * Disabled when:
@@ -1689,46 +1769,38 @@ const PublishAction$1 = ({
1689
1769
  * - the user doesn't have the permission to create a new document
1690
1770
  * - the user doesn't have the permission to update the document
1691
1771
  */
1692
- disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
1772
+ disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
1693
1773
  label: formatMessage({
1694
1774
  id: "app.utils.publish",
1695
1775
  defaultMessage: "Publish"
1696
1776
  }),
1697
1777
  onClick: async () => {
1698
- setSubmitting(true);
1699
- try {
1700
- const { errors } = await validate();
1701
- if (errors) {
1702
- toggleNotification({
1703
- type: "danger",
1704
- message: formatMessage({
1705
- id: "content-manager.validation.error",
1706
- defaultMessage: "There are validation errors in your document. Please fix them before saving."
1707
- })
1708
- });
1709
- return;
1710
- }
1711
- const res = await publish(
1712
- {
1713
- collectionType,
1714
- model,
1715
- documentId,
1716
- params
1717
- },
1718
- formValues
1719
- );
1720
- if ("data" in res && collectionType !== SINGLE_TYPES) {
1721
- navigate({
1722
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1723
- search: rawQuery
1724
- });
1725
- } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1726
- setErrors(formatValidationErrors(res.error));
1778
+ if (hasDraftRelations) {
1779
+ return;
1780
+ }
1781
+ await performPublish();
1782
+ },
1783
+ dialog: hasDraftRelations ? {
1784
+ type: "dialog",
1785
+ variant: "danger",
1786
+ footer: null,
1787
+ title: formatMessage({
1788
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
1789
+ defaultMessage: "Confirmation"
1790
+ }),
1791
+ content: formatMessage(
1792
+ {
1793
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
1794
+ defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
1795
+ },
1796
+ {
1797
+ count: totalDraftRelations
1727
1798
  }
1728
- } finally {
1729
- setSubmitting(false);
1799
+ ),
1800
+ onConfirm: async () => {
1801
+ await performPublish();
1730
1802
  }
1731
- }
1803
+ } : void 0
1732
1804
  };
1733
1805
  };
1734
1806
  PublishAction$1.type = "publish";
@@ -1796,10 +1868,13 @@ const UpdateAction = ({
1796
1868
  document
1797
1869
  );
1798
1870
  if ("data" in res) {
1799
- navigate({
1800
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1801
- search: rawQuery
1802
- });
1871
+ navigate(
1872
+ {
1873
+ pathname: `../${res.data.documentId}`,
1874
+ search: rawQuery
1875
+ },
1876
+ { relative: "path" }
1877
+ );
1803
1878
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1804
1879
  setErrors(formatValidationErrors(res.error));
1805
1880
  }
@@ -1827,10 +1902,13 @@ const UpdateAction = ({
1827
1902
  document
1828
1903
  );
1829
1904
  if ("data" in res && collectionType !== SINGLE_TYPES) {
1830
- navigate({
1831
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1832
- search: rawQuery
1833
- });
1905
+ navigate(
1906
+ {
1907
+ pathname: `../${res.data.documentId}`,
1908
+ search: rawQuery
1909
+ },
1910
+ { replace: true, relative: "path" }
1911
+ );
1834
1912
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1835
1913
  setErrors(formatValidationErrors(res.error));
1836
1914
  }
@@ -1862,10 +1940,8 @@ const UnpublishAction$1 = ({
1862
1940
  const { toggleNotification } = useNotification();
1863
1941
  const [shouldKeepDraft, setShouldKeepDraft] = React.useState(true);
1864
1942
  const isDocumentModified = document?.status === "modified";
1865
- const handleChange = (e) => {
1866
- if ("value" in e.target) {
1867
- setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
1868
- }
1943
+ const handleChange = (value) => {
1944
+ setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
1869
1945
  };
1870
1946
  if (!schema?.options?.draftAndPublish) {
1871
1947
  return null;
@@ -1915,40 +1991,24 @@ const UnpublishAction$1 = ({
1915
1991
  }) })
1916
1992
  ] }),
1917
1993
  /* @__PURE__ */ jsxs(
1918
- Flex,
1994
+ Radio.Group,
1919
1995
  {
1920
- onChange: handleChange,
1921
- direction: "column",
1922
- alignItems: "flex-start",
1923
- tag: "fieldset",
1924
- borderWidth: 0,
1925
- gap: 3,
1996
+ defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
1997
+ name: "discard-options",
1998
+ "aria-label": formatMessage({
1999
+ id: "content-manager.actions.unpublish.dialog.radio-label",
2000
+ defaultMessage: "Choose an option to unpublish the document."
2001
+ }),
2002
+ onValueChange: handleChange,
1926
2003
  children: [
1927
- /* @__PURE__ */ jsx(VisuallyHidden, { tag: "legend" }),
1928
- /* @__PURE__ */ jsx(
1929
- Radio,
1930
- {
1931
- checked: shouldKeepDraft,
1932
- value: UNPUBLISH_DRAFT_OPTIONS.KEEP,
1933
- name: "discard-options",
1934
- children: formatMessage({
1935
- id: "content-manager.actions.unpublish.dialog.option.keep-draft",
1936
- defaultMessage: "Keep draft"
1937
- })
1938
- }
1939
- ),
1940
- /* @__PURE__ */ jsx(
1941
- Radio,
1942
- {
1943
- checked: !shouldKeepDraft,
1944
- value: UNPUBLISH_DRAFT_OPTIONS.DISCARD,
1945
- name: "discard-options",
1946
- children: formatMessage({
1947
- id: "content-manager.actions.unpublish.dialog.option.replace-draft",
1948
- defaultMessage: "Replace draft"
1949
- })
1950
- }
1951
- )
2004
+ /* @__PURE__ */ jsx(Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
2005
+ id: "content-manager.actions.unpublish.dialog.option.keep-draft",
2006
+ defaultMessage: "Keep draft"
2007
+ }) }),
2008
+ /* @__PURE__ */ jsx(Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
2009
+ id: "content-manager.actions.unpublish.dialog.option.replace-draft",
2010
+ defaultMessage: "Replace draft"
2011
+ }) })
1952
2012
  ]
1953
2013
  }
1954
2014
  )
@@ -2094,23 +2154,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2094
2154
  id: "content-manager.containers.edit.title.new",
2095
2155
  defaultMessage: "Create an entry"
2096
2156
  }) : documentTitle;
2097
- return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 8, paddingBottom: 4, gap: 3, children: [
2157
+ return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
2098
2158
  /* @__PURE__ */ jsx(BackButton, {}),
2099
- /* @__PURE__ */ jsxs(
2100
- Flex,
2101
- {
2102
- width: "100%",
2103
- justifyContent: "space-between",
2104
- paddingTop: 1,
2105
- gap: "80px",
2106
- alignItems: "flex-start",
2107
- children: [
2108
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
2109
- /* @__PURE__ */ jsx(HeaderToolbar, {})
2110
- ]
2111
- }
2112
- ),
2113
- status ? /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
2159
+ /* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
2160
+ /* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
2161
+ /* @__PURE__ */ jsx(HeaderToolbar, {})
2162
+ ] }),
2163
+ status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
2114
2164
  ] });
2115
2165
  };
2116
2166
  const HeaderToolbar = () => {
@@ -2801,30 +2851,23 @@ const ConfirmBulkActionDialog = ({
2801
2851
  endAction
2802
2852
  }) => {
2803
2853
  const { formatMessage } = useIntl();
2804
- return /* @__PURE__ */ jsxs(
2805
- Dialog,
2806
- {
2807
- onClose: onToggleDialog,
2808
- title: formatMessage({
2809
- id: "app.components.ConfirmDialog.title",
2810
- defaultMessage: "Confirmation"
2811
- }),
2812
- isOpen,
2813
- children: [
2814
- /* @__PURE__ */ jsx(DialogBody, { icon: /* @__PURE__ */ jsx(WarningCircle, {}), children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: dialogBody }) }),
2815
- /* @__PURE__ */ jsx(
2816
- DialogFooter,
2817
- {
2818
- startAction: /* @__PURE__ */ jsx(Button, { onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
2819
- id: "app.components.Button.cancel",
2820
- defaultMessage: "Cancel"
2821
- }) }),
2822
- endAction
2823
- }
2824
- )
2825
- ]
2826
- }
2827
- );
2854
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
2855
+ /* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
2856
+ id: "app.components.ConfirmDialog.title",
2857
+ defaultMessage: "Confirmation"
2858
+ }) }),
2859
+ /* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
2860
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
2861
+ dialogBody
2862
+ ] }) }),
2863
+ /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
2864
+ /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
2865
+ id: "app.components.Button.cancel",
2866
+ defaultMessage: "Cancel"
2867
+ }) }) }),
2868
+ endAction
2869
+ ] })
2870
+ ] }) });
2828
2871
  };
2829
2872
  const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
2830
2873
  const ConfirmDialogPublishAll = ({
@@ -2929,7 +2972,14 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
2929
2972
  )
2930
2973
  );
2931
2974
  } else {
2932
- messages.push(...formatErrorMessages(value, currentKey, formatMessage));
2975
+ messages.push(
2976
+ ...formatErrorMessages(
2977
+ // @ts-expect-error TODO: check why value is not compatible with FormErrors
2978
+ value,
2979
+ currentKey,
2980
+ formatMessage
2981
+ )
2982
+ );
2933
2983
  }
2934
2984
  } else {
2935
2985
  messages.push(
@@ -3166,7 +3216,7 @@ const SelectedEntriesModalContent = ({
3166
3216
  );
3167
3217
  };
3168
3218
  return /* @__PURE__ */ jsxs(Fragment, { children: [
3169
- /* @__PURE__ */ jsxs(ModalBody, { children: [
3219
+ /* @__PURE__ */ jsxs(Modal.Body, { children: [
3170
3220
  /* @__PURE__ */ jsx(Typography, { children: getFormattedCountMessage() }),
3171
3221
  /* @__PURE__ */ jsx(Box, { marginTop: 5, children: /* @__PURE__ */ jsx(
3172
3222
  SelectedEntriesTableContent,
@@ -3178,27 +3228,24 @@ const SelectedEntriesModalContent = ({
3178
3228
  }
3179
3229
  ) })
3180
3230
  ] }),
3181
- /* @__PURE__ */ jsx(
3182
- ModalFooter,
3183
- {
3184
- startActions: /* @__PURE__ */ jsx(Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
3185
- id: "app.components.Button.cancel",
3186
- defaultMessage: "Cancel"
3187
- }) }),
3188
- endActions: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3189
- /* @__PURE__ */ jsx(Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
3190
- /* @__PURE__ */ jsx(
3191
- Button,
3192
- {
3193
- onClick: toggleDialog,
3194
- disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
3195
- loading: isSubmittingForm,
3196
- children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
3197
- }
3198
- )
3199
- ] })
3200
- }
3201
- ),
3231
+ /* @__PURE__ */ jsxs(Modal.Footer, { children: [
3232
+ /* @__PURE__ */ jsx(Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
3233
+ id: "app.components.Button.cancel",
3234
+ defaultMessage: "Cancel"
3235
+ }) }),
3236
+ /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3237
+ /* @__PURE__ */ jsx(Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
3238
+ /* @__PURE__ */ jsx(
3239
+ Button,
3240
+ {
3241
+ onClick: toggleDialog,
3242
+ disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
3243
+ loading: isSubmittingForm,
3244
+ children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
3245
+ }
3246
+ )
3247
+ ] })
3248
+ ] }),
3202
3249
  /* @__PURE__ */ jsx(
3203
3250
  ConfirmDialogPublishAll,
3204
3251
  {
@@ -3263,143 +3310,10 @@ const BulkActionsRenderer = () => {
3263
3310
  documents: selectedRows
3264
3311
  },
3265
3312
  descriptions: plugins["content-manager"].apis.getBulkActions(),
3266
- children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(BulkActionAction, { ...action }, action.id))
3313
+ children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(DocumentActionButton, { ...action }, action.id))
3267
3314
  }
3268
3315
  ) });
3269
3316
  };
3270
- const BulkActionAction = (action) => {
3271
- const [dialogId, setDialogId] = React.useState(null);
3272
- const { toggleNotification } = useNotification();
3273
- const handleClick = (action2) => (e) => {
3274
- const { onClick, dialog, id } = action2;
3275
- if (onClick) {
3276
- onClick(e);
3277
- }
3278
- if (dialog) {
3279
- switch (dialog.type) {
3280
- case "notification":
3281
- toggleNotification({
3282
- title: dialog.title,
3283
- message: dialog.content,
3284
- type: dialog.status,
3285
- timeout: dialog.timeout,
3286
- onClose: dialog.onClose
3287
- });
3288
- break;
3289
- case "dialog":
3290
- case "modal": {
3291
- e.preventDefault();
3292
- setDialogId(id);
3293
- }
3294
- }
3295
- }
3296
- };
3297
- const handleClose = () => {
3298
- setDialogId(null);
3299
- if (action.dialog?.type === "modal" && action.dialog?.onClose) {
3300
- action.dialog.onClose();
3301
- }
3302
- };
3303
- return /* @__PURE__ */ jsxs(Fragment, { children: [
3304
- /* @__PURE__ */ jsx(
3305
- Button,
3306
- {
3307
- disabled: action.disabled,
3308
- startIcon: action.icon,
3309
- variant: action.variant,
3310
- onClick: handleClick(action),
3311
- children: action.label
3312
- }
3313
- ),
3314
- action.dialog?.type === "dialog" ? /* @__PURE__ */ jsx(
3315
- BulkActionConfirmDialog,
3316
- {
3317
- ...action.dialog,
3318
- variant: action.variant,
3319
- isOpen: dialogId === action.id,
3320
- onClose: handleClose
3321
- }
3322
- ) : null,
3323
- action.dialog?.type === "modal" ? /* @__PURE__ */ jsx(
3324
- BulkActionModal,
3325
- {
3326
- ...action.dialog,
3327
- onModalClose: handleClose,
3328
- isOpen: dialogId === action.id
3329
- }
3330
- ) : null
3331
- ] });
3332
- };
3333
- const BulkActionConfirmDialog = ({
3334
- onClose,
3335
- onCancel,
3336
- onConfirm,
3337
- title,
3338
- content,
3339
- confirmButton,
3340
- isOpen,
3341
- variant = "secondary"
3342
- }) => {
3343
- const { formatMessage } = useIntl();
3344
- const handleClose = async () => {
3345
- if (onCancel) {
3346
- await onCancel();
3347
- }
3348
- onClose();
3349
- };
3350
- const handleConfirm = async () => {
3351
- if (onConfirm) {
3352
- await onConfirm();
3353
- }
3354
- onClose();
3355
- };
3356
- return /* @__PURE__ */ jsxs(Dialog, { isOpen, title, onClose: handleClose, children: [
3357
- /* @__PURE__ */ jsx(DialogBody, { icon: /* @__PURE__ */ jsx(WarningCircle, {}), children: content }),
3358
- /* @__PURE__ */ jsx(
3359
- DialogFooter,
3360
- {
3361
- startAction: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", children: formatMessage({
3362
- id: "app.components.Button.cancel",
3363
- defaultMessage: "Cancel"
3364
- }) }),
3365
- endAction: /* @__PURE__ */ jsx(
3366
- Button,
3367
- {
3368
- onClick: handleConfirm,
3369
- variant: variant === "danger-light" ? variant : "secondary",
3370
- startIcon: variant === "danger-light" ? /* @__PURE__ */ jsx(Trash, {}) : /* @__PURE__ */ jsx(Check, {}),
3371
- children: confirmButton ? confirmButton : formatMessage({
3372
- id: "app.components.Button.confirm",
3373
- defaultMessage: "Confirm"
3374
- })
3375
- }
3376
- )
3377
- }
3378
- )
3379
- ] });
3380
- };
3381
- const BulkActionModal = ({
3382
- isOpen,
3383
- title,
3384
- onClose,
3385
- content: Content,
3386
- onModalClose
3387
- }) => {
3388
- const id = React.useId();
3389
- if (!isOpen) {
3390
- return null;
3391
- }
3392
- const handleClose = () => {
3393
- if (onClose) {
3394
- onClose();
3395
- }
3396
- onModalClose();
3397
- };
3398
- return /* @__PURE__ */ jsxs(ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
3399
- /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
3400
- /* @__PURE__ */ jsx(Content, { onClose: handleClose })
3401
- ] });
3402
- };
3403
3317
  const DeleteAction = ({ documents, model }) => {
3404
3318
  const { formatMessage } = useIntl();
3405
3319
  const { schema: contentType } = useDoc();
@@ -3432,6 +3346,7 @@ const DeleteAction = ({ documents, model }) => {
3432
3346
  defaultMessage: "Confirmation"
3433
3347
  }),
3434
3348
  content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3349
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3435
3350
  /* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3436
3351
  id: "popUpWarning.bodyMessage.contentType.delete.all",
3437
3352
  defaultMessage: "Are you sure you want to delete these entries?"
@@ -3481,6 +3396,7 @@ const UnpublishAction = ({ documents, model }) => {
3481
3396
  defaultMessage: "Confirmation"
3482
3397
  }),
3483
3398
  content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3399
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3484
3400
  /* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3485
3401
  id: "popUpWarning.bodyMessage.contentType.unpublish.all",
3486
3402
  defaultMessage: "Are you sure you want to unpublish these entries?"
@@ -3726,8 +3642,7 @@ class ContentManagerPlugin {
3726
3642
  documentActions = [
3727
3643
  ...DEFAULT_ACTIONS,
3728
3644
  ...DEFAULT_TABLE_ROW_ACTIONS,
3729
- ...DEFAULT_HEADER_ACTIONS,
3730
- HistoryAction
3645
+ ...DEFAULT_HEADER_ACTIONS
3731
3646
  ];
3732
3647
  editViewSidePanels = [ActionsPanel];
3733
3648
  headerActions = [];
@@ -3816,6 +3731,52 @@ const getPrintableType = (value) => {
3816
3731
  }
3817
3732
  return nativeType;
3818
3733
  };
3734
+ const HistoryAction = ({ model, document }) => {
3735
+ const { formatMessage } = useIntl();
3736
+ const [{ query }] = useQueryParams();
3737
+ const navigate = useNavigate();
3738
+ const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
3739
+ if (!window.strapi.features.isEnabled("cms-content-history")) {
3740
+ return null;
3741
+ }
3742
+ return {
3743
+ icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
3744
+ label: formatMessage({
3745
+ id: "content-manager.history.document-action",
3746
+ defaultMessage: "Content History"
3747
+ }),
3748
+ onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
3749
+ disabled: (
3750
+ /**
3751
+ * The user is creating a new document.
3752
+ * It hasn't been saved yet, so there's no history to go to
3753
+ */
3754
+ !document || /**
3755
+ * The document has been created but the current dimension has never been saved.
3756
+ * For example, the user is creating a new locale in an existing document,
3757
+ * so there's no history for the document in that locale
3758
+ */
3759
+ !document.id || /**
3760
+ * History is only available for content types created by the user.
3761
+ * These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
3762
+ * which start with `admin::` or `plugin::`
3763
+ */
3764
+ !model.startsWith("api::")
3765
+ ),
3766
+ position: "header"
3767
+ };
3768
+ };
3769
+ HistoryAction.type = "history";
3770
+ const historyAdmin = {
3771
+ bootstrap(app) {
3772
+ const { addDocumentAction } = app.getPlugin("content-manager").apis;
3773
+ addDocumentAction((actions2) => {
3774
+ const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
3775
+ actions2.splice(indexOfDeleteAction, 0, HistoryAction);
3776
+ return actions2;
3777
+ });
3778
+ }
3779
+ };
3819
3780
  const initialState = {
3820
3781
  collectionTypeLinks: [],
3821
3782
  components: [],
@@ -3866,15 +3827,29 @@ const index = {
3866
3827
  defaultMessage: "Content Manager"
3867
3828
  },
3868
3829
  permissions: [],
3869
- Component: () => import("./layout-BzAbmoO6.mjs").then((mod) => ({ default: mod.Layout })),
3870
3830
  position: 1
3871
3831
  });
3832
+ app.router.addRoute({
3833
+ path: "content-manager/*",
3834
+ lazy: async () => {
3835
+ const { Layout } = await import("./layout-Dewoec1b.mjs");
3836
+ return {
3837
+ Component: Layout
3838
+ };
3839
+ },
3840
+ children: routes
3841
+ });
3872
3842
  app.registerPlugin(cm.config);
3873
3843
  },
3844
+ bootstrap(app) {
3845
+ if (typeof historyAdmin.bootstrap === "function") {
3846
+ historyAdmin.bootstrap(app);
3847
+ }
3848
+ },
3874
3849
  async registerTrads({ locales }) {
3875
3850
  const importedTrads = await Promise.all(
3876
3851
  locales.map((locale) => {
3877
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-Ux26r5pl.mjs"), "./translations/es.json": () => import("./es-CeXiYflN.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr-CD9VFbPM.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-CtsUxOvk.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
3852
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-BrCTWlZv.mjs"), "./translations/es.json": () => import("./es-CeXiYflN.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr-CD9VFbPM.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-CtsUxOvk.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
3878
3853
  return {
3879
3854
  data: prefixPluginTranslations(data, PLUGIN_ID),
3880
3855
  locale
@@ -3895,14 +3870,13 @@ export {
3895
3870
  BulkActionsRenderer as B,
3896
3871
  COLLECTION_TYPES as C,
3897
3872
  DocumentStatus as D,
3898
- extractContentTypeComponents as E,
3899
- DEFAULT_SETTINGS as F,
3900
- convertEditLayoutToFieldLayouts as G,
3873
+ DEFAULT_SETTINGS as E,
3874
+ convertEditLayoutToFieldLayouts as F,
3875
+ useDocument as G,
3901
3876
  HOOKS as H,
3902
3877
  InjectionZone as I,
3903
- useDocument as J,
3904
- index as K,
3905
- useDocumentActions as L,
3878
+ index as J,
3879
+ useDocumentActions as K,
3906
3880
  Panels as P,
3907
3881
  RelativeTime as R,
3908
3882
  SINGLE_TYPES as S,
@@ -3924,14 +3898,14 @@ export {
3924
3898
  useGetContentTypeConfigurationQuery as o,
3925
3899
  CREATOR_FIELDS as p,
3926
3900
  getMainField as q,
3927
- routes as r,
3901
+ getDisplayName as r,
3928
3902
  setInitialData as s,
3929
- getDisplayName as t,
3903
+ checkIfAttributeIsDisplayable as t,
3930
3904
  useContentTypeSchema as u,
3931
- checkIfAttributeIsDisplayable as v,
3932
- useGetAllDocumentsQuery as w,
3933
- convertListLayoutToFieldLayouts as x,
3934
- capitalise as y,
3935
- useUpdateContentTypeConfigurationMutation as z
3905
+ useGetAllDocumentsQuery as v,
3906
+ convertListLayoutToFieldLayouts as w,
3907
+ capitalise as x,
3908
+ useUpdateContentTypeConfigurationMutation as y,
3909
+ extractContentTypeComponents as z
3936
3910
  };
3937
- //# sourceMappingURL=index-Drt2DN7v.mjs.map
3911
+ //# sourceMappingURL=index-JSJrqmB9.mjs.map