@strapi/content-manager 0.0.0-experimental.545ccead2ee1717bbc7ab950455dbb0ddb9924a3 → 0.0.0-experimental.550e739e36d7678bd8317b48acab2f24b1f4dcd6
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.
- package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -1
- package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-Bqgx7Mes.js → ComponentConfigurationPage-CJPoOvy3.js} +5 -6
- package/dist/_chunks/{ComponentConfigurationPage-Bqgx7Mes.js.map → ComponentConfigurationPage-CJPoOvy3.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-B1bIXVuX.mjs → ComponentConfigurationPage-CcRDqD0e.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-B1bIXVuX.mjs.map → ComponentConfigurationPage-CcRDqD0e.mjs.map} +1 -1
- package/dist/_chunks/{ComponentIcon-BXdiCGQp.js → ComponentIcon-CRbtQEUV.js} +2 -3
- package/dist/_chunks/{ComponentIcon-BXdiCGQp.js.map → ComponentIcon-CRbtQEUV.js.map} +1 -1
- package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -1
- package/dist/_chunks/{EditConfigurationPage-ZO0vOO8q.mjs → EditConfigurationPage-C1ddZ_zf.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-ZO0vOO8q.mjs.map → EditConfigurationPage-C1ddZ_zf.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-BFEwvdMW.js → EditConfigurationPage-CF3lxOy2.js} +5 -6
- package/dist/_chunks/{EditConfigurationPage-BFEwvdMW.js.map → EditConfigurationPage-CF3lxOy2.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-DlLEyUL6.mjs → EditViewPage-BPFcUbqi.mjs} +63 -12
- package/dist/_chunks/EditViewPage-BPFcUbqi.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-DA95Ha6J.js → EditViewPage-CDyTC6aU.js} +63 -13
- package/dist/_chunks/EditViewPage-CDyTC6aU.js.map +1 -0
- package/dist/_chunks/{Field-CnK8dO8N.js → Field-DuxAW9q2.js} +344 -220
- package/dist/_chunks/Field-DuxAW9q2.js.map +1 -0
- package/dist/_chunks/{Field-Dq7bDnuh.mjs → Field-fBnTwgU4.mjs} +340 -216
- package/dist/_chunks/Field-fBnTwgU4.mjs.map +1 -0
- package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
- package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
- package/dist/_chunks/{Form-B_JE0dbz.mjs → Form-BGl7PhlZ.mjs} +37 -18
- package/dist/_chunks/Form-BGl7PhlZ.mjs.map +1 -0
- package/dist/_chunks/{Form-BpiR4piS.js → Form-DSGh_zkz.js} +39 -21
- package/dist/_chunks/Form-DSGh_zkz.js.map +1 -0
- package/dist/_chunks/{History-CBNGU7a-.mjs → History-DTYB9CSB.mjs} +59 -106
- package/dist/_chunks/History-DTYB9CSB.mjs.map +1 -0
- package/dist/_chunks/{History-DdIstl8b.js → History-DrDJv698.js} +58 -106
- package/dist/_chunks/History-DrDJv698.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-5dr4qpue.mjs → ListConfigurationPage-qWx8r4D_.mjs} +19 -8
- package/dist/_chunks/ListConfigurationPage-qWx8r4D_.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DkKRparB.js → ListConfigurationPage-zurIlUZ7.js} +19 -9
- package/dist/_chunks/ListConfigurationPage-zurIlUZ7.js.map +1 -0
- package/dist/_chunks/{ListViewPage-wE0lXqoD.js → ListViewPage-DTM2uO_S.js} +109 -78
- package/dist/_chunks/ListViewPage-DTM2uO_S.js.map +1 -0
- package/dist/_chunks/{ListViewPage-DecLrYV6.mjs → ListViewPage-GKpL5p8A.mjs} +106 -74
- package/dist/_chunks/ListViewPage-GKpL5p8A.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-CiIcfYsd.mjs → NoContentTypePage-B5Vc5Cal.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CiIcfYsd.mjs.map → NoContentTypePage-B5Vc5Cal.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-DEKR6tf9.js → NoContentTypePage-BuZlNroO.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-DEKR6tf9.js.map → NoContentTypePage-BuZlNroO.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-CM5UD8ee.mjs → NoPermissionsPage-BAZlWgJ4.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-CM5UD8ee.mjs.map → NoPermissionsPage-BAZlWgJ4.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DmNfF2Bb.js → NoPermissionsPage-DLzkS4Hy.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DmNfF2Bb.js.map → NoPermissionsPage-DLzkS4Hy.js.map} +1 -1
- package/dist/_chunks/Preview-VOJ8RuQp.js +312 -0
- package/dist/_chunks/Preview-VOJ8RuQp.js.map +1 -0
- package/dist/_chunks/Preview-Zzjg2_K_.mjs +294 -0
- package/dist/_chunks/Preview-Zzjg2_K_.mjs.map +1 -0
- package/dist/_chunks/{Relations-Dqz0C1fz.mjs → Relations-BVdRfDkW.mjs} +76 -42
- package/dist/_chunks/Relations-BVdRfDkW.mjs.map +1 -0
- package/dist/_chunks/{Relations-L0xYRoSQ.js → Relations-Dsj0boFJ.js} +76 -43
- package/dist/_chunks/Relations-Dsj0boFJ.js.map +1 -0
- package/dist/_chunks/{en-uOUIxfcQ.js → en-BzQmavmK.js} +33 -15
- package/dist/_chunks/{en-uOUIxfcQ.js.map → en-BzQmavmK.js.map} +1 -1
- package/dist/_chunks/{en-BrCTWlZv.mjs → en-CSxLmrh1.mjs} +33 -15
- package/dist/_chunks/{en-BrCTWlZv.mjs.map → en-CSxLmrh1.mjs.map} +1 -1
- package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
- package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
- package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
- package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
- package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
- package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
- package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
- package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
- package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
- package/dist/_chunks/{index-BSn97i8U.mjs → index-Bu_-B7ZA.mjs} +1143 -767
- package/dist/_chunks/index-Bu_-B7ZA.mjs.map +1 -0
- package/dist/_chunks/{index-DyvUPg1a.js → index-Ct-GZ0iV.js} +1125 -749
- package/dist/_chunks/index-Ct-GZ0iV.js.map +1 -0
- package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
- package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
- package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
- package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
- package/dist/_chunks/{layout-TPqF2oJ5.js → layout-CDBEgRsM.js} +23 -11
- package/dist/_chunks/layout-CDBEgRsM.js.map +1 -0
- package/dist/_chunks/{layout-DPaHUusj.mjs → layout-COzAvgJh.mjs} +23 -10
- package/dist/_chunks/layout-COzAvgJh.mjs.map +1 -0
- package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
- package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
- package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
- package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
- package/dist/_chunks/{relations-BWYS9gkn.js → relations-BjiF1Aad.js} +6 -7
- package/dist/_chunks/relations-BjiF1Aad.js.map +1 -0
- package/dist/_chunks/{relations-Ck7-ecDT.mjs → relations-BtmMFBpM.mjs} +6 -7
- package/dist/_chunks/relations-BtmMFBpM.mjs.map +1 -0
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
- package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
- package/dist/admin/index.js +3 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +6 -4
- package/dist/admin/src/content-manager.d.ts +3 -2
- package/dist/admin/src/exports.d.ts +2 -1
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +3 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +7 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +4 -48
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
- package/dist/admin/src/preview/index.d.ts +4 -0
- package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
- package/dist/admin/src/preview/routes.d.ts +3 -0
- package/dist/admin/src/preview/services/preview.d.ts +3 -0
- package/dist/admin/src/router.d.ts +1 -1
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +19 -20
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/validation.d.ts +4 -1
- package/dist/server/index.js +682 -360
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +683 -360
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/metadata.d.ts +16 -1
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +4 -4
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +7 -6
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/preview/controllers/index.d.ts +2 -0
- package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/preview.d.ts +13 -0
- package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
- package/dist/server/src/preview/index.d.ts +4 -0
- package/dist/server/src/preview/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/index.d.ts +8 -0
- package/dist/server/src/preview/routes/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/preview.d.ts +4 -0
- package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
- package/dist/server/src/preview/services/index.d.ts +16 -0
- package/dist/server/src/preview/services/index.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview-config.d.ts +32 -0
- package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview.d.ts +12 -0
- package/dist/server/src/preview/services/preview.d.ts.map +1 -0
- package/dist/server/src/preview/utils.d.ts +19 -0
- package/dist/server/src/preview/utils.d.ts.map +1 -0
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +12 -10
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +7 -6
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.d.ts +2 -2
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +3 -1
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/dist/shared/contracts/index.d.ts +1 -0
- package/dist/shared/contracts/index.d.ts.map +1 -1
- package/dist/shared/contracts/preview.d.ts +27 -0
- package/dist/shared/contracts/preview.d.ts.map +1 -0
- package/dist/shared/index.js +4 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +4 -0
- package/dist/shared/index.mjs.map +1 -1
- package/package.json +17 -15
- package/dist/_chunks/EditViewPage-DA95Ha6J.js.map +0 -1
- package/dist/_chunks/EditViewPage-DlLEyUL6.mjs.map +0 -1
- package/dist/_chunks/Field-CnK8dO8N.js.map +0 -1
- package/dist/_chunks/Field-Dq7bDnuh.mjs.map +0 -1
- package/dist/_chunks/Form-B_JE0dbz.mjs.map +0 -1
- package/dist/_chunks/Form-BpiR4piS.js.map +0 -1
- package/dist/_chunks/History-CBNGU7a-.mjs.map +0 -1
- package/dist/_chunks/History-DdIstl8b.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-5dr4qpue.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DkKRparB.js.map +0 -1
- package/dist/_chunks/ListViewPage-DecLrYV6.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-wE0lXqoD.js.map +0 -1
- package/dist/_chunks/Relations-Dqz0C1fz.mjs.map +0 -1
- package/dist/_chunks/Relations-L0xYRoSQ.js.map +0 -1
- package/dist/_chunks/index-BSn97i8U.mjs.map +0 -1
- package/dist/_chunks/index-DyvUPg1a.js.map +0 -1
- package/dist/_chunks/layout-DPaHUusj.mjs.map +0 -1
- package/dist/_chunks/layout-TPqF2oJ5.js.map +0 -1
- package/dist/_chunks/relations-BWYS9gkn.js.map +0 -1
- package/dist/_chunks/relations-Ck7-ecDT.mjs.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
@@ -1,25 +1,33 @@
|
|
1
|
-
import {
|
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,
|
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 {
|
6
|
+
import { Menu, Button, VisuallyHidden, Flex, Dialog, Modal, Typography, Radio, Status, Box, SingleSelect, SingleSelectOption, IconButton, Loader, Tooltip, LinkButton } from "@strapi/design-system";
|
7
|
+
import mapValues from "lodash/fp/mapValues";
|
7
8
|
import { useIntl } from "react-intl";
|
8
|
-
import { useParams,
|
9
|
+
import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
9
10
|
import { styled } from "styled-components";
|
10
11
|
import * as yup from "yup";
|
11
12
|
import { ValidationError } from "yup";
|
13
|
+
import { stringify } from "qs";
|
12
14
|
import pipe from "lodash/fp/pipe";
|
13
15
|
import { intervalToDuration, isPast } from "date-fns";
|
14
|
-
import { stringify } from "qs";
|
15
16
|
import { createSlice, combineReducers } from "@reduxjs/toolkit";
|
16
|
-
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
17
|
+
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
17
18
|
const v = glob[path];
|
18
19
|
if (v) {
|
19
20
|
return typeof v === "function" ? v() : Promise.resolve(v);
|
20
21
|
}
|
21
22
|
return new Promise((_, reject) => {
|
22
|
-
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
23
|
+
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
24
|
+
reject.bind(
|
25
|
+
null,
|
26
|
+
new Error(
|
27
|
+
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
28
|
+
)
|
29
|
+
)
|
30
|
+
);
|
23
31
|
});
|
24
32
|
};
|
25
33
|
const PLUGIN_ID = "content-manager";
|
@@ -100,6 +108,7 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
100
108
|
if (!slug) {
|
101
109
|
throw new Error("Cannot find the slug param in the URL");
|
102
110
|
}
|
111
|
+
const [{ rawQuery }] = useQueryParams();
|
103
112
|
const userPermissions = useAuth("DocumentRBAC", (state) => state.permissions);
|
104
113
|
const contentTypePermissions = React.useMemo(() => {
|
105
114
|
const contentTypePermissions2 = userPermissions.filter(
|
@@ -110,7 +119,14 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
110
119
|
return { ...acc, [action]: [permission] };
|
111
120
|
}, {});
|
112
121
|
}, [slug, userPermissions]);
|
113
|
-
const { isLoading, allowedActions } = useRBAC(
|
122
|
+
const { isLoading, allowedActions } = useRBAC(
|
123
|
+
contentTypePermissions,
|
124
|
+
permissions ?? void 0,
|
125
|
+
// TODO: useRBAC context should be typed and built differently
|
126
|
+
// We are passing raw query as context to the hook so that it can
|
127
|
+
// rely on the locale provided from DocumentRBAC for its permission calculations.
|
128
|
+
rawQuery
|
129
|
+
);
|
114
130
|
const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
|
115
131
|
const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
|
116
132
|
const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
|
@@ -158,7 +174,9 @@ const contentManagerApi = adminApi.enhanceEndpoints({
|
|
158
174
|
"Document",
|
159
175
|
"InitialData",
|
160
176
|
"HistoryVersion",
|
161
|
-
"Relations"
|
177
|
+
"Relations",
|
178
|
+
"UidAvailability",
|
179
|
+
"RecentDocumentList"
|
162
180
|
]
|
163
181
|
});
|
164
182
|
const documentApi = contentManagerApi.injectEndpoints({
|
@@ -172,7 +190,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
172
190
|
params: query
|
173
191
|
}
|
174
192
|
}),
|
175
|
-
invalidatesTags: (_result,
|
193
|
+
invalidatesTags: (_result, error, { model }) => {
|
194
|
+
if (error) {
|
195
|
+
return [];
|
196
|
+
}
|
197
|
+
return [{ type: "Document", id: `${model}_LIST` }, "RecentDocumentList"];
|
198
|
+
}
|
176
199
|
}),
|
177
200
|
cloneDocument: builder.mutation({
|
178
201
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -183,7 +206,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
183
206
|
params
|
184
207
|
}
|
185
208
|
}),
|
186
|
-
invalidatesTags: (_result, _error, { model }) => [
|
209
|
+
invalidatesTags: (_result, _error, { model }) => [
|
210
|
+
{ type: "Document", id: `${model}_LIST` },
|
211
|
+
{ type: "UidAvailability", id: model },
|
212
|
+
"RecentDocumentList"
|
213
|
+
]
|
187
214
|
}),
|
188
215
|
/**
|
189
216
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -200,8 +227,22 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
200
227
|
}),
|
201
228
|
invalidatesTags: (result, _error, { model }) => [
|
202
229
|
{ type: "Document", id: `${model}_LIST` },
|
203
|
-
"Relations"
|
204
|
-
|
230
|
+
"Relations",
|
231
|
+
{ type: "UidAvailability", id: model },
|
232
|
+
"RecentDocumentList"
|
233
|
+
],
|
234
|
+
transformResponse: (response, meta, arg) => {
|
235
|
+
if (!("data" in response) && arg.model === "plugin::users-permissions.user") {
|
236
|
+
return {
|
237
|
+
data: response,
|
238
|
+
meta: {
|
239
|
+
availableStatus: [],
|
240
|
+
availableLocales: []
|
241
|
+
}
|
242
|
+
};
|
243
|
+
}
|
244
|
+
return response;
|
245
|
+
}
|
205
246
|
}),
|
206
247
|
deleteDocument: builder.mutation({
|
207
248
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -212,7 +253,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
212
253
|
}
|
213
254
|
}),
|
214
255
|
invalidatesTags: (_result, _error, { collectionType, model }) => [
|
215
|
-
{ type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model }
|
256
|
+
{ type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model },
|
257
|
+
"RecentDocumentList"
|
216
258
|
]
|
217
259
|
}),
|
218
260
|
deleteManyDocuments: builder.mutation({
|
@@ -224,7 +266,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
224
266
|
params
|
225
267
|
}
|
226
268
|
}),
|
227
|
-
invalidatesTags: (_res, _error, { model }) => [
|
269
|
+
invalidatesTags: (_res, _error, { model }) => [
|
270
|
+
{ type: "Document", id: `${model}_LIST` },
|
271
|
+
"RecentDocumentList"
|
272
|
+
]
|
228
273
|
}),
|
229
274
|
discardDocument: builder.mutation({
|
230
275
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -241,7 +286,9 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
241
286
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
242
287
|
},
|
243
288
|
{ type: "Document", id: `${model}_LIST` },
|
244
|
-
"Relations"
|
289
|
+
"Relations",
|
290
|
+
{ type: "UidAvailability", id: model },
|
291
|
+
"RecentDocumentList"
|
245
292
|
];
|
246
293
|
}
|
247
294
|
}),
|
@@ -254,11 +301,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
254
301
|
url: `/content-manager/collection-types/${model}`,
|
255
302
|
method: "GET",
|
256
303
|
config: {
|
257
|
-
params
|
304
|
+
params: stringify(params, { encode: true })
|
258
305
|
}
|
259
306
|
}),
|
260
307
|
providesTags: (result, _error, arg) => {
|
261
308
|
return [
|
309
|
+
{ type: "Document", id: `ALL_LIST` },
|
262
310
|
{ type: "Document", id: `${arg.model}_LIST` },
|
263
311
|
...result?.results.map(({ documentId }) => ({
|
264
312
|
type: "Document",
|
@@ -297,6 +345,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
297
345
|
{
|
298
346
|
type: "Document",
|
299
347
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
348
|
+
},
|
349
|
+
// Make it easy to invalidate all individual documents queries for a model
|
350
|
+
{
|
351
|
+
type: "Document",
|
352
|
+
id: `${model}_ALL_ITEMS`
|
300
353
|
}
|
301
354
|
];
|
302
355
|
}
|
@@ -330,7 +383,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
330
383
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
331
384
|
},
|
332
385
|
{ type: "Document", id: `${model}_LIST` },
|
333
|
-
"Relations"
|
386
|
+
"Relations",
|
387
|
+
"RecentDocumentList"
|
334
388
|
];
|
335
389
|
}
|
336
390
|
}),
|
@@ -360,8 +414,23 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
360
414
|
type: "Document",
|
361
415
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
362
416
|
},
|
363
|
-
"Relations"
|
417
|
+
"Relations",
|
418
|
+
{ type: "UidAvailability", id: model },
|
419
|
+
"RecentDocumentList",
|
420
|
+
"RecentDocumentList"
|
364
421
|
];
|
422
|
+
},
|
423
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
424
|
+
const patchResult = dispatch(
|
425
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
426
|
+
Object.assign(draft.data, data);
|
427
|
+
})
|
428
|
+
);
|
429
|
+
try {
|
430
|
+
await queryFulfilled;
|
431
|
+
} catch {
|
432
|
+
patchResult.undo();
|
433
|
+
}
|
365
434
|
}
|
366
435
|
}),
|
367
436
|
unpublishDocument: builder.mutation({
|
@@ -378,7 +447,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
378
447
|
{
|
379
448
|
type: "Document",
|
380
449
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
381
|
-
}
|
450
|
+
},
|
451
|
+
"RecentDocumentList"
|
382
452
|
];
|
383
453
|
}
|
384
454
|
}),
|
@@ -391,7 +461,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
391
461
|
params
|
392
462
|
}
|
393
463
|
}),
|
394
|
-
invalidatesTags: (_res, _error, { model, documentIds }) =>
|
464
|
+
invalidatesTags: (_res, _error, { model, documentIds }) => [
|
465
|
+
...documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` })),
|
466
|
+
"RecentDocumentList"
|
467
|
+
]
|
395
468
|
})
|
396
469
|
})
|
397
470
|
});
|
@@ -414,8 +487,7 @@ const {
|
|
414
487
|
useUnpublishManyDocumentsMutation
|
415
488
|
} = documentApi;
|
416
489
|
const buildValidParams = (query) => {
|
417
|
-
if (!query)
|
418
|
-
return query;
|
490
|
+
if (!query) return query;
|
419
491
|
const { plugins: _, ...validQueryParams } = {
|
420
492
|
...query,
|
421
493
|
...Object.values(query?.plugins ?? {}).reduce(
|
@@ -423,28 +495,44 @@ const buildValidParams = (query) => {
|
|
423
495
|
{}
|
424
496
|
)
|
425
497
|
};
|
426
|
-
if ("_q" in validQueryParams) {
|
427
|
-
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
428
|
-
}
|
429
498
|
return validQueryParams;
|
430
499
|
};
|
431
500
|
const isBaseQueryError = (error) => {
|
432
501
|
return error.name !== void 0;
|
433
502
|
};
|
434
|
-
const
|
503
|
+
const arrayValidator = (attribute, options) => ({
|
504
|
+
message: translatedErrors.required,
|
505
|
+
test(value) {
|
506
|
+
if (options.status === "draft") {
|
507
|
+
return true;
|
508
|
+
}
|
509
|
+
if (!attribute.required) {
|
510
|
+
return true;
|
511
|
+
}
|
512
|
+
if (!value) {
|
513
|
+
return false;
|
514
|
+
}
|
515
|
+
if (Array.isArray(value) && value.length === 0) {
|
516
|
+
return false;
|
517
|
+
}
|
518
|
+
return true;
|
519
|
+
}
|
520
|
+
});
|
521
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
435
522
|
const createModelSchema = (attributes2) => yup.object().shape(
|
436
523
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
437
524
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
438
525
|
return acc;
|
439
526
|
}
|
440
527
|
const validations = [
|
528
|
+
addNullableValidation,
|
441
529
|
addRequiredValidation,
|
442
530
|
addMinLengthValidation,
|
443
531
|
addMaxLengthValidation,
|
444
532
|
addMinValidation,
|
445
533
|
addMaxValidation,
|
446
534
|
addRegexValidation
|
447
|
-
].map((fn) => fn(attribute));
|
535
|
+
].map((fn) => fn(attribute, options));
|
448
536
|
const transformSchema = pipe(...validations);
|
449
537
|
switch (attribute.type) {
|
450
538
|
case "component": {
|
@@ -454,12 +542,12 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
454
542
|
...acc,
|
455
543
|
[name]: transformSchema(
|
456
544
|
yup.array().of(createModelSchema(attributes3).nullable(false))
|
457
|
-
)
|
545
|
+
).test(arrayValidator(attribute, options))
|
458
546
|
};
|
459
547
|
} else {
|
460
548
|
return {
|
461
549
|
...acc,
|
462
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
550
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
463
551
|
};
|
464
552
|
}
|
465
553
|
}
|
@@ -481,7 +569,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
481
569
|
}
|
482
570
|
)
|
483
571
|
)
|
484
|
-
)
|
572
|
+
).test(arrayValidator(attribute, options))
|
485
573
|
};
|
486
574
|
case "relation":
|
487
575
|
return {
|
@@ -493,7 +581,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
493
581
|
} else if (Array.isArray(value)) {
|
494
582
|
return yup.array().of(
|
495
583
|
yup.object().shape({
|
496
|
-
id: yup.
|
584
|
+
id: yup.number().required()
|
497
585
|
})
|
498
586
|
);
|
499
587
|
} else if (typeof value === "object") {
|
@@ -545,6 +633,14 @@ const createAttributeSchema = (attribute) => {
|
|
545
633
|
if (!value || typeof value === "string" && value.length === 0) {
|
546
634
|
return true;
|
547
635
|
}
|
636
|
+
if (typeof value === "object") {
|
637
|
+
try {
|
638
|
+
JSON.stringify(value);
|
639
|
+
return true;
|
640
|
+
} catch (err) {
|
641
|
+
return false;
|
642
|
+
}
|
643
|
+
}
|
548
644
|
try {
|
549
645
|
JSON.parse(value);
|
550
646
|
return true;
|
@@ -563,13 +659,7 @@ const createAttributeSchema = (attribute) => {
|
|
563
659
|
return yup.mixed();
|
564
660
|
}
|
565
661
|
};
|
566
|
-
const
|
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
|
-
}
|
662
|
+
const nullableSchema = (schema) => {
|
573
663
|
return schema?.nullable ? schema.nullable() : (
|
574
664
|
// In some cases '.nullable' will not be available on the schema.
|
575
665
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -577,7 +667,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
577
667
|
schema
|
578
668
|
);
|
579
669
|
};
|
580
|
-
const
|
670
|
+
const addNullableValidation = () => (schema) => {
|
671
|
+
return nullableSchema(schema);
|
672
|
+
};
|
673
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
674
|
+
if (options.status === "draft" || !attribute.required) {
|
675
|
+
return schema;
|
676
|
+
}
|
677
|
+
if (attribute.required && "required" in schema) {
|
678
|
+
return schema.required(translatedErrors.required);
|
679
|
+
}
|
680
|
+
return schema;
|
681
|
+
};
|
682
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
683
|
+
if (options.status === "draft") {
|
684
|
+
return schema;
|
685
|
+
}
|
581
686
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
582
687
|
return schema.min(attribute.minLength, {
|
583
688
|
...translatedErrors.minLength,
|
@@ -599,32 +704,13 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
599
704
|
}
|
600
705
|
return schema;
|
601
706
|
};
|
602
|
-
const addMinValidation = (attribute) => (schema) => {
|
603
|
-
if ("
|
707
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
708
|
+
if (options.status === "draft") {
|
709
|
+
return schema;
|
710
|
+
}
|
711
|
+
if ("min" in attribute && "min" in schema) {
|
604
712
|
const min = toInteger(attribute.min);
|
605
|
-
if (
|
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) {
|
713
|
+
if (min) {
|
628
714
|
return schema.min(min, {
|
629
715
|
...translatedErrors.min,
|
630
716
|
values: {
|
@@ -742,19 +828,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
742
828
|
}, {});
|
743
829
|
return componentsByKey;
|
744
830
|
};
|
745
|
-
const
|
831
|
+
const HOOKS = {
|
832
|
+
/**
|
833
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
834
|
+
* @constant
|
835
|
+
* @type {string}
|
836
|
+
*/
|
837
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
838
|
+
/**
|
839
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
840
|
+
* @constant
|
841
|
+
* @type {string}
|
842
|
+
*/
|
843
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
844
|
+
/**
|
845
|
+
* Hook that allows to mutate the CM's edit view layout
|
846
|
+
* @constant
|
847
|
+
* @type {string}
|
848
|
+
*/
|
849
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
850
|
+
/**
|
851
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
852
|
+
* @constant
|
853
|
+
* @type {string}
|
854
|
+
*/
|
855
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
856
|
+
};
|
857
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
858
|
+
endpoints: (builder) => ({
|
859
|
+
getContentTypeConfiguration: builder.query({
|
860
|
+
query: (uid) => ({
|
861
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
862
|
+
method: "GET"
|
863
|
+
}),
|
864
|
+
transformResponse: (response) => response.data,
|
865
|
+
providesTags: (_result, _error, uid) => [
|
866
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
867
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
868
|
+
]
|
869
|
+
}),
|
870
|
+
getAllContentTypeSettings: builder.query({
|
871
|
+
query: () => "/content-manager/content-types-settings",
|
872
|
+
transformResponse: (response) => response.data,
|
873
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
874
|
+
}),
|
875
|
+
updateContentTypeConfiguration: builder.mutation({
|
876
|
+
query: ({ uid, ...body }) => ({
|
877
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
878
|
+
method: "PUT",
|
879
|
+
data: body
|
880
|
+
}),
|
881
|
+
transformResponse: (response) => response.data,
|
882
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
883
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
884
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
885
|
+
// Is this necessary?
|
886
|
+
{ type: "InitialData" }
|
887
|
+
]
|
888
|
+
})
|
889
|
+
})
|
890
|
+
});
|
891
|
+
const {
|
892
|
+
useGetContentTypeConfigurationQuery,
|
893
|
+
useGetAllContentTypeSettingsQuery,
|
894
|
+
useUpdateContentTypeConfigurationMutation
|
895
|
+
} = contentTypesApi;
|
896
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
897
|
+
const { type } = attribute;
|
898
|
+
if (type === "relation") {
|
899
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
900
|
+
}
|
901
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
902
|
+
};
|
903
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
904
|
+
if (!mainFieldName) {
|
905
|
+
return void 0;
|
906
|
+
}
|
907
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
908
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
909
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
910
|
+
);
|
911
|
+
return {
|
912
|
+
name: mainFieldName,
|
913
|
+
type: mainFieldType ?? "string"
|
914
|
+
};
|
915
|
+
};
|
916
|
+
const DEFAULT_SETTINGS = {
|
917
|
+
bulkable: false,
|
918
|
+
filterable: false,
|
919
|
+
searchable: false,
|
920
|
+
pagination: false,
|
921
|
+
defaultSortBy: "",
|
922
|
+
defaultSortOrder: "asc",
|
923
|
+
mainField: "id",
|
924
|
+
pageSize: 10
|
925
|
+
};
|
926
|
+
const useDocumentLayout = (model) => {
|
927
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
928
|
+
const [{ query }] = useQueryParams();
|
929
|
+
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
746
930
|
const { toggleNotification } = useNotification();
|
747
931
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
932
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
748
933
|
const {
|
749
|
-
|
750
|
-
isLoading:
|
751
|
-
|
752
|
-
|
753
|
-
} =
|
754
|
-
|
755
|
-
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
756
|
-
});
|
757
|
-
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
934
|
+
data,
|
935
|
+
isLoading: isLoadingConfigs,
|
936
|
+
error,
|
937
|
+
isFetching: isFetchingConfigs
|
938
|
+
} = useGetContentTypeConfigurationQuery(model);
|
939
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
758
940
|
React.useEffect(() => {
|
759
941
|
if (error) {
|
760
942
|
toggleNotification({
|
@@ -762,68 +944,322 @@ const useDocument = (args, opts) => {
|
|
762
944
|
message: formatAPIError(error)
|
763
945
|
});
|
764
946
|
}
|
765
|
-
}, [
|
766
|
-
const
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
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
|
-
}
|
947
|
+
}, [error, formatAPIError, toggleNotification]);
|
948
|
+
const editLayout = React.useMemo(
|
949
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
950
|
+
layout: [],
|
951
|
+
components: {},
|
952
|
+
metadatas: {},
|
953
|
+
options: {},
|
954
|
+
settings: DEFAULT_SETTINGS
|
788
955
|
},
|
789
|
-
[
|
956
|
+
[data, isLoading, schemas, schema, components]
|
957
|
+
);
|
958
|
+
const listLayout = React.useMemo(() => {
|
959
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
960
|
+
layout: [],
|
961
|
+
metadatas: {},
|
962
|
+
options: {},
|
963
|
+
settings: DEFAULT_SETTINGS
|
964
|
+
};
|
965
|
+
}, [data, isLoading, schemas, schema, components]);
|
966
|
+
const { layout: edit } = React.useMemo(
|
967
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
968
|
+
layout: editLayout,
|
969
|
+
query
|
970
|
+
}),
|
971
|
+
[editLayout, query, runHookWaterfall]
|
790
972
|
);
|
791
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
792
973
|
return {
|
793
|
-
|
794
|
-
document: data?.data,
|
795
|
-
meta: data?.meta,
|
974
|
+
error,
|
796
975
|
isLoading,
|
797
|
-
|
798
|
-
|
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
|
-
)
|
976
|
+
edit,
|
977
|
+
list: listLayout
|
821
978
|
};
|
822
979
|
};
|
823
|
-
const
|
824
|
-
|
825
|
-
|
980
|
+
const useDocLayout = () => {
|
981
|
+
const { model } = useDoc();
|
982
|
+
return useDocumentLayout(model);
|
983
|
+
};
|
984
|
+
const formatEditLayout = (data, {
|
985
|
+
schemas,
|
986
|
+
schema,
|
987
|
+
components
|
988
|
+
}) => {
|
989
|
+
let currentPanelIndex = 0;
|
990
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
991
|
+
data.contentType.layouts.edit,
|
992
|
+
schema?.attributes,
|
993
|
+
data.contentType.metadatas,
|
994
|
+
{ configurations: data.components, schemas: components },
|
995
|
+
schemas
|
996
|
+
).reduce((panels, row) => {
|
997
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
998
|
+
panels.push([row]);
|
999
|
+
currentPanelIndex += 2;
|
1000
|
+
} else {
|
1001
|
+
if (!panels[currentPanelIndex]) {
|
1002
|
+
panels.push([row]);
|
1003
|
+
} else {
|
1004
|
+
panels[currentPanelIndex].push(row);
|
1005
|
+
}
|
1006
|
+
}
|
1007
|
+
return panels;
|
1008
|
+
}, []);
|
1009
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
1010
|
+
(acc, [uid, configuration]) => {
|
1011
|
+
acc[uid] = {
|
1012
|
+
layout: convertEditLayoutToFieldLayouts(
|
1013
|
+
configuration.layouts.edit,
|
1014
|
+
components[uid].attributes,
|
1015
|
+
configuration.metadatas,
|
1016
|
+
{ configurations: data.components, schemas: components }
|
1017
|
+
),
|
1018
|
+
settings: {
|
1019
|
+
...configuration.settings,
|
1020
|
+
icon: components[uid].info.icon,
|
1021
|
+
displayName: components[uid].info.displayName
|
1022
|
+
}
|
1023
|
+
};
|
1024
|
+
return acc;
|
1025
|
+
},
|
1026
|
+
{}
|
1027
|
+
);
|
1028
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1029
|
+
(acc, [attribute, metadata]) => {
|
1030
|
+
return {
|
1031
|
+
...acc,
|
1032
|
+
[attribute]: metadata.edit
|
1033
|
+
};
|
1034
|
+
},
|
1035
|
+
{}
|
1036
|
+
);
|
1037
|
+
return {
|
1038
|
+
layout: panelledEditAttributes,
|
1039
|
+
components: componentEditAttributes,
|
1040
|
+
metadatas: editMetadatas,
|
1041
|
+
settings: {
|
1042
|
+
...data.contentType.settings,
|
1043
|
+
displayName: schema?.info.displayName
|
1044
|
+
},
|
1045
|
+
options: {
|
1046
|
+
...schema?.options,
|
1047
|
+
...schema?.pluginOptions,
|
1048
|
+
...data.contentType.options
|
1049
|
+
}
|
1050
|
+
};
|
1051
|
+
};
|
1052
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1053
|
+
return rows.map(
|
1054
|
+
(row) => row.map((field) => {
|
1055
|
+
const attribute = attributes[field.name];
|
1056
|
+
if (!attribute) {
|
1057
|
+
return null;
|
1058
|
+
}
|
1059
|
+
const { edit: metadata } = metadatas[field.name];
|
1060
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1061
|
+
return {
|
1062
|
+
attribute,
|
1063
|
+
disabled: !metadata.editable,
|
1064
|
+
hint: metadata.description,
|
1065
|
+
label: metadata.label ?? "",
|
1066
|
+
name: field.name,
|
1067
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1068
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1069
|
+
schemas,
|
1070
|
+
components: components?.schemas ?? {}
|
1071
|
+
}),
|
1072
|
+
placeholder: metadata.placeholder ?? "",
|
1073
|
+
required: attribute.required ?? false,
|
1074
|
+
size: field.size,
|
1075
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1076
|
+
visible: metadata.visible ?? true,
|
1077
|
+
type: attribute.type
|
1078
|
+
};
|
1079
|
+
}).filter((field) => field !== null)
|
1080
|
+
);
|
1081
|
+
};
|
1082
|
+
const formatListLayout = (data, {
|
1083
|
+
schemas,
|
1084
|
+
schema,
|
1085
|
+
components
|
1086
|
+
}) => {
|
1087
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1088
|
+
(acc, [attribute, metadata]) => {
|
1089
|
+
return {
|
1090
|
+
...acc,
|
1091
|
+
[attribute]: metadata.list
|
1092
|
+
};
|
1093
|
+
},
|
1094
|
+
{}
|
1095
|
+
);
|
1096
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1097
|
+
data.contentType.layouts.list,
|
1098
|
+
schema?.attributes,
|
1099
|
+
listMetadatas,
|
1100
|
+
{ configurations: data.components, schemas: components },
|
1101
|
+
schemas
|
1102
|
+
);
|
1103
|
+
return {
|
1104
|
+
layout: listAttributes,
|
1105
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1106
|
+
metadatas: listMetadatas,
|
1107
|
+
options: {
|
1108
|
+
...schema?.options,
|
1109
|
+
...schema?.pluginOptions,
|
1110
|
+
...data.contentType.options
|
1111
|
+
}
|
1112
|
+
};
|
1113
|
+
};
|
1114
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1115
|
+
return columns.map((name) => {
|
1116
|
+
const attribute = attributes[name];
|
1117
|
+
if (!attribute) {
|
1118
|
+
return null;
|
1119
|
+
}
|
1120
|
+
const metadata = metadatas[name];
|
1121
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1122
|
+
return {
|
1123
|
+
attribute,
|
1124
|
+
label: metadata.label ?? "",
|
1125
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1126
|
+
schemas,
|
1127
|
+
components: components?.schemas ?? {}
|
1128
|
+
}),
|
1129
|
+
name,
|
1130
|
+
searchable: metadata.searchable ?? true,
|
1131
|
+
sortable: metadata.sortable ?? true
|
1132
|
+
};
|
1133
|
+
}).filter((field) => field !== null);
|
1134
|
+
};
|
1135
|
+
const useDocument = (args, opts) => {
|
1136
|
+
const { toggleNotification } = useNotification();
|
1137
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1138
|
+
const {
|
1139
|
+
currentData: data,
|
1140
|
+
isLoading: isLoadingDocument,
|
1141
|
+
isFetching: isFetchingDocument,
|
1142
|
+
error
|
1143
|
+
} = useGetDocumentQuery(args, {
|
1144
|
+
...opts,
|
1145
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1146
|
+
});
|
1147
|
+
const {
|
1148
|
+
components,
|
1149
|
+
schema,
|
1150
|
+
schemas,
|
1151
|
+
isLoading: isLoadingSchema
|
1152
|
+
} = useContentTypeSchema(args.model);
|
1153
|
+
React.useEffect(() => {
|
1154
|
+
if (error) {
|
1155
|
+
toggleNotification({
|
1156
|
+
type: "danger",
|
1157
|
+
message: formatAPIError(error)
|
1158
|
+
});
|
1159
|
+
}
|
1160
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1161
|
+
const validationSchema = React.useMemo(() => {
|
1162
|
+
if (!schema) {
|
1163
|
+
return null;
|
1164
|
+
}
|
1165
|
+
return createYupSchema(schema.attributes, components);
|
1166
|
+
}, [schema, components]);
|
1167
|
+
const validate = React.useCallback(
|
1168
|
+
(document) => {
|
1169
|
+
if (!validationSchema) {
|
1170
|
+
throw new Error(
|
1171
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1172
|
+
);
|
1173
|
+
}
|
1174
|
+
try {
|
1175
|
+
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
1176
|
+
return null;
|
1177
|
+
} catch (error2) {
|
1178
|
+
if (error2 instanceof ValidationError) {
|
1179
|
+
return getYupValidationErrors(error2);
|
1180
|
+
}
|
1181
|
+
throw error2;
|
1182
|
+
}
|
1183
|
+
},
|
1184
|
+
[validationSchema]
|
1185
|
+
);
|
1186
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1187
|
+
const hasError = !!error;
|
1188
|
+
return {
|
1189
|
+
components,
|
1190
|
+
document: data?.data,
|
1191
|
+
meta: data?.meta,
|
1192
|
+
isLoading,
|
1193
|
+
hasError,
|
1194
|
+
schema,
|
1195
|
+
schemas,
|
1196
|
+
validate
|
1197
|
+
};
|
1198
|
+
};
|
1199
|
+
const useDoc = () => {
|
1200
|
+
const { id, slug, collectionType, origin } = useParams();
|
1201
|
+
const [{ query }] = useQueryParams();
|
1202
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1203
|
+
if (!collectionType) {
|
1204
|
+
throw new Error("Could not find collectionType in url params");
|
1205
|
+
}
|
1206
|
+
if (!slug) {
|
1207
|
+
throw new Error("Could not find model in url params");
|
826
1208
|
}
|
1209
|
+
const document = useDocument(
|
1210
|
+
{ documentId: origin || id, model: slug, collectionType, params },
|
1211
|
+
{
|
1212
|
+
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
1213
|
+
}
|
1214
|
+
);
|
1215
|
+
const returnId = origin || id === "create" ? void 0 : id;
|
1216
|
+
return {
|
1217
|
+
collectionType,
|
1218
|
+
model: slug,
|
1219
|
+
id: returnId,
|
1220
|
+
...document
|
1221
|
+
};
|
1222
|
+
};
|
1223
|
+
const useContentManagerContext = () => {
|
1224
|
+
const {
|
1225
|
+
collectionType,
|
1226
|
+
model,
|
1227
|
+
id,
|
1228
|
+
components,
|
1229
|
+
isLoading: isLoadingDoc,
|
1230
|
+
schema,
|
1231
|
+
schemas
|
1232
|
+
} = useDoc();
|
1233
|
+
const layout = useDocumentLayout(model);
|
1234
|
+
const form = useForm("useContentManagerContext", (state) => state);
|
1235
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1236
|
+
const slug = model;
|
1237
|
+
const isCreatingEntry = id === "create";
|
1238
|
+
useContentTypeSchema();
|
1239
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1240
|
+
const error = layout.error;
|
1241
|
+
return {
|
1242
|
+
error,
|
1243
|
+
isLoading,
|
1244
|
+
// Base metadata
|
1245
|
+
model,
|
1246
|
+
collectionType,
|
1247
|
+
id,
|
1248
|
+
slug,
|
1249
|
+
isCreatingEntry,
|
1250
|
+
isSingleType,
|
1251
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1252
|
+
// All schema infos
|
1253
|
+
components,
|
1254
|
+
contentType: schema,
|
1255
|
+
contentTypes: schemas,
|
1256
|
+
// Form state
|
1257
|
+
form,
|
1258
|
+
// layout infos
|
1259
|
+
layout
|
1260
|
+
};
|
1261
|
+
};
|
1262
|
+
const prefixPluginTranslations = (trad, pluginId) => {
|
827
1263
|
return Object.keys(trad).reduce((acc, current) => {
|
828
1264
|
acc[`${pluginId}.${current}`] = trad[current];
|
829
1265
|
return acc;
|
@@ -839,6 +1275,8 @@ const useDocumentActions = () => {
|
|
839
1275
|
const { formatMessage } = useIntl();
|
840
1276
|
const { trackUsage } = useTracking();
|
841
1277
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1278
|
+
const navigate = useNavigate();
|
1279
|
+
const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
842
1280
|
const [deleteDocument] = useDeleteDocumentMutation();
|
843
1281
|
const _delete = React.useCallback(
|
844
1282
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1153,6 +1591,7 @@ const useDocumentActions = () => {
|
|
1153
1591
|
defaultMessage: "Saved document"
|
1154
1592
|
})
|
1155
1593
|
});
|
1594
|
+
setCurrentStep("contentManager.success");
|
1156
1595
|
return res.data;
|
1157
1596
|
} catch (err) {
|
1158
1597
|
toggleNotification({
|
@@ -1174,7 +1613,6 @@ const useDocumentActions = () => {
|
|
1174
1613
|
sourceId
|
1175
1614
|
});
|
1176
1615
|
if ("error" in res) {
|
1177
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1178
1616
|
return { error: res.error };
|
1179
1617
|
}
|
1180
1618
|
toggleNotification({
|
@@ -1193,7 +1631,7 @@ const useDocumentActions = () => {
|
|
1193
1631
|
throw err;
|
1194
1632
|
}
|
1195
1633
|
},
|
1196
|
-
[autoCloneDocument,
|
1634
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1197
1635
|
);
|
1198
1636
|
const [cloneDocument] = useCloneDocumentMutation();
|
1199
1637
|
const clone = React.useCallback(
|
@@ -1219,6 +1657,7 @@ const useDocumentActions = () => {
|
|
1219
1657
|
defaultMessage: "Cloned document"
|
1220
1658
|
})
|
1221
1659
|
});
|
1660
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1222
1661
|
return res.data;
|
1223
1662
|
} catch (err) {
|
1224
1663
|
toggleNotification({
|
@@ -1229,7 +1668,7 @@ const useDocumentActions = () => {
|
|
1229
1668
|
throw err;
|
1230
1669
|
}
|
1231
1670
|
},
|
1232
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1671
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1233
1672
|
);
|
1234
1673
|
const [getDoc] = useLazyGetDocumentQuery();
|
1235
1674
|
const getDocument = React.useCallback(
|
@@ -1254,10 +1693,10 @@ const useDocumentActions = () => {
|
|
1254
1693
|
update
|
1255
1694
|
};
|
1256
1695
|
};
|
1257
|
-
const ProtectedHistoryPage = lazy(
|
1258
|
-
() => import("./History-
|
1696
|
+
const ProtectedHistoryPage = React.lazy(
|
1697
|
+
() => import("./History-DTYB9CSB.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1259
1698
|
);
|
1260
|
-
const routes$
|
1699
|
+
const routes$2 = [
|
1261
1700
|
{
|
1262
1701
|
path: ":collectionType/:slug/:id/history",
|
1263
1702
|
Component: ProtectedHistoryPage
|
@@ -1267,32 +1706,45 @@ const routes$1 = [
|
|
1267
1706
|
Component: ProtectedHistoryPage
|
1268
1707
|
}
|
1269
1708
|
];
|
1709
|
+
const ProtectedPreviewPage = React.lazy(
|
1710
|
+
() => import("./Preview-Zzjg2_K_.mjs").then((mod) => ({ default: mod.ProtectedPreviewPage }))
|
1711
|
+
);
|
1712
|
+
const routes$1 = [
|
1713
|
+
{
|
1714
|
+
path: ":collectionType/:slug/:id/preview",
|
1715
|
+
Component: ProtectedPreviewPage
|
1716
|
+
},
|
1717
|
+
{
|
1718
|
+
path: ":collectionType/:slug/preview",
|
1719
|
+
Component: ProtectedPreviewPage
|
1720
|
+
}
|
1721
|
+
];
|
1270
1722
|
const ProtectedEditViewPage = lazy(
|
1271
|
-
() => import("./EditViewPage-
|
1723
|
+
() => import("./EditViewPage-BPFcUbqi.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1272
1724
|
);
|
1273
1725
|
const ProtectedListViewPage = lazy(
|
1274
|
-
() => import("./ListViewPage-
|
1726
|
+
() => import("./ListViewPage-GKpL5p8A.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1275
1727
|
);
|
1276
1728
|
const ProtectedListConfiguration = lazy(
|
1277
|
-
() => import("./ListConfigurationPage-
|
1729
|
+
() => import("./ListConfigurationPage-qWx8r4D_.mjs").then((mod) => ({
|
1278
1730
|
default: mod.ProtectedListConfiguration
|
1279
1731
|
}))
|
1280
1732
|
);
|
1281
1733
|
const ProtectedEditConfigurationPage = lazy(
|
1282
|
-
() => import("./EditConfigurationPage-
|
1734
|
+
() => import("./EditConfigurationPage-C1ddZ_zf.mjs").then((mod) => ({
|
1283
1735
|
default: mod.ProtectedEditConfigurationPage
|
1284
1736
|
}))
|
1285
1737
|
);
|
1286
1738
|
const ProtectedComponentConfigurationPage = lazy(
|
1287
|
-
() => import("./ComponentConfigurationPage-
|
1739
|
+
() => import("./ComponentConfigurationPage-CcRDqD0e.mjs").then((mod) => ({
|
1288
1740
|
default: mod.ProtectedComponentConfigurationPage
|
1289
1741
|
}))
|
1290
1742
|
);
|
1291
1743
|
const NoPermissions = lazy(
|
1292
|
-
() => import("./NoPermissionsPage-
|
1744
|
+
() => import("./NoPermissionsPage-BAZlWgJ4.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1293
1745
|
);
|
1294
1746
|
const NoContentType = lazy(
|
1295
|
-
() => import("./NoContentTypePage-
|
1747
|
+
() => import("./NoContentTypePage-B5Vc5Cal.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1296
1748
|
);
|
1297
1749
|
const CollectionTypePages = () => {
|
1298
1750
|
const { collectionType } = useParams();
|
@@ -1304,7 +1756,7 @@ const CollectionTypePages = () => {
|
|
1304
1756
|
const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
|
1305
1757
|
const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
|
1306
1758
|
const LIST_RELATIVE_PATH = ":collectionType/:slug";
|
1307
|
-
const LIST_PATH = `/content-manager
|
1759
|
+
const LIST_PATH = `/content-manager/collection-types/:slug`;
|
1308
1760
|
const routes = [
|
1309
1761
|
{
|
1310
1762
|
path: LIST_RELATIVE_PATH,
|
@@ -1338,6 +1790,7 @@ const routes = [
|
|
1338
1790
|
path: "no-content-types",
|
1339
1791
|
Component: NoContentType
|
1340
1792
|
},
|
1793
|
+
...routes$2,
|
1341
1794
|
...routes$1
|
1342
1795
|
];
|
1343
1796
|
const DocumentActions = ({ actions: actions2 }) => {
|
@@ -1406,12 +1859,14 @@ const DocumentActionButton = (action) => {
|
|
1406
1859
|
/* @__PURE__ */ jsx(
|
1407
1860
|
Button,
|
1408
1861
|
{
|
1409
|
-
flex:
|
1862
|
+
flex: "auto",
|
1410
1863
|
startIcon: action.icon,
|
1411
1864
|
disabled: action.disabled,
|
1412
1865
|
onClick: handleClick(action),
|
1413
1866
|
justifyContent: "center",
|
1414
1867
|
variant: action.variant || "default",
|
1868
|
+
paddingTop: "7px",
|
1869
|
+
paddingBottom: "7px",
|
1415
1870
|
children: action.label
|
1416
1871
|
}
|
1417
1872
|
),
|
@@ -1434,6 +1889,11 @@ const DocumentActionButton = (action) => {
|
|
1434
1889
|
) : null
|
1435
1890
|
] });
|
1436
1891
|
};
|
1892
|
+
const MenuItem = styled(Menu.Item)`
|
1893
|
+
&:hover {
|
1894
|
+
background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
|
1895
|
+
}
|
1896
|
+
`;
|
1437
1897
|
const DocumentActionsMenu = ({
|
1438
1898
|
actions: actions2,
|
1439
1899
|
children,
|
@@ -1476,9 +1936,9 @@ const DocumentActionsMenu = ({
|
|
1476
1936
|
disabled: isDisabled,
|
1477
1937
|
size: "S",
|
1478
1938
|
endIcon: null,
|
1479
|
-
paddingTop: "
|
1480
|
-
paddingLeft: "
|
1481
|
-
paddingRight: "
|
1939
|
+
paddingTop: "4px",
|
1940
|
+
paddingLeft: "7px",
|
1941
|
+
paddingRight: "7px",
|
1482
1942
|
variant,
|
1483
1943
|
children: [
|
1484
1944
|
/* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
|
@@ -1489,36 +1949,35 @@ const DocumentActionsMenu = ({
|
|
1489
1949
|
]
|
1490
1950
|
}
|
1491
1951
|
),
|
1492
|
-
/* @__PURE__ */ jsxs(Menu.Content, {
|
1952
|
+
/* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1493
1953
|
actions2.map((action) => {
|
1494
1954
|
return /* @__PURE__ */ jsx(
|
1495
|
-
|
1955
|
+
MenuItem,
|
1496
1956
|
{
|
1497
1957
|
disabled: action.disabled,
|
1498
1958
|
onSelect: handleClick(action),
|
1499
1959
|
display: "block",
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
] })
|
1960
|
+
isVariantDanger: action.variant === "danger",
|
1961
|
+
isDisabled: action.disabled,
|
1962
|
+
children: /* @__PURE__ */ jsx(Flex, { justifyContent: "space-between", gap: 4, children: /* @__PURE__ */ jsxs(
|
1963
|
+
Flex,
|
1964
|
+
{
|
1965
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1966
|
+
gap: 2,
|
1967
|
+
tag: "span",
|
1968
|
+
children: [
|
1969
|
+
/* @__PURE__ */ jsx(
|
1970
|
+
Flex,
|
1971
|
+
{
|
1972
|
+
tag: "span",
|
1973
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1974
|
+
children: action.icon
|
1975
|
+
}
|
1976
|
+
),
|
1977
|
+
action.label
|
1978
|
+
]
|
1979
|
+
}
|
1980
|
+
) })
|
1522
1981
|
},
|
1523
1982
|
action.id
|
1524
1983
|
);
|
@@ -1598,11 +2057,11 @@ const DocumentActionConfirmDialog = ({
|
|
1598
2057
|
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
1599
2058
|
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
1600
2059
|
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
1601
|
-
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
|
2060
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
1602
2061
|
id: "app.components.Button.cancel",
|
1603
2062
|
defaultMessage: "Cancel"
|
1604
2063
|
}) }) }),
|
1605
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2064
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1606
2065
|
id: "app.components.Button.confirm",
|
1607
2066
|
defaultMessage: "Confirm"
|
1608
2067
|
}) })
|
@@ -1625,10 +2084,22 @@ const DocumentActionModal = ({
|
|
1625
2084
|
};
|
1626
2085
|
return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
|
1627
2086
|
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
|
1628
|
-
|
1629
|
-
|
2087
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
|
2088
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1630
2089
|
] }) });
|
1631
2090
|
};
|
2091
|
+
const transformData = (data) => {
|
2092
|
+
if (Array.isArray(data)) {
|
2093
|
+
return data.map(transformData);
|
2094
|
+
}
|
2095
|
+
if (typeof data === "object" && data !== null) {
|
2096
|
+
if ("apiData" in data) {
|
2097
|
+
return data.apiData;
|
2098
|
+
}
|
2099
|
+
return mapValues(transformData)(data);
|
2100
|
+
}
|
2101
|
+
return data;
|
2102
|
+
};
|
1632
2103
|
const PublishAction$1 = ({
|
1633
2104
|
activeTab,
|
1634
2105
|
documentId,
|
@@ -1641,12 +2112,11 @@ const PublishAction$1 = ({
|
|
1641
2112
|
const navigate = useNavigate();
|
1642
2113
|
const { toggleNotification } = useNotification();
|
1643
2114
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
2115
|
+
const isListView = useMatch(LIST_PATH) !== null;
|
1644
2116
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2117
|
+
const { id } = useParams();
|
1645
2118
|
const { formatMessage } = useIntl();
|
1646
|
-
const { canPublish
|
1647
|
-
"PublishAction",
|
1648
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1649
|
-
);
|
2119
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1650
2120
|
const { publish } = useDocumentActions();
|
1651
2121
|
const [
|
1652
2122
|
countDraftRelations,
|
@@ -1698,24 +2168,25 @@ const PublishAction$1 = ({
|
|
1698
2168
|
}
|
1699
2169
|
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1700
2170
|
React.useEffect(() => {
|
1701
|
-
if (documentId) {
|
1702
|
-
|
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();
|
2171
|
+
if (!document || !document.documentId || isListView) {
|
2172
|
+
return;
|
1717
2173
|
}
|
1718
|
-
|
2174
|
+
const fetchDraftRelationsCount = async () => {
|
2175
|
+
const { data, error } = await countDraftRelations({
|
2176
|
+
collectionType,
|
2177
|
+
model,
|
2178
|
+
documentId,
|
2179
|
+
params
|
2180
|
+
});
|
2181
|
+
if (error) {
|
2182
|
+
throw error;
|
2183
|
+
}
|
2184
|
+
if (data) {
|
2185
|
+
setServerCountOfDraftRelations(data.data);
|
2186
|
+
}
|
2187
|
+
};
|
2188
|
+
fetchDraftRelationsCount();
|
2189
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
1719
2190
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1720
2191
|
if (!schema?.options?.draftAndPublish) {
|
1721
2192
|
return null;
|
@@ -1723,7 +2194,9 @@ const PublishAction$1 = ({
|
|
1723
2194
|
const performPublish = async () => {
|
1724
2195
|
setSubmitting(true);
|
1725
2196
|
try {
|
1726
|
-
const { errors } = await validate(
|
2197
|
+
const { errors } = await validate(true, {
|
2198
|
+
status: "published"
|
2199
|
+
});
|
1727
2200
|
if (errors) {
|
1728
2201
|
toggleNotification({
|
1729
2202
|
type: "danger",
|
@@ -1741,13 +2214,15 @@ const PublishAction$1 = ({
|
|
1741
2214
|
documentId,
|
1742
2215
|
params
|
1743
2216
|
},
|
1744
|
-
formValues
|
2217
|
+
transformData(formValues)
|
1745
2218
|
);
|
1746
2219
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1747
|
-
|
1748
|
-
|
1749
|
-
|
1750
|
-
|
2220
|
+
if (id === "create") {
|
2221
|
+
navigate({
|
2222
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2223
|
+
search: rawQuery
|
2224
|
+
});
|
2225
|
+
}
|
1751
2226
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1752
2227
|
setErrors(formatValidationErrors(res.error));
|
1753
2228
|
}
|
@@ -1756,7 +2231,8 @@ const PublishAction$1 = ({
|
|
1756
2231
|
}
|
1757
2232
|
};
|
1758
2233
|
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1759
|
-
const
|
2234
|
+
const enableDraftRelationsCount = false;
|
2235
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1760
2236
|
return {
|
1761
2237
|
/**
|
1762
2238
|
* Disabled when:
|
@@ -1766,18 +2242,13 @@ const PublishAction$1 = ({
|
|
1766
2242
|
* - the document is already published & not modified
|
1767
2243
|
* - the document is being created & not modified
|
1768
2244
|
* - 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
2245
|
*/
|
1772
|
-
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
2246
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1773
2247
|
label: formatMessage({
|
1774
2248
|
id: "app.utils.publish",
|
1775
2249
|
defaultMessage: "Publish"
|
1776
2250
|
}),
|
1777
2251
|
onClick: async () => {
|
1778
|
-
if (hasDraftRelations) {
|
1779
|
-
return;
|
1780
|
-
}
|
1781
2252
|
await performPublish();
|
1782
2253
|
},
|
1783
2254
|
dialog: hasDraftRelations ? {
|
@@ -1804,6 +2275,7 @@ const PublishAction$1 = ({
|
|
1804
2275
|
};
|
1805
2276
|
};
|
1806
2277
|
PublishAction$1.type = "publish";
|
2278
|
+
PublishAction$1.position = "panel";
|
1807
2279
|
const UpdateAction = ({
|
1808
2280
|
activeTab,
|
1809
2281
|
documentId,
|
@@ -1816,10 +2288,6 @@ const UpdateAction = ({
|
|
1816
2288
|
const cloneMatch = useMatch(CLONE_PATH);
|
1817
2289
|
const isCloning = cloneMatch !== null;
|
1818
2290
|
const { formatMessage } = useIntl();
|
1819
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1820
|
-
canCreate: canCreate2,
|
1821
|
-
canUpdate: canUpdate2
|
1822
|
-
}));
|
1823
2291
|
const { create, update, clone } = useDocumentActions();
|
1824
2292
|
const [{ query, rawQuery }] = useQueryParams();
|
1825
2293
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
@@ -1830,93 +2298,134 @@ const UpdateAction = ({
|
|
1830
2298
|
const validate = useForm("UpdateAction", (state) => state.validate);
|
1831
2299
|
const setErrors = useForm("UpdateAction", (state) => state.setErrors);
|
1832
2300
|
const resetForm = useForm("PublishAction", ({ resetForm: resetForm2 }) => resetForm2);
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1843
|
-
|
1844
|
-
|
1845
|
-
|
1846
|
-
|
1847
|
-
|
1848
|
-
|
1849
|
-
|
1850
|
-
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
1858
|
-
}
|
1859
|
-
|
1860
|
-
|
1861
|
-
if (
|
1862
|
-
|
2301
|
+
const handleUpdate = React.useCallback(async () => {
|
2302
|
+
setSubmitting(true);
|
2303
|
+
try {
|
2304
|
+
if (!modified) {
|
2305
|
+
return;
|
2306
|
+
}
|
2307
|
+
const { errors } = await validate(true, {
|
2308
|
+
status: "draft"
|
2309
|
+
});
|
2310
|
+
if (errors) {
|
2311
|
+
toggleNotification({
|
2312
|
+
type: "danger",
|
2313
|
+
message: formatMessage({
|
2314
|
+
id: "content-manager.validation.error",
|
2315
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2316
|
+
})
|
2317
|
+
});
|
2318
|
+
return;
|
2319
|
+
}
|
2320
|
+
if (isCloning) {
|
2321
|
+
const res = await clone(
|
2322
|
+
{
|
2323
|
+
model,
|
2324
|
+
documentId: cloneMatch.params.origin,
|
2325
|
+
params
|
2326
|
+
},
|
2327
|
+
transformData(document)
|
2328
|
+
);
|
2329
|
+
if ("data" in res) {
|
2330
|
+
navigate(
|
1863
2331
|
{
|
1864
|
-
|
1865
|
-
documentId: cloneMatch.params.origin,
|
1866
|
-
params
|
1867
|
-
},
|
1868
|
-
document
|
1869
|
-
);
|
1870
|
-
if ("data" in res) {
|
1871
|
-
navigate({
|
1872
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2332
|
+
pathname: `../${res.data.documentId}`,
|
1873
2333
|
search: rawQuery
|
1874
|
-
});
|
1875
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1876
|
-
setErrors(formatValidationErrors(res.error));
|
1877
|
-
}
|
1878
|
-
} else if (documentId || collectionType === SINGLE_TYPES) {
|
1879
|
-
const res = await update(
|
1880
|
-
{
|
1881
|
-
collectionType,
|
1882
|
-
model,
|
1883
|
-
documentId,
|
1884
|
-
params
|
1885
2334
|
},
|
1886
|
-
|
2335
|
+
{ relative: "path" }
|
1887
2336
|
);
|
1888
|
-
|
1889
|
-
|
1890
|
-
|
1891
|
-
|
1892
|
-
|
2337
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2338
|
+
setErrors(formatValidationErrors(res.error));
|
2339
|
+
}
|
2340
|
+
} else if (documentId || collectionType === SINGLE_TYPES) {
|
2341
|
+
const res = await update(
|
2342
|
+
{
|
2343
|
+
collectionType,
|
2344
|
+
model,
|
2345
|
+
documentId,
|
2346
|
+
params
|
2347
|
+
},
|
2348
|
+
transformData(document)
|
2349
|
+
);
|
2350
|
+
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2351
|
+
setErrors(formatValidationErrors(res.error));
|
1893
2352
|
} else {
|
1894
|
-
|
2353
|
+
resetForm();
|
2354
|
+
}
|
2355
|
+
} else {
|
2356
|
+
const res = await create(
|
2357
|
+
{
|
2358
|
+
model,
|
2359
|
+
params
|
2360
|
+
},
|
2361
|
+
transformData(document)
|
2362
|
+
);
|
2363
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2364
|
+
navigate(
|
1895
2365
|
{
|
1896
|
-
|
1897
|
-
|
2366
|
+
pathname: `../${res.data.documentId}`,
|
2367
|
+
search: rawQuery
|
1898
2368
|
},
|
1899
|
-
|
2369
|
+
{ replace: true, relative: "path" }
|
1900
2370
|
);
|
1901
|
-
|
1902
|
-
|
1903
|
-
{
|
1904
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1905
|
-
search: rawQuery
|
1906
|
-
},
|
1907
|
-
{ replace: true }
|
1908
|
-
);
|
1909
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1910
|
-
setErrors(formatValidationErrors(res.error));
|
1911
|
-
}
|
2371
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2372
|
+
setErrors(formatValidationErrors(res.error));
|
1912
2373
|
}
|
1913
|
-
} finally {
|
1914
|
-
setSubmitting(false);
|
1915
2374
|
}
|
2375
|
+
} finally {
|
2376
|
+
setSubmitting(false);
|
1916
2377
|
}
|
2378
|
+
}, [
|
2379
|
+
clone,
|
2380
|
+
cloneMatch?.params.origin,
|
2381
|
+
collectionType,
|
2382
|
+
create,
|
2383
|
+
document,
|
2384
|
+
documentId,
|
2385
|
+
formatMessage,
|
2386
|
+
formatValidationErrors,
|
2387
|
+
isCloning,
|
2388
|
+
model,
|
2389
|
+
modified,
|
2390
|
+
navigate,
|
2391
|
+
params,
|
2392
|
+
rawQuery,
|
2393
|
+
resetForm,
|
2394
|
+
setErrors,
|
2395
|
+
setSubmitting,
|
2396
|
+
toggleNotification,
|
2397
|
+
update,
|
2398
|
+
validate
|
2399
|
+
]);
|
2400
|
+
React.useEffect(() => {
|
2401
|
+
const handleKeyDown = (e) => {
|
2402
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
2403
|
+
e.preventDefault();
|
2404
|
+
handleUpdate();
|
2405
|
+
}
|
2406
|
+
};
|
2407
|
+
window.addEventListener("keydown", handleKeyDown);
|
2408
|
+
return () => {
|
2409
|
+
window.removeEventListener("keydown", handleKeyDown);
|
2410
|
+
};
|
2411
|
+
}, [handleUpdate]);
|
2412
|
+
return {
|
2413
|
+
/**
|
2414
|
+
* Disabled when:
|
2415
|
+
* - the form is submitting
|
2416
|
+
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
2417
|
+
* - the active tab is the published tab
|
2418
|
+
*/
|
2419
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
2420
|
+
label: formatMessage({
|
2421
|
+
id: "global.save",
|
2422
|
+
defaultMessage: "Save"
|
2423
|
+
}),
|
2424
|
+
onClick: handleUpdate
|
1917
2425
|
};
|
1918
2426
|
};
|
1919
2427
|
UpdateAction.type = "update";
|
2428
|
+
UpdateAction.position = "panel";
|
1920
2429
|
const UNPUBLISH_DRAFT_OPTIONS = {
|
1921
2430
|
KEEP: "keep",
|
1922
2431
|
DISCARD: "discard"
|
@@ -1949,7 +2458,7 @@ const UnpublishAction$1 = ({
|
|
1949
2458
|
id: "app.utils.unpublish",
|
1950
2459
|
defaultMessage: "Unpublish"
|
1951
2460
|
}),
|
1952
|
-
icon: /* @__PURE__ */ jsx(
|
2461
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1953
2462
|
onClick: async () => {
|
1954
2463
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1955
2464
|
if (!documentId) {
|
@@ -2039,6 +2548,7 @@ const UnpublishAction$1 = ({
|
|
2039
2548
|
};
|
2040
2549
|
};
|
2041
2550
|
UnpublishAction$1.type = "unpublish";
|
2551
|
+
UnpublishAction$1.position = "panel";
|
2042
2552
|
const DiscardAction = ({
|
2043
2553
|
activeTab,
|
2044
2554
|
documentId,
|
@@ -2061,7 +2571,7 @@ const DiscardAction = ({
|
|
2061
2571
|
id: "content-manager.actions.discard.label",
|
2062
2572
|
defaultMessage: "Discard changes"
|
2063
2573
|
}),
|
2064
|
-
icon: /* @__PURE__ */ jsx(
|
2574
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
2065
2575
|
position: ["panel", "table-row"],
|
2066
2576
|
variant: "danger",
|
2067
2577
|
dialog: {
|
@@ -2089,11 +2599,7 @@ const DiscardAction = ({
|
|
2089
2599
|
};
|
2090
2600
|
};
|
2091
2601
|
DiscardAction.type = "discard";
|
2092
|
-
|
2093
|
-
path {
|
2094
|
-
fill: currentColor;
|
2095
|
-
}
|
2096
|
-
`;
|
2602
|
+
DiscardAction.position = "panel";
|
2097
2603
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2098
2604
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2099
2605
|
const RelativeTime = React.forwardRef(
|
@@ -2106,7 +2612,7 @@ const RelativeTime = React.forwardRef(
|
|
2106
2612
|
});
|
2107
2613
|
const unit = intervals.find((intervalUnit) => {
|
2108
2614
|
return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
|
2109
|
-
});
|
2615
|
+
}) ?? "seconds";
|
2110
2616
|
const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
|
2111
2617
|
const customInterval = customIntervals.find(
|
2112
2618
|
(custom) => interval[custom.unit] < custom.threshold
|
@@ -2140,19 +2646,29 @@ const getDisplayName = ({
|
|
2140
2646
|
return email ?? "";
|
2141
2647
|
};
|
2142
2648
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2143
|
-
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2144
|
-
const statusVariant = status === "draft" ? "
|
2145
|
-
|
2649
|
+
const DocumentStatus = ({ status = "draft", size = "S", ...restProps }) => {
|
2650
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2651
|
+
const { formatMessage } = useIntl();
|
2652
|
+
return /* @__PURE__ */ jsx(Status, { ...restProps, size, variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: formatMessage({
|
2653
|
+
id: `content-manager.containers.List.${status}`,
|
2654
|
+
defaultMessage: capitalise(status)
|
2655
|
+
}) }) });
|
2146
2656
|
};
|
2147
2657
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2148
2658
|
const { formatMessage } = useIntl();
|
2149
2659
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2660
|
+
const params = useParams();
|
2150
2661
|
const title = isCreating ? formatMessage({
|
2151
2662
|
id: "content-manager.containers.edit.title.new",
|
2152
2663
|
defaultMessage: "Create an entry"
|
2153
2664
|
}) : documentTitle;
|
2154
2665
|
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2155
|
-
/* @__PURE__ */ jsx(
|
2666
|
+
/* @__PURE__ */ jsx(
|
2667
|
+
BackButton,
|
2668
|
+
{
|
2669
|
+
fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
|
2670
|
+
}
|
2671
|
+
),
|
2156
2672
|
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2157
2673
|
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2158
2674
|
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
@@ -2203,7 +2719,7 @@ const HeaderToolbar = () => {
|
|
2203
2719
|
meta: isCloning ? void 0 : meta,
|
2204
2720
|
collectionType
|
2205
2721
|
},
|
2206
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2722
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("header"),
|
2207
2723
|
children: (actions2) => {
|
2208
2724
|
const headerActions = actions2.filter((action) => {
|
2209
2725
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -2240,12 +2756,12 @@ const Information = ({ activeTab }) => {
|
|
2240
2756
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2241
2757
|
label: formatMessage({
|
2242
2758
|
id: "content-manager.containers.edit.information.last-published.label",
|
2243
|
-
defaultMessage: "
|
2759
|
+
defaultMessage: "Published"
|
2244
2760
|
}),
|
2245
2761
|
value: formatMessage(
|
2246
2762
|
{
|
2247
2763
|
id: "content-manager.containers.edit.information.last-published.value",
|
2248
|
-
defaultMessage: `
|
2764
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2249
2765
|
},
|
2250
2766
|
{
|
2251
2767
|
time: /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2258,12 +2774,12 @@ const Information = ({ activeTab }) => {
|
|
2258
2774
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2259
2775
|
label: formatMessage({
|
2260
2776
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2261
|
-
defaultMessage: "
|
2777
|
+
defaultMessage: "Updated"
|
2262
2778
|
}),
|
2263
2779
|
value: formatMessage(
|
2264
2780
|
{
|
2265
2781
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2266
|
-
defaultMessage: `
|
2782
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2267
2783
|
},
|
2268
2784
|
{
|
2269
2785
|
time: /* @__PURE__ */ jsx(
|
@@ -2281,12 +2797,12 @@ const Information = ({ activeTab }) => {
|
|
2281
2797
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2282
2798
|
label: formatMessage({
|
2283
2799
|
id: "content-manager.containers.edit.information.document.label",
|
2284
|
-
defaultMessage: "
|
2800
|
+
defaultMessage: "Created"
|
2285
2801
|
}),
|
2286
2802
|
value: formatMessage(
|
2287
2803
|
{
|
2288
2804
|
id: "content-manager.containers.edit.information.document.value",
|
2289
|
-
defaultMessage: `
|
2805
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2290
2806
|
},
|
2291
2807
|
{
|
2292
2808
|
time: /* @__PURE__ */ jsx(
|
@@ -2324,25 +2840,77 @@ const Information = ({ activeTab }) => {
|
|
2324
2840
|
);
|
2325
2841
|
};
|
2326
2842
|
const HeaderActions = ({ actions: actions2 }) => {
|
2327
|
-
|
2328
|
-
|
2843
|
+
const [dialogId, setDialogId] = React.useState(null);
|
2844
|
+
const handleClick = (action) => async (e) => {
|
2845
|
+
if (!("options" in action)) {
|
2846
|
+
const { onClick = () => false, dialog, id } = action;
|
2847
|
+
const muteDialog = await onClick(e);
|
2848
|
+
if (dialog && !muteDialog) {
|
2849
|
+
e.preventDefault();
|
2850
|
+
setDialogId(id);
|
2851
|
+
}
|
2852
|
+
}
|
2853
|
+
};
|
2854
|
+
const handleClose = () => {
|
2855
|
+
setDialogId(null);
|
2856
|
+
};
|
2857
|
+
return /* @__PURE__ */ jsx(Flex, { gap: 1, children: actions2.map((action) => {
|
2858
|
+
if (action.options) {
|
2329
2859
|
return /* @__PURE__ */ jsx(
|
2330
2860
|
SingleSelect,
|
2331
2861
|
{
|
2332
2862
|
size: "S",
|
2333
|
-
disabled: action.disabled,
|
2334
|
-
"aria-label": action.label,
|
2335
2863
|
onChange: action.onSelect,
|
2336
|
-
|
2864
|
+
"aria-label": action.label,
|
2865
|
+
...action,
|
2337
2866
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
|
2338
2867
|
},
|
2339
2868
|
action.id
|
2340
2869
|
);
|
2341
2870
|
} else {
|
2342
|
-
|
2871
|
+
if (action.type === "icon") {
|
2872
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
2873
|
+
/* @__PURE__ */ jsx(
|
2874
|
+
IconButton,
|
2875
|
+
{
|
2876
|
+
disabled: action.disabled,
|
2877
|
+
label: action.label,
|
2878
|
+
size: "S",
|
2879
|
+
onClick: handleClick(action),
|
2880
|
+
children: action.icon
|
2881
|
+
}
|
2882
|
+
),
|
2883
|
+
action.dialog ? /* @__PURE__ */ jsx(
|
2884
|
+
HeaderActionDialog,
|
2885
|
+
{
|
2886
|
+
...action.dialog,
|
2887
|
+
isOpen: dialogId === action.id,
|
2888
|
+
onClose: handleClose
|
2889
|
+
}
|
2890
|
+
) : null
|
2891
|
+
] }, action.id);
|
2892
|
+
}
|
2343
2893
|
}
|
2344
2894
|
}) });
|
2345
2895
|
};
|
2896
|
+
const HeaderActionDialog = ({
|
2897
|
+
onClose,
|
2898
|
+
onCancel,
|
2899
|
+
title,
|
2900
|
+
content: Content,
|
2901
|
+
isOpen
|
2902
|
+
}) => {
|
2903
|
+
const handleClose = async () => {
|
2904
|
+
if (onCancel) {
|
2905
|
+
await onCancel();
|
2906
|
+
}
|
2907
|
+
onClose();
|
2908
|
+
};
|
2909
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2910
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
2911
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content
|
2912
|
+
] }) });
|
2913
|
+
};
|
2346
2914
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2347
2915
|
const navigate = useNavigate();
|
2348
2916
|
const { formatMessage } = useIntl();
|
@@ -2359,6 +2927,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2359
2927
|
};
|
2360
2928
|
};
|
2361
2929
|
ConfigureTheViewAction.type = "configure-the-view";
|
2930
|
+
ConfigureTheViewAction.position = "header";
|
2362
2931
|
const EditTheModelAction = ({ model }) => {
|
2363
2932
|
const navigate = useNavigate();
|
2364
2933
|
const { formatMessage } = useIntl();
|
@@ -2375,6 +2944,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2375
2944
|
};
|
2376
2945
|
};
|
2377
2946
|
EditTheModelAction.type = "edit-the-model";
|
2947
|
+
EditTheModelAction.position = "header";
|
2378
2948
|
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2379
2949
|
const navigate = useNavigate();
|
2380
2950
|
const { formatMessage } = useIntl();
|
@@ -2383,12 +2953,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2383
2953
|
const { delete: deleteAction } = useDocumentActions();
|
2384
2954
|
const { toggleNotification } = useNotification();
|
2385
2955
|
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
2956
|
+
const isLocalized = document?.locale != null;
|
2386
2957
|
return {
|
2387
2958
|
disabled: !canDelete || !document,
|
2388
|
-
label: formatMessage(
|
2389
|
-
|
2390
|
-
|
2391
|
-
|
2959
|
+
label: formatMessage(
|
2960
|
+
{
|
2961
|
+
id: "content-manager.actions.delete.label",
|
2962
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2963
|
+
},
|
2964
|
+
{ isLocalized }
|
2965
|
+
),
|
2392
2966
|
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2393
2967
|
dialog: {
|
2394
2968
|
type: "dialog",
|
@@ -2430,417 +3004,116 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2430
3004
|
}
|
2431
3005
|
});
|
2432
3006
|
if (!("error" in res)) {
|
2433
|
-
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2434
|
-
}
|
2435
|
-
} finally {
|
2436
|
-
if (!listViewPathMatch) {
|
2437
|
-
setSubmitting(false);
|
2438
|
-
}
|
2439
|
-
}
|
2440
|
-
}
|
2441
|
-
},
|
2442
|
-
variant: "danger",
|
2443
|
-
position: ["header", "table-row"]
|
2444
|
-
};
|
2445
|
-
};
|
2446
|
-
DeleteAction$1.type = "delete";
|
2447
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2448
|
-
const Panels = () => {
|
2449
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2450
|
-
const [
|
2451
|
-
{
|
2452
|
-
query: { status }
|
2453
|
-
}
|
2454
|
-
] = useQueryParams({
|
2455
|
-
status: "draft"
|
2456
|
-
});
|
2457
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2458
|
-
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
2459
|
-
const props = {
|
2460
|
-
activeTab: status,
|
2461
|
-
model,
|
2462
|
-
documentId: id,
|
2463
|
-
document: isCloning ? void 0 : document,
|
2464
|
-
meta: isCloning ? void 0 : meta,
|
2465
|
-
collectionType
|
2466
|
-
};
|
2467
|
-
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
2468
|
-
DescriptionComponentRenderer,
|
2469
|
-
{
|
2470
|
-
props,
|
2471
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2472
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
2473
|
-
}
|
2474
|
-
) });
|
2475
|
-
};
|
2476
|
-
const ActionsPanel = () => {
|
2477
|
-
const { formatMessage } = useIntl();
|
2478
|
-
return {
|
2479
|
-
title: formatMessage({
|
2480
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2481
|
-
defaultMessage: "Document"
|
2482
|
-
}),
|
2483
|
-
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2484
|
-
};
|
2485
|
-
};
|
2486
|
-
ActionsPanel.type = "actions";
|
2487
|
-
const ActionsPanelContent = () => {
|
2488
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2489
|
-
const [
|
2490
|
-
{
|
2491
|
-
query: { status = "draft" }
|
2492
|
-
}
|
2493
|
-
] = useQueryParams();
|
2494
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2495
|
-
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2496
|
-
const props = {
|
2497
|
-
activeTab: status,
|
2498
|
-
model,
|
2499
|
-
documentId: id,
|
2500
|
-
document: isCloning ? void 0 : document,
|
2501
|
-
meta: isCloning ? void 0 : meta,
|
2502
|
-
collectionType
|
2503
|
-
};
|
2504
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2505
|
-
/* @__PURE__ */ jsx(
|
2506
|
-
DescriptionComponentRenderer,
|
2507
|
-
{
|
2508
|
-
props,
|
2509
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2510
|
-
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
2511
|
-
}
|
2512
|
-
),
|
2513
|
-
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2514
|
-
] });
|
2515
|
-
};
|
2516
|
-
const Panel = React.forwardRef(({ children, title }, ref) => {
|
2517
|
-
return /* @__PURE__ */ jsxs(
|
2518
|
-
Flex,
|
2519
|
-
{
|
2520
|
-
ref,
|
2521
|
-
tag: "aside",
|
2522
|
-
"aria-labelledby": "additional-information",
|
2523
|
-
background: "neutral0",
|
2524
|
-
borderColor: "neutral150",
|
2525
|
-
hasRadius: true,
|
2526
|
-
paddingBottom: 4,
|
2527
|
-
paddingLeft: 4,
|
2528
|
-
paddingRight: 4,
|
2529
|
-
paddingTop: 4,
|
2530
|
-
shadow: "tableShadow",
|
2531
|
-
gap: 3,
|
2532
|
-
direction: "column",
|
2533
|
-
justifyContent: "stretch",
|
2534
|
-
alignItems: "flex-start",
|
2535
|
-
children: [
|
2536
|
-
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2537
|
-
children
|
2538
|
-
]
|
2539
|
-
}
|
2540
|
-
);
|
2541
|
-
});
|
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
|
3007
|
+
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
3008
|
+
}
|
3009
|
+
} finally {
|
3010
|
+
if (!listViewPathMatch) {
|
3011
|
+
setSubmitting(false);
|
3012
|
+
}
|
2731
3013
|
}
|
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
|
3014
|
+
}
|
2753
3015
|
},
|
2754
|
-
|
2755
|
-
|
2756
|
-
...schema?.pluginOptions,
|
2757
|
-
...data.contentType.options
|
2758
|
-
}
|
3016
|
+
variant: "danger",
|
3017
|
+
position: ["header", "table-row"]
|
2759
3018
|
};
|
2760
3019
|
};
|
2761
|
-
|
2762
|
-
|
2763
|
-
|
2764
|
-
|
2765
|
-
|
2766
|
-
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
|
2774
|
-
|
2775
|
-
|
2776
|
-
|
2777
|
-
|
2778
|
-
|
2779
|
-
|
2780
|
-
|
2781
|
-
|
2782
|
-
|
2783
|
-
|
2784
|
-
|
2785
|
-
|
2786
|
-
|
2787
|
-
|
2788
|
-
|
2789
|
-
|
3020
|
+
DeleteAction$1.type = "delete";
|
3021
|
+
DeleteAction$1.position = ["header", "table-row"];
|
3022
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
3023
|
+
const Panels = () => {
|
3024
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
3025
|
+
const [
|
3026
|
+
{
|
3027
|
+
query: { status }
|
3028
|
+
}
|
3029
|
+
] = useQueryParams({
|
3030
|
+
status: "draft"
|
3031
|
+
});
|
3032
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
3033
|
+
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
3034
|
+
const props = {
|
3035
|
+
activeTab: status,
|
3036
|
+
model,
|
3037
|
+
documentId: id,
|
3038
|
+
document: isCloning ? void 0 : document,
|
3039
|
+
meta: isCloning ? void 0 : meta,
|
3040
|
+
collectionType
|
3041
|
+
};
|
3042
|
+
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
3043
|
+
DescriptionComponentRenderer,
|
3044
|
+
{
|
3045
|
+
props,
|
3046
|
+
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
3047
|
+
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
3048
|
+
}
|
3049
|
+
) });
|
2790
3050
|
};
|
2791
|
-
const
|
2792
|
-
|
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
|
-
);
|
3051
|
+
const ActionsPanel = () => {
|
3052
|
+
const { formatMessage } = useIntl();
|
2812
3053
|
return {
|
2813
|
-
|
2814
|
-
|
2815
|
-
|
2816
|
-
|
2817
|
-
|
2818
|
-
...schema?.pluginOptions,
|
2819
|
-
...data.contentType.options
|
2820
|
-
}
|
3054
|
+
title: formatMessage({
|
3055
|
+
id: "content-manager.containers.edit.panels.default.title",
|
3056
|
+
defaultMessage: "Entry"
|
3057
|
+
}),
|
3058
|
+
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2821
3059
|
};
|
2822
3060
|
};
|
2823
|
-
|
2824
|
-
|
2825
|
-
|
2826
|
-
|
2827
|
-
|
3061
|
+
ActionsPanel.type = "actions";
|
3062
|
+
const ActionsPanelContent = () => {
|
3063
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
3064
|
+
const [
|
3065
|
+
{
|
3066
|
+
query: { status = "draft" }
|
2828
3067
|
}
|
2829
|
-
|
2830
|
-
|
2831
|
-
|
2832
|
-
|
2833
|
-
|
2834
|
-
|
2835
|
-
|
2836
|
-
|
2837
|
-
|
2838
|
-
|
2839
|
-
|
2840
|
-
|
2841
|
-
|
2842
|
-
|
3068
|
+
] = useQueryParams();
|
3069
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
3070
|
+
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
3071
|
+
const props = {
|
3072
|
+
activeTab: status,
|
3073
|
+
model,
|
3074
|
+
documentId: id,
|
3075
|
+
document: isCloning ? void 0 : document,
|
3076
|
+
meta: isCloning ? void 0 : meta,
|
3077
|
+
collectionType
|
3078
|
+
};
|
3079
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
3080
|
+
/* @__PURE__ */ jsx(
|
3081
|
+
DescriptionComponentRenderer,
|
3082
|
+
{
|
3083
|
+
props,
|
3084
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("panel"),
|
3085
|
+
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
3086
|
+
}
|
3087
|
+
),
|
3088
|
+
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
3089
|
+
] });
|
2843
3090
|
};
|
3091
|
+
const Panel = React.forwardRef(({ children, title }, ref) => {
|
3092
|
+
return /* @__PURE__ */ jsxs(
|
3093
|
+
Flex,
|
3094
|
+
{
|
3095
|
+
ref,
|
3096
|
+
tag: "aside",
|
3097
|
+
"aria-labelledby": "additional-information",
|
3098
|
+
background: "neutral0",
|
3099
|
+
borderColor: "neutral150",
|
3100
|
+
hasRadius: true,
|
3101
|
+
paddingBottom: 4,
|
3102
|
+
paddingLeft: 4,
|
3103
|
+
paddingRight: 4,
|
3104
|
+
paddingTop: 4,
|
3105
|
+
shadow: "tableShadow",
|
3106
|
+
gap: 3,
|
3107
|
+
direction: "column",
|
3108
|
+
justifyContent: "stretch",
|
3109
|
+
alignItems: "flex-start",
|
3110
|
+
children: [
|
3111
|
+
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", textColor: "neutral600", children: title }),
|
3112
|
+
children
|
3113
|
+
]
|
3114
|
+
}
|
3115
|
+
);
|
3116
|
+
});
|
2844
3117
|
const ConfirmBulkActionDialog = ({
|
2845
3118
|
onToggleDialog,
|
2846
3119
|
isOpen = false,
|
@@ -2879,6 +3152,7 @@ const ConfirmDialogPublishAll = ({
|
|
2879
3152
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
|
2880
3153
|
const { model, schema } = useDoc();
|
2881
3154
|
const [{ query }] = useQueryParams();
|
3155
|
+
const enableDraftRelationsCount = false;
|
2882
3156
|
const {
|
2883
3157
|
data: countDraftRelations = 0,
|
2884
3158
|
isLoading,
|
@@ -2890,7 +3164,7 @@ const ConfirmDialogPublishAll = ({
|
|
2890
3164
|
locale: query?.plugins?.i18n?.locale
|
2891
3165
|
},
|
2892
3166
|
{
|
2893
|
-
skip:
|
3167
|
+
skip: !enableDraftRelationsCount
|
2894
3168
|
}
|
2895
3169
|
);
|
2896
3170
|
React.useEffect(() => {
|
@@ -3075,7 +3349,7 @@ const SelectedEntriesTableContent = ({
|
|
3075
3349
|
status: row.status
|
3076
3350
|
}
|
3077
3351
|
) }),
|
3078
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
3352
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
|
3079
3353
|
IconButton,
|
3080
3354
|
{
|
3081
3355
|
tag: Link,
|
@@ -3084,23 +3358,16 @@ const SelectedEntriesTableContent = ({
|
|
3084
3358
|
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3085
3359
|
},
|
3086
3360
|
state: { from: pathname },
|
3087
|
-
label: formatMessage(
|
3088
|
-
|
3089
|
-
|
3090
|
-
|
3091
|
-
{
|
3092
|
-
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3093
|
-
defaultMessage: "item line {number}"
|
3094
|
-
},
|
3095
|
-
{ number: index2 + 1 }
|
3096
|
-
)
|
3097
|
-
}
|
3098
|
-
),
|
3361
|
+
label: formatMessage({
|
3362
|
+
id: "content-manager.bulk-publish.edit",
|
3363
|
+
defaultMessage: "Edit"
|
3364
|
+
}),
|
3099
3365
|
target: "_blank",
|
3100
3366
|
marginLeft: "auto",
|
3101
|
-
|
3367
|
+
variant: "ghost",
|
3368
|
+
children: /* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" })
|
3102
3369
|
}
|
3103
|
-
) })
|
3370
|
+
) }) })
|
3104
3371
|
] }, row.id)) })
|
3105
3372
|
] });
|
3106
3373
|
};
|
@@ -3137,7 +3404,13 @@ const SelectedEntriesModalContent = ({
|
|
3137
3404
|
);
|
3138
3405
|
const { rows, validationErrors } = React.useMemo(() => {
|
3139
3406
|
if (data.length > 0 && schema) {
|
3140
|
-
const validate = createYupSchema(
|
3407
|
+
const validate = createYupSchema(
|
3408
|
+
schema.attributes,
|
3409
|
+
components,
|
3410
|
+
// Since this is the "Publish" action, the validation
|
3411
|
+
// schema must enforce the rules for published entities
|
3412
|
+
{ status: "published" }
|
3413
|
+
);
|
3141
3414
|
const validationErrors2 = {};
|
3142
3415
|
const rows2 = data.map((entry) => {
|
3143
3416
|
try {
|
@@ -3262,8 +3535,7 @@ const PublishAction = ({ documents, model }) => {
|
|
3262
3535
|
const refetchList = () => {
|
3263
3536
|
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3264
3537
|
};
|
3265
|
-
if (!showPublishButton)
|
3266
|
-
return null;
|
3538
|
+
if (!showPublishButton) return null;
|
3267
3539
|
return {
|
3268
3540
|
actionType: "publish",
|
3269
3541
|
variant: "tertiary",
|
@@ -3331,8 +3603,7 @@ const DeleteAction = ({ documents, model }) => {
|
|
3331
3603
|
selectRow([]);
|
3332
3604
|
}
|
3333
3605
|
};
|
3334
|
-
if (!hasDeletePermission)
|
3335
|
-
return null;
|
3606
|
+
if (!hasDeletePermission) return null;
|
3336
3607
|
return {
|
3337
3608
|
variant: "danger-light",
|
3338
3609
|
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
@@ -3381,8 +3652,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3381
3652
|
}
|
3382
3653
|
};
|
3383
3654
|
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3384
|
-
if (!showUnpublishButton)
|
3385
|
-
return null;
|
3655
|
+
if (!showUnpublishButton) return null;
|
3386
3656
|
return {
|
3387
3657
|
variant: "tertiary",
|
3388
3658
|
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
@@ -3487,7 +3757,7 @@ const TableActions = ({ document }) => {
|
|
3487
3757
|
DescriptionComponentRenderer,
|
3488
3758
|
{
|
3489
3759
|
props,
|
3490
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3760
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("table-row").filter((action) => action.name !== "PublishAction"),
|
3491
3761
|
children: (actions2) => {
|
3492
3762
|
const tableRowActions = actions2.filter((action) => {
|
3493
3763
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3546,6 +3816,7 @@ const EditAction = ({ documentId }) => {
|
|
3546
3816
|
};
|
3547
3817
|
};
|
3548
3818
|
EditAction.type = "edit";
|
3819
|
+
EditAction.position = "table-row";
|
3549
3820
|
const StyledPencil = styled(Pencil)`
|
3550
3821
|
path {
|
3551
3822
|
fill: currentColor;
|
@@ -3598,7 +3869,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3598
3869
|
}),
|
3599
3870
|
content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3600
3871
|
footer: ({ onClose }) => {
|
3601
|
-
return /* @__PURE__ */ jsxs(
|
3872
|
+
return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3602
3873
|
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3603
3874
|
id: "cancel",
|
3604
3875
|
defaultMessage: "Cancel"
|
@@ -3622,6 +3893,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3622
3893
|
};
|
3623
3894
|
};
|
3624
3895
|
CloneAction.type = "clone";
|
3896
|
+
CloneAction.position = "table-row";
|
3625
3897
|
const StyledDuplicate = styled(Duplicate)`
|
3626
3898
|
path {
|
3627
3899
|
fill: currentColor;
|
@@ -3708,7 +3980,14 @@ class ContentManagerPlugin {
|
|
3708
3980
|
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3709
3981
|
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3710
3982
|
getBulkActions: () => this.bulkActions,
|
3711
|
-
getDocumentActions: () =>
|
3983
|
+
getDocumentActions: (position) => {
|
3984
|
+
if (position) {
|
3985
|
+
return this.documentActions.filter(
|
3986
|
+
(action) => action.position == void 0 || [action.position].flat().includes(position)
|
3987
|
+
);
|
3988
|
+
}
|
3989
|
+
return this.documentActions;
|
3990
|
+
},
|
3712
3991
|
getEditViewSidePanels: () => this.editViewSidePanels,
|
3713
3992
|
getHeaderActions: () => this.headerActions
|
3714
3993
|
}
|
@@ -3718,10 +3997,8 @@ class ContentManagerPlugin {
|
|
3718
3997
|
const getPrintableType = (value) => {
|
3719
3998
|
const nativeType = typeof value;
|
3720
3999
|
if (nativeType === "object") {
|
3721
|
-
if (value === null)
|
3722
|
-
|
3723
|
-
if (Array.isArray(value))
|
3724
|
-
return "array";
|
4000
|
+
if (value === null) return "null";
|
4001
|
+
if (Array.isArray(value)) return "array";
|
3725
4002
|
if (value instanceof Object && value.constructor.name !== "Object") {
|
3726
4003
|
return value.constructor.name;
|
3727
4004
|
}
|
@@ -3732,17 +4009,27 @@ const HistoryAction = ({ model, document }) => {
|
|
3732
4009
|
const { formatMessage } = useIntl();
|
3733
4010
|
const [{ query }] = useQueryParams();
|
3734
4011
|
const navigate = useNavigate();
|
4012
|
+
const { trackUsage } = useTracking();
|
4013
|
+
const { pathname } = useLocation();
|
3735
4014
|
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
3736
4015
|
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3737
4016
|
return null;
|
3738
4017
|
}
|
4018
|
+
const handleOnClick = () => {
|
4019
|
+
const destination = { pathname: "history", search: pluginsQueryParams };
|
4020
|
+
trackUsage("willNavigate", {
|
4021
|
+
from: pathname,
|
4022
|
+
to: `${pathname}/${destination.pathname}`
|
4023
|
+
});
|
4024
|
+
navigate(destination);
|
4025
|
+
};
|
3739
4026
|
return {
|
3740
4027
|
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
3741
4028
|
label: formatMessage({
|
3742
4029
|
id: "content-manager.history.document-action",
|
3743
4030
|
defaultMessage: "Content History"
|
3744
4031
|
}),
|
3745
|
-
onClick:
|
4032
|
+
onClick: handleOnClick,
|
3746
4033
|
disabled: (
|
3747
4034
|
/**
|
3748
4035
|
* The user is creating a new document.
|
@@ -3764,6 +4051,7 @@ const HistoryAction = ({ model, document }) => {
|
|
3764
4051
|
};
|
3765
4052
|
};
|
3766
4053
|
HistoryAction.type = "history";
|
4054
|
+
HistoryAction.position = "header";
|
3767
4055
|
const historyAdmin = {
|
3768
4056
|
bootstrap(app) {
|
3769
4057
|
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
@@ -3810,6 +4098,88 @@ const { setInitialData } = actions;
|
|
3810
4098
|
const reducer = combineReducers({
|
3811
4099
|
app: reducer$1
|
3812
4100
|
});
|
4101
|
+
const previewApi = contentManagerApi.injectEndpoints({
|
4102
|
+
endpoints: (builder) => ({
|
4103
|
+
getPreviewUrl: builder.query({
|
4104
|
+
query({ query, params }) {
|
4105
|
+
return {
|
4106
|
+
url: `/content-manager/preview/url/${params.contentType}`,
|
4107
|
+
method: "GET",
|
4108
|
+
config: {
|
4109
|
+
params: query
|
4110
|
+
}
|
4111
|
+
};
|
4112
|
+
}
|
4113
|
+
})
|
4114
|
+
})
|
4115
|
+
});
|
4116
|
+
const { useGetPreviewUrlQuery } = previewApi;
|
4117
|
+
const ConditionalTooltip = ({ isShown, label, children }) => {
|
4118
|
+
if (isShown) {
|
4119
|
+
return /* @__PURE__ */ jsx(Tooltip, { label, children });
|
4120
|
+
}
|
4121
|
+
return children;
|
4122
|
+
};
|
4123
|
+
const PreviewSidePanel = ({ model, documentId, document }) => {
|
4124
|
+
const { formatMessage } = useIntl();
|
4125
|
+
const { trackUsage } = useTracking();
|
4126
|
+
const { pathname } = useLocation();
|
4127
|
+
const [{ query }] = useQueryParams();
|
4128
|
+
const isModified = useForm("PreviewSidePanel", (state) => state.modified);
|
4129
|
+
const { data, error } = useGetPreviewUrlQuery({
|
4130
|
+
params: {
|
4131
|
+
contentType: model
|
4132
|
+
},
|
4133
|
+
query: {
|
4134
|
+
documentId,
|
4135
|
+
locale: document?.locale,
|
4136
|
+
status: document?.status
|
4137
|
+
}
|
4138
|
+
});
|
4139
|
+
if (!data?.data?.url || error) {
|
4140
|
+
return null;
|
4141
|
+
}
|
4142
|
+
const trackNavigation = () => {
|
4143
|
+
const destinationPathname = pathname.replace(/\/$/, "") + "/preview";
|
4144
|
+
trackUsage("willNavigate", { from: pathname, to: destinationPathname });
|
4145
|
+
};
|
4146
|
+
return {
|
4147
|
+
title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
|
4148
|
+
content: /* @__PURE__ */ jsx(
|
4149
|
+
ConditionalTooltip,
|
4150
|
+
{
|
4151
|
+
label: formatMessage({
|
4152
|
+
id: "content-manager.preview.panel.button-disabled-tooltip",
|
4153
|
+
defaultMessage: "Please save to open the preview"
|
4154
|
+
}),
|
4155
|
+
isShown: isModified,
|
4156
|
+
children: /* @__PURE__ */ jsx(Box, { cursor: "not-allowed", width: "100%", children: /* @__PURE__ */ jsx(
|
4157
|
+
Button,
|
4158
|
+
{
|
4159
|
+
variant: "tertiary",
|
4160
|
+
tag: Link,
|
4161
|
+
to: { pathname: "preview", search: stringify(query, { encode: false }) },
|
4162
|
+
onClick: trackNavigation,
|
4163
|
+
width: "100%",
|
4164
|
+
disabled: isModified,
|
4165
|
+
pointerEvents: isModified ? "none" : void 0,
|
4166
|
+
tabIndex: isModified ? -1 : void 0,
|
4167
|
+
children: formatMessage({
|
4168
|
+
id: "content-manager.preview.panel.button",
|
4169
|
+
defaultMessage: "Open preview"
|
4170
|
+
})
|
4171
|
+
}
|
4172
|
+
) })
|
4173
|
+
}
|
4174
|
+
)
|
4175
|
+
};
|
4176
|
+
};
|
4177
|
+
const previewAdmin = {
|
4178
|
+
bootstrap(app) {
|
4179
|
+
const contentManagerPluginApis = app.getPlugin("content-manager").apis;
|
4180
|
+
contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
|
4181
|
+
}
|
4182
|
+
};
|
3813
4183
|
const index = {
|
3814
4184
|
register(app) {
|
3815
4185
|
const cm = new ContentManagerPlugin();
|
@@ -3829,7 +4199,7 @@ const index = {
|
|
3829
4199
|
app.router.addRoute({
|
3830
4200
|
path: "content-manager/*",
|
3831
4201
|
lazy: async () => {
|
3832
|
-
const { Layout } = await import("./layout-
|
4202
|
+
const { Layout } = await import("./layout-COzAvgJh.mjs");
|
3833
4203
|
return {
|
3834
4204
|
Component: Layout
|
3835
4205
|
};
|
@@ -3842,11 +4212,14 @@ const index = {
|
|
3842
4212
|
if (typeof historyAdmin.bootstrap === "function") {
|
3843
4213
|
historyAdmin.bootstrap(app);
|
3844
4214
|
}
|
4215
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
4216
|
+
previewAdmin.bootstrap(app);
|
4217
|
+
}
|
3845
4218
|
},
|
3846
4219
|
async registerTrads({ locales }) {
|
3847
4220
|
const importedTrads = await Promise.all(
|
3848
4221
|
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-
|
4222
|
+
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-CSxLmrh1.mjs"), "./translations/es.json": () => import("./es-D34tqjMw.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr--pg5jUbt.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-BHqhDq4V.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
|
3850
4223
|
return {
|
3851
4224
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3852
4225
|
locale
|
@@ -3867,13 +4240,16 @@ export {
|
|
3867
4240
|
BulkActionsRenderer as B,
|
3868
4241
|
COLLECTION_TYPES as C,
|
3869
4242
|
DocumentStatus as D,
|
3870
|
-
|
3871
|
-
|
3872
|
-
|
4243
|
+
extractContentTypeComponents as E,
|
4244
|
+
DEFAULT_SETTINGS as F,
|
4245
|
+
convertEditLayoutToFieldLayouts as G,
|
3873
4246
|
HOOKS as H,
|
3874
4247
|
InjectionZone as I,
|
3875
|
-
|
3876
|
-
|
4248
|
+
useDocument as J,
|
4249
|
+
useGetPreviewUrlQuery as K,
|
4250
|
+
index as L,
|
4251
|
+
useContentManagerContext as M,
|
4252
|
+
useDocumentActions as N,
|
3877
4253
|
Panels as P,
|
3878
4254
|
RelativeTime as R,
|
3879
4255
|
SINGLE_TYPES as S,
|
@@ -3891,18 +4267,18 @@ export {
|
|
3891
4267
|
PERMISSIONS as k,
|
3892
4268
|
DocumentRBAC as l,
|
3893
4269
|
DOCUMENT_META_FIELDS as m,
|
3894
|
-
|
3895
|
-
|
3896
|
-
|
3897
|
-
|
3898
|
-
|
4270
|
+
CLONE_PATH as n,
|
4271
|
+
useDocLayout as o,
|
4272
|
+
useGetContentTypeConfigurationQuery as p,
|
4273
|
+
CREATOR_FIELDS as q,
|
4274
|
+
getMainField as r,
|
3899
4275
|
setInitialData as s,
|
3900
|
-
|
4276
|
+
getDisplayName as t,
|
3901
4277
|
useContentTypeSchema as u,
|
3902
|
-
|
3903
|
-
|
3904
|
-
|
3905
|
-
|
3906
|
-
|
4278
|
+
checkIfAttributeIsDisplayable as v,
|
4279
|
+
useGetAllDocumentsQuery as w,
|
4280
|
+
convertListLayoutToFieldLayouts as x,
|
4281
|
+
capitalise as y,
|
4282
|
+
useUpdateContentTypeConfigurationMutation as z
|
3907
4283
|
};
|
3908
|
-
//# sourceMappingURL=index-
|
4284
|
+
//# sourceMappingURL=index-Bu_-B7ZA.mjs.map
|