@strapi/content-manager 0.0.0-experimental.62ce06180fe9a772eaeb3d43d238b26644f39f7c → 0.0.0-experimental.779667bd163026468f566293decf331a0246fff9

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 (96) hide show
  1. package/LICENSE +18 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-DErJQEVW.mjs → ComponentConfigurationPage-B1bIXVuX.mjs} +3 -3
  3. package/dist/_chunks/{ComponentConfigurationPage-DErJQEVW.mjs.map → ComponentConfigurationPage-B1bIXVuX.mjs.map} +1 -1
  4. package/dist/_chunks/{ComponentConfigurationPage-Cl7eB3s4.js → ComponentConfigurationPage-Bqgx7Mes.js} +3 -3
  5. package/dist/_chunks/{ComponentConfigurationPage-Cl7eB3s4.js.map → ComponentConfigurationPage-Bqgx7Mes.js.map} +1 -1
  6. package/dist/_chunks/{EditConfigurationPage-CyfFvH6-.js → EditConfigurationPage-BFEwvdMW.js} +3 -3
  7. package/dist/_chunks/{EditConfigurationPage-CyfFvH6-.js.map → EditConfigurationPage-BFEwvdMW.js.map} +1 -1
  8. package/dist/_chunks/{EditConfigurationPage-CBosWqQ7.mjs → EditConfigurationPage-ZO0vOO8q.mjs} +3 -3
  9. package/dist/_chunks/{EditConfigurationPage-CBosWqQ7.mjs.map → EditConfigurationPage-ZO0vOO8q.mjs.map} +1 -1
  10. package/dist/_chunks/{EditViewPage-DxyAOItK.js → EditViewPage-DA95Ha6J.js} +3 -3
  11. package/dist/_chunks/{EditViewPage-DxyAOItK.js.map → EditViewPage-DA95Ha6J.js.map} +1 -1
  12. package/dist/_chunks/{EditViewPage-ClIueJnM.mjs → EditViewPage-DlLEyUL6.mjs} +3 -3
  13. package/dist/_chunks/{EditViewPage-ClIueJnM.mjs.map → EditViewPage-DlLEyUL6.mjs.map} +1 -1
  14. package/dist/_chunks/{Field-C0Y_SR9e.js → Field-CnK8dO8N.js} +343 -51
  15. package/dist/_chunks/Field-CnK8dO8N.js.map +1 -0
  16. package/dist/_chunks/{Field-BZBYmvaf.mjs → Field-Dq7bDnuh.mjs} +344 -52
  17. package/dist/_chunks/Field-Dq7bDnuh.mjs.map +1 -0
  18. package/dist/_chunks/{Form-jwRSC2kV.mjs → Form-B_JE0dbz.mjs} +2 -2
  19. package/dist/_chunks/{Form-jwRSC2kV.mjs.map → Form-B_JE0dbz.mjs.map} +1 -1
  20. package/dist/_chunks/{Form-DwvGnISS.js → Form-BpiR4piS.js} +2 -2
  21. package/dist/_chunks/{Form-DwvGnISS.js.map → Form-BpiR4piS.js.map} +1 -1
  22. package/dist/_chunks/{History-BgzAIj0G.mjs → History-CBNGU7a-.mjs} +27 -12
  23. package/dist/_chunks/History-CBNGU7a-.mjs.map +1 -0
  24. package/dist/_chunks/{History-Cda0Yjzz.js → History-DdIstl8b.js} +27 -12
  25. package/dist/_chunks/History-DdIstl8b.js.map +1 -0
  26. package/dist/_chunks/{ListConfigurationPage-GH55qfoT.mjs → ListConfigurationPage-5dr4qpue.mjs} +8 -6
  27. package/dist/_chunks/ListConfigurationPage-5dr4qpue.mjs.map +1 -0
  28. package/dist/_chunks/{ListConfigurationPage-C29EF97r.js → ListConfigurationPage-DkKRparB.js} +8 -6
  29. package/dist/_chunks/ListConfigurationPage-DkKRparB.js.map +1 -0
  30. package/dist/_chunks/{ListViewPage-QU03PFj1.mjs → ListViewPage-DecLrYV6.mjs} +15 -6
  31. package/dist/_chunks/ListViewPage-DecLrYV6.mjs.map +1 -0
  32. package/dist/_chunks/{ListViewPage-CnRt0UT7.js → ListViewPage-wE0lXqoD.js} +15 -6
  33. package/dist/_chunks/ListViewPage-wE0lXqoD.js.map +1 -0
  34. package/dist/_chunks/{NoContentTypePage-CPs2CnzH.mjs → NoContentTypePage-CiIcfYsd.mjs} +2 -2
  35. package/dist/_chunks/{NoContentTypePage-CPs2CnzH.mjs.map → NoContentTypePage-CiIcfYsd.mjs.map} +1 -1
  36. package/dist/_chunks/{NoContentTypePage-DFDjxByI.js → NoContentTypePage-DEKR6tf9.js} +2 -2
  37. package/dist/_chunks/{NoContentTypePage-DFDjxByI.js.map → NoContentTypePage-DEKR6tf9.js.map} +1 -1
  38. package/dist/_chunks/{NoPermissionsPage-ct58lcY0.mjs → NoPermissionsPage-CM5UD8ee.mjs} +2 -2
  39. package/dist/_chunks/{NoPermissionsPage-ct58lcY0.mjs.map → NoPermissionsPage-CM5UD8ee.mjs.map} +1 -1
  40. package/dist/_chunks/{NoPermissionsPage-BVHI-jv5.js → NoPermissionsPage-DmNfF2Bb.js} +2 -2
  41. package/dist/_chunks/{NoPermissionsPage-BVHI-jv5.js.map → NoPermissionsPage-DmNfF2Bb.js.map} +1 -1
  42. package/dist/_chunks/{Relations-KMf5qEN0.mjs → Relations-Dqz0C1fz.mjs} +3 -3
  43. package/dist/_chunks/Relations-Dqz0C1fz.mjs.map +1 -0
  44. package/dist/_chunks/{Relations-BjpPPCKp.js → Relations-L0xYRoSQ.js} +3 -3
  45. package/dist/_chunks/Relations-L0xYRoSQ.js.map +1 -0
  46. package/dist/_chunks/{en-Ux26r5pl.mjs → en-BrCTWlZv.mjs} +5 -4
  47. package/dist/_chunks/{en-Ux26r5pl.mjs.map → en-BrCTWlZv.mjs.map} +1 -1
  48. package/dist/_chunks/{en-fbKQxLGn.js → en-uOUIxfcQ.js} +5 -4
  49. package/dist/_chunks/{en-fbKQxLGn.js.map → en-uOUIxfcQ.js.map} +1 -1
  50. package/dist/_chunks/{index-6kKXK7y8.mjs → index-BSn97i8U.mjs} +272 -148
  51. package/dist/_chunks/index-BSn97i8U.mjs.map +1 -0
  52. package/dist/_chunks/{index-D9ZwczCV.js → index-DyvUPg1a.js} +258 -134
  53. package/dist/_chunks/index-DyvUPg1a.js.map +1 -0
  54. package/dist/_chunks/{layout-B1Z-9koY.mjs → layout-DPaHUusj.mjs} +8 -8
  55. package/dist/_chunks/layout-DPaHUusj.mjs.map +1 -0
  56. package/dist/_chunks/{layout-BJfBoBiF.js → layout-TPqF2oJ5.js} +7 -7
  57. package/dist/_chunks/layout-TPqF2oJ5.js.map +1 -0
  58. package/dist/_chunks/{relations-CMvjzyU3.js → relations-BWYS9gkn.js} +2 -2
  59. package/dist/_chunks/{relations-CMvjzyU3.js.map → relations-BWYS9gkn.js.map} +1 -1
  60. package/dist/_chunks/{relations-CgZg7Pyx.mjs → relations-Ck7-ecDT.mjs} +2 -2
  61. package/dist/_chunks/{relations-CgZg7Pyx.mjs.map → relations-Ck7-ecDT.mjs.map} +1 -1
  62. package/dist/admin/index.js +1 -1
  63. package/dist/admin/index.mjs +4 -4
  64. package/dist/admin/src/history/index.d.ts +3 -0
  65. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  66. package/dist/admin/src/index.d.ts +1 -0
  67. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -0
  68. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
  69. package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
  70. package/dist/admin/src/services/api.d.ts +1 -1
  71. package/dist/admin/src/services/components.d.ts +2 -2
  72. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  73. package/dist/admin/src/services/documents.d.ts +16 -16
  74. package/dist/admin/src/services/init.d.ts +1 -1
  75. package/dist/admin/src/services/relations.d.ts +2 -2
  76. package/dist/admin/src/services/uid.d.ts +3 -3
  77. package/dist/server/index.js +4 -0
  78. package/dist/server/index.js.map +1 -1
  79. package/dist/server/index.mjs +4 -0
  80. package/dist/server/index.mjs.map +1 -1
  81. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  82. package/package.json +6 -6
  83. package/dist/_chunks/Field-BZBYmvaf.mjs.map +0 -1
  84. package/dist/_chunks/Field-C0Y_SR9e.js.map +0 -1
  85. package/dist/_chunks/History-BgzAIj0G.mjs.map +0 -1
  86. package/dist/_chunks/History-Cda0Yjzz.js.map +0 -1
  87. package/dist/_chunks/ListConfigurationPage-C29EF97r.js.map +0 -1
  88. package/dist/_chunks/ListConfigurationPage-GH55qfoT.mjs.map +0 -1
  89. package/dist/_chunks/ListViewPage-CnRt0UT7.js.map +0 -1
  90. package/dist/_chunks/ListViewPage-QU03PFj1.mjs.map +0 -1
  91. package/dist/_chunks/Relations-BjpPPCKp.js.map +0 -1
  92. package/dist/_chunks/Relations-KMf5qEN0.mjs.map +0 -1
  93. package/dist/_chunks/index-6kKXK7y8.mjs.map +0 -1
  94. package/dist/_chunks/index-D9ZwczCV.js.map +0 -1
  95. package/dist/_chunks/layout-B1Z-9koY.mjs.map +0 -1
  96. package/dist/_chunks/layout-BJfBoBiF.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
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";
@@ -194,9 +158,7 @@ const contentManagerApi = adminApi.enhanceEndpoints({
194
158
  "Document",
195
159
  "InitialData",
196
160
  "HistoryVersion",
197
- "Relations",
198
- "Release",
199
- "ReleaseAction"
161
+ "Relations"
200
162
  ]
201
163
  });
