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

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 (104) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-y_7iLdmB.js → ComponentConfigurationPage-k6fnZytn.js} +3 -3
  3. package/dist/_chunks/{ComponentConfigurationPage-y_7iLdmB.js.map → ComponentConfigurationPage-k6fnZytn.js.map} +1 -1
  4. package/dist/_chunks/{ComponentConfigurationPage-BMajAl1u.mjs → ComponentConfigurationPage-o2HOTHL4.mjs} +3 -3
  5. package/dist/_chunks/{ComponentConfigurationPage-BMajAl1u.mjs.map → ComponentConfigurationPage-o2HOTHL4.mjs.map} +1 -1
  6. package/dist/_chunks/{EditConfigurationPage-CPVB8Uqc.js → EditConfigurationPage-DKtok23W.js} +3 -3
  7. package/dist/_chunks/{EditConfigurationPage-CPVB8Uqc.js.map → EditConfigurationPage-DKtok23W.js.map} +1 -1
  8. package/dist/_chunks/{EditConfigurationPage-CcOoD26O.mjs → EditConfigurationPage-HNi0pVX4.mjs} +3 -3
  9. package/dist/_chunks/{EditConfigurationPage-CcOoD26O.mjs.map → EditConfigurationPage-HNi0pVX4.mjs.map} +1 -1
  10. package/dist/_chunks/{EditViewPage-CTTDHKkQ.js → EditViewPage-CrX5Iz3h.js} +45 -45
  11. package/dist/_chunks/EditViewPage-CrX5Iz3h.js.map +1 -0
  12. package/dist/_chunks/{EditViewPage-DWb0DE7R.mjs → EditViewPage-DGnFsrTV.mjs} +46 -46
  13. package/dist/_chunks/EditViewPage-DGnFsrTV.mjs.map +1 -0
  14. package/dist/_chunks/{Field-DnStdvQw.mjs → Field-DlWgNyun.mjs} +422 -142
  15. package/dist/_chunks/Field-DlWgNyun.mjs.map +1 -0
  16. package/dist/_chunks/{Field-C5Z1Ivdv.js → Field-DvDdA59J.js} +421 -141
  17. package/dist/_chunks/Field-DvDdA59J.js.map +1 -0
  18. package/dist/_chunks/{Form-DqGgE55Q.mjs → Form-B7VJjkXr.mjs} +27 -28
  19. package/dist/_chunks/Form-B7VJjkXr.mjs.map +1 -0
  20. package/dist/_chunks/{Form-B81OtW-k.js → Form-D9w2wzOa.js} +25 -26
  21. package/dist/_chunks/Form-D9w2wzOa.js.map +1 -0
  22. package/dist/_chunks/{History-DS6-HCYX.mjs → History-84QY4Lau.mjs} +52 -29
  23. package/dist/_chunks/History-84QY4Lau.mjs.map +1 -0
  24. package/dist/_chunks/{History-4NbOq2dX.js → History-GCscEVds.js} +51 -28
  25. package/dist/_chunks/History-GCscEVds.js.map +1 -0
  26. package/dist/_chunks/{ListConfigurationPage-DQJJltko.mjs → ListConfigurationPage-C_S6OFYL.mjs} +49 -49
  27. package/dist/_chunks/ListConfigurationPage-C_S6OFYL.mjs.map +1 -0
  28. package/dist/_chunks/{ListConfigurationPage-CpfstlYY.js → ListConfigurationPage-Ck-lKA_g.js} +48 -47
  29. package/dist/_chunks/ListConfigurationPage-Ck-lKA_g.js.map +1 -0
  30. package/dist/_chunks/{ListViewPage-CA3I75m5.js → ListViewPage-D1vAbQW4.js} +65 -68
  31. package/dist/_chunks/ListViewPage-D1vAbQW4.js.map +1 -0
  32. package/dist/_chunks/{ListViewPage-nQrOQuVo.mjs → ListViewPage-DkQT6AN6.mjs} +67 -70
  33. package/dist/_chunks/ListViewPage-DkQT6AN6.mjs.map +1 -0
  34. package/dist/_chunks/{NoContentTypePage-DbnHE22g.mjs → NoContentTypePage-D5QYn9pN.mjs} +2 -2
  35. package/dist/_chunks/{NoContentTypePage-DbnHE22g.mjs.map → NoContentTypePage-D5QYn9pN.mjs.map} +1 -1
  36. package/dist/_chunks/{NoContentTypePage-Dldu-_Mx.js → NoContentTypePage-DnMToxdO.js} +2 -2
  37. package/dist/_chunks/{NoContentTypePage-Dldu-_Mx.js.map → NoContentTypePage-DnMToxdO.js.map} +1 -1
  38. package/dist/_chunks/{NoPermissionsPage-CO2MK200.js → NoPermissionsPage-COirbirm.js} +2 -2
  39. package/dist/_chunks/{NoPermissionsPage-CO2MK200.js.map → NoPermissionsPage-COirbirm.js.map} +1 -1
  40. package/dist/_chunks/{NoPermissionsPage-fOIkQM0v.mjs → NoPermissionsPage-eV9XOUs6.mjs} +2 -2
  41. package/dist/_chunks/{NoPermissionsPage-fOIkQM0v.mjs.map → NoPermissionsPage-eV9XOUs6.mjs.map} +1 -1
  42. package/dist/_chunks/{Relations-BDRl99Ux.mjs → Relations-CMu33f0Q.mjs} +3 -3
  43. package/dist/_chunks/Relations-CMu33f0Q.mjs.map +1 -0
  44. package/dist/_chunks/{Relations-DG2jnOcr.js → Relations-CvSHeSTB.js} +3 -3
  45. package/dist/_chunks/Relations-CvSHeSTB.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-BU73akFF.js} +371 -388
  51. package/dist/_chunks/index-BU73akFF.js.map +1 -0
  52. package/dist/_chunks/{index-Drt2DN7v.mjs → index-DYjyBm-q.mjs} +386 -403
  53. package/dist/_chunks/index-DYjyBm-q.mjs.map +1 -0
  54. package/dist/_chunks/{layout-BzAbmoO6.mjs → layout-CK49ltFD.mjs} +22 -10
  55. package/dist/_chunks/layout-CK49ltFD.mjs.map +1 -0
  56. package/dist/_chunks/{layout-DEYBqgF1.js → layout-IJUR2XBA.js} +20 -8
  57. package/dist/_chunks/layout-IJUR2XBA.js.map +1 -0
  58. package/dist/_chunks/{relations-D26zVRdi.mjs → relations-Dl8Jk9_i.mjs} +2 -2
  59. package/dist/_chunks/{relations-D26zVRdi.mjs.map → relations-Dl8Jk9_i.mjs.map} +1 -1
  60. package/dist/_chunks/{relations-D0eZ4VWw.js → relations-T1zuutNL.js} +2 -2
  61. package/dist/_chunks/{relations-D0eZ4VWw.js.map → relations-T1zuutNL.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 +137 -87
  73. package/dist/server/index.js.map +1 -1
  74. package/dist/server/index.mjs +138 -88
  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 +1 -1
  82. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  83. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  84. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  85. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  86. package/package.json +8 -8
  87. package/dist/_chunks/EditViewPage-CTTDHKkQ.js.map +0 -1
  88. package/dist/_chunks/EditViewPage-DWb0DE7R.mjs.map +0 -1
  89. package/dist/_chunks/Field-C5Z1Ivdv.js.map +0 -1
  90. package/dist/_chunks/Field-DnStdvQw.mjs.map +0 -1
  91. package/dist/_chunks/Form-B81OtW-k.js.map +0 -1
  92. package/dist/_chunks/Form-DqGgE55Q.mjs.map +0 -1
  93. package/dist/_chunks/History-4NbOq2dX.js.map +0 -1
  94. package/dist/_chunks/History-DS6-HCYX.mjs.map +0 -1
  95. package/dist/_chunks/ListConfigurationPage-CpfstlYY.js.map +0 -1
  96. package/dist/_chunks/ListConfigurationPage-DQJJltko.mjs.map +0 -1
  97. package/dist/_chunks/ListViewPage-CA3I75m5.js.map +0 -1
  98. package/dist/_chunks/ListViewPage-nQrOQuVo.mjs.map +0 -1
  99. package/dist/_chunks/Relations-BDRl99Ux.mjs.map +0 -1
  100. package/dist/_chunks/Relations-DG2jnOcr.js.map +0 -1
  101. package/dist/_chunks/index-BZoNZMXL.js.map +0 -1
  102. package/dist/_chunks/index-Drt2DN7v.mjs.map +0 -1
  103. package/dist/_chunks/layout-BzAbmoO6.mjs.map +0 -1
  104. 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, Typography, Dialog, Modal, Radio, Status, Box, 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 }) => ({
@@ -294,6 +264,7 @@ const documentApi = contentManagerApi.injectEndpoints({
294
264
  }),
295
265
  providesTags: (result, _error, arg) => {
296
266
  return [
267
+ { type: "Document", id: `ALL_LIST` },
297
268
  { type: "Document", id: `${arg.model}_LIST` },
298
269
  ...result?.results.map(({ documentId }) => ({
299
270
  type: "Document",
@@ -397,6 +368,18 @@ const documentApi = contentManagerApi.injectEndpoints({
397
368
  },
398
369
  "Relations"
399
370
  ];
371
+ },
372
+ async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
373
+ const patchResult = dispatch(
374
+ documentApi.util.updateQueryData("getDocument", patch, (draft) => {
375
+ Object.assign(draft.data, data);
376
+ })
377
+ );
378
+ try {
379
+ await queryFulfilled;
380
+ } catch {
381
+ patchResult.undo();
382
+ }
400
383
  }
401
384
  }),
402
385
  unpublishDocument: builder.mutation({
@@ -599,11 +582,11 @@ const createAttributeSchema = (attribute) => {
599
582
  }
600
583
  };
601
584
  const addRequiredValidation = (attribute) => (schema) => {
602
- if (attribute.required) {
603
- return schema.required({
604
- id: translatedErrors.required.id,
605
- defaultMessage: "This field is required."
606
- });
585
+ if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
586
+ return schema.min(1, translatedErrors.required);
587
+ }
588
+ if (attribute.required && attribute.type !== "relation") {
589
+ return schema.required(translatedErrors.required);
607
590
  }
608
591
  return schema?.nullable ? schema.nullable() : (
609
592
  // In some cases '.nullable' will not be available on the schema.
@@ -637,6 +620,28 @@ const addMaxLengthValidation = (attribute) => (schema) => {
637
620
  const addMinValidation = (attribute) => (schema) => {
638
621
  if ("min" in attribute) {
639
622
  const min = toInteger(attribute.min);
623
+ if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
624
+ if (!attribute.required && "test" in schema && min) {
625
+ return schema.test(
626
+ "custom-min",
627
+ {
628
+ ...translatedErrors.min,
629
+ values: {
630
+ min: attribute.min
631
+ }
632
+ },
633
+ (value) => {
634
+ if (!value) {
635
+ return true;
636
+ }
637
+ if (Array.isArray(value) && value.length === 0) {
638
+ return true;
639
+ }
640
+ return value.length >= min;
641
+ }
642
+ );
643
+ }
644
+ }
640
645
  if ("min" in schema && min) {
641
646
  return schema.min(min, {
642
647
  ...translatedErrors.min,
@@ -763,7 +768,10 @@ const useDocument = (args, opts) => {
763
768
  isLoading: isLoadingDocument,
764
769
  isFetching: isFetchingDocument,
765
770
  error
766
- } = useGetDocumentQuery(args, opts);
771
+ } = useGetDocumentQuery(args, {
772
+ ...opts,
773
+ skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
774
+ });
767
775
  const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
768
776
  React.useEffect(() => {
769
777
  if (error) {
@@ -1184,7 +1192,6 @@ const useDocumentActions = () => {
1184
1192
  sourceId
1185
1193
  });
1186
1194
  if ("error" in res) {
1187
- toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1188
1195
  return { error: res.error };
1189
1196
  }
1190
1197
  toggleNotification({
@@ -1265,7 +1272,7 @@ const useDocumentActions = () => {
1265
1272
  };
1266
1273
  };
1267
1274
  const ProtectedHistoryPage = lazy(
1268
- () => import("./History-DS6-HCYX.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1275
+ () => import("./History-84QY4Lau.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1269
1276
  );
1270
1277
  const routes$1 = [
1271
1278
  {
@@ -1278,31 +1285,31 @@ const routes$1 = [
1278
1285
  }
1279
1286
  ];
1280
1287
  const ProtectedEditViewPage = lazy(
1281
- () => import("./EditViewPage-DWb0DE7R.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1288
+ () => import("./EditViewPage-DGnFsrTV.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1282
1289
  );
1283
1290
  const ProtectedListViewPage = lazy(
1284
- () => import("./ListViewPage-nQrOQuVo.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1291
+ () => import("./ListViewPage-DkQT6AN6.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1285
1292
  );
1286
1293
  const ProtectedListConfiguration = lazy(
1287
- () => import("./ListConfigurationPage-DQJJltko.mjs").then((mod) => ({
1294
+ () => import("./ListConfigurationPage-C_S6OFYL.mjs").then((mod) => ({
1288
1295
  default: mod.ProtectedListConfiguration
1289
1296
  }))
1290
1297
  );
1291
1298
  const ProtectedEditConfigurationPage = lazy(
1292
- () => import("./EditConfigurationPage-CcOoD26O.mjs").then((mod) => ({
1299
+ () => import("./EditConfigurationPage-HNi0pVX4.mjs").then((mod) => ({
1293
1300
  default: mod.ProtectedEditConfigurationPage
1294
1301
  }))
1295
1302
  );
1296
1303
  const ProtectedComponentConfigurationPage = lazy(
1297
- () => import("./ComponentConfigurationPage-BMajAl1u.mjs").then((mod) => ({
1304
+ () => import("./ComponentConfigurationPage-o2HOTHL4.mjs").then((mod) => ({
1298
1305
  default: mod.ProtectedComponentConfigurationPage
1299
1306
  }))
1300
1307
  );
1301
1308
  const NoPermissions = lazy(
1302
- () => import("./NoPermissionsPage-fOIkQM0v.mjs").then((mod) => ({ default: mod.NoPermissions }))
1309
+ () => import("./NoPermissionsPage-eV9XOUs6.mjs").then((mod) => ({ default: mod.NoPermissions }))
1303
1310
  );
1304
1311
  const NoContentType = lazy(
1305
- () => import("./NoContentTypePage-DbnHE22g.mjs").then((mod) => ({ default: mod.NoContentType }))
1312
+ () => import("./NoContentTypePage-D5QYn9pN.mjs").then((mod) => ({ default: mod.NoContentType }))
1306
1313
  );
1307
1314
  const CollectionTypePages = () => {
1308
1315
  const { collectionType } = useParams();
@@ -1416,7 +1423,7 @@ const DocumentActionButton = (action) => {
1416
1423
  /* @__PURE__ */ jsx(
1417
1424
  Button,
1418
1425
  {
1419
- flex: 1,
1426
+ flex: "auto",
1420
1427
  startIcon: action.icon,
1421
1428
  disabled: action.disabled,
1422
1429
  onClick: handleClick(action),
@@ -1429,7 +1436,7 @@ const DocumentActionButton = (action) => {
1429
1436
  DocumentActionConfirmDialog,
1430
1437
  {
1431
1438
  ...action.dialog,
1432
- variant: action.variant,
1439
+ variant: action.dialog?.variant ?? action.variant,
1433
1440
  isOpen: dialogId === action.id,
1434
1441
  onClose: handleClose
1435
1442
  }
@@ -1486,9 +1493,9 @@ const DocumentActionsMenu = ({
1486
1493
  disabled: isDisabled,
1487
1494
  size: "S",
1488
1495
  endIcon: null,
1489
- paddingTop: "7px",
1490
- paddingLeft: "9px",
1491
- paddingRight: "9px",
1496
+ paddingTop: "4px",
1497
+ paddingLeft: "7px",
1498
+ paddingRight: "7px",
1492
1499
  variant,
1493
1500
  children: [
1494
1501
  /* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
@@ -1508,10 +1515,18 @@ const DocumentActionsMenu = ({
1508
1515
  onSelect: handleClick(action),
1509
1516
  display: "block",
1510
1517
  children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
1511
- /* @__PURE__ */ jsxs(Flex, { color: convertActionVariantToColor(action.variant), gap: 2, tag: "span", children: [
1512
- action.icon,
1513
- action.label
1514
- ] }),
1518
+ /* @__PURE__ */ jsxs(
1519
+ Flex,
1520
+ {
1521
+ color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
1522
+ gap: 2,
1523
+ tag: "span",
1524
+ children: [
1525
+ /* @__PURE__ */ jsx("span", { children: action.icon }),
1526
+ action.label
1527
+ ]
1528
+ }
1529
+ ),
1515
1530
  action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
1516
1531
  Flex,
1517
1532
  {
@@ -1592,22 +1607,20 @@ const DocumentActionConfirmDialog = ({
1592
1607
  }
1593
1608
  onClose();
1594
1609
  };
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
- ] });
1610
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
1611
+ /* @__PURE__ */ jsx(Dialog.Header, { children: title }),
1612
+ /* @__PURE__ */ jsx(Dialog.Body, { children: content }),
1613
+ /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
1614
+ /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
1615
+ id: "app.components.Button.cancel",
1616
+ defaultMessage: "Cancel"
1617
+ }) }) }),
1618
+ /* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
1619
+ id: "app.components.Button.confirm",
1620
+ defaultMessage: "Confirm"
1621
+ }) })
1622
+ ] })
1623
+ ] }) });
1611
1624
  };
1612
1625
  const DocumentActionModal = ({
1613
1626
  isOpen,
@@ -1617,34 +1630,17 @@ const DocumentActionModal = ({
1617
1630
  content: Content,
1618
1631
  onModalClose
1619
1632
  }) => {
1620
- const id = React.useId();
1621
- if (!isOpen) {
1622
- return null;
1623
- }
1624
1633
  const handleClose = () => {
1625
1634
  if (onClose) {
1626
1635
  onClose();
1627
1636
  }
1628
1637
  onModalClose();
1629
1638
  };
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
- ] });
1639
+ return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
1640
+ /* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
1641
+ typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
1642
+ typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
1643
+ ] }) });
1648
1644
  };
1649
1645
  const PublishAction$1 = ({
1650
1646
  activeTab,
@@ -1665,6 +1661,12 @@ const PublishAction$1 = ({
1665
1661
  ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
1666
1662
  );
1667
1663
  const { publish } = useDocumentActions();
1664
+ const [
1665
+ countDraftRelations,
1666
+ { isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
1667
+ ] = useLazyGetDraftRelationCountQuery();
1668
+ const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
1669
+ const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
1668
1670
  const [{ query, rawQuery }] = useQueryParams();
1669
1671
  const params = React.useMemo(() => buildValidParams(query), [query]);
1670
1672
  const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
@@ -1673,10 +1675,101 @@ const PublishAction$1 = ({
1673
1675
  const validate = useForm("PublishAction", (state) => state.validate);
1674
1676
  const setErrors = useForm("PublishAction", (state) => state.setErrors);
1675
1677
  const formValues = useForm("PublishAction", ({ values }) => values);
1678
+ React.useEffect(() => {
1679
+ if (isErrorDraftRelations) {
1680
+ toggleNotification({
1681
+ type: "danger",
1682
+ message: formatMessage({
1683
+ id: getTranslation("error.records.fetch-draft-relatons"),
1684
+ defaultMessage: "An error occurred while fetching draft relations on this document."
1685
+ })
1686
+ });
1687
+ }
1688
+ }, [isErrorDraftRelations, toggleNotification, formatMessage]);
1689
+ React.useEffect(() => {
1690
+ const localDraftRelations = /* @__PURE__ */ new Set();
1691
+ const extractDraftRelations = (data) => {
1692
+ const relations = data.connect || [];
1693
+ relations.forEach((relation) => {
1694
+ if (relation.status === "draft") {
1695
+ localDraftRelations.add(relation.id);
1696
+ }
1697
+ });
1698
+ };
1699
+ const traverseAndExtract = (data) => {
1700
+ Object.entries(data).forEach(([key, value]) => {
1701
+ if (key === "connect" && Array.isArray(value)) {
1702
+ extractDraftRelations({ connect: value });
1703
+ } else if (typeof value === "object" && value !== null) {
1704
+ traverseAndExtract(value);
1705
+ }
1706
+ });
1707
+ };
1708
+ if (!documentId || modified) {
1709
+ traverseAndExtract(formValues);
1710
+ setLocalCountOfDraftRelations(localDraftRelations.size);
1711
+ }
1712
+ }, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
1713
+ React.useEffect(() => {
1714
+ if (documentId) {
1715
+ const fetchDraftRelationsCount = async () => {
1716
+ const { data, error } = await countDraftRelations({
1717
+ collectionType,
1718
+ model,
1719
+ documentId,
1720
+ params
1721
+ });
1722
+ if (error) {
1723
+ throw error;
1724
+ }
1725
+ if (data) {
1726
+ setServerCountOfDraftRelations(data.data);
1727
+ }
1728
+ };
1729
+ fetchDraftRelationsCount();
1730
+ }
1731
+ }, [documentId, countDraftRelations, collectionType, model, params]);
1676
1732
  const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
1677
1733
  if (!schema?.options?.draftAndPublish) {
1678
1734
  return null;
1679
1735
  }
1736
+ const performPublish = async () => {
1737
+ setSubmitting(true);
1738
+ try {
1739
+ const { errors } = await validate();
1740
+ if (errors) {
1741
+ toggleNotification({
1742
+ type: "danger",
1743
+ message: formatMessage({
1744
+ id: "content-manager.validation.error",
1745
+ defaultMessage: "There are validation errors in your document. Please fix them before saving."
1746
+ })
1747
+ });
1748
+ return;
1749
+ }
1750
+ const res = await publish(
1751
+ {
1752
+ collectionType,
1753
+ model,
1754
+ documentId,
1755
+ params
1756
+ },
1757
+ formValues
1758
+ );
1759
+ if ("data" in res && collectionType !== SINGLE_TYPES) {
1760
+ navigate({
1761
+ pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1762
+ search: rawQuery
1763
+ });
1764
+ } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1765
+ setErrors(formatValidationErrors(res.error));
1766
+ }
1767
+ } finally {
1768
+ setSubmitting(false);
1769
+ }
1770
+ };
1771
+ const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
1772
+ const hasDraftRelations = totalDraftRelations > 0;
1680
1773
  return {
1681
1774
  /**
1682
1775
  * Disabled when:
@@ -1686,49 +1779,39 @@ const PublishAction$1 = ({
1686
1779
  * - the document is already published & not modified
1687
1780
  * - the document is being created & not modified
1688
1781
  * - the user doesn't have the permission to publish
1689
- * - the user doesn't have the permission to create a new document
1690
- * - the user doesn't have the permission to update the document
1691
1782
  */
1692
- disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
1783
+ disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
1693
1784
  label: formatMessage({
1694
1785
  id: "app.utils.publish",
1695
1786
  defaultMessage: "Publish"
1696
1787
  }),
1697
1788
  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));
1789
+ if (hasDraftRelations) {
1790
+ return;
1791
+ }
1792
+ await performPublish();
1793
+ },
1794
+ dialog: hasDraftRelations ? {
1795
+ type: "dialog",
1796
+ variant: "danger",
1797
+ footer: null,
1798
+ title: formatMessage({
1799
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
1800
+ defaultMessage: "Confirmation"
1801
+ }),
1802
+ content: formatMessage(
1803
+ {
1804
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
1805
+ defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
1806
+ },
1807
+ {
1808
+ count: totalDraftRelations
1727
1809
  }
1728
- } finally {
1729
- setSubmitting(false);
1810
+ ),
1811
+ onConfirm: async () => {
1812
+ await performPublish();
1730
1813
  }
1731
- }
1814
+ } : void 0
1732
1815
  };
1733
1816
  };
1734
1817
  PublishAction$1.type = "publish";
@@ -1744,7 +1827,7 @@ const UpdateAction = ({
1744
1827
  const cloneMatch = useMatch(CLONE_PATH);
1745
1828
  const isCloning = cloneMatch !== null;
1746
1829
  const { formatMessage } = useIntl();
1747
- const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
1830
+ useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
1748
1831
  canCreate: canCreate2,
1749
1832
  canUpdate: canUpdate2
1750
1833
  }));
@@ -1764,10 +1847,8 @@ const UpdateAction = ({
1764
1847
  * - the form is submitting
1765
1848
  * - the document is not modified & we're not cloning (you can save a clone entity straight away)
1766
1849
  * - the active tab is the published tab
1767
- * - the user doesn't have the permission to create a new document
1768
- * - the user doesn't have the permission to update the document
1769
1850
  */
1770
- disabled: isSubmitting || !modified && !isCloning || activeTab === "published" || Boolean(!documentId && !canCreate || documentId && !canUpdate),
1851
+ disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
1771
1852
  label: formatMessage({
1772
1853
  id: "content-manager.containers.Edit.save",
1773
1854
  defaultMessage: "Save"
@@ -1796,10 +1877,13 @@ const UpdateAction = ({
1796
1877
  document
1797
1878
  );
1798
1879
  if ("data" in res) {
1799
- navigate({
1800
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1801
- search: rawQuery
1802
- });
1880
+ navigate(
1881
+ {
1882
+ pathname: `../${res.data.documentId}`,
1883
+ search: rawQuery
1884
+ },
1885
+ { relative: "path" }
1886
+ );
1803
1887
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1804
1888
  setErrors(formatValidationErrors(res.error));
1805
1889
  }
@@ -1827,10 +1911,13 @@ const UpdateAction = ({
1827
1911
  document
1828
1912
  );
1829
1913
  if ("data" in res && collectionType !== SINGLE_TYPES) {
1830
- navigate({
1831
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1832
- search: rawQuery
1833
- });
1914
+ navigate(
1915
+ {
1916
+ pathname: `../${res.data.documentId}`,
1917
+ search: rawQuery
1918
+ },
1919
+ { replace: true, relative: "path" }
1920
+ );
1834
1921
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1835
1922
  setErrors(formatValidationErrors(res.error));
1836
1923
  }
@@ -1862,10 +1949,8 @@ const UnpublishAction$1 = ({
1862
1949
  const { toggleNotification } = useNotification();
1863
1950
  const [shouldKeepDraft, setShouldKeepDraft] = React.useState(true);
1864
1951
  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
- }
1952
+ const handleChange = (value) => {
1953
+ setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
1869
1954
  };
1870
1955
  if (!schema?.options?.draftAndPublish) {
1871
1956
  return null;
@@ -1915,40 +2000,24 @@ const UnpublishAction$1 = ({
1915
2000
  }) })
1916
2001
  ] }),
1917
2002
  /* @__PURE__ */ jsxs(
1918
- Flex,
2003
+ Radio.Group,
1919
2004
  {
1920
- onChange: handleChange,
1921
- direction: "column",
1922
- alignItems: "flex-start",
1923
- tag: "fieldset",
1924
- borderWidth: 0,
1925
- gap: 3,
2005
+ defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
2006
+ name: "discard-options",
2007
+ "aria-label": formatMessage({
2008
+ id: "content-manager.actions.unpublish.dialog.radio-label",
2009
+ defaultMessage: "Choose an option to unpublish the document."
2010
+ }),
2011
+ onValueChange: handleChange,
1926
2012
  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
- )
2013
+ /* @__PURE__ */ jsx(Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
2014
+ id: "content-manager.actions.unpublish.dialog.option.keep-draft",
2015
+ defaultMessage: "Keep draft"
2016
+ }) }),
2017
+ /* @__PURE__ */ jsx(Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
2018
+ id: "content-manager.actions.unpublish.dialog.option.replace-draft",
2019
+ defaultMessage: "Replace draft"
2020
+ }) })
1952
2021
  ]
1953
2022
  }
1954
2023
  )
@@ -2094,23 +2163,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2094
2163
  id: "content-manager.containers.edit.title.new",
2095
2164
  defaultMessage: "Create an entry"
2096
2165
  }) : documentTitle;
2097
- return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 8, paddingBottom: 4, gap: 3, children: [
2166
+ return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
2098
2167
  /* @__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
2168
+ /* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
2169
+ /* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
2170
+ /* @__PURE__ */ jsx(HeaderToolbar, {})
2171
+ ] }),
2172
+ status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
2114
2173
  ] });
2115
2174
  };
2116
2175
  const HeaderToolbar = () => {
@@ -2801,30 +2860,23 @@ const ConfirmBulkActionDialog = ({
2801
2860
  endAction
2802
2861
  }) => {
2803
2862
  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
- );
2863
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
2864
+ /* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
2865
+ id: "app.components.ConfirmDialog.title",
2866
+ defaultMessage: "Confirmation"
2867
+ }) }),
2868
+ /* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
2869
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
2870
+ dialogBody
2871
+ ] }) }),
2872
+ /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
2873
+ /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
2874
+ id: "app.components.Button.cancel",
2875
+ defaultMessage: "Cancel"
2876
+ }) }) }),
2877
+ endAction
2878
+ ] })
2879
+ ] }) });
2828
2880
  };
2829
2881
  const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
2830
2882
  const ConfirmDialogPublishAll = ({
@@ -2929,7 +2981,14 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
2929
2981
  )
2930
2982
  );
2931
2983
  } else {
2932
- messages.push(...formatErrorMessages(value, currentKey, formatMessage));
2984
+ messages.push(
2985
+ ...formatErrorMessages(
2986
+ // @ts-expect-error TODO: check why value is not compatible with FormErrors
2987
+ value,
2988
+ currentKey,
2989
+ formatMessage
2990
+ )
2991
+ );
2933
2992
  }
2934
2993
  } else {
2935
2994
  messages.push(
@@ -3166,7 +3225,7 @@ const SelectedEntriesModalContent = ({
3166
3225
  );
3167
3226
  };
3168
3227
  return /* @__PURE__ */ jsxs(Fragment, { children: [
3169
- /* @__PURE__ */ jsxs(ModalBody, { children: [
3228
+ /* @__PURE__ */ jsxs(Modal.Body, { children: [
3170
3229
  /* @__PURE__ */ jsx(Typography, { children: getFormattedCountMessage() }),
3171
3230
  /* @__PURE__ */ jsx(Box, { marginTop: 5, children: /* @__PURE__ */ jsx(
3172
3231
  SelectedEntriesTableContent,
@@ -3178,27 +3237,24 @@ const SelectedEntriesModalContent = ({
3178
3237
  }
3179
3238
  ) })
3180
3239
  ] }),
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
- ),
3240
+ /* @__PURE__ */ jsxs(Modal.Footer, { children: [
3241
+ /* @__PURE__ */ jsx(Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
3242
+ id: "app.components.Button.cancel",
3243
+ defaultMessage: "Cancel"
3244
+ }) }),
3245
+ /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3246
+ /* @__PURE__ */ jsx(Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
3247
+ /* @__PURE__ */ jsx(
3248
+ Button,
3249
+ {
3250
+ onClick: toggleDialog,
3251
+ disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
3252
+ loading: isSubmittingForm,
3253
+ children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
3254
+ }
3255
+ )
3256
+ ] })
3257
+ ] }),
3202
3258
  /* @__PURE__ */ jsx(
3203
3259
  ConfirmDialogPublishAll,
3204
3260
  {
@@ -3263,143 +3319,10 @@ const BulkActionsRenderer = () => {
3263
3319
  documents: selectedRows
3264
3320
  },
3265
3321
  descriptions: plugins["content-manager"].apis.getBulkActions(),
3266
- children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(BulkActionAction, { ...action }, action.id))
3322
+ children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(DocumentActionButton, { ...action }, action.id))
3267
3323
  }
3268
3324
  ) });
3269
3325
  };
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
3326
  const DeleteAction = ({ documents, model }) => {
3404
3327
  const { formatMessage } = useIntl();
3405
3328
  const { schema: contentType } = useDoc();
@@ -3432,6 +3355,7 @@ const DeleteAction = ({ documents, model }) => {
3432
3355
  defaultMessage: "Confirmation"
3433
3356
  }),
3434
3357
  content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3358
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3435
3359
  /* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3436
3360
  id: "popUpWarning.bodyMessage.contentType.delete.all",
3437
3361
  defaultMessage: "Are you sure you want to delete these entries?"
@@ -3481,6 +3405,7 @@ const UnpublishAction = ({ documents, model }) => {
3481
3405
  defaultMessage: "Confirmation"
3482
3406
  }),
3483
3407
  content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3408
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3484
3409
  /* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3485
3410
  id: "popUpWarning.bodyMessage.contentType.unpublish.all",
3486
3411
  defaultMessage: "Are you sure you want to unpublish these entries?"
@@ -3726,8 +3651,7 @@ class ContentManagerPlugin {
3726
3651
  documentActions = [
3727
3652
  ...DEFAULT_ACTIONS,
3728
3653
  ...DEFAULT_TABLE_ROW_ACTIONS,
3729
- ...DEFAULT_HEADER_ACTIONS,
3730
- HistoryAction
3654
+ ...DEFAULT_HEADER_ACTIONS
3731
3655
  ];
3732
3656
  editViewSidePanels = [ActionsPanel];
3733
3657
  headerActions = [];
@@ -3816,6 +3740,52 @@ const getPrintableType = (value) => {
3816
3740
  }
3817
3741
  return nativeType;
3818
3742
  };
3743
+ const HistoryAction = ({ model, document }) => {
3744
+ const { formatMessage } = useIntl();
3745
+ const [{ query }] = useQueryParams();
3746
+ const navigate = useNavigate();
3747
+ const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
3748
+ if (!window.strapi.features.isEnabled("cms-content-history")) {
3749
+ return null;
3750
+ }
3751
+ return {
3752
+ icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
3753
+ label: formatMessage({
3754
+ id: "content-manager.history.document-action",
3755
+ defaultMessage: "Content History"
3756
+ }),
3757
+ onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
3758
+ disabled: (
3759
+ /**
3760
+ * The user is creating a new document.
3761
+ * It hasn't been saved yet, so there's no history to go to
3762
+ */
3763
+ !document || /**
3764
+ * The document has been created but the current dimension has never been saved.
3765
+ * For example, the user is creating a new locale in an existing document,
3766
+ * so there's no history for the document in that locale
3767
+ */
3768
+ !document.id || /**
3769
+ * History is only available for content types created by the user.
3770
+ * These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
3771
+ * which start with `admin::` or `plugin::`
3772
+ */
3773
+ !model.startsWith("api::")
3774
+ ),
3775
+ position: "header"
3776
+ };
3777
+ };
3778
+ HistoryAction.type = "history";
3779
+ const historyAdmin = {
3780
+ bootstrap(app) {
3781
+ const { addDocumentAction } = app.getPlugin("content-manager").apis;
3782
+ addDocumentAction((actions2) => {
3783
+ const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
3784
+ actions2.splice(indexOfDeleteAction, 0, HistoryAction);
3785
+ return actions2;
3786
+ });
3787
+ }
3788
+ };
3819
3789
  const initialState = {
3820
3790
  collectionTypeLinks: [],
3821
3791
  components: [],
@@ -3866,15 +3836,29 @@ const index = {
3866
3836
  defaultMessage: "Content Manager"
3867
3837
  },
3868
3838
  permissions: [],
3869
- Component: () => import("./layout-BzAbmoO6.mjs").then((mod) => ({ default: mod.Layout })),
3870
3839
  position: 1
3871
3840
  });
3841
+ app.router.addRoute({
3842
+ path: "content-manager/*",
3843
+ lazy: async () => {
3844
+ const { Layout } = await import("./layout-CK49ltFD.mjs");
3845
+ return {
3846
+ Component: Layout
3847
+ };
3848
+ },
3849
+ children: routes
3850
+ });
3872
3851
  app.registerPlugin(cm.config);
3873
3852
  },
