@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
@@ -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 }) => ({
@@ -207,7 +172,12 @@ const documentApi = contentManagerApi.injectEndpoints({
207
172
  params: query
208
173
  }
209
174
  }),
210
- invalidatesTags: (_result, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
175
+ invalidatesTags: (_result, error, { model }) => {
176
+ if (error) {
177
+ return [];
178
+ }
179
+ return [{ type: "Document", id: `${model}_LIST` }];
180
+ }
211
181
  }),
212
182
  cloneDocument: builder.mutation({
213
183
  query: ({ model, sourceId, data, params }) => ({
@@ -397,6 +367,18 @@ const documentApi = contentManagerApi.injectEndpoints({
397
367
  },
398
368
  "Relations"
399
369
  ];
370
+ },
371
+ async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
372
+ const patchResult = dispatch(
373
+ documentApi.util.updateQueryData("getDocument", patch, (draft) => {
374
+ Object.assign(draft.data, data);
375
+ })
376
+ );
377
+ try {
378
+ await queryFulfilled;
379
+ } catch {
380
+ patchResult.undo();
381
+ }
400
382
  }
401
383
  }),
402
384
  unpublishDocument: builder.mutation({
@@ -599,11 +581,11 @@ const createAttributeSchema = (attribute) => {
599
581
  }
600
582
  };
601
583
  const addRequiredValidation = (attribute) => (schema) => {
602
- if (attribute.required) {
603
- return schema.required({
604
- id: translatedErrors.required.id,
605
- defaultMessage: "This field is required."
606
- });
584
+ if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
585
+ return schema.min(1, translatedErrors.required);
586
+ }
587
+ if (attribute.required && attribute.type !== "relation") {
588
+ return schema.required(translatedErrors.required);
607
589
  }
608
590
  return schema?.nullable ? schema.nullable() : (
609
591
  // In some cases '.nullable' will not be available on the schema.
@@ -637,6 +619,28 @@ const addMaxLengthValidation = (attribute) => (schema) => {
637
619
  const addMinValidation = (attribute) => (schema) => {
638
620
  if ("min" in attribute) {
639
621
  const min = toInteger(attribute.min);
622
+ if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
623
+ if (!attribute.required && "test" in schema && min) {
624
+ return schema.test(
625
+ "custom-min",
626
+ {
627
+ ...translatedErrors.min,
628
+ values: {
629
+ min: attribute.min
630
+ }
631
+ },
632
+ (value) => {
633
+ if (!value) {
634
+ return true;
635
+ }
636
+ if (Array.isArray(value) && value.length === 0) {
637
+ return true;
638
+ }
639
+ return value.length >= min;
640
+ }
641
+ );
642
+ }
643
+ }
640
644
  if ("min" in schema && min) {
641
645
  return schema.min(min, {
642
646
  ...translatedErrors.min,
@@ -763,7 +767,10 @@ const useDocument = (args, opts) => {
763
767
  isLoading: isLoadingDocument,
764
768
  isFetching: isFetchingDocument,
765
769
  error
766
- } = useGetDocumentQuery(args, opts);
770
+ } = useGetDocumentQuery(args, {
771
+ ...opts,
772
+ skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
773
+ });
767
774
  const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
768
775
  React.useEffect(() => {
769
776
  if (error) {
@@ -1184,7 +1191,6 @@ const useDocumentActions = () => {
1184
1191
  sourceId
1185
1192
  });
1186
1193
  if ("error" in res) {
1187
- toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1188
1194
  return { error: res.error };
1189
1195
  }
1190
1196
  toggleNotification({
@@ -1265,7 +1271,7 @@ const useDocumentActions = () => {
1265
1271
  };
1266
1272
  };
1267
1273
  const ProtectedHistoryPage = lazy(
1268
- () => import("./History-DS6-HCYX.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1274
+ () => import("./History-wrnHqf09.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1269
1275
  );
1270
1276
  const routes$1 = [
1271
1277
  {
@@ -1278,31 +1284,31 @@ const routes$1 = [
1278
1284
  }
1279
1285
  ];
1280
1286
  const ProtectedEditViewPage = lazy(
1281
- () => import("./EditViewPage-DWb0DE7R.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1287
+ () => import("./EditViewPage-BLsjc5F-.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1282
1288
  );
1283
1289
  const ProtectedListViewPage = lazy(
1284
- () => import("./ListViewPage-nQrOQuVo.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1290
+ () => import("./ListViewPage-C4IvrMgY.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1285
1291
  );
1286
1292
  const ProtectedListConfiguration = lazy(
1287
- () => import("./ListConfigurationPage-DQJJltko.mjs").then((mod) => ({
1293
+ () => import("./ListConfigurationPage-DScmJVkW.mjs").then((mod) => ({
1288
1294
  default: mod.ProtectedListConfiguration
1289
1295
  }))
1290
1296
  );
1291
1297
  const ProtectedEditConfigurationPage = lazy(
1292
- () => import("./EditConfigurationPage-CcOoD26O.mjs").then((mod) => ({
1298
+ () => import("./EditConfigurationPage-DmoXawIh.mjs").then((mod) => ({
1293
1299
  default: mod.ProtectedEditConfigurationPage
1294
1300
  }))
1295
1301
  );
1296
1302
  const ProtectedComponentConfigurationPage = lazy(
1297
- () => import("./ComponentConfigurationPage-BMajAl1u.mjs").then((mod) => ({
1303
+ () => import("./ComponentConfigurationPage-BAgyHiMm.mjs").then((mod) => ({
1298
1304
  default: mod.ProtectedComponentConfigurationPage
1299
1305
  }))
1300
1306
  );
1301
1307
  const NoPermissions = lazy(
1302
- () => import("./NoPermissionsPage-fOIkQM0v.mjs").then((mod) => ({ default: mod.NoPermissions }))
1308
+ () => import("./NoPermissionsPage-DSP7R-hv.mjs").then((mod) => ({ default: mod.NoPermissions }))
1303
1309
  );
1304
1310
  const NoContentType = lazy(
1305
- () => import("./NoContentTypePage-DbnHE22g.mjs").then((mod) => ({ default: mod.NoContentType }))
1311
+ () => import("./NoContentTypePage-Djg8nPlj.mjs").then((mod) => ({ default: mod.NoContentType }))
1306
1312
  );
1307
1313
  const CollectionTypePages = () => {
1308
1314
  const { collectionType } = useParams();
@@ -1429,7 +1435,7 @@ const DocumentActionButton = (action) => {
1429
1435
  DocumentActionConfirmDialog,
1430
1436
  {
1431
1437
  ...action.dialog,
1432
- variant: action.variant,
1438
+ variant: action.dialog?.variant ?? action.variant,
1433
1439
  isOpen: dialogId === action.id,
1434
1440
  onClose: handleClose
1435
1441
  }
@@ -1509,7 +1515,7 @@ const DocumentActionsMenu = ({
1509
1515
  display: "block",
1510
1516
  children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
1511
1517
  /* @__PURE__ */ jsxs(Flex, { color: convertActionVariantToColor(action.variant), gap: 2, tag: "span", children: [
1512
- action.icon,
1518
+ /* @__PURE__ */ jsx(Box, { tag: "span", color: convertActionVariantToIconColor(action.variant), children: action.icon }),
1513
1519
  action.label
1514
1520
  ] }),
1515
1521
  action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
@@ -1570,6 +1576,18 @@ const convertActionVariantToColor = (variant = "secondary") => {
1570
1576
  return "primary600";
1571
1577
  }
1572
1578
  };
1579
+ const convertActionVariantToIconColor = (variant = "secondary") => {
1580
+ switch (variant) {
1581
+ case "danger":
1582
+ return "danger600";
1583
+ case "secondary":
1584
+ return "neutral500";
1585
+ case "success":
1586
+ return "success600";
1587
+ default:
1588
+ return "primary600";
1589
+ }
1590
+ };
1573
1591
  const DocumentActionConfirmDialog = ({
1574
1592
  onClose,
1575
1593
  onCancel,
@@ -1592,22 +1610,20 @@ const DocumentActionConfirmDialog = ({
1592
1610
  }
1593
1611
  onClose();
1594
1612
  };
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
- ] });
1613
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
1614
+ /* @__PURE__ */ jsx(Dialog.Header, { children: title }),
1615
+ /* @__PURE__ */ jsx(Dialog.Body, { children: content }),
1616
+ /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
1617
+ /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
1618
+ id: "app.components.Button.cancel",
1619
+ defaultMessage: "Cancel"
1620
+ }) }) }),
1621
+ /* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
1622
+ id: "app.components.Button.confirm",
1623
+ defaultMessage: "Confirm"
1624
+ }) })
1625
+ ] })
1626
+ ] }) });
1611
1627
  };
1612
1628
  const DocumentActionModal = ({
1613
1629
  isOpen,
@@ -1617,34 +1633,17 @@ const DocumentActionModal = ({
1617
1633
  content: Content,
1618
1634
  onModalClose
1619
1635
  }) => {
1620
- const id = React.useId();
1621
- if (!isOpen) {
1622
- return null;
1623
- }
1624
1636
  const handleClose = () => {
1625
1637
  if (onClose) {
1626
1638
  onClose();
1627
1639
  }
1628
1640
  onModalClose();
1629
1641
  };
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
- ] });
1642
+ return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
1643
+ /* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
1644
+ typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
1645
+ typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
1646
+ ] }) });
1648
1647
  };
1649
1648
  const PublishAction$1 = ({
1650
1649
  activeTab,
@@ -1665,6 +1664,12 @@ const PublishAction$1 = ({
1665
1664
  ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
1666
1665
  );
1667
1666
  const { publish } = useDocumentActions();
1667
+ const [
1668
+ countDraftRelations,
1669
+ { isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
1670
+ ] = useLazyGetDraftRelationCountQuery();
1671
+ const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
1672
+ const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
1668
1673
  const [{ query, rawQuery }] = useQueryParams();
1669
1674
  const params = React.useMemo(() => buildValidParams(query), [query]);
1670
1675
  const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
@@ -1673,10 +1678,101 @@ const PublishAction$1 = ({
1673
1678
  const validate = useForm("PublishAction", (state) => state.validate);
1674
1679
  const setErrors = useForm("PublishAction", (state) => state.setErrors);
1675
1680
  const formValues = useForm("PublishAction", ({ values }) => values);
1681
+ React.useEffect(() => {
1682
+ if (isErrorDraftRelations) {
1683
+ toggleNotification({
1684
+ type: "danger",
1685
+ message: formatMessage({
1686
+ id: getTranslation("error.records.fetch-draft-relatons"),
1687
+ defaultMessage: "An error occurred while fetching draft relations on this document."
1688
+ })
1689
+ });
1690
+ }
1691
+ }, [isErrorDraftRelations, toggleNotification, formatMessage]);
1692
+ React.useEffect(() => {
1693
+ const localDraftRelations = /* @__PURE__ */ new Set();
1694
+ const extractDraftRelations = (data) => {
1695
+ const relations = data.connect || [];
1696
+ relations.forEach((relation) => {
1697
+ if (relation.status === "draft") {
1698
+ localDraftRelations.add(relation.id);
1699
+ }
1700
+ });
1701
+ };
1702
+ const traverseAndExtract = (data) => {
1703
+ Object.entries(data).forEach(([key, value]) => {
1704
+ if (key === "connect" && Array.isArray(value)) {
1705
+ extractDraftRelations({ connect: value });
1706
+ } else if (typeof value === "object" && value !== null) {
1707
+ traverseAndExtract(value);
1708
+ }
1709
+ });
1710
+ };
1711
+ if (!documentId || modified) {
1712
+ traverseAndExtract(formValues);
1713
+ setLocalCountOfDraftRelations(localDraftRelations.size);
1714
+ }
1715
+ }, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
1716
+ React.useEffect(() => {
1717
+ if (documentId) {
1718
+ const fetchDraftRelationsCount = async () => {
1719
+ const { data, error } = await countDraftRelations({
1720
+ collectionType,
1721
+ model,
1722
+ documentId,
1723
+ params
1724
+ });
1725
+ if (error) {
1726
+ throw error;
1727
+ }
1728
+ if (data) {
1729
+ setServerCountOfDraftRelations(data.data);
1730
+ }
1731
+ };
1732
+ fetchDraftRelationsCount();
1733
+ }
1734
+ }, [documentId, countDraftRelations, collectionType, model, params]);
1676
1735
  const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
1677
1736
  if (!schema?.options?.draftAndPublish) {
1678
1737
  return null;
1679
1738
  }
1739
+ const performPublish = async () => {
1740
+ setSubmitting(true);
1741
+ try {
1742
+ const { errors } = await validate();
1743
+ if (errors) {
1744
+ toggleNotification({
1745
+ type: "danger",
1746
+ message: formatMessage({
1747
+ id: "content-manager.validation.error",
1748
+ defaultMessage: "There are validation errors in your document. Please fix them before saving."
1749
+ })
1750
+ });
1751
+ return;
1752
+ }
1753
+ const res = await publish(
1754
+ {
1755
+ collectionType,
1756
+ model,
1757
+ documentId,
1758
+ params
1759
+ },
1760
+ formValues
1761
+ );
1762
+ if ("data" in res && collectionType !== SINGLE_TYPES) {
1763
+ navigate({
1764
+ pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1765
+ search: rawQuery
1766
+ });
1767
+ } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1768
+ setErrors(formatValidationErrors(res.error));
1769
+ }
1770
+ } finally {
1771
+ setSubmitting(false);
1772
+ }
1773
+ };
1774
+ const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
1775
+ const hasDraftRelations = totalDraftRelations > 0;
1680
1776
  return {
1681
1777
  /**
1682
1778
  * Disabled when:
@@ -1689,46 +1785,38 @@ const PublishAction$1 = ({
1689
1785
  * - the user doesn't have the permission to create a new document
1690
1786
  * - the user doesn't have the permission to update the document
1691
1787
  */
1692
- disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
1788
+ disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
1693
1789
  label: formatMessage({
1694
1790
  id: "app.utils.publish",
1695
1791
  defaultMessage: "Publish"
1696
1792
  }),
1697
1793
  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));
1794
+ if (hasDraftRelations) {
1795
+ return;
1796
+ }
1797
+ await performPublish();
1798
+ },
1799
+ dialog: hasDraftRelations ? {
1800
+ type: "dialog",
1801
+ variant: "danger",
1802
+ footer: null,
1803
+ title: formatMessage({
1804
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
1805
+ defaultMessage: "Confirmation"
1806
+ }),
1807
+ content: formatMessage(
1808
+ {
1809
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
1810
+ defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
1811
+ },
1812
+ {
1813
+ count: totalDraftRelations
1727
1814
  }
1728
- } finally {
1729
- setSubmitting(false);
1815
+ ),
1816
+ onConfirm: async () => {
1817
+ await performPublish();
1730
1818
  }
1731
- }
1819
+ } : void 0
1732
1820
  };
1733
1821
  };
1734
1822
  PublishAction$1.type = "publish";
@@ -1796,10 +1884,13 @@ const UpdateAction = ({
1796
1884
  document
1797
1885
  );
1798
1886
  if ("data" in res) {
1799
- navigate({
1800
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1801
- search: rawQuery
1802
- });
1887
+ navigate(
1888
+ {
1889
+ pathname: `../${res.data.documentId}`,
1890
+ search: rawQuery
1891
+ },
1892
+ { relative: "path" }
1893
+ );
1803
1894
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1804
1895
  setErrors(formatValidationErrors(res.error));
1805
1896
  }
@@ -1827,10 +1918,13 @@ const UpdateAction = ({
1827
1918
  document
1828
1919
  );
1829
1920
  if ("data" in res && collectionType !== SINGLE_TYPES) {
1830
- navigate({
1831
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1832
- search: rawQuery
1833
- });
1921
+ navigate(
1922
+ {
1923
+ pathname: `../${res.data.documentId}`,
1924
+ search: rawQuery
1925
+ },
1926
+ { replace: true, relative: "path" }
1927
+ );
1834
1928
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1835
1929
  setErrors(formatValidationErrors(res.error));
1836
1930
  }
@@ -1862,10 +1956,8 @@ const UnpublishAction$1 = ({
1862
1956
  const { toggleNotification } = useNotification();
1863
1957
  const [shouldKeepDraft, setShouldKeepDraft] = React.useState(true);
1864
1958
  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
- }
1959
+ const handleChange = (value) => {
1960
+ setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
1869
1961
  };
1870
1962
  if (!schema?.options?.draftAndPublish) {
1871
1963
  return null;
@@ -1915,40 +2007,24 @@ const UnpublishAction$1 = ({
1915
2007
  }) })
1916
2008
  ] }),
1917
2009
  /* @__PURE__ */ jsxs(
1918
- Flex,
2010
+ Radio.Group,
1919
2011
  {
1920
- onChange: handleChange,
1921
- direction: "column",
1922
- alignItems: "flex-start",
1923
- tag: "fieldset",
1924
- borderWidth: 0,
1925
- gap: 3,
2012
+ defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
2013
+ name: "discard-options",
2014
+ "aria-label": formatMessage({
2015
+ id: "content-manager.actions.unpublish.dialog.radio-label",
2016
+ defaultMessage: "Choose an option to unpublish the document."
2017
+ }),
2018
+ onValueChange: handleChange,
1926
2019
  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
- )
2020
+ /* @__PURE__ */ jsx(Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
2021
+ id: "content-manager.actions.unpublish.dialog.option.keep-draft",
2022
+ defaultMessage: "Keep draft"
2023
+ }) }),
2024
+ /* @__PURE__ */ jsx(Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
2025
+ id: "content-manager.actions.unpublish.dialog.option.replace-draft",
2026
+ defaultMessage: "Replace draft"
2027
+ }) })
1952
2028
  ]
1953
2029
  }
1954
2030
  )
@@ -2094,23 +2170,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2094
2170
  id: "content-manager.containers.edit.title.new",
2095
2171
  defaultMessage: "Create an entry"
2096
2172
  }) : documentTitle;
2097
- return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 8, paddingBottom: 4, gap: 3, children: [
2173
+ return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
2098
2174
  /* @__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
2175
+ /* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
2176
+ /* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
2177
+ /* @__PURE__ */ jsx(HeaderToolbar, {})
2178
+ ] }),
2179
+ status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
2114
2180
  ] });
