@strapi/content-manager 0.0.0-experimental.bd712ad3930045f4a5d2144c119e0b7856e97fc4 → 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 (91) hide show
  1. package/dist/_chunks/{ComponentConfigurationPage-BWQv6yRj.js → ComponentConfigurationPage-k6fnZytn.js} +3 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-BWQv6yRj.js.map → ComponentConfigurationPage-k6fnZytn.js.map} +1 -1
  3. package/dist/_chunks/{ComponentConfigurationPage-C7ImeKGM.mjs → ComponentConfigurationPage-o2HOTHL4.mjs} +3 -3
  4. package/dist/_chunks/{ComponentConfigurationPage-C7ImeKGM.mjs.map → ComponentConfigurationPage-o2HOTHL4.mjs.map} +1 -1
  5. package/dist/_chunks/{EditConfigurationPage-CEGwxV-L.js → EditConfigurationPage-DKtok23W.js} +3 -3
  6. package/dist/_chunks/{EditConfigurationPage-CEGwxV-L.js.map → EditConfigurationPage-DKtok23W.js.map} +1 -1
  7. package/dist/_chunks/{EditConfigurationPage-MItFGzT9.mjs → EditConfigurationPage-HNi0pVX4.mjs} +3 -3
  8. package/dist/_chunks/{EditConfigurationPage-MItFGzT9.mjs.map → EditConfigurationPage-HNi0pVX4.mjs.map} +1 -1
  9. package/dist/_chunks/{EditViewPage-CmMi2Xsn.js → EditViewPage-CrX5Iz3h.js} +3 -3
  10. package/dist/_chunks/{EditViewPage-CmMi2Xsn.js.map → EditViewPage-CrX5Iz3h.js.map} +1 -1
  11. package/dist/_chunks/{EditViewPage-DhmAg0NK.mjs → EditViewPage-DGnFsrTV.mjs} +3 -3
  12. package/dist/_chunks/{EditViewPage-DhmAg0NK.mjs.map → EditViewPage-DGnFsrTV.mjs.map} +1 -1
  13. package/dist/_chunks/{Field-Cs62u5pl.mjs → Field-DlWgNyun.mjs} +8 -8
  14. package/dist/_chunks/Field-DlWgNyun.mjs.map +1 -0
  15. package/dist/_chunks/{Field-1DLtcLAI.js → Field-DvDdA59J.js} +8 -8
  16. package/dist/_chunks/Field-DvDdA59J.js.map +1 -0
  17. package/dist/_chunks/{Form-zYHtzGUX.mjs → Form-B7VJjkXr.mjs} +2 -2
  18. package/dist/_chunks/{Form-zYHtzGUX.mjs.map → Form-B7VJjkXr.mjs.map} +1 -1
  19. package/dist/_chunks/{Form-CqFA7F_V.js → Form-D9w2wzOa.js} +2 -2
  20. package/dist/_chunks/{Form-CqFA7F_V.js.map → Form-D9w2wzOa.js.map} +1 -1
  21. package/dist/_chunks/{History-DalgFQ3D.mjs → History-84QY4Lau.mjs} +21 -11
  22. package/dist/_chunks/History-84QY4Lau.mjs.map +1 -0
  23. package/dist/_chunks/{History-BblwXv7-.js → History-GCscEVds.js} +21 -11
  24. package/dist/_chunks/History-GCscEVds.js.map +1 -0
  25. package/dist/_chunks/{ListConfigurationPage-DWy-vRzs.mjs → ListConfigurationPage-C_S6OFYL.mjs} +2 -2
  26. package/dist/_chunks/{ListConfigurationPage-DWy-vRzs.mjs.map → ListConfigurationPage-C_S6OFYL.mjs.map} +1 -1
  27. package/dist/_chunks/{ListConfigurationPage-Cpy4QqNd.js → ListConfigurationPage-Ck-lKA_g.js} +2 -2
  28. package/dist/_chunks/{ListConfigurationPage-Cpy4QqNd.js.map → ListConfigurationPage-Ck-lKA_g.js.map} +1 -1
  29. package/dist/_chunks/{ListViewPage-DFjn1DNW.js → ListViewPage-D1vAbQW4.js} +9 -4
  30. package/dist/_chunks/ListViewPage-D1vAbQW4.js.map +1 -0
  31. package/dist/_chunks/{ListViewPage-BkAwIW9s.mjs → ListViewPage-DkQT6AN6.mjs} +10 -5
  32. package/dist/_chunks/ListViewPage-DkQT6AN6.mjs.map +1 -0
  33. package/dist/_chunks/{NoContentTypePage-B9BCNNdL.mjs → NoContentTypePage-D5QYn9pN.mjs} +2 -2
  34. package/dist/_chunks/{NoContentTypePage-B9BCNNdL.mjs.map → NoContentTypePage-D5QYn9pN.mjs.map} +1 -1
  35. package/dist/_chunks/{NoContentTypePage-C-3ykoxs.js → NoContentTypePage-DnMToxdO.js} +2 -2
  36. package/dist/_chunks/{NoContentTypePage-C-3ykoxs.js.map → NoContentTypePage-DnMToxdO.js.map} +1 -1
  37. package/dist/_chunks/{NoPermissionsPage-DKLmDZnZ.js → NoPermissionsPage-COirbirm.js} +2 -2
  38. package/dist/_chunks/{NoPermissionsPage-DKLmDZnZ.js.map → NoPermissionsPage-COirbirm.js.map} +1 -1
  39. package/dist/_chunks/{NoPermissionsPage-Bt_HWGat.mjs → NoPermissionsPage-eV9XOUs6.mjs} +2 -2
  40. package/dist/_chunks/{NoPermissionsPage-Bt_HWGat.mjs.map → NoPermissionsPage-eV9XOUs6.mjs.map} +1 -1
  41. package/dist/_chunks/{Relations-CJmTbZ8T.mjs → Relations-CMu33f0Q.mjs} +3 -3
  42. package/dist/_chunks/Relations-CMu33f0Q.mjs.map +1 -0
  43. package/dist/_chunks/{Relations-CrxfoH2n.js → Relations-CvSHeSTB.js} +3 -3
  44. package/dist/_chunks/Relations-CvSHeSTB.js.map +1 -0
  45. package/dist/_chunks/{en-Ux26r5pl.mjs → en-BrCTWlZv.mjs} +5 -4
  46. package/dist/_chunks/{en-Ux26r5pl.mjs.map → en-BrCTWlZv.mjs.map} +1 -1
  47. package/dist/_chunks/{en-fbKQxLGn.js → en-uOUIxfcQ.js} +5 -4
  48. package/dist/_chunks/{en-fbKQxLGn.js.map → en-uOUIxfcQ.js.map} +1 -1
  49. package/dist/_chunks/{index-Buwn78Rt.js → index-BU73akFF.js} +244 -139
  50. package/dist/_chunks/index-BU73akFF.js.map +1 -0
  51. package/dist/_chunks/{index-D1344xdw.mjs → index-DYjyBm-q.mjs} +247 -142
  52. package/dist/_chunks/index-DYjyBm-q.mjs.map +1 -0
  53. package/dist/_chunks/{layout-ChVuUpa1.mjs → layout-CK49ltFD.mjs} +17 -5
  54. package/dist/_chunks/{layout-ChVuUpa1.mjs.map → layout-CK49ltFD.mjs.map} +1 -1
  55. package/dist/_chunks/{layout-DRuJUpas.js → layout-IJUR2XBA.js} +16 -4
  56. package/dist/_chunks/{layout-DRuJUpas.js.map → layout-IJUR2XBA.js.map} +1 -1
  57. package/dist/_chunks/{relations-B-deMCy4.mjs → relations-Dl8Jk9_i.mjs} +2 -2
  58. package/dist/_chunks/{relations-B-deMCy4.mjs.map → relations-Dl8Jk9_i.mjs.map} +1 -1
  59. package/dist/_chunks/{relations-DuoUwyJr.js → relations-T1zuutNL.js} +2 -2
  60. package/dist/_chunks/{relations-DuoUwyJr.js.map → relations-T1zuutNL.js.map} +1 -1
  61. package/dist/admin/index.js +1 -1
  62. package/dist/admin/index.mjs +1 -1
  63. package/dist/admin/src/history/index.d.ts +3 -0
  64. package/dist/admin/src/index.d.ts +1 -0
  65. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -0
  66. package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
  67. package/dist/server/index.js +130 -85
  68. package/dist/server/index.js.map +1 -1
  69. package/dist/server/index.mjs +131 -86
  70. package/dist/server/index.mjs.map +1 -1
  71. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  72. package/dist/server/src/controllers/uid.d.ts.map +1 -1
  73. package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
  74. package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
  75. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  76. package/dist/server/src/history/services/utils.d.ts +1 -1
  77. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  78. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  79. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  80. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  81. package/package.json +6 -6
  82. package/dist/_chunks/Field-1DLtcLAI.js.map +0 -1
  83. package/dist/_chunks/Field-Cs62u5pl.mjs.map +0 -1
  84. package/dist/_chunks/History-BblwXv7-.js.map +0 -1
  85. package/dist/_chunks/History-DalgFQ3D.mjs.map +0 -1
  86. package/dist/_chunks/ListViewPage-BkAwIW9s.mjs.map +0 -1
  87. package/dist/_chunks/ListViewPage-DFjn1DNW.js.map +0 -1
  88. package/dist/_chunks/Relations-CJmTbZ8T.mjs.map +0 -1
  89. package/dist/_chunks/Relations-CrxfoH2n.js.map +0 -1
  90. package/dist/_chunks/index-Buwn78Rt.js.map +0 -1
  91. package/dist/_chunks/index-D1344xdw.mjs.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 { Button, Menu, VisuallyHidden, Flex, Box, Typography, Dialog, Modal, Radio, Status, SingleSelect, SingleSelectOption, 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";
@@ -208,7 +172,12 @@ const documentApi = contentManagerApi.injectEndpoints({
208
172
  params: query
209
173
  }
210
174
  }),
