@strapi/content-manager 0.0.0-experimental.545ccead2ee1717bbc7ab950455dbb0ddb9924a3 → 0.0.0-experimental.55dabf6295dfb7987fcab8a6b40212555f0e684c

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 (125) hide show
  1. package/dist/_chunks/{ComponentConfigurationPage-B1bIXVuX.mjs → ComponentConfigurationPage-DfFSZQxe.mjs} +3 -3
  2. package/dist/_chunks/{ComponentConfigurationPage-B1bIXVuX.mjs.map → ComponentConfigurationPage-DfFSZQxe.mjs.map} +1 -1
  3. package/dist/_chunks/{ComponentConfigurationPage-Bqgx7Mes.js → ComponentConfigurationPage-FqfsxQ1j.js} +3 -3
  4. package/dist/_chunks/{ComponentConfigurationPage-Bqgx7Mes.js.map → ComponentConfigurationPage-FqfsxQ1j.js.map} +1 -1
  5. package/dist/_chunks/{EditConfigurationPage-BFEwvdMW.js → EditConfigurationPage-Cn0e8t3I.js} +3 -3
  6. package/dist/_chunks/{EditConfigurationPage-BFEwvdMW.js.map → EditConfigurationPage-Cn0e8t3I.js.map} +1 -1
  7. package/dist/_chunks/{EditConfigurationPage-ZO0vOO8q.mjs → EditConfigurationPage-DdPNAbl3.mjs} +3 -3
  8. package/dist/_chunks/{EditConfigurationPage-ZO0vOO8q.mjs.map → EditConfigurationPage-DdPNAbl3.mjs.map} +1 -1
  9. package/dist/_chunks/{EditViewPage-DlLEyUL6.mjs → EditViewPage-B82x_x1b.mjs} +30 -9
  10. package/dist/_chunks/EditViewPage-B82x_x1b.mjs.map +1 -0
  11. package/dist/_chunks/{EditViewPage-DA95Ha6J.js → EditViewPage-DlxEHhUt.js} +30 -9
  12. package/dist/_chunks/EditViewPage-DlxEHhUt.js.map +1 -0
  13. package/dist/_chunks/{Field-CnK8dO8N.js → Field-COL25JiC.js} +179 -107
  14. package/dist/_chunks/Field-COL25JiC.js.map +1 -0
  15. package/dist/_chunks/{Field-Dq7bDnuh.mjs → Field-DufHXW17.mjs} +177 -105
  16. package/dist/_chunks/Field-DufHXW17.mjs.map +1 -0
  17. package/dist/_chunks/{Form-BpiR4piS.js → Form-BssUwrTO.js} +36 -17
  18. package/dist/_chunks/Form-BssUwrTO.js.map +1 -0
  19. package/dist/_chunks/{Form-B_JE0dbz.mjs → Form-u_kAOhwB.mjs} +36 -17
  20. package/dist/_chunks/Form-u_kAOhwB.mjs.map +1 -0
  21. package/dist/_chunks/{History-DdIstl8b.js → History-C9t9UqpO.js} +40 -17
  22. package/dist/_chunks/History-C9t9UqpO.js.map +1 -0
  23. package/dist/_chunks/{History-CBNGU7a-.mjs → History-DRwA3oMM.mjs} +41 -18
  24. package/dist/_chunks/History-DRwA3oMM.mjs.map +1 -0
  25. package/dist/_chunks/{ListConfigurationPage-DkKRparB.js → ListConfigurationPage-BXYPohh-.js} +14 -4
  26. package/dist/_chunks/ListConfigurationPage-BXYPohh-.js.map +1 -0
  27. package/dist/_chunks/{ListConfigurationPage-5dr4qpue.mjs → ListConfigurationPage-BxfQJzPk.mjs} +14 -4
  28. package/dist/_chunks/ListConfigurationPage-BxfQJzPk.mjs.map +1 -0
  29. package/dist/_chunks/{ListViewPage-DecLrYV6.mjs → ListViewPage-CELx2ysp.mjs} +47 -38
  30. package/dist/_chunks/ListViewPage-CELx2ysp.mjs.map +1 -0
  31. package/dist/_chunks/{ListViewPage-wE0lXqoD.js → ListViewPage-D2VD8Szg.js} +49 -40
  32. package/dist/_chunks/ListViewPage-D2VD8Szg.js.map +1 -0
  33. package/dist/_chunks/{NoContentTypePage-DEKR6tf9.js → NoContentTypePage-BV9IjJSM.js} +2 -2
  34. package/dist/_chunks/{NoContentTypePage-DEKR6tf9.js.map → NoContentTypePage-BV9IjJSM.js.map} +1 -1
  35. package/dist/_chunks/{NoContentTypePage-CiIcfYsd.mjs → NoContentTypePage-DtJ9jcfk.mjs} +2 -2
  36. package/dist/_chunks/{NoContentTypePage-CiIcfYsd.mjs.map → NoContentTypePage-DtJ9jcfk.mjs.map} +1 -1
  37. package/dist/_chunks/{NoPermissionsPage-CM5UD8ee.mjs → NoPermissionsPage-DWleVYK7.mjs} +2 -2
  38. package/dist/_chunks/{NoPermissionsPage-CM5UD8ee.mjs.map → NoPermissionsPage-DWleVYK7.mjs.map} +1 -1
  39. package/dist/_chunks/{NoPermissionsPage-DmNfF2Bb.js → NoPermissionsPage-Dp8NpF9I.js} +2 -2
  40. package/dist/_chunks/{NoPermissionsPage-DmNfF2Bb.js.map → NoPermissionsPage-Dp8NpF9I.js.map} +1 -1
  41. package/dist/_chunks/{Relations-Dqz0C1fz.mjs → Relations-BTcf5xaw.mjs} +33 -24
  42. package/dist/_chunks/Relations-BTcf5xaw.mjs.map +1 -0
  43. package/dist/_chunks/{Relations-L0xYRoSQ.js → Relations-DR7EUgyC.js} +33 -24
  44. package/dist/_chunks/Relations-DR7EUgyC.js.map +1 -0
  45. package/dist/_chunks/{en-uOUIxfcQ.js → en-Bm0D0IWz.js} +13 -12
  46. package/dist/_chunks/{en-uOUIxfcQ.js.map → en-Bm0D0IWz.js.map} +1 -1
  47. package/dist/_chunks/{en-BrCTWlZv.mjs → en-DKV44jRb.mjs} +13 -12
  48. package/dist/_chunks/{en-BrCTWlZv.mjs.map → en-DKV44jRb.mjs.map} +1 -1
  49. package/dist/_chunks/{index-DyvUPg1a.js → index-BdMf2lfT.js} +708 -526
  50. package/dist/_chunks/index-BdMf2lfT.js.map +1 -0
  51. package/dist/_chunks/{index-BSn97i8U.mjs → index-wnqzm4Q8.mjs} +728 -546
  52. package/dist/_chunks/index-wnqzm4Q8.mjs.map +1 -0
  53. package/dist/_chunks/{layout-DPaHUusj.mjs → layout-2CfjL0T9.mjs} +22 -9
  54. package/dist/_chunks/layout-2CfjL0T9.mjs.map +1 -0
  55. package/dist/_chunks/{layout-TPqF2oJ5.js → layout-B2MyZU-_.js} +21 -8
  56. package/dist/_chunks/layout-B2MyZU-_.js.map +1 -0
  57. package/dist/_chunks/{relations-BWYS9gkn.js → relations-BH7JJGGe.js} +2 -2
  58. package/dist/_chunks/{relations-BWYS9gkn.js.map → relations-BH7JJGGe.js.map} +1 -1
  59. package/dist/_chunks/{relations-Ck7-ecDT.mjs → relations-C0w0GcXi.mjs} +2 -2
  60. package/dist/_chunks/{relations-Ck7-ecDT.mjs.map → relations-C0w0GcXi.mjs.map} +1 -1
  61. package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
  62. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
  63. package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
  64. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
  65. package/dist/admin/index.js +2 -1
  66. package/dist/admin/index.js.map +1 -1
  67. package/dist/admin/index.mjs +5 -4
  68. package/dist/admin/src/exports.d.ts +1 -1
  69. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  70. package/dist/admin/src/hooks/useDocument.d.ts +32 -1
  71. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
  72. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
  73. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +4 -48
  74. package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
  75. package/dist/admin/src/services/api.d.ts +1 -1
  76. package/dist/admin/src/services/components.d.ts +2 -2
  77. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  78. package/dist/admin/src/services/documents.d.ts +19 -17
  79. package/dist/admin/src/services/init.d.ts +1 -1
  80. package/dist/admin/src/services/relations.d.ts +2 -2
  81. package/dist/admin/src/services/uid.d.ts +3 -3
  82. package/dist/admin/src/utils/validation.d.ts +4 -1
  83. package/dist/server/index.js +201 -118
  84. package/dist/server/index.js.map +1 -1
  85. package/dist/server/index.mjs +202 -119
  86. package/dist/server/index.mjs.map +1 -1
  87. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  88. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  89. package/dist/server/src/controllers/uid.d.ts.map +1 -1
  90. package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
  91. package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
  92. package/dist/server/src/history/services/history.d.ts.map +1 -1
  93. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  94. package/dist/server/src/history/services/utils.d.ts +2 -1
  95. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  96. package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
  97. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  98. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  99. package/dist/server/src/services/permission-checker.d.ts.map +1 -1
  100. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  101. package/dist/shared/contracts/collection-types.d.ts +3 -1
  102. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  103. package/package.json +12 -12
  104. package/dist/_chunks/EditViewPage-DA95Ha6J.js.map +0 -1
  105. package/dist/_chunks/EditViewPage-DlLEyUL6.mjs.map +0 -1
  106. package/dist/_chunks/Field-CnK8dO8N.js.map +0 -1
  107. package/dist/_chunks/Field-Dq7bDnuh.mjs.map +0 -1
  108. package/dist/_chunks/Form-B_JE0dbz.mjs.map +0 -1
  109. package/dist/_chunks/Form-BpiR4piS.js.map +0 -1
  110. package/dist/_chunks/History-CBNGU7a-.mjs.map +0 -1
  111. package/dist/_chunks/History-DdIstl8b.js.map +0 -1
  112. package/dist/_chunks/ListConfigurationPage-5dr4qpue.mjs.map +0 -1
  113. package/dist/_chunks/ListConfigurationPage-DkKRparB.js.map +0 -1
  114. package/dist/_chunks/ListViewPage-DecLrYV6.mjs.map +0 -1
  115. package/dist/_chunks/ListViewPage-wE0lXqoD.js.map +0 -1
  116. package/dist/_chunks/Relations-Dqz0C1fz.mjs.map +0 -1
  117. package/dist/_chunks/Relations-L0xYRoSQ.js.map +0 -1
  118. package/dist/_chunks/index-BSn97i8U.mjs.map +0 -1
  119. package/dist/_chunks/index-DyvUPg1a.js.map +0 -1
  120. package/dist/_chunks/layout-DPaHUusj.mjs.map +0 -1
  121. package/dist/_chunks/layout-TPqF2oJ5.js.map +0 -1
  122. package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
  123. package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
  124. package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
  125. package/strapi-server.js +0 -3