3853
+ bootstrap(app) {
3854
+ if (typeof historyAdmin.bootstrap === "function") {
3855
+ historyAdmin.bootstrap(app);
3856
+ }
3857
+ },
3874
3858
  async registerTrads({ locales }) {
3875
3859
  const importedTrads = await Promise.all(
3876
3860
  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 }) => {
3861
+ 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
3862
  return {
3879
3863
  data: prefixPluginTranslations(data, PLUGIN_ID),
3880
3864
  locale
@@ -3895,14 +3879,13 @@ export {
3895
3879
  BulkActionsRenderer as B,
3896
3880
  COLLECTION_TYPES as C,
3897
3881
  DocumentStatus as D,
3898
- extractContentTypeComponents as E,
3899
- DEFAULT_SETTINGS as F,
3900
- convertEditLayoutToFieldLayouts as G,
3882
+ DEFAULT_SETTINGS as E,
3883
+ convertEditLayoutToFieldLayouts as F,
3884
+ useDocument as G,
3901
3885
  HOOKS as H,
3902
3886
  InjectionZone as I,
3903
- useDocument as J,
3904
- index as K,
3905
- useDocumentActions as L,
3887
+ index as J,
3888
+ useDocumentActions as K,
3906
3889
  Panels as P,
3907
3890
  RelativeTime as R,
3908
3891
  SINGLE_TYPES as S,
@@ -3924,14 +3907,14 @@ export {
3924
3907
  useGetContentTypeConfigurationQuery as o,
3925
3908
  CREATOR_FIELDS as p,
3926
3909
  getMainField as q,
3927
- routes as r,
3910
+ getDisplayName as r,
3928
3911
  setInitialData as s,
3929
- getDisplayName as t,
3912
+ checkIfAttributeIsDisplayable as t,
3930
3913
  useContentTypeSchema as u,
3931
- checkIfAttributeIsDisplayable as v,
3932
- useGetAllDocumentsQuery as w,
3933
- convertListLayoutToFieldLayouts as x,
3934
- capitalise as y,
3935
- useUpdateContentTypeConfigurationMutation as z
3914
+ useGetAllDocumentsQuery as v,
3915
+ convertListLayoutToFieldLayouts as w,
3916
+ capitalise as x,
3917
+ useUpdateContentTypeConfigurationMutation as y,
3918
+ extractContentTypeComponents as z
3936
3919
  };
3937
- //# sourceMappingURL=index-Drt2DN7v.mjs.map
3920
+ //# sourceMappingURL=index-DYjyBm-q.mjs.map