@strapi/content-manager 0.0.0-next.bb6ff32f5168f3e380d3d9acba90a9d53bfcfb89 → 0.0.0-next.bffd3c1819cd08304e7d270e88b4973e9fcbc183

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 (162) 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-DqB7veg_.mjs → ComponentConfigurationPage-9_4yUE9L.mjs} +3 -3
  4. package/dist/_chunks/{ComponentConfigurationPage-DqB7veg_.mjs.map → ComponentConfigurationPage-9_4yUE9L.mjs.map} +1 -1
  5. package/dist/_chunks/{ComponentConfigurationPage-Bmwd-G2q.js → ComponentConfigurationPage-DBSh-kET.js} +4 -5
  6. package/dist/_chunks/{ComponentConfigurationPage-Bmwd-G2q.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-DmruXqgR.js → EditConfigurationPage-Bl_U2JgH.js} +4 -5
  11. package/dist/_chunks/{EditConfigurationPage-DmruXqgR.js.map → EditConfigurationPage-Bl_U2JgH.js.map} +1 -1
  12. package/dist/_chunks/{EditConfigurationPage-CDLVqqay.mjs → EditConfigurationPage-COe6hjPC.mjs} +3 -3
  13. package/dist/_chunks/{EditConfigurationPage-CDLVqqay.mjs.map → EditConfigurationPage-COe6hjPC.mjs.map} +1 -1
  14. package/dist/_chunks/{EditViewPage-0zrWXtMz.js → EditViewPage-D4yFJET6.js} +14 -78
  15. package/dist/_chunks/EditViewPage-D4yFJET6.js.map +1 -0
  16. package/dist/_chunks/{EditViewPage-BgcbLW7w.mjs → EditViewPage-DrmVmYN0.mjs} +11 -74
  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-CIDoAFoD.js → Form-C4rSaGsz.js} +5 -6
  21. package/dist/_chunks/{Form-CIDoAFoD.js.map → Form-C4rSaGsz.js.map} +1 -1
  22. package/dist/_chunks/{Form-WNWgTBtb.mjs → Form-DamaxNpG.mjs} +3 -3
  23. package/dist/_chunks/{Form-WNWgTBtb.mjs.map → Form-DamaxNpG.mjs.map} +1 -1
  24. package/dist/_chunks/{History-DEZDHwP0.mjs → History-D1PreDSY.mjs} +36 -10
  25. package/dist/_chunks/History-D1PreDSY.mjs.map +1 -0
  26. package/dist/_chunks/{History-BNvm2TK2.js → History-DTm8UCCQ.js} +47 -22
  27. package/dist/_chunks/History-DTm8UCCQ.js.map +1 -0
  28. package/dist/_chunks/{Field-BV7ZYdqe.js → Input-B7sapvBG.js} +1331 -1329
  29. package/dist/_chunks/Input-B7sapvBG.js.map +1 -0
  30. package/dist/_chunks/{Field-fTjqtEem.mjs → Input-CZ1YvjHR.mjs} +1245 -1243
  31. package/dist/_chunks/Input-CZ1YvjHR.mjs.map +1 -0
  32. package/dist/_chunks/{ListConfigurationPage-Ddz3G-It.mjs → ListConfigurationPage-Bbi32isk.mjs} +6 -5
  33. package/dist/_chunks/ListConfigurationPage-Bbi32isk.mjs.map +1 -0
  34. package/dist/_chunks/{ListConfigurationPage-B3FZwPHp.js → ListConfigurationPage-ysFMjKI3.js} +6 -6
  35. package/dist/_chunks/ListConfigurationPage-ysFMjKI3.js.map +1 -0
  36. package/dist/_chunks/{ListViewPage-BsLdw25U.mjs → ListViewPage-Bud_jBDQ.mjs} +55 -51
  37. package/dist/_chunks/ListViewPage-Bud_jBDQ.mjs.map +1 -0
  38. package/dist/_chunks/{ListViewPage-BEilNylQ.js → ListViewPage-DTuuxU3n.js} +61 -58
  39. package/dist/_chunks/ListViewPage-DTuuxU3n.js.map +1 -0
  40. package/dist/_chunks/{NoContentTypePage-BD2C-IMr.js → NoContentTypePage-CL7VVeYs.js} +2 -2
  41. package/dist/_chunks/{NoContentTypePage-BD2C-IMr.js.map → NoContentTypePage-CL7VVeYs.js.map} +1 -1
  42. package/dist/_chunks/{NoContentTypePage-D0jXEWKM.mjs → NoContentTypePage-DVhkugsf.mjs} +2 -2
  43. package/dist/_chunks/{NoContentTypePage-D0jXEWKM.mjs.map → NoContentTypePage-DVhkugsf.mjs.map} +1 -1
  44. package/dist/_chunks/{NoPermissionsPage-CIPqlrQq.mjs → NoPermissionsPage-CMdM-dCo.mjs} +2 -2
  45. package/dist/_chunks/{NoPermissionsPage-CIPqlrQq.mjs.map → NoPermissionsPage-CMdM-dCo.mjs.map} +1 -1
  46. package/dist/_chunks/{NoPermissionsPage-yNOvz9XO.js → NoPermissionsPage-v7I599vC.js} +2 -2
  47. package/dist/_chunks/{NoPermissionsPage-yNOvz9XO.js.map → NoPermissionsPage-v7I599vC.js.map} +1 -1
  48. package/dist/_chunks/{Preview-ot2fh0yZ.mjs → Preview-BNuU0SuQ.mjs} +74 -24
  49. package/dist/_chunks/Preview-BNuU0SuQ.mjs.map +1 -0
  50. package/dist/_chunks/{Preview-1cqLecKr.js → Preview-Cxq-uI6D.js} +73 -24
  51. package/dist/_chunks/Preview-Cxq-uI6D.js.map +1 -0
  52. package/dist/_chunks/{Relations-CfdwHP-0.mjs → Relations-C2Ahkrdg.mjs} +6 -8
  53. package/dist/_chunks/{Relations-CfdwHP-0.mjs.map → Relations-C2Ahkrdg.mjs.map} +1 -1
  54. package/dist/_chunks/{Relations-C3U9SKEb.js → Relations-CWS79QQn.js} +7 -10
  55. package/dist/_chunks/{Relations-C3U9SKEb.js.map → Relations-CWS79QQn.js.map} +1 -1
  56. package/dist/_chunks/{en-CHOp_xJv.js → en-BR48D_RH.js} +13 -3
  57. package/dist/_chunks/{en-CHOp_xJv.js.map → en-BR48D_RH.js.map} +1 -1
  58. package/dist/_chunks/{en-D_BMf0hT.mjs → en-D65uIF6Y.mjs} +13 -3
  59. package/dist/_chunks/{en-D_BMf0hT.mjs.map → en-D65uIF6Y.mjs.map} +1 -1
  60. package/dist/_chunks/{fr-B2Kyv8Z9.js → fr-C43IbhA_.js} +4 -1
  61. package/dist/_chunks/{fr-B2Kyv8Z9.js.map → fr-C43IbhA_.js.map} +1 -1
  62. package/dist/_chunks/{fr--pg5jUbt.mjs → fr-DBseuRuB.mjs} +4 -1
  63. package/dist/_chunks/{fr--pg5jUbt.mjs.map → fr-DBseuRuB.mjs.map} +1 -1
  64. package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
  65. package/dist/_chunks/{index-Cg4RLIAw.js → index-DQsvBb_N.js} +518 -207
  66. package/dist/_chunks/index-DQsvBb_N.js.map +1 -0
  67. package/dist/_chunks/{index-BzUT1l9A.mjs → index-ZKrsjv-2.mjs} +536 -224
  68. package/dist/_chunks/index-ZKrsjv-2.mjs.map +1 -0
  69. package/dist/_chunks/{layout-Cj_1EKbm.js → layout-Cl0NhlQB.js} +5 -6
  70. package/dist/_chunks/{layout-Cj_1EKbm.js.map → layout-Cl0NhlQB.js.map} +1 -1
  71. package/dist/_chunks/{layout-C0QEDBAh.mjs → layout-fQk1rMk9.mjs} +4 -4
  72. package/dist/_chunks/{layout-C0QEDBAh.mjs.map → layout-fQk1rMk9.mjs.map} +1 -1
  73. package/dist/_chunks/objects-BcXOv6_9.js.map +1 -1
  74. package/dist/_chunks/objects-D6yBsdmx.mjs.map +1 -1
  75. package/dist/_chunks/{relations-hDOgJy2R.js → relations-BRfBxVbX.js} +2 -2
  76. package/dist/_chunks/{relations-hDOgJy2R.js.map → relations-BRfBxVbX.js.map} +1 -1
  77. package/dist/_chunks/{relations-CgPG3AwU.mjs → relations-BakOFl_1.mjs} +2 -2
  78. package/dist/_chunks/{relations-CgPG3AwU.mjs.map → relations-BakOFl_1.mjs.map} +1 -1
  79. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
  80. package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
  81. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
  82. package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
  83. package/dist/_chunks/{useDebounce-DmuSJIF3.mjs → usePrev-CZGy2Vjf.mjs} +11 -11
  84. package/dist/_chunks/usePrev-CZGy2Vjf.mjs.map +1 -0
  85. package/dist/_chunks/{useDebounce-CtcjDB3L.js → usePrev-D5J_2fEu.js} +8 -8
  86. package/dist/_chunks/usePrev-D5J_2fEu.js.map +1 -0
  87. package/dist/admin/index.js +2 -1
  88. package/dist/admin/index.js.map +1 -1
  89. package/dist/admin/index.mjs +6 -5
  90. package/dist/admin/src/content-manager.d.ts +3 -2
  91. package/dist/admin/src/exports.d.ts +1 -0
  92. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  93. package/dist/admin/src/hooks/useDocument.d.ts +19 -2
  94. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -1
  95. package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +1 -1
  96. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +7 -0
  97. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
  98. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
  99. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.d.ts +4 -1
  100. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +4 -1
  101. package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +27 -0
  102. package/dist/admin/src/pages/EditView/utils/data.d.ts +1 -0
  103. package/dist/admin/src/preview/pages/Preview.d.ts +1 -1
  104. package/dist/admin/src/preview/services/preview.d.ts +1 -1
  105. package/dist/admin/src/services/api.d.ts +1 -1
  106. package/dist/admin/src/services/components.d.ts +2 -2
  107. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  108. package/dist/admin/src/services/documents.d.ts +16 -19
  109. package/dist/admin/src/services/init.d.ts +1 -1
  110. package/dist/admin/src/services/relations.d.ts +2 -2
  111. package/dist/admin/src/services/uid.d.ts +3 -3
  112. package/dist/server/index.js +230 -187
  113. package/dist/server/index.js.map +1 -1
  114. package/dist/server/index.mjs +231 -187
  115. package/dist/server/index.mjs.map +1 -1
  116. package/dist/server/src/controllers/utils/metadata.d.ts +1 -0
  117. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  118. package/dist/server/src/history/controllers/history-version.d.ts +1 -1
  119. package/dist/server/src/history/controllers/history-version.d.ts.map +1 -1
  120. package/dist/server/src/history/services/history.d.ts +3 -3
  121. package/dist/server/src/history/services/history.d.ts.map +1 -1
  122. package/dist/server/src/history/services/utils.d.ts +6 -10
  123. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  124. package/dist/server/src/index.d.ts +3 -2
  125. package/dist/server/src/index.d.ts.map +1 -1
  126. package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -1
  127. package/dist/server/src/preview/index.d.ts.map +1 -1
  128. package/dist/server/src/preview/services/index.d.ts +1 -0
  129. package/dist/server/src/preview/services/index.d.ts.map +1 -1
  130. package/dist/server/src/preview/services/preview-config.d.ts +2 -0
  131. package/dist/server/src/preview/services/preview-config.d.ts.map +1 -1
  132. package/dist/server/src/preview/utils.d.ts +1 -0
  133. package/dist/server/src/preview/utils.d.ts.map +1 -1
  134. package/dist/server/src/register.d.ts.map +1 -1
  135. package/dist/server/src/services/document-metadata.d.ts +4 -2
  136. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  137. package/dist/server/src/services/index.d.ts +3 -2
  138. package/dist/server/src/services/index.d.ts.map +1 -1
  139. package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
  140. package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
  141. package/dist/server/src/services/utils/populate.d.ts +2 -2
  142. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  143. package/package.json +12 -11
  144. package/dist/_chunks/EditViewPage-0zrWXtMz.js.map +0 -1
  145. package/dist/_chunks/EditViewPage-BgcbLW7w.mjs.map +0 -1
  146. package/dist/_chunks/Field-BV7ZYdqe.js.map +0 -1
  147. package/dist/_chunks/Field-fTjqtEem.mjs.map +0 -1
  148. package/dist/_chunks/History-BNvm2TK2.js.map +0 -1
  149. package/dist/_chunks/History-DEZDHwP0.mjs.map +0 -1
  150. package/dist/_chunks/ListConfigurationPage-B3FZwPHp.js.map +0 -1
  151. package/dist/_chunks/ListConfigurationPage-Ddz3G-It.mjs.map +0 -1
  152. package/dist/_chunks/ListViewPage-BEilNylQ.js.map +0 -1
  153. package/dist/_chunks/ListViewPage-BsLdw25U.mjs.map +0 -1
  154. package/dist/_chunks/Preview-1cqLecKr.js.map +0 -1
  155. package/dist/_chunks/Preview-ot2fh0yZ.mjs.map +0 -1
  156. package/dist/_chunks/index-BzUT1l9A.mjs.map +0 -1
  157. package/dist/_chunks/index-Cg4RLIAw.js.map +0 -1
  158. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +0 -1
  159. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +0 -1
  160. package/dist/admin/src/preview/constants.d.ts +0 -1
  161. package/dist/server/src/preview/constants.d.ts +0 -2
  162. package/dist/server/src/preview/constants.d.ts.map +0 -1