@@ -1,16 +1,16 @@
1
- import { CrossCircle, More, WarningCircle, ListPlus, Pencil, Trash, Check, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
1
+ import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check, CrossCircle, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
2
2
  import { jsx, Fragment, jsxs } from "react/jsx-runtime";
3
- import { useStrapiApp, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useQueryParams, useTracking, useForm, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
3
+ import { useStrapiApp, createContext, useQueryParams, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useForm, useTracking, useGuidedTour, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
4
4
  import * as React from "react";
5
5
  import { lazy } from "react";
6
- import { Button, Menu, VisuallyHidden, Flex, Box, Typography, Dialog, Modal, Radio, Status, SingleSelect, SingleSelectOption, Loader, IconButton, Tooltip, LinkButton } from "@strapi/design-system";
6
+ import { Button, Menu, VisuallyHidden, Flex, Typography, Dialog, Modal, Radio, Status, Box, SingleSelect, SingleSelectOption, IconButton, Loader, Tooltip, LinkButton } from "@strapi/design-system";
7
7
  import { useIntl } from "react-intl";
8
- import { useParams, Navigate, useNavigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
9
- import { styled } from "styled-components";
8
+ import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
10
9
  import * as yup from "yup";
11
10
  import { ValidationError } from "yup";
12
11
  import pipe from "lodash/fp/pipe";
13
12
  import { intervalToDuration, isPast } from "date-fns";
13
+ import { styled } from "styled-components";
14
14
  import { stringify } from "qs";
15
15
  import { createSlice, combineReducers } from "@reduxjs/toolkit";
16
16
  const __variableDynamicImportRuntimeHelper = (glob, path) => {
@@ -100,6 +100,7 @@ const DocumentRBAC = ({ children, permissions }) => {
100
100
  if (!slug) {
101
101
  throw new Error("Cannot find the slug param in the URL");
102
102
  }
103
+ const [{ rawQuery }] = useQueryParams();
103
104
  const userPermissions = useAuth("DocumentRBAC", (state) => state.permissions);
104
105
  const contentTypePermissions = React.useMemo(() => {
105
106
  const contentTypePermissions2 = userPermissions.filter(
@@ -110,7 +111,14 @@ const DocumentRBAC = ({ children, permissions }) => {
110
111
  return { ...acc, [action]: [permission] };
111
112
  }, {});
112
113
  }, [slug, userPermissions]);
113
- const { isLoading, allowedActions } = useRBAC(contentTypePermissions, permissions ?? void 0);
114
+ const { isLoading, allowedActions } = useRBAC(
115
+ contentTypePermissions,
116
+ permissions ?? void 0,
117
+ // TODO: useRBAC context should be typed and built differently
118
+ // We are passing raw query as context to the hook so that it can
119
+ // rely on the locale provided from DocumentRBAC for its permission calculations.
120
+ rawQuery
121
+ );
114
122
  const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
115
123
  const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
116
124
  const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
@@ -158,7 +166,8 @@ const contentManagerApi = adminApi.enhanceEndpoints({
158
166
  "Document",
159
167
  "InitialData",
160
168
  "HistoryVersion",
161
- "Relations"
169
+ "Relations",
170
+ "UidAvailability"
162
171
  ]
163
172
  });
164
173
  const documentApi = contentManagerApi.injectEndpoints({
@@ -172,7 +181,12 @@ const documentApi = contentManagerApi.injectEndpoints({
172
181
  params: query
173
182
  }
174
183
  }),
175
- invalidatesTags: (_result, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
184
+ invalidatesTags: (_result, error, { model }) => {
185
+ if (error) {
186
+ return [];
187
+ }
188
+ return [{ type: "Document", id: `${model}_LIST` }];
189
+ }
176
190
  }),
177
191
  cloneDocument: builder.mutation({
178
192
  query: ({ model, sourceId, data, params }) => ({
@@ -183,7 +197,10 @@ const documentApi = contentManagerApi.injectEndpoints({
183
197
  params
184
198
  }
185
199
  }),
186
- invalidatesTags: (_result, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
200
+ invalidatesTags: (_result, _error, { model }) => [
201
+ { type: "Document", id: `${model}_LIST` },
202
+ { type: "UidAvailability", id: model }
203
+ ]
187
204
  }),
188
205
  /**
189
206
  * Creates a new collection-type document. This should ONLY be used for collection-types.
@@ -200,7 +217,8 @@ const documentApi = contentManagerApi.injectEndpoints({
200
217
  }),
201
218
  invalidatesTags: (result, _error, { model }) => [
202
219
  { type: "Document", id: `${model}_LIST` },
203
- "Relations"
220
+ "Relations",
221
+ { type: "UidAvailability", id: model }
204
222
  ]
205
223
  }),
206
224
  deleteDocument: builder.mutation({
@@ -241,7 +259,8 @@ const documentApi = contentManagerApi.injectEndpoints({
241
259
  id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
242
260
  },
243
261
  { type: "Document", id: `${model}_LIST` },
244
- "Relations"
262
+ "Relations",
263
+ { type: "UidAvailability", id: model }
245
264
  ];
246
265
  }
247
266
  }),
@@ -259,6 +278,7 @@ const documentApi = contentManagerApi.injectEndpoints({
259
278
  }),
260
279
  providesTags: (result, _error, arg) => {
261
280
  return [
281
+ { type: "Document", id: `ALL_LIST` },
262
282
  { type: "Document", id: `${arg.model}_LIST` },
263
283
  ...result?.results.map(({ documentId }) => ({
264
284
  type: "Document",
@@ -297,6 +317,11 @@ const documentApi = contentManagerApi.injectEndpoints({
297
317
  {
298
318
  type: "Document",
299
319
  id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
320
+ },
321
+ // Make it easy to invalidate all individual documents queries for a model
322
+ {
323
+ type: "Document",
324
+ id: `${model}_ALL_ITEMS`
300
325
  }
301
326
  ];
302
327
  }
@@ -360,8 +385,21 @@ const documentApi = contentManagerApi.injectEndpoints({
360
385
  type: "Document",
361
386
  id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
362
387
  },
363
- "Relations"
388
+ "Relations",
389
+ { type: "UidAvailability", id: model }
364
390
  ];
391
+ },
392
+ async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
393
+ const patchResult = dispatch(
394
+ documentApi.util.updateQueryData("getDocument", patch, (draft) => {
395
+ Object.assign(draft.data, data);
396
+ })
397
+ );
398
+ try {
399
+ await queryFulfilled;
400
+ } catch {
401
+ patchResult.undo();
402
+ }
365
403
  }
366
404
  }),
367
405
  unpublishDocument: builder.mutation({
@@ -431,20 +469,39 @@ const buildValidParams = (query) => {
431
469
  const isBaseQueryError = (error) => {
432
470
  return error.name !== void 0;
433
471
  };
434
- const createYupSchema = (attributes = {}, components = {}) => {
472
+ const arrayValidator = (attribute, options) => ({
473
+ message: translatedErrors.required,
474
+ test(value) {
475
+ if (options.status === "draft") {
476
+ return true;
477
+ }
478
+ if (!attribute.required) {
479
+ return true;
480
+ }
481
+ if (!value) {
482
+ return false;
483
+ }
484
+ if (Array.isArray(value) && value.length === 0) {
485
+ return false;
486
+ }
487
+ return true;
488
+ }
489
+ });
490
+ const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
435
491
  const createModelSchema = (attributes2) => yup.object().shape(
436
492
  Object.entries(attributes2).reduce((acc, [name, attribute]) => {
437
493
  if (DOCUMENT_META_FIELDS.includes(name)) {
438
494
  return acc;
439
495
  }
440
496
  const validations = [
497
+ addNullableValidation,
441
498
  addRequiredValidation,
442
499
  addMinLengthValidation,
443
500
  addMaxLengthValidation,
444
501
  addMinValidation,
445
502
  addMaxValidation,
446
503
  addRegexValidation
447
- ].map((fn) => fn(attribute));
504
+ ].map((fn) => fn(attribute, options));
448
505
  const transformSchema = pipe(...validations);
449
506
  switch (attribute.type) {
450
507
  case "component": {
@@ -454,12 +511,12 @@ const createYupSchema = (attributes = {}, components = {}) => {
454
511
  ...acc,
455
512
  [name]: transformSchema(
456
513
  yup.array().of(createModelSchema(attributes3).nullable(false))
457
- )
514
+ ).test(arrayValidator(attribute, options))
458
515
  };
459
516
  } else {
460
517
  return {
461
518
  ...acc,
462
- [name]: transformSchema(createModelSchema(attributes3))
519
+ [name]: transformSchema(createModelSchema(attributes3).nullable())
463
520
  };
464
521
  }
465
522
  }
@@ -481,7 +538,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
481
538
  }
482
539
  )
483
540
  )
484
- )
541
+ ).test(arrayValidator(attribute, options))
485
542
  };
486
543
  case "relation":
487
544
  return {
@@ -493,7 +550,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
493
550
  } else if (Array.isArray(value)) {
494
551
  return yup.array().of(
495
552
  yup.object().shape({
496
- id: yup.string().required()
553
+ id: yup.number().required()
497
554
  })
498
555
  );
499
556
  } else if (typeof value === "object") {
@@ -545,6 +602,14 @@ const createAttributeSchema = (attribute) => {
545
602
  if (!value || typeof value === "string" && value.length === 0) {
546
603
  return true;
547
604
  }
605
+ if (typeof value === "object") {
606
+ try {
607
+ JSON.stringify(value);
608
+ return true;
609
+ } catch (err) {
610
+ return false;
611
+ }
612
+ }
548
613
  try {
549
614
  JSON.parse(value);
550
615
  return true;
@@ -563,13 +628,7 @@ const createAttributeSchema = (attribute) => {
563
628
  return yup.mixed();
564
629
  }
565
630
  };
566
- const addRequiredValidation = (attribute) => (schema) => {
567
- if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
568
- return schema.min(1, translatedErrors.required);
569
- }
570
- if (attribute.required && attribute.type !== "relation") {
571
- return schema.required(translatedErrors.required);
572
- }
631
+ const nullableSchema = (schema) => {
573
632
  return schema?.nullable ? schema.nullable() : (
574
633
  // In some cases '.nullable' will not be available on the schema.
575
634
  // e.g. when the schema has been built using yup.lazy (e.g. for relations).
@@ -577,7 +636,22 @@ const addRequiredValidation = (attribute) => (schema) => {
577
636
  schema
578
637
  );
579
638
  };
580
- const addMinLengthValidation = (attribute) => (schema) => {
639
+ const addNullableValidation = () => (schema) => {
640
+ return nullableSchema(schema);
641
+ };
642
+ const addRequiredValidation = (attribute, options) => (schema) => {
643
+ if (options.status === "draft" || !attribute.required) {
644
+ return schema;
645
+ }
646
+ if (attribute.required && "required" in schema) {
647
+ return schema.required(translatedErrors.required);
648
+ }
649
+ return schema;
650
+ };
651
+ const addMinLengthValidation = (attribute, options) => (schema) => {
652
+ if (options.status === "draft") {
653
+ return schema;
654
+ }
581
655
  if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
582
656
  return schema.min(attribute.minLength, {
583
657
  ...translatedErrors.minLength,
@@ -599,32 +673,13 @@ const addMaxLengthValidation = (attribute) => (schema) => {
599
673
  }
600
674
  return schema;
601
675
  };
602
- const addMinValidation = (attribute) => (schema) => {
603
- if ("min" in attribute) {
676
+ const addMinValidation = (attribute, options) => (schema) => {
677
+ if (options.status === "draft") {
678
+ return schema;
679
+ }
680
+ if ("min" in attribute && "min" in schema) {
604
681
  const min = toInteger(attribute.min);
605
- if (attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") {
606
- if (!attribute.required && "test" in schema && min) {
607
- return schema.test(
608
- "custom-min",
609
- {
610
- ...translatedErrors.min,
611
- values: {
612
- min: attribute.min
613
- }
614
- },
615
- (value) => {
616
- if (!value) {
617
- return true;
618
- }
619
- if (Array.isArray(value) && value.length === 0) {
620
- return true;
621
- }
622
- return value.length >= min;
623
- }
624
- );
625
- }
626
- }
627
- if ("min" in schema && min) {
682
+ if (min) {
628
683
  return schema.min(min, {
629
684
  ...translatedErrors.min,
630
685
  values: {
@@ -742,19 +797,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
742
797
  }, {});
743
798
  return componentsByKey;
744
799
  };
745
- const useDocument = (args, opts) => {
800
+ const HOOKS = {
801
+ /**
802
+ * Hook that allows to mutate the displayed headers of the list view table
803
+ * @constant
804
+ * @type {string}
805
+ */
806
+ INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
807
+ /**
808
+ * Hook that allows to mutate the CM's collection types links pre-set filters
809
+ * @constant
810
+ * @type {string}
811
+ */
812
+ MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
813
+ /**
814
+ * Hook that allows to mutate the CM's edit view layout
815
+ * @constant
816
+ * @type {string}
817
+ */
818
+ MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
819
+ /**
820
+ * Hook that allows to mutate the CM's single types links pre-set filters
821
+ * @constant
822
+ * @type {string}
823
+ */
824
+ MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
825
+ };
826
+ const contentTypesApi = contentManagerApi.injectEndpoints({
827
+ endpoints: (builder) => ({
828
+ getContentTypeConfiguration: builder.query({
829
+ query: (uid) => ({
830
+ url: `/content-manager/content-types/${uid}/configuration`,
831
+ method: "GET"
832
+ }),
833
+ transformResponse: (response) => response.data,
834
+ providesTags: (_result, _error, uid) => [
835
+ { type: "ContentTypesConfiguration", id: uid },
836
+ { type: "ContentTypeSettings", id: "LIST" }
837
+ ]
838
+ }),
839
+ getAllContentTypeSettings: builder.query({
840
+ query: () => "/content-manager/content-types-settings",
841
+ transformResponse: (response) => response.data,
842
+ providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
843
+ }),
844
+ updateContentTypeConfiguration: builder.mutation({
845
+ query: ({ uid, ...body }) => ({
846
+ url: `/content-manager/content-types/${uid}/configuration`,
847
+ method: "PUT",
848
+ data: body
849
+ }),
850
+ transformResponse: (response) => response.data,
851
+ invalidatesTags: (_result, _error, { uid }) => [
852
+ { type: "ContentTypesConfiguration", id: uid },
853
+ { type: "ContentTypeSettings", id: "LIST" },
854
+ // Is this necessary?
855
+ { type: "InitialData" }
856
+ ]
857
+ })
858
+ })
859
+ });
860
+ const {
861
+ useGetContentTypeConfigurationQuery,
862
+ useGetAllContentTypeSettingsQuery,
863
+ useUpdateContentTypeConfigurationMutation
864
+ } = contentTypesApi;
865
+ const checkIfAttributeIsDisplayable = (attribute) => {
866
+ const { type } = attribute;
867
+ if (type === "relation") {
868
+ return !attribute.relation.toLowerCase().includes("morph");
869
+ }
870
+ return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
871
+ };
872
+ const getMainField = (attribute, mainFieldName, { schemas, components }) => {
873
+ if (!mainFieldName) {
874
+ return void 0;
875
+ }
876
+ const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
877
+ // @ts-expect-error – `targetModel` does exist on the attribute for a relation.
878
+ schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
879
+ );
880
+ return {
881
+ name: mainFieldName,
882
+ type: mainFieldType ?? "string"
883
+ };
884
+ };
885
+ const DEFAULT_SETTINGS = {
886
+ bulkable: false,
887
+ filterable: false,
888
+ searchable: false,
889
+ pagination: false,
890
+ defaultSortBy: "",
891
+ defaultSortOrder: "asc",
892
+ mainField: "id",
893
+ pageSize: 10
894
+ };
895
+ const useDocumentLayout = (model) => {
896
+ const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
897
+ const [{ query }] = useQueryParams();
898
+ const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
746
899
  const { toggleNotification } = useNotification();
747
900
  const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
901
+ const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
748
902
  const {
749
- currentData: data,
750
- isLoading: isLoadingDocument,
751
- isFetching: isFetchingDocument,
752
- error
753
- } = useGetDocumentQuery(args, {
754
- ...opts,
755
- skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
756
- });
757
- const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
903
+ data,
904
+ isLoading: isLoadingConfigs,
905
+ error,
906
+ isFetching: isFetchingConfigs
907
+ } = useGetContentTypeConfigurationQuery(model);
908
+ const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
758
909
  React.useEffect(() => {
759
910
  if (error) {
760
911
  toggleNotification({
@@ -762,83 +913,341 @@ const useDocument = (args, opts) => {
762
913
  message: formatAPIError(error)
763
914
  });
764
915
  }
765
- }, [toggleNotification, error, formatAPIError, args.collectionType]);
766
- const validationSchema = React.useMemo(() => {
767
- if (!schema) {
768
- return null;
769
- }
770
- return createYupSchema(schema.attributes, components);
771
- }, [schema, components]);
772
- const validate = React.useCallback(
773
- (document) => {
774
- if (!validationSchema) {
775
- throw new Error(
776
- "There is no validation schema generated, this is likely due to the schema not being loaded yet."
777
- );
778
- }
779
- try {
780
- validationSchema.validateSync(document, { abortEarly: false, strict: true });
781
- return null;
782
- } catch (error2) {
783
- if (error2 instanceof ValidationError) {
784
- return getYupValidationErrors(error2);
785
- }
786
- throw error2;
787
- }
916
+ }, [error, formatAPIError, toggleNotification]);
917
+ const editLayout = React.useMemo(
918
+ () => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
919
+ layout: [],
920
+ components: {},
921
+ metadatas: {},
922
+ options: {},
923
+ settings: DEFAULT_SETTINGS
788
924
  },
789
- [validationSchema]
925
+ [data, isLoading, schemas, schema, components]
926
+ );
927
+ const listLayout = React.useMemo(() => {
928
+ return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
929
+ layout: [],
930
+ metadatas: {},
931
+ options: {},
932
+ settings: DEFAULT_SETTINGS
933
+ };
934
+ }, [data, isLoading, schemas, schema, components]);
935
+ const { layout: edit } = React.useMemo(
936
+ () => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
937
+ layout: editLayout,
938
+ query
939
+ }),
940
+ [editLayout, query, runHookWaterfall]
790
941
  );
791
- const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
792
942
  return {
793
- components,
794
- document: data?.data,
795
- meta: data?.meta,
943
+ error,
796
944
  isLoading,
797
- schema,
798
- validate
799
- };
800
- };
801
- const useDoc = () => {
802
- const { id, slug, collectionType, origin } = useParams();
803
- const [{ query }] = useQueryParams();
804
- const params = React.useMemo(() => buildValidParams(query), [query]);
805
- if (!collectionType) {
806
- throw new Error("Could not find collectionType in url params");
807
- }
808
- if (!slug) {
809
- throw new Error("Could not find model in url params");
810
- }
811
- return {
812
- collectionType,
813
- model: slug,
814
- id: origin || id === "create" ? void 0 : id,
815
- ...useDocument(
816
- { documentId: origin || id, model: slug, collectionType, params },
817
- {
818
- skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
819
- }
820
- )
945
+ edit,
946
+ list: listLayout
821
947
  };
822
948
  };
823
- const prefixPluginTranslations = (trad, pluginId) => {
824
- if (!pluginId) {
825
- throw new TypeError("pluginId can't be empty");
826
- }
827
- return Object.keys(trad).reduce((acc, current) => {
828
- acc[`${pluginId}.${current}`] = trad[current];
829
- return acc;
830
- }, {});
831
- };
832
- const getTranslation = (id) => `content-manager.${id}`;
833
- const DEFAULT_UNEXPECTED_ERROR_MSG = {
834
- id: "notification.error",
835
- defaultMessage: "An error occurred, please try again"
949
+ const useDocLayout = () => {
950
+ const { model } = useDoc();
951
+ return useDocumentLayout(model);
952
+ };
953
+ const formatEditLayout = (data, {
954
+ schemas,
955
+ schema,
956
+ components
957
+ }) => {
958
+ let currentPanelIndex = 0;
959
+ const panelledEditAttributes = convertEditLayoutToFieldLayouts(
960
+ data.contentType.layouts.edit,
961
+ schema?.attributes,
962
+ data.contentType.metadatas,
963
+ { configurations: data.components, schemas: components },
964
+ schemas
965
+ ).reduce((panels, row) => {
966
+ if (row.some((field) => field.type === "dynamiczone")) {
967
+ panels.push([row]);
968
+ currentPanelIndex += 2;
969
+ } else {
970
+ if (!panels[currentPanelIndex]) {
971
+ panels.push([]);
972
+ }
973
+ panels[currentPanelIndex].push(row);
974
+ }
975
+ return panels;
976
+ }, []);
977
+ const componentEditAttributes = Object.entries(data.components).reduce(
978
+ (acc, [uid, configuration]) => {
979
+ acc[uid] = {
980
+ layout: convertEditLayoutToFieldLayouts(
981
+ configuration.layouts.edit,
982
+ components[uid].attributes,
983
+ configuration.metadatas,
984
+ { configurations: data.components, schemas: components }
985
+ ),
986
+ settings: {
987
+ ...configuration.settings,
988
+ icon: components[uid].info.icon,
989
+ displayName: components[uid].info.displayName
990
+ }
991
+ };
992
+ return acc;
993
+ },
994
+ {}
995
+ );
996
+ const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
997
+ (acc, [attribute, metadata]) => {
998
+ return {
999
+ ...acc,
1000
+ [attribute]: metadata.edit
1001
+ };
1002
+ },
1003
+ {}
1004
+ );
1005
+ return {
1006
+ layout: panelledEditAttributes,
1007
+ components: componentEditAttributes,
1008
+ metadatas: editMetadatas,
1009
+ settings: {
1010
+ ...data.contentType.settings,
1011
+ displayName: schema?.info.displayName
1012
+ },
1013
+ options: {
1014
+ ...schema?.options,
1015
+ ...schema?.pluginOptions,
1016
+ ...data.contentType.options
1017
+ }
1018
+ };
1019
+ };
1020
+ const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
1021
+ return rows.map(
1022
+ (row) => row.map((field) => {
1023
+ const attribute = attributes[field.name];
1024
+ if (!attribute) {
1025
+ return null;
1026
+ }
1027
+ const { edit: metadata } = metadatas[field.name];
1028
+ const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
1029
+ return {
1030
+ attribute,
1031
+ disabled: !metadata.editable,
1032
+ hint: metadata.description,
1033
+ label: metadata.label ?? "",
1034
+ name: field.name,
1035
+ // @ts-expect-error – mainField does exist on the metadata for a relation.
1036
+ mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
1037
+ schemas,
1038
+ components: components?.schemas ?? {}
1039
+ }),
1040
+ placeholder: metadata.placeholder ?? "",
1041
+ required: attribute.required ?? false,
1042
+ size: field.size,
1043
+ unique: "unique" in attribute ? attribute.unique : false,
1044
+ visible: metadata.visible ?? true,
1045
+ type: attribute.type
1046
+ };
1047
+ }).filter((field) => field !== null)
1048
+ );
1049
+ };
1050
+ const formatListLayout = (data, {
1051
+ schemas,
1052
+ schema,
1053
+ components
1054
+ }) => {
1055
+ const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
1056
+ (acc, [attribute, metadata]) => {
1057
+ return {
1058
+ ...acc,
1059
+ [attribute]: metadata.list
1060
+ };
1061
+ },
1062
+ {}
1063
+ );
1064
+ const listAttributes = convertListLayoutToFieldLayouts(
1065
+ data.contentType.layouts.list,
1066
+ schema?.attributes,
1067
+ listMetadatas,
1068
+ { configurations: data.components, schemas: components },
1069
+ schemas
1070
+ );
1071
+ return {
1072
+ layout: listAttributes,
1073
+ settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
1074
+ metadatas: listMetadatas,
1075
+ options: {
1076
+ ...schema?.options,
1077
+ ...schema?.pluginOptions,
1078
+ ...data.contentType.options
1079
+ }
1080
+ };
1081
+ };
1082
+ const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
1083
+ return columns.map((name) => {
1084
+ const attribute = attributes[name];
1085
+ if (!attribute) {
1086
+ return null;
1087
+ }
1088
+ const metadata = metadatas[name];
1089
+ const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
1090
+ return {
1091
+ attribute,
1092
+ label: metadata.label ?? "",
1093
+ mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
1094
+ schemas,
1095
+ components: components?.schemas ?? {}
1096
+ }),
1097
+ name,
1098
+ searchable: metadata.searchable ?? true,
1099
+ sortable: metadata.sortable ?? true
1100
+ };
1101
+ }).filter((field) => field !== null);
1102
+ };
1103
+ const useDocument = (args, opts) => {
1104
+ const { toggleNotification } = useNotification();
1105
+ const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
1106
+ const {
1107
+ currentData: data,
1108
+ isLoading: isLoadingDocument,
1109
+ isFetching: isFetchingDocument,
1110
+ error
1111
+ } = useGetDocumentQuery(args, {
1112
+ ...opts,
1113
+ skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
1114
+ });
1115
+ const {
1116
+ components,
1117
+ schema,
1118
+ schemas,
1119
+ isLoading: isLoadingSchema
1120
+ } = useContentTypeSchema(args.model);
1121
+ React.useEffect(() => {
1122
+ if (error) {
1123
+ toggleNotification({
1124
+ type: "danger",
1125
+ message: formatAPIError(error)
1126
+ });
1127
+ }
1128
+ }, [toggleNotification, error, formatAPIError, args.collectionType]);
1129
+ const validationSchema = React.useMemo(() => {
1130
+ if (!schema) {
1131
+ return null;
1132
+ }
1133
+ return createYupSchema(schema.attributes, components);
1134
+ }, [schema, components]);
1135
+ const validate = React.useCallback(
1136
+ (document) => {
1137
+ if (!validationSchema) {
1138
+ throw new Error(
1139
+ "There is no validation schema generated, this is likely due to the schema not being loaded yet."
1140
+ );
1141
+ }
1142
+ try {
1143
+ validationSchema.validateSync(document, { abortEarly: false, strict: true });
1144
+ return null;
1145
+ } catch (error2) {
1146
+ if (error2 instanceof ValidationError) {
1147
+ return getYupValidationErrors(error2);
1148
+ }
1149
+ throw error2;
1150
+ }
1151
+ },
1152
+ [validationSchema]
1153
+ );
1154
+ const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
1155
+ const hasError = !!error;
1156
+ return {
1157
+ components,
1158
+ document: data?.data,
1159
+ meta: data?.meta,
1160
+ isLoading,
1161
+ hasError,
1162
+ schema,
1163
+ schemas,
1164
+ validate
1165
+ };
1166
+ };
1167
+ const useDoc = () => {
1168
+ const { id, slug, collectionType, origin } = useParams();
1169
+ const [{ query }] = useQueryParams();
1170
+ const params = React.useMemo(() => buildValidParams(query), [query]);
1171
+ if (!collectionType) {
1172
+ throw new Error("Could not find collectionType in url params");
1173
+ }
1174
+ if (!slug) {
1175
+ throw new Error("Could not find model in url params");
1176
+ }
1177
+ const document = useDocument(
1178
+ { documentId: origin || id, model: slug, collectionType, params },
1179
+ {
1180
+ skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
1181
+ }
1182
+ );
1183
+ const returnId = origin || id === "create" ? void 0 : id;
1184
+ return {
1185
+ collectionType,
1186
+ model: slug,
1187
+ id: returnId,
1188
+ ...document
1189
+ };
1190
+ };
1191
+ const useContentManagerContext = () => {
1192
+ const {
1193
+ collectionType,
1194
+ model,
1195
+ id,
1196
+ components,
1197
+ isLoading: isLoadingDoc,
1198
+ schema,
1199
+ schemas
1200
+ } = useDoc();
1201
+ const layout = useDocumentLayout(model);
1202
+ const form = useForm("useContentManagerContext", (state) => state);
1203
+ const isSingleType = collectionType === SINGLE_TYPES;
1204
+ const slug = model;
1205
+ const isCreatingEntry = id === "create";
1206
+ useContentTypeSchema();
1207
+ const isLoading = isLoadingDoc || layout.isLoading;
1208
+ const error = layout.error;
1209
+ return {
1210
+ error,
1211
+ isLoading,
1212
+ // Base metadata
1213
+ model,
1214
+ collectionType,
1215
+ id,
1216
+ slug,
1217
+ isCreatingEntry,
1218
+ isSingleType,
1219
+ hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
1220
+ // All schema infos
1221
+ components,
1222
+ contentType: schema,
1223
+ contentTypes: schemas,
1224
+ // Form state
1225
+ form,
1226
+ // layout infos
1227
+ layout
1228
+ };
1229
+ };
1230
+ const prefixPluginTranslations = (trad, pluginId) => {
1231
+ if (!pluginId) {
1232
+ throw new TypeError("pluginId can't be empty");
1233
+ }
1234
+ return Object.keys(trad).reduce((acc, current) => {
1235
+ acc[`${pluginId}.${current}`] = trad[current];
1236
+ return acc;
1237
+ }, {});
1238
+ };
1239
+ const getTranslation = (id) => `content-manager.${id}`;
1240
+ const DEFAULT_UNEXPECTED_ERROR_MSG = {
1241
+ id: "notification.error",
1242
+ defaultMessage: "An error occurred, please try again"
836
1243
  };
