@strapi/content-manager 0.0.0-experimental.fed75ee8e64c57dbed0b670b25ef026b69baab10 → 0.0.0-next.008421e40e4f0fb98aab7504cea5a2b8ef7099d5

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 (204) 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-BVM7LScS.mjs → ComponentConfigurationPage-9_4yUE9L.mjs} +4 -4
  4. package/dist/_chunks/{ComponentConfigurationPage-BVM7LScS.mjs.map → ComponentConfigurationPage-9_4yUE9L.mjs.map} +1 -1
  5. package/dist/_chunks/{ComponentConfigurationPage-DNRPa10q.js → ComponentConfigurationPage-DBSh-kET.js} +5 -6
  6. package/dist/_chunks/{ComponentConfigurationPage-DNRPa10q.js.map → ComponentConfigurationPage-DBSh-kET.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-BrG0mEfF.js → EditConfigurationPage-Bl_U2JgH.js} +5 -6
  11. package/dist/_chunks/{EditConfigurationPage-BrG0mEfF.js.map → EditConfigurationPage-Bl_U2JgH.js.map} +1 -1
  12. package/dist/_chunks/{EditConfigurationPage-BWq-9Zhk.mjs → EditConfigurationPage-COe6hjPC.mjs} +4 -4
  13. package/dist/_chunks/{EditConfigurationPage-BWq-9Zhk.mjs.map → EditConfigurationPage-COe6hjPC.mjs.map} +1 -1
  14. package/dist/_chunks/{EditViewPage-BbY0bNNE.js → EditViewPage-D4yFJET6.js} +23 -57
  15. package/dist/_chunks/EditViewPage-D4yFJET6.js.map +1 -0
  16. package/dist/_chunks/{EditViewPage-Dx0QnTxn.mjs → EditViewPage-DrmVmYN0.mjs} +21 -54
  17. package/dist/_chunks/EditViewPage-DrmVmYN0.mjs.map +1 -0
  18. package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
  19. package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
  20. package/dist/_chunks/{Form-B7nYNIUm.js → Form-C4rSaGsz.js} +5 -6
  21. package/dist/_chunks/{Form-B7nYNIUm.js.map → Form-C4rSaGsz.js.map} +1 -1
  22. package/dist/_chunks/{Form-BQwxPqu3.mjs → Form-DamaxNpG.mjs} +3 -3
  23. package/dist/_chunks/{Form-BQwxPqu3.mjs.map → Form-DamaxNpG.mjs.map} +1 -1
  24. package/dist/_chunks/{History-Bmu6tx6s.mjs → History-D1PreDSY.mjs} +51 -97
  25. package/dist/_chunks/History-D1PreDSY.mjs.map +1 -0
  26. package/dist/_chunks/{History-3JN4BIS1.js → History-DTm8UCCQ.js} +62 -109
  27. package/dist/_chunks/History-DTm8UCCQ.js.map +1 -0
  28. package/dist/_chunks/{Field-CglKum3X.js → Input-B7sapvBG.js} +1258 -1236
  29. package/dist/_chunks/Input-B7sapvBG.js.map +1 -0
  30. package/dist/_chunks/{Field-DVZSGAon.mjs → Input-CZ1YvjHR.mjs} +1333 -1311
  31. package/dist/_chunks/Input-CZ1YvjHR.mjs.map +1 -0
  32. package/dist/_chunks/{ListConfigurationPage-DwijcJ17.mjs → ListConfigurationPage-Bbi32isk.mjs} +7 -6
  33. package/dist/_chunks/ListConfigurationPage-Bbi32isk.mjs.map +1 -0
  34. package/dist/_chunks/{ListConfigurationPage-BcC28SV0.js → ListConfigurationPage-ysFMjKI3.js} +7 -7
  35. package/dist/_chunks/ListConfigurationPage-ysFMjKI3.js.map +1 -0
  36. package/dist/_chunks/{ListViewPage-DzhuS3CW.mjs → ListViewPage-Bud_jBDQ.mjs} +67 -41
  37. package/dist/_chunks/ListViewPage-Bud_jBDQ.mjs.map +1 -0
  38. package/dist/_chunks/{ListViewPage-ZPNQ6jWC.js → ListViewPage-DTuuxU3n.js} +73 -48
  39. package/dist/_chunks/ListViewPage-DTuuxU3n.js.map +1 -0
  40. package/dist/_chunks/{NoContentTypePage-DzwJNXvn.js → NoContentTypePage-CL7VVeYs.js} +2 -2
  41. package/dist/_chunks/{NoContentTypePage-DzwJNXvn.js.map → NoContentTypePage-CL7VVeYs.js.map} +1 -1
  42. package/dist/_chunks/{NoContentTypePage-BKMgOyd3.mjs → NoContentTypePage-DVhkugsf.mjs} +2 -2
  43. package/dist/_chunks/{NoContentTypePage-BKMgOyd3.mjs.map → NoContentTypePage-DVhkugsf.mjs.map} +1 -1
  44. package/dist/_chunks/{NoPermissionsPage-DBbGJqL9.mjs → NoPermissionsPage-CMdM-dCo.mjs} +2 -2
  45. package/dist/_chunks/{NoPermissionsPage-DBbGJqL9.mjs.map → NoPermissionsPage-CMdM-dCo.mjs.map} +1 -1
  46. package/dist/_chunks/{NoPermissionsPage-GaweP-NG.js → NoPermissionsPage-v7I599vC.js} +2 -2
  47. package/dist/_chunks/{NoPermissionsPage-GaweP-NG.js.map → NoPermissionsPage-v7I599vC.js.map} +1 -1
  48. package/dist/_chunks/Preview-BNuU0SuQ.mjs +287 -0
  49. package/dist/_chunks/Preview-BNuU0SuQ.mjs.map +1 -0
  50. package/dist/_chunks/Preview-Cxq-uI6D.js +305 -0
  51. package/dist/_chunks/Preview-Cxq-uI6D.js.map +1 -0
  52. package/dist/_chunks/{Relations-B7VtRA3g.mjs → Relations-C2Ahkrdg.mjs} +47 -23
  53. package/dist/_chunks/Relations-C2Ahkrdg.mjs.map +1 -0
  54. package/dist/_chunks/{Relations-BHXq_cKF.js → Relations-CWS79QQn.js} +47 -24
  55. package/dist/_chunks/Relations-CWS79QQn.js.map +1 -0
  56. package/dist/_chunks/{en-Bm0D0IWz.js → en-BR48D_RH.js} +23 -4
  57. package/dist/_chunks/{en-Bm0D0IWz.js.map → en-BR48D_RH.js.map} +1 -1
  58. package/dist/_chunks/{en-DKV44jRb.mjs → en-D65uIF6Y.mjs} +23 -4
  59. package/dist/_chunks/{en-DKV44jRb.mjs.map → en-D65uIF6Y.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-B7kGGg3E.js → fr-C43IbhA_.js} +16 -3
  65. package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-C43IbhA_.js.map} +1 -1
  66. package/dist/_chunks/{fr-CD9VFbPM.mjs → fr-DBseuRuB.mjs} +16 -3
  67. package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr-DBseuRuB.mjs.map} +1 -1
  68. package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
  69. package/dist/_chunks/{index-DcA8_tJw.js → index-DQsvBb_N.js} +629 -268
  70. package/dist/_chunks/index-DQsvBb_N.js.map +1 -0
  71. package/dist/_chunks/{index-TaRzG09p.mjs → index-ZKrsjv-2.mjs} +645 -284
  72. package/dist/_chunks/index-ZKrsjv-2.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-CrgXpOxT.js → layout-Cl0NhlQB.js} +5 -6
  78. package/dist/_chunks/{layout-CrgXpOxT.js.map → layout-Cl0NhlQB.js.map} +1 -1
  79. package/dist/_chunks/{layout-aX-RJhd5.mjs → layout-fQk1rMk9.mjs} +4 -4
  80. package/dist/_chunks/{layout-aX-RJhd5.mjs.map → layout-fQk1rMk9.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-Z6RA1sBS.js → relations-BRfBxVbX.js} +6 -7
  86. package/dist/_chunks/relations-BRfBxVbX.js.map +1 -0
  87. package/dist/_chunks/{relations-D3Hlx6QX.mjs → relations-BakOFl_1.mjs} +6 -7
  88. package/dist/_chunks/relations-BakOFl_1.mjs.map +1 -0
  89. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
  90. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
  91. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
  92. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
  93. package/dist/_chunks/{useDebounce-DmuSJIF3.mjs → usePrev-CZGy2Vjf.mjs} +11 -11
  94. package/dist/_chunks/usePrev-CZGy2Vjf.mjs.map +1 -0
  95. package/dist/_chunks/{useDebounce-CtcjDB3L.js → usePrev-D5J_2fEu.js} +8 -8
  96. package/dist/_chunks/usePrev-D5J_2fEu.js.map +1 -0
  97. package/dist/admin/index.js +2 -1
  98. package/dist/admin/index.js.map +1 -1
  99. package/dist/admin/index.mjs +6 -5
  100. package/dist/admin/src/content-manager.d.ts +3 -2
  101. package/dist/admin/src/exports.d.ts +1 -0
  102. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  103. package/dist/admin/src/hooks/useDocument.d.ts +19 -2
  104. package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
  105. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -1
  106. package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +3 -3
  107. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +7 -0
  108. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
  109. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
  110. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.d.ts +4 -1
  111. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +4 -1
  112. package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +27 -0
  113. package/dist/admin/src/pages/EditView/utils/data.d.ts +1 -0
  114. package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
  115. package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
  116. package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
  117. package/dist/admin/src/preview/index.d.ts +4 -0
  118. package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
  119. package/dist/admin/src/preview/routes.d.ts +3 -0
  120. package/dist/admin/src/preview/services/preview.d.ts +3 -0
  121. package/dist/admin/src/router.d.ts +1 -1
  122. package/dist/admin/src/services/api.d.ts +1 -1
  123. package/dist/admin/src/services/components.d.ts +2 -2
  124. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  125. package/dist/admin/src/services/documents.d.ts +16 -19
  126. package/dist/admin/src/services/init.d.ts +1 -1
  127. package/dist/admin/src/services/relations.d.ts +2 -2
  128. package/dist/admin/src/services/uid.d.ts +3 -3
  129. package/dist/server/index.js +560 -317
  130. package/dist/server/index.js.map +1 -1
  131. package/dist/server/index.mjs +561 -317
  132. package/dist/server/index.mjs.map +1 -1
  133. package/dist/server/src/bootstrap.d.ts.map +1 -1
  134. package/dist/server/src/controllers/index.d.ts.map +1 -1
  135. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  136. package/dist/server/src/controllers/utils/metadata.d.ts +16 -1
  137. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  138. package/dist/server/src/history/controllers/history-version.d.ts +1 -1
  139. package/dist/server/src/history/controllers/history-version.d.ts.map +1 -1
  140. package/dist/server/src/history/services/history.d.ts +3 -3
  141. package/dist/server/src/history/services/history.d.ts.map +1 -1
  142. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  143. package/dist/server/src/history/services/utils.d.ts +6 -11
  144. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  145. package/dist/server/src/index.d.ts +7 -6
  146. package/dist/server/src/index.d.ts.map +1 -1
  147. package/dist/server/src/preview/controllers/index.d.ts +2 -0
  148. package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
  149. package/dist/server/src/preview/controllers/preview.d.ts +13 -0
  150. package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
  151. package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
  152. package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
  153. package/dist/server/src/preview/index.d.ts +4 -0
  154. package/dist/server/src/preview/index.d.ts.map +1 -0
  155. package/dist/server/src/preview/routes/index.d.ts +8 -0
  156. package/dist/server/src/preview/routes/index.d.ts.map +1 -0
  157. package/dist/server/src/preview/routes/preview.d.ts +4 -0
  158. package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
  159. package/dist/server/src/preview/services/index.d.ts +16 -0
  160. package/dist/server/src/preview/services/index.d.ts.map +1 -0
  161. package/dist/server/src/preview/services/preview-config.d.ts +32 -0
  162. package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
  163. package/dist/server/src/preview/services/preview.d.ts +12 -0
  164. package/dist/server/src/preview/services/preview.d.ts.map +1 -0
  165. package/dist/server/src/preview/utils.d.ts +19 -0
  166. package/dist/server/src/preview/utils.d.ts.map +1 -0
  167. package/dist/server/src/register.d.ts.map +1 -1
  168. package/dist/server/src/routes/index.d.ts.map +1 -1
  169. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  170. package/dist/server/src/services/document-metadata.d.ts +12 -10
  171. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  172. package/dist/server/src/services/index.d.ts +7 -6
  173. package/dist/server/src/services/index.d.ts.map +1 -1
  174. package/dist/server/src/services/utils/populate.d.ts +2 -2
  175. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  176. package/dist/server/src/utils/index.d.ts +2 -0
  177. package/dist/server/src/utils/index.d.ts.map +1 -1
  178. package/dist/shared/contracts/index.d.ts +1 -0
  179. package/dist/shared/contracts/index.d.ts.map +1 -1
  180. package/dist/shared/contracts/preview.d.ts +27 -0
  181. package/dist/shared/contracts/preview.d.ts.map +1 -0
  182. package/dist/shared/index.js +4 -0
  183. package/dist/shared/index.js.map +1 -1
  184. package/dist/shared/index.mjs +4 -0
  185. package/dist/shared/index.mjs.map +1 -1
  186. package/package.json +13 -12
  187. package/dist/_chunks/EditViewPage-BbY0bNNE.js.map +0 -1
  188. package/dist/_chunks/EditViewPage-Dx0QnTxn.mjs.map +0 -1
  189. package/dist/_chunks/Field-CglKum3X.js.map +0 -1
  190. package/dist/_chunks/Field-DVZSGAon.mjs.map +0 -1
  191. package/dist/_chunks/History-3JN4BIS1.js.map +0 -1
  192. package/dist/_chunks/History-Bmu6tx6s.mjs.map +0 -1
  193. package/dist/_chunks/ListConfigurationPage-BcC28SV0.js.map +0 -1
  194. package/dist/_chunks/ListConfigurationPage-DwijcJ17.mjs.map +0 -1
  195. package/dist/_chunks/ListViewPage-DzhuS3CW.mjs.map +0 -1
  196. package/dist/_chunks/ListViewPage-ZPNQ6jWC.js.map +0 -1
  197. package/dist/_chunks/Relations-B7VtRA3g.mjs.map +0 -1
  198. package/dist/_chunks/Relations-BHXq_cKF.js.map +0 -1
  199. package/dist/_chunks/index-DcA8_tJw.js.map +0 -1
  200. package/dist/_chunks/index-TaRzG09p.mjs.map +0 -1
  201. package/dist/_chunks/relations-D3Hlx6QX.mjs.map +0 -1
  202. package/dist/_chunks/relations-Z6RA1sBS.js.map +0 -1
  203. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +0 -1
  204. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +0 -1