211
- 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
+ }
212
181
  }),
213
182
  cloneDocument: builder.mutation({
214
183
  query: ({ model, sourceId, data, params }) => ({
@@ -295,6 +264,7 @@ const documentApi = contentManagerApi.injectEndpoints({
295
264
  }),
296
265
  providesTags: (result, _error, arg) => {
297
266
  return [
267
+ { type: "Document", id: `ALL_LIST` },
298
268
  { type: "Document", id: `${arg.model}_LIST` },
299
269
  ...result?.results.map(({ documentId }) => ({
300
270
  type: "Document",
@@ -398,6 +368,18 @@ const documentApi = contentManagerApi.injectEndpoints({
398
368
  },
399
369
  "Relations"
400
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
+ }
401
383
  }
402
384
  }),
403
385
  unpublishDocument: builder.mutation({
@@ -1210,7 +1192,6 @@ const useDocumentActions = () => {
1210
1192
  sourceId
1211
1193
  });
1212
1194
  if ("error" in res) {
1213
- toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1214
1195
  return { error: res.error };
1215
1196
  }
1216
1197
  toggleNotification({
@@ -1291,7 +1272,7 @@ const useDocumentActions = () => {
1291
1272
  };
1292
1273
  };
1293
1274
  const ProtectedHistoryPage = lazy(
1294
- () => import("./History-DalgFQ3D.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1275
+ () => import("./History-84QY4Lau.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1295
1276
  );
1296
1277
  const routes$1 = [
1297
1278
  {
@@ -1304,31 +1285,31 @@ const routes$1 = [
1304
1285
  }
1305
1286
  ];
1306
1287
  const ProtectedEditViewPage = lazy(
1307
- () => import("./EditViewPage-DhmAg0NK.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1288
+ () => import("./EditViewPage-DGnFsrTV.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1308
1289
  );
1309
1290
  const ProtectedListViewPage = lazy(
1310
- () => import("./ListViewPage-BkAwIW9s.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1291
+ () => import("./ListViewPage-DkQT6AN6.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1311
1292
  );
1312
1293
  const ProtectedListConfiguration = lazy(
1313
- () => import("./ListConfigurationPage-DWy-vRzs.mjs").then((mod) => ({
1294
+ () => import("./ListConfigurationPage-C_S6OFYL.mjs").then((mod) => ({
1314
1295
  default: mod.ProtectedListConfiguration
1315
1296
  }))
1316
1297
  );
1317
1298
  const ProtectedEditConfigurationPage = lazy(
1318
- () => import("./EditConfigurationPage-MItFGzT9.mjs").then((mod) => ({
1299
+ () => import("./EditConfigurationPage-HNi0pVX4.mjs").then((mod) => ({
1319
1300
  default: mod.ProtectedEditConfigurationPage
1320
1301
  }))
1321
1302
  );
1322
1303
  const ProtectedComponentConfigurationPage = lazy(
1323
- () => import("./ComponentConfigurationPage-C7ImeKGM.mjs").then((mod) => ({
1304
+ () => import("./ComponentConfigurationPage-o2HOTHL4.mjs").then((mod) => ({
1324
1305
  default: mod.ProtectedComponentConfigurationPage
1325
1306
  }))
1326
1307
  );
1327
1308
  const NoPermissions = lazy(
1328
- () => import("./NoPermissionsPage-Bt_HWGat.mjs").then((mod) => ({ default: mod.NoPermissions }))
1309
+ () => import("./NoPermissionsPage-eV9XOUs6.mjs").then((mod) => ({ default: mod.NoPermissions }))
1329
1310
  );
1330
1311
  const NoContentType = lazy(
1331
- () => import("./NoContentTypePage-B9BCNNdL.mjs").then((mod) => ({ default: mod.NoContentType }))
1312
+ () => import("./NoContentTypePage-D5QYn9pN.mjs").then((mod) => ({ default: mod.NoContentType }))
1332
1313
  );
1333
1314
  const CollectionTypePages = () => {
1334
1315
  const { collectionType } = useParams();
@@ -1442,7 +1423,7 @@ const DocumentActionButton = (action) => {
1442
1423
  /* @__PURE__ */ jsx(
1443
1424
  Button,
1444
1425
  {
1445
- flex: 1,
1426
+ flex: "auto",
1446
1427
  startIcon: action.icon,
1447
1428
  disabled: action.disabled,
1448
1429
  onClick: handleClick(action),
@@ -1455,7 +1436,7 @@ const DocumentActionButton = (action) => {
1455
1436
  DocumentActionConfirmDialog,
1456
1437
  {
1457
1438
  ...action.dialog,
1458
- variant: action.variant,
1439
+ variant: action.dialog?.variant ?? action.variant,
1459
1440
  isOpen: dialogId === action.id,
1460
1441
  onClose: handleClose
1461
1442
  }
@@ -1512,9 +1493,9 @@ const DocumentActionsMenu = ({
1512
1493
  disabled: isDisabled,
1513
1494
  size: "S",
1514
1495
  endIcon: null,
1515
- paddingTop: "7px",
1516
- paddingLeft: "9px",
1517
- paddingRight: "9px",
1496
+ paddingTop: "4px",
1497
+ paddingLeft: "7px",
1498
+ paddingRight: "7px",
1518
1499
  variant,
1519
1500
  children: [
1520
1501
  /* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
@@ -1534,10 +1515,18 @@ const DocumentActionsMenu = ({
1534
1515
  onSelect: handleClick(action),
1535
1516
  display: "block",
1536
1517
  children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
1537
- /* @__PURE__ */ jsxs(Flex, { color: convertActionVariantToColor(action.variant), gap: 2, tag: "span", children: [
1538
- /* @__PURE__ */ jsx(Box, { tag: "span", color: convertActionVariantToIconColor(action.variant), children: action.icon }),
1539
- action.label
1540
- ] }),
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
+ ),
1541
1530
  action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
1542
1531
  Flex,
1543
1532
  {
@@ -1596,18 +1585,6 @@ const convertActionVariantToColor = (variant = "secondary") => {
1596
1585
  return "primary600";
1597
1586
  }
1598
1587
  };
1599
- const convertActionVariantToIconColor = (variant = "secondary") => {
1600
- switch (variant) {
1601
- case "danger":
1602
- return "danger600";
1603
- case "secondary":
1604
- return "neutral500";
1605
- case "success":
1606
- return "success600";
1607
- default:
1608
- return "primary600";
1609
- }
1610
- };
1611
1588
  const DocumentActionConfirmDialog = ({
1612
1589
  onClose,
1613
1590
  onCancel,
@@ -1661,8 +1638,8 @@ const DocumentActionModal = ({
1661
1638
  };
1662
1639
  return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
1663
1640
  /* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
1664
- /* @__PURE__ */ jsx(Modal.Body, { children: typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content }),
1665
- /* @__PURE__ */ jsx(Modal.Footer, { children: typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer })
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
1666
1643
  ] }) });
1667
1644
  };
1668
1645
  const PublishAction$1 = ({
@@ -1684,6 +1661,12 @@ const PublishAction$1 = ({
1684
1661
  ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
1685
1662
  );
1686
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);
1687
1670
  const [{ query, rawQuery }] = useQueryParams();
1688
1671
  const params = React.useMemo(() => buildValidParams(query), [query]);
1689
1672
  const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
@@ -1692,10 +1675,101 @@ const PublishAction$1 = ({
1692
1675
  const validate = useForm("PublishAction", (state) => state.validate);
1693
1676
  const setErrors = useForm("PublishAction", (state) => state.setErrors);
1694
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]);
1695
1732
  const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
1696
1733
  if (!schema?.options?.draftAndPublish) {
1697
1734
  return null;
1698
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;
1699
1773
  return {
1700
1774
  /**
1701
1775
  * Disabled when:
@@ -1705,49 +1779,39 @@ const PublishAction$1 = ({
1705
1779
  * - the document is already published & not modified
1706
1780
  * - the document is being created & not modified
1707
1781
  * - the user doesn't have the permission to publish
1708
- * - the user doesn't have the permission to create a new document
1709
- * - the user doesn't have the permission to update the document
1710
1782
  */
1711
- 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,
1712
1784
  label: formatMessage({
1713
1785
  id: "app.utils.publish",
1714
1786
  defaultMessage: "Publish"
1715
1787
  }),
1716
1788
  onClick: async () => {
1717
- setSubmitting(true);
1718
- try {
1719
- const { errors } = await validate();
1720
- if (errors) {
1721
- toggleNotification({
1722
- type: "danger",
1723
- message: formatMessage({
1724
- id: "content-manager.validation.error",
1725
- defaultMessage: "There are validation errors in your document. Please fix them before saving."
1726
- })
1727
- });
1728
- return;
1729
- }
1730
- const res = await publish(
1731
- {
1732
- collectionType,
1733
- model,
1734
- documentId,
1735
- params
1736
- },
1737
- formValues
1738
- );
1739
- if ("data" in res && collectionType !== SINGLE_TYPES) {
1740
- navigate({
1741
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1742
- search: rawQuery
1743
- });
1744
- } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1745
- 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
1746
1809
  }
1747
- } finally {
1748
- setSubmitting(false);
1810
+ ),
1811
+ onConfirm: async () => {
1812
+ await performPublish();
1749
1813
  }
1750
- }
1814
+ } : void 0
1751
1815
  };
1752
1816
  };
1753
1817
  PublishAction$1.type = "publish";
@@ -1763,7 +1827,7 @@ const UpdateAction = ({
1763
1827
  const cloneMatch = useMatch(CLONE_PATH);
1764
1828
  const isCloning = cloneMatch !== null;
1765
1829
  const { formatMessage } = useIntl();
1766
- const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
1830
+ useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
1767
1831
  canCreate: canCreate2,
1768
1832
  canUpdate: canUpdate2
1769
1833
  }));
@@ -1783,10 +1847,8 @@ const UpdateAction = ({
1783
1847
  * - the form is submitting
1784
1848
  * - the document is not modified & we're not cloning (you can save a clone entity straight away)
1785
1849
  * - the active tab is the published tab
1786
- * - the user doesn't have the permission to create a new document
1787
- * - the user doesn't have the permission to update the document
1788
1850
  */
1789
- disabled: isSubmitting || !modified && !isCloning || activeTab === "published" || Boolean(!documentId && !canCreate || documentId && !canUpdate),
1851
+ disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
1790
1852
  label: formatMessage({
1791
1853
  id: "content-manager.containers.Edit.save",
1792
1854
  defaultMessage: "Save"
@@ -1815,10 +1877,13 @@ const UpdateAction = ({
1815
1877
  document
1816
1878
  );
1817
1879
  if ("data" in res) {
1818
- navigate({
1819
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1820
- search: rawQuery
1821
- });
1880
+ navigate(
1881
+ {
1882
+ pathname: `../${res.data.documentId}`,
1883
+ search: rawQuery
1884
+ },
1885
+ { relative: "path" }
1886
+ );
1822
1887
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1823
1888
  setErrors(formatValidationErrors(res.error));
1824
1889
  }
@@ -1848,10 +1913,10 @@ const UpdateAction = ({
1848
1913
  if ("data" in res && collectionType !== SINGLE_TYPES) {
1849
1914
  navigate(
1850
1915
  {
1851
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1916
+ pathname: `../${res.data.documentId}`,
1852
1917
  search: rawQuery
1853
1918
  },
1854
- { replace: true }
1919
+ { replace: true, relative: "path" }
1855
1920
  );
1856
1921
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1857
1922
  setErrors(formatValidationErrors(res.error));
@@ -2098,23 +2163,13 @@ const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2098
2163
  id: "content-manager.containers.edit.title.new",
2099
2164
  defaultMessage: "Create an entry"
2100
2165
  }) : documentTitle;
2101
- 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: [
2102
2167
  /* @__PURE__ */ jsx(BackButton, {}),
2103
- /* @__PURE__ */ jsxs(
2104
- Flex,
2105
- {
2106
- width: "100%",
2107
- justifyContent: "space-between",
2108
- paddingTop: 1,
2109
- gap: "80px",
2110
- alignItems: "flex-start",
2111
- children: [
2112
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
2113
- /* @__PURE__ */ jsx(HeaderToolbar, {})
2114
- ]
2115
- }
2116
- ),
2117
- 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
2118
2173
  ] });
2119
2174
  };
2120
2175
  const HeaderToolbar = () => {
@@ -2805,7 +2860,7 @@ const ConfirmBulkActionDialog = ({
2805
2860
  endAction
2806
2861
  }) => {
2807
2862
  const { formatMessage } = useIntl();
2808
- return /* @__PURE__ */ jsx(Dialog.Root, { onOpenChange: onToggleDialog, open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
2863
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
2809
2864
  /* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
2810
2865
  id: "app.components.ConfirmDialog.title",
2811
2866
  defaultMessage: "Confirmation"
@@ -3596,8 +3651,7 @@ class ContentManagerPlugin {
3596
3651
  documentActions = [
3597
3652
  ...DEFAULT_ACTIONS,
3598
3653
  ...DEFAULT_TABLE_ROW_ACTIONS,
3599
- ...DEFAULT_HEADER_ACTIONS,
3600
- HistoryAction
3654
+ ...DEFAULT_HEADER_ACTIONS
3601
3655
  ];
3602
3656
  editViewSidePanels = [ActionsPanel];
3603
3657
  headerActions = [];
@@ -3686,6 +3740,52 @@ const getPrintableType = (value) => {
3686
3740
  }
3687
3741
  return nativeType;
3688
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
+ };
3689
3789
  const initialState = {
3690
3790
  collectionTypeLinks: [],
3691
3791
  components: [],
@@ -3741,7 +3841,7 @@ const index = {
3741
3841
  app.router.addRoute({
3742
3842
  path: "content-manager/*",
3743
3843
  lazy: async () => {
3744
- const { Layout } = await import("./layout-ChVuUpa1.mjs");
3844
+ const { Layout } = await import("./layout-CK49ltFD.mjs");
3745
3845
  return {
3746
3846
  Component: Layout
3747
3847
  };
@@ -3750,10 +3850,15 @@ const index = {
3750
3850
  });
3751
3851
  app.registerPlugin(cm.config);
3752
3852
  },
3853
+ bootstrap(app) {
3854
+ if (typeof historyAdmin.bootstrap === "function") {
3855
+ historyAdmin.bootstrap(app);
3856
+ }
3857
+ },
3753
3858
  async registerTrads({ locales }) {
3754
3859
  const importedTrads = await Promise.all(
3755
3860
  locales.map((locale) => {
3756
- 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 }) => {
3757
3862
  return {
3758
3863
  data: prefixPluginTranslations(data, PLUGIN_ID),
3759
3864
  locale
@@ -3812,4 +3917,4 @@ export {
3812
3917
  useUpdateContentTypeConfigurationMutation as y,
3813
3918
  extractContentTypeComponents as z
3814
3919
  };
3815
- //# sourceMappingURL=index-D1344xdw.mjs.map
3920
+ //# sourceMappingURL=index-DYjyBm-q.mjs.map