2115
2181
  };
2116
2182
  const HeaderToolbar = () => {
@@ -2801,30 +2867,23 @@ const ConfirmBulkActionDialog = ({
2801
2867
  endAction
2802
2868
  }) => {
2803
2869
  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
- );
2870
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
2871
+ /* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
2872
+ id: "app.components.ConfirmDialog.title",
2873
+ defaultMessage: "Confirmation"
2874
+ }) }),
2875
+ /* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
2876
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
2877
+ dialogBody
2878
+ ] }) }),
2879
+ /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
2880
+ /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
2881
+ id: "app.components.Button.cancel",
2882
+ defaultMessage: "Cancel"
2883
+ }) }) }),
2884
+ endAction
2885
+ ] })
2886
+ ] }) });
2828
2887
  };
2829
2888
  const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
2830
2889
  const ConfirmDialogPublishAll = ({
@@ -2929,7 +2988,14 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
2929
2988
  )
2930
2989
  );
2931
2990
  } else {
2932
- messages.push(...formatErrorMessages(value, currentKey, formatMessage));
2991
+ messages.push(
2992
+ ...formatErrorMessages(
2993
+ // @ts-expect-error TODO: check why value is not compatible with FormErrors
2994
+ value,
2995
+ currentKey,
2996
+ formatMessage
2997
+ )
2998
+ );
2933
2999
  }
2934
3000
  } else {
2935
3001
  messages.push(
@@ -3166,7 +3232,7 @@ const SelectedEntriesModalContent = ({
3166
3232
  );
3167
3233
  };
3168
3234
  return /* @__PURE__ */ jsxs(Fragment, { children: [
3169
- /* @__PURE__ */ jsxs(ModalBody, { children: [
3235
+ /* @__PURE__ */ jsxs(Modal.Body, { children: [
3170
3236
  /* @__PURE__ */ jsx(Typography, { children: getFormattedCountMessage() }),
3171
3237
  /* @__PURE__ */ jsx(Box, { marginTop: 5, children: /* @__PURE__ */ jsx(
3172
3238
  SelectedEntriesTableContent,
@@ -3178,27 +3244,24 @@ const SelectedEntriesModalContent = ({
3178
3244
  }
3179
3245
  ) })
3180
3246
  ] }),
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
- ),
3247
+ /* @__PURE__ */ jsxs(Modal.Footer, { children: [
3248
+ /* @__PURE__ */ jsx(Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
3249
+ id: "app.components.Button.cancel",
3250
+ defaultMessage: "Cancel"
3251
+ }) }),
3252
+ /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3253
+ /* @__PURE__ */ jsx(Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
3254
+ /* @__PURE__ */ jsx(
3255
+ Button,
3256
+ {
3257
+ onClick: toggleDialog,
3258
+ disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
3259
+ loading: isSubmittingForm,
3260
+ children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
3261
+ }
3262
+ )
3263
+ ] })
3264
+ ] }),
3202
3265
  /* @__PURE__ */ jsx(
3203
3266
  ConfirmDialogPublishAll,
3204
3267
  {
@@ -3263,143 +3326,10 @@ const BulkActionsRenderer = () => {
3263
3326
  documents: selectedRows
3264
3327
  },
3265
3328
  descriptions: plugins["content-manager"].apis.getBulkActions(),
3266
- children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(BulkActionAction, { ...action }, action.id))
3329
+ children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(DocumentActionButton, { ...action }, action.id))
3267
3330
  }
3268
3331
  ) });