@@ -1,25 +1,34 @@
1
- import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check, CrossCircle, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
1
+ import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check, CheckCircle, ArrowsCounterClockwise, CrossCircle, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
2
2
  import { jsx, Fragment, jsxs } from "react/jsx-runtime";
3
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, RawTable, Loader, Tbody, Tr, Td, 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 { generateNKeysBetween } from "fractional-indexing";
11
14
  import pipe from "lodash/fp/pipe";
12
- import { intervalToDuration, isPast } from "date-fns";
13
- import { styled } from "styled-components";
14
15
  import { stringify } from "qs";
16
+ import { intervalToDuration, isPast } from "date-fns";
15
17
  import { createSlice, combineReducers } from "@reduxjs/toolkit";
16
- const __variableDynamicImportRuntimeHelper = (glob, path) => {
18
+ const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
17
19
  const v = glob[path];
18
20
  if (v) {
19
21
  return typeof v === "function" ? v() : Promise.resolve(v);
20
22
  }
21
23
  return new Promise((_, reject) => {
22
- (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(reject.bind(null, new Error("Unknown variable dynamic import: " + path)));
24
+ (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
25
+ reject.bind(
26
+ null,
27
+ new Error(
28
+ "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
29
+ )
30
+ )
31
+ );
23
32
  });
24
33
  };
25
34
  const PLUGIN_ID = "content-manager";
@@ -158,6 +167,113 @@ const extractAndDedupeFields = (permissions = []) => permissions.flatMap((permis
158
167
  (field, index2, arr) => arr.indexOf(field) === index2 && typeof field === "string"
159
168
  );
160
169
  const removeNumericalStrings = (arr) => arr.filter((item) => isNaN(Number(item)));
170
+ const BLOCK_LIST_ATTRIBUTE_KEYS = ["__component", "__temp_key__"];
171
+ const traverseData = (predicate, transform) => (schema, components = {}) => (data = {}) => {
172
+ const traverse = (datum, attributes) => {
173
+ return Object.entries(datum).reduce((acc, [key, value]) => {
174
+ const attribute = attributes[key];
175
+ if (BLOCK_LIST_ATTRIBUTE_KEYS.includes(key) || value === null || value === void 0) {
176
+ acc[key] = value;
177
+ return acc;
178
+ }
179
+ if (attribute.type === "component") {
180
+ if (attribute.repeatable) {
181
+ const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
182
+ acc[key] = componentValue.map(
183
+ (componentData) => traverse(componentData, components[attribute.component]?.attributes ?? {})
184
+ );
185
+ } else {
186
+ const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
187
+ acc[key] = traverse(componentValue, components[attribute.component]?.attributes ?? {});
188
+ }
189
+ } else if (attribute.type === "dynamiczone") {
190
+ const dynamicZoneValue = predicate(attribute, value) ? transform(value, attribute) : value;
191
+ acc[key] = dynamicZoneValue.map(
192
+ (componentData) => traverse(componentData, components[componentData.__component]?.attributes ?? {})
193
+ );
194
+ } else if (predicate(attribute, value)) {
195
+ acc[key] = transform(value, attribute);
196
+ } else {
197
+ acc[key] = value;
198
+ }
199
+ return acc;
200
+ }, {});
201
+ };
202
+ return traverse(data, schema.attributes);
203
+ };
204
+ const removeProhibitedFields = (prohibitedFields) => traverseData(
205
+ (attribute) => prohibitedFields.includes(attribute.type),
206
+ () => ""
207
+ );
208
+ const prepareRelations = traverseData(
209
+ (attribute) => attribute.type === "relation",
210
+ () => ({
211
+ connect: [],
212
+ disconnect: []
213
+ })
214
+ );
215
+ const prepareTempKeys = traverseData(
216
+ (attribute) => attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone",
217
+ (data) => {
218
+ if (Array.isArray(data) && data.length > 0) {
219
+ const keys = generateNKeysBetween(void 0, void 0, data.length);
220
+ return data.map((datum, index2) => ({
221
+ ...datum,
222
+ __temp_key__: keys[index2]
223
+ }));
224
+ }
225
+ return data;
226
+ }
227
+ );
228
+ const removeFieldsThatDontExistOnSchema = (schema) => (data) => {
229
+ const schemaKeys = Object.keys(schema.attributes);
230
+ const dataKeys = Object.keys(data);
231
+ const keysToRemove = dataKeys.filter((key) => !schemaKeys.includes(key));
232
+ const revisedData = [...keysToRemove, ...DOCUMENT_META_FIELDS].reduce((acc, key) => {
233
+ delete acc[key];
234
+ return acc;
235
+ }, structuredClone(data));
236
+ return revisedData;
237
+ };
238
+ const removeNullValues = (data) => {
239
+ return Object.entries(data).reduce((acc, [key, value]) => {
240
+ if (value === null) {
241
+ return acc;
242
+ }
243
+ acc[key] = value;
244
+ return acc;
245
+ }, {});
246
+ };
247
+ const transformDocument = (schema, components = {}) => (document) => {
248
+ const transformations = pipe(
249
+ removeFieldsThatDontExistOnSchema(schema),
250
+ removeProhibitedFields(["password"])(schema, components),
251
+ removeNullValues,
252
+ prepareRelations(schema, components),
253
+ prepareTempKeys(schema, components)
254
+ );
255
+ return transformations(document);
256
+ };
257
+ const createDefaultForm = (contentType, components = {}) => {
258
+ const traverseSchema = (attributes) => {
259
+ return Object.entries(attributes).reduce((acc, [key, attribute]) => {
260
+ if ("default" in attribute) {
261
+ acc[key] = attribute.default;
262
+ } else if (attribute.type === "component" && attribute.required) {
263
+ const defaultComponentForm = traverseSchema(components[attribute.component].attributes);
264
+ if (attribute.repeatable) {
265
+ acc[key] = attribute.min ? [...Array(attribute.min).fill(defaultComponentForm)] : [];
266
+ } else {
267
+ acc[key] = defaultComponentForm;
268
+ }
269
+ } else if (attribute.type === "dynamiczone" && attribute.required) {
270
+ acc[key] = [];
271
+ }
272
+ return acc;
273
+ }, {});
274
+ };
275
+ return traverseSchema(contentType.attributes);
276
+ };
161
277
  const contentManagerApi = adminApi.enhanceEndpoints({
162
278
  addTagTypes: [
163
279
  "ComponentConfiguration",
@@ -167,7 +283,8 @@ const contentManagerApi = adminApi.enhanceEndpoints({
167
283
  "InitialData",
168
284
  "HistoryVersion",
169
285
  "Relations",
170
- "UidAvailability"
286
+ "UidAvailability",
287
+ "RecentDocumentList"
171
288
  ]
172
289
  });
173
290
  const documentApi = contentManagerApi.injectEndpoints({
@@ -185,7 +302,7 @@ const documentApi = contentManagerApi.injectEndpoints({
185
302
  if (error) {
186
303
  return [];
187
304
  }
188
- return [{ type: "Document", id: `${model}_LIST` }];
305
+ return [{ type: "Document", id: `${model}_LIST` }, "RecentDocumentList"];
189
306
  }
190
307
  }),
191
308
  cloneDocument: builder.mutation({
@@ -199,7 +316,8 @@ const documentApi = contentManagerApi.injectEndpoints({
199
316
  }),
200
317
  invalidatesTags: (_result, _error, { model }) => [
201
318
  { type: "Document", id: `${model}_LIST` },
202
- { type: "UidAvailability", id: model }
319
+ { type: "UidAvailability", id: model },
320
+ "RecentDocumentList"
203
321
  ]
204
322
  }),
205
323
  /**
@@ -218,8 +336,21 @@ const documentApi = contentManagerApi.injectEndpoints({
218
336
  invalidatesTags: (result, _error, { model }) => [
219
337
  { type: "Document", id: `${model}_LIST` },
220
338
  "Relations",
221
- { type: "UidAvailability", id: model }
222
- ]
339
+ { type: "UidAvailability", id: model },
340
+ "RecentDocumentList"
341
+ ],
342
+ transformResponse: (response, meta, arg) => {
343
+ if (!("data" in response) && arg.model === "plugin::users-permissions.user") {
344
+ return {
345
+ data: response,
346
+ meta: {
347
+ availableStatus: [],
348
+ availableLocales: []
349
+ }
350
+ };
351
+ }
352
+ return response;
353
+ }
223
354
  }),
224
355
  deleteDocument: builder.mutation({
225
356
  query: ({ collectionType, model, documentId, params }) => ({
@@ -230,7 +361,8 @@ const documentApi = contentManagerApi.injectEndpoints({
230
361
  }
231
362
  }),
232
363
  invalidatesTags: (_result, _error, { collectionType, model }) => [
233
- { type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model }
364
+ { type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model },
365
+ "RecentDocumentList"
234
366
  ]
235
367
  }),
236
368
  deleteManyDocuments: builder.mutation({
@@ -242,7 +374,10 @@ const documentApi = contentManagerApi.injectEndpoints({
242
374
  params
243
375
  }
244
376
  }),
245
- invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
377
+ invalidatesTags: (_res, _error, { model }) => [
378
+ { type: "Document", id: `${model}_LIST` },
379
+ "RecentDocumentList"
380
+ ]
246
381
  }),
247
382
  discardDocument: builder.mutation({
248
383
  query: ({ collectionType, model, documentId, params }) => ({
@@ -260,7 +395,8 @@ const documentApi = contentManagerApi.injectEndpoints({
260
395
  },
261
396
  { type: "Document", id: `${model}_LIST` },
262
397
  "Relations",
263
- { type: "UidAvailability", id: model }
398
+ { type: "UidAvailability", id: model },
399
+ "RecentDocumentList"
264
400
  ];
265
401
  }
266
402
  }),
@@ -273,7 +409,7 @@ const documentApi = contentManagerApi.injectEndpoints({
273
409
  url: `/content-manager/collection-types/${model}`,
274
410
  method: "GET",
275
411
  config: {
276
- params
412
+ params: stringify(params, { encode: true })
277
413
  }
278
414
  }),
279
415
  providesTags: (result, _error, arg) => {
@@ -355,7 +491,8 @@ const documentApi = contentManagerApi.injectEndpoints({
355
491
  id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
356
492
  },
357
493
  { type: "Document", id: `${model}_LIST` },
358
- "Relations"
494
+ "Relations",
495
+ "RecentDocumentList"
359
496
  ];
360
497
  }
361
498
  }),
@@ -386,7 +523,9 @@ const documentApi = contentManagerApi.injectEndpoints({
386
523
  id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
387
524
  },
388
525
  "Relations",
389
- { type: "UidAvailability", id: model }
526
+ { type: "UidAvailability", id: model },
527
+ "RecentDocumentList",
528
+ "RecentDocumentList"
390
529
  ];
391
530
  },
392
531
  async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
@@ -416,7 +555,8 @@ const documentApi = contentManagerApi.injectEndpoints({
416
555
  {
417
556
  type: "Document",
418
557
  id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
419
- }
558
+ },
559
+ "RecentDocumentList"
420
560
  ];
421
561
  }
422
562
  }),
@@ -429,7 +569,10 @@ const documentApi = contentManagerApi.injectEndpoints({
429
569
  params
430
570
  }
431
571
  }),
432
- invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
572
+ invalidatesTags: (_res, _error, { model, documentIds }) => [
573
+ ...documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` })),
574
+ "RecentDocumentList"
575
+ ]
433
576
  })
434
577
  })
435
578
  });
@@ -452,8 +595,7 @@ const {
452
595
  useUnpublishManyDocumentsMutation
453
596
  } = documentApi;
454
597
  const buildValidParams = (query) => {
455
- if (!query)
456
- return query;
598
+ if (!query) return query;
457
599
  const { plugins: _, ...validQueryParams } = {
458
600
  ...query,
459
601
  ...Object.values(query?.plugins ?? {}).reduce(
@@ -461,9 +603,6 @@ const buildValidParams = (query) => {
461
603
  {}
462
604
  )
463
605
  };
464
- if ("_q" in validQueryParams) {
465
- validQueryParams._q = encodeURIComponent(validQueryParams._q);
466
- }
467
606
  return validQueryParams;
468
607
  };
469
608
  const isBaseQueryError = (error) => {
@@ -968,9 +1107,10 @@ const formatEditLayout = (data, {
968
1107
  currentPanelIndex += 2;
969
1108
  } else {
970
1109
  if (!panels[currentPanelIndex]) {
971
- panels.push([]);
1110
+ panels.push([row]);
1111
+ } else {
1112
+ panels[currentPanelIndex].push(row);
972
1113
  }
973
- panels[currentPanelIndex].push(row);
974
1114
  }
975
1115
  return panels;
976
1116
  }, []);
@@ -1103,6 +1243,7 @@ const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, co
1103
1243
  const useDocument = (args, opts) => {
1104
1244
  const { toggleNotification } = useNotification();
1105
1245
  const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
1246
+ const { formatMessage } = useIntl();
1106
1247
  const {
1107
1248
  currentData: data,
1108
1249
  isLoading: isLoadingDocument,
@@ -1112,12 +1253,27 @@ const useDocument = (args, opts) => {
1112
1253
  ...opts,
1113
1254
  skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
1114
1255
  });
1256
+ const document = data?.data;
1257
+ const meta = data?.meta;
1115
1258
  const {
1116
1259
  components,
1117
1260
  schema,
1118
1261
  schemas,
1119
1262
  isLoading: isLoadingSchema
1120
1263
  } = useContentTypeSchema(args.model);
1264
+ const isSingleType = schema?.kind === "singleType";
1265
+ const getTitle = (mainField) => {
1266
+ if (mainField !== "id" && document?.[mainField]) {
1267
+ return document[mainField];
1268
+ }
1269
+ if (isSingleType && schema?.info.displayName) {
1270
+ return schema.info.displayName;
1271
+ }
1272
+ return formatMessage({
1273
+ id: "content-manager.containers.untitled",
1274
+ defaultMessage: "Untitled"
1275
+ });
1276
+ };
1121
1277
  React.useEffect(() => {
1122
1278
  if (error) {
1123
1279
  toggleNotification({
@@ -1133,14 +1289,14 @@ const useDocument = (args, opts) => {
1133
1289
  return createYupSchema(schema.attributes, components);
1134
1290
  }, [schema, components]);
1135
1291
  const validate = React.useCallback(
1136
- (document) => {
1292
+ (document2) => {
1137
1293
  if (!validationSchema) {
1138
1294
  throw new Error(
1139
1295
  "There is no validation schema generated, this is likely due to the schema not being loaded yet."
1140
1296
  );
1141
1297
  }
1142
1298
  try {
1143
- validationSchema.validateSync(document, { abortEarly: false, strict: true });
1299
+ validationSchema.validateSync(document2, { abortEarly: false, strict: true });
1144
1300
  return null;
1145
1301
  } catch (error2) {
1146
1302
  if (error2 instanceof ValidationError) {
@@ -1151,17 +1307,29 @@ const useDocument = (args, opts) => {
1151
1307
  },
1152
1308
  [validationSchema]
1153
1309
  );
1310
+ const getInitialFormValues = React.useCallback(
1311
+ (isCreatingDocument = false) => {
1312
+ if (!document && !isCreatingDocument && !isSingleType || !schema) {
1313
+ return void 0;
1314
+ }
1315
+ const form = document?.id ? document : createDefaultForm(schema, components);
1316
+ return transformDocument(schema, components)(form);
1317
+ },
1318
+ [document, isSingleType, schema, components]
1319
+ );
1154
1320
  const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
1155
1321
  const hasError = !!error;
1156
1322
  return {
1157
1323
  components,
1158
- document: data?.data,
1159
- meta: data?.meta,
1324
+ document,
1325
+ meta,
1160
1326
  isLoading,
1161
1327
  hasError,
1162
1328
  schema,
1163
1329
  schemas,
1164
- validate
1330
+ validate,
1331
+ getTitle,
1332
+ getInitialFormValues
1165
1333
  };
1166
1334
  };
1167
1335
  const useDoc = () => {
@@ -1228,9 +1396,6 @@ const useContentManagerContext = () => {
1228
1396
  };
1229
1397
  };
1230
1398
  const prefixPluginTranslations = (trad, pluginId) => {
1231
- if (!pluginId) {
1232
- throw new TypeError("pluginId can't be empty");
1233
- }
1234
1399
  return Object.keys(trad).reduce((acc, current) => {
1235
1400
  acc[`${pluginId}.${current}`] = trad[current];
1236
1401
  return acc;
@@ -1664,10 +1829,10 @@ const useDocumentActions = () => {
1664
1829
  update
1665
1830
  };
1666
1831
  };
1667
- const ProtectedHistoryPage = lazy(
1668
- () => import("./History-Bmu6tx6s.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1832
+ const ProtectedHistoryPage = React.lazy(
1833
+ () => import("./History-D1PreDSY.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1669
1834
  );
1670
- const routes$1 = [
1835
+ const routes$2 = [
1671
1836
  {
1672
1837
  path: ":collectionType/:slug/:id/history",
1673
1838
  Component: ProtectedHistoryPage
@@ -1677,32 +1842,45 @@ const routes$1 = [
1677
1842
  Component: ProtectedHistoryPage
1678
1843
  }
1679
1844
  ];
1845
+ const ProtectedPreviewPage = React.lazy(
1846
+ () => import("./Preview-BNuU0SuQ.mjs").then((mod) => ({ default: mod.ProtectedPreviewPage }))
1847
+ );
1848
+ const routes$1 = [
1849
+ {
1850
+ path: ":collectionType/:slug/:id/preview",
1851
+ Component: ProtectedPreviewPage
1852
+ },
1853
+ {
1854
+ path: ":collectionType/:slug/preview",
1855
+ Component: ProtectedPreviewPage
1856
+ }
1857
+ ];
1680
1858
  const ProtectedEditViewPage = lazy(
1681
- () => import("./EditViewPage-Dx0QnTxn.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1859
+ () => import("./EditViewPage-DrmVmYN0.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1682
1860
  );
1683
1861
  const ProtectedListViewPage = lazy(
1684
- () => import("./ListViewPage-DzhuS3CW.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1862
+ () => import("./ListViewPage-Bud_jBDQ.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1685
1863
  );
1686
1864
  const ProtectedListConfiguration = lazy(
1687
- () => import("./ListConfigurationPage-DwijcJ17.mjs").then((mod) => ({
1865
+ () => import("./ListConfigurationPage-Bbi32isk.mjs").then((mod) => ({
1688
1866
  default: mod.ProtectedListConfiguration
1689
1867
  }))
1690
1868
  );
1691
1869
  const ProtectedEditConfigurationPage = lazy(
1692
- () => import("./EditConfigurationPage-BWq-9Zhk.mjs").then((mod) => ({
1870
+ () => import("./EditConfigurationPage-COe6hjPC.mjs").then((mod) => ({
1693
1871
  default: mod.ProtectedEditConfigurationPage
1694
1872
  }))
1695
1873
  );
1696
1874
  const ProtectedComponentConfigurationPage = lazy(
1697
- () => import("./ComponentConfigurationPage-BVM7LScS.mjs").then((mod) => ({
1875
+ () => import("./ComponentConfigurationPage-9_4yUE9L.mjs").then((mod) => ({
1698
1876
  default: mod.ProtectedComponentConfigurationPage
1699
1877
  }))
1700
1878
  );
1701
1879
  const NoPermissions = lazy(
1702
- () => import("./NoPermissionsPage-DBbGJqL9.mjs").then((mod) => ({ default: mod.NoPermissions }))
1880
+ () => import("./NoPermissionsPage-CMdM-dCo.mjs").then((mod) => ({ default: mod.NoPermissions }))
1703
1881
  );
1704
1882
  const NoContentType = lazy(
1705
- () => import("./NoContentTypePage-BKMgOyd3.mjs").then((mod) => ({ default: mod.NoContentType }))
1883
+ () => import("./NoContentTypePage-DVhkugsf.mjs").then((mod) => ({ default: mod.NoContentType }))
1706
1884
  );
1707
1885
  const CollectionTypePages = () => {
1708
1886
  const { collectionType } = useParams();
@@ -1714,7 +1892,7 @@ const CollectionTypePages = () => {
1714
1892
  const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
1715
1893
  const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
1716
1894
  const LIST_RELATIVE_PATH = ":collectionType/:slug";
1717
- const LIST_PATH = `/content-manager/${LIST_RELATIVE_PATH}`;
1895
+ const LIST_PATH = `/content-manager/collection-types/:slug`;
1718
1896
  const routes = [
1719
1897
  {
1720
1898
  path: LIST_RELATIVE_PATH,
@@ -1748,6 +1926,7 @@ const routes = [
1748
1926
  path: "no-content-types",
1749
1927
  Component: NoContentType
1750
1928
  },
1929
+ ...routes$2,
1751
1930
  ...routes$1
1752
1931
  ];
1753
1932
  const DocumentActions = ({ actions: actions2 }) => {
@@ -1846,6 +2025,11 @@ const DocumentActionButton = (action) => {
1846
2025
  ) : null
1847
2026
  ] });
1848
2027
  };
2028
+ const MenuItem = styled(Menu.Item)`
2029
+ &:hover {
2030
+ background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
2031
+ }
2032
+ `;
1849
2033
  const DocumentActionsMenu = ({
1850
2034
  actions: actions2,
1851
2035
  children,
@@ -1904,48 +2088,32 @@ const DocumentActionsMenu = ({
1904
2088
  /* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
1905
2089
  actions2.map((action) => {
1906
2090
  return /* @__PURE__ */ jsx(
1907
- Menu.Item,
2091
+ MenuItem,
1908
2092
  {
1909
2093
  disabled: action.disabled,
1910
2094
  onSelect: handleClick(action),
1911
2095
  display: "block",
1912
- children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
1913
- /* @__PURE__ */ jsxs(
1914
- Flex,
1915
- {
1916
- color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
1917
- gap: 2,
1918
- tag: "span",
1919
- children: [
1920
- /* @__PURE__ */ jsx(
1921
- Flex,
1922
- {
1923
- tag: "span",
1924
- color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
1925
- children: action.icon
1926
- }
1927
- ),
1928
- action.label
1929
- ]
1930
- }
1931
- ),
1932
- action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
1933
- Flex,
1934
- {
1935
- alignItems: "center",
1936
- background: "alternative100",
1937
- borderStyle: "solid",
1938
- borderColor: "alternative200",
1939
- borderWidth: "1px",
1940
- height: 5,
1941
- paddingLeft: 2,
1942
- paddingRight: 2,
1943
- hasRadius: true,
1944
- color: "alternative600",
1945
- children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", fontWeight: "bold", lineHeight: 1, children: formatMessage({ id: "global.new", defaultMessage: "New" }) })
1946
- }
1947
- )
1948
- ] })
2096
+ isVariantDanger: action.variant === "danger",
2097
+ isDisabled: action.disabled,
2098
+ children: /* @__PURE__ */ jsx(Flex, { justifyContent: "space-between", gap: 4, children: /* @__PURE__ */ jsxs(
2099
+ Flex,
2100
+ {
2101
+ color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
2102
+ gap: 2,
2103
+ tag: "span",
2104
+ children: [
2105
+ /* @__PURE__ */ jsx(
2106
+ Flex,
2107
+ {
2108
+ tag: "span",
2109
+ color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
2110
+ children: action.icon
2111
+ }
2112
+ ),
2113
+ action.label
2114
+ ]
2115
+ }
2116
+ ) })
1949
2117
  },
1950
2118
  action.id
1951
2119
  );
@@ -2056,6 +2224,18 @@ const DocumentActionModal = ({
2056
2224
  typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
2057
2225
  ] }) });