837
1244
  const useDocumentActions = () => {
838
1245
  const { toggleNotification } = useNotification();
839
1246
  const { formatMessage } = useIntl();
840
1247
  const { trackUsage } = useTracking();
841
1248
  const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
1249
+ const navigate = useNavigate();
1250
+ const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
842
1251
  const [deleteDocument] = useDeleteDocumentMutation();
843
1252
  const _delete = React.useCallback(
844
1253
  async ({ collectionType, model, documentId, params }, trackerProperty) => {
@@ -1153,6 +1562,7 @@ const useDocumentActions = () => {
1153
1562
  defaultMessage: "Saved document"
1154
1563
  })
1155
1564
  });
1565
+ setCurrentStep("contentManager.success");
1156
1566
  return res.data;
1157
1567
  } catch (err) {
1158
1568
  toggleNotification({
@@ -1174,7 +1584,6 @@ const useDocumentActions = () => {
1174
1584
  sourceId
1175
1585
  });
1176
1586
  if ("error" in res) {
1177
- toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1178
1587
  return { error: res.error };
1179
1588
  }
1180
1589
  toggleNotification({
@@ -1193,7 +1602,7 @@ const useDocumentActions = () => {
1193
1602
  throw err;
1194
1603
  }
1195
1604
  },
1196
- [autoCloneDocument, formatAPIError, formatMessage, toggleNotification]
1605
+ [autoCloneDocument, formatMessage, toggleNotification]
1197
1606
  );
1198
1607
  const [cloneDocument] = useCloneDocumentMutation();
1199
1608
  const clone = React.useCallback(
@@ -1219,6 +1628,7 @@ const useDocumentActions = () => {
1219
1628
  defaultMessage: "Cloned document"
1220
1629
  })
1221
1630
  });