3269
3332
  };
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
3333
  const DeleteAction = ({ documents, model }) => {
3404
3334
  const { formatMessage } = useIntl();
3405
3335
  const { schema: contentType } = useDoc();
@@ -3432,6 +3362,7 @@ const DeleteAction = ({ documents, model }) => {
3432
3362
  defaultMessage: "Confirmation"
3433
3363
  }),
3434
3364
  content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3365
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3435
3366
  /* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3436
3367
  id: "popUpWarning.bodyMessage.contentType.delete.all",
3437
3368
  defaultMessage: "Are you sure you want to delete these entries?"
@@ -3481,6 +3412,7 @@ const UnpublishAction = ({ documents, model }) => {
3481
3412
  defaultMessage: "Confirmation"
3482
3413
  }),
3483
3414
  content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3415
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3484
3416
  /* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3485
3417
  id: "popUpWarning.bodyMessage.contentType.unpublish.all",
3486
3418
  defaultMessage: "Are you sure you want to unpublish these entries?"
@@ -3726,8 +3658,7 @@ class ContentManagerPlugin {
3726
3658
  documentActions = [
3727
3659
  ...DEFAULT_ACTIONS,
3728
3660
  ...DEFAULT_TABLE_ROW_ACTIONS,
3729
- ...DEFAULT_HEADER_ACTIONS,
3730
- HistoryAction
3661
+ ...DEFAULT_HEADER_ACTIONS
3731
3662
  ];
3732
3663
  editViewSidePanels = [ActionsPanel];
3733
3664
  headerActions = [];
@@ -3816,6 +3747,52 @@ const getPrintableType = (value) => {
3816
3747
  }
3817
3748
  return nativeType;
3818
3749
  };
3750
+ const HistoryAction = ({ model, document }) => {
3751
+ const { formatMessage } = useIntl();
3752
+ const [{ query }] = useQueryParams();
3753
+ const navigate = useNavigate();
3754
+ const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
3755
+ if (!window.strapi.features.isEnabled("cms-content-history")) {
3756
+ return null;
3757
+ }
3758
+ return {
3759
+ icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
3760
+ label: formatMessage({
3761
+ id: "content-manager.history.document-action",
3762
+ defaultMessage: "Content History"
3763
+ }),
3764
+ onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
3765
+ disabled: (
3766
+ /**
3767
+ * The user is creating a new document.
3768
+ * It hasn't been saved yet, so there's no history to go to
3769
+ */
3770
+ !document || /**
3771
+ * The document has been created but the current dimension has never been saved.
3772
+ * For example, the user is creating a new locale in an existing document,
3773
+ * so there's no history for the document in that locale
3774
+ */
3775
+ !document.id || /**
3776
+ * History is only available for content types created by the user.
3777
+ * These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
3778
+ * which start with `admin::` or `plugin::`
3779
+ */
3780
+ !model.startsWith("api::")
3781
+ ),
3782
+ position: "header"
3783
+ };
3784
+ };
3785
+ HistoryAction.type = "history";
3786
+ const historyAdmin = {
3787
+ bootstrap(app) {
3788
+ const { addDocumentAction } = app.getPlugin("content-manager").apis;
3789
+ addDocumentAction((actions2) => {
3790
+ const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
3791
+ actions2.splice(indexOfDeleteAction, 0, HistoryAction);
3792
+ return actions2;
3793
+ });
3794
+ }
3795
+ };
3819
3796
  const initialState = {
3820
3797
  collectionTypeLinks: [],
3821
3798
  components: [],
@@ -3866,15 +3843,29 @@ const index = {
3866
3843
  defaultMessage: "Content Manager"
3867
3844
  },
3868
3845
  permissions: [],
3869
- Component: () => import("./layout-BzAbmoO6.mjs").then((mod) => ({ default: mod.Layout })),
3870
3846
  position: 1
3871
3847
  });