2058
2226
  };
2227
+ const transformData = (data) => {
2228
+ if (Array.isArray(data)) {
2229
+ return data.map(transformData);
2230
+ }
2231
+ if (typeof data === "object" && data !== null) {
2232
+ if ("apiData" in data) {
2233
+ return data.apiData;
2234
+ }
2235
+ return mapValues(transformData)(data);
2236
+ }
2237
+ return data;
2238
+ };
2059
2239
  const PublishAction$1 = ({
2060
2240
  activeTab,
2061
2241
  documentId,
@@ -2070,6 +2250,7 @@ const PublishAction$1 = ({
2070
2250
  const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
2071
2251
  const isListView = useMatch(LIST_PATH) !== null;
2072
2252
  const isCloning = useMatch(CLONE_PATH) !== null;
2253
+ const { id } = useParams();
2073
2254
  const { formatMessage } = useIntl();
2074
2255
  const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
2075
2256
  const { publish } = useDocumentActions();
@@ -2169,13 +2350,15 @@ const PublishAction$1 = ({
2169
2350
  documentId,
2170
2351
  params
2171
2352
  },
2172
- formDocumentToData(formValues)
2353
+ transformData(formValues)
2173
2354
  );
2174
2355
  if ("data" in res && collectionType !== SINGLE_TYPES) {
2175
- navigate({
2176
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
2177
- search: rawQuery
2178
- });
2356
+ if (id === "create") {
2357
+ navigate({
2358
+ pathname: `../${collectionType}/${model}/${res.data.documentId}`,
2359
+ search: rawQuery
2360
+ });
2361
+ }
2179
2362
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2180
2363
  setErrors(formatValidationErrors(res.error));
2181
2364
  }
@@ -2228,36 +2411,7 @@ const PublishAction$1 = ({
2228
2411
  };
2229
2412
  };
2230
2413
  PublishAction$1.type = "publish";
2231
- const formDocumentToData = (document) => {
2232
- return Object.keys(document).reduce((acc, key) => {
2233
- if (document[key] !== void 0) {
2234
- acc[key] = document[key];
2235
- }
2236
- if (typeof document[key] === "object" && document[key] !== null) {
2237
- if ("connect" in document[key] && document[key].connect !== null) {
2238
- acc[key] = {
2239
- ...acc[key],
2240
- connect: document[key].connect.map((item) => {
2241
- return {
2242
- documentId: item.documentId
2243
- };
2244
- })
2245
- };
2246
- }
2247
- if ("disconnect" in document[key] && document[key].disconnect !== null) {
2248
- acc[key] = {
2249
- ...acc[key],
2250
- disconnect: document[key].disconnect.map((item) => {
2251
- return {
2252
- documentId: item.documentId
2253
- };
2254
- })
2255
- };
2256
- }
2257
- }
2258
- return acc;
2259
- }, {});
2260
- };
2414
+ PublishAction$1.position = "panel";
2261
2415
  const UpdateAction = ({
2262
2416
  activeTab,
2263
2417
  documentId,
@@ -2280,96 +2434,134 @@ const UpdateAction = ({
2280
2434
  const validate = useForm("UpdateAction", (state) => state.validate);
2281
2435
  const setErrors = useForm("UpdateAction", (state) => state.setErrors);
2282
2436
  const resetForm = useForm("PublishAction", ({ resetForm: resetForm2 }) => resetForm2);
2283
- return {
2284
- /**
2285
- * Disabled when:
2286
- * - the form is submitting
2287
- * - the document is not modified & we're not cloning (you can save a clone entity straight away)
2288
- * - the active tab is the published tab
2289
- */
2290
- disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
2291
- label: formatMessage({
2292
- id: "content-manager.containers.Edit.save",
2293
- defaultMessage: "Save"
2294
- }),
2295
- onClick: async () => {
2296
- setSubmitting(true);
2297
- try {
2298
- const { errors } = await validate(true, {
2299
- status: "draft"
2437
+ const handleUpdate = React.useCallback(async () => {
2438
+ setSubmitting(true);
2439
+ try {
2440
+ if (!modified) {
2441
+ return;
2442
+ }
2443
+ const { errors } = await validate(true, {
2444
+ status: "draft"
2445
+ });
2446
+ if (errors) {
2447
+ toggleNotification({
2448
+ type: "danger",
2449
+ message: formatMessage({
2450
+ id: "content-manager.validation.error",
2451
+ defaultMessage: "There are validation errors in your document. Please fix them before saving."
2452
+ })
2300
2453
  });
2301
- if (errors) {
2302
- toggleNotification({
2303
- type: "danger",
2304
- message: formatMessage({
2305
- id: "content-manager.validation.error",
2306
- defaultMessage: "There are validation errors in your document. Please fix them before saving."
2307
- })
2308
- });
2309
- return;
2310
- }
2311
- if (isCloning) {
2312
- const res = await clone(
2313
- {
2314
- model,
2315
- documentId: cloneMatch.params.origin,
2316
- params
2317
- },
2318
- formDocumentToData(document)
2319
- );
2320
- if ("data" in res) {
2321
- navigate(
2322
- {
2323
- pathname: `../${res.data.documentId}`,
2324
- search: rawQuery
2325
- },
2326
- { relative: "path" }
2327
- );
2328
- } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2329
- setErrors(formatValidationErrors(res.error));
2330
- }
2331
- } else if (documentId || collectionType === SINGLE_TYPES) {
2332
- const res = await update(
2454
+ return;
2455
+ }
2456
+ if (isCloning) {
2457
+ const res = await clone(
2458
+ {
2459
+ model,
2460
+ documentId: cloneMatch.params.origin,
2461
+ params
2462
+ },
2463
+ transformData(document)
2464
+ );
2465
+ if ("data" in res) {
2466
+ navigate(
2333
2467
  {
2334
- collectionType,
2335
- model,
2336
- documentId,
2337
- params
2468
+ pathname: `../${res.data.documentId}`,
2469
+ search: rawQuery
2338
2470
  },
2339
- formDocumentToData(document)
2471
+ { relative: "path" }
2340
2472
  );
2341
- if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2342
- setErrors(formatValidationErrors(res.error));
2343
- } else {
2344
- resetForm();
2345
- }
2473
+ } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2474
+ setErrors(formatValidationErrors(res.error));
2475
+ }
2476
+ } else if (documentId || collectionType === SINGLE_TYPES) {
2477
+ const res = await update(
2478
+ {
2479
+ collectionType,
2480
+ model,
2481
+ documentId,
2482
+ params
2483
+ },
2484
+ transformData(document)
2485
+ );
2486
+ if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2487
+ setErrors(formatValidationErrors(res.error));
2346
2488
  } else {
2347
- const res = await create(
2489
+ resetForm();
2490
+ }
2491
+ } else {
2492
+ const res = await create(
2493
+ {
2494
+ model,
2495
+ params
2496
+ },
2497
+ transformData(document)
2498
+ );
2499
+ if ("data" in res && collectionType !== SINGLE_TYPES) {
2500
+ navigate(
2348
2501
  {
2349
- model,
2350
- params
2502
+ pathname: `../${res.data.documentId}`,
2503
+ search: rawQuery
2351
2504
  },
2352
- formDocumentToData(document)
2505
+ { replace: true, relative: "path" }
2353
2506
  );
2354
- if ("data" in res && collectionType !== SINGLE_TYPES) {
2355
- navigate(
2356
- {
2357
- pathname: `../${res.data.documentId}`,
2358
- search: rawQuery
2359
- },
2360
- { replace: true, relative: "path" }
2361
- );
2362
- } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2363
- setErrors(formatValidationErrors(res.error));
2364
- }
2507
+ } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2508
+ setErrors(formatValidationErrors(res.error));
2365
2509
  }
2366
- } finally {
2367
- setSubmitting(false);
2368
2510
  }
2511
+ } finally {
2512
+ setSubmitting(false);
2369
2513
  }
2514
+ }, [
2515
+ clone,
2516
+ cloneMatch?.params.origin,
2517
+ collectionType,
2518
+ create,
2519
+ document,
2520
+ documentId,
2521
+ formatMessage,
2522
+ formatValidationErrors,
2523
+ isCloning,
2524
+ model,
2525
+ modified,
2526
+ navigate,
2527
+ params,
2528
+ rawQuery,
2529
+ resetForm,
2530
+ setErrors,
2531
+ setSubmitting,
2532
+ toggleNotification,
2533
+ update,
2534
+ validate
2535
+ ]);
2536
+ React.useEffect(() => {
2537
+ const handleKeyDown = (e) => {
2538
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
2539
+ e.preventDefault();
2540
+ handleUpdate();
2541
+ }
2542
+ };
2543
+ window.addEventListener("keydown", handleKeyDown);
2544
+ return () => {
2545
+ window.removeEventListener("keydown", handleKeyDown);
2546
+ };
2547
+ }, [handleUpdate]);
2548
+ return {
2549
+ /**
2550
+ * Disabled when:
2551
+ * - the form is submitting
2552
+ * - the document is not modified & we're not cloning (you can save a clone entity straight away)
2553
+ * - the active tab is the published tab
2554
+ */
2555
+ disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
2556
+ label: formatMessage({
2557
+ id: "global.save",
2558
+ defaultMessage: "Save"
2559
+ }),
2560
+ onClick: handleUpdate
2370
2561
  };
2371
2562
  };
2372
2563
  UpdateAction.type = "update";
2564
+ UpdateAction.position = "panel";
2373
2565
  const UNPUBLISH_DRAFT_OPTIONS = {
2374
2566
  KEEP: "keep",
2375
2567
  DISCARD: "discard"
@@ -2492,6 +2684,7 @@ const UnpublishAction$1 = ({
2492
2684
  };
2493
2685
  };
2494
2686
  UnpublishAction$1.type = "unpublish";
2687
+ UnpublishAction$1.position = "panel";
2495
2688
  const DiscardAction = ({
2496
2689
  activeTab,
2497
2690
  documentId,
@@ -2542,6 +2735,7 @@ const DiscardAction = ({
2542
2735
  };
2543
2736
  };
2544
2737
  DiscardAction.type = "discard";
2738
+ DiscardAction.position = "panel";
2545
2739
  const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
2546
2740
  const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
2547
2741
  const RelativeTime = React.forwardRef(
@@ -2554,7 +2748,7 @@ const RelativeTime = React.forwardRef(
2554
2748
  });
2555
2749
  const unit = intervals.find((intervalUnit) => {
2556
2750
  return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
2557
- });
2751
+ }) ?? "seconds";
2558
2752
  const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
2559
2753
  const customInterval = customIntervals.find(
2560
2754
  (custom) => interval[custom.unit] < custom.threshold
@@ -2588,19 +2782,29 @@ const getDisplayName = ({
2588
2782
  return email ?? "";
2589
2783
  };
2590
2784
  const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2591
- const DocumentStatus = ({ status = "draft", ...restProps }) => {
2785
+ const DocumentStatus = ({ status = "draft", size = "S", ...restProps }) => {
2592
2786
  const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
2593
- return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
2787
+ const { formatMessage } = useIntl();
2788
+ return /* @__PURE__ */ jsx(Status, { ...restProps, size, variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: formatMessage({
2789
+ id: `content-manager.containers.List.${status}`,
2790
+ defaultMessage: capitalise(status)
2791
+ }) }) });
2594
2792
  };
2595
2793
  const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2596
2794
  const { formatMessage } = useIntl();
2597
2795
  const isCloning = useMatch(CLONE_PATH) !== null;
2796
+ const params = useParams();
2598
2797
  const title = isCreating ? formatMessage({
2599
2798
  id: "content-manager.containers.edit.title.new",
2600
2799
  defaultMessage: "Create an entry"
2601
2800
  }) : documentTitle;
2602
2801
  return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
2603
- /* @__PURE__ */ jsx(BackButton, {}),
2802
+ /* @__PURE__ */ jsx(
2803
+ BackButton,
2804
+ {
2805
+ fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
2806
+ }
2807
+ ),
2604
2808
  /* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
2605
2809
  /* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
2606
2810
  /* @__PURE__ */ jsx(HeaderToolbar, {})
@@ -2651,7 +2855,7 @@ const HeaderToolbar = () => {
2651
2855
  meta: isCloning ? void 0 : meta,
2652
2856
  collectionType
2653
2857
  },
2654
- descriptions: plugins["content-manager"].apis.getDocumentActions(),
2858
+ descriptions: plugins["content-manager"].apis.getDocumentActions("header"),
2655
2859
  children: (actions2) => {
2656
2860
  const headerActions = actions2.filter((action) => {
2657
2861
  const positions = Array.isArray(action.position) ? action.position : [action.position];
@@ -2859,6 +3063,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
2859
3063
  };
2860
3064
  };
2861
3065
  ConfigureTheViewAction.type = "configure-the-view";
3066
+ ConfigureTheViewAction.position = "header";
2862
3067
  const EditTheModelAction = ({ model }) => {
2863
3068
  const navigate = useNavigate();
2864
3069
  const { formatMessage } = useIntl();
@@ -2875,6 +3080,7 @@ const EditTheModelAction = ({ model }) => {
2875
3080
  };
2876
3081
  };
2877
3082
  EditTheModelAction.type = "edit-the-model";
3083
+ EditTheModelAction.position = "header";
2878
3084
  const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
2879
3085
  const navigate = useNavigate();
2880
3086
  const { formatMessage } = useIntl();
@@ -2948,6 +3154,7 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
2948
3154
  };
2949
3155
  };
2950
3156
  DeleteAction$1.type = "delete";
3157
+ DeleteAction$1.position = ["header", "table-row"];
2951
3158
  const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
2952
3159
  const Panels = () => {
2953
3160
  const isCloning = useMatch(CLONE_PATH) !== null;
@@ -3010,7 +3217,7 @@ const ActionsPanelContent = () => {
3010
3217
  DescriptionComponentRenderer,
3011
3218
  {
3012
3219
  props,
3013
- descriptions: plugins["content-manager"].apis.getDocumentActions(),
3220
+ descriptions: plugins["content-manager"].apis.getDocumentActions("panel"),
3014
3221
  children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
3015
3222
  }
3016
3223
  ),
@@ -3037,7 +3244,7 @@ const Panel = React.forwardRef(({ children, title }, ref) => {
3037
3244
  justifyContent: "stretch",
3038
3245
  alignItems: "flex-start",
3039
3246
  children: [
3040
- /* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
3247
+ /* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", textColor: "neutral600", children: title }),
3041
3248
  children
3042
3249
  ]
3043
3250
  }
@@ -3068,7 +3275,7 @@ const ConfirmBulkActionDialog = ({
3068
3275
  ] })
3069
3276
  ] }) });
3070
3277
  };
3071
- const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
3278
+ const BoldChunk = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
3072
3279
  const ConfirmDialogPublishAll = ({
3073
3280
  isOpen,
3074
3281
  onToggleDialog,
@@ -3117,7 +3324,7 @@ const ConfirmDialogPublishAll = ({
3117
3324
  defaultMessage: "<b>{count} {count, plural, one { relation } other { relations } } out of {entities} { entities, plural, one { entry } other { entries } } {count, plural, one { is } other { are } }</b> not published yet and might lead to unexpected behavior. "
3118
3325
  },
3119
3326
  {
3120
- b: BoldChunk$1,
3327
+ b: BoldChunk,
3121
3328
  count: countDraftRelations,
3122
3329
  entities: selectedEntries.length
3123
3330
  }
@@ -3156,6 +3363,16 @@ const ConfirmDialogPublishAll = ({
3156
3363
  const TypographyMaxWidth = styled(Typography)`
3157
3364
  max-width: 300px;
3158
3365
  `;
3366
+ const TableComponent = styled(RawTable)`
3367
+ width: 100%;
3368
+ table-layout: fixed;
3369
+ td:first-child {
3370
+ border-right: 1px solid ${({ theme }) => theme.colors.neutral150};
3371
+ }
3372
+ td:first-of-type {
3373
+ padding: ${({ theme }) => theme.spaces[4]};
3374
+ }
3375
+ `;
3159
3376
  const formatErrorMessages = (errors, parentKey, formatMessage) => {
3160
3377
  const messages = [];
3161
3378
  Object.entries(errors).forEach(([key, value]) => {
@@ -3260,7 +3477,7 @@ const SelectedEntriesTableContent = ({
3260
3477
  )
3261
3478
  ] }),
3262
3479
  /* @__PURE__ */ jsx(Table.Loading, {}),
3263
- /* @__PURE__ */ jsx(Table.Body, { children: rowsToDisplay.map((row, index2) => /* @__PURE__ */ jsxs(Table.Row, { children: [
3480
+ /* @__PURE__ */ jsx(Table.Body, { children: rowsToDisplay.map((row) => /* @__PURE__ */ jsxs(Table.Row, { children: [
3264
3481
  /* @__PURE__ */ jsx(Table.CheckboxCell, { id: row.id }),
3265
3482
  /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row.id }) }),
3266
3483
  shouldDisplayMainField && /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row[mainField] }) }),
@@ -3287,18 +3504,10 @@ const SelectedEntriesTableContent = ({
3287
3504
  search: row.locale && `?plugins[i18n][locale]=${row.locale}`
3288
3505
  },
3289
3506
  state: { from: pathname },
3290
- label: formatMessage(
3291
- { id: "app.component.HelperPluginTable.edit", defaultMessage: "Edit {target}" },
3292
- {
3293
- target: formatMessage(
3294
- {
3295
- id: "content-manager.components.ListViewHelperPluginTable.row-line",
3296
- defaultMessage: "item line {number}"
3297
- },
3298
- { number: index2 + 1 }
3299
- )
3300
- }
3301
- ),
3507
+ label: formatMessage({
3508
+ id: "content-manager.bulk-publish.edit",
3509
+ defaultMessage: "Edit"
3510
+ }),
3302
3511
  target: "_blank",
3303
3512
  marginLeft: "auto",
3304
3513
  variant: "ghost",
@@ -3308,7 +3517,73 @@ const SelectedEntriesTableContent = ({
3308
3517
  ] }, row.id)) })
3309
3518
  ] });
3310
3519
  };
3311
- const BoldChunk = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
3520
+ const PublicationStatusSummary = ({ count, icon, message }) => {
3521
+ return /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", flex: 1, gap: 3, children: [
3522
+ /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3523
+ icon,
3524
+ /* @__PURE__ */ jsx(Typography, { children: message })
3525
+ ] }),
3526
+ /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: count })
3527
+ ] });
3528
+ };
3529
+ const PublicationStatusGrid = ({
3530
+ entriesReadyToPublishCount,
3531
+ entriesPublishedCount,
3532
+ entriesModifiedCount,
3533
+ entriesWithErrorsCount
3534
+ }) => {
3535
+ const { formatMessage } = useIntl();
3536
+ return /* @__PURE__ */ jsx(Box, { hasRadius: true, borderColor: "neutral150", children: /* @__PURE__ */ jsx(TableComponent, { colCount: 2, rowCount: 2, children: /* @__PURE__ */ jsxs(Tbody, { children: [
3537
+ /* @__PURE__ */ jsxs(Tr, { children: [
3538
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(
3539
+ PublicationStatusSummary,
3540
+ {
3541
+ count: entriesReadyToPublishCount,
3542
+ icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
3543
+ message: formatMessage({
3544
+ id: "app.utils.ready-to-publish",
3545
+ defaultMessage: "Ready to publish"
3546
+ })
3547
+ }
3548
+ ) }),
3549
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(
3550
+ PublicationStatusSummary,
3551
+ {
3552
+ count: entriesPublishedCount,
3553
+ icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
3554
+ message: formatMessage({
3555
+ id: "app.utils.already-published",
3556
+ defaultMessage: "Already published"
3557
+ })
3558
+ }
3559
+ ) })
3560
+ ] }),
3561
+ /* @__PURE__ */ jsxs(Tr, { children: [
3562
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(
3563
+ PublicationStatusSummary,
3564
+ {
3565
+ count: entriesModifiedCount,
3566
+ icon: /* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
3567
+ message: formatMessage({
3568
+ id: "content-manager.bulk-publish.modified",
3569
+ defaultMessage: "Ready to publish changes"
3570
+ })
3571
+ }
3572
+ ) }),
3573
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(
3574
+ PublicationStatusSummary,
3575
+ {
3576
+ count: entriesWithErrorsCount,
3577
+ icon: /* @__PURE__ */ jsx(CrossCircle, { fill: "danger600" }),
3578
+ message: formatMessage({
3579
+ id: "content-manager.bulk-publish.waiting-for-action",
3580
+ defaultMessage: "Waiting for action"
3581
+ })
3582
+ }
3583
+ ) })
3584
+ ] })
3585
+ ] }) }) });
3586
+ };
3312
3587
  const SelectedEntriesModalContent = ({
3313
3588
  listViewSelectedEntries,
3314
3589
  toggleModal,
@@ -3367,7 +3642,6 @@ const SelectedEntriesModalContent = ({
3367
3642
  validationErrors: {}
3368
3643
  };
3369
3644
  }, [components, data, schema]);
3370
- const [publishedCount, setPublishedCount] = React.useState(0);
3371
3645
  const [isDialogOpen, setIsDialogOpen] = React.useState(false);
3372
3646
  const { publishMany: bulkPublishAction } = useDocumentActions();
3373
3647
  const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
@@ -3379,53 +3653,36 @@ const SelectedEntriesModalContent = ({
3379
3653
  const selectedEntriesWithErrorsCount = selectedEntries.filter(
3380
3654
  ({ documentId }) => validationErrors[documentId]
3381
3655
  ).length;
3382
- const selectedEntriesPublished = selectedEntries.filter(
3656
+ const selectedEntriesPublishedCount = selectedEntries.filter(
3383
3657
  ({ status }) => status === "published"
3384
3658
  ).length;
3385
- const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublished;
3659
+ const selectedEntriesModifiedCount = selectedEntries.filter(
3660
+ ({ status, documentId }) => status === "modified" && !validationErrors[documentId]
3661
+ ).length;
3662
+ const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublishedCount;
3386
3663
  const toggleDialog = () => setIsDialogOpen((prev) => !prev);
3387
3664
  const handleConfirmBulkPublish = async () => {
3388
3665
  toggleDialog();
3389
3666
  const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
3390
3667
  if (!("error" in res)) {
3391
- setPublishedCount(res.count);
3392
3668
  const unpublishedEntries = rows.filter((row) => {
3393
3669
  return !entriesToPublish.includes(row.documentId);
3394
3670
  });
3395
3671
  setListViewSelectedDocuments(unpublishedEntries);
3396
3672
  }
3397
3673
  };
3398
- const getFormattedCountMessage = () => {
3399
- if (publishedCount) {
3400
- return formatMessage(
3401
- {
3402
- id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
3403
- defaultMessage: "<b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} published. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
3404
- },
3405
- {
3406
- publishedCount,
3407
- withErrorsCount: selectedEntriesWithErrorsCount,
3408
- b: BoldChunk
3409
- }
3410
- );
3411
- }
3412
- return formatMessage(
3413
- {
3414
- id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
3415
- defaultMessage: "<b>{alreadyPublishedCount}</b> {alreadyPublishedCount, plural, =0 {entries} one {entry} other {entries}} already published. <b>{readyToPublishCount}</b> {readyToPublishCount, plural, =0 {entries} one {entry} other {entries}} ready to publish. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
3416
- },
3417
- {
3418
- readyToPublishCount: selectedEntriesWithNoErrorsCount,
3419
- withErrorsCount: selectedEntriesWithErrorsCount,
3420
- alreadyPublishedCount: selectedEntriesPublished,
3421
- b: BoldChunk
3422
- }
3423
- );
3424
- };
3425
3674
  return /* @__PURE__ */ jsxs(Fragment, { children: [
3426
3675
  /* @__PURE__ */ jsxs(Modal.Body, { children: [
3427
- /* @__PURE__ */ jsx(Typography, { children: getFormattedCountMessage() }),
3428
- /* @__PURE__ */ jsx(Box, { marginTop: 5, children: /* @__PURE__ */ jsx(
3676
+ /* @__PURE__ */ jsx(
3677
+ PublicationStatusGrid,
3678
+ {
3679
+ entriesReadyToPublishCount: selectedEntriesWithNoErrorsCount - selectedEntriesModifiedCount,
3680
+ entriesPublishedCount: selectedEntriesPublishedCount,
3681
+ entriesModifiedCount: selectedEntriesModifiedCount,
3682
+ entriesWithErrorsCount: selectedEntriesWithErrorsCount
3683
+ }
3684
+ ),
3685
+ /* @__PURE__ */ jsx(Box, { marginTop: 7, children: /* @__PURE__ */ jsx(
3429
3686
  SelectedEntriesTableContent,
3430
3687
  {
3431
3688
  isPublishing: isSubmittingForm,
@@ -3446,7 +3703,7 @@ const SelectedEntriesModalContent = ({
3446
3703
  Button,
3447
3704
  {
3448
3705
  onClick: toggleDialog,
3449
- disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
3706
+ disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublishedCount === selectedEntries.length || isLoading,
3450
3707
  loading: isSubmittingForm,
3451
3708
  children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
3452
3709
  }
@@ -3472,8 +3729,7 @@ const PublishAction = ({ documents, model }) => {
3472
3729
  const refetchList = () => {
3473
3730
  contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
3474
3731
  };
3475
- if (!showPublishButton)
3476
- return null;
3732
+ if (!showPublishButton) return null;
3477
3733
  return {
3478
3734
  actionType: "publish",
3479
3735
  variant: "tertiary",
@@ -3541,8 +3797,7 @@ const DeleteAction = ({ documents, model }) => {
3541
3797
  selectRow([]);
3542
3798
  }
3543
3799
  };
3544
- if (!hasDeletePermission)
3545
- return null;
3800
+ if (!hasDeletePermission) return null;
3546
3801
  return {
3547
3802
  variant: "danger-light",
3548
3803
  label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
@@ -3591,8 +3846,7 @@ const UnpublishAction = ({ documents, model }) => {
3591
3846
  }
3592
3847
  };
3593
3848
  const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
3594
- if (!showUnpublishButton)
3595
- return null;
3849
+ if (!showUnpublishButton) return null;
3596
3850
  return {
3597
3851
  variant: "tertiary",
3598
3852
  label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
@@ -3697,7 +3951,7 @@ const TableActions = ({ document }) => {
3697
3951
  DescriptionComponentRenderer,
3698
3952
  {
3699
3953
  props,
3700
- descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
3954
+ descriptions: plugins["content-manager"].apis.getDocumentActions("table-row").filter((action) => action.name !== "PublishAction"),
3701
3955
  children: (actions2) => {
3702
3956
  const tableRowActions = actions2.filter((action) => {
3703
3957
  const positions = Array.isArray(action.position) ? action.position : [action.position];
@@ -3756,6 +4010,7 @@ const EditAction = ({ documentId }) => {
3756
4010
  };
3757
4011
  };
3758
4012
  EditAction.type = "edit";
4013
+ EditAction.position = "table-row";
3759
4014
  const StyledPencil = styled(Pencil)`
3760
4015
  path {
3761
4016
  fill: currentColor;
@@ -3832,6 +4087,7 @@ const CloneAction = ({ model, documentId }) => {
3832
4087
  };
3833
4088
  };
3834
4089
  CloneAction.type = "clone";
4090
+ CloneAction.position = "table-row";
3835
4091
  const StyledDuplicate = styled(Duplicate)`
3836
4092
  path {
3837
4093
  fill: currentColor;
@@ -3918,7 +4174,14 @@ class ContentManagerPlugin {
3918
4174
  addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
3919
4175
  addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
3920
4176
  getBulkActions: () => this.bulkActions,
3921
- getDocumentActions: () => this.documentActions,
4177
+ getDocumentActions: (position) => {
4178
+ if (position) {
4179
+ return this.documentActions.filter(
4180
+ (action) => action.position == void 0 || [action.position].flat().includes(position)
4181
+ );
4182
+ }
4183
+ return this.documentActions;
4184
+ },
3922
4185
  getEditViewSidePanels: () => this.editViewSidePanels,
3923
4186
  getHeaderActions: () => this.headerActions
3924
4187
  }
@@ -3928,10 +4191,8 @@ class ContentManagerPlugin {
3928
4191
  const getPrintableType = (value) => {
3929
4192
  const nativeType = typeof value;
3930
4193
  if (nativeType === "object") {
3931
- if (value === null)
3932
- return "null";
3933
- if (Array.isArray(value))
3934
- return "array";
4194
+ if (value === null) return "null";
4195
+ if (Array.isArray(value)) return "array";
3935
4196
  if (value instanceof Object && value.constructor.name !== "Object") {
3936
4197
  return value.constructor.name;
3937
4198
  }
@@ -3942,17 +4203,27 @@ const HistoryAction = ({ model, document }) => {
3942
4203
  const { formatMessage } = useIntl();
3943
4204
  const [{ query }] = useQueryParams();
3944
4205
  const navigate = useNavigate();
4206
+ const { trackUsage } = useTracking();
4207
+ const { pathname } = useLocation();
3945
4208
  const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
3946
4209
  if (!window.strapi.features.isEnabled("cms-content-history")) {
3947
4210
  return null;
3948
4211
  }
4212
+ const handleOnClick = () => {
4213
+ const destination = { pathname: "history", search: pluginsQueryParams };
4214
+ trackUsage("willNavigate", {
4215
+ from: pathname,
4216
+ to: `${pathname}/${destination.pathname}`
4217
+ });
4218
+ navigate(destination);
4219
+ };
3949
4220
  return {
3950
4221
  icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
3951
4222
  label: formatMessage({
3952
4223
  id: "content-manager.history.document-action",
3953
4224
  defaultMessage: "Content History"
3954
4225
  }),
3955
- onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
4226
+ onClick: handleOnClick,
3956
4227
  disabled: (
3957
4228
  /**
3958
4229
  * The user is creating a new document.
@@ -3974,6 +4245,7 @@ const HistoryAction = ({ model, document }) => {
3974
4245
  };
3975
4246
  };
3976
4247
  HistoryAction.type = "history";
4248
+ HistoryAction.position = "header";
3977
4249
  const historyAdmin = {
3978
4250
  bootstrap(app) {
3979
4251
  const { addDocumentAction } = app.getPlugin("content-manager").apis;
@@ -4020,6 +4292,88 @@ const { setInitialData } = actions;
4020
4292
  const reducer = combineReducers({
4021
4293
  app: reducer$1
4022
4294
  });
4295
+ const previewApi = contentManagerApi.injectEndpoints({
4296
+ endpoints: (builder) => ({
4297
+ getPreviewUrl: builder.query({
4298
+ query({ query, params }) {
4299
+ return {
4300
+ url: `/content-manager/preview/url/${params.contentType}`,
4301
+ method: "GET",
4302
+ config: {
4303
+ params: query
4304
+ }
4305
+ };
4306
+ }
4307
+ })
4308
+ })
4309
+ });
4310
+ const { useGetPreviewUrlQuery } = previewApi;
4311
+ const ConditionalTooltip = ({ isShown, label, children }) => {
4312
+ if (isShown) {
4313
+ return /* @__PURE__ */ jsx(Tooltip, { label, children });
4314
+ }
4315
+ return children;
4316
+ };
4317
+ const PreviewSidePanel = ({ model, documentId, document }) => {
4318
+ const { formatMessage } = useIntl();
4319
+ const { trackUsage } = useTracking();
4320
+ const { pathname } = useLocation();
4321
+ const [{ query }] = useQueryParams();
4322
+ const isModified = useForm("PreviewSidePanel", (state) => state.modified);
4323
+ const { data, error } = useGetPreviewUrlQuery({
4324
+ params: {
4325
+ contentType: model
4326
+ },
4327
+ query: {
4328
+ documentId,
4329
+ locale: document?.locale,
4330
+ status: document?.status
4331
+ }
4332
+ });
4333
+ if (!data?.data?.url || error) {
4334
+ return null;
4335
+ }
4336
+ const trackNavigation = () => {
4337
+ const destinationPathname = pathname.replace(/\/$/, "") + "/preview";
4338
+ trackUsage("willNavigate", { from: pathname, to: destinationPathname });
4339
+ };
4340
+ return {
4341
+ title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
4342
+ content: /* @__PURE__ */ jsx(
4343
+ ConditionalTooltip,
4344
+ {
4345
+ label: formatMessage({
4346
+ id: "content-manager.preview.panel.button-disabled-tooltip",
4347
+ defaultMessage: "Please save to open the preview"
4348
+ }),
4349
+ isShown: isModified,
4350
+ children: /* @__PURE__ */ jsx(Box, { cursor: "not-allowed", width: "100%", children: /* @__PURE__ */ jsx(
4351
+ Button,
4352
+ {
4353
+ variant: "tertiary",
4354
+ tag: Link,
4355
+ to: { pathname: "preview", search: stringify(query, { encode: false }) },
4356
+ onClick: trackNavigation,
4357
+ width: "100%",
4358
+ disabled: isModified,
4359
+ pointerEvents: isModified ? "none" : void 0,
4360
+ tabIndex: isModified ? -1 : void 0,
4361
+ children: formatMessage({
4362
+ id: "content-manager.preview.panel.button",
4363
+ defaultMessage: "Open preview"
4364
+ })
4365
+ }
4366
+ ) })
4367
+ }
4368
+ )
4369
+ };
4370
+ };
4371
+ const previewAdmin = {
4372
+ bootstrap(app) {
4373
+ const contentManagerPluginApis = app.getPlugin("content-manager").apis;
4374
+ contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
4375
+ }
4376
+ };
4023
4377
  const index = {
4024
4378
  register(app) {
4025
4379
  const cm = new ContentManagerPlugin();
@@ -4039,7 +4393,7 @@ const index = {
4039
4393
  app.router.addRoute({
4040
4394
  path: "content-manager/*",
4041
4395
  lazy: async () => {
4042
- const { Layout } = await import("./layout-aX-RJhd5.mjs");
4396
+ const { Layout } = await import("./layout-fQk1rMk9.mjs");
4043
4397
  return {
4044
4398
  Component: Layout
4045
4399
  };
@@ -4052,11 +4406,14 @@ const index = {
4052
4406
  if (typeof historyAdmin.bootstrap === "function") {
4053
4407
  historyAdmin.bootstrap(app);
4054
4408
  }
4409
+ if (typeof previewAdmin.bootstrap === "function") {
4410
+ previewAdmin.bootstrap(app);
4411
+ }
4055
4412
  },
4056
4413
  async registerTrads({ locales }) {
4057
4414
  const importedTrads = await Promise.all(
4058
4415
  locales.map((locale) => {
4059
- 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-DKV44jRb.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 }) => {
4416
+ 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-D65uIF6Y.mjs"), "./translations/es.json": () => import("./es-D34tqjMw.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr-DBseuRuB.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 }) => {
4060
4417
  return {
4061
4418
  data: prefixPluginTranslations(data, PLUGIN_ID),
4062
4419
  locale
@@ -4073,23 +4430,27 @@ const index = {
4073
4430
  }
4074
4431
  };
4075
4432
  export {
4076
- ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD as A,
4433
+ useUpdateContentTypeConfigurationMutation as A,
4077
4434
  BulkActionsRenderer as B,
4078
4435
  COLLECTION_TYPES as C,
4079
4436
  DocumentStatus as D,
4080
- extractContentTypeComponents as E,
4081
- DEFAULT_SETTINGS as F,
4082
- convertEditLayoutToFieldLayouts as G,
4437
+ ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD as E,
4438
+ extractContentTypeComponents as F,
4439
+ DEFAULT_SETTINGS as G,
4083
4440
  HOOKS as H,
4084
4441
  InjectionZone as I,
4085
- useDocument as J,
4086
- index as K,
4087
- useContentManagerContext as L,
4088
- useDocumentActions as M,
4442
+ convertEditLayoutToFieldLayouts as J,
4443
+ removeFieldsThatDontExistOnSchema as K,
4444
+ prepareTempKeys as L,
4445
+ useDocument as M,
4446
+ useGetPreviewUrlQuery as N,
4447
+ index as O,
4089
4448
  Panels as P,
4449
+ useContentManagerContext as Q,
4090
4450
  RelativeTime as R,
4091
4451
  SINGLE_TYPES as S,
4092
4452
  TableActions as T,
4453
+ useDocumentActions as U,
4093
4454
  useGetInitialDataQuery as a,
4094
4455
  useGetAllContentTypeSettingsQuery as b,
4095
4456
  useDoc as c,
@@ -4102,19 +4463,19 @@ export {
4102
4463
  Header as j,
4103
4464
  PERMISSIONS as k,
4104
4465
  DocumentRBAC as l,
4105
- DOCUMENT_META_FIELDS as m,
4106
- CLONE_PATH as n,
4107
- useDocLayout as o,
4466
+ useDocLayout as m,
4467
+ createDefaultForm as n,
4468
+ CLONE_PATH as o,
4108
4469
  useGetContentTypeConfigurationQuery as p,
4109
4470
  CREATOR_FIELDS as q,
4110
4471
  getMainField as r,
4111
4472
  setInitialData as s,
4112
- getDisplayName as t,
4473
+ transformDocument as t,
4113
4474
  useContentTypeSchema as u,
4114
- checkIfAttributeIsDisplayable as v,
4115
- useGetAllDocumentsQuery as w,
4116
- convertListLayoutToFieldLayouts as x,
4117
- capitalise as y,
4118
- useUpdateContentTypeConfigurationMutation as z
4475
+ getDisplayName as v,
4476
+ checkIfAttributeIsDisplayable as w,
4477
+ useGetAllDocumentsQuery as x,
4478
+ convertListLayoutToFieldLayouts as y,
4479
+ capitalise as z
4119
4480
  };
4120
- //# sourceMappingURL=index-TaRzG09p.mjs.map
4481
+ //# sourceMappingURL=index-ZKrsjv-2.mjs.map