1631
+ navigate(`../../${res.data.data.documentId}`, { relative: "path" });
1222
1632
  return res.data;
1223
1633
  } catch (err) {
1224
1634
  toggleNotification({
@@ -1229,7 +1639,7 @@ const useDocumentActions = () => {
1229
1639
  throw err;
1230
1640
  }
1231
1641
  },
1232
- [cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
1642
+ [cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
1233
1643
  );
1234
1644
  const [getDoc] = useLazyGetDocumentQuery();
1235
1645
  const getDocument = React.useCallback(
@@ -1255,7 +1665,7 @@ const useDocumentActions = () => {
1255
1665
  };
1256
1666
  };
1257
1667
  const ProtectedHistoryPage = lazy(
1258
- () => import("./History-CBNGU7a-.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1668
+ () => import("./History-DRwA3oMM.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1259
1669
  );
1260
1670
  const routes$1 = [
1261
1671
  {
@@ -1268,31 +1678,31 @@ const routes$1 = [
1268
1678
  }
1269
1679
  ];
1270
1680
  const ProtectedEditViewPage = lazy(
1271
- () => import("./EditViewPage-DlLEyUL6.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1681
+ () => import("./EditViewPage-B82x_x1b.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1272
1682
  );
1273
1683
  const ProtectedListViewPage = lazy(
1274
- () => import("./ListViewPage-DecLrYV6.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1684
+ () => import("./ListViewPage-CELx2ysp.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1275
1685
  );
1276
1686
  const ProtectedListConfiguration = lazy(
1277
- () => import("./ListConfigurationPage-5dr4qpue.mjs").then((mod) => ({
1687
+ () => import("./ListConfigurationPage-BxfQJzPk.mjs").then((mod) => ({
1278
1688
  default: mod.ProtectedListConfiguration
1279
1689
  }))
1280
1690
  );
1281
1691
  const ProtectedEditConfigurationPage = lazy(
1282
- () => import("./EditConfigurationPage-ZO0vOO8q.mjs").then((mod) => ({
1692
+ () => import("./EditConfigurationPage-DdPNAbl3.mjs").then((mod) => ({
1283
1693
  default: mod.ProtectedEditConfigurationPage
1284
1694
  }))
1285
1695
  );
1286
1696
  const ProtectedComponentConfigurationPage = lazy(
1287
- () => import("./ComponentConfigurationPage-B1bIXVuX.mjs").then((mod) => ({
1697
+ () => import("./ComponentConfigurationPage-DfFSZQxe.mjs").then((mod) => ({
1288
1698
  default: mod.ProtectedComponentConfigurationPage
1289
1699
  }))
1290
1700
  );
1291
1701
  const NoPermissions = lazy(
1292
- () => import("./NoPermissionsPage-CM5UD8ee.mjs").then((mod) => ({ default: mod.NoPermissions }))
1702
+ () => import("./NoPermissionsPage-DWleVYK7.mjs").then((mod) => ({ default: mod.NoPermissions }))
1293
1703
  );
1294
1704
  const NoContentType = lazy(
1295
- () => import("./NoContentTypePage-CiIcfYsd.mjs").then((mod) => ({ default: mod.NoContentType }))
1705
+ () => import("./NoContentTypePage-DtJ9jcfk.mjs").then((mod) => ({ default: mod.NoContentType }))
1296
1706
  );
1297
1707
  const CollectionTypePages = () => {
1298
1708
  const { collectionType } = useParams();
@@ -1406,12 +1816,14 @@ const DocumentActionButton = (action) => {
1406
1816
  /* @__PURE__ */ jsx(
1407
1817
  Button,
1408
1818
  {
1409
- flex: 1,
1819
+ flex: "auto",
1410
1820
  startIcon: action.icon,
1411
1821
  disabled: action.disabled,
1412
1822
  onClick: handleClick(action),
1413
1823
  justifyContent: "center",
1414
1824
  variant: action.variant || "default",
1825
+ paddingTop: "7px",
1826
+ paddingBottom: "7px",
1415
1827
  children: action.label
1416
1828
  }
1417
1829
  ),
@@ -1476,9 +1888,9 @@ const DocumentActionsMenu = ({
1476
1888
  disabled: isDisabled,
1477
1889
  size: "S",
1478
1890
  endIcon: null,
1479
- paddingTop: "7px",
1480
- paddingLeft: "9px",
1481
- paddingRight: "9px",
1891
+ paddingTop: "4px",
1892
+ paddingLeft: "7px",
1893
+ paddingRight: "7px",
1482
1894
  variant,
1483
1895
  children: [
1484
1896
  /* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
@@ -1489,7 +1901,7 @@ const DocumentActionsMenu = ({
1489
1901
  ]
1490
1902
  }
1491
1903
  ),
1492
- /* @__PURE__ */ jsxs(Menu.Content, { top: "4px", maxHeight: void 0, popoverPlacement: "bottom-end", children: [
1904
+ /* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
1493
1905
  actions2.map((action) => {
1494
1906
  return /* @__PURE__ */ jsx(
1495
1907
  Menu.Item,
@@ -1498,10 +1910,25 @@ const DocumentActionsMenu = ({
1498
1910
  onSelect: handleClick(action),
1499
1911
  display: "block",
1500
1912
  children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
1501
- /* @__PURE__ */ jsxs(Flex, { color: convertActionVariantToColor(action.variant), gap: 2, tag: "span", children: [
1502
- /* @__PURE__ */ jsx(Box, { tag: "span", color: convertActionVariantToIconColor(action.variant), children: action.icon }),
1503
- action.label
1504
- ] }),
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
+ ),
1505
1932
  action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
1506
1933
  Flex,
1507
1934
  {
@@ -1598,11 +2025,11 @@ const DocumentActionConfirmDialog = ({
1598
2025
  /* @__PURE__ */ jsx(Dialog.Header, { children: title }),
1599
2026
  /* @__PURE__ */ jsx(Dialog.Body, { children: content }),
1600
2027
  /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
1601
- /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
2028
+ /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
1602
2029
  id: "app.components.Button.cancel",
1603
2030
  defaultMessage: "Cancel"
1604
2031
  }) }) }),
1605
- /* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
2032
+ /* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
1606
2033
  id: "app.components.Button.confirm",
1607
2034
  defaultMessage: "Confirm"
1608
2035
  }) })
@@ -1625,8 +2052,8 @@ const DocumentActionModal = ({
1625
2052
  };
1626
2053
  return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
1627
2054
  /* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
1628
- /* @__PURE__ */ jsx(Modal.Body, { children: typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content }),
1629
- /* @__PURE__ */ jsx(Modal.Footer, { children: typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer })
2055
+ typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
2056
+ typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
1630
2057
  ] }) });
1631
2058
  };
1632
2059
  const PublishAction$1 = ({
@@ -1641,12 +2068,10 @@ const PublishAction$1 = ({
1641
2068
  const navigate = useNavigate();
1642
2069
  const { toggleNotification } = useNotification();
1643
2070
  const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
2071
+ const isListView = useMatch(LIST_PATH) !== null;
1644
2072
  const isCloning = useMatch(CLONE_PATH) !== null;
1645
2073
  const { formatMessage } = useIntl();
1646
- const { canPublish, canCreate, canUpdate } = useDocumentRBAC(
1647
- "PublishAction",
1648
- ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
1649
- );
2074
+ const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
1650
2075
  const { publish } = useDocumentActions();
1651
2076
  const [
1652
2077
  countDraftRelations,
@@ -1698,24 +2123,25 @@ const PublishAction$1 = ({
1698
2123
  }
1699
2124
  }, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
1700
2125
  React.useEffect(() => {
1701
- if (documentId) {
1702
- const fetchDraftRelationsCount = async () => {
1703
- const { data, error } = await countDraftRelations({
1704
- collectionType,
1705
- model,
1706
- documentId,
1707
- params
1708
- });
1709
- if (error) {
1710
- throw error;
1711
- }
1712
- if (data) {
1713
- setServerCountOfDraftRelations(data.data);
1714
- }
1715
- };
1716
- fetchDraftRelationsCount();
2126
+ if (!document || !document.documentId || isListView) {
2127
+ return;
1717
2128
  }
1718
- }, [documentId, countDraftRelations, collectionType, model, params]);
2129
+ const fetchDraftRelationsCount = async () => {
2130
+ const { data, error } = await countDraftRelations({
2131
+ collectionType,
2132
+ model,
2133
+ documentId,
2134
+ params
2135
+ });
2136
+ if (error) {
2137
+ throw error;
2138
+ }
2139
+ if (data) {
2140
+ setServerCountOfDraftRelations(data.data);
2141
+ }
2142
+ };
2143
+ fetchDraftRelationsCount();
2144
+ }, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
1719
2145
  const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
1720
2146
  if (!schema?.options?.draftAndPublish) {
1721
2147
  return null;
@@ -1723,7 +2149,9 @@ const PublishAction$1 = ({
1723
2149
  const performPublish = async () => {
1724
2150
  setSubmitting(true);
1725
2151
  try {
1726
- const { errors } = await validate();
2152
+ const { errors } = await validate(true, {
2153
+ status: "published"
2154
+ });
1727
2155
  if (errors) {
1728
2156
  toggleNotification({
1729
2157
  type: "danger",
@@ -1756,7 +2184,8 @@ const PublishAction$1 = ({
1756
2184
  }
1757
2185
  };
1758
2186
  const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
1759
- const hasDraftRelations = totalDraftRelations > 0;
2187
+ const enableDraftRelationsCount = false;
2188
+ const hasDraftRelations = enableDraftRelationsCount;
1760
2189
  return {
1761
2190
  /**
1762
2191
  * Disabled when:
@@ -1766,18 +2195,13 @@ const PublishAction$1 = ({
1766
2195
  * - the document is already published & not modified
1767
2196
  * - the document is being created & not modified
1768
2197
  * - the user doesn't have the permission to publish
1769
- * - the user doesn't have the permission to create a new document
1770
- * - the user doesn't have the permission to update the document
1771
2198
  */
1772
- disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish || Boolean(!document?.documentId && !canCreate || document?.documentId && !canUpdate),
2199
+ disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
1773
2200
  label: formatMessage({
1774
2201
  id: "app.utils.publish",
1775
2202
  defaultMessage: "Publish"
1776
2203
  }),
1777
2204
  onClick: async () => {
1778
- if (hasDraftRelations) {
1779
- return;
1780
- }
1781
2205
  await performPublish();
1782
2206
  },
1783
2207
  dialog: hasDraftRelations ? {
@@ -1816,10 +2240,6 @@ const UpdateAction = ({
1816
2240
  const cloneMatch = useMatch(CLONE_PATH);
1817
2241
  const isCloning = cloneMatch !== null;
1818
2242
  const { formatMessage } = useIntl();
1819
- const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
1820
- canCreate: canCreate2,
1821
- canUpdate: canUpdate2
1822
- }));
1823
2243
  const { create, update, clone } = useDocumentActions();
1824
2244
  const [{ query, rawQuery }] = useQueryParams();
1825
2245
  const params = React.useMemo(() => buildValidParams(query), [query]);
@@ -1836,10 +2256,8 @@ const UpdateAction = ({
1836
2256
  * - the form is submitting
1837
2257
  * - the document is not modified & we're not cloning (you can save a clone entity straight away)
1838
2258
  * - the active tab is the published tab
1839
- * - the user doesn't have the permission to create a new document
1840
- * - the user doesn't have the permission to update the document
1841
2259
  */
1842
- disabled: isSubmitting || !modified && !isCloning || activeTab === "published" || Boolean(!documentId && !canCreate || documentId && !canUpdate),
2260
+ disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
1843
2261
  label: formatMessage({
1844
2262
  id: "content-manager.containers.Edit.save",
1845
2263
  defaultMessage: "Save"
@@ -1847,7 +2265,9 @@ const UpdateAction = ({
1847
2265
  onClick: async () => {
1848
2266
  setSubmitting(true);
1849
2267
  try {
1850
- const { errors } = await validate();
2268
+ const { errors } = await validate(true, {
2269
+ status: "draft"
2270
+ });
1851
2271
  if (errors) {
1852
2272
  toggleNotification({
1853
2273
  type: "danger",
@@ -1868,10 +2288,13 @@ const UpdateAction = ({
1868
2288
  document
1869
2289
  );
1870
2290
  if ("data" in res) {
1871
- navigate({
1872
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
1873
- search: rawQuery
1874
- });
2291
+ navigate(
2292
+ {
2293
+ pathname: `../${res.data.documentId}`,
2294
+ search: rawQuery
2295
+ },
2296
+ { relative: "path" }
2297
+ );
1875
2298
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1876
2299
  setErrors(formatValidationErrors(res.error));
1877
2300
  }
@@ -1901,10 +2324,10 @@ const UpdateAction = ({
1901
2324
  if ("data" in res && collectionType !== SINGLE_TYPES) {
1902
2325
  navigate(
1903
2326
  {
1904
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
2327
+ pathname: `../${res.data.documentId}`,
1905
2328
  search: rawQuery
1906
2329
  },
1907
- { replace: true }
2330
+ { replace: true, relative: "path" }
1908
2331
  );
1909
2332
  } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
1910
2333
  setErrors(formatValidationErrors(res.error));
@@ -1949,7 +2372,7 @@ const UnpublishAction$1 = ({
1949
2372
  id: "app.utils.unpublish",
1950
2373
  defaultMessage: "Unpublish"
1951
2374
  }),
1952
- icon: /* @__PURE__ */ jsx(StyledCrossCircle, {}),
2375
+ icon: /* @__PURE__ */ jsx(Cross, {}),
1953
2376
  onClick: async () => {
1954
2377
  if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
1955
2378
  if (!documentId) {
@@ -2061,7 +2484,7 @@ const DiscardAction = ({
2061
2484
  id: "content-manager.actions.discard.label",
2062
2485
  defaultMessage: "Discard changes"
2063
2486
  }),
2064
- icon: /* @__PURE__ */ jsx(StyledCrossCircle, {}),
2487
+ icon: /* @__PURE__ */ jsx(Cross, {}),
2065
2488
  position: ["panel", "table-row"],
2066
2489
  variant: "danger",
2067
2490
  dialog: {
@@ -2089,11 +2512,6 @@ const DiscardAction = ({
2089
2512
  };
2090
2513
  };
2091
2514
  DiscardAction.type = "discard";
2092
- const StyledCrossCircle = styled(CrossCircle)`
2093
- path {
2094
- fill: currentColor;
2095
- }
2096
- `;
2097
2515
  const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
2098
2516
  const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
2099
2517
  const RelativeTime = React.forwardRef(
@@ -2141,7 +2559,7 @@ const getDisplayName = ({
2141
2559
  };
2142
2560
  const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2143
2561
  const DocumentStatus = ({ status = "draft", ...restProps }) => {
2144
- const statusVariant = status === "draft" ? "primary" : status === "published" ? "success" : "alternative";
2562
+ const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
2145
2563
  return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
2146
2564
  };
2147
2565
  const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
@@ -2240,12 +2658,12 @@ const Information = ({ activeTab }) => {
2240
2658
  isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
2241
2659
  label: formatMessage({
2242
2660
  id: "content-manager.containers.edit.information.last-published.label",
2243
- defaultMessage: "Last published"
2661
+ defaultMessage: "Published"
2244
2662
  }),
2245
2663
  value: formatMessage(
2246
2664
  {
2247
2665
  id: "content-manager.containers.edit.information.last-published.value",
2248
- defaultMessage: `Published {time}{isAnonymous, select, true {} other { by {author}}}`
2666
+ defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
2249
2667
  },
2250
2668
  {
2251
2669
  time: /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
@@ -2258,12 +2676,12 @@ const Information = ({ activeTab }) => {
2258
2676
  isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
2259
2677
  label: formatMessage({
2260
2678
  id: "content-manager.containers.edit.information.last-draft.label",
2261
- defaultMessage: "Last draft"
2679
+ defaultMessage: "Updated"
2262
2680
  }),
2263
2681
  value: formatMessage(
2264
2682
  {
2265
2683
  id: "content-manager.containers.edit.information.last-draft.value",
2266
- defaultMessage: `Modified {time}{isAnonymous, select, true {} other { by {author}}}`
2684
+ defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
2267
2685
  },
2268
2686
  {
2269
2687
  time: /* @__PURE__ */ jsx(
@@ -2281,12 +2699,12 @@ const Information = ({ activeTab }) => {
2281
2699
  isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
2282
2700
  label: formatMessage({
2283
2701
  id: "content-manager.containers.edit.information.document.label",
2284
- defaultMessage: "Document"
2702
+ defaultMessage: "Created"
2285
2703
  }),
2286
2704
  value: formatMessage(
2287
2705
  {
2288
2706
  id: "content-manager.containers.edit.information.document.value",
2289
- defaultMessage: `Created {time}{isAnonymous, select, true {} other { by {author}}}`
2707
+ defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
2290
2708
  },
2291
2709
  {
2292
2710
  time: /* @__PURE__ */ jsx(
@@ -2324,25 +2742,77 @@ const Information = ({ activeTab }) => {
2324
2742
  );
2325
2743
  };
2326
2744
  const HeaderActions = ({ actions: actions2 }) => {
2327
- return /* @__PURE__ */ jsx(Flex, { children: actions2.map((action) => {
2328
- if ("options" in action) {
2745
+ const [dialogId, setDialogId] = React.useState(null);
2746
+ const handleClick = (action) => async (e) => {
2747
+ if (!("options" in action)) {
2748
+ const { onClick = () => false, dialog, id } = action;
2749
+ const muteDialog = await onClick(e);
2750
+ if (dialog && !muteDialog) {
2751
+ e.preventDefault();
2752
+ setDialogId(id);
2753
+ }
2754
+ }
2755
+ };
2756
+ const handleClose = () => {
2757
+ setDialogId(null);
2758
+ };
2759
+ return /* @__PURE__ */ jsx(Flex, { gap: 1, children: actions2.map((action) => {
2760
+ if (action.options) {
2329
2761
  return /* @__PURE__ */ jsx(
2330
2762
  SingleSelect,
2331
2763
  {
2332
2764
  size: "S",
2333
- disabled: action.disabled,
2334
- "aria-label": action.label,
2335
2765
  onChange: action.onSelect,
2336
- value: action.value,
2766
+ "aria-label": action.label,
2767
+ ...action,
2337
2768
  children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
2338
2769
  },
2339
2770
  action.id
2340
2771
  );
2341
2772
  } else {
2342
- return null;
2773
+ if (action.type === "icon") {
2774
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
2775
+ /* @__PURE__ */ jsx(
2776
+ IconButton,
2777
+ {
2778
+ disabled: action.disabled,
2779
+ label: action.label,
2780
+ size: "S",
2781
+ onClick: handleClick(action),
2782
+ children: action.icon
2783
+ }
2784
+ ),
2785
+ action.dialog ? /* @__PURE__ */ jsx(
2786
+ HeaderActionDialog,
2787
+ {
2788
+ ...action.dialog,
2789
+ isOpen: dialogId === action.id,
2790
+ onClose: handleClose
2791
+ }
2792
+ ) : null
2793
+ ] }, action.id);
2794
+ }
2343
2795
  }
2344
2796
  }) });
2345
2797
  };
2798
+ const HeaderActionDialog = ({
2799
+ onClose,
2800
+ onCancel,
2801
+ title,
2802
+ content: Content,
2803
+ isOpen
2804
+ }) => {
2805
+ const handleClose = async () => {
2806
+ if (onCancel) {
2807
+ await onCancel();
2808
+ }
2809
+ onClose();
2810
+ };
2811
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
2812
+ /* @__PURE__ */ jsx(Dialog.Header, { children: title }),
2813
+ typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content
2814
+ ] }) });
2815
+ };
2346
2816
  const ConfigureTheViewAction = ({ collectionType, model }) => {
2347
2817
  const navigate = useNavigate();
2348
2818
  const { formatMessage } = useIntl();
@@ -2383,12 +2853,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
2383
2853
  const { delete: deleteAction } = useDocumentActions();
2384
2854
  const { toggleNotification } = useNotification();
2385
2855
  const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
2856
+ const isLocalized = document?.locale != null;
2386
2857
  return {
2387
2858
  disabled: !canDelete || !document,
2388
- label: formatMessage({
2389
- id: "content-manager.actions.delete.label",
2390
- defaultMessage: "Delete document"
2391
- }),
2859
+ label: formatMessage(
2860
+ {
2861
+ id: "content-manager.actions.delete.label",
2862
+ defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
2863
+ },
2864
+ { isLocalized }
2865
+ ),
2392
2866
  icon: /* @__PURE__ */ jsx(Trash, {}),
2393
2867
  dialog: {
2394
2868
  type: "dialog",
@@ -2478,7 +2952,7 @@ const ActionsPanel = () => {
2478
2952
  return {
2479
2953
  title: formatMessage({
2480
2954
  id: "content-manager.containers.edit.panels.default.title",
2481
- defaultMessage: "Document"
2955
+ defaultMessage: "Entry"
2482
2956
  }),
2483
2957
  content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
2484
2958
  };
@@ -2539,308 +3013,6 @@ const Panel = React.forwardRef(({ children, title }, ref) => {
2539
3013
  }
2540
3014
  );
2541
3015
  });
2542
- const HOOKS = {
2543
- /**
2544
- * Hook that allows to mutate the displayed headers of the list view table
2545
- * @constant
2546
- * @type {string}
2547
- */
2548
- INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
2549
- /**
2550
- * Hook that allows to mutate the CM's collection types links pre-set filters
2551
- * @constant
2552
- * @type {string}
2553
- */
2554
- MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
2555
- /**
2556
- * Hook that allows to mutate the CM's edit view layout
2557
- * @constant
2558
- * @type {string}
2559
- */
2560
- MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
2561
- /**
2562
- * Hook that allows to mutate the CM's single types links pre-set filters
2563
- * @constant
2564
- * @type {string}
2565
- */
2566
- MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
2567
- };
2568
- const contentTypesApi = contentManagerApi.injectEndpoints({
2569
- endpoints: (builder) => ({
2570
- getContentTypeConfiguration: builder.query({
2571
- query: (uid) => ({
2572
- url: `/content-manager/content-types/${uid}/configuration`,
2573
- method: "GET"
2574
- }),
2575
- transformResponse: (response) => response.data,
2576
- providesTags: (_result, _error, uid) => [
2577
- { type: "ContentTypesConfiguration", id: uid },
2578
- { type: "ContentTypeSettings", id: "LIST" }
2579
- ]
2580
- }),
2581
- getAllContentTypeSettings: builder.query({
2582
- query: () => "/content-manager/content-types-settings",
2583
- transformResponse: (response) => response.data,
2584
- providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
2585
- }),
2586
- updateContentTypeConfiguration: builder.mutation({
2587
- query: ({ uid, ...body }) => ({
2588
- url: `/content-manager/content-types/${uid}/configuration`,
2589
- method: "PUT",
2590
- data: body
2591
- }),
2592
- transformResponse: (response) => response.data,
2593
- invalidatesTags: (_result, _error, { uid }) => [
2594
- { type: "ContentTypesConfiguration", id: uid },
2595
- { type: "ContentTypeSettings", id: "LIST" },
2596
- // Is this necessary?
2597
- { type: "InitialData" }
2598
- ]
2599
- })
2600
- })
2601
- });
2602
- const {
2603
- useGetContentTypeConfigurationQuery,
2604
- useGetAllContentTypeSettingsQuery,
2605
- useUpdateContentTypeConfigurationMutation
2606
- } = contentTypesApi;
2607
- const checkIfAttributeIsDisplayable = (attribute) => {
2608
- const { type } = attribute;
2609
- if (type === "relation") {
2610
- return !attribute.relation.toLowerCase().includes("morph");
2611
- }
2612
- return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
2613
- };
2614
- const getMainField = (attribute, mainFieldName, { schemas, components }) => {
2615
- if (!mainFieldName) {
2616
- return void 0;
2617
- }
2618
- const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
2619
- // @ts-expect-error – `targetModel` does exist on the attribute for a relation.
2620
- schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
2621
- );
2622
- return {
2623
- name: mainFieldName,
2624
- type: mainFieldType ?? "string"
2625
- };
2626
- };
2627
- const DEFAULT_SETTINGS = {
2628
- bulkable: false,
2629
- filterable: false,
2630
- searchable: false,
2631
- pagination: false,
2632
- defaultSortBy: "",
2633
- defaultSortOrder: "asc",
2634
- mainField: "id",
2635
- pageSize: 10
2636
- };
2637
- const useDocumentLayout = (model) => {
2638
- const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
2639
- const [{ query }] = useQueryParams();
2640
- const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
2641
- const { toggleNotification } = useNotification();
2642
- const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
2643
- const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
2644
- const {
2645
- data,
2646
- isLoading: isLoadingConfigs,
2647
- error,
2648
- isFetching: isFetchingConfigs
2649
- } = useGetContentTypeConfigurationQuery(model);
2650
- const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
2651
- React.useEffect(() => {
2652
- if (error) {
2653
- toggleNotification({
2654
- type: "danger",
2655
- message: formatAPIError(error)
2656
- });
2657
- }
2658
- }, [error, formatAPIError, toggleNotification]);
2659
- const editLayout = React.useMemo(
2660
- () => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
2661
- layout: [],
2662
- components: {},
2663
- metadatas: {},
2664
- options: {},
2665
- settings: DEFAULT_SETTINGS
2666
- },
2667
- [data, isLoading, schemas, schema, components]
2668
- );
2669
- const listLayout = React.useMemo(() => {
2670
- return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
2671
- layout: [],
2672
- metadatas: {},
2673
- options: {},
2674
- settings: DEFAULT_SETTINGS
2675
- };
2676
- }, [data, isLoading, schemas, schema, components]);
2677
- const { layout: edit } = React.useMemo(
2678
- () => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
2679
- layout: editLayout,
2680
- query
2681
- }),
2682
- [editLayout, query, runHookWaterfall]
2683
- );
2684
- return {
2685
- error,
2686
- isLoading,
2687
- edit,
2688
- list: listLayout
2689
- };
2690
- };
2691
- const useDocLayout = () => {
2692
- const { model } = useDoc();
2693
- return useDocumentLayout(model);
2694
- };
2695
- const formatEditLayout = (data, {
2696
- schemas,
2697
- schema,
2698
- components
2699
- }) => {
2700
- let currentPanelIndex = 0;
2701
- const panelledEditAttributes = convertEditLayoutToFieldLayouts(
2702
- data.contentType.layouts.edit,
2703
- schema?.attributes,
2704
- data.contentType.metadatas,
2705
- { configurations: data.components, schemas: components },
2706
- schemas
2707
- ).reduce((panels, row) => {
2708
- if (row.some((field) => field.type === "dynamiczone")) {
2709
- panels.push([row]);
2710
- currentPanelIndex += 2;
2711
- } else {
2712
- if (!panels[currentPanelIndex]) {
2713
- panels.push([]);
2714
- }
2715
- panels[currentPanelIndex].push(row);
2716
- }
2717
- return panels;
2718
- }, []);
2719
- const componentEditAttributes = Object.entries(data.components).reduce(
2720
- (acc, [uid, configuration]) => {
2721
- acc[uid] = {
2722
- layout: convertEditLayoutToFieldLayouts(
2723
- configuration.layouts.edit,
2724
- components[uid].attributes,
2725
- configuration.metadatas
2726
- ),
2727
- settings: {
2728
- ...configuration.settings,
2729
- icon: components[uid].info.icon,
2730
- displayName: components[uid].info.displayName
2731
- }
2732
- };
2733
- return acc;
2734
- },
2735
- {}
2736
- );
2737
- const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
2738
- (acc, [attribute, metadata]) => {
2739
- return {
2740
- ...acc,
2741
- [attribute]: metadata.edit
2742
- };
2743
- },
2744
- {}
2745
- );
2746
- return {
2747
- layout: panelledEditAttributes,
2748
- components: componentEditAttributes,
2749
- metadatas: editMetadatas,
2750
- settings: {
2751
- ...data.contentType.settings,
2752
- displayName: schema?.info.displayName
2753
- },
2754
- options: {
2755
- ...schema?.options,
2756
- ...schema?.pluginOptions,
2757
- ...data.contentType.options
2758
- }
2759
- };
2760
- };
2761
- const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
2762
- return rows.map(
2763
- (row) => row.map((field) => {
2764
- const attribute = attributes[field.name];
2765
- if (!attribute) {
2766
- return null;
2767
- }
2768
- const { edit: metadata } = metadatas[field.name];
2769
- const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
2770
- return {
2771
- attribute,
2772
- disabled: !metadata.editable,
2773
- hint: metadata.description,
2774
- label: metadata.label ?? "",
2775
- name: field.name,
2776
- // @ts-expect-error – mainField does exist on the metadata for a relation.
2777
- mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
2778
- schemas,
2779
- components: components?.schemas ?? {}
2780
- }),
2781
- placeholder: metadata.placeholder ?? "",
2782
- required: attribute.required ?? false,
2783
- size: field.size,
2784
- unique: "unique" in attribute ? attribute.unique : false,
2785
- visible: metadata.visible ?? true,
2786
- type: attribute.type
2787
- };
2788
- }).filter((field) => field !== null)
2789
- );
2790
- };
2791
- const formatListLayout = (data, {
2792
- schemas,
2793
- schema,
2794
- components
2795
- }) => {
2796
- const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
2797
- (acc, [attribute, metadata]) => {
2798
- return {
2799
- ...acc,
2800
- [attribute]: metadata.list
2801
- };
2802
- },
2803
- {}
2804
- );
2805
- const listAttributes = convertListLayoutToFieldLayouts(
2806
- data.contentType.layouts.list,
2807
- schema?.attributes,
2808
- listMetadatas,
2809
- { configurations: data.components, schemas: components },
2810
- schemas
2811
- );
2812
- return {
2813
- layout: listAttributes,
2814
- settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
2815
- metadatas: listMetadatas,
2816
- options: {
2817
- ...schema?.options,
2818
- ...schema?.pluginOptions,
2819
- ...data.contentType.options
2820
- }
2821
- };
2822
- };
2823
- const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
2824
- return columns.map((name) => {
2825
- const attribute = attributes[name];
2826
- if (!attribute) {
2827
- return null;
2828
- }
2829
- const metadata = metadatas[name];
2830
- const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
2831
- return {
2832
- attribute,
2833
- label: metadata.label ?? "",
2834
- mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
2835
- schemas,
2836
- components: components?.schemas ?? {}
2837
- }),
2838
- name,
2839
- searchable: metadata.searchable ?? true,
2840
- sortable: metadata.sortable ?? true
2841
- };
2842
- }).filter((field) => field !== null);
2843
- };
2844
3016
  const ConfirmBulkActionDialog = ({
2845
3017
  onToggleDialog,
2846
3018
  isOpen = false,
@@ -2879,6 +3051,7 @@ const ConfirmDialogPublishAll = ({
2879
3051
  const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
2880
3052
  const { model, schema } = useDoc();
2881
3053
  const [{ query }] = useQueryParams();
3054
+ const enableDraftRelationsCount = false;
2882
3055
  const {
2883
3056
  data: countDraftRelations = 0,
2884
3057
  isLoading,
@@ -2890,7 +3063,7 @@ const ConfirmDialogPublishAll = ({
2890
3063
  locale: query?.plugins?.i18n?.locale
2891
3064
  },
2892
3065
  {
2893
- skip: selectedEntries.length === 0
3066
+ skip: !enableDraftRelationsCount
2894
3067
  }
2895
3068
  );
2896
3069
  React.useEffect(() => {
@@ -3075,7 +3248,7 @@ const SelectedEntriesTableContent = ({
3075
3248
  status: row.status
3076
3249
  }
3077
3250
  ) }),
3078
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
3251
+ /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
3079
3252
  IconButton,
3080
3253
  {
3081
3254
  tag: Link,
@@ -3098,9 +3271,10 @@ const SelectedEntriesTableContent = ({
3098
3271
  ),
3099
3272
  target: "_blank",
3100
3273
  marginLeft: "auto",
3101
- children: /* @__PURE__ */ jsx(Pencil, {})
3274
+ variant: "ghost",
3275
+ children: /* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" })
3102
3276
  }
3103
- ) })
3277
+ ) }) })
3104
3278
  ] }, row.id)) })
3105
3279
  ] });
3106
3280
  };
@@ -3137,7 +3311,13 @@ const SelectedEntriesModalContent = ({
3137
3311
  );
3138
3312
  const { rows, validationErrors } = React.useMemo(() => {
3139
3313
  if (data.length > 0 && schema) {
3140
- const validate = createYupSchema(schema.attributes, components);
3314
+ const validate = createYupSchema(
3315
+ schema.attributes,
3316
+ components,
3317
+ // Since this is the "Publish" action, the validation
3318
+ // schema must enforce the rules for published entities
3319
+ { status: "published" }
3320
+ );
3141
3321
  const validationErrors2 = {};
3142
3322
  const rows2 = data.map((entry) => {
3143
3323
  try {
@@ -3487,7 +3667,7 @@ const TableActions = ({ document }) => {
3487
3667
  DescriptionComponentRenderer,
3488
3668
  {
3489
3669
  props,
3490
- descriptions: plugins["content-manager"].apis.getDocumentActions(),
3670
+ descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
3491
3671
  children: (actions2) => {
3492
3672
  const tableRowActions = actions2.filter((action) => {
3493
3673
  const positions = Array.isArray(action.position) ? action.position : [action.position];
@@ -3598,7 +3778,7 @@ const CloneAction = ({ model, documentId }) => {
3598
3778
  }),
3599
3779
  content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
3600
3780
  footer: ({ onClose }) => {
3601
- return /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", children: [
3781
+ return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
3602
3782
  /* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
3603
3783
  id: "cancel",
3604
3784
  defaultMessage: "Cancel"
@@ -3829,7 +4009,7 @@ const index = {
3829
4009
  app.router.addRoute({
3830
4010
  path: "content-manager/*",
3831
4011
  lazy: async () => {
3832
- const { Layout } = await import("./layout-DPaHUusj.mjs");
4012
+ const { Layout } = await import("./layout-2CfjL0T9.mjs");
3833
4013
  return {
3834
4014
  Component: Layout
3835
4015
  };
@@ -3846,7 +4026,7 @@ const index = {
3846
4026
  async registerTrads({ locales }) {
3847
4027
  const importedTrads = await Promise.all(
3848
4028
  locales.map((locale) => {
3849
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-BrCTWlZv.mjs"), "./translations/es.json": () => import("./es-CeXiYflN.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr-CD9VFbPM.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-CtsUxOvk.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
4029
+ 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 }) => {
3850
4030
  return {
3851
4031
  data: prefixPluginTranslations(data, PLUGIN_ID),
3852
4032
  locale
@@ -3867,13 +4047,15 @@ export {
3867
4047
  BulkActionsRenderer as B,
3868
4048
  COLLECTION_TYPES as C,
3869
4049
  DocumentStatus as D,
3870
- DEFAULT_SETTINGS as E,
3871
- convertEditLayoutToFieldLayouts as F,
3872
- useDocument as G,
4050
+ extractContentTypeComponents as E,
4051
+ DEFAULT_SETTINGS as F,
4052
+ convertEditLayoutToFieldLayouts as G,
3873
4053
  HOOKS as H,
3874
4054
  InjectionZone as I,
3875
- index as J,
3876
- useDocumentActions as K,
4055
+ useDocument as J,
4056
+ index as K,
4057
+ useContentManagerContext as L,
4058
+ useDocumentActions as M,
3877
4059
  Panels as P,
3878
4060
  RelativeTime as R,
3879
4061
  SINGLE_TYPES as S,
@@ -3891,18 +4073,18 @@ export {
3891
4073
  PERMISSIONS as k,
3892
4074
  DocumentRBAC as l,
3893
4075
  DOCUMENT_META_FIELDS as m,
3894
- useDocLayout as n,
3895
- useGetContentTypeConfigurationQuery as o,
3896
- CREATOR_FIELDS as p,
3897
- getMainField as q,
3898
- getDisplayName as r,
4076
+ CLONE_PATH as n,
4077
+ useDocLayout as o,
4078
+ useGetContentTypeConfigurationQuery as p,
4079
+ CREATOR_FIELDS as q,
4080
+ getMainField as r,
3899
4081
  setInitialData as s,
3900
- checkIfAttributeIsDisplayable as t,
4082
+ getDisplayName as t,
3901
4083
  useContentTypeSchema as u,
3902
- useGetAllDocumentsQuery as v,
3903
- convertListLayoutToFieldLayouts as w,
3904
- capitalise as x,
3905
- useUpdateContentTypeConfigurationMutation as y,
3906
- extractContentTypeComponents as z
4084
+ checkIfAttributeIsDisplayable as v,
4085
+ useGetAllDocumentsQuery as w,
4086
+ convertListLayoutToFieldLayouts as x,
4087
+ capitalise as y,
4088
+ useUpdateContentTypeConfigurationMutation as z
3907
4089
  };
3908
- //# sourceMappingURL=index-BSn97i8U.mjs.map
4090
+ //# sourceMappingURL=index-wnqzm4Q8.mjs.map