@strapi/content-manager 0.0.0-experimental.7b750d18de359d0a42233cb8707e3c31c5983345 → 0.0.0-experimental.7bd770909ce799cf6fc76b7ebccd6d3ce2e377b5

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 (185) hide show
  1. package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -1
  2. package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -1
  3. package/dist/_chunks/{ComponentConfigurationPage-hLMNf7KI.mjs → ComponentConfigurationPage-BgCLcjXO.mjs} +4 -4
  4. package/dist/_chunks/{ComponentConfigurationPage-hLMNf7KI.mjs.map → ComponentConfigurationPage-BgCLcjXO.mjs.map} +1 -1
  5. package/dist/_chunks/{ComponentConfigurationPage-DnnZJc1F.js → ComponentConfigurationPage-DywpTZeV.js} +5 -6
  6. package/dist/_chunks/{ComponentConfigurationPage-DnnZJc1F.js.map → ComponentConfigurationPage-DywpTZeV.js.map} +1 -1
  7. package/dist/_chunks/{ComponentIcon-BXdiCGQp.js → ComponentIcon-CRbtQEUV.js} +2 -3
  8. package/dist/_chunks/{ComponentIcon-BXdiCGQp.js.map → ComponentIcon-CRbtQEUV.js.map} +1 -1
  9. package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -1
  10. package/dist/_chunks/{EditConfigurationPage-Dh6sq-G4.mjs → EditConfigurationPage-BNjOAHNS.mjs} +4 -4
  11. package/dist/_chunks/{EditConfigurationPage-Dh6sq-G4.mjs.map → EditConfigurationPage-BNjOAHNS.mjs.map} +1 -1
  12. package/dist/_chunks/{EditConfigurationPage-CpLj5gYZ.js → EditConfigurationPage-CxRlP5if.js} +5 -6
  13. package/dist/_chunks/{EditConfigurationPage-CpLj5gYZ.js.map → EditConfigurationPage-CxRlP5if.js.map} +1 -1
  14. package/dist/_chunks/{EditViewPage-D2QVRr_2.js → EditViewPage-BRewdTqE.js} +50 -11
  15. package/dist/_chunks/EditViewPage-BRewdTqE.js.map +1 -0
  16. package/dist/_chunks/{EditViewPage-BU1ugeVi.mjs → EditViewPage-CD_hqc1J.mjs} +50 -10
  17. package/dist/_chunks/EditViewPage-CD_hqc1J.mjs.map +1 -0
  18. package/dist/_chunks/{Field-VSPY6uzs.mjs → Field-BPkQ-3Ku.mjs} +129 -85
  19. package/dist/_chunks/Field-BPkQ-3Ku.mjs.map +1 -0
  20. package/dist/_chunks/{Field-BEDX9i_V.js → Field-DwvmENVf.js} +130 -87
  21. package/dist/_chunks/Field-DwvmENVf.js.map +1 -0
  22. package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
  23. package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
  24. package/dist/_chunks/{Form-DCaY8xBX.js → Form-C_Gwv8P_.js} +6 -7
  25. package/dist/_chunks/Form-C_Gwv8P_.js.map +1 -0
  26. package/dist/_chunks/{Form-05Oaes1N.mjs → Form-Czi0cf_2.mjs} +4 -4
  27. package/dist/_chunks/Form-Czi0cf_2.mjs.map +1 -0
  28. package/dist/_chunks/{History-BrJ1tUvt.js → History-C1TKAig-.js} +42 -100
  29. package/dist/_chunks/History-C1TKAig-.js.map +1 -0
  30. package/dist/_chunks/{History-BqO2G3MV.mjs → History-CIQHyi4T.mjs} +43 -100
  31. package/dist/_chunks/History-CIQHyi4T.mjs.map +1 -0
  32. package/dist/_chunks/{ListConfigurationPage-Eane5LKE.js → ListConfigurationPage-D-NGRLYu.js} +7 -7
  33. package/dist/_chunks/ListConfigurationPage-D-NGRLYu.js.map +1 -0
  34. package/dist/_chunks/{ListConfigurationPage-C6rsFlme.mjs → ListConfigurationPage-DcZsfyEL.mjs} +7 -6
  35. package/dist/_chunks/ListConfigurationPage-DcZsfyEL.mjs.map +1 -0
  36. package/dist/_chunks/{ListViewPage-yE_zYhcI.mjs → ListViewPage-C10McTK1.mjs} +62 -39
  37. package/dist/_chunks/ListViewPage-C10McTK1.mjs.map +1 -0
  38. package/dist/_chunks/{ListViewPage-Coj-RPsx.js → ListViewPage-xv5IQoZp.js} +63 -41
  39. package/dist/_chunks/ListViewPage-xv5IQoZp.js.map +1 -0
  40. package/dist/_chunks/{NoContentTypePage-NW_FSVdY.mjs → NoContentTypePage-CPc0Cd3S.mjs} +2 -2
  41. package/dist/_chunks/{NoContentTypePage-NW_FSVdY.mjs.map → NoContentTypePage-CPc0Cd3S.mjs.map} +1 -1
  42. package/dist/_chunks/{NoContentTypePage-BDJ0dshy.js → NoContentTypePage-Dzw5Yj5u.js} +2 -2
  43. package/dist/_chunks/{NoContentTypePage-BDJ0dshy.js.map → NoContentTypePage-Dzw5Yj5u.js.map} +1 -1
  44. package/dist/_chunks/{NoPermissionsPage-BOtb5FTM.js → NoPermissionsPage-DAe5CDCC.js} +2 -2
  45. package/dist/_chunks/{NoPermissionsPage-BOtb5FTM.js.map → NoPermissionsPage-DAe5CDCC.js.map} +1 -1
  46. package/dist/_chunks/{NoPermissionsPage-h0I3ImsX.mjs → NoPermissionsPage-wfPBh2_0.mjs} +2 -2
  47. package/dist/_chunks/{NoPermissionsPage-h0I3ImsX.mjs.map → NoPermissionsPage-wfPBh2_0.mjs.map} +1 -1
  48. package/dist/_chunks/Preview-B7LyGT_b.js +290 -0
  49. package/dist/_chunks/Preview-B7LyGT_b.js.map +1 -0
  50. package/dist/_chunks/Preview-BVFFm7uB.mjs +272 -0
  51. package/dist/_chunks/Preview-BVFFm7uB.mjs.map +1 -0
  52. package/dist/_chunks/{Relations-CVh0DOKv.js → Relations-BmYR1AjY.js} +75 -42
  53. package/dist/_chunks/Relations-BmYR1AjY.js.map +1 -0
  54. package/dist/_chunks/{Relations-FP0uWpBz.mjs → Relations-JPhWxk-s.mjs} +75 -41
  55. package/dist/_chunks/Relations-JPhWxk-s.mjs.map +1 -0
  56. package/dist/_chunks/{en-BlhnxQfj.js → en-BK8Xyl5I.js} +22 -10
  57. package/dist/_chunks/{en-BlhnxQfj.js.map → en-BK8Xyl5I.js.map} +1 -1
  58. package/dist/_chunks/{en-C8YBvRrK.mjs → en-Dtk_ot79.mjs} +22 -10
  59. package/dist/_chunks/{en-C8YBvRrK.mjs.map → en-Dtk_ot79.mjs.map} +1 -1
  60. package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
  61. package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
  62. package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
  63. package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
  64. package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
  65. package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
  66. package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
  67. package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
  68. package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
  69. package/dist/_chunks/{index-DTKVhcla.js → index-C2Q_PLWj.js} +299 -171
  70. package/dist/_chunks/index-C2Q_PLWj.js.map +1 -0
  71. package/dist/_chunks/{index-CPCHQ3X_.mjs → index-DLIkNVnQ.mjs} +302 -174
  72. package/dist/_chunks/index-DLIkNVnQ.mjs.map +1 -0
  73. package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
  74. package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
  75. package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
  76. package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
  77. package/dist/_chunks/{layout-CWgZzMYf.js → layout-7AsWJzZJ.js} +5 -6
  78. package/dist/_chunks/{layout-CWgZzMYf.js.map → layout-7AsWJzZJ.js.map} +1 -1
  79. package/dist/_chunks/{layout-B4UhJ8MJ.mjs → layout-qE8qkNH_.mjs} +4 -4
  80. package/dist/_chunks/{layout-B4UhJ8MJ.mjs.map → layout-qE8qkNH_.mjs.map} +1 -1
  81. package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
  82. package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
  83. package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
  84. package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
  85. package/dist/_chunks/{relations-B83Ge9a7.mjs → relations-BjHH_1Am.mjs} +6 -7
  86. package/dist/_chunks/relations-BjHH_1Am.mjs.map +1 -0
  87. package/dist/_chunks/{relations-D81a_2zw.js → relations-EifVzf_2.js} +6 -7
  88. package/dist/_chunks/relations-EifVzf_2.js.map +1 -0
  89. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -1
  90. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -1
  91. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
  92. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
  93. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
  94. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
  95. package/dist/admin/index.js +1 -1
  96. package/dist/admin/index.mjs +4 -4
  97. package/dist/admin/src/hooks/useDocument.d.ts +2 -0
  98. package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
  99. package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +2 -2
  100. package/dist/admin/src/pages/EditView/components/Header.d.ts +1 -0
  101. package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
  102. package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
  103. package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
  104. package/dist/admin/src/preview/constants.d.ts +1 -0
  105. package/dist/admin/src/preview/index.d.ts +4 -0
  106. package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
  107. package/dist/admin/src/preview/routes.d.ts +3 -0
  108. package/dist/admin/src/preview/services/preview.d.ts +3 -0
  109. package/dist/admin/src/router.d.ts +1 -1
  110. package/dist/admin/src/services/documents.d.ts +0 -3
  111. package/dist/server/index.js +435 -193
  112. package/dist/server/index.js.map +1 -1
  113. package/dist/server/index.mjs +435 -192
  114. package/dist/server/index.mjs.map +1 -1
  115. package/dist/server/src/bootstrap.d.ts.map +1 -1
  116. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  117. package/dist/server/src/controllers/index.d.ts.map +1 -1
  118. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  119. package/dist/server/src/controllers/utils/metadata.d.ts +15 -1
  120. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  121. package/dist/server/src/history/services/history.d.ts.map +1 -1
  122. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  123. package/dist/server/src/history/services/utils.d.ts +2 -3
  124. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  125. package/dist/server/src/index.d.ts +4 -4
  126. package/dist/server/src/preview/constants.d.ts +2 -0
  127. package/dist/server/src/preview/constants.d.ts.map +1 -0
  128. package/dist/server/src/preview/controllers/index.d.ts +2 -0
  129. package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
  130. package/dist/server/src/preview/controllers/preview.d.ts +13 -0
  131. package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
  132. package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
  133. package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
  134. package/dist/server/src/preview/index.d.ts +4 -0
  135. package/dist/server/src/preview/index.d.ts.map +1 -0
  136. package/dist/server/src/preview/routes/index.d.ts +8 -0
  137. package/dist/server/src/preview/routes/index.d.ts.map +1 -0
  138. package/dist/server/src/preview/routes/preview.d.ts +4 -0
  139. package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
  140. package/dist/server/src/preview/services/index.d.ts +16 -0
  141. package/dist/server/src/preview/services/index.d.ts.map +1 -0
  142. package/dist/server/src/preview/services/preview-config.d.ts +32 -0
  143. package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
  144. package/dist/server/src/preview/services/preview.d.ts +12 -0
  145. package/dist/server/src/preview/services/preview.d.ts.map +1 -0
  146. package/dist/server/src/preview/utils.d.ts +19 -0
  147. package/dist/server/src/preview/utils.d.ts.map +1 -0
  148. package/dist/server/src/register.d.ts.map +1 -1
  149. package/dist/server/src/routes/index.d.ts.map +1 -1
  150. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  151. package/dist/server/src/services/document-metadata.d.ts +8 -8
  152. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  153. package/dist/server/src/services/index.d.ts +4 -4
  154. package/dist/server/src/services/index.d.ts.map +1 -1
  155. package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
  156. package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
  157. package/dist/server/src/utils/index.d.ts +2 -0
  158. package/dist/server/src/utils/index.d.ts.map +1 -1
  159. package/dist/shared/contracts/index.d.ts +1 -0
  160. package/dist/shared/contracts/index.d.ts.map +1 -1
  161. package/dist/shared/contracts/preview.d.ts +27 -0
  162. package/dist/shared/contracts/preview.d.ts.map +1 -0
  163. package/dist/shared/index.js +4 -0
  164. package/dist/shared/index.js.map +1 -1
  165. package/dist/shared/index.mjs +4 -0
  166. package/dist/shared/index.mjs.map +1 -1
  167. package/package.json +12 -12
  168. package/dist/_chunks/EditViewPage-BU1ugeVi.mjs.map +0 -1
  169. package/dist/_chunks/EditViewPage-D2QVRr_2.js.map +0 -1
  170. package/dist/_chunks/Field-BEDX9i_V.js.map +0 -1
  171. package/dist/_chunks/Field-VSPY6uzs.mjs.map +0 -1
  172. package/dist/_chunks/Form-05Oaes1N.mjs.map +0 -1
  173. package/dist/_chunks/Form-DCaY8xBX.js.map +0 -1
  174. package/dist/_chunks/History-BqO2G3MV.mjs.map +0 -1
  175. package/dist/_chunks/History-BrJ1tUvt.js.map +0 -1
  176. package/dist/_chunks/ListConfigurationPage-C6rsFlme.mjs.map +0 -1
  177. package/dist/_chunks/ListConfigurationPage-Eane5LKE.js.map +0 -1
  178. package/dist/_chunks/ListViewPage-Coj-RPsx.js.map +0 -1
  179. package/dist/_chunks/ListViewPage-yE_zYhcI.mjs.map +0 -1
  180. package/dist/_chunks/Relations-CVh0DOKv.js.map +0 -1
  181. package/dist/_chunks/Relations-FP0uWpBz.mjs.map +0 -1
  182. package/dist/_chunks/index-CPCHQ3X_.mjs.map +0 -1
  183. package/dist/_chunks/index-DTKVhcla.js.map +0 -1
  184. package/dist/_chunks/relations-B83Ge9a7.mjs.map +0 -1
  185. package/dist/_chunks/relations-D81a_2zw.js.map +0 -1