202
164
  const documentApi = contentManagerApi.injectEndpoints({
@@ -250,9 +212,7 @@ const documentApi = contentManagerApi.injectEndpoints({
250
212
  }
251
213
  }),
252
214
  invalidatesTags: (_result, _error, { collectionType, model }) => [
253
- { type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model },
254
- { type: "Release", id: "LIST" },
255
- { type: "ReleaseAction", id: "LIST" }
215
+ { type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model }
256
216
  ]
257
217
  }),
258
218
  deleteManyDocuments: builder.mutation({
@@ -264,11 +224,7 @@ const documentApi = contentManagerApi.injectEndpoints({
264
224
  params
265
225
  }
266
226
  }),
267
- invalidatesTags: (_res, _error, { model }) => [
268
- { type: "Document", id: `${model}_LIST` },
269
- { type: "Release", id: "LIST" },
270
- { type: "ReleaseAction", id: "LIST" }
271
- ]
227
+ invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
272
228
  }),
273
229
  discardDocument: builder.mutation({
274
230
  query: ({ collectionType, model, documentId, params }) => ({
@@ -285,9 +241,7 @@ const documentApi = contentManagerApi.injectEndpoints({
285
241
  id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
286
242
  },
287
243
  { type: "Document", id: `${model}_LIST` },
288
- "Relations",
289
- { type: "Release", id: "LIST" },
290
- { type: "ReleaseAction", id: "LIST" }
244
+ "Relations"
291
245
  ];
292
246
  }
293
247
  }),
@@ -406,9 +360,7 @@ const documentApi = contentManagerApi.injectEndpoints({
406
360
  type: "Document",
407
361
  id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
408
362
  },
409
- "Relations",
410
- { type: "Release", id: "LIST" },
411
- { type: "ReleaseAction", id: "LIST" }
363
+ "Relations"
412
364
  ];
413
365
  }