@@ -7,16 +7,16 @@ const designSystem = require("@strapi/design-system");
7
7
  const mapValues = require("lodash/fp/mapValues");
8
8
  const reactIntl = require("react-intl");
9
9
  const reactRouterDom = require("react-router-dom");
10
+ const styledComponents = require("styled-components");
10
11
  const yup = require("yup");
12
+ const fractionalIndexing = require("fractional-indexing");
11
13
  const pipe = require("lodash/fp/pipe");
12
- const dateFns = require("date-fns");
13
- const styledComponents = require("styled-components");
14
14
  const qs = require("qs");
15
+ const dateFns = require("date-fns");
15
16
  const toolkit = require("@reduxjs/toolkit");
16
17
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
17
18
  function _interopNamespace(e) {
18
- if (e && e.__esModule)
19
- return e;
19
+ if (e && e.__esModule) return e;
20
20
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
21
21
  if (e) {
22
22
  for (const k in e) {
@@ -36,13 +36,20 @@ const React__namespace = /* @__PURE__ */ _interopNamespace(React);
36
36
  const mapValues__default = /* @__PURE__ */ _interopDefault(mapValues);
37
37
  const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
38
38
  const pipe__default = /* @__PURE__ */ _interopDefault(pipe);
39
- const __variableDynamicImportRuntimeHelper = (glob, path) => {
39
+ const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
40
40
  const v = glob[path];
41
41
  if (v) {
42
42
  return typeof v === "function" ? v() : Promise.resolve(v);
43
43
  }
44
44
  return new Promise((_, reject) => {
45
- (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(reject.bind(null, new Error("Unknown variable dynamic import: " + path)));
45
+ (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
46
+ reject.bind(
47
+ null,
48
+ new Error(
49
+ "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
50
+ )
51
+ )
52
+ );
46
53
  });
47
54
  };
48
55
  const PLUGIN_ID = "content-manager";
@@ -181,6 +188,113 @@ const extractAndDedupeFields = (permissions = []) => permissions.flatMap((permis
181
188
  (field, index2, arr) => arr.indexOf(field) === index2 && typeof field === "string"
182
189
  );
183
190
  const removeNumericalStrings = (arr) => arr.filter((item) => isNaN(Number(item)));
191
+ const BLOCK_LIST_ATTRIBUTE_KEYS = ["__component", "__temp_key__"];
192
+ const traverseData = (predicate, transform) => (schema, components = {}) => (data = {}) => {
193
+ const traverse = (datum, attributes) => {
194
+ return Object.entries(datum).reduce((acc, [key, value]) => {
195
+ const attribute = attributes[key];
196
+ if (BLOCK_LIST_ATTRIBUTE_KEYS.includes(key) || value === null || value === void 0) {
197
+ acc[key] = value;
198
+ return acc;
199
+ }
200
+ if (attribute.type === "component") {
201
+ if (attribute.repeatable) {
202
+ const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
203
+ acc[key] = componentValue.map(
204
+ (componentData) => traverse(componentData, components[attribute.component]?.attributes ?? {})
205
+ );
206
+ } else {
207
+ const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
208
+ acc[key] = traverse(componentValue, components[attribute.component]?.attributes ?? {});
209
+ }
210
+ } else if (attribute.type === "dynamiczone") {
211
+ const dynamicZoneValue = predicate(attribute, value) ? transform(value, attribute) : value;
212
+ acc[key] = dynamicZoneValue.map(
213
+ (componentData) => traverse(componentData, components[componentData.__component]?.attributes ?? {})
214
+ );
215
+ } else if (predicate(attribute, value)) {
216
+ acc[key] = transform(value, attribute);
217
+ } else {
218
+ acc[key] = value;
219
+ }
220
+ return acc;
221
+ }, {});
222
+ };
223
+ return traverse(data, schema.attributes);
224
+ };
225
+ const removeProhibitedFields = (prohibitedFields) => traverseData(
226
+ (attribute) => prohibitedFields.includes(attribute.type),
227
+ () => ""
228
+ );
229
+ const prepareRelations = traverseData(
230
+ (attribute) => attribute.type === "relation",
231
+ () => ({
232
+ connect: [],
233
+ disconnect: []
234
+ })
235
+ );
236
+ const prepareTempKeys = traverseData(
237
+ (attribute) => attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone",
238
+ (data) => {
239
+ if (Array.isArray(data) && data.length > 0) {
240
+ const keys = fractionalIndexing.generateNKeysBetween(void 0, void 0, data.length);
241
+ return data.map((datum, index2) => ({
242
+ ...datum,
243
+ __temp_key__: keys[index2]
244
+ }));
245
+ }
246
+ return data;
247
+ }
248
+ );
249
+ const removeFieldsThatDontExistOnSchema = (schema) => (data) => {
250
+ const schemaKeys = Object.keys(schema.attributes);
251
+ const dataKeys = Object.keys(data);
252
+ const keysToRemove = dataKeys.filter((key) => !schemaKeys.includes(key));
253
+ const revisedData = [...keysToRemove, ...DOCUMENT_META_FIELDS].reduce((acc, key) => {
254
+ delete acc[key];
255
+ return acc;
256
+ }, structuredClone(data));
257
+ return revisedData;
258
+ };
259
+ const removeNullValues = (data) => {
260
+ return Object.entries(data).reduce((acc, [key, value]) => {
261
+ if (value === null) {
262
+ return acc;
263
+ }
264
+ acc[key] = value;
265
+ return acc;
266
+ }, {});
267
+ };
268
+ const transformDocument = (schema, components = {}) => (document) => {
269
+ const transformations = pipe__default.default(
270
+ removeFieldsThatDontExistOnSchema(schema),
271
+ removeProhibitedFields(["password"])(schema, components),
272
+ removeNullValues,
273
+ prepareRelations(schema, components),
274
+ prepareTempKeys(schema, components)
275
+ );
276
+ return transformations(document);
277
+ };
278
+ const createDefaultForm = (contentType, components = {}) => {
279
+ const traverseSchema = (attributes) => {
280
+ return Object.entries(attributes).reduce((acc, [key, attribute]) => {
281
+ if ("default" in attribute) {
282
+ acc[key] = attribute.default;
283
+ } else if (attribute.type === "component" && attribute.required) {
284
+ const defaultComponentForm = traverseSchema(components[attribute.component].attributes);
285
+ if (attribute.repeatable) {
286
+ acc[key] = attribute.min ? [...Array(attribute.min).fill(defaultComponentForm)] : [];
287
+ } else {
288
+ acc[key] = defaultComponentForm;
289
+ }
290
+ } else if (attribute.type === "dynamiczone" && attribute.required) {
291
+ acc[key] = [];
292
+ }
293
+ return acc;
294
+ }, {});
295
+ };
296
+ return traverseSchema(contentType.attributes);
297
+ };
184
298
  const contentManagerApi = strapiAdmin.adminApi.enhanceEndpoints({
185
299
  addTagTypes: [
186
300
  "ComponentConfiguration",
@@ -190,7 +304,8 @@ const contentManagerApi = strapiAdmin.adminApi.enhanceEndpoints({
190
304
  "InitialData",
191
305
  "HistoryVersion",
192
306
  "Relations",
193
- "UidAvailability"
307
+ "UidAvailability",
308
+ "RecentDocumentList"
194
309
  ]
195
310
  });
196
311
  const documentApi = contentManagerApi.injectEndpoints({
@@ -208,7 +323,7 @@ const documentApi = contentManagerApi.injectEndpoints({
208
323
  if (error) {
209
324
  return [];
210
325
  }
211
- return [{ type: "Document", id: `${model}_LIST` }];
326
+ return [{ type: "Document", id: `${model}_LIST` }, "RecentDocumentList"];
212
327
  }
213
328
  }),
214
329
  cloneDocument: builder.mutation({
@@ -222,7 +337,8 @@ const documentApi = contentManagerApi.injectEndpoints({
222
337
  }),
223
338
  invalidatesTags: (_result, _error, { model }) => [
224
339
  { type: "Document", id: `${model}_LIST` },
225
- { type: "UidAvailability", id: model }
340
+ { type: "UidAvailability", id: model },
341
+ "RecentDocumentList"
226
342
  ]
227
343
  }),
228
344
  /**
@@ -241,8 +357,21 @@ const documentApi = contentManagerApi.injectEndpoints({
241
357
  invalidatesTags: (result, _error, { model }) => [
242
358
  { type: "Document", id: `${model}_LIST` },
243
359
  "Relations",
244
- { type: "UidAvailability", id: model }
245
- ]
360
+ { type: "UidAvailability", id: model },
361
+ "RecentDocumentList"
362
+ ],
363
+ transformResponse: (response, meta, arg) => {
364
+ if (!("data" in response) && arg.model === "plugin::users-permissions.user") {
365
+ return {
366
+ data: response,
367
+ meta: {
368
+ availableStatus: [],
369
+ availableLocales: []
370
+ }
371
+ };
372
+ }
373
+ return response;
374
+ }
246
375
  }),
247
376
  deleteDocument: builder.mutation({
248
377
  query: ({ collectionType, model, documentId, params }) => ({
@@ -253,7 +382,8 @@ const documentApi = contentManagerApi.injectEndpoints({
253
382
  }
254
383
  }),
255
384
  invalidatesTags: (_result, _error, { collectionType, model }) => [
256
- { type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model }
385
+ { type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model },
386
+ "RecentDocumentList"
257
387
  ]
258
388
  }),
259
389
  deleteManyDocuments: builder.mutation({
@@ -265,7 +395,10 @@ const documentApi = contentManagerApi.injectEndpoints({
265
395
  params
266
396
  }
267
397
  }),
268
- invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
398
+ invalidatesTags: (_res, _error, { model }) => [
399
+ { type: "Document", id: `${model}_LIST` },
400
+ "RecentDocumentList"
401
+ ]
269
402
  }),
270
403
  discardDocument: builder.mutation({
271
404
  query: ({ collectionType, model, documentId, params }) => ({
@@ -283,7 +416,8 @@ const documentApi = contentManagerApi.injectEndpoints({
283
416
  },
284
417
  { type: "Document", id: `${model}_LIST` },
285
418
  "Relations",
286
- { type: "UidAvailability", id: model }
419
+ { type: "UidAvailability", id: model },
420
+ "RecentDocumentList"
287
421
  ];
288
422
  }
289
423
  }),
@@ -296,7 +430,7 @@ const documentApi = contentManagerApi.injectEndpoints({
296
430
  url: `/content-manager/collection-types/${model}`,
297
431
  method: "GET",
298
432
  config: {
299
- params
433
+ params: qs.stringify(params, { encode: true })
300
434
  }
301
435
  }),
302
436
  providesTags: (result, _error, arg) => {
@@ -378,7 +512,8 @@ const documentApi = contentManagerApi.injectEndpoints({
378
512
  id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
379
513
  },
380
514
  { type: "Document", id: `${model}_LIST` },
381
- "Relations"
515
+ "Relations",
516
+ "RecentDocumentList"
382
517
  ];
383
518
  }
384
519
  }),
@@ -409,7 +544,9 @@ const documentApi = contentManagerApi.injectEndpoints({
409
544
  id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
410
545
  },
411
546
  "Relations",
412
- { type: "UidAvailability", id: model }
547
+ { type: "UidAvailability", id: model },
548
+ "RecentDocumentList",
549
+ "RecentDocumentList"
413
550
  ];
414
551
  },
415
552
  async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
@@ -439,7 +576,8 @@ const documentApi = contentManagerApi.injectEndpoints({
439
576
  {
440
577
  type: "Document",
441
578
  id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
442
- }
579
+ },
580
+ "RecentDocumentList"
443
581
  ];
444
582
  }
445
583
  }),
@@ -452,7 +590,10 @@ const documentApi = contentManagerApi.injectEndpoints({
452
590
  params
453
591
  }
454
592
  }),
455
- invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
593
+ invalidatesTags: (_res, _error, { model, documentIds }) => [
594
+ ...documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` })),
595
+ "RecentDocumentList"
596
+ ]
456
597
  })
457
598
  })
458
599
  });
@@ -475,8 +616,7 @@ const {
475
616
  useUnpublishManyDocumentsMutation
476
617
  } = documentApi;
477
618
  const buildValidParams = (query) => {
478
- if (!query)
479
- return query;
619
+ if (!query) return query;
480
620
  const { plugins: _, ...validQueryParams } = {
481
621
  ...query,
482
622
  ...Object.values(query?.plugins ?? {}).reduce(
@@ -484,9 +624,6 @@ const buildValidParams = (query) => {
484
624
  {}
485
625
  )
486
626
  };
487
- if ("_q" in validQueryParams) {
488
- validQueryParams._q = encodeURIComponent(validQueryParams._q);
489
- }
490
627
  return validQueryParams;
491
628
  };
492
629
  const isBaseQueryError = (error) => {
@@ -1127,6 +1264,7 @@ const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, co
1127
1264
  const useDocument = (args, opts) => {
1128
1265
  const { toggleNotification } = strapiAdmin.useNotification();
1129
1266
  const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
1267
+ const { formatMessage } = reactIntl.useIntl();
1130
1268
  const {
1131
1269
  currentData: data,
1132
1270
  isLoading: isLoadingDocument,
@@ -1136,12 +1274,27 @@ const useDocument = (args, opts) => {
1136
1274
  ...opts,
1137
1275
  skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
1138
1276
  });
1277
+ const document = data?.data;
1278
+ const meta = data?.meta;
1139
1279
  const {
1140
1280
  components,
1141
1281
  schema,
1142
1282
  schemas,
1143
1283
  isLoading: isLoadingSchema
1144
1284
  } = useContentTypeSchema(args.model);
1285
+ const isSingleType = schema?.kind === "singleType";
1286
+ const getTitle = (mainField) => {
1287
+ if (mainField !== "id" && document?.[mainField]) {
1288
+ return document[mainField];
1289
+ }
1290
+ if (isSingleType && schema?.info.displayName) {
1291
+ return schema.info.displayName;
1292
+ }
1293
+ return formatMessage({
1294
+ id: "content-manager.containers.untitled",
1295
+ defaultMessage: "Untitled"
1296
+ });
1297
+ };
1145
1298
  React__namespace.useEffect(() => {
1146
1299
  if (error) {
1147
1300
  toggleNotification({
@@ -1157,14 +1310,14 @@ const useDocument = (args, opts) => {
1157
1310
  return createYupSchema(schema.attributes, components);
1158
1311
  }, [schema, components]);
1159
1312
  const validate = React__namespace.useCallback(
1160
- (document) => {
1313
+ (document2) => {
1161
1314
  if (!validationSchema) {
1162
1315
  throw new Error(
1163
1316
  "There is no validation schema generated, this is likely due to the schema not being loaded yet."
1164
1317
  );
1165
1318
  }
1166
1319
  try {
1167
- validationSchema.validateSync(document, { abortEarly: false, strict: true });
1320
+ validationSchema.validateSync(document2, { abortEarly: false, strict: true });
1168
1321
  return null;
1169
1322
  } catch (error2) {
1170
1323
  if (error2 instanceof yup.ValidationError) {
@@ -1175,17 +1328,29 @@ const useDocument = (args, opts) => {
1175
1328
  },
1176
1329
  [validationSchema]
1177
1330
  );
1331
+ const getInitialFormValues = React__namespace.useCallback(
1332
+ (isCreatingDocument = false) => {
1333
+ if (!document && !isCreatingDocument && !isSingleType || !schema) {
1334
+ return void 0;
1335
+ }
1336
+ const form = document?.id ? document : createDefaultForm(schema, components);
1337
+ return transformDocument(schema, components)(form);
1338
+ },
1339
+ [document, isSingleType, schema, components]
1340
+ );
1178
1341
  const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
1179
1342
  const hasError = !!error;
1180
1343
  return {
1181
1344
  components,
1182
- document: data?.data,
1183
- meta: data?.meta,
1345
+ document,
1346
+ meta,
1184
1347
  isLoading,
1185
1348
  hasError,
1186
1349
  schema,
1187
1350
  schemas,
1188
- validate
1351
+ validate,
1352
+ getTitle,
1353
+ getInitialFormValues
1189
1354
  };
1190
1355
  };
1191
1356
  const useDoc = () => {
@@ -1686,7 +1851,7 @@ const useDocumentActions = () => {
1686
1851
  };
1687
1852
  };
1688
1853
  const ProtectedHistoryPage = React__namespace.lazy(
1689
- () => Promise.resolve().then(() => require("./History-BNvm2TK2.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
1854
+ () => Promise.resolve().then(() => require("./History-DTm8UCCQ.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
1690
1855
  );
1691
1856
  const routes$2 = [
1692
1857
  {
@@ -1699,7 +1864,7 @@ const routes$2 = [
1699
1864
  }
1700
1865
  ];
1701
1866
  const ProtectedPreviewPage = React__namespace.lazy(
1702
- () => Promise.resolve().then(() => require("./Preview-1cqLecKr.js")).then((mod) => ({ default: mod.ProtectedPreviewPage }))
1867
+ () => Promise.resolve().then(() => require("./Preview-Cxq-uI6D.js")).then((mod) => ({ default: mod.ProtectedPreviewPage }))
1703
1868
  );
1704
1869
  const routes$1 = [
1705
1870
  {
@@ -1712,31 +1877,31 @@ const routes$1 = [
1712
1877
  }
1713
1878
  ];
1714
1879
  const ProtectedEditViewPage = React.lazy(
1715
- () => Promise.resolve().then(() => require("./EditViewPage-0zrWXtMz.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
1880
+ () => Promise.resolve().then(() => require("./EditViewPage-D4yFJET6.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
1716
1881
  );
1717
1882
  const ProtectedListViewPage = React.lazy(
1718
- () => Promise.resolve().then(() => require("./ListViewPage-BEilNylQ.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
1883
+ () => Promise.resolve().then(() => require("./ListViewPage-DTuuxU3n.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
1719
1884
  );
1720
1885
  const ProtectedListConfiguration = React.lazy(
1721
- () => Promise.resolve().then(() => require("./ListConfigurationPage-B3FZwPHp.js")).then((mod) => ({
1886
+ () => Promise.resolve().then(() => require("./ListConfigurationPage-ysFMjKI3.js")).then((mod) => ({
1722
1887
  default: mod.ProtectedListConfiguration
1723
1888
  }))
1724
1889
  );
1725
1890
  const ProtectedEditConfigurationPage = React.lazy(
1726
- () => Promise.resolve().then(() => require("./EditConfigurationPage-DmruXqgR.js")).then((mod) => ({
1891
+ () => Promise.resolve().then(() => require("./EditConfigurationPage-Bl_U2JgH.js")).then((mod) => ({
1727
1892
  default: mod.ProtectedEditConfigurationPage
1728
1893
  }))
1729
1894
  );
1730
1895
  const ProtectedComponentConfigurationPage = React.lazy(
1731
- () => Promise.resolve().then(() => require("./ComponentConfigurationPage-Bmwd-G2q.js")).then((mod) => ({
1896
+ () => Promise.resolve().then(() => require("./ComponentConfigurationPage-DBSh-kET.js")).then((mod) => ({
1732
1897
  default: mod.ProtectedComponentConfigurationPage
1733
1898
  }))
1734
1899
  );
1735
1900
  const NoPermissions = React.lazy(
1736
- () => Promise.resolve().then(() => require("./NoPermissionsPage-yNOvz9XO.js")).then((mod) => ({ default: mod.NoPermissions }))
1901
+ () => Promise.resolve().then(() => require("./NoPermissionsPage-v7I599vC.js")).then((mod) => ({ default: mod.NoPermissions }))
1737
1902
  );
1738
1903
  const NoContentType = React.lazy(
1739
- () => Promise.resolve().then(() => require("./NoContentTypePage-BD2C-IMr.js")).then((mod) => ({ default: mod.NoContentType }))
1904
+ () => Promise.resolve().then(() => require("./NoContentTypePage-CL7VVeYs.js")).then((mod) => ({ default: mod.NoContentType }))
1740
1905
  );
1741
1906
  const CollectionTypePages = () => {
1742
1907
  const { collectionType } = reactRouterDom.useParams();
@@ -1881,6 +2046,11 @@ const DocumentActionButton = (action) => {
1881
2046
  ) : null
1882
2047
  ] });
1883
2048
  };
2049
+ const MenuItem = styledComponents.styled(designSystem.Menu.Item)`
2050
+ &:hover {
2051
+ background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
2052
+ }
2053
+ `;
1884
2054
  const DocumentActionsMenu = ({
1885
2055
  actions: actions2,
1886
2056
  children,
@@ -1939,11 +2109,13 @@ const DocumentActionsMenu = ({
1939
2109
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
1940
2110
  actions2.map((action) => {
1941
2111
  return /* @__PURE__ */ jsxRuntime.jsx(
1942
- designSystem.Menu.Item,
2112
+ MenuItem,
1943
2113
  {
1944
2114
  disabled: action.disabled,
1945
2115
  onSelect: handleClick(action),
1946
2116
  display: "block",
2117
+ isVariantDanger: action.variant === "danger",
2118
+ isDisabled: action.disabled,
1947
2119
  children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(
1948
2120
  designSystem.Flex,
1949
2121
  {
@@ -2099,6 +2271,7 @@ const PublishAction$1 = ({
2099
2271
  const { _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
2100
2272
  const isListView = reactRouterDom.useMatch(LIST_PATH) !== null;
2101
2273
  const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
2274
+ const { id } = reactRouterDom.useParams();
2102
2275
  const { formatMessage } = reactIntl.useIntl();
2103
2276
  const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
2104
2277
  const { publish } = useDocumentActions();
@@ -2201,10 +2374,12 @@ const PublishAction$1 = ({
2201
2374
  transformData(formValues)
2202
2375
  );
2203
2376
  if ("data" in res && collectionType !== SINGLE_TYPES) {
2204
- navigate({
2205
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
2206
- search: rawQuery
2207
- });
2377
+ if (id === "create") {
2378
+ navigate({
2379
+ pathname: `../${collectionType}/${model}/${res.data.documentId}`,
2380
+ search: rawQuery
2381
+ });
2382
+ }
2208
2383
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2209
2384
  setErrors(formatValidationErrors(res.error));
2210
2385
  }
@@ -2257,6 +2432,7 @@ const PublishAction$1 = ({
2257
2432
  };
2258
2433
  };
2259
2434
  PublishAction$1.type = "publish";
2435
+ PublishAction$1.position = "panel";
2260
2436
  const UpdateAction = ({
2261
2437
  activeTab,
2262
2438
  documentId,
@@ -2279,96 +2455,134 @@ const UpdateAction = ({
2279
2455
  const validate = strapiAdmin.useForm("UpdateAction", (state) => state.validate);
2280
2456
  const setErrors = strapiAdmin.useForm("UpdateAction", (state) => state.setErrors);
2281
2457
  const resetForm = strapiAdmin.useForm("PublishAction", ({ resetForm: resetForm2 }) => resetForm2);
2282
- return {
2283
- /**
2284
- * Disabled when:
2285
- * - the form is submitting
2286
- * - the document is not modified & we're not cloning (you can save a clone entity straight away)
2287
- * - the active tab is the published tab
2288
- */
2289
- disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
2290
- label: formatMessage({
2291
- id: "content-manager.containers.Edit.save",
2292
- defaultMessage: "Save"
2293
- }),
2294
- onClick: async () => {
2295
- setSubmitting(true);
2296
- try {
2297
- const { errors } = await validate(true, {
2298
- status: "draft"
2458
+ const handleUpdate = React__namespace.useCallback(async () => {
2459
+ setSubmitting(true);
2460
+ try {
2461
+ if (!modified) {
2462
+ return;
2463
+ }
2464
+ const { errors } = await validate(true, {
2465
+ status: "draft"
2466
+ });
2467
+ if (errors) {
2468
+ toggleNotification({
2469
+ type: "danger",
2470
+ message: formatMessage({
2471
+ id: "content-manager.validation.error",
2472
+ defaultMessage: "There are validation errors in your document. Please fix them before saving."
2473
+ })
2299
2474
  });
2300
- if (errors) {
2301
- toggleNotification({
2302
- type: "danger",
2303
- message: formatMessage({
2304
- id: "content-manager.validation.error",
2305
- defaultMessage: "There are validation errors in your document. Please fix them before saving."
2306
- })
2307
- });
2308
- return;
2309
- }
2310
- if (isCloning) {
2311
- const res = await clone(
2312
- {
2313
- model,
2314
- documentId: cloneMatch.params.origin,
2315
- params
2316
- },
2317
- transformData(document)
2318
- );
2319
- if ("data" in res) {
2320
- navigate(
2321
- {
2322
- pathname: `../${res.data.documentId}`,
2323
- search: rawQuery
2324
- },
2325
- { relative: "path" }
2326
- );
2327
- } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2328
- setErrors(formatValidationErrors(res.error));
2329
- }
2330
- } else if (documentId || collectionType === SINGLE_TYPES) {
2331
- const res = await update(
2475
+ return;
2476
+ }
2477
+ if (isCloning) {
2478
+ const res = await clone(
2479
+ {
2480
+ model,
2481
+ documentId: cloneMatch.params.origin,
2482
+ params
2483
+ },
2484
+ transformData(document)
2485
+ );
2486
+ if ("data" in res) {
2487
+ navigate(
2332
2488
  {
2333
- collectionType,
2334
- model,
2335
- documentId,
2336
- params
2489
+ pathname: `../${res.data.documentId}`,
2490
+ search: rawQuery
2337
2491
  },
2338
- transformData(document)
2492
+ { relative: "path" }
2339
2493
  );
2340
- if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2341
- setErrors(formatValidationErrors(res.error));
2342
- } else {
2343
- resetForm();
2344
- }
2494
+ } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2495
+ setErrors(formatValidationErrors(res.error));
2496
+ }
2497
+ } else if (documentId || collectionType === SINGLE_TYPES) {
2498
+ const res = await update(
2499
+ {
2500
+ collectionType,
2501
+ model,
2502
+ documentId,
2503
+ params
2504
+ },
2505
+ transformData(document)
2506
+ );
2507
+ if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2508
+ setErrors(formatValidationErrors(res.error));
2345
2509
  } else {
2346
- const res = await create(
2510
+ resetForm();
2511
+ }
2512
+ } else {
2513
+ const res = await create(
2514
+ {
2515
+ model,
2516
+ params
2517
+ },
2518
+ transformData(document)
2519
+ );
2520
+ if ("data" in res && collectionType !== SINGLE_TYPES) {
2521
+ navigate(
2347
2522
  {
2348
- model,
2349
- params
2523
+ pathname: `../${res.data.documentId}`,
2524
+ search: rawQuery
2350
2525
  },
2351
- transformData(document)
2526
+ { replace: true, relative: "path" }
2352
2527
  );
2353
- if ("data" in res && collectionType !== SINGLE_TYPES) {
2354
- navigate(
2355
- {
2356
- pathname: `../${res.data.documentId}`,
2357
- search: rawQuery
2358
- },
2359
- { replace: true, relative: "path" }
2360
- );
2361
- } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2362
- setErrors(formatValidationErrors(res.error));
2363
- }
2528
+ } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2529
+ setErrors(formatValidationErrors(res.error));
2364
2530
  }
2365
- } finally {
2366
- setSubmitting(false);
2367
2531
  }
2532
+ } finally {
2533
+ setSubmitting(false);
2368
2534
  }
2535
+ }, [
2536
+ clone,
2537
+ cloneMatch?.params.origin,
2538
+ collectionType,
2539
+ create,
2540
+ document,
2541
+ documentId,
2542
+ formatMessage,
2543
+ formatValidationErrors,
2544
+ isCloning,
2545
+ model,
2546
+ modified,
2547
+ navigate,
2548
+ params,
2549
+ rawQuery,
2550
+ resetForm,
2551
+ setErrors,
2552
+ setSubmitting,
2553
+ toggleNotification,
2554
+ update,
2555
+ validate
2556
+ ]);
2557
+ React__namespace.useEffect(() => {
2558
+ const handleKeyDown = (e) => {
2559
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
2560
+ e.preventDefault();
2561
+ handleUpdate();
2562
+ }
2563
+ };
2564
+ window.addEventListener("keydown", handleKeyDown);
2565
+ return () => {
2566
+ window.removeEventListener("keydown", handleKeyDown);
2567
+ };
2568
+ }, [handleUpdate]);
2569
+ return {
2570
+ /**
2571
+ * Disabled when:
2572
+ * - the form is submitting
2573
+ * - the document is not modified & we're not cloning (you can save a clone entity straight away)
2574
+ * - the active tab is the published tab
2575
+ */
2576
+ disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
2577
+ label: formatMessage({
2578
+ id: "global.save",
2579
+ defaultMessage: "Save"
2580
+ }),
2581
+ onClick: handleUpdate
2369
2582
  };
2370
2583
  };
2371
2584
  UpdateAction.type = "update";
2585
+ UpdateAction.position = "panel";
2372
2586
  const UNPUBLISH_DRAFT_OPTIONS = {
2373
2587
  KEEP: "keep",
2374
2588
  DISCARD: "discard"
@@ -2491,6 +2705,7 @@ const UnpublishAction$1 = ({
2491
2705
  };
2492
2706
  };
2493
2707
  UnpublishAction$1.type = "unpublish";
2708
+ UnpublishAction$1.position = "panel";
2494
2709
  const DiscardAction = ({
2495
2710
  activeTab,
2496
2711
  documentId,
@@ -2541,6 +2756,7 @@ const DiscardAction = ({
2541
2756
  };
2542
2757
  };
2543
2758
  DiscardAction.type = "discard";
2759
+ DiscardAction.position = "panel";
2544
2760
  const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
2545
2761
  const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
2546
2762
  const RelativeTime = React__namespace.forwardRef(
@@ -2598,12 +2814,18 @@ const DocumentStatus = ({ status = "draft", size = "S", ...restProps }) => {
2598
2814
  const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2599
2815
  const { formatMessage } = reactIntl.useIntl();
2600
2816
  const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
2817
+ const params = reactRouterDom.useParams();
2601
2818
  const title = isCreating ? formatMessage({
2602
2819
  id: "content-manager.containers.edit.title.new",
2603
2820
  defaultMessage: "Create an entry"
2604
2821
  }) : documentTitle;
2605
2822
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
2606
- /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.BackButton, {}),
2823
+ /* @__PURE__ */ jsxRuntime.jsx(
2824
+ strapiAdmin.BackButton,
2825
+ {
2826
+ fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
2827
+ }
2828
+ ),
2607
2829
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
2608
2830
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
2609
2831
  /* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
@@ -2654,7 +2876,7 @@ const HeaderToolbar = () => {
2654
2876
  meta: isCloning ? void 0 : meta,
2655
2877
  collectionType
2656
2878
  },
2657
- descriptions: plugins["content-manager"].apis.getDocumentActions(),
2879
+ descriptions: plugins["content-manager"].apis.getDocumentActions("header"),
2658
2880
  children: (actions2) => {
2659
2881
  const headerActions = actions2.filter((action) => {
2660
2882
  const positions = Array.isArray(action.position) ? action.position : [action.position];
@@ -2862,6 +3084,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
2862
3084
  };
2863
3085
  };
2864
3086
  ConfigureTheViewAction.type = "configure-the-view";
3087
+ ConfigureTheViewAction.position = "header";
2865
3088
  const EditTheModelAction = ({ model }) => {
2866
3089
  const navigate = reactRouterDom.useNavigate();
2867
3090
  const { formatMessage } = reactIntl.useIntl();
@@ -2878,6 +3101,7 @@ const EditTheModelAction = ({ model }) => {
2878
3101
  };
2879
3102
  };
2880
3103
  EditTheModelAction.type = "edit-the-model";
3104
+ EditTheModelAction.position = "header";
2881
3105
  const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
2882
3106
  const navigate = reactRouterDom.useNavigate();
2883
3107
  const { formatMessage } = reactIntl.useIntl();
@@ -2951,6 +3175,7 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
2951
3175
  };
2952
3176
  };
2953
3177
  DeleteAction$1.type = "delete";
3178
+ DeleteAction$1.position = ["header", "table-row"];
2954
3179
  const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
2955
3180
  const Panels = () => {
2956
3181
  const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
@@ -3013,7 +3238,7 @@ const ActionsPanelContent = () => {
3013
3238
  strapiAdmin.DescriptionComponentRenderer,
3014
3239
  {
3015
3240
  props,
3016
- descriptions: plugins["content-manager"].apis.getDocumentActions(),
3241
+ descriptions: plugins["content-manager"].apis.getDocumentActions("panel"),
3017
3242
  children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
3018
3243
  }
3019
3244
  ),
@@ -3071,7 +3296,7 @@ const ConfirmBulkActionDialog = ({
3071
3296
  ] })
3072
3297
  ] }) });
3073
3298
  };
3074
- const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
3299
+ const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
3075
3300
  const ConfirmDialogPublishAll = ({
3076
3301
  isOpen,
3077
3302
  onToggleDialog,
@@ -3120,7 +3345,7 @@ const ConfirmDialogPublishAll = ({
3120
3345
  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. "
3121
3346
  },
3122
3347
  {
3123
- b: BoldChunk$1,
3348
+ b: BoldChunk,
3124
3349
  count: countDraftRelations,
3125
3350
  entities: selectedEntries.length
3126
3351
  }
@@ -3159,6 +3384,16 @@ const ConfirmDialogPublishAll = ({
3159
3384
  const TypographyMaxWidth = styledComponents.styled(designSystem.Typography)`
3160
3385
  max-width: 300px;
3161
3386
  `;
3387
+ const TableComponent = styledComponents.styled(designSystem.RawTable)`
3388
+ width: 100%;
3389
+ table-layout: fixed;
3390
+ td:first-child {
3391
+ border-right: 1px solid ${({ theme }) => theme.colors.neutral150};
3392
+ }
3393
+ td:first-of-type {
3394
+ padding: ${({ theme }) => theme.spaces[4]};
3395
+ }
3396
+ `;
3162
3397
  const formatErrorMessages = (errors, parentKey, formatMessage) => {
3163
3398
  const messages = [];
3164
3399
  Object.entries(errors).forEach(([key, value]) => {
@@ -3263,7 +3498,7 @@ const SelectedEntriesTableContent = ({
3263
3498
  )
3264
3499
  ] }),
3265
3500
  /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Loading, {}),
3266
- /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Body, { children: rowsToDisplay.map((row, index2) => /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Row, { children: [
3501
+ /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Body, { children: rowsToDisplay.map((row) => /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Row, { children: [
3267
3502
  /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.CheckboxCell, { id: row.id }),
3268
3503
  /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row.id }) }),
3269
3504
  shouldDisplayMainField && /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row[mainField] }) }),
@@ -3290,18 +3525,10 @@ const SelectedEntriesTableContent = ({
3290
3525
  search: row.locale && `?plugins[i18n][locale]=${row.locale}`
3291
3526
  },
3292
3527
  state: { from: pathname },
3293
- label: formatMessage(
3294
- { id: "app.component.HelperPluginTable.edit", defaultMessage: "Edit {target}" },
3295
- {
3296
- target: formatMessage(
3297
- {
3298
- id: "content-manager.components.ListViewHelperPluginTable.row-line",
3299
- defaultMessage: "item line {number}"
3300
- },
3301
- { number: index2 + 1 }
3302
- )
3303
- }
3304
- ),
3528
+ label: formatMessage({
3529
+ id: "content-manager.bulk-publish.edit",
3530
+ defaultMessage: "Edit"
3531
+ }),
3305
3532
  target: "_blank",
3306
3533
  marginLeft: "auto",
3307
3534
  variant: "ghost",
@@ -3311,7 +3538,73 @@ const SelectedEntriesTableContent = ({
3311
3538
  ] }, row.id)) })
3312
3539
  ] });
3313
3540
  };
3314
- const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
3541
+ const PublicationStatusSummary = ({ count, icon, message }) => {
3542
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", flex: 1, gap: 3, children: [
3543
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
3544
+ icon,
3545
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: message })
3546
+ ] }),
3547
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: count })
3548
+ ] });
3549
+ };
3550
+ const PublicationStatusGrid = ({
3551
+ entriesReadyToPublishCount,
3552
+ entriesPublishedCount,
3553
+ entriesModifiedCount,
3554
+ entriesWithErrorsCount
3555
+ }) => {
3556
+ const { formatMessage } = reactIntl.useIntl();
3557
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { hasRadius: true, borderColor: "neutral150", children: /* @__PURE__ */ jsxRuntime.jsx(TableComponent, { colCount: 2, rowCount: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tbody, { children: [
3558
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
3559
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(
3560
+ PublicationStatusSummary,
3561
+ {
3562
+ count: entriesReadyToPublishCount,
3563
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
3564
+ message: formatMessage({
3565
+ id: "app.utils.ready-to-publish",
3566
+ defaultMessage: "Ready to publish"
3567
+ })
3568
+ }
3569
+ ) }),
3570
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(
3571
+ PublicationStatusSummary,
3572
+ {
3573
+ count: entriesPublishedCount,
3574
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
3575
+ message: formatMessage({
3576
+ id: "app.utils.already-published",
3577
+ defaultMessage: "Already published"
3578
+ })
3579
+ }
3580
+ ) })
3581
+ ] }),
3582
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
3583
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(
3584
+ PublicationStatusSummary,
3585
+ {
3586
+ count: entriesModifiedCount,
3587
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ArrowsCounterClockwise, { fill: "alternative600" }),
3588
+ message: formatMessage({
3589
+ id: "content-manager.bulk-publish.modified",
3590
+ defaultMessage: "Ready to publish changes"
3591
+ })
3592
+ }
3593
+ ) }),
3594
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(
3595
+ PublicationStatusSummary,
3596
+ {
3597
+ count: entriesWithErrorsCount,
3598
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.CrossCircle, { fill: "danger600" }),
3599
+ message: formatMessage({
3600
+ id: "content-manager.bulk-publish.waiting-for-action",
3601
+ defaultMessage: "Waiting for action"
3602
+ })
3603
+ }
3604
+ ) })
3605
+ ] })
3606
+ ] }) }) });
3607
+ };
3315
3608
  const SelectedEntriesModalContent = ({
3316
3609
  listViewSelectedEntries,
3317
3610
  toggleModal,
@@ -3370,7 +3663,6 @@ const SelectedEntriesModalContent = ({
3370
3663
  validationErrors: {}
3371
3664
  };
3372
3665
  }, [components, data, schema]);
3373
- const [publishedCount, setPublishedCount] = React__namespace.useState(0);
3374
3666
  const [isDialogOpen, setIsDialogOpen] = React__namespace.useState(false);
3375
3667
  const { publishMany: bulkPublishAction } = useDocumentActions();
3376
3668
  const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
@@ -3382,53 +3674,36 @@ const SelectedEntriesModalContent = ({
3382
3674
  const selectedEntriesWithErrorsCount = selectedEntries.filter(
3383
3675
  ({ documentId }) => validationErrors[documentId]
3384
3676
  ).length;
3385
- const selectedEntriesPublished = selectedEntries.filter(
3677
+ const selectedEntriesPublishedCount = selectedEntries.filter(
3386
3678
  ({ status }) => status === "published"
3387
3679
  ).length;
3388
- const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublished;
3680
+ const selectedEntriesModifiedCount = selectedEntries.filter(
3681
+ ({ status, documentId }) => status === "modified" && !validationErrors[documentId]
3682
+ ).length;
3683
+ const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublishedCount;
3389
3684
  const toggleDialog = () => setIsDialogOpen((prev) => !prev);
3390
3685
  const handleConfirmBulkPublish = async () => {
3391
3686
  toggleDialog();
3392
3687
  const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
3393
3688
  if (!("error" in res)) {
3394
- setPublishedCount(res.count);
3395
3689
  const unpublishedEntries = rows.filter((row) => {
3396
3690
  return !entriesToPublish.includes(row.documentId);
3397
3691
  });
3398
3692
  setListViewSelectedDocuments(unpublishedEntries);
3399
3693
  }
3400
3694
  };
3401
- const getFormattedCountMessage = () => {
3402
- if (publishedCount) {
3403
- return formatMessage(
3404
- {
3405
- id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
3406
- 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."
3407
- },
3408
- {
3409
- publishedCount,
3410
- withErrorsCount: selectedEntriesWithErrorsCount,
3411
- b: BoldChunk
3412
- }
3413
- );
3414
- }
3415
- return formatMessage(
3416
- {
3417
- id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
3418
- 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."
3419
- },
3420
- {
3421
- readyToPublishCount: selectedEntriesWithNoErrorsCount,
3422
- withErrorsCount: selectedEntriesWithErrorsCount,
3423
- alreadyPublishedCount: selectedEntriesPublished,
3424
- b: BoldChunk
3425
- }
3426
- );
3427
- };
3428
3695
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3429
3696
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
3430
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
3431
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsx(
3697
+ /* @__PURE__ */ jsxRuntime.jsx(
3698
+ PublicationStatusGrid,
3699
+ {
3700
+ entriesReadyToPublishCount: selectedEntriesWithNoErrorsCount - selectedEntriesModifiedCount,
3701
+ entriesPublishedCount: selectedEntriesPublishedCount,
3702
+ entriesModifiedCount: selectedEntriesModifiedCount,
3703
+ entriesWithErrorsCount: selectedEntriesWithErrorsCount
3704
+ }
3705
+ ),
3706
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 7, children: /* @__PURE__ */ jsxRuntime.jsx(
3432
3707
  SelectedEntriesTableContent,
3433
3708
  {
3434
3709
  isPublishing: isSubmittingForm,
@@ -3449,7 +3724,7 @@ const SelectedEntriesModalContent = ({
3449
3724
  designSystem.Button,
3450
3725
  {
3451
3726
  onClick: toggleDialog,
3452
- disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
3727
+ disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublishedCount === selectedEntries.length || isLoading,
3453
3728
  loading: isSubmittingForm,
3454
3729
  children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
3455
3730
  }
@@ -3475,8 +3750,7 @@ const PublishAction = ({ documents, model }) => {
3475
3750
  const refetchList = () => {
3476
3751
  contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
3477
3752
  };
3478
- if (!showPublishButton)
3479
- return null;
3753
+ if (!showPublishButton) return null;
3480
3754
  return {
3481
3755
  actionType: "publish",
3482
3756
  variant: "tertiary",
@@ -3544,8 +3818,7 @@ const DeleteAction = ({ documents, model }) => {
3544
3818
  selectRow([]);
3545
3819
  }
3546
3820
  };
3547
- if (!hasDeletePermission)
3548
- return null;
3821
+ if (!hasDeletePermission) return null;
3549
3822
  return {
3550
3823
  variant: "danger-light",
3551
3824
  label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
@@ -3594,8 +3867,7 @@ const UnpublishAction = ({ documents, model }) => {
3594
3867
  }
3595
3868
  };
3596
3869
  const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
3597
- if (!showUnpublishButton)
3598
- return null;
3870
+ if (!showUnpublishButton) return null;
3599
3871
  return {
3600
3872
  variant: "tertiary",
3601
3873
  label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
@@ -3700,7 +3972,7 @@ const TableActions = ({ document }) => {
3700
3972
  strapiAdmin.DescriptionComponentRenderer,
3701
3973
  {
3702
3974
  props,
3703
- descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
3975
+ descriptions: plugins["content-manager"].apis.getDocumentActions("table-row").filter((action) => action.name !== "PublishAction"),
3704
3976
  children: (actions2) => {
3705
3977
  const tableRowActions = actions2.filter((action) => {
3706
3978
  const positions = Array.isArray(action.position) ? action.position : [action.position];
@@ -3759,6 +4031,7 @@ const EditAction = ({ documentId }) => {
3759
4031
  };
3760
4032
  };
3761
4033
  EditAction.type = "edit";
4034
+ EditAction.position = "table-row";
3762
4035
  const StyledPencil = styledComponents.styled(Icons.Pencil)`
3763
4036
  path {
3764
4037
  fill: currentColor;
@@ -3835,6 +4108,7 @@ const CloneAction = ({ model, documentId }) => {
3835
4108
  };
3836
4109
  };
3837
4110
  CloneAction.type = "clone";
4111
+ CloneAction.position = "table-row";
3838
4112
  const StyledDuplicate = styledComponents.styled(Icons.Duplicate)`
3839
4113
  path {
3840
4114
  fill: currentColor;
@@ -3921,7 +4195,14 @@ class ContentManagerPlugin {
3921
4195
  addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
3922
4196
  addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
3923
4197
  getBulkActions: () => this.bulkActions,
3924
- getDocumentActions: () => this.documentActions,
4198
+ getDocumentActions: (position) => {
4199
+ if (position) {
4200
+ return this.documentActions.filter(
4201
+ (action) => action.position == void 0 || [action.position].flat().includes(position)
4202
+ );
4203
+ }
4204
+ return this.documentActions;
4205
+ },
3925
4206
  getEditViewSidePanels: () => this.editViewSidePanels,
3926
4207
  getHeaderActions: () => this.headerActions
3927
4208
  }
@@ -3931,10 +4212,8 @@ class ContentManagerPlugin {
3931
4212
  const getPrintableType = (value) => {
3932
4213
  const nativeType = typeof value;
3933
4214
  if (nativeType === "object") {
3934
- if (value === null)
3935
- return "null";
3936
- if (Array.isArray(value))
3937
- return "array";
4215
+ if (value === null) return "null";
4216
+ if (Array.isArray(value)) return "array";
3938
4217
  if (value instanceof Object && value.constructor.name !== "Object") {
3939
4218
  return value.constructor.name;
3940
4219
  }
@@ -3945,17 +4224,27 @@ const HistoryAction = ({ model, document }) => {
3945
4224
  const { formatMessage } = reactIntl.useIntl();
3946
4225
  const [{ query }] = strapiAdmin.useQueryParams();
3947
4226
  const navigate = reactRouterDom.useNavigate();
4227
+ const { trackUsage } = strapiAdmin.useTracking();
4228
+ const { pathname } = reactRouterDom.useLocation();
3948
4229
  const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
3949
4230
  if (!window.strapi.features.isEnabled("cms-content-history")) {
3950
4231
  return null;
3951
4232
  }
4233
+ const handleOnClick = () => {
4234
+ const destination = { pathname: "history", search: pluginsQueryParams };
4235
+ trackUsage("willNavigate", {
4236
+ from: pathname,
4237
+ to: `${pathname}/${destination.pathname}`
4238
+ });
4239
+ navigate(destination);
4240
+ };
3952
4241
  return {
3953
4242
  icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
3954
4243
  label: formatMessage({
3955
4244
  id: "content-manager.history.document-action",
3956
4245
  defaultMessage: "Content History"
3957
4246
  }),
3958
- onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
4247
+ onClick: handleOnClick,
3959
4248
  disabled: (
3960
4249
  /**
3961
4250
  * The user is creating a new document.
@@ -3977,6 +4266,7 @@ const HistoryAction = ({ model, document }) => {
3977
4266
  };
3978
4267
  };
3979
4268
  HistoryAction.type = "history";
4269
+ HistoryAction.position = "header";
3980
4270
  const historyAdmin = {
3981
4271
  bootstrap(app) {
3982
4272
  const { addDocumentAction } = app.getPlugin("content-manager").apis;
@@ -4039,10 +4329,18 @@ const previewApi = contentManagerApi.injectEndpoints({
4039
4329
  })
4040
4330
  });
4041
4331
  const { useGetPreviewUrlQuery } = previewApi;
4332
+ const ConditionalTooltip = ({ isShown, label, children }) => {
4333
+ if (isShown) {
4334
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { label, children });
4335
+ }
4336
+ return children;
4337
+ };
4042
4338
  const PreviewSidePanel = ({ model, documentId, document }) => {
4043
4339
  const { formatMessage } = reactIntl.useIntl();
4044
4340
  const { trackUsage } = strapiAdmin.useTracking();
4341
+ const { pathname } = reactRouterDom.useLocation();
4045
4342
  const [{ query }] = strapiAdmin.useQueryParams();
4343
+ const isModified = strapiAdmin.useForm("PreviewSidePanel", (state) => state.modified);
4046
4344
  const { data, error } = useGetPreviewUrlQuery({
4047
4345
  params: {
4048
4346
  contentType: model
@@ -4056,33 +4354,43 @@ const PreviewSidePanel = ({ model, documentId, document }) => {
4056
4354
  if (!data?.data?.url || error) {
4057
4355
  return null;
4058
4356
  }
4059
- const handleClick = () => {
4060
- trackUsage("willOpenPreview");
4357
+ const trackNavigation = () => {
4358
+ const destinationPathname = pathname.replace(/\/$/, "") + "/preview";
4359
+ trackUsage("willNavigate", { from: pathname, to: destinationPathname });
4061
4360
  };
4062
4361
  return {
4063
4362
  title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
4064
- content: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(
4065
- designSystem.Button,
4363
+ content: /* @__PURE__ */ jsxRuntime.jsx(
4364
+ ConditionalTooltip,
4066
4365
  {
4067
- variant: "tertiary",
4068
- tag: reactRouterDom.Link,
4069
- to: { pathname: "preview", search: qs.stringify(query, { encode: false }) },
4070
- onClick: handleClick,
4071
- flex: "auto",
4072
- children: formatMessage({
4073
- id: "content-manager.preview.panel.button",
4074
- defaultMessage: "Open preview"
4075
- })
4366
+ label: formatMessage({
4367
+ id: "content-manager.preview.panel.button-disabled-tooltip",
4368
+ defaultMessage: "Please save to open the preview"
4369
+ }),
4370
+ isShown: isModified,
4371
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { cursor: "not-allowed", width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(
4372
+ designSystem.Button,
4373
+ {
4374
+ variant: "tertiary",
4375
+ tag: reactRouterDom.Link,
4376
+ to: { pathname: "preview", search: qs.stringify(query, { encode: false }) },
4377
+ onClick: trackNavigation,
4378
+ width: "100%",
4379
+ disabled: isModified,
4380
+ pointerEvents: isModified ? "none" : void 0,
4381
+ tabIndex: isModified ? -1 : void 0,
4382
+ children: formatMessage({
4383
+ id: "content-manager.preview.panel.button",
4384
+ defaultMessage: "Open preview"
4385
+ })
4386
+ }
4387
+ ) })
4076
4388
  }
4077
- ) })
4389
+ )
4078
4390
  };
4079
4391
  };
4080
- const FEATURE_ID = "preview";
4081
4392
  const previewAdmin = {
4082
4393
  bootstrap(app) {
4083
- if (!window.strapi.future.isEnabled(FEATURE_ID)) {
4084
- return;
4085
- }
4086
4394
  const contentManagerPluginApis = app.getPlugin("content-manager").apis;
4087
4395
  contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
4088
4396
  }
@@ -4106,7 +4414,7 @@ const index = {
4106
4414
  app.router.addRoute({
4107
4415
  path: "content-manager/*",
4108
4416
  lazy: async () => {
4109
- const { Layout } = await Promise.resolve().then(() => require("./layout-Cj_1EKbm.js"));
4417
+ const { Layout } = await Promise.resolve().then(() => require("./layout-Cl0NhlQB.js"));
4110
4418
  return {
4111
4419
  Component: Layout
4112
4420
  };
@@ -4126,7 +4434,7 @@ const index = {
4126
4434
  async registerTrads({ locales }) {
4127
4435
  const importedTrads = await Promise.all(
4128
4436
  locales.map((locale) => {
4129
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-CHOp_xJv.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-9K52xZIr.js")), "./translations/eu.json": () => Promise.resolve().then(() => require("./eu-VDH-3ovk.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-B2Kyv8Z9.js")), "./translations/gu.json": () => Promise.resolve().then(() => require("./gu-BRmF601H.js")), "./translations/hi.json": () => Promise.resolve().then(() => require("./hi-CCJBptSq.js")), "./translations/hu.json": () => Promise.resolve().then(() => require("./hu-sNV_yLYy.js")), "./translations/id.json": () => Promise.resolve().then(() => require("./id-B5Ser98A.js")), "./translations/it.json": () => Promise.resolve().then(() => require("./it-DkBIs7vD.js")), "./translations/ja.json": () => Promise.resolve().then(() => require("./ja-7sfIbjxE.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-woFZPmLk.js")), "./translations/ml.json": () => Promise.resolve().then(() => require("./ml-C2W8N8k1.js")), "./translations/ms.json": () => Promise.resolve().then(() => require("./ms-BuFotyP_.js")), "./translations/nl.json": () => Promise.resolve().then(() => require("./nl-bbEOHChV.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-uzwG-hk7.js")), "./translations/pt-BR.json": () => Promise.resolve().then(() => require("./pt-BR-BiOz37D9.js")), "./translations/pt.json": () => Promise.resolve().then(() => require("./pt-CeXQuq50.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BT3ybNny.js")), "./translations/sa.json": () => Promise.resolve().then(() => require("./sa-CcvkYInH.js")), "./translations/sk.json": () => Promise.resolve().then(() => require("./sk-CvY09Xjv.js")), "./translations/sv.json": () => Promise.resolve().then(() => require("./sv-MYDuzgvT.js")), "./translations/th.json": () => Promise.resolve().then(() => require("./th-D9_GfAjc.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-D9UH-O_R.js")), "./translations/uk.json": () => Promise.resolve().then(() => require("./uk-C8EiqJY7.js")), "./translations/vi.json": () => Promise.resolve().then(() => require("./vi-CJlYDheJ.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-9kOncHGw.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CQQfszqR.js")) }), `./translations/${locale}.json`).then(({ default: data }) => {
4437
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-BR48D_RH.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-9K52xZIr.js")), "./translations/eu.json": () => Promise.resolve().then(() => require("./eu-VDH-3ovk.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-C43IbhA_.js")), "./translations/gu.json": () => Promise.resolve().then(() => require("./gu-BRmF601H.js")), "./translations/hi.json": () => Promise.resolve().then(() => require("./hi-CCJBptSq.js")), "./translations/hu.json": () => Promise.resolve().then(() => require("./hu-sNV_yLYy.js")), "./translations/id.json": () => Promise.resolve().then(() => require("./id-B5Ser98A.js")), "./translations/it.json": () => Promise.resolve().then(() => require("./it-DkBIs7vD.js")), "./translations/ja.json": () => Promise.resolve().then(() => require("./ja-7sfIbjxE.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-woFZPmLk.js")), "./translations/ml.json": () => Promise.resolve().then(() => require("./ml-C2W8N8k1.js")), "./translations/ms.json": () => Promise.resolve().then(() => require("./ms-BuFotyP_.js")), "./translations/nl.json": () => Promise.resolve().then(() => require("./nl-bbEOHChV.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-uzwG-hk7.js")), "./translations/pt-BR.json": () => Promise.resolve().then(() => require("./pt-BR-BiOz37D9.js")), "./translations/pt.json": () => Promise.resolve().then(() => require("./pt-CeXQuq50.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BT3ybNny.js")), "./translations/sa.json": () => Promise.resolve().then(() => require("./sa-CcvkYInH.js")), "./translations/sk.json": () => Promise.resolve().then(() => require("./sk-CvY09Xjv.js")), "./translations/sv.json": () => Promise.resolve().then(() => require("./sv-MYDuzgvT.js")), "./translations/th.json": () => Promise.resolve().then(() => require("./th-D9_GfAjc.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-D9UH-O_R.js")), "./translations/uk.json": () => Promise.resolve().then(() => require("./uk-C8EiqJY7.js")), "./translations/vi.json": () => Promise.resolve().then(() => require("./vi-CJlYDheJ.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-9kOncHGw.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CQQfszqR.js")) }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
4130
4438
  return {
4131
4439
  data: prefixPluginTranslations(data, PLUGIN_ID),
4132
4440
  locale
@@ -4148,7 +4456,6 @@ exports.CLONE_PATH = CLONE_PATH;
4148
4456
  exports.COLLECTION_TYPES = COLLECTION_TYPES;
4149
4457
  exports.CREATOR_FIELDS = CREATOR_FIELDS;
4150
4458
  exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
4151
- exports.DOCUMENT_META_FIELDS = DOCUMENT_META_FIELDS;
4152
4459
  exports.DocumentRBAC = DocumentRBAC;
4153
4460
  exports.DocumentStatus = DocumentStatus;
4154
4461
  exports.HOOKS = HOOKS;
@@ -4165,13 +4472,17 @@ exports.checkIfAttributeIsDisplayable = checkIfAttributeIsDisplayable;
4165
4472
  exports.contentManagerApi = contentManagerApi;
4166
4473
  exports.convertEditLayoutToFieldLayouts = convertEditLayoutToFieldLayouts;
4167
4474
  exports.convertListLayoutToFieldLayouts = convertListLayoutToFieldLayouts;
4475
+ exports.createDefaultForm = createDefaultForm;
4168
4476
  exports.createYupSchema = createYupSchema;
4169
4477
  exports.extractContentTypeComponents = extractContentTypeComponents;
4170
4478
  exports.getDisplayName = getDisplayName;
4171
4479
  exports.getMainField = getMainField;
4172
4480
  exports.getTranslation = getTranslation;
4173
4481
  exports.index = index;
4482
+ exports.prepareTempKeys = prepareTempKeys;
4483
+ exports.removeFieldsThatDontExistOnSchema = removeFieldsThatDontExistOnSchema;
4174
4484
  exports.setInitialData = setInitialData;
4485
+ exports.transformDocument = transformDocument;
4175
4486
  exports.useContentManagerContext = useContentManagerContext;
4176
4487
  exports.useContentTypeSchema = useContentTypeSchema;
4177
4488
  exports.useDoc = useDoc;
@@ -4186,4 +4497,4 @@ exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuer
4186
4497
  exports.useGetInitialDataQuery = useGetInitialDataQuery;
4187
4498
  exports.useGetPreviewUrlQuery = useGetPreviewUrlQuery;
4188
4499
  exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
4189
- //# sourceMappingURL=index-Cg4RLIAw.js.map
4500
+ //# sourceMappingURL=index-DQsvBb_N.js.map