@@ -1,25 +1,33 @@
1
1
  import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check, CrossCircle, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
2
2
  import { jsx, Fragment, jsxs } from "react/jsx-runtime";
3
- import { useStrapiApp, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, useQueryParams, getYupValidationErrors, useForm, useTracking, useGuidedTour, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
3
+ import { useStrapiApp, createContext, useQueryParams, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useForm, useTracking, useGuidedTour, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
4
4
  import * as React from "react";
5
5
  import { lazy } from "react";
6
- import { Button, Menu, VisuallyHidden, Flex, Typography, Dialog, Modal, Radio, Status, Box, SingleSelect, SingleSelectOption, IconButton, Loader, Tooltip, LinkButton } from "@strapi/design-system";
6
+ import { Menu, Button, VisuallyHidden, Flex, Dialog, Modal, Typography, Radio, Status, Box, SingleSelect, SingleSelectOption, IconButton, Loader, Tooltip, LinkButton } from "@strapi/design-system";
7
+ import mapValues from "lodash/fp/mapValues";
7
8
  import { useIntl } from "react-intl";
8
9
  import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
10
+ import { styled } from "styled-components";
9
11
  import * as yup from "yup";
10
12
  import { ValidationError } from "yup";
13
+ import { stringify } from "qs";
11
14
  import pipe from "lodash/fp/pipe";
12
15
  import { intervalToDuration, isPast } from "date-fns";
13
- import { styled } from "styled-components";
14
- import { stringify } from "qs";
15
16
  import { createSlice, combineReducers } from "@reduxjs/toolkit";
16
- const __variableDynamicImportRuntimeHelper = (glob, path) => {
17
+ const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
17
18
  const v = glob[path];
18
19
  if (v) {
19
20
  return typeof v === "function" ? v() : Promise.resolve(v);
20
21
  }
21
22
  return new Promise((_, reject) => {
22
- (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(reject.bind(null, new Error("Unknown variable dynamic import: " + path)));
23
+ (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
24
+ reject.bind(
25
+ null,
26
+ new Error(
27
+ "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
28
+ )
29
+ )
30
+ );
23
31
  });
24
32
  };
25
33
  const PLUGIN_ID = "content-manager";
@@ -100,6 +108,7 @@ const DocumentRBAC = ({ children, permissions }) => {
100
108
  if (!slug) {
101
109
  throw new Error("Cannot find the slug param in the URL");
102
110
  }
111
+ const [{ rawQuery }] = useQueryParams();
103
112
  const userPermissions = useAuth("DocumentRBAC", (state) => state.permissions);
104
113
  const contentTypePermissions = React.useMemo(() => {
105
114
  const contentTypePermissions2 = userPermissions.filter(
@@ -110,7 +119,14 @@ const DocumentRBAC = ({ children, permissions }) => {
110
119
  return { ...acc, [action]: [permission] };
111
120
  }, {});
112
121
  }, [slug, userPermissions]);
113
- const { isLoading, allowedActions } = useRBAC(contentTypePermissions, permissions ?? void 0);
122
+ const { isLoading, allowedActions } = useRBAC(
123
+ contentTypePermissions,
124
+ permissions ?? void 0,
125
+ // TODO: useRBAC context should be typed and built differently
126
+ // We are passing raw query as context to the hook so that it can
127
+ // rely on the locale provided from DocumentRBAC for its permission calculations.
128
+ rawQuery
129
+ );
114
130
  const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
115
131
  const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
116
132
  const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
@@ -265,7 +281,7 @@ const documentApi = contentManagerApi.injectEndpoints({
265
281
  url: `/content-manager/collection-types/${model}`,
266
282
  method: "GET",
267
283
  config: {
268
- params
284
+ params: stringify(params, { encode: true })
269
285
  }
270
286
  }),
271
287
  providesTags: (result, _error, arg) => {
@@ -444,8 +460,7 @@ const {
444
460
  useUnpublishManyDocumentsMutation
445
461
  } = documentApi;
446
462
  const buildValidParams = (query) => {
447
- if (!query)
448
- return query;
463
+ if (!query) return query;
449
464
  const { plugins: _, ...validQueryParams } = {
450
465
  ...query,
451
466
  ...Object.values(query?.plugins ?? {}).reduce(
@@ -453,14 +468,29 @@ const buildValidParams = (query) => {
453
468
  {}
454
469
  )
455
470
  };
456
- if ("_q" in validQueryParams) {
457
- validQueryParams._q = encodeURIComponent(validQueryParams._q);
458
- }
459
471
  return validQueryParams;
460
472
  };
461
473
  const isBaseQueryError = (error) => {
462
474
  return error.name !== void 0;
463
475
  };
476
+ const arrayValidator = (attribute, options) => ({
477
+ message: translatedErrors.required,
478
+ test(value) {
479
+ if (options.status === "draft") {
480
+ return true;
481
+ }
482
+ if (!attribute.required) {
483
+ return true;
484
+ }
485
+ if (!value) {
486
+ return false;
487
+ }
488
+ if (Array.isArray(value) && value.length === 0) {
489
+ return false;
490
+ }
491
+ return true;
492
+ }
493
+ });
464
494
  const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
465
495
  const createModelSchema = (attributes2) => yup.object().shape(
466
496
  Object.entries(attributes2).reduce((acc, [name, attribute]) => {
@@ -468,6 +498,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
468
498
  return acc;
469
499
  }
470
500
  const validations = [
501
+ addNullableValidation,
471
502
  addRequiredValidation,
472
503
  addMinLengthValidation,
473
504
  addMaxLengthValidation,
@@ -484,12 +515,12 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
484
515
  ...acc,
485
516
  [name]: transformSchema(
486
517
  yup.array().of(createModelSchema(attributes3).nullable(false))
487
- )
518
+ ).test(arrayValidator(attribute, options))
488
519
  };
489
520
  } else {
490
521
  return {
491
522
  ...acc,
492
- [name]: transformSchema(createModelSchema(attributes3))
523
+ [name]: transformSchema(createModelSchema(attributes3).nullable())
493
524
  };
494
525
  }
495
526
  }
@@ -511,7 +542,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
511
542
  }
512
543
  )
513
544
  )
514
- )
545
+ ).test(arrayValidator(attribute, options))
515
546
  };