3848
+ app.router.addRoute({
3849
+ path: "content-manager/*",
3850
+ lazy: async () => {
3851
+ const { Layout } = await import("./layout-oPBiO7RY.mjs");
3852
+ return {
3853
+ Component: Layout
3854
+ };
3855
+ },
3856
+ children: routes
3857
+ });
3872
3858
  app.registerPlugin(cm.config);
3873
3859
  },
3860
+ bootstrap(app) {
3861
+ if (typeof historyAdmin.bootstrap === "function") {
3862
+ historyAdmin.bootstrap(app);
3863
+ }
3864
+ },
3874
3865
  async registerTrads({ locales }) {
3875
3866
  const importedTrads = await Promise.all(
3876
3867
  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 }) => {
3868
+ 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
3869
  return {
3879
3870
  data: prefixPluginTranslations(data, PLUGIN_ID),
3880
3871
  locale
@@ -3895,14 +3886,13 @@ export {
3895
3886
  BulkActionsRenderer as B,
3896
3887
  COLLECTION_TYPES as C,
3897
3888
  DocumentStatus as D,
3898
- extractContentTypeComponents as E,
3899
- DEFAULT_SETTINGS as F,
3900
- convertEditLayoutToFieldLayouts as G,
3889
+ DEFAULT_SETTINGS as E,
3890
+ convertEditLayoutToFieldLayouts as F,
3891
+ useDocument as G,
3901
3892
  HOOKS as H,
3902
3893
  InjectionZone as I,
3903
- useDocument as J,
3904
- index as K,
3905
- useDocumentActions as L,
3894
+ index as J,
3895
+ useDocumentActions as K,
3906
3896
  Panels as P,
3907
3897
  RelativeTime as R,
3908
3898
  SINGLE_TYPES as S,
@@ -3924,14 +3914,14 @@ export {
3924
3914
  useGetContentTypeConfigurationQuery as o,
3925
3915
  CREATOR_FIELDS as p,
3926
3916
  getMainField as q,
3927
- routes as r,
3917
+ getDisplayName as r,
3928
3918
  setInitialData as s,
3929
- getDisplayName as t,
3919
+ checkIfAttributeIsDisplayable as t,
3930
3920
  useContentTypeSchema as u,
3931
- checkIfAttributeIsDisplayable as v,
3932
- useGetAllDocumentsQuery as w,
3933
- convertListLayoutToFieldLayouts as x,
3934
- capitalise as y,
3935
- useUpdateContentTypeConfigurationMutation as z
3921
+ useGetAllDocumentsQuery as v,
3922
+ convertListLayoutToFieldLayouts as w,
3923
+ capitalise as x,
3924
+ useUpdateContentTypeConfigurationMutation as y,
3925
+ extractContentTypeComponents as z
3936
3926
  };
3937
- //# sourceMappingURL=index-Drt2DN7v.mjs.map
3927
+ //# sourceMappingURL=index-c_5DdJi-.mjs.map