414
366
  }),
@@ -612,11 +564,11 @@ const createAttributeSchema = (attribute) => {
612
564
  }
613
565
  };
614
566
  const addRequiredValidation = (attribute) => (schema) => {
615
- if (attribute.required) {
616
- return schema.required({
617
- id: translatedErrors.required.id,
618
- defaultMessage: "This field is required."
619
- });
567
+ if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
568
+ return schema.min(1, translatedErrors.required);
569
+ }
570
+ if (attribute.required && attribute.type !== "relation") {
571
+ return schema.required(translatedErrors.required);
620
572
  }
621
573
  return schema?.nullable ? schema.nullable() : (
622
574
  // In some cases '.nullable' will not be available on the schema.
@@ -650,6 +602,28 @@ const addMaxLengthValidation = (attribute) => (schema) => {
650
602
  const addMinValidation = (attribute) => (schema) => {
651
603
  if ("min" in attribute) {
652
604
  const min = toInteger(attribute.min);
605
+ if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
606
+ if (!attribute.required && "test" in schema && min) {
607
+ return schema.test(
608
+ "custom-min",
609
+ {
610
+ ...translatedErrors.min,
611
+ values: {
612
+ min: attribute.min
613
+ }
614
+ },
615
+ (value) => {
616
+ if (!value) {
617
+ return true;
618
+ }
619
+ if (Array.isArray(value) && value.length === 0) {
620
+ return true;
621
+ }
622
+ return value.length >= min;
623
+ }
624
+ );
625
+ }
626
+ }
653
627
  if ("min" in schema && min) {
654
628
  return schema.min(min, {
655
629
  ...translatedErrors.min,
@@ -776,7 +750,10 @@ const useDocument = (args, opts) => {
776
750
  isLoading: isLoadingDocument,
777
751
  isFetching: isFetchingDocument,
778
752
  error
779
- } = useGetDocumentQuery(args, opts);
753
+ } = useGetDocumentQuery(args, {
754
+ ...opts,
755
+ skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
756
+ });
780
757
  const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
781
758
  React.useEffect(() => {
782
759
  if (error) {
@@ -1278,7 +1255,7 @@ const useDocumentActions = () => {
1278
1255
  };
1279
1256
  };
1280
1257
  const ProtectedHistoryPage = lazy(
1281
- () => import("./History-BgzAIj0G.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1258
+ () => import("./History-CBNGU7a-.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1282
1259
  );
1283
1260
  const routes$1 = [
1284
1261
  {
@@ -1291,31 +1268,31 @@ const routes$1 = [
1291
1268
  }
1292
1269
  ];
1293
1270
  const ProtectedEditViewPage = lazy(
1294
- () => import("./EditViewPage-ClIueJnM.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1271
+ () => import("./EditViewPage-DlLEyUL6.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1295
1272
  );
1296
1273
  const ProtectedListViewPage = lazy(
1297
- () => import("./ListViewPage-QU03PFj1.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1274
+ () => import("./ListViewPage-DecLrYV6.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1298
1275
  );
1299
1276
  const ProtectedListConfiguration = lazy(
1300
- () => import("./ListConfigurationPage-GH55qfoT.mjs").then((mod) => ({
1277
+ () => import("./ListConfigurationPage-5dr4qpue.mjs").then((mod) => ({
1301
1278
  default: mod.ProtectedListConfiguration
1302
1279
  }))
1303
1280
  );
1304
1281
  const ProtectedEditConfigurationPage = lazy(
1305
- () => import("./EditConfigurationPage-CBosWqQ7.mjs").then((mod) => ({
1282
+ () => import("./EditConfigurationPage-ZO0vOO8q.mjs").then((mod) => ({
1306
1283
  default: mod.ProtectedEditConfigurationPage
1307
1284
  }))
1308
1285
  );
1309
1286
  const ProtectedComponentConfigurationPage = lazy(
1310
- () => import("./ComponentConfigurationPage-DErJQEVW.mjs").then((mod) => ({
1287
+ () => import("./ComponentConfigurationPage-B1bIXVuX.mjs").then((mod) => ({
1311
1288
  default: mod.ProtectedComponentConfigurationPage
1312
1289
  }))
1313
1290
  );
1314
1291
  const NoPermissions = lazy(
1315
- () => import("./NoPermissionsPage-ct58lcY0.mjs").then((mod) => ({ default: mod.NoPermissions }))
1292
+ () => import("./NoPermissionsPage-CM5UD8ee.mjs").then((mod) => ({ default: mod.NoPermissions }))
1316
1293
  );
1317
1294
  const NoContentType = lazy(
1318
- () => import("./NoContentTypePage-CPs2CnzH.mjs").then((mod) => ({ default: mod.NoContentType }))
1295
+ () => import("./NoContentTypePage-CiIcfYsd.mjs").then((mod) => ({ default: mod.NoContentType }))
1319
1296
  );
1320
1297
  const CollectionTypePages = () => {
1321
1298
  const { collectionType } = useParams();
@@ -1442,7 +1419,7 @@ const DocumentActionButton = (action) => {
1442
1419
  DocumentActionConfirmDialog,
1443
1420
  {
1444
1421
  ...action.dialog,
1445
- variant: action.variant,
1422
+ variant: action.dialog?.variant ?? action.variant,
1446
1423
  isOpen: dialogId === action.id,
1447
1424
  onClose: handleClose
1448
1425
  }
@@ -1648,8 +1625,8 @@ const DocumentActionModal = ({
1648
1625
  };
1649
1626
  return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
1650
1627
  /* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
1651
- typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
1652
- typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
1628
+ /* @__PURE__ */ jsx(Modal.Body, { children: typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content }),
1629
+ /* @__PURE__ */ jsx(Modal.Footer, { children: typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer })
1653
1630
  ] }) });
1654
1631
  };
1655
1632
  const PublishAction$1 = ({
@@ -1671,6 +1648,12 @@ const PublishAction$1 = ({
1671
1648
  ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
1672
1649
  );
1673
1650
  const { publish } = useDocumentActions();
1651
+ const [
1652
+ countDraftRelations,
1653
+ { isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
1654
+ ] = useLazyGetDraftRelationCountQuery();
1655
+ const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
1656
+ const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
1674
1657
  const [{ query, rawQuery }] = useQueryParams();
1675
1658
  const params = React.useMemo(() => buildValidParams(query), [query]);
1676
1659
  const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
@@ -1679,10 +1662,101 @@ const PublishAction$1 = ({
1679
1662
  const validate = useForm("PublishAction", (state) => state.validate);
1680
1663
  const setErrors = useForm("PublishAction", (state) => state.setErrors);
1681
1664
  const formValues = useForm("PublishAction", ({ values }) => values);
1665
+ React.useEffect(() => {
1666
+ if (isErrorDraftRelations) {
1667
+ toggleNotification({
1668
+ type: "danger",
1669
+ message: formatMessage({
1670
+ id: getTranslation("error.records.fetch-draft-relatons"),
1671
+ defaultMessage: "An error occurred while fetching draft relations on this document."
1672
+ })
1673
+ });
1674
+ }
1675
+ }, [isErrorDraftRelations, toggleNotification, formatMessage]);
1676
+ React.useEffect(() => {
1677
+ const localDraftRelations = /* @__PURE__ */ new Set();
1678
+ const extractDraftRelations = (data) => {
1679
+ const relations = data.connect || [];
1680
+ relations.forEach((relation) => {
1681
+ if (relation.status === "draft") {
1682
+ localDraftRelations.add(relation.id);
1683
+ }
1684
+ });
1685
+ };
1686
+ const traverseAndExtract = (data) => {
1687
+ Object.entries(data).forEach(([key, value]) => {
1688
+ if (key === "connect" && Array.isArray(value)) {
1689
+ extractDraftRelations({ connect: value });
1690
+ } else if (typeof value === "object" && value !== null) {
1691
+ traverseAndExtract(value);
1692
+ }
1693
+ });
1694
+ };
1695
+ if (!documentId || modified) {
1696
+ traverseAndExtract(formValues);
1697
+ setLocalCountOfDraftRelations(localDraftRelations.size);
1698
+ }
1699
+ }, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
1700
+ React.useEffect(() => {
1701
+ if (documentId) {
1702
+ const fetchDraftRelationsCount = async () => {
1703
+ const { data, error } = await countDraftRelations({
1704
+ collectionType,
1705
+ model,
1706
+ documentId,
1707
+ params
1708
+ });
1709
+ if (error) {
1710
+ throw error;
1711
+ }
1712
+ if (data) {
1713
+ setServerCountOfDraftRelations(data.data);
1714
+ }
1715
+ };
1716
+ fetchDraftRelationsCount();
1717
+ }
1718
+ }, [documentId, countDraftRelations, collectionType, model, params]);
1682
1719
  const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
1683
1720
  if (!schema?.options?.draftAndPublish) {
1684
1721
  return null;
1685
1722
  }
1723
+ const performPublish = async () => {
1724
+ setSubmitting(true);
1725
+ try {
1726
+ const { errors } = await validate();
1727
+ if (errors) {
1728
+ toggleNotification({
1729
+ type: "danger",
1730
+ message: formatMessage({
1731
+ id: "content-manager.validation.error",
1732
+ defaultMessage: "There are validation errors in your document. Please fix them before saving."
1733
+ })
1734
+ });
1735
+ return;
1736
+ }
1737
+ const res = await publish(
1738
+ {
1739
+ collectionType,
1740
+ model,
1741
+ documentId,
1742
+ params
1743
+ },
1744
+ formValues
1745
+ );
1746
+ if ("data" in res && collectionType !== SINGLE_TYPES) {
1747
+ navigate({
1748
+ pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1749
+ search: rawQuery
1750
+ });
1751
+ } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1752
+ setErrors(formatValidationErrors(res.error));
1753
+ }
1754
+ } finally {
1755
+ setSubmitting(false);
1756
+ }
1757
+ };
1758
+ const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
1759
+ const hasDraftRelations = totalDraftRelations > 0;
1686
1760
  return {
1687
1761
  /**
1688
1762
  * Disabled when:
@@ -1695,46 +1769,38 @@ const PublishAction$1 = ({
1695
1769
  * - the user doesn't have the permission to create a new document
1696
1770
  * - the user doesn't have the permission to update the document
1697
1771
  */
1698
- disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
1772
+ disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
1699
1773
  label: formatMessage({
1700
1774
  id: "app.utils.publish",
1701
1775
  defaultMessage: "Publish"
1702
1776
  }),
1703
1777
  onClick: async () => {
1704
- setSubmitting(true);
1705
- try {
1706
- const { errors } = await validate();
1707
- if (errors) {
1708
- toggleNotification({
1709
- type: "danger",
1710
- message: formatMessage({
1711
- id: "content-manager.validation.error",
1712
- defaultMessage: "There are validation errors in your document. Please fix them before saving."
1713
- })
1714
- });
1715
- return;
1716
- }
1717
- const res = await publish(
1718
- {
1719
- collectionType,
1720
- model,
1721
- documentId,
1722
- params
1723
- },
1724
- formValues
1725
- );
1726
- if ("data" in res && collectionType !== SINGLE_TYPES) {
1727
- navigate({
1728
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1729
- search: rawQuery
1730
- });
1731
- } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1732
- setErrors(formatValidationErrors(res.error));
1778
+ if (hasDraftRelations) {
1779
+ return;
1780
+ }
1781
+ await performPublish();
1782
+ },
1783
+ dialog: hasDraftRelations ? {
1784
+ type: "dialog",
1785
+ variant: "danger",
1786
+ footer: null,
1787
+ title: formatMessage({
1788
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
1789
+ defaultMessage: "Confirmation"
1790
+ }),
1791
+ content: formatMessage(
1792
+ {
1793
+ id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
1794
+ defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
1795
+ },
1796
+ {
1797
+ count: totalDraftRelations
1733
1798
  }
1734
- } finally {
1735
- setSubmitting(false);
1799
+ ),
1800
+ onConfirm: async () => {
1801
+ await performPublish();
1736
1802
  }
1737
- }
1803
+ } : void 0
1738
1804
  };
1739
1805
  };
1740
1806
  PublishAction$1.type = "publish";
@@ -1833,10 +1899,13 @@ const UpdateAction = ({
1833
1899
  document
1834
1900
  );
1835
1901
  if ("data" in res && collectionType !== SINGLE_TYPES) {
1836
- navigate({
1837
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1838
- search: rawQuery
1839
- });
1902
+ navigate(
1903
+ {
1904
+ pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1905
+ search: rawQuery
1906
+ },
1907
+ { replace: true }
1908
+ );
1840
1909
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1841
1910
  setErrors(formatValidationErrors(res.error));
1842
1911
  }
@@ -2082,23 +2151,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2082
2151
  id: "content-manager.containers.edit.title.new",
2083
2152
  defaultMessage: "Create an entry"
2084
2153
  }) : documentTitle;
2085
- return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 8, paddingBottom: 4, gap: 3, children: [
2154
+ return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
2086
2155
  /* @__PURE__ */ jsx(BackButton, {}),
2087
- /* @__PURE__ */ jsxs(
2088
- Flex,
2089
- {
2090
- width: "100%",
2091
- justifyContent: "space-between",
2092
- paddingTop: 1,
2093
- gap: "80px",
2094
- alignItems: "flex-start",
2095
- children: [
2096
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
2097
- /* @__PURE__ */ jsx(HeaderToolbar, {})
2098
- ]
2099
- }
2100
- ),
2101
- status ? /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) : null
2156
+ /* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
2157
+ /* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
2158
+ /* @__PURE__ */ jsx(HeaderToolbar, {})
2159
+ ] }),
2160
+ status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
2102
2161
  ] });
2103
2162
  };
2104
2163
  const HeaderToolbar = () => {
@@ -2789,7 +2848,7 @@ const ConfirmBulkActionDialog = ({
2789
2848
  endAction
2790
2849
  }) => {
2791
2850
  const { formatMessage } = useIntl();
2792
- return /* @__PURE__ */ jsx(Dialog.Root, { onOpenChange: onToggleDialog, open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
2851
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
2793
2852
  /* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
2794
2853
  id: "app.components.ConfirmDialog.title",
2795
2854
  defaultMessage: "Confirmation"
@@ -2910,7 +2969,14 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
2910
2969
  )
2911
2970
  );
2912
2971
  } else {
2913
- messages.push(...formatErrorMessages(value, currentKey, formatMessage));
2972
+ messages.push(
2973
+ ...formatErrorMessages(
2974
+ // @ts-expect-error TODO: check why value is not compatible with FormErrors
2975
+ value,
2976
+ currentKey,
2977
+ formatMessage
2978
+ )
2979
+ );
2914
2980
  }
2915
2981
  } else {
2916
2982
  messages.push(
@@ -3573,8 +3639,7 @@ class ContentManagerPlugin {
3573
3639
  documentActions = [
3574
3640
  ...DEFAULT_ACTIONS,
3575
3641
  ...DEFAULT_TABLE_ROW_ACTIONS,
3576
- ...DEFAULT_HEADER_ACTIONS,
3577
- HistoryAction
3642
+ ...DEFAULT_HEADER_ACTIONS
3578
3643
  ];
3579
3644
  editViewSidePanels = [ActionsPanel];
3580
3645
  headerActions = [];
@@ -3663,6 +3728,52 @@ const getPrintableType = (value) => {
3663
3728
  }
3664
3729
  return nativeType;
3665
3730
  };
3731
+ const HistoryAction = ({ model, document }) => {
3732
+ const { formatMessage } = useIntl();
3733
+ const [{ query }] = useQueryParams();
3734
+ const navigate = useNavigate();
3735
+ const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
3736
+ if (!window.strapi.features.isEnabled("cms-content-history")) {
3737
+ return null;
3738
+ }
3739
+ return {
3740
+ icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
3741
+ label: formatMessage({
3742
+ id: "content-manager.history.document-action",
3743
+ defaultMessage: "Content History"
3744
+ }),
3745
+ onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
3746
+ disabled: (
3747
+ /**
3748
+ * The user is creating a new document.
3749
+ * It hasn't been saved yet, so there's no history to go to
3750
+ */
3751
+ !document || /**
3752
+ * The document has been created but the current dimension has never been saved.
3753
+ * For example, the user is creating a new locale in an existing document,
3754
+ * so there's no history for the document in that locale
3755
+ */
3756
+ !document.id || /**
3757
+ * History is only available for content types created by the user.
3758
+ * These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
3759
+ * which start with `admin::` or `plugin::`
3760
+ */
3761
+ !model.startsWith("api::")
3762
+ ),
3763
+ position: "header"
3764
+ };
3765
+ };
3766
+ HistoryAction.type = "history";
3767
+ const historyAdmin = {
3768
+ bootstrap(app) {
3769
+ const { addDocumentAction } = app.getPlugin("content-manager").apis;
3770
+ addDocumentAction((actions2) => {
3771
+ const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
3772
+ actions2.splice(indexOfDeleteAction, 0, HistoryAction);
3773
+ return actions2;
3774
+ });
3775
+ }
3776
+ };
3666
3777
  const initialState = {
3667
3778
  collectionTypeLinks: [],
3668
3779
  components: [],
@@ -3713,15 +3824,29 @@ const index = {
3713
3824
  defaultMessage: "Content Manager"
3714
3825
  },
3715
3826
  permissions: [],
3716
- Component: () => import("./layout-B1Z-9koY.mjs").then((mod) => ({ default: mod.Layout })),
3717
3827
  position: 1
3718
3828
  });
3829
+ app.router.addRoute({
3830
+ path: "content-manager/*",
3831
+ lazy: async () => {
3832
+ const { Layout } = await import("./layout-DPaHUusj.mjs");
3833
+ return {
3834
+ Component: Layout
3835
+ };
3836
+ },
3837
+ children: routes
3838
+ });
3719
3839
  app.registerPlugin(cm.config);
3720
3840
  },
3841
+ bootstrap(app) {
3842
+ if (typeof historyAdmin.bootstrap === "function") {
3843
+ historyAdmin.bootstrap(app);
3844
+ }
3845
+ },
3721
3846
  async registerTrads({ locales }) {
3722
3847
  const importedTrads = await Promise.all(
3723
3848
  locales.map((locale) => {
3724
- 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 }) => {
3849
+ 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 }) => {
3725
3850
  return {
3726
3851
  data: prefixPluginTranslations(data, PLUGIN_ID),
3727
3852
  locale
@@ -3742,14 +3867,13 @@ export {
3742
3867
  BulkActionsRenderer as B,
3743
3868
  COLLECTION_TYPES as C,
3744
3869
  DocumentStatus as D,
3745
- extractContentTypeComponents as E,
3746
- DEFAULT_SETTINGS as F,
3747
- convertEditLayoutToFieldLayouts as G,
3870
+ DEFAULT_SETTINGS as E,
3871
+ convertEditLayoutToFieldLayouts as F,
3872
+ useDocument as G,
3748
3873
  HOOKS as H,
3749
3874
  InjectionZone as I,
3750
- useDocument as J,
3751
- index as K,
3752
- useDocumentActions as L,
3875
+ index as J,
3876
+ useDocumentActions as K,
3753
3877
  Panels as P,
3754
3878
  RelativeTime as R,
3755
3879
  SINGLE_TYPES as S,
@@ -3771,14 +3895,14 @@ export {
3771
3895
  useGetContentTypeConfigurationQuery as o,
3772
3896
  CREATOR_FIELDS as p,
3773
3897
  getMainField as q,
3774
- routes as r,
3898
+ getDisplayName as r,
3775
3899
  setInitialData as s,
3776
- getDisplayName as t,
3900
+ checkIfAttributeIsDisplayable as t,
3777
3901
  useContentTypeSchema as u,
3778
- checkIfAttributeIsDisplayable as v,
3779
- useGetAllDocumentsQuery as w,
3780
- convertListLayoutToFieldLayouts as x,
3781
- capitalise as y,
3782
- useUpdateContentTypeConfigurationMutation as z
3902
+ useGetAllDocumentsQuery as v,
3903
+ convertListLayoutToFieldLayouts as w,
3904
+ capitalise as x,
3905
+ useUpdateContentTypeConfigurationMutation as y,
3906
+ extractContentTypeComponents as z
3783
3907
  };
3784
- //# sourceMappingURL=index-6kKXK7y8.mjs.map
3908
+ //# sourceMappingURL=index-BSn97i8U.mjs.map