516
547
  case "relation":
517
548
  return {
@@ -523,7 +554,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
523
554
  } else if (Array.isArray(value)) {
524
555
  return yup.array().of(
525
556
  yup.object().shape({
526
- id: yup.string().required()
557
+ id: yup.number().required()
527
558
  })
528
559
  );
529
560
  } else if (typeof value === "object") {
@@ -609,17 +640,17 @@ const nullableSchema = (schema) => {
609
640
  schema
610
641
  );
611
642
  };
643
+ const addNullableValidation = () => (schema) => {
644
+ return nullableSchema(schema);
645
+ };
612
646
  const addRequiredValidation = (attribute, options) => (schema) => {
613
- if (options.status === "draft") {
614
- return nullableSchema(schema);
615
- }
616
- if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
617
- return schema.min(1, translatedErrors.required);
647
+ if (options.status === "draft" || !attribute.required) {
648
+ return schema;
618
649
  }
619
- if (attribute.required && attribute.type !== "relation") {
650
+ if (attribute.required && "required" in schema) {
620
651
  return schema.required(translatedErrors.required);
621
652
  }
622
- return nullableSchema(schema);
653
+ return schema;
623
654
  };
624
655
  const addMinLengthValidation = (attribute, options) => (schema) => {
625
656
  if (options.status === "draft") {
@@ -647,31 +678,12 @@ const addMaxLengthValidation = (attribute) => (schema) => {
647
678
  return schema;
648
679
  };
649
680
  const addMinValidation = (attribute, options) => (schema) => {
650
- if ("min" in attribute) {
681
+ if (options.status === "draft") {
682
+ return schema;
683
+ }
684
+ if ("min" in attribute && "min" in schema) {
651
685
  const min = toInteger(attribute.min);
652
- if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
653
- if (options.status !== "draft" && !attribute.required && "test" in schema && min) {
654
- return schema.test(
655
- "custom-min",
656
- {
657
- ...translatedErrors.min,
658
- values: {
659
- min: attribute.min
660
- }
661
- },
662
- (value) => {
663
- if (!value) {
664
- return true;
665
- }
666
- if (Array.isArray(value) && value.length === 0) {
667
- return true;
668
- }
669
- return value.length >= min;
670
- }
671
- );
672
- }
673
- }
674
- if ("min" in schema && min) {
686
+ if (min) {
675
687
  return schema.min(min, {
676
688
  ...translatedErrors.min,
677
689
  values: {
@@ -960,9 +972,10 @@ const formatEditLayout = (data, {
960
972
  currentPanelIndex += 2;
961
973
  } else {
962
974
  if (!panels[currentPanelIndex]) {
963
- panels.push([]);
975
+ panels.push([row]);
976
+ } else {
977
+ panels[currentPanelIndex].push(row);
964
978
  }
965
- panels[currentPanelIndex].push(row);
966
979
  }
967
980
  return panels;
968
981
  }, []);
@@ -1144,11 +1157,13 @@ const useDocument = (args, opts) => {
1144
1157
  [validationSchema]
1145
1158
  );
1146
1159
  const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
1160
+ const hasError = !!error;
1147
1161
  return {
1148
1162
  components,
1149
1163
  document: data?.data,
1150
1164
  meta: data?.meta,
1151
1165
  isLoading,
1166
+ hasError,
1152
1167
  schema,
1153
1168
  schemas,
1154
1169
  validate
@@ -1164,16 +1179,18 @@ const useDoc = () => {
1164
1179
  if (!slug) {
1165
1180
  throw new Error("Could not find model in url params");
1166
1181
  }
1182
+ const document = useDocument(
1183
+ { documentId: origin || id, model: slug, collectionType, params },
1184
+ {
1185
+ skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
1186
+ }
1187
+ );
1188
+ const returnId = origin || id === "create" ? void 0 : id;
1167
1189
  return {
1168
1190
  collectionType,
1169
1191
  model: slug,
1170
- id: origin || id === "create" ? void 0 : id,
1171
- ...useDocument(
1172
- { documentId: origin || id, model: slug, collectionType, params },
1173
- {
1174
- skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
1175
- }
1176
- )
1192
+ id: returnId,
1193
+ ...document
1177
1194
  };
1178
1195
  };
1179
1196
  const useContentManagerContext = () => {
@@ -1216,9 +1233,6 @@ const useContentManagerContext = () => {
1216
1233
  };
1217
1234
  };
1218
1235
  const prefixPluginTranslations = (trad, pluginId) => {
1219
- if (!pluginId) {
1220
- throw new TypeError("pluginId can't be empty");
1221
- }
1222
1236
  return Object.keys(trad).reduce((acc, current) => {
1223
1237
  acc[`${pluginId}.${current}`] = trad[current];
1224
1238
  return acc;
@@ -1652,10 +1666,10 @@ const useDocumentActions = () => {
1652
1666
  update
1653
1667
  };
1654
1668
  };
1655
- const ProtectedHistoryPage = lazy(
1656
- () => import("./History-BqO2G3MV.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1669
+ const ProtectedHistoryPage = React.lazy(
1670
+ () => import("./History-CIQHyi4T.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1657
1671
  );
1658
- const routes$1 = [
1672
+ const routes$2 = [
1659
1673
  {
1660
1674
  path: ":collectionType/:slug/:id/history",
1661
1675
  Component: ProtectedHistoryPage
@@ -1665,32 +1679,45 @@ const routes$1 = [
1665
1679
  Component: ProtectedHistoryPage
1666
1680
  }
1667
1681
  ];
1682
+ const ProtectedPreviewPage = React.lazy(
1683
+ () => import("./Preview-BVFFm7uB.mjs").then((mod) => ({ default: mod.ProtectedPreviewPage }))
1684
+ );
1685
+ const routes$1 = [
1686
+ {
1687
+ path: ":collectionType/:slug/:id/preview",
1688
+ Component: ProtectedPreviewPage
1689
+ },
1690
+ {
1691
+ path: ":collectionType/:slug/preview",
1692
+ Component: ProtectedPreviewPage
1693
+ }
1694
+ ];
1668
1695
  const ProtectedEditViewPage = lazy(
1669
- () => import("./EditViewPage-BU1ugeVi.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1696
+ () => import("./EditViewPage-CD_hqc1J.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1670
1697
  );
1671
1698
  const ProtectedListViewPage = lazy(
1672
- () => import("./ListViewPage-yE_zYhcI.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1699
+ () => import("./ListViewPage-C10McTK1.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1673
1700
  );
1674
1701
  const ProtectedListConfiguration = lazy(
1675
- () => import("./ListConfigurationPage-C6rsFlme.mjs").then((mod) => ({
1702
+ () => import("./ListConfigurationPage-DcZsfyEL.mjs").then((mod) => ({
1676
1703
  default: mod.ProtectedListConfiguration
1677
1704
  }))
1678
1705
  );
1679
1706
  const ProtectedEditConfigurationPage = lazy(
1680
- () => import("./EditConfigurationPage-Dh6sq-G4.mjs").then((mod) => ({
1707
+ () => import("./EditConfigurationPage-BNjOAHNS.mjs").then((mod) => ({
1681
1708
  default: mod.ProtectedEditConfigurationPage
1682
1709
  }))
1683
1710
  );
1684
1711
  const ProtectedComponentConfigurationPage = lazy(
1685
- () => import("./ComponentConfigurationPage-hLMNf7KI.mjs").then((mod) => ({
1712
+ () => import("./ComponentConfigurationPage-BgCLcjXO.mjs").then((mod) => ({
1686
1713
  default: mod.ProtectedComponentConfigurationPage
1687
1714
  }))
1688
1715
  );
1689
1716
  const NoPermissions = lazy(
1690
- () => import("./NoPermissionsPage-h0I3ImsX.mjs").then((mod) => ({ default: mod.NoPermissions }))
1717
+ () => import("./NoPermissionsPage-wfPBh2_0.mjs").then((mod) => ({ default: mod.NoPermissions }))
1691
1718
  );
1692
1719
  const NoContentType = lazy(
1693
- () => import("./NoContentTypePage-NW_FSVdY.mjs").then((mod) => ({ default: mod.NoContentType }))
1720
+ () => import("./NoContentTypePage-CPc0Cd3S.mjs").then((mod) => ({ default: mod.NoContentType }))
1694
1721
  );
1695
1722
  const CollectionTypePages = () => {
1696
1723
  const { collectionType } = useParams();
@@ -1702,7 +1729,7 @@ const CollectionTypePages = () => {
1702
1729
  const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
1703
1730
  const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
1704
1731
  const LIST_RELATIVE_PATH = ":collectionType/:slug";
1705
- const LIST_PATH = `/content-manager/${LIST_RELATIVE_PATH}`;
1732
+ const LIST_PATH = `/content-manager/collection-types/:slug`;
1706
1733
  const routes = [
1707
1734
  {
1708
1735
  path: LIST_RELATIVE_PATH,
@@ -1736,6 +1763,7 @@ const routes = [
1736
1763
  path: "no-content-types",
1737
1764
  Component: NoContentType
1738
1765
  },
1766
+ ...routes$2,
1739
1767
  ...routes$1
1740
1768
  ];
1741
1769
  const DocumentActions = ({ actions: actions2 }) => {
@@ -1834,6 +1862,11 @@ const DocumentActionButton = (action) => {
1834
1862
  ) : null
1835
1863
  ] });
1836
1864
  };
1865
+ const MenuItem = styled(Menu.Item)`
1866
+ &:hover {
1867
+ background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
1868
+ }
1869
+ `;
1837
1870
  const DocumentActionsMenu = ({
1838
1871
  actions: actions2,
1839
1872
  children,
@@ -1892,48 +1925,32 @@ const DocumentActionsMenu = ({
1892
1925
  /* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
1893
1926
  actions2.map((action) => {
1894
1927
  return /* @__PURE__ */ jsx(
1895
- Menu.Item,
1928
+ MenuItem,
1896
1929
  {
1897
1930
  disabled: action.disabled,
1898
1931
  onSelect: handleClick(action),
1899
1932
  display: "block",
1900
- children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
1901
- /* @__PURE__ */ jsxs(
1902
- Flex,
1903
- {
1904
- color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
1905
- gap: 2,
1906
- tag: "span",
1907
- children: [
1908
- /* @__PURE__ */ jsx(
1909
- Flex,
1910
- {
1911
- tag: "span",
1912
- color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
1913
- children: action.icon
1914
- }
1915
- ),
1916
- action.label
1917
- ]
1918
- }
1919
- ),
1920
- action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
1921
- Flex,
1922
- {
1923
- alignItems: "center",
1924
- background: "alternative100",
1925
- borderStyle: "solid",
1926
- borderColor: "alternative200",
1927
- borderWidth: "1px",
1928
- height: 5,
1929
- paddingLeft: 2,
1930
- paddingRight: 2,
1931
- hasRadius: true,
1932
- color: "alternative600",
1933
- children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", fontWeight: "bold", lineHeight: 1, children: formatMessage({ id: "global.new", defaultMessage: "New" }) })
1934
- }
1935
- )
1936
- ] })
1933
+ isVariantDanger: action.variant === "danger",
1934
+ isDisabled: action.disabled,
1935
+ children: /* @__PURE__ */ jsx(Flex, { justifyContent: "space-between", gap: 4, children: /* @__PURE__ */ jsxs(
1936
+ Flex,
1937
+ {
1938
+ color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
1939
+ gap: 2,
1940
+ tag: "span",
1941
+ children: [
1942
+ /* @__PURE__ */ jsx(
1943
+ Flex,
1944
+ {
1945
+ tag: "span",
1946
+ color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
1947
+ children: action.icon
1948
+ }
1949
+ ),
1950
+ action.label
1951
+ ]
1952
+ }
1953
+ ) })
1937
1954
  },
1938
1955
  action.id
1939
1956
  );
@@ -2044,6 +2061,18 @@ const DocumentActionModal = ({
2044
2061
  typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
2045
2062
  ] }) });
2046
2063
  };
2064
+ const transformData = (data) => {
2065
+ if (Array.isArray(data)) {
2066
+ return data.map(transformData);
2067
+ }
2068
+ if (typeof data === "object" && data !== null) {
2069
+ if ("apiData" in data) {
2070
+ return data.apiData;
2071
+ }
2072
+ return mapValues(transformData)(data);
2073
+ }
2074
+ return data;
2075
+ };
2047
2076
  const PublishAction$1 = ({
2048
2077
  activeTab,
2049
2078
  documentId,
@@ -2058,6 +2087,7 @@ const PublishAction$1 = ({
2058
2087
  const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
2059
2088
  const isListView = useMatch(LIST_PATH) !== null;
2060
2089
  const isCloning = useMatch(CLONE_PATH) !== null;
2090
+ const { id } = useParams();
2061
2091
  const { formatMessage } = useIntl();
2062
2092
  const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
2063
2093
  const { publish } = useDocumentActions();
@@ -2137,7 +2167,9 @@ const PublishAction$1 = ({
2137
2167
  const performPublish = async () => {
2138
2168
  setSubmitting(true);
2139
2169
  try {
2140
- const { errors } = await validate();
2170
+ const { errors } = await validate(true, {
2171
+ status: "published"
2172
+ });
2141
2173
  if (errors) {
2142
2174
  toggleNotification({
2143
2175
  type: "danger",
@@ -2155,13 +2187,15 @@ const PublishAction$1 = ({
2155
2187
  documentId,
2156
2188
  params
2157
2189
  },
2158
- formValues
2190
+ transformData(formValues)
2159
2191
  );
2160
2192
  if ("data" in res && collectionType !== SINGLE_TYPES) {
2161
- navigate({
2162
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
2163
- search: rawQuery
2164
- });
2193
+ if (id === "create") {
2194
+ navigate({
2195
+ pathname: `../${collectionType}/${model}/${res.data.documentId}`,
2196
+ search: rawQuery
2197
+ });
2198
+ }
2165
2199
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2166
2200
  setErrors(formatValidationErrors(res.error));
2167
2201
  }
@@ -2245,24 +2279,24 @@ const UpdateAction = ({
2245
2279
  */
2246
2280
  disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
2247
2281
  label: formatMessage({
2248
- id: "content-manager.containers.Edit.save",
2282
+ id: "global.save",
2249
2283
  defaultMessage: "Save"
2250
2284
  }),
2251
2285
  onClick: async () => {
2252
2286
  setSubmitting(true);
2253
2287
  try {
2254
- if (activeTab !== "draft") {
2255
- const { errors } = await validate();
2256
- if (errors) {
2257
- toggleNotification({
2258
- type: "danger",
2259
- message: formatMessage({
2260
- id: "content-manager.validation.error",
2261
- defaultMessage: "There are validation errors in your document. Please fix them before saving."
2262
- })
2263
- });
2264
- return;
2265
- }
2288
+ const { errors } = await validate(true, {
2289
+ status: "draft"
2290
+ });
2291
+ if (errors) {
2292
+ toggleNotification({
2293
+ type: "danger",
2294
+ message: formatMessage({
2295
+ id: "content-manager.validation.error",
2296
+ defaultMessage: "There are validation errors in your document. Please fix them before saving."
2297
+ })
2298
+ });
2299
+ return;
2266
2300
  }
2267
2301
  if (isCloning) {
2268
2302
  const res = await clone(
@@ -2271,7 +2305,7 @@ const UpdateAction = ({
2271
2305
  documentId: cloneMatch.params.origin,
2272
2306
  params
2273
2307
  },
2274
- document
2308
+ transformData(document)
2275
2309
  );
2276
2310
  if ("data" in res) {
2277
2311
  navigate(
@@ -2292,7 +2326,7 @@ const UpdateAction = ({
2292
2326
  documentId,
2293
2327
  params
2294
2328
  },
2295
- document
2329
+ transformData(document)
2296
2330
  );
2297
2331
  if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2298
2332
  setErrors(formatValidationErrors(res.error));
@@ -2305,7 +2339,7 @@ const UpdateAction = ({
2305
2339
  model,
2306
2340
  params
2307
2341
  },
2308
- document
2342
+ transformData(document)
2309
2343
  );
2310
2344
  if ("data" in res && collectionType !== SINGLE_TYPES) {
2311
2345
  navigate(
@@ -2510,7 +2544,7 @@ const RelativeTime = React.forwardRef(
2510
2544
  });
2511
2545
  const unit = intervals.find((intervalUnit) => {
2512
2546
  return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
2513
- });
2547
+ }) ?? "seconds";
2514
2548
  const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
2515
2549
  const customInterval = customIntervals.find(
2516
2550
  (custom) => interval[custom.unit] < custom.threshold
@@ -2544,19 +2578,29 @@ const getDisplayName = ({
2544
2578
  return email ?? "";
2545
2579
  };
2546
2580
  const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2547
- const DocumentStatus = ({ status = "draft", ...restProps }) => {
2581
+ const DocumentStatus = ({ status = "draft", size = "S", ...restProps }) => {
2548
2582
  const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
2549
- return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
2583
+ const { formatMessage } = useIntl();
2584
+ return /* @__PURE__ */ jsx(Status, { ...restProps, size, variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: formatMessage({
2585
+ id: `content-manager.containers.List.${status}`,
2586
+ defaultMessage: capitalise(status)
2587
+ }) }) });
2550
2588
  };
2551
2589
  const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2552
2590
  const { formatMessage } = useIntl();
2553
2591
  const isCloning = useMatch(CLONE_PATH) !== null;
2592
+ const params = useParams();
2554
2593
  const title = isCreating ? formatMessage({
2555
2594
  id: "content-manager.containers.edit.title.new",
2556
2595
  defaultMessage: "Create an entry"
2557
2596
  }) : documentTitle;
2558
2597
  return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
2559
- /* @__PURE__ */ jsx(BackButton, {}),
2598
+ /* @__PURE__ */ jsx(
2599
+ BackButton,
2600
+ {
2601
+ fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
2602
+ }
2603
+ ),
2560
2604
  /* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
2561
2605
  /* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
2562
2606
  /* @__PURE__ */ jsx(HeaderToolbar, {})
@@ -2644,12 +2688,12 @@ const Information = ({ activeTab }) => {
2644
2688
  isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
2645
2689
  label: formatMessage({
2646
2690
  id: "content-manager.containers.edit.information.last-published.label",
2647
- defaultMessage: "Last published"
2691
+ defaultMessage: "Published"
2648
2692
  }),
2649
2693
  value: formatMessage(
2650
2694
  {
2651
2695
  id: "content-manager.containers.edit.information.last-published.value",
2652
- defaultMessage: `Published {time}{isAnonymous, select, true {} other { by {author}}}`
2696
+ defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
2653
2697
  },
2654
2698
  {
2655
2699
  time: /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
@@ -2662,12 +2706,12 @@ const Information = ({ activeTab }) => {
2662
2706
  isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
2663
2707
  label: formatMessage({
2664
2708
  id: "content-manager.containers.edit.information.last-draft.label",
2665
- defaultMessage: "Last draft"
2709
+ defaultMessage: "Updated"
2666
2710
  }),
2667
2711
  value: formatMessage(
2668
2712
  {
2669
2713
  id: "content-manager.containers.edit.information.last-draft.value",
2670
- defaultMessage: `Modified {time}{isAnonymous, select, true {} other { by {author}}}`
2714
+ defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
2671
2715
  },
2672
2716
  {
2673
2717
  time: /* @__PURE__ */ jsx(
@@ -2685,12 +2729,12 @@ const Information = ({ activeTab }) => {
2685
2729
  isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
2686
2730
  label: formatMessage({
2687
2731
  id: "content-manager.containers.edit.information.document.label",
2688
- defaultMessage: "Document"
2732
+ defaultMessage: "Created"
2689
2733
  }),
2690
2734
  value: formatMessage(
2691
2735
  {
2692
2736
  id: "content-manager.containers.edit.information.document.value",
2693
- defaultMessage: `Created {time}{isAnonymous, select, true {} other { by {author}}}`
2737
+ defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
2694
2738
  },
2695
2739
  {
2696
2740
  time: /* @__PURE__ */ jsx(
@@ -2748,10 +2792,9 @@ const HeaderActions = ({ actions: actions2 }) => {
2748
2792
  SingleSelect,
2749
2793
  {
2750
2794
  size: "S",
2751
- disabled: action.disabled,
2752
- "aria-label": action.label,
2753
2795
  onChange: action.onSelect,
2754
- value: action.value,
2796
+ "aria-label": action.label,
2797
+ ...action,
2755
2798
  children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
2756
2799
  },
2757
2800
  action.id
@@ -2994,7 +3037,7 @@ const Panel = React.forwardRef(({ children, title }, ref) => {
2994
3037
  justifyContent: "stretch",
2995
3038
  alignItems: "flex-start",
2996
3039
  children: [
2997
- /* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
3040
+ /* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", textColor: "neutral600", children: title }),
2998
3041
  children
2999
3042
  ]
3000
3043
  }
@@ -3244,18 +3287,10 @@ const SelectedEntriesTableContent = ({
3244
3287
  search: row.locale && `?plugins[i18n][locale]=${row.locale}`
3245
3288
  },
3246
3289
  state: { from: pathname },
3247
- label: formatMessage(
3248
- { id: "app.component.HelperPluginTable.edit", defaultMessage: "Edit {target}" },
3249
- {
3250
- target: formatMessage(
3251
- {
3252
- id: "content-manager.components.ListViewHelperPluginTable.row-line",
3253
- defaultMessage: "item line {number}"
3254
- },
3255
- { number: index2 + 1 }
3256
- )
3257
- }
3258
- ),
3290
+ label: formatMessage({
3291
+ id: "content-manager.bulk-publish.edit",
3292
+ defaultMessage: "Edit"
3293
+ }),
3259
3294
  target: "_blank",
3260
3295
  marginLeft: "auto",
3261
3296
  variant: "ghost",
@@ -3429,8 +3464,7 @@ const PublishAction = ({ documents, model }) => {
3429
3464
  const refetchList = () => {
3430
3465
  contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
3431
3466
  };
3432
- if (!showPublishButton)
3433
- return null;
3467
+ if (!showPublishButton) return null;
3434
3468
  return {
3435
3469
  actionType: "publish",
3436
3470
  variant: "tertiary",
@@ -3498,8 +3532,7 @@ const DeleteAction = ({ documents, model }) => {
3498
3532
  selectRow([]);
3499
3533
  }
3500
3534
  };
3501
- if (!hasDeletePermission)
3502
- return null;
3535
+ if (!hasDeletePermission) return null;
3503
3536
  return {
3504
3537
  variant: "danger-light",
3505
3538
  label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
@@ -3548,8 +3581,7 @@ const UnpublishAction = ({ documents, model }) => {
3548
3581
  }
3549
3582
  };
3550
3583
  const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
3551
- if (!showUnpublishButton)
3552
- return null;
3584
+ if (!showUnpublishButton) return null;
3553
3585
  return {
3554
3586
  variant: "tertiary",
3555
3587
  label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
@@ -3885,10 +3917,8 @@ class ContentManagerPlugin {
3885
3917
  const getPrintableType = (value) => {
3886
3918
  const nativeType = typeof value;
3887
3919
  if (nativeType === "object") {
3888
- if (value === null)
3889
- return "null";
3890
- if (Array.isArray(value))
3891
- return "array";
3920
+ if (value === null) return "null";
3921
+ if (Array.isArray(value)) return "array";
3892
3922
  if (value instanceof Object && value.constructor.name !== "Object") {
3893
3923
  return value.constructor.name;
3894
3924
  }
@@ -3899,17 +3929,27 @@ const HistoryAction = ({ model, document }) => {
3899
3929
  const { formatMessage } = useIntl();
3900
3930
  const [{ query }] = useQueryParams();
3901
3931
  const navigate = useNavigate();
3932
+ const { trackUsage } = useTracking();
3933
+ const { pathname } = useLocation();
3902
3934
  const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
3903
3935
  if (!window.strapi.features.isEnabled("cms-content-history")) {
3904
3936
  return null;
3905
3937
  }
3938
+ const handleOnClick = () => {
3939
+ const destination = { pathname: "history", search: pluginsQueryParams };
3940
+ trackUsage("willNavigate", {
3941
+ from: pathname,
3942
+ to: `${pathname}/${destination.pathname}`
3943
+ });
3944
+ navigate(destination);
3945
+ };
3906
3946
  return {
3907
3947
  icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
3908
3948
  label: formatMessage({
3909
3949
  id: "content-manager.history.document-action",
3910
3950
  defaultMessage: "Content History"
3911
3951
  }),
3912
- onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
3952
+ onClick: handleOnClick,
3913
3953
  disabled: (
3914
3954
  /**
3915
3955
  * The user is creating a new document.
@@ -3977,6 +4017,90 @@ const { setInitialData } = actions;
3977
4017
  const reducer = combineReducers({
3978
4018
  app: reducer$1
3979
4019
  });
4020
+ const previewApi = contentManagerApi.injectEndpoints({
4021
+ endpoints: (builder) => ({
4022
+ getPreviewUrl: builder.query({
4023
+ query({ query, params }) {
4024
+ return {
4025
+ url: `/content-manager/preview/url/${params.contentType}`,
4026
+ method: "GET",
4027
+ config: {
4028
+ params: query
4029
+ }
4030
+ };
4031
+ }
4032
+ })
4033
+ })
4034
+ });
4035
+ const { useGetPreviewUrlQuery } = previewApi;
4036
+ const ConditionalTooltip = ({ isShown, label, children }) => {
4037
+ if (isShown) {
4038
+ return /* @__PURE__ */ jsx(Tooltip, { label, children });
4039
+ }
4040
+ return children;
4041
+ };
4042
+ const PreviewSidePanel = ({ model, documentId, document }) => {
4043
+ const { formatMessage } = useIntl();
4044
+ const { trackUsage } = useTracking();
4045
+ const { pathname } = useLocation();
4046
+ const [{ query }] = useQueryParams();
4047
+ const isModified = useForm("PreviewSidePanel", (state) => state.modified);
4048
+ const { data, error } = useGetPreviewUrlQuery({
4049
+ params: {
4050
+ contentType: model
4051
+ },
4052
+ query: {
4053
+ documentId,
4054
+ locale: document?.locale,
4055
+ status: document?.status
4056
+ }
4057
+ });
4058
+ if (!data?.data?.url || error) {
4059
+ return null;
4060
+ }
4061
+ const trackNavigation = () => {
4062
+ const destinationPathname = pathname.replace(/\/$/, "") + "/preview";
4063
+ trackUsage("willNavigate", { from: pathname, to: destinationPathname });
4064
+ };
4065
+ return {
4066
+ title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
4067
+ content: /* @__PURE__ */ jsx(Flex, { gap: 2, width: "100%", children: /* @__PURE__ */ jsx(
4068
+ ConditionalTooltip,
4069
+ {
4070
+ label: formatMessage({
4071
+ id: "content-manager.preview.panel.button-disabled-tooltip",
4072
+ defaultMessage: "Please save to open the preview"
4073
+ }),
4074
+ isShown: isModified,
4075
+ children: /* @__PURE__ */ jsx(
4076
+ Button,
4077
+ {
4078
+ variant: "tertiary",
4079
+ tag: Link,
4080
+ to: { pathname: "preview", search: stringify(query, { encode: false }) },
4081
+ onClick: trackNavigation,
4082
+ flex: "auto",
4083
+ disabled: isModified,
4084
+ children: formatMessage({
4085
+ id: "content-manager.preview.panel.button",
4086
+ defaultMessage: "Open preview"
4087
+ })
4088
+ }
4089
+ )
4090
+ }
4091
+ ) })
4092
+ };
4093
+ };
4094
+ const FEATURE_ID = "preview";
4095
+ const previewAdmin = {
4096
+ bootstrap(app) {
4097
+ if (!window.strapi.future.isEnabled(FEATURE_ID)) {
4098
+ return;
4099
+ }
4100
+ const contentManagerPluginApis = app.getPlugin("content-manager").apis;
4101
+ contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
4102
+ }
4103
+ };
3980
4104
  const index = {
3981
4105
  register(app) {
3982
4106
  const cm = new ContentManagerPlugin();
@@ -3996,7 +4120,7 @@ const index = {
3996
4120
  app.router.addRoute({
3997
4121
  path: "content-manager/*",
3998
4122
  lazy: async () => {
3999
- const { Layout } = await import("./layout-B4UhJ8MJ.mjs");
4123
+ const { Layout } = await import("./layout-qE8qkNH_.mjs");
4000
4124
  return {
4001
4125
  Component: Layout
4002
4126
  };
@@ -4009,11 +4133,14 @@ const index = {
4009
4133
  if (typeof historyAdmin.bootstrap === "function") {
4010
4134
  historyAdmin.bootstrap(app);
4011
4135
  }
4136
+ if (typeof previewAdmin.bootstrap === "function") {
4137
+ previewAdmin.bootstrap(app);
4138
+ }
4012
4139
  },
4013
4140
  async registerTrads({ locales }) {
4014
4141
  const importedTrads = await Promise.all(
4015
4142
  locales.map((locale) => {
4016
- 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-C8YBvRrK.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 }) => {
4143
+ 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-Dtk_ot79.mjs"), "./translations/es.json": () => import("./es-D34tqjMw.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr--pg5jUbt.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-BHqhDq4V.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`, 3).then(({ default: data }) => {
4017
4144
  return {
4018
4145
  data: prefixPluginTranslations(data, PLUGIN_ID),
4019
4146
  locale
@@ -4040,9 +4167,10 @@ export {
4040
4167
  HOOKS as H,
4041
4168
  InjectionZone as I,
4042
4169
  useDocument as J,
4043
- index as K,
4044
- useContentManagerContext as L,
4045
- useDocumentActions as M,
4170
+ useGetPreviewUrlQuery as K,
4171
+ index as L,
4172
+ useContentManagerContext as M,
4173
+ useDocumentActions as N,
4046
4174
  Panels as P,
4047
4175
  RelativeTime as R,
4048
4176
  SINGLE_TYPES as S,
@@ -4074,4 +4202,4 @@ export {
4074
4202
  capitalise as y,
4075
4203
  useUpdateContentTypeConfigurationMutation as z
4076
4204
  };
4077
- //# sourceMappingURL=index-CPCHQ3X_.mjs.map
4205
+ //# sourceMappingURL=index-DLIkNVnQ.mjs.map