@strapi/content-manager 0.0.0-experimental.32c4b04580cc12400710050c8198e46b3644cfd4 → 0.0.0-experimental.332a7d5b6b1d23635d7e205657f0ff39ec133c9e
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-BAgyHiMm.mjs → ComponentConfigurationPage-D4H-v0et.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-BAgyHiMm.mjs.map → ComponentConfigurationPage-D4H-v0et.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-5ukroXAh.js → ComponentConfigurationPage-DdkVGfXC.js} +5 -6
- package/dist/_chunks/{ComponentConfigurationPage-5ukroXAh.js.map → ComponentConfigurationPage-DdkVGfXC.js.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-DmoXawIh.mjs → EditConfigurationPage-D1nvB7Br.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-DmoXawIh.mjs.map → EditConfigurationPage-D1nvB7Br.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-Xp7lun0f.js → EditConfigurationPage-LYEvR4fW.js} +5 -6
- package/dist/_chunks/{EditConfigurationPage-Xp7lun0f.js.map → EditConfigurationPage-LYEvR4fW.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-BLsjc5F-.mjs → EditViewPage-Bcnff6Vd.mjs} +34 -46
- package/dist/_chunks/EditViewPage-Bcnff6Vd.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-C-ukDOB7.js → EditViewPage-DqelJ9UK.js} +36 -49
- package/dist/_chunks/EditViewPage-DqelJ9UK.js.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-CPYqIWDG.js → Form-CnHfBeiB.js} +39 -21
- package/dist/_chunks/Form-CnHfBeiB.js.map +1 -0
- package/dist/_chunks/{Form-Dg_GS5TQ.mjs → Form-CzPCJi3B.mjs} +37 -18
- package/dist/_chunks/Form-CzPCJi3B.mjs.map +1 -0
- package/dist/_chunks/{History-wrnHqf09.mjs → History-CcmSn3Mj.mjs} +71 -104
- package/dist/_chunks/History-CcmSn3Mj.mjs.map +1 -0
- package/dist/_chunks/{History-DNQkXANT.js → History-zArjENzj.js} +81 -115
- package/dist/_chunks/History-zArjENzj.js.map +1 -0
- package/dist/_chunks/{Field-Bfph5SOd.js → Input-CDHKQd7o.js} +1334 -1239
- package/dist/_chunks/Input-CDHKQd7o.js.map +1 -0
- package/dist/_chunks/{Field-Cs7duwWd.mjs → Input-aV8SSoTa.mjs} +1192 -1097
- package/dist/_chunks/Input-aV8SSoTa.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DScmJVkW.mjs → ListConfigurationPage-BPvzENJJ.mjs} +19 -8
- package/dist/_chunks/ListConfigurationPage-BPvzENJJ.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-CUQxfpjT.js → ListConfigurationPage-ByZAO_9H.js} +19 -9
- package/dist/_chunks/ListConfigurationPage-ByZAO_9H.js.map +1 -0
- package/dist/_chunks/{ListViewPage-BsLiH2-2.js → ListViewPage-BVKBeQAA.js} +108 -74
- package/dist/_chunks/ListViewPage-BVKBeQAA.js.map +1 -0
- package/dist/_chunks/{ListViewPage-C4IvrMgY.mjs → ListViewPage-HljQVnFH.mjs} +109 -74
- package/dist/_chunks/ListViewPage-HljQVnFH.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-BZ-PnGAf.js → NoContentTypePage-BV5zfDxr.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-BZ-PnGAf.js.map → NoContentTypePage-BV5zfDxr.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-Djg8nPlj.mjs → NoContentTypePage-BfHaSM-K.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-Djg8nPlj.mjs.map → NoContentTypePage-BfHaSM-K.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DSP7R-hv.mjs → NoPermissionsPage-D6ze2nQL.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DSP7R-hv.mjs.map → NoPermissionsPage-D6ze2nQL.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-_lUqjGW3.js → NoPermissionsPage-vdNpc6jb.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-_lUqjGW3.js.map → NoPermissionsPage-vdNpc6jb.js.map} +1 -1
- package/dist/_chunks/Preview-DEHdENT1.js +305 -0
- package/dist/_chunks/Preview-DEHdENT1.js.map +1 -0
- package/dist/_chunks/Preview-vfWOtPG5.mjs +287 -0
- package/dist/_chunks/Preview-vfWOtPG5.mjs.map +1 -0
- package/dist/_chunks/{Relations-BZr8tL0R.mjs → Relations-B7_hbF0w.mjs} +79 -44
- package/dist/_chunks/Relations-B7_hbF0w.mjs.map +1 -0
- package/dist/_chunks/{Relations-CtELXYIK.js → Relations-DcoOBejP.js} +79 -45
- package/dist/_chunks/Relations-DcoOBejP.js.map +1 -0
- package/dist/_chunks/{en-uOUIxfcQ.js → en-BR48D_RH.js} +35 -15
- package/dist/_chunks/{en-uOUIxfcQ.js.map → en-BR48D_RH.js.map} +1 -1
- package/dist/_chunks/{en-BrCTWlZv.mjs → en-D65uIF6Y.mjs} +35 -15
- package/dist/_chunks/{en-BrCTWlZv.mjs.map → en-D65uIF6Y.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-B7kGGg3E.js → fr-C43IbhA_.js} +16 -3
- package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-C43IbhA_.js.map} +1 -1
- package/dist/_chunks/{fr-CD9VFbPM.mjs → fr-DBseuRuB.mjs} +16 -3
- package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr-DBseuRuB.mjs.map} +1 -1
- package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
- package/dist/_chunks/{index-OerGjbAN.js → index-CxLSGwnk.js} +1304 -750
- package/dist/_chunks/index-CxLSGwnk.js.map +1 -0
- package/dist/_chunks/{index-c_5DdJi-.mjs → index-EH8ZtHd5.mjs} +1323 -769
- package/dist/_chunks/index-EH8ZtHd5.mjs.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-oPBiO7RY.mjs → layout-CxDMdJ13.mjs} +23 -10
- package/dist/_chunks/layout-CxDMdJ13.mjs.map +1 -0
- package/dist/_chunks/{layout-Ci7qHlFb.js → layout-DSeUTfMv.js} +23 -11
- package/dist/_chunks/layout-DSeUTfMv.js.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-BIdWFjdq.mjs → relations-B8_Uu38Q.mjs} +21 -8
- package/dist/_chunks/relations-B8_Uu38Q.mjs.map +1 -0
- package/dist/_chunks/{relations-COBpStiF.js → relations-S5nNKdN3.js} +20 -7
- package/dist/_chunks/relations-S5nNKdN3.js.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/_chunks/usePrev-B9w_-eYc.js.map +1 -1
- package/dist/_chunks/usePrev-DH6iah0A.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 +49 -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/DynamicZone/DynamicComponent.d.ts +4 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +4 -1
- 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/FormLayout.d.ts +27 -0
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- package/dist/admin/src/pages/EditView/utils/data.d.ts +1 -0
- 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 +727 -406
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +728 -406
- 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/utils/metadata.d.ts +16 -1
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
- package/dist/server/src/history/controllers/history-version.d.ts +1 -1
- package/dist/server/src/history/controllers/history-version.d.ts.map +1 -1
- package/dist/server/src/history/services/history.d.ts +3 -3
- 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 +8 -12
- 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 -16
- package/dist/_chunks/EditViewPage-BLsjc5F-.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-C-ukDOB7.js.map +0 -1
- package/dist/_chunks/Field-Bfph5SOd.js.map +0 -1
- package/dist/_chunks/Field-Cs7duwWd.mjs.map +0 -1
- package/dist/_chunks/Form-CPYqIWDG.js.map +0 -1
- package/dist/_chunks/Form-Dg_GS5TQ.mjs.map +0 -1
- package/dist/_chunks/History-DNQkXANT.js.map +0 -1
- package/dist/_chunks/History-wrnHqf09.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-CUQxfpjT.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DScmJVkW.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-BsLiH2-2.js.map +0 -1
- package/dist/_chunks/ListViewPage-C4IvrMgY.mjs.map +0 -1
- package/dist/_chunks/Relations-BZr8tL0R.mjs.map +0 -1
- package/dist/_chunks/Relations-CtELXYIK.js.map +0 -1
- package/dist/_chunks/index-OerGjbAN.js.map +0 -1
- package/dist/_chunks/index-c_5DdJi-.mjs.map +0 -1
- package/dist/_chunks/layout-Ci7qHlFb.js.map +0 -1
- package/dist/_chunks/layout-oPBiO7RY.mjs.map +0 -1
- package/dist/_chunks/relations-BIdWFjdq.mjs.map +0 -1
- package/dist/_chunks/relations-COBpStiF.js.map +0 -1
- package/strapi-server.js +0 -3
@@ -1,25 +1,34 @@
|
|
1
|
-
import {
|
1
|
+
import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check, CheckCircle, ArrowsCounterClockwise, CrossCircle, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
|
2
2
|
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
3
|
-
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, RawTable, Loader, Tbody, Tr, Td, Tooltip, LinkButton } from "@strapi/design-system";
|
7
|
+
import mapValues from "lodash/fp/mapValues";
|
7
8
|
import { useIntl } from "react-intl";
|
8
|
-
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 { generateNKeysBetween } from "fractional-indexing";
|
12
14
|
import pipe from "lodash/fp/pipe";
|
13
|
-
import { intervalToDuration, isPast } from "date-fns";
|
14
15
|
import { stringify } from "qs";
|
16
|
+
import { intervalToDuration, isPast } from "date-fns";
|
15
17
|
import { createSlice, combineReducers } from "@reduxjs/toolkit";
|
16
|
-
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
18
|
+
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
17
19
|
const v = glob[path];
|
18
20
|
if (v) {
|
19
21
|
return typeof v === "function" ? v() : Promise.resolve(v);
|
20
22
|
}
|
21
23
|
return new Promise((_, reject) => {
|
22
|
-
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
24
|
+
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
25
|
+
reject.bind(
|
26
|
+
null,
|
27
|
+
new Error(
|
28
|
+
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
29
|
+
)
|
30
|
+
)
|
31
|
+
);
|
23
32
|
});
|
24
33
|
};
|
25
34
|
const PLUGIN_ID = "content-manager";
|
@@ -100,6 +109,7 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
100
109
|
if (!slug) {
|
101
110
|
throw new Error("Cannot find the slug param in the URL");
|
102
111
|
}
|
112
|
+
const [{ rawQuery }] = useQueryParams();
|
103
113
|
const userPermissions = useAuth("DocumentRBAC", (state) => state.permissions);
|
104
114
|
const contentTypePermissions = React.useMemo(() => {
|
105
115
|
const contentTypePermissions2 = userPermissions.filter(
|
@@ -110,7 +120,14 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
110
120
|
return { ...acc, [action]: [permission] };
|
111
121
|
}, {});
|
112
122
|
}, [slug, userPermissions]);
|
113
|
-
const { isLoading, allowedActions } = useRBAC(
|
123
|
+
const { isLoading, allowedActions } = useRBAC(
|
124
|
+
contentTypePermissions,
|
125
|
+
permissions ?? void 0,
|
126
|
+
// TODO: useRBAC context should be typed and built differently
|
127
|
+
// We are passing raw query as context to the hook so that it can
|
128
|
+
// rely on the locale provided from DocumentRBAC for its permission calculations.
|
129
|
+
rawQuery
|
130
|
+
);
|
114
131
|
const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
|
115
132
|
const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
|
116
133
|
const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
|
@@ -150,6 +167,113 @@ const extractAndDedupeFields = (permissions = []) => permissions.flatMap((permis
|
|
150
167
|
(field, index2, arr) => arr.indexOf(field) === index2 && typeof field === "string"
|
151
168
|
);
|
152
169
|
const removeNumericalStrings = (arr) => arr.filter((item) => isNaN(Number(item)));
|
170
|
+
const BLOCK_LIST_ATTRIBUTE_KEYS = ["__component", "__temp_key__"];
|
171
|
+
const traverseData = (predicate, transform) => (schema, components = {}) => (data = {}) => {
|
172
|
+
const traverse = (datum, attributes) => {
|
173
|
+
return Object.entries(datum).reduce((acc, [key, value]) => {
|
174
|
+
const attribute = attributes[key];
|
175
|
+
if (BLOCK_LIST_ATTRIBUTE_KEYS.includes(key) || value === null || value === void 0) {
|
176
|
+
acc[key] = value;
|
177
|
+
return acc;
|
178
|
+
}
|
179
|
+
if (attribute.type === "component") {
|
180
|
+
if (attribute.repeatable) {
|
181
|
+
const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
|
182
|
+
acc[key] = componentValue.map(
|
183
|
+
(componentData) => traverse(componentData, components[attribute.component]?.attributes ?? {})
|
184
|
+
);
|
185
|
+
} else {
|
186
|
+
const componentValue = predicate(attribute, value) ? transform(value, attribute) : value;
|
187
|
+
acc[key] = traverse(componentValue, components[attribute.component]?.attributes ?? {});
|
188
|
+
}
|
189
|
+
} else if (attribute.type === "dynamiczone") {
|
190
|
+
const dynamicZoneValue = predicate(attribute, value) ? transform(value, attribute) : value;
|
191
|
+
acc[key] = dynamicZoneValue.map(
|
192
|
+
(componentData) => traverse(componentData, components[componentData.__component]?.attributes ?? {})
|
193
|
+
);
|
194
|
+
} else if (predicate(attribute, value)) {
|
195
|
+
acc[key] = transform(value, attribute);
|
196
|
+
} else {
|
197
|
+
acc[key] = value;
|
198
|
+
}
|
199
|
+
return acc;
|
200
|
+
}, {});
|
201
|
+
};
|
202
|
+
return traverse(data, schema.attributes);
|
203
|
+
};
|
204
|
+
const removeProhibitedFields = (prohibitedFields) => traverseData(
|
205
|
+
(attribute) => prohibitedFields.includes(attribute.type),
|
206
|
+
() => ""
|
207
|
+
);
|
208
|
+
const prepareRelations = traverseData(
|
209
|
+
(attribute) => attribute.type === "relation",
|
210
|
+
() => ({
|
211
|
+
connect: [],
|
212
|
+
disconnect: []
|
213
|
+
})
|
214
|
+
);
|
215
|
+
const prepareTempKeys = traverseData(
|
216
|
+
(attribute) => attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone",
|
217
|
+
(data) => {
|
218
|
+
if (Array.isArray(data) && data.length > 0) {
|
219
|
+
const keys = generateNKeysBetween(void 0, void 0, data.length);
|
220
|
+
return data.map((datum, index2) => ({
|
221
|
+
...datum,
|
222
|
+
__temp_key__: keys[index2]
|
223
|
+
}));
|
224
|
+
}
|
225
|
+
return data;
|
226
|
+
}
|
227
|
+
);
|
228
|
+
const removeFieldsThatDontExistOnSchema = (schema) => (data) => {
|
229
|
+
const schemaKeys = Object.keys(schema.attributes);
|
230
|
+
const dataKeys = Object.keys(data);
|
231
|
+
const keysToRemove = dataKeys.filter((key) => !schemaKeys.includes(key));
|
232
|
+
const revisedData = [...keysToRemove, ...DOCUMENT_META_FIELDS].reduce((acc, key) => {
|
233
|
+
delete acc[key];
|
234
|
+
return acc;
|
235
|
+
}, structuredClone(data));
|
236
|
+
return revisedData;
|
237
|
+
};
|
238
|
+
const removeNullValues = (data) => {
|
239
|
+
return Object.entries(data).reduce((acc, [key, value]) => {
|
240
|
+
if (value === null) {
|
241
|
+
return acc;
|
242
|
+
}
|
243
|
+
acc[key] = value;
|
244
|
+
return acc;
|
245
|
+
}, {});
|
246
|
+
};
|
247
|
+
const transformDocument = (schema, components = {}) => (document) => {
|
248
|
+
const transformations = pipe(
|
249
|
+
removeFieldsThatDontExistOnSchema(schema),
|
250
|
+
removeProhibitedFields(["password"])(schema, components),
|
251
|
+
removeNullValues,
|
252
|
+
prepareRelations(schema, components),
|
253
|
+
prepareTempKeys(schema, components)
|
254
|
+
);
|
255
|
+
return transformations(document);
|
256
|
+
};
|
257
|
+
const createDefaultForm = (contentType, components = {}) => {
|
258
|
+
const traverseSchema = (attributes) => {
|
259
|
+
return Object.entries(attributes).reduce((acc, [key, attribute]) => {
|
260
|
+
if ("default" in attribute) {
|
261
|
+
acc[key] = attribute.default;
|
262
|
+
} else if (attribute.type === "component" && attribute.required) {
|
263
|
+
const defaultComponentForm = traverseSchema(components[attribute.component].attributes);
|
264
|
+
if (attribute.repeatable) {
|
265
|
+
acc[key] = attribute.min ? [...Array(attribute.min).fill(defaultComponentForm)] : [];
|
266
|
+
} else {
|
267
|
+
acc[key] = defaultComponentForm;
|
268
|
+
}
|
269
|
+
} else if (attribute.type === "dynamiczone" && attribute.required) {
|
270
|
+
acc[key] = [];
|
271
|
+
}
|
272
|
+
return acc;
|
273
|
+
}, {});
|
274
|
+
};
|
275
|
+
return traverseSchema(contentType.attributes);
|
276
|
+
};
|
153
277
|
const contentManagerApi = adminApi.enhanceEndpoints({
|
154
278
|
addTagTypes: [
|
155
279
|
"ComponentConfiguration",
|
@@ -158,7 +282,9 @@ const contentManagerApi = adminApi.enhanceEndpoints({
|
|
158
282
|
"Document",
|
159
283
|
"InitialData",
|
160
284
|
"HistoryVersion",
|
161
|
-
"Relations"
|
285
|
+
"Relations",
|
286
|
+
"UidAvailability",
|
287
|
+
"RecentDocumentList"
|
162
288
|
]
|
163
289
|
});
|
164
290
|
const documentApi = contentManagerApi.injectEndpoints({
|
@@ -176,7 +302,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
176
302
|
if (error) {
|
177
303
|
return [];
|
178
304
|
}
|
179
|
-
return [{ type: "Document", id: `${model}_LIST` }];
|
305
|
+
return [{ type: "Document", id: `${model}_LIST` }, "RecentDocumentList"];
|
180
306
|
}
|
181
307
|
}),
|
182
308
|
cloneDocument: builder.mutation({
|
@@ -188,7 +314,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
188
314
|
params
|
189
315
|
}
|
190
316
|
}),
|
191
|
-
invalidatesTags: (_result, _error, { model }) => [
|
317
|
+
invalidatesTags: (_result, _error, { model }) => [
|
318
|
+
{ type: "Document", id: `${model}_LIST` },
|
319
|
+
{ type: "UidAvailability", id: model },
|
320
|
+
"RecentDocumentList"
|
321
|
+
]
|
192
322
|
}),
|
193
323
|
/**
|
194
324
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -205,8 +335,22 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
205
335
|
}),
|
206
336
|
invalidatesTags: (result, _error, { model }) => [
|
207
337
|
{ type: "Document", id: `${model}_LIST` },
|
208
|
-
"Relations"
|
209
|
-
|
338
|
+
"Relations",
|
339
|
+
{ type: "UidAvailability", id: model },
|
340
|
+
"RecentDocumentList"
|
341
|
+
],
|
342
|
+
transformResponse: (response, meta, arg) => {
|
343
|
+
if (!("data" in response) && arg.model === "plugin::users-permissions.user") {
|
344
|
+
return {
|
345
|
+
data: response,
|
346
|
+
meta: {
|
347
|
+
availableStatus: [],
|
348
|
+
availableLocales: []
|
349
|
+
}
|
350
|
+
};
|
351
|
+
}
|
352
|
+
return response;
|
353
|
+
}
|
210
354
|
}),
|
211
355
|
deleteDocument: builder.mutation({
|
212
356
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -217,7 +361,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
217
361
|
}
|
218
362
|
}),
|
219
363
|
invalidatesTags: (_result, _error, { collectionType, model }) => [
|
220
|
-
{ type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model }
|
364
|
+
{ type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model },
|
365
|
+
"RecentDocumentList"
|
221
366
|
]
|
222
367
|
}),
|
223
368
|
deleteManyDocuments: builder.mutation({
|
@@ -229,7 +374,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
229
374
|
params
|
230
375
|
}
|
231
376
|
}),
|
232
|
-
invalidatesTags: (_res, _error, { model }) => [
|
377
|
+
invalidatesTags: (_res, _error, { model }) => [
|
378
|
+
{ type: "Document", id: `${model}_LIST` },
|
379
|
+
"RecentDocumentList"
|
380
|
+
]
|
233
381
|
}),
|
234
382
|
discardDocument: builder.mutation({
|
235
383
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -246,7 +394,9 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
246
394
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
247
395
|
},
|
248
396
|
{ type: "Document", id: `${model}_LIST` },
|
249
|
-
"Relations"
|
397
|
+
"Relations",
|
398
|
+
{ type: "UidAvailability", id: model },
|
399
|
+
"RecentDocumentList"
|
250
400
|
];
|
251
401
|
}
|
252
402
|
}),
|
@@ -259,11 +409,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
259
409
|
url: `/content-manager/collection-types/${model}`,
|
260
410
|
method: "GET",
|
261
411
|
config: {
|
262
|
-
params
|
412
|
+
params: stringify(params, { encode: true })
|
263
413
|
}
|
264
414
|
}),
|
265
415
|
providesTags: (result, _error, arg) => {
|
266
416
|
return [
|
417
|
+
{ type: "Document", id: `ALL_LIST` },
|
267
418
|
{ type: "Document", id: `${arg.model}_LIST` },
|
268
419
|
...result?.results.map(({ documentId }) => ({
|
269
420
|
type: "Document",
|
@@ -302,6 +453,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
302
453
|
{
|
303
454
|
type: "Document",
|
304
455
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
456
|
+
},
|
457
|
+
// Make it easy to invalidate all individual documents queries for a model
|
458
|
+
{
|
459
|
+
type: "Document",
|
460
|
+
id: `${model}_ALL_ITEMS`
|
305
461
|
}
|
306
462
|
];
|
307
463
|
}
|
@@ -335,7 +491,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
335
491
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
336
492
|
},
|
337
493
|
{ type: "Document", id: `${model}_LIST` },
|
338
|
-
"Relations"
|
494
|
+
"Relations",
|
495
|
+
"RecentDocumentList"
|
339
496
|
];
|
340
497
|
}
|
341
498
|
}),
|
@@ -365,7 +522,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
365
522
|
type: "Document",
|
366
523
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
367
524
|
},
|
368
|
-
"Relations"
|
525
|
+
"Relations",
|
526
|
+
{ type: "UidAvailability", id: model },
|
527
|
+
"RecentDocumentList",
|
528
|
+
"RecentDocumentList"
|
369
529
|
];
|
370
530
|
},
|
371
531
|
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
@@ -395,7 +555,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
395
555
|
{
|
396
556
|
type: "Document",
|
397
557
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
398
|
-
}
|
558
|
+
},
|
559
|
+
"RecentDocumentList"
|
399
560
|
];
|
400
561
|
}
|
401
562
|
}),
|
@@ -408,7 +569,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
408
569
|
params
|
409
570
|
}
|
410
571
|
}),
|
411
|
-
invalidatesTags: (_res, _error, { model, documentIds }) =>
|
572
|
+
invalidatesTags: (_res, _error, { model, documentIds }) => [
|
573
|
+
...documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` })),
|
574
|
+
"RecentDocumentList"
|
575
|
+
]
|
412
576
|
})
|
413
577
|
})
|
414
578
|
});
|
@@ -431,8 +595,7 @@ const {
|
|
431
595
|
useUnpublishManyDocumentsMutation
|
432
596
|
} = documentApi;
|
433
597
|
const buildValidParams = (query) => {
|
434
|
-
if (!query)
|
435
|
-
return query;
|
598
|
+
if (!query) return query;
|
436
599
|
const { plugins: _, ...validQueryParams } = {
|
437
600
|
...query,
|
438
601
|
...Object.values(query?.plugins ?? {}).reduce(
|
@@ -440,28 +603,44 @@ const buildValidParams = (query) => {
|
|
440
603
|
{}
|
441
604
|
)
|
442
605
|
};
|
443
|
-
if ("_q" in validQueryParams) {
|
444
|
-
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
445
|
-
}
|
446
606
|
return validQueryParams;
|
447
607
|
};
|
448
608
|
const isBaseQueryError = (error) => {
|
449
609
|
return error.name !== void 0;
|
450
610
|
};
|
451
|
-
const
|
611
|
+
const arrayValidator = (attribute, options) => ({
|
612
|
+
message: translatedErrors.required,
|
613
|
+
test(value) {
|
614
|
+
if (options.status === "draft") {
|
615
|
+
return true;
|
616
|
+
}
|
617
|
+
if (!attribute.required) {
|
618
|
+
return true;
|
619
|
+
}
|
620
|
+
if (!value) {
|
621
|
+
return false;
|
622
|
+
}
|
623
|
+
if (Array.isArray(value) && value.length === 0) {
|
624
|
+
return false;
|
625
|
+
}
|
626
|
+
return true;
|
627
|
+
}
|
628
|
+
});
|
629
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
452
630
|
const createModelSchema = (attributes2) => yup.object().shape(
|
453
631
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
454
632
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
455
633
|
return acc;
|
456
634
|
}
|
457
635
|
const validations = [
|
636
|
+
addNullableValidation,
|
458
637
|
addRequiredValidation,
|
459
638
|
addMinLengthValidation,
|
460
639
|
addMaxLengthValidation,
|
461
640
|
addMinValidation,
|
462
641
|
addMaxValidation,
|
463
642
|
addRegexValidation
|
464
|
-
].map((fn) => fn(attribute));
|
643
|
+
].map((fn) => fn(attribute, options));
|
465
644
|
const transformSchema = pipe(...validations);
|
466
645
|
switch (attribute.type) {
|
467
646
|
case "component": {
|
@@ -471,12 +650,12 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
471
650
|
...acc,
|
472
651
|
[name]: transformSchema(
|
473
652
|
yup.array().of(createModelSchema(attributes3).nullable(false))
|
474
|
-
)
|
653
|
+
).test(arrayValidator(attribute, options))
|
475
654
|
};
|
476
655
|
} else {
|
477
656
|
return {
|
478
657
|
...acc,
|
479
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
658
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
480
659
|
};
|
481
660
|
}
|
482
661
|
}
|
@@ -498,7 +677,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
498
677
|
}
|
499
678
|
)
|
500
679
|
)
|
501
|
-
)
|
680
|
+
).test(arrayValidator(attribute, options))
|
502
681
|
};
|
503
682
|
case "relation":
|
504
683
|
return {
|
@@ -510,7 +689,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
510
689
|
} else if (Array.isArray(value)) {
|
511
690
|
return yup.array().of(
|
512
691
|
yup.object().shape({
|
513
|
-
id: yup.
|
692
|
+
id: yup.number().required()
|
514
693
|
})
|
515
694
|
);
|
516
695
|
} else if (typeof value === "object") {
|
@@ -562,6 +741,14 @@ const createAttributeSchema = (attribute) => {
|
|
562
741
|
if (!value || typeof value === "string" && value.length === 0) {
|
563
742
|
return true;
|
564
743
|
}
|
744
|
+
if (typeof value === "object") {
|
745
|
+
try {
|
746
|
+
JSON.stringify(value);
|
747
|
+
return true;
|
748
|
+
} catch (err) {
|
749
|
+
return false;
|
750
|
+
}
|
751
|
+
}
|
565
752
|
try {
|
566
753
|
JSON.parse(value);
|
567
754
|
return true;
|
@@ -580,13 +767,7 @@ const createAttributeSchema = (attribute) => {
|
|
580
767
|
return yup.mixed();
|
581
768
|
}
|
582
769
|
};
|
583
|
-
const
|
584
|
-
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
585
|
-
return schema.min(1, translatedErrors.required);
|
586
|
-
}
|
587
|
-
if (attribute.required && attribute.type !== "relation") {
|
588
|
-
return schema.required(translatedErrors.required);
|
589
|
-
}
|
770
|
+
const nullableSchema = (schema) => {
|
590
771
|
return schema?.nullable ? schema.nullable() : (
|
591
772
|
// In some cases '.nullable' will not be available on the schema.
|
592
773
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -594,7 +775,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
594
775
|
schema
|
595
776
|
);
|
596
777
|
};
|
597
|
-
const
|
778
|
+
const addNullableValidation = () => (schema) => {
|
779
|
+
return nullableSchema(schema);
|
780
|
+
};
|
781
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
782
|
+
if (options.status === "draft" || !attribute.required) {
|
783
|
+
return schema;
|
784
|
+
}
|
785
|
+
if (attribute.required && "required" in schema) {
|
786
|
+
return schema.required(translatedErrors.required);
|
787
|
+
}
|
788
|
+
return schema;
|
789
|
+
};
|
790
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
791
|
+
if (options.status === "draft") {
|
792
|
+
return schema;
|
793
|
+
}
|
598
794
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
599
795
|
return schema.min(attribute.minLength, {
|
600
796
|
...translatedErrors.minLength,
|
@@ -616,32 +812,13 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
616
812
|
}
|
617
813
|
return schema;
|
618
814
|
};
|
619
|
-
const addMinValidation = (attribute) => (schema) => {
|
620
|
-
if ("
|
815
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
816
|
+
if (options.status === "draft") {
|
817
|
+
return schema;
|
818
|
+
}
|
819
|
+
if ("min" in attribute && "min" in schema) {
|
621
820
|
const min = toInteger(attribute.min);
|
622
|
-
if (
|
623
|
-
if (!attribute.required && "test" in schema && min) {
|
624
|
-
return schema.test(
|
625
|
-
"custom-min",
|
626
|
-
{
|
627
|
-
...translatedErrors.min,
|
628
|
-
values: {
|
629
|
-
min: attribute.min
|
630
|
-
}
|
631
|
-
},
|
632
|
-
(value) => {
|
633
|
-
if (!value) {
|
634
|
-
return true;
|
635
|
-
}
|
636
|
-
if (Array.isArray(value) && value.length === 0) {
|
637
|
-
return true;
|
638
|
-
}
|
639
|
-
return value.length >= min;
|
640
|
-
}
|
641
|
-
);
|
642
|
-
}
|
643
|
-
}
|
644
|
-
if ("min" in schema && min) {
|
821
|
+
if (min) {
|
645
822
|
return schema.min(min, {
|
646
823
|
...translatedErrors.min,
|
647
824
|
values: {
|
@@ -759,19 +936,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
759
936
|
}, {});
|
760
937
|
return componentsByKey;
|
761
938
|
};
|
762
|
-
const
|
939
|
+
const HOOKS = {
|
940
|
+
/**
|
941
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
942
|
+
* @constant
|
943
|
+
* @type {string}
|
944
|
+
*/
|
945
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
946
|
+
/**
|
947
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
948
|
+
* @constant
|
949
|
+
* @type {string}
|
950
|
+
*/
|
951
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
952
|
+
/**
|
953
|
+
* Hook that allows to mutate the CM's edit view layout
|
954
|
+
* @constant
|
955
|
+
* @type {string}
|
956
|
+
*/
|
957
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
958
|
+
/**
|
959
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
960
|
+
* @constant
|
961
|
+
* @type {string}
|
962
|
+
*/
|
963
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
964
|
+
};
|
965
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
966
|
+
endpoints: (builder) => ({
|
967
|
+
getContentTypeConfiguration: builder.query({
|
968
|
+
query: (uid) => ({
|
969
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
970
|
+
method: "GET"
|
971
|
+
}),
|
972
|
+
transformResponse: (response) => response.data,
|
973
|
+
providesTags: (_result, _error, uid) => [
|
974
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
975
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
976
|
+
]
|
977
|
+
}),
|
978
|
+
getAllContentTypeSettings: builder.query({
|
979
|
+
query: () => "/content-manager/content-types-settings",
|
980
|
+
transformResponse: (response) => response.data,
|
981
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
982
|
+
}),
|
983
|
+
updateContentTypeConfiguration: builder.mutation({
|
984
|
+
query: ({ uid, ...body }) => ({
|
985
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
986
|
+
method: "PUT",
|
987
|
+
data: body
|
988
|
+
}),
|
989
|
+
transformResponse: (response) => response.data,
|
990
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
991
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
992
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
993
|
+
// Is this necessary?
|
994
|
+
{ type: "InitialData" }
|
995
|
+
]
|
996
|
+
})
|
997
|
+
})
|
998
|
+
});
|
999
|
+
const {
|
1000
|
+
useGetContentTypeConfigurationQuery,
|
1001
|
+
useGetAllContentTypeSettingsQuery,
|
1002
|
+
useUpdateContentTypeConfigurationMutation
|
1003
|
+
} = contentTypesApi;
|
1004
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
1005
|
+
const { type } = attribute;
|
1006
|
+
if (type === "relation") {
|
1007
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
1008
|
+
}
|
1009
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
1010
|
+
};
|
1011
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
1012
|
+
if (!mainFieldName) {
|
1013
|
+
return void 0;
|
1014
|
+
}
|
1015
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
1016
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
1017
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
1018
|
+
);
|
1019
|
+
return {
|
1020
|
+
name: mainFieldName,
|
1021
|
+
type: mainFieldType ?? "string"
|
1022
|
+
};
|
1023
|
+
};
|
1024
|
+
const DEFAULT_SETTINGS = {
|
1025
|
+
bulkable: false,
|
1026
|
+
filterable: false,
|
1027
|
+
searchable: false,
|
1028
|
+
pagination: false,
|
1029
|
+
defaultSortBy: "",
|
1030
|
+
defaultSortOrder: "asc",
|
1031
|
+
mainField: "id",
|
1032
|
+
pageSize: 10
|
1033
|
+
};
|
1034
|
+
const useDocumentLayout = (model) => {
|
1035
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
1036
|
+
const [{ query }] = useQueryParams();
|
1037
|
+
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
763
1038
|
const { toggleNotification } = useNotification();
|
764
1039
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1040
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
765
1041
|
const {
|
766
|
-
|
767
|
-
isLoading:
|
768
|
-
|
769
|
-
|
770
|
-
} =
|
771
|
-
|
772
|
-
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
773
|
-
});
|
774
|
-
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
1042
|
+
data,
|
1043
|
+
isLoading: isLoadingConfigs,
|
1044
|
+
error,
|
1045
|
+
isFetching: isFetchingConfigs
|
1046
|
+
} = useGetContentTypeConfigurationQuery(model);
|
1047
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
775
1048
|
React.useEffect(() => {
|
776
1049
|
if (error) {
|
777
1050
|
toggleNotification({
|
@@ -779,40 +1052,284 @@ const useDocument = (args, opts) => {
|
|
779
1052
|
message: formatAPIError(error)
|
780
1053
|
});
|
781
1054
|
}
|
782
|
-
}, [
|
783
|
-
const
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
(document) => {
|
791
|
-
if (!validationSchema) {
|
792
|
-
throw new Error(
|
793
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
794
|
-
);
|
795
|
-
}
|
796
|
-
try {
|
797
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
798
|
-
return null;
|
799
|
-
} catch (error2) {
|
800
|
-
if (error2 instanceof ValidationError) {
|
801
|
-
return getYupValidationErrors(error2);
|
802
|
-
}
|
803
|
-
throw error2;
|
804
|
-
}
|
1055
|
+
}, [error, formatAPIError, toggleNotification]);
|
1056
|
+
const editLayout = React.useMemo(
|
1057
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
1058
|
+
layout: [],
|
1059
|
+
components: {},
|
1060
|
+
metadatas: {},
|
1061
|
+
options: {},
|
1062
|
+
settings: DEFAULT_SETTINGS
|
805
1063
|
},
|
806
|
-
[
|
1064
|
+
[data, isLoading, schemas, schema, components]
|
1065
|
+
);
|
1066
|
+
const listLayout = React.useMemo(() => {
|
1067
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
1068
|
+
layout: [],
|
1069
|
+
metadatas: {},
|
1070
|
+
options: {},
|
1071
|
+
settings: DEFAULT_SETTINGS
|
1072
|
+
};
|
1073
|
+
}, [data, isLoading, schemas, schema, components]);
|
1074
|
+
const { layout: edit } = React.useMemo(
|
1075
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
1076
|
+
layout: editLayout,
|
1077
|
+
query
|
1078
|
+
}),
|
1079
|
+
[editLayout, query, runHookWaterfall]
|
807
1080
|
);
|
808
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
809
1081
|
return {
|
810
|
-
|
811
|
-
|
812
|
-
|
1082
|
+
error,
|
1083
|
+
isLoading,
|
1084
|
+
edit,
|
1085
|
+
list: listLayout
|
1086
|
+
};
|
1087
|
+
};
|
1088
|
+
const useDocLayout = () => {
|
1089
|
+
const { model } = useDoc();
|
1090
|
+
return useDocumentLayout(model);
|
1091
|
+
};
|
1092
|
+
const formatEditLayout = (data, {
|
1093
|
+
schemas,
|
1094
|
+
schema,
|
1095
|
+
components
|
1096
|
+
}) => {
|
1097
|
+
let currentPanelIndex = 0;
|
1098
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
1099
|
+
data.contentType.layouts.edit,
|
1100
|
+
schema?.attributes,
|
1101
|
+
data.contentType.metadatas,
|
1102
|
+
{ configurations: data.components, schemas: components },
|
1103
|
+
schemas
|
1104
|
+
).reduce((panels, row) => {
|
1105
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
1106
|
+
panels.push([row]);
|
1107
|
+
currentPanelIndex += 2;
|
1108
|
+
} else {
|
1109
|
+
if (!panels[currentPanelIndex]) {
|
1110
|
+
panels.push([row]);
|
1111
|
+
} else {
|
1112
|
+
panels[currentPanelIndex].push(row);
|
1113
|
+
}
|
1114
|
+
}
|
1115
|
+
return panels;
|
1116
|
+
}, []);
|
1117
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
1118
|
+
(acc, [uid, configuration]) => {
|
1119
|
+
acc[uid] = {
|
1120
|
+
layout: convertEditLayoutToFieldLayouts(
|
1121
|
+
configuration.layouts.edit,
|
1122
|
+
components[uid].attributes,
|
1123
|
+
configuration.metadatas,
|
1124
|
+
{ configurations: data.components, schemas: components }
|
1125
|
+
),
|
1126
|
+
settings: {
|
1127
|
+
...configuration.settings,
|
1128
|
+
icon: components[uid].info.icon,
|
1129
|
+
displayName: components[uid].info.displayName
|
1130
|
+
}
|
1131
|
+
};
|
1132
|
+
return acc;
|
1133
|
+
},
|
1134
|
+
{}
|
1135
|
+
);
|
1136
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1137
|
+
(acc, [attribute, metadata]) => {
|
1138
|
+
return {
|
1139
|
+
...acc,
|
1140
|
+
[attribute]: metadata.edit
|
1141
|
+
};
|
1142
|
+
},
|
1143
|
+
{}
|
1144
|
+
);
|
1145
|
+
return {
|
1146
|
+
layout: panelledEditAttributes,
|
1147
|
+
components: componentEditAttributes,
|
1148
|
+
metadatas: editMetadatas,
|
1149
|
+
settings: {
|
1150
|
+
...data.contentType.settings,
|
1151
|
+
displayName: schema?.info.displayName
|
1152
|
+
},
|
1153
|
+
options: {
|
1154
|
+
...schema?.options,
|
1155
|
+
...schema?.pluginOptions,
|
1156
|
+
...data.contentType.options
|
1157
|
+
}
|
1158
|
+
};
|
1159
|
+
};
|
1160
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1161
|
+
return rows.map(
|
1162
|
+
(row) => row.map((field) => {
|
1163
|
+
const attribute = attributes[field.name];
|
1164
|
+
if (!attribute) {
|
1165
|
+
return null;
|
1166
|
+
}
|
1167
|
+
const { edit: metadata } = metadatas[field.name];
|
1168
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1169
|
+
return {
|
1170
|
+
attribute,
|
1171
|
+
disabled: !metadata.editable,
|
1172
|
+
hint: metadata.description,
|
1173
|
+
label: metadata.label ?? "",
|
1174
|
+
name: field.name,
|
1175
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1176
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1177
|
+
schemas,
|
1178
|
+
components: components?.schemas ?? {}
|
1179
|
+
}),
|
1180
|
+
placeholder: metadata.placeholder ?? "",
|
1181
|
+
required: attribute.required ?? false,
|
1182
|
+
size: field.size,
|
1183
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1184
|
+
visible: metadata.visible ?? true,
|
1185
|
+
type: attribute.type
|
1186
|
+
};
|
1187
|
+
}).filter((field) => field !== null)
|
1188
|
+
);
|
1189
|
+
};
|
1190
|
+
const formatListLayout = (data, {
|
1191
|
+
schemas,
|
1192
|
+
schema,
|
1193
|
+
components
|
1194
|
+
}) => {
|
1195
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1196
|
+
(acc, [attribute, metadata]) => {
|
1197
|
+
return {
|
1198
|
+
...acc,
|
1199
|
+
[attribute]: metadata.list
|
1200
|
+
};
|
1201
|
+
},
|
1202
|
+
{}
|
1203
|
+
);
|
1204
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1205
|
+
data.contentType.layouts.list,
|
1206
|
+
schema?.attributes,
|
1207
|
+
listMetadatas,
|
1208
|
+
{ configurations: data.components, schemas: components },
|
1209
|
+
schemas
|
1210
|
+
);
|
1211
|
+
return {
|
1212
|
+
layout: listAttributes,
|
1213
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1214
|
+
metadatas: listMetadatas,
|
1215
|
+
options: {
|
1216
|
+
...schema?.options,
|
1217
|
+
...schema?.pluginOptions,
|
1218
|
+
...data.contentType.options
|
1219
|
+
}
|
1220
|
+
};
|
1221
|
+
};
|
1222
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1223
|
+
return columns.map((name) => {
|
1224
|
+
const attribute = attributes[name];
|
1225
|
+
if (!attribute) {
|
1226
|
+
return null;
|
1227
|
+
}
|
1228
|
+
const metadata = metadatas[name];
|
1229
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1230
|
+
return {
|
1231
|
+
attribute,
|
1232
|
+
label: metadata.label ?? "",
|
1233
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1234
|
+
schemas,
|
1235
|
+
components: components?.schemas ?? {}
|
1236
|
+
}),
|
1237
|
+
name,
|
1238
|
+
searchable: metadata.searchable ?? true,
|
1239
|
+
sortable: metadata.sortable ?? true
|
1240
|
+
};
|
1241
|
+
}).filter((field) => field !== null);
|
1242
|
+
};
|
1243
|
+
const useDocument = (args, opts) => {
|
1244
|
+
const { toggleNotification } = useNotification();
|
1245
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1246
|
+
const { formatMessage } = useIntl();
|
1247
|
+
const {
|
1248
|
+
currentData: data,
|
1249
|
+
isLoading: isLoadingDocument,
|
1250
|
+
isFetching: isFetchingDocument,
|
1251
|
+
error
|
1252
|
+
} = useGetDocumentQuery(args, {
|
1253
|
+
...opts,
|
1254
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1255
|
+
});
|
1256
|
+
const document = data?.data;
|
1257
|
+
const meta = data?.meta;
|
1258
|
+
const {
|
1259
|
+
components,
|
1260
|
+
schema,
|
1261
|
+
schemas,
|
1262
|
+
isLoading: isLoadingSchema
|
1263
|
+
} = useContentTypeSchema(args.model);
|
1264
|
+
const isSingleType = schema?.kind === "singleType";
|
1265
|
+
const getTitle = (mainField) => {
|
1266
|
+
if (mainField !== "id" && document?.[mainField]) {
|
1267
|
+
return document[mainField];
|
1268
|
+
}
|
1269
|
+
if (isSingleType && schema?.info.displayName) {
|
1270
|
+
return schema.info.displayName;
|
1271
|
+
}
|
1272
|
+
return formatMessage({
|
1273
|
+
id: "content-manager.containers.untitled",
|
1274
|
+
defaultMessage: "Untitled"
|
1275
|
+
});
|
1276
|
+
};
|
1277
|
+
React.useEffect(() => {
|
1278
|
+
if (error) {
|
1279
|
+
toggleNotification({
|
1280
|
+
type: "danger",
|
1281
|
+
message: formatAPIError(error)
|
1282
|
+
});
|
1283
|
+
}
|
1284
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1285
|
+
const validationSchema = React.useMemo(() => {
|
1286
|
+
if (!schema) {
|
1287
|
+
return null;
|
1288
|
+
}
|
1289
|
+
return createYupSchema(schema.attributes, components);
|
1290
|
+
}, [schema, components]);
|
1291
|
+
const validate = React.useCallback(
|
1292
|
+
(document2) => {
|
1293
|
+
if (!validationSchema) {
|
1294
|
+
throw new Error(
|
1295
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1296
|
+
);
|
1297
|
+
}
|
1298
|
+
try {
|
1299
|
+
validationSchema.validateSync(document2, { abortEarly: false, strict: true });
|
1300
|
+
return null;
|
1301
|
+
} catch (error2) {
|
1302
|
+
if (error2 instanceof ValidationError) {
|
1303
|
+
return getYupValidationErrors(error2);
|
1304
|
+
}
|
1305
|
+
throw error2;
|
1306
|
+
}
|
1307
|
+
},
|
1308
|
+
[validationSchema]
|
1309
|
+
);
|
1310
|
+
const getInitialFormValues = React.useCallback(
|
1311
|
+
(isCreatingDocument = false) => {
|
1312
|
+
if (!document && !isCreatingDocument && !isSingleType || !schema) {
|
1313
|
+
return void 0;
|
1314
|
+
}
|
1315
|
+
const form = document?.id ? document : createDefaultForm(schema, components);
|
1316
|
+
return transformDocument(schema, components)(form);
|
1317
|
+
},
|
1318
|
+
[document, isSingleType, schema, components]
|
1319
|
+
);
|
1320
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1321
|
+
const hasError = !!error;
|
1322
|
+
return {
|
1323
|
+
components,
|
1324
|
+
document,
|
1325
|
+
meta,
|
813
1326
|
isLoading,
|
1327
|
+
hasError,
|
814
1328
|
schema,
|
815
|
-
|
1329
|
+
schemas,
|
1330
|
+
validate,
|
1331
|
+
getTitle,
|
1332
|
+
getInitialFormValues
|
816
1333
|
};
|
817
1334
|
};
|
818
1335
|
const useDoc = () => {
|
@@ -825,22 +1342,60 @@ const useDoc = () => {
|
|
825
1342
|
if (!slug) {
|
826
1343
|
throw new Error("Could not find model in url params");
|
827
1344
|
}
|
1345
|
+
const document = useDocument(
|
1346
|
+
{ documentId: origin || id, model: slug, collectionType, params },
|
1347
|
+
{
|
1348
|
+
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
1349
|
+
}
|
1350
|
+
);
|
1351
|
+
const returnId = origin || id === "create" ? void 0 : id;
|
828
1352
|
return {
|
829
1353
|
collectionType,
|
830
1354
|
model: slug,
|
831
|
-
id:
|
832
|
-
...
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
1355
|
+
id: returnId,
|
1356
|
+
...document
|
1357
|
+
};
|
1358
|
+
};
|
1359
|
+
const useContentManagerContext = () => {
|
1360
|
+
const {
|
1361
|
+
collectionType,
|
1362
|
+
model,
|
1363
|
+
id,
|
1364
|
+
components,
|
1365
|
+
isLoading: isLoadingDoc,
|
1366
|
+
schema,
|
1367
|
+
schemas
|
1368
|
+
} = useDoc();
|
1369
|
+
const layout = useDocumentLayout(model);
|
1370
|
+
const form = useForm("useContentManagerContext", (state) => state);
|
1371
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1372
|
+
const slug = model;
|
1373
|
+
const isCreatingEntry = id === "create";
|
1374
|
+
useContentTypeSchema();
|
1375
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1376
|
+
const error = layout.error;
|
1377
|
+
return {
|
1378
|
+
error,
|
1379
|
+
isLoading,
|
1380
|
+
// Base metadata
|
1381
|
+
model,
|
1382
|
+
collectionType,
|
1383
|
+
id,
|
1384
|
+
slug,
|
1385
|
+
isCreatingEntry,
|
1386
|
+
isSingleType,
|
1387
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1388
|
+
// All schema infos
|
1389
|
+
components,
|
1390
|
+
contentType: schema,
|
1391
|
+
contentTypes: schemas,
|
1392
|
+
// Form state
|
1393
|
+
form,
|
1394
|
+
// layout infos
|
1395
|
+
layout
|
838
1396
|
};
|
839
1397
|
};
|
840
1398
|
const prefixPluginTranslations = (trad, pluginId) => {
|
841
|
-
if (!pluginId) {
|
842
|
-
throw new TypeError("pluginId can't be empty");
|
843
|
-
}
|
844
1399
|
return Object.keys(trad).reduce((acc, current) => {
|
845
1400
|
acc[`${pluginId}.${current}`] = trad[current];
|
846
1401
|
return acc;
|
@@ -856,6 +1411,8 @@ const useDocumentActions = () => {
|
|
856
1411
|
const { formatMessage } = useIntl();
|
857
1412
|
const { trackUsage } = useTracking();
|
858
1413
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1414
|
+
const navigate = useNavigate();
|
1415
|
+
const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
859
1416
|
const [deleteDocument] = useDeleteDocumentMutation();
|
860
1417
|
const _delete = React.useCallback(
|
861
1418
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1170,6 +1727,7 @@ const useDocumentActions = () => {
|
|
1170
1727
|
defaultMessage: "Saved document"
|
1171
1728
|
})
|
1172
1729
|
});
|
1730
|
+
setCurrentStep("contentManager.success");
|
1173
1731
|
return res.data;
|
1174
1732
|
} catch (err) {
|
1175
1733
|
toggleNotification({
|
@@ -1209,7 +1767,7 @@ const useDocumentActions = () => {
|
|
1209
1767
|
throw err;
|
1210
1768
|
}
|
1211
1769
|
},
|
1212
|
-
[autoCloneDocument,
|
1770
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1213
1771
|
);
|
1214
1772
|
const [cloneDocument] = useCloneDocumentMutation();
|
1215
1773
|
const clone = React.useCallback(
|
@@ -1235,6 +1793,7 @@ const useDocumentActions = () => {
|
|
1235
1793
|
defaultMessage: "Cloned document"
|
1236
1794
|
})
|
1237
1795
|
});
|
1796
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1238
1797
|
return res.data;
|
1239
1798
|
} catch (err) {
|
1240
1799
|
toggleNotification({
|
@@ -1245,7 +1804,7 @@ const useDocumentActions = () => {
|
|
1245
1804
|
throw err;
|
1246
1805
|
}
|
1247
1806
|
},
|
1248
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1807
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1249
1808
|
);
|
1250
1809
|
const [getDoc] = useLazyGetDocumentQuery();
|
1251
1810
|
const getDocument = React.useCallback(
|
@@ -1270,10 +1829,10 @@ const useDocumentActions = () => {
|
|
1270
1829
|
update
|
1271
1830
|
};
|
1272
1831
|
};
|
1273
|
-
const ProtectedHistoryPage = lazy(
|
1274
|
-
() => import("./History-
|
1832
|
+
const ProtectedHistoryPage = React.lazy(
|
1833
|
+
() => import("./History-CcmSn3Mj.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1275
1834
|
);
|
1276
|
-
const routes$
|
1835
|
+
const routes$2 = [
|
1277
1836
|
{
|
1278
1837
|
path: ":collectionType/:slug/:id/history",
|
1279
1838
|
Component: ProtectedHistoryPage
|
@@ -1283,32 +1842,45 @@ const routes$1 = [
|
|
1283
1842
|
Component: ProtectedHistoryPage
|
1284
1843
|
}
|
1285
1844
|
];
|
1845
|
+
const ProtectedPreviewPage = React.lazy(
|
1846
|
+
() => import("./Preview-vfWOtPG5.mjs").then((mod) => ({ default: mod.ProtectedPreviewPage }))
|
1847
|
+
);
|
1848
|
+
const routes$1 = [
|
1849
|
+
{
|
1850
|
+
path: ":collectionType/:slug/:id/preview",
|
1851
|
+
Component: ProtectedPreviewPage
|
1852
|
+
},
|
1853
|
+
{
|
1854
|
+
path: ":collectionType/:slug/preview",
|
1855
|
+
Component: ProtectedPreviewPage
|
1856
|
+
}
|
1857
|
+
];
|
1286
1858
|
const ProtectedEditViewPage = lazy(
|
1287
|
-
() => import("./EditViewPage-
|
1859
|
+
() => import("./EditViewPage-Bcnff6Vd.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1288
1860
|
);
|
1289
1861
|
const ProtectedListViewPage = lazy(
|
1290
|
-
() => import("./ListViewPage-
|
1862
|
+
() => import("./ListViewPage-HljQVnFH.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1291
1863
|
);
|
1292
1864
|
const ProtectedListConfiguration = lazy(
|
1293
|
-
() => import("./ListConfigurationPage-
|
1865
|
+
() => import("./ListConfigurationPage-BPvzENJJ.mjs").then((mod) => ({
|
1294
1866
|
default: mod.ProtectedListConfiguration
|
1295
1867
|
}))
|
1296
1868
|
);
|
1297
1869
|
const ProtectedEditConfigurationPage = lazy(
|
1298
|
-
() => import("./EditConfigurationPage-
|
1870
|
+
() => import("./EditConfigurationPage-D1nvB7Br.mjs").then((mod) => ({
|
1299
1871
|
default: mod.ProtectedEditConfigurationPage
|
1300
1872
|
}))
|
1301
1873
|
);
|
1302
1874
|
const ProtectedComponentConfigurationPage = lazy(
|
1303
|
-
() => import("./ComponentConfigurationPage-
|
1875
|
+
() => import("./ComponentConfigurationPage-D4H-v0et.mjs").then((mod) => ({
|
1304
1876
|
default: mod.ProtectedComponentConfigurationPage
|
1305
1877
|
}))
|
1306
1878
|
);
|
1307
1879
|
const NoPermissions = lazy(
|
1308
|
-
() => import("./NoPermissionsPage-
|
1880
|
+
() => import("./NoPermissionsPage-D6ze2nQL.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1309
1881
|
);
|
1310
1882
|
const NoContentType = lazy(
|
1311
|
-
() => import("./NoContentTypePage-
|
1883
|
+
() => import("./NoContentTypePage-BfHaSM-K.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1312
1884
|
);
|
1313
1885
|
const CollectionTypePages = () => {
|
1314
1886
|
const { collectionType } = useParams();
|
@@ -1320,7 +1892,7 @@ const CollectionTypePages = () => {
|
|
1320
1892
|
const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
|
1321
1893
|
const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
|
1322
1894
|
const LIST_RELATIVE_PATH = ":collectionType/:slug";
|
1323
|
-
const LIST_PATH = `/content-manager
|
1895
|
+
const LIST_PATH = `/content-manager/collection-types/:slug`;
|
1324
1896
|
const routes = [
|
1325
1897
|
{
|
1326
1898
|
path: LIST_RELATIVE_PATH,
|
@@ -1354,6 +1926,7 @@ const routes = [
|
|
1354
1926
|
path: "no-content-types",
|
1355
1927
|
Component: NoContentType
|
1356
1928
|
},
|
1929
|
+
...routes$2,
|
1357
1930
|
...routes$1
|
1358
1931
|
];
|
1359
1932
|
const DocumentActions = ({ actions: actions2 }) => {
|
@@ -1422,12 +1995,14 @@ const DocumentActionButton = (action) => {
|
|
1422
1995
|
/* @__PURE__ */ jsx(
|
1423
1996
|
Button,
|
1424
1997
|
{
|
1425
|
-
flex:
|
1998
|
+
flex: "auto",
|
1426
1999
|
startIcon: action.icon,
|
1427
2000
|
disabled: action.disabled,
|
1428
2001
|
onClick: handleClick(action),
|
1429
2002
|
justifyContent: "center",
|
1430
2003
|
variant: action.variant || "default",
|
2004
|
+
paddingTop: "7px",
|
2005
|
+
paddingBottom: "7px",
|
1431
2006
|
children: action.label
|
1432
2007
|
}
|
1433
2008
|
),
|
@@ -1450,6 +2025,11 @@ const DocumentActionButton = (action) => {
|
|
1450
2025
|
) : null
|
1451
2026
|
] });
|
1452
2027
|
};
|
2028
|
+
const MenuItem = styled(Menu.Item)`
|
2029
|
+
&:hover {
|
2030
|
+
background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
|
2031
|
+
}
|
2032
|
+
`;
|
1453
2033
|
const DocumentActionsMenu = ({
|
1454
2034
|
actions: actions2,
|
1455
2035
|
children,
|
@@ -1492,9 +2072,9 @@ const DocumentActionsMenu = ({
|
|
1492
2072
|
disabled: isDisabled,
|
1493
2073
|
size: "S",
|
1494
2074
|
endIcon: null,
|
1495
|
-
paddingTop: "
|
1496
|
-
paddingLeft: "
|
1497
|
-
paddingRight: "
|
2075
|
+
paddingTop: "4px",
|
2076
|
+
paddingLeft: "7px",
|
2077
|
+
paddingRight: "7px",
|
1498
2078
|
variant,
|
1499
2079
|
children: [
|
1500
2080
|
/* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
|
@@ -1505,36 +2085,35 @@ const DocumentActionsMenu = ({
|
|
1505
2085
|
]
|
1506
2086
|
}
|
1507
2087
|
),
|
1508
|
-
/* @__PURE__ */ jsxs(Menu.Content, {
|
2088
|
+
/* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1509
2089
|
actions2.map((action) => {
|
1510
2090
|
return /* @__PURE__ */ jsx(
|
1511
|
-
|
2091
|
+
MenuItem,
|
1512
2092
|
{
|
1513
2093
|
disabled: action.disabled,
|
1514
2094
|
onSelect: handleClick(action),
|
1515
2095
|
display: "block",
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
] })
|
2096
|
+
isVariantDanger: action.variant === "danger",
|
2097
|
+
isDisabled: action.disabled,
|
2098
|
+
children: /* @__PURE__ */ jsx(Flex, { justifyContent: "space-between", gap: 4, children: /* @__PURE__ */ jsxs(
|
2099
|
+
Flex,
|
2100
|
+
{
|
2101
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
2102
|
+
gap: 2,
|
2103
|
+
tag: "span",
|
2104
|
+
children: [
|
2105
|
+
/* @__PURE__ */ jsx(
|
2106
|
+
Flex,
|
2107
|
+
{
|
2108
|
+
tag: "span",
|
2109
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
2110
|
+
children: action.icon
|
2111
|
+
}
|
2112
|
+
),
|
2113
|
+
action.label
|
2114
|
+
]
|
2115
|
+
}
|
2116
|
+
) })
|
1538
2117
|
},
|
1539
2118
|
action.id
|
1540
2119
|
);
|
@@ -1614,11 +2193,11 @@ const DocumentActionConfirmDialog = ({
|
|
1614
2193
|
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
1615
2194
|
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
1616
2195
|
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
1617
|
-
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
|
2196
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
1618
2197
|
id: "app.components.Button.cancel",
|
1619
2198
|
defaultMessage: "Cancel"
|
1620
2199
|
}) }) }),
|
1621
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2200
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1622
2201
|
id: "app.components.Button.confirm",
|
1623
2202
|
defaultMessage: "Confirm"
|
1624
2203
|
}) })
|
@@ -1645,8 +2224,20 @@ const DocumentActionModal = ({
|
|
1645
2224
|
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1646
2225
|
] }) });
|
1647
2226
|
};
|
1648
|
-
const
|
1649
|
-
|
2227
|
+
const transformData = (data) => {
|
2228
|
+
if (Array.isArray(data)) {
|
2229
|
+
return data.map(transformData);
|
2230
|
+
}
|
2231
|
+
if (typeof data === "object" && data !== null) {
|
2232
|
+
if ("apiData" in data) {
|
2233
|
+
return data.apiData;
|
2234
|
+
}
|
2235
|
+
return mapValues(transformData)(data);
|
2236
|
+
}
|
2237
|
+
return data;
|
2238
|
+
};
|
2239
|
+
const PublishAction$1 = ({
|
2240
|
+
activeTab,
|
1650
2241
|
documentId,
|
1651
2242
|
model,
|
1652
2243
|
collectionType,
|
@@ -1657,12 +2248,11 @@ const PublishAction$1 = ({
|
|
1657
2248
|
const navigate = useNavigate();
|
1658
2249
|
const { toggleNotification } = useNotification();
|
1659
2250
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
2251
|
+
const isListView = useMatch(LIST_PATH) !== null;
|
1660
2252
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2253
|
+
const { id } = useParams();
|
1661
2254
|
const { formatMessage } = useIntl();
|
1662
|
-
const { canPublish
|
1663
|
-
"PublishAction",
|
1664
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1665
|
-
);
|
2255
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1666
2256
|
const { publish } = useDocumentActions();
|
1667
2257
|
const [
|
1668
2258
|
countDraftRelations,
|
@@ -1714,24 +2304,25 @@ const PublishAction$1 = ({
|
|
1714
2304
|
}
|
1715
2305
|
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1716
2306
|
React.useEffect(() => {
|
1717
|
-
if (documentId) {
|
1718
|
-
|
1719
|
-
const { data, error } = await countDraftRelations({
|
1720
|
-
collectionType,
|
1721
|
-
model,
|
1722
|
-
documentId,
|
1723
|
-
params
|
1724
|
-
});
|
1725
|
-
if (error) {
|
1726
|
-
throw error;
|
1727
|
-
}
|
1728
|
-
if (data) {
|
1729
|
-
setServerCountOfDraftRelations(data.data);
|
1730
|
-
}
|
1731
|
-
};
|
1732
|
-
fetchDraftRelationsCount();
|
2307
|
+
if (!document || !document.documentId || isListView) {
|
2308
|
+
return;
|
1733
2309
|
}
|
1734
|
-
|
2310
|
+
const fetchDraftRelationsCount = async () => {
|
2311
|
+
const { data, error } = await countDraftRelations({
|
2312
|
+
collectionType,
|
2313
|
+
model,
|
2314
|
+
documentId,
|
2315
|
+
params
|
2316
|
+
});
|
2317
|
+
if (error) {
|
2318
|
+
throw error;
|
2319
|
+
}
|
2320
|
+
if (data) {
|
2321
|
+
setServerCountOfDraftRelations(data.data);
|
2322
|
+
}
|
2323
|
+
};
|
2324
|
+
fetchDraftRelationsCount();
|
2325
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
1735
2326
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1736
2327
|
if (!schema?.options?.draftAndPublish) {
|
1737
2328
|
return null;
|
@@ -1739,7 +2330,9 @@ const PublishAction$1 = ({
|
|
1739
2330
|
const performPublish = async () => {
|
1740
2331
|
setSubmitting(true);
|
1741
2332
|
try {
|
1742
|
-
const { errors } = await validate(
|
2333
|
+
const { errors } = await validate(true, {
|
2334
|
+
status: "published"
|
2335
|
+
});
|
1743
2336
|
if (errors) {
|
1744
2337
|
toggleNotification({
|
1745
2338
|
type: "danger",
|
@@ -1757,13 +2350,15 @@ const PublishAction$1 = ({
|
|
1757
2350
|
documentId,
|
1758
2351
|
params
|
1759
2352
|
},
|
1760
|
-
formValues
|
2353
|
+
transformData(formValues)
|
1761
2354
|
);
|
1762
2355
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1763
|
-
|
1764
|
-
|
1765
|
-
|
1766
|
-
|
2356
|
+
if (id === "create") {
|
2357
|
+
navigate({
|
2358
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2359
|
+
search: rawQuery
|
2360
|
+
});
|
2361
|
+
}
|
1767
2362
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1768
2363
|
setErrors(formatValidationErrors(res.error));
|
1769
2364
|
}
|
@@ -1772,7 +2367,8 @@ const PublishAction$1 = ({
|
|
1772
2367
|
}
|
1773
2368
|
};
|
1774
2369
|
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1775
|
-
const
|
2370
|
+
const enableDraftRelationsCount = false;
|
2371
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1776
2372
|
return {
|
1777
2373
|
/**
|
1778
2374
|
* Disabled when:
|
@@ -1782,18 +2378,13 @@ const PublishAction$1 = ({
|
|
1782
2378
|
* - the document is already published & not modified
|
1783
2379
|
* - the document is being created & not modified
|
1784
2380
|
* - the user doesn't have the permission to publish
|
1785
|
-
* - the user doesn't have the permission to create a new document
|
1786
|
-
* - the user doesn't have the permission to update the document
|
1787
2381
|
*/
|
1788
|
-
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
2382
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1789
2383
|
label: formatMessage({
|
1790
2384
|
id: "app.utils.publish",
|
1791
2385
|
defaultMessage: "Publish"
|
1792
2386
|
}),
|
1793
2387
|
onClick: async () => {
|
1794
|
-
if (hasDraftRelations) {
|
1795
|
-
return;
|
1796
|
-
}
|
1797
2388
|
await performPublish();
|
1798
2389
|
},
|
1799
2390
|
dialog: hasDraftRelations ? {
|
@@ -1820,6 +2411,7 @@ const PublishAction$1 = ({
|
|
1820
2411
|
};
|
1821
2412
|
};
|
1822
2413
|
PublishAction$1.type = "publish";
|
2414
|
+
PublishAction$1.position = "panel";
|
1823
2415
|
const UpdateAction = ({
|
1824
2416
|
activeTab,
|
1825
2417
|
documentId,
|
@@ -1832,10 +2424,6 @@ const UpdateAction = ({
|
|
1832
2424
|
const cloneMatch = useMatch(CLONE_PATH);
|
1833
2425
|
const isCloning = cloneMatch !== null;
|
1834
2426
|
const { formatMessage } = useIntl();
|
1835
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1836
|
-
canCreate: canCreate2,
|
1837
|
-
canUpdate: canUpdate2
|
1838
|
-
}));
|
1839
2427
|
const { create, update, clone } = useDocumentActions();
|
1840
2428
|
const [{ query, rawQuery }] = useQueryParams();
|
1841
2429
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
@@ -1846,96 +2434,134 @@ const UpdateAction = ({
|
|
1846
2434
|
const validate = useForm("UpdateAction", (state) => state.validate);
|
1847
2435
|
const setErrors = useForm("UpdateAction", (state) => state.setErrors);
|
1848
2436
|
const resetForm = useForm("PublishAction", ({ resetForm: resetForm2 }) => resetForm2);
|
1849
|
-
|
1850
|
-
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
1859
|
-
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1866
|
-
|
1867
|
-
|
1868
|
-
|
1869
|
-
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
}
|
1875
|
-
|
1876
|
-
|
1877
|
-
if (
|
1878
|
-
|
1879
|
-
{
|
1880
|
-
model,
|
1881
|
-
documentId: cloneMatch.params.origin,
|
1882
|
-
params
|
1883
|
-
},
|
1884
|
-
document
|
1885
|
-
);
|
1886
|
-
if ("data" in res) {
|
1887
|
-
navigate(
|
1888
|
-
{
|
1889
|
-
pathname: `../${res.data.documentId}`,
|
1890
|
-
search: rawQuery
|
1891
|
-
},
|
1892
|
-
{ relative: "path" }
|
1893
|
-
);
|
1894
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1895
|
-
setErrors(formatValidationErrors(res.error));
|
1896
|
-
}
|
1897
|
-
} else if (documentId || collectionType === SINGLE_TYPES) {
|
1898
|
-
const res = await update(
|
2437
|
+
const handleUpdate = React.useCallback(async () => {
|
2438
|
+
setSubmitting(true);
|
2439
|
+
try {
|
2440
|
+
if (!modified) {
|
2441
|
+
return;
|
2442
|
+
}
|
2443
|
+
const { errors } = await validate(true, {
|
2444
|
+
status: "draft"
|
2445
|
+
});
|
2446
|
+
if (errors) {
|
2447
|
+
toggleNotification({
|
2448
|
+
type: "danger",
|
2449
|
+
message: formatMessage({
|
2450
|
+
id: "content-manager.validation.error",
|
2451
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2452
|
+
})
|
2453
|
+
});
|
2454
|
+
return;
|
2455
|
+
}
|
2456
|
+
if (isCloning) {
|
2457
|
+
const res = await clone(
|
2458
|
+
{
|
2459
|
+
model,
|
2460
|
+
documentId: cloneMatch.params.origin,
|
2461
|
+
params
|
2462
|
+
},
|
2463
|
+
transformData(document)
|
2464
|
+
);
|
2465
|
+
if ("data" in res) {
|
2466
|
+
navigate(
|
1899
2467
|
{
|
1900
|
-
|
1901
|
-
|
1902
|
-
documentId,
|
1903
|
-
params
|
2468
|
+
pathname: `../${res.data.documentId}`,
|
2469
|
+
search: rawQuery
|
1904
2470
|
},
|
1905
|
-
|
2471
|
+
{ relative: "path" }
|
1906
2472
|
);
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
2473
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2474
|
+
setErrors(formatValidationErrors(res.error));
|
2475
|
+
}
|
2476
|
+
} else if (documentId || collectionType === SINGLE_TYPES) {
|
2477
|
+
const res = await update(
|
2478
|
+
{
|
2479
|
+
collectionType,
|
2480
|
+
model,
|
2481
|
+
documentId,
|
2482
|
+
params
|
2483
|
+
},
|
2484
|
+
transformData(document)
|
2485
|
+
);
|
2486
|
+
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2487
|
+
setErrors(formatValidationErrors(res.error));
|
1912
2488
|
} else {
|
1913
|
-
|
2489
|
+
resetForm();
|
2490
|
+
}
|
2491
|
+
} else {
|
2492
|
+
const res = await create(
|
2493
|
+
{
|
2494
|
+
model,
|
2495
|
+
params
|
2496
|
+
},
|
2497
|
+
transformData(document)
|
2498
|
+
);
|
2499
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2500
|
+
navigate(
|
1914
2501
|
{
|
1915
|
-
|
1916
|
-
|
2502
|
+
pathname: `../${res.data.documentId}`,
|
2503
|
+
search: rawQuery
|
1917
2504
|
},
|
1918
|
-
|
2505
|
+
{ replace: true, relative: "path" }
|
1919
2506
|
);
|
1920
|
-
|
1921
|
-
|
1922
|
-
{
|
1923
|
-
pathname: `../${res.data.documentId}`,
|
1924
|
-
search: rawQuery
|
1925
|
-
},
|
1926
|
-
{ replace: true, relative: "path" }
|
1927
|
-
);
|
1928
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1929
|
-
setErrors(formatValidationErrors(res.error));
|
1930
|
-
}
|
2507
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2508
|
+
setErrors(formatValidationErrors(res.error));
|
1931
2509
|
}
|
1932
|
-
} finally {
|
1933
|
-
setSubmitting(false);
|
1934
2510
|
}
|
2511
|
+
} finally {
|
2512
|
+
setSubmitting(false);
|
1935
2513
|
}
|
2514
|
+
}, [
|
2515
|
+
clone,
|
2516
|
+
cloneMatch?.params.origin,
|
2517
|
+
collectionType,
|
2518
|
+
create,
|
2519
|
+
document,
|
2520
|
+
documentId,
|
2521
|
+
formatMessage,
|
2522
|
+
formatValidationErrors,
|
2523
|
+
isCloning,
|
2524
|
+
model,
|
2525
|
+
modified,
|
2526
|
+
navigate,
|
2527
|
+
params,
|
2528
|
+
rawQuery,
|
2529
|
+
resetForm,
|
2530
|
+
setErrors,
|
2531
|
+
setSubmitting,
|
2532
|
+
toggleNotification,
|
2533
|
+
update,
|
2534
|
+
validate
|
2535
|
+
]);
|
2536
|
+
React.useEffect(() => {
|
2537
|
+
const handleKeyDown = (e) => {
|
2538
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
2539
|
+
e.preventDefault();
|
2540
|
+
handleUpdate();
|
2541
|
+
}
|
2542
|
+
};
|
2543
|
+
window.addEventListener("keydown", handleKeyDown);
|
2544
|
+
return () => {
|
2545
|
+
window.removeEventListener("keydown", handleKeyDown);
|
2546
|
+
};
|
2547
|
+
}, [handleUpdate]);
|
2548
|
+
return {
|
2549
|
+
/**
|
2550
|
+
* Disabled when:
|
2551
|
+
* - the form is submitting
|
2552
|
+
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
2553
|
+
* - the active tab is the published tab
|
2554
|
+
*/
|
2555
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
2556
|
+
label: formatMessage({
|
2557
|
+
id: "global.save",
|
2558
|
+
defaultMessage: "Save"
|
2559
|
+
}),
|
2560
|
+
onClick: handleUpdate
|
1936
2561
|
};
|
1937
2562
|
};
|
1938
2563
|
UpdateAction.type = "update";
|
2564
|
+
UpdateAction.position = "panel";
|
1939
2565
|
const UNPUBLISH_DRAFT_OPTIONS = {
|
1940
2566
|
KEEP: "keep",
|
1941
2567
|
DISCARD: "discard"
|
@@ -1968,7 +2594,7 @@ const UnpublishAction$1 = ({
|
|
1968
2594
|
id: "app.utils.unpublish",
|
1969
2595
|
defaultMessage: "Unpublish"
|
1970
2596
|
}),
|
1971
|
-
icon: /* @__PURE__ */ jsx(
|
2597
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1972
2598
|
onClick: async () => {
|
1973
2599
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1974
2600
|
if (!documentId) {
|
@@ -2058,6 +2684,7 @@ const UnpublishAction$1 = ({
|
|
2058
2684
|
};
|
2059
2685
|
};
|
2060
2686
|
UnpublishAction$1.type = "unpublish";
|
2687
|
+
UnpublishAction$1.position = "panel";
|
2061
2688
|
const DiscardAction = ({
|
2062
2689
|
activeTab,
|
2063
2690
|
documentId,
|
@@ -2080,7 +2707,7 @@ const DiscardAction = ({
|
|
2080
2707
|
id: "content-manager.actions.discard.label",
|
2081
2708
|
defaultMessage: "Discard changes"
|
2082
2709
|
}),
|
2083
|
-
icon: /* @__PURE__ */ jsx(
|
2710
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
2084
2711
|
position: ["panel", "table-row"],
|
2085
2712
|
variant: "danger",
|
2086
2713
|
dialog: {
|
@@ -2108,11 +2735,7 @@ const DiscardAction = ({
|
|
2108
2735
|
};
|
2109
2736
|
};
|
2110
2737
|
DiscardAction.type = "discard";
|
2111
|
-
|
2112
|
-
path {
|
2113
|
-
fill: currentColor;
|
2114
|
-
}
|
2115
|
-
`;
|
2738
|
+
DiscardAction.position = "panel";
|
2116
2739
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2117
2740
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2118
2741
|
const RelativeTime = React.forwardRef(
|
@@ -2125,7 +2748,7 @@ const RelativeTime = React.forwardRef(
|
|
2125
2748
|
});
|
2126
2749
|
const unit = intervals.find((intervalUnit) => {
|
2127
2750
|
return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
|
2128
|
-
});
|
2751
|
+
}) ?? "seconds";
|
2129
2752
|
const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
|
2130
2753
|
const customInterval = customIntervals.find(
|
2131
2754
|
(custom) => interval[custom.unit] < custom.threshold
|
@@ -2159,19 +2782,29 @@ const getDisplayName = ({
|
|
2159
2782
|
return email ?? "";
|
2160
2783
|
};
|
2161
2784
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2162
|
-
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2163
|
-
const statusVariant = status === "draft" ? "
|
2164
|
-
|
2785
|
+
const DocumentStatus = ({ status = "draft", size = "S", ...restProps }) => {
|
2786
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2787
|
+
const { formatMessage } = useIntl();
|
2788
|
+
return /* @__PURE__ */ jsx(Status, { ...restProps, size, variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: formatMessage({
|
2789
|
+
id: `content-manager.containers.List.${status}`,
|
2790
|
+
defaultMessage: capitalise(status)
|
2791
|
+
}) }) });
|
2165
2792
|
};
|
2166
2793
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2167
2794
|
const { formatMessage } = useIntl();
|
2168
2795
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2796
|
+
const params = useParams();
|
2169
2797
|
const title = isCreating ? formatMessage({
|
2170
2798
|
id: "content-manager.containers.edit.title.new",
|
2171
2799
|
defaultMessage: "Create an entry"
|
2172
2800
|
}) : documentTitle;
|
2173
2801
|
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2174
|
-
/* @__PURE__ */ jsx(
|
2802
|
+
/* @__PURE__ */ jsx(
|
2803
|
+
BackButton,
|
2804
|
+
{
|
2805
|
+
fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
|
2806
|
+
}
|
2807
|
+
),
|
2175
2808
|
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2176
2809
|
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2177
2810
|
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
@@ -2222,7 +2855,7 @@ const HeaderToolbar = () => {
|
|
2222
2855
|
meta: isCloning ? void 0 : meta,
|
2223
2856
|
collectionType
|
2224
2857
|
},
|
2225
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2858
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("header"),
|
2226
2859
|
children: (actions2) => {
|
2227
2860
|
const headerActions = actions2.filter((action) => {
|
2228
2861
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -2259,12 +2892,12 @@ const Information = ({ activeTab }) => {
|
|
2259
2892
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2260
2893
|
label: formatMessage({
|
2261
2894
|
id: "content-manager.containers.edit.information.last-published.label",
|
2262
|
-
defaultMessage: "
|
2895
|
+
defaultMessage: "Published"
|
2263
2896
|
}),
|
2264
2897
|
value: formatMessage(
|
2265
2898
|
{
|
2266
2899
|
id: "content-manager.containers.edit.information.last-published.value",
|
2267
|
-
defaultMessage: `
|
2900
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2268
2901
|
},
|
2269
2902
|
{
|
2270
2903
|
time: /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2277,12 +2910,12 @@ const Information = ({ activeTab }) => {
|
|
2277
2910
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2278
2911
|
label: formatMessage({
|
2279
2912
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2280
|
-
defaultMessage: "
|
2913
|
+
defaultMessage: "Updated"
|
2281
2914
|
}),
|
2282
2915
|
value: formatMessage(
|
2283
2916
|
{
|
2284
2917
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2285
|
-
defaultMessage: `
|
2918
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2286
2919
|
},
|
2287
2920
|
{
|
2288
2921
|
time: /* @__PURE__ */ jsx(
|
@@ -2300,12 +2933,12 @@ const Information = ({ activeTab }) => {
|
|
2300
2933
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2301
2934
|
label: formatMessage({
|
2302
2935
|
id: "content-manager.containers.edit.information.document.label",
|
2303
|
-
defaultMessage: "
|
2936
|
+
defaultMessage: "Created"
|
2304
2937
|
}),
|
2305
2938
|
value: formatMessage(
|
2306
2939
|
{
|
2307
2940
|
id: "content-manager.containers.edit.information.document.value",
|
2308
|
-
defaultMessage: `
|
2941
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2309
2942
|
},
|
2310
2943
|
{
|
2311
2944
|
time: /* @__PURE__ */ jsx(
|
@@ -2343,25 +2976,77 @@ const Information = ({ activeTab }) => {
|
|
2343
2976
|
);
|
2344
2977
|
};
|
2345
2978
|
const HeaderActions = ({ actions: actions2 }) => {
|
2346
|
-
|
2347
|
-
|
2979
|
+
const [dialogId, setDialogId] = React.useState(null);
|
2980
|
+
const handleClick = (action) => async (e) => {
|
2981
|
+
if (!("options" in action)) {
|
2982
|
+
const { onClick = () => false, dialog, id } = action;
|
2983
|
+
const muteDialog = await onClick(e);
|
2984
|
+
if (dialog && !muteDialog) {
|
2985
|
+
e.preventDefault();
|
2986
|
+
setDialogId(id);
|
2987
|
+
}
|
2988
|
+
}
|
2989
|
+
};
|
2990
|
+
const handleClose = () => {
|
2991
|
+
setDialogId(null);
|
2992
|
+
};
|
2993
|
+
return /* @__PURE__ */ jsx(Flex, { gap: 1, children: actions2.map((action) => {
|
2994
|
+
if (action.options) {
|
2348
2995
|
return /* @__PURE__ */ jsx(
|
2349
2996
|
SingleSelect,
|
2350
2997
|
{
|
2351
2998
|
size: "S",
|
2352
|
-
disabled: action.disabled,
|
2353
|
-
"aria-label": action.label,
|
2354
2999
|
onChange: action.onSelect,
|
2355
|
-
|
3000
|
+
"aria-label": action.label,
|
3001
|
+
...action,
|
2356
3002
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
|
2357
3003
|
},
|
2358
3004
|
action.id
|
2359
3005
|
);
|
2360
3006
|
} else {
|
2361
|
-
|
3007
|
+
if (action.type === "icon") {
|
3008
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
3009
|
+
/* @__PURE__ */ jsx(
|
3010
|
+
IconButton,
|
3011
|
+
{
|
3012
|
+
disabled: action.disabled,
|
3013
|
+
label: action.label,
|
3014
|
+
size: "S",
|
3015
|
+
onClick: handleClick(action),
|
3016
|
+
children: action.icon
|
3017
|
+
}
|
3018
|
+
),
|
3019
|
+
action.dialog ? /* @__PURE__ */ jsx(
|
3020
|
+
HeaderActionDialog,
|
3021
|
+
{
|
3022
|
+
...action.dialog,
|
3023
|
+
isOpen: dialogId === action.id,
|
3024
|
+
onClose: handleClose
|
3025
|
+
}
|
3026
|
+
) : null
|
3027
|
+
] }, action.id);
|
3028
|
+
}
|
2362
3029
|
}
|
2363
3030
|
}) });
|
2364
3031
|
};
|
3032
|
+
const HeaderActionDialog = ({
|
3033
|
+
onClose,
|
3034
|
+
onCancel,
|
3035
|
+
title,
|
3036
|
+
content: Content,
|
3037
|
+
isOpen
|
3038
|
+
}) => {
|
3039
|
+
const handleClose = async () => {
|
3040
|
+
if (onCancel) {
|
3041
|
+
await onCancel();
|
3042
|
+
}
|
3043
|
+
onClose();
|
3044
|
+
};
|
3045
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
3046
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
3047
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content
|
3048
|
+
] }) });
|
3049
|
+
};
|
2365
3050
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2366
3051
|
const navigate = useNavigate();
|
2367
3052
|
const { formatMessage } = useIntl();
|
@@ -2378,6 +3063,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2378
3063
|
};
|
2379
3064
|
};
|
2380
3065
|
ConfigureTheViewAction.type = "configure-the-view";
|
3066
|
+
ConfigureTheViewAction.position = "header";
|
2381
3067
|
const EditTheModelAction = ({ model }) => {
|
2382
3068
|
const navigate = useNavigate();
|
2383
3069
|
const { formatMessage } = useIntl();
|
@@ -2394,6 +3080,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2394
3080
|
};
|
2395
3081
|
};
|
2396
3082
|
EditTheModelAction.type = "edit-the-model";
|
3083
|
+
EditTheModelAction.position = "header";
|
2397
3084
|
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2398
3085
|
const navigate = useNavigate();
|
2399
3086
|
const { formatMessage } = useIntl();
|
@@ -2402,12 +3089,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2402
3089
|
const { delete: deleteAction } = useDocumentActions();
|
2403
3090
|
const { toggleNotification } = useNotification();
|
2404
3091
|
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
3092
|
+
const isLocalized = document?.locale != null;
|
2405
3093
|
return {
|
2406
3094
|
disabled: !canDelete || !document,
|
2407
|
-
label: formatMessage(
|
2408
|
-
|
2409
|
-
|
2410
|
-
|
3095
|
+
label: formatMessage(
|
3096
|
+
{
|
3097
|
+
id: "content-manager.actions.delete.label",
|
3098
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
3099
|
+
},
|
3100
|
+
{ isLocalized }
|
3101
|
+
),
|
2411
3102
|
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2412
3103
|
dialog: {
|
2413
3104
|
type: "dialog",
|
@@ -2463,6 +3154,7 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2463
3154
|
};
|
2464
3155
|
};
|
2465
3156
|
DeleteAction$1.type = "delete";
|
3157
|
+
DeleteAction$1.position = ["header", "table-row"];
|
2466
3158
|
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2467
3159
|
const Panels = () => {
|
2468
3160
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
@@ -2477,389 +3169,87 @@ const Panels = () => {
|
|
2477
3169
|
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
2478
3170
|
const props = {
|
2479
3171
|
activeTab: status,
|
2480
|
-
model,
|
2481
|
-
documentId: id,
|
2482
|
-
document: isCloning ? void 0 : document,
|
2483
|
-
meta: isCloning ? void 0 : meta,
|
2484
|
-
collectionType
|
2485
|
-
};
|
2486
|
-
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
2487
|
-
DescriptionComponentRenderer,
|
2488
|
-
{
|
2489
|
-
props,
|
2490
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2491
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
2492
|
-
}
|
2493
|
-
) });
|
2494
|
-
};
|
2495
|
-
const ActionsPanel = () => {
|
2496
|
-
const { formatMessage } = useIntl();
|
2497
|
-
return {
|
2498
|
-
title: formatMessage({
|
2499
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2500
|
-
defaultMessage: "Document"
|
2501
|
-
}),
|
2502
|
-
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2503
|
-
};
|
2504
|
-
};
|
2505
|
-
ActionsPanel.type = "actions";
|
2506
|
-
const ActionsPanelContent = () => {
|
2507
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2508
|
-
const [
|
2509
|
-
{
|
2510
|
-
query: { status = "draft" }
|
2511
|
-
}
|
2512
|
-
] = useQueryParams();
|
2513
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2514
|
-
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2515
|
-
const props = {
|
2516
|
-
activeTab: status,
|
2517
|
-
model,
|
2518
|
-
documentId: id,
|
2519
|
-
document: isCloning ? void 0 : document,
|
2520
|
-
meta: isCloning ? void 0 : meta,
|
2521
|
-
collectionType
|
2522
|
-
};
|
2523
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2524
|
-
/* @__PURE__ */ jsx(
|
2525
|
-
DescriptionComponentRenderer,
|
2526
|
-
{
|
2527
|
-
props,
|
2528
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2529
|
-
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
2530
|
-
}
|
2531
|
-
),
|
2532
|
-
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2533
|
-
] });
|
2534
|
-
};
|
2535
|
-
const Panel = React.forwardRef(({ children, title }, ref) => {
|
2536
|
-
return /* @__PURE__ */ jsxs(
|
2537
|
-
Flex,
|
2538
|
-
{
|
2539
|
-
ref,
|
2540
|
-
tag: "aside",
|
2541
|
-
"aria-labelledby": "additional-information",
|
2542
|
-
background: "neutral0",
|
2543
|
-
borderColor: "neutral150",
|
2544
|
-
hasRadius: true,
|
2545
|
-
paddingBottom: 4,
|
2546
|
-
paddingLeft: 4,
|
2547
|
-
paddingRight: 4,
|
2548
|
-
paddingTop: 4,
|
2549
|
-
shadow: "tableShadow",
|
2550
|
-
gap: 3,
|
2551
|
-
direction: "column",
|
2552
|
-
justifyContent: "stretch",
|
2553
|
-
alignItems: "flex-start",
|
2554
|
-
children: [
|
2555
|
-
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2556
|
-
children
|
2557
|
-
]
|
2558
|
-
}
|
2559
|
-
);
|
2560
|
-
});
|
2561
|
-
const HOOKS = {
|
2562
|
-
/**
|
2563
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2564
|
-
* @constant
|
2565
|
-
* @type {string}
|
2566
|
-
*/
|
2567
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2568
|
-
/**
|
2569
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2570
|
-
* @constant
|
2571
|
-
* @type {string}
|
2572
|
-
*/
|
2573
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2574
|
-
/**
|
2575
|
-
* Hook that allows to mutate the CM's edit view layout
|
2576
|
-
* @constant
|
2577
|
-
* @type {string}
|
2578
|
-
*/
|
2579
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2580
|
-
/**
|
2581
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2582
|
-
* @constant
|
2583
|
-
* @type {string}
|
2584
|
-
*/
|
2585
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2586
|
-
};
|
2587
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2588
|
-
endpoints: (builder) => ({
|
2589
|
-
getContentTypeConfiguration: builder.query({
|
2590
|
-
query: (uid) => ({
|
2591
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2592
|
-
method: "GET"
|
2593
|
-
}),
|
2594
|
-
transformResponse: (response) => response.data,
|
2595
|
-
providesTags: (_result, _error, uid) => [
|
2596
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2597
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2598
|
-
]
|
2599
|
-
}),
|
2600
|
-
getAllContentTypeSettings: builder.query({
|
2601
|
-
query: () => "/content-manager/content-types-settings",
|
2602
|
-
transformResponse: (response) => response.data,
|
2603
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2604
|
-
}),
|
2605
|
-
updateContentTypeConfiguration: builder.mutation({
|
2606
|
-
query: ({ uid, ...body }) => ({
|
2607
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2608
|
-
method: "PUT",
|
2609
|
-
data: body
|
2610
|
-
}),
|
2611
|
-
transformResponse: (response) => response.data,
|
2612
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2613
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2614
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2615
|
-
// Is this necessary?
|
2616
|
-
{ type: "InitialData" }
|
2617
|
-
]
|
2618
|
-
})
|
2619
|
-
})
|
2620
|
-
});
|
2621
|
-
const {
|
2622
|
-
useGetContentTypeConfigurationQuery,
|
2623
|
-
useGetAllContentTypeSettingsQuery,
|
2624
|
-
useUpdateContentTypeConfigurationMutation
|
2625
|
-
} = contentTypesApi;
|
2626
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2627
|
-
const { type } = attribute;
|
2628
|
-
if (type === "relation") {
|
2629
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2630
|
-
}
|
2631
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2632
|
-
};
|
2633
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2634
|
-
if (!mainFieldName) {
|
2635
|
-
return void 0;
|
2636
|
-
}
|
2637
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2638
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2639
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2640
|
-
);
|
2641
|
-
return {
|
2642
|
-
name: mainFieldName,
|
2643
|
-
type: mainFieldType ?? "string"
|
2644
|
-
};
|
2645
|
-
};
|
2646
|
-
const DEFAULT_SETTINGS = {
|
2647
|
-
bulkable: false,
|
2648
|
-
filterable: false,
|
2649
|
-
searchable: false,
|
2650
|
-
pagination: false,
|
2651
|
-
defaultSortBy: "",
|
2652
|
-
defaultSortOrder: "asc",
|
2653
|
-
mainField: "id",
|
2654
|
-
pageSize: 10
|
2655
|
-
};
|
2656
|
-
const useDocumentLayout = (model) => {
|
2657
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2658
|
-
const [{ query }] = useQueryParams();
|
2659
|
-
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2660
|
-
const { toggleNotification } = useNotification();
|
2661
|
-
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
2662
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2663
|
-
const {
|
2664
|
-
data,
|
2665
|
-
isLoading: isLoadingConfigs,
|
2666
|
-
error,
|
2667
|
-
isFetching: isFetchingConfigs
|
2668
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2669
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2670
|
-
React.useEffect(() => {
|
2671
|
-
if (error) {
|
2672
|
-
toggleNotification({
|
2673
|
-
type: "danger",
|
2674
|
-
message: formatAPIError(error)
|
2675
|
-
});
|
2676
|
-
}
|
2677
|
-
}, [error, formatAPIError, toggleNotification]);
|
2678
|
-
const editLayout = React.useMemo(
|
2679
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2680
|
-
layout: [],
|
2681
|
-
components: {},
|
2682
|
-
metadatas: {},
|
2683
|
-
options: {},
|
2684
|
-
settings: DEFAULT_SETTINGS
|
2685
|
-
},
|
2686
|
-
[data, isLoading, schemas, schema, components]
|
2687
|
-
);
|
2688
|
-
const listLayout = React.useMemo(() => {
|
2689
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2690
|
-
layout: [],
|
2691
|
-
metadatas: {},
|
2692
|
-
options: {},
|
2693
|
-
settings: DEFAULT_SETTINGS
|
2694
|
-
};
|
2695
|
-
}, [data, isLoading, schemas, schema, components]);
|
2696
|
-
const { layout: edit } = React.useMemo(
|
2697
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2698
|
-
layout: editLayout,
|
2699
|
-
query
|
2700
|
-
}),
|
2701
|
-
[editLayout, query, runHookWaterfall]
|
2702
|
-
);
|
2703
|
-
return {
|
2704
|
-
error,
|
2705
|
-
isLoading,
|
2706
|
-
edit,
|
2707
|
-
list: listLayout
|
2708
|
-
};
|
2709
|
-
};
|
2710
|
-
const useDocLayout = () => {
|
2711
|
-
const { model } = useDoc();
|
2712
|
-
return useDocumentLayout(model);
|
2713
|
-
};
|
2714
|
-
const formatEditLayout = (data, {
|
2715
|
-
schemas,
|
2716
|
-
schema,
|
2717
|
-
components
|
2718
|
-
}) => {
|
2719
|
-
let currentPanelIndex = 0;
|
2720
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2721
|
-
data.contentType.layouts.edit,
|
2722
|
-
schema?.attributes,
|
2723
|
-
data.contentType.metadatas,
|
2724
|
-
{ configurations: data.components, schemas: components },
|
2725
|
-
schemas
|
2726
|
-
).reduce((panels, row) => {
|
2727
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2728
|
-
panels.push([row]);
|
2729
|
-
currentPanelIndex += 2;
|
2730
|
-
} else {
|
2731
|
-
if (!panels[currentPanelIndex]) {
|
2732
|
-
panels.push([]);
|
2733
|
-
}
|
2734
|
-
panels[currentPanelIndex].push(row);
|
2735
|
-
}
|
2736
|
-
return panels;
|
2737
|
-
}, []);
|
2738
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2739
|
-
(acc, [uid, configuration]) => {
|
2740
|
-
acc[uid] = {
|
2741
|
-
layout: convertEditLayoutToFieldLayouts(
|
2742
|
-
configuration.layouts.edit,
|
2743
|
-
components[uid].attributes,
|
2744
|
-
configuration.metadatas
|
2745
|
-
),
|
2746
|
-
settings: {
|
2747
|
-
...configuration.settings,
|
2748
|
-
icon: components[uid].info.icon,
|
2749
|
-
displayName: components[uid].info.displayName
|
2750
|
-
}
|
2751
|
-
};
|
2752
|
-
return acc;
|
2753
|
-
},
|
2754
|
-
{}
|
2755
|
-
);
|
2756
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2757
|
-
(acc, [attribute, metadata]) => {
|
2758
|
-
return {
|
2759
|
-
...acc,
|
2760
|
-
[attribute]: metadata.edit
|
2761
|
-
};
|
2762
|
-
},
|
2763
|
-
{}
|
2764
|
-
);
|
2765
|
-
return {
|
2766
|
-
layout: panelledEditAttributes,
|
2767
|
-
components: componentEditAttributes,
|
2768
|
-
metadatas: editMetadatas,
|
2769
|
-
settings: {
|
2770
|
-
...data.contentType.settings,
|
2771
|
-
displayName: schema?.info.displayName
|
2772
|
-
},
|
2773
|
-
options: {
|
2774
|
-
...schema?.options,
|
2775
|
-
...schema?.pluginOptions,
|
2776
|
-
...data.contentType.options
|
2777
|
-
}
|
3172
|
+
model,
|
3173
|
+
documentId: id,
|
3174
|
+
document: isCloning ? void 0 : document,
|
3175
|
+
meta: isCloning ? void 0 : meta,
|
3176
|
+
collectionType
|
2778
3177
|
};
|
3178
|
+
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
3179
|
+
DescriptionComponentRenderer,
|
3180
|
+
{
|
3181
|
+
props,
|
3182
|
+
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
3183
|
+
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
3184
|
+
}
|
3185
|
+
) });
|
2779
3186
|
};
|
2780
|
-
const
|
2781
|
-
|
2782
|
-
(row) => row.map((field) => {
|
2783
|
-
const attribute = attributes[field.name];
|
2784
|
-
if (!attribute) {
|
2785
|
-
return null;
|
2786
|
-
}
|
2787
|
-
const { edit: metadata } = metadatas[field.name];
|
2788
|
-
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2789
|
-
return {
|
2790
|
-
attribute,
|
2791
|
-
disabled: !metadata.editable,
|
2792
|
-
hint: metadata.description,
|
2793
|
-
label: metadata.label ?? "",
|
2794
|
-
name: field.name,
|
2795
|
-
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
2796
|
-
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2797
|
-
schemas,
|
2798
|
-
components: components?.schemas ?? {}
|
2799
|
-
}),
|
2800
|
-
placeholder: metadata.placeholder ?? "",
|
2801
|
-
required: attribute.required ?? false,
|
2802
|
-
size: field.size,
|
2803
|
-
unique: "unique" in attribute ? attribute.unique : false,
|
2804
|
-
visible: metadata.visible ?? true,
|
2805
|
-
type: attribute.type
|
2806
|
-
};
|
2807
|
-
}).filter((field) => field !== null)
|
2808
|
-
);
|
2809
|
-
};
|
2810
|
-
const formatListLayout = (data, {
|
2811
|
-
schemas,
|
2812
|
-
schema,
|
2813
|
-
components
|
2814
|
-
}) => {
|
2815
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2816
|
-
(acc, [attribute, metadata]) => {
|
2817
|
-
return {
|
2818
|
-
...acc,
|
2819
|
-
[attribute]: metadata.list
|
2820
|
-
};
|
2821
|
-
},
|
2822
|
-
{}
|
2823
|
-
);
|
2824
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2825
|
-
data.contentType.layouts.list,
|
2826
|
-
schema?.attributes,
|
2827
|
-
listMetadatas,
|
2828
|
-
{ configurations: data.components, schemas: components },
|
2829
|
-
schemas
|
2830
|
-
);
|
3187
|
+
const ActionsPanel = () => {
|
3188
|
+
const { formatMessage } = useIntl();
|
2831
3189
|
return {
|
2832
|
-
|
2833
|
-
|
2834
|
-
|
2835
|
-
|
2836
|
-
|
2837
|
-
...schema?.pluginOptions,
|
2838
|
-
...data.contentType.options
|
2839
|
-
}
|
3190
|
+
title: formatMessage({
|
3191
|
+
id: "content-manager.containers.edit.panels.default.title",
|
3192
|
+
defaultMessage: "Entry"
|
3193
|
+
}),
|
3194
|
+
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2840
3195
|
};
|
2841
3196
|
};
|
2842
|
-
|
2843
|
-
|
2844
|
-
|
2845
|
-
|
2846
|
-
|
3197
|
+
ActionsPanel.type = "actions";
|
3198
|
+
const ActionsPanelContent = () => {
|
3199
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
3200
|
+
const [
|
3201
|
+
{
|
3202
|
+
query: { status = "draft" }
|
2847
3203
|
}
|
2848
|
-
|
2849
|
-
|
2850
|
-
|
2851
|
-
|
2852
|
-
|
2853
|
-
|
2854
|
-
|
2855
|
-
|
2856
|
-
|
2857
|
-
|
2858
|
-
|
2859
|
-
|
2860
|
-
|
2861
|
-
|
3204
|
+
] = useQueryParams();
|
3205
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
3206
|
+
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
3207
|
+
const props = {
|
3208
|
+
activeTab: status,
|
3209
|
+
model,
|
3210
|
+
documentId: id,
|
3211
|
+
document: isCloning ? void 0 : document,
|
3212
|
+
meta: isCloning ? void 0 : meta,
|
3213
|
+
collectionType
|
3214
|
+
};
|
3215
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
3216
|
+
/* @__PURE__ */ jsx(
|
3217
|
+
DescriptionComponentRenderer,
|
3218
|
+
{
|
3219
|
+
props,
|
3220
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("panel"),
|
3221
|
+
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
3222
|
+
}
|
3223
|
+
),
|
3224
|
+
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
3225
|
+
] });
|
2862
3226
|
};
|
3227
|
+
const Panel = React.forwardRef(({ children, title }, ref) => {
|
3228
|
+
return /* @__PURE__ */ jsxs(
|
3229
|
+
Flex,
|
3230
|
+
{
|
3231
|
+
ref,
|
3232
|
+
tag: "aside",
|
3233
|
+
"aria-labelledby": "additional-information",
|
3234
|
+
background: "neutral0",
|
3235
|
+
borderColor: "neutral150",
|
3236
|
+
hasRadius: true,
|
3237
|
+
paddingBottom: 4,
|
3238
|
+
paddingLeft: 4,
|
3239
|
+
paddingRight: 4,
|
3240
|
+
paddingTop: 4,
|
3241
|
+
shadow: "tableShadow",
|
3242
|
+
gap: 3,
|
3243
|
+
direction: "column",
|
3244
|
+
justifyContent: "stretch",
|
3245
|
+
alignItems: "flex-start",
|
3246
|
+
children: [
|
3247
|
+
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", textColor: "neutral600", children: title }),
|
3248
|
+
children
|
3249
|
+
]
|
3250
|
+
}
|
3251
|
+
);
|
3252
|
+
});
|
2863
3253
|
const ConfirmBulkActionDialog = ({
|
2864
3254
|
onToggleDialog,
|
2865
3255
|
isOpen = false,
|
@@ -2885,7 +3275,7 @@ const ConfirmBulkActionDialog = ({
|
|
2885
3275
|
] })
|
2886
3276
|
] }) });
|
2887
3277
|
};
|
2888
|
-
const BoldChunk
|
3278
|
+
const BoldChunk = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
|
2889
3279
|
const ConfirmDialogPublishAll = ({
|
2890
3280
|
isOpen,
|
2891
3281
|
onToggleDialog,
|
@@ -2898,6 +3288,7 @@ const ConfirmDialogPublishAll = ({
|
|
2898
3288
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
|
2899
3289
|
const { model, schema } = useDoc();
|
2900
3290
|
const [{ query }] = useQueryParams();
|
3291
|
+
const enableDraftRelationsCount = false;
|
2901
3292
|
const {
|
2902
3293
|
data: countDraftRelations = 0,
|
2903
3294
|
isLoading,
|
@@ -2909,7 +3300,7 @@ const ConfirmDialogPublishAll = ({
|
|
2909
3300
|
locale: query?.plugins?.i18n?.locale
|
2910
3301
|
},
|
2911
3302
|
{
|
2912
|
-
skip:
|
3303
|
+
skip: !enableDraftRelationsCount
|
2913
3304
|
}
|
2914
3305
|
);
|
2915
3306
|
React.useEffect(() => {
|
@@ -2933,7 +3324,7 @@ const ConfirmDialogPublishAll = ({
|
|
2933
3324
|
defaultMessage: "<b>{count} {count, plural, one { relation } other { relations } } out of {entities} { entities, plural, one { entry } other { entries } } {count, plural, one { is } other { are } }</b> not published yet and might lead to unexpected behavior. "
|
2934
3325
|
},
|
2935
3326
|
{
|
2936
|
-
b: BoldChunk
|
3327
|
+
b: BoldChunk,
|
2937
3328
|
count: countDraftRelations,
|
2938
3329
|
entities: selectedEntries.length
|
2939
3330
|
}
|
@@ -2972,6 +3363,16 @@ const ConfirmDialogPublishAll = ({
|
|
2972
3363
|
const TypographyMaxWidth = styled(Typography)`
|
2973
3364
|
max-width: 300px;
|
2974
3365
|
`;
|
3366
|
+
const TableComponent = styled(RawTable)`
|
3367
|
+
width: 100%;
|
3368
|
+
table-layout: fixed;
|
3369
|
+
td:first-child {
|
3370
|
+
border-right: 1px solid ${({ theme }) => theme.colors.neutral150};
|
3371
|
+
}
|
3372
|
+
td:first-of-type {
|
3373
|
+
padding: ${({ theme }) => theme.spaces[4]};
|
3374
|
+
}
|
3375
|
+
`;
|
2975
3376
|
const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
2976
3377
|
const messages = [];
|
2977
3378
|
Object.entries(errors).forEach(([key, value]) => {
|
@@ -3076,7 +3477,7 @@ const SelectedEntriesTableContent = ({
|
|
3076
3477
|
)
|
3077
3478
|
] }),
|
3078
3479
|
/* @__PURE__ */ jsx(Table.Loading, {}),
|
3079
|
-
/* @__PURE__ */ jsx(Table.Body, { children: rowsToDisplay.map((row
|
3480
|
+
/* @__PURE__ */ jsx(Table.Body, { children: rowsToDisplay.map((row) => /* @__PURE__ */ jsxs(Table.Row, { children: [
|
3080
3481
|
/* @__PURE__ */ jsx(Table.CheckboxCell, { id: row.id }),
|
3081
3482
|
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row.id }) }),
|
3082
3483
|
shouldDisplayMainField && /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row[mainField] }) }),
|
@@ -3094,7 +3495,7 @@ const SelectedEntriesTableContent = ({
|
|
3094
3495
|
status: row.status
|
3095
3496
|
}
|
3096
3497
|
) }),
|
3097
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
3498
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
|
3098
3499
|
IconButton,
|
3099
3500
|
{
|
3100
3501
|
tag: Link,
|
@@ -3103,27 +3504,86 @@ const SelectedEntriesTableContent = ({
|
|
3103
3504
|
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3104
3505
|
},
|
3105
3506
|
state: { from: pathname },
|
3106
|
-
label: formatMessage(
|
3107
|
-
|
3108
|
-
|
3109
|
-
|
3110
|
-
{
|
3111
|
-
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3112
|
-
defaultMessage: "item line {number}"
|
3113
|
-
},
|
3114
|
-
{ number: index2 + 1 }
|
3115
|
-
)
|
3116
|
-
}
|
3117
|
-
),
|
3507
|
+
label: formatMessage({
|
3508
|
+
id: "content-manager.bulk-publish.edit",
|
3509
|
+
defaultMessage: "Edit"
|
3510
|
+
}),
|
3118
3511
|
target: "_blank",
|
3119
3512
|
marginLeft: "auto",
|
3120
|
-
|
3513
|
+
variant: "ghost",
|
3514
|
+
children: /* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" })
|
3121
3515
|
}
|
3122
|
-
) })
|
3516
|
+
) }) })
|
3123
3517
|
] }, row.id)) })
|
3124
3518
|
] });
|
3125
3519
|
};
|
3126
|
-
const
|
3520
|
+
const PublicationStatusSummary = ({ count, icon, message }) => {
|
3521
|
+
return /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", flex: 1, gap: 3, children: [
|
3522
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3523
|
+
icon,
|
3524
|
+
/* @__PURE__ */ jsx(Typography, { children: message })
|
3525
|
+
] }),
|
3526
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: count })
|
3527
|
+
] });
|
3528
|
+
};
|
3529
|
+
const PublicationStatusGrid = ({
|
3530
|
+
entriesReadyToPublishCount,
|
3531
|
+
entriesPublishedCount,
|
3532
|
+
entriesModifiedCount,
|
3533
|
+
entriesWithErrorsCount
|
3534
|
+
}) => {
|
3535
|
+
const { formatMessage } = useIntl();
|
3536
|
+
return /* @__PURE__ */ jsx(Box, { hasRadius: true, borderColor: "neutral150", children: /* @__PURE__ */ jsx(TableComponent, { colCount: 2, rowCount: 2, children: /* @__PURE__ */ jsxs(Tbody, { children: [
|
3537
|
+
/* @__PURE__ */ jsxs(Tr, { children: [
|
3538
|
+
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(
|
3539
|
+
PublicationStatusSummary,
|
3540
|
+
{
|
3541
|
+
count: entriesReadyToPublishCount,
|
3542
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
3543
|
+
message: formatMessage({
|
3544
|
+
id: "app.utils.ready-to-publish",
|
3545
|
+
defaultMessage: "Ready to publish"
|
3546
|
+
})
|
3547
|
+
}
|
3548
|
+
) }),
|
3549
|
+
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(
|
3550
|
+
PublicationStatusSummary,
|
3551
|
+
{
|
3552
|
+
count: entriesPublishedCount,
|
3553
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
3554
|
+
message: formatMessage({
|
3555
|
+
id: "app.utils.already-published",
|
3556
|
+
defaultMessage: "Already published"
|
3557
|
+
})
|
3558
|
+
}
|
3559
|
+
) })
|
3560
|
+
] }),
|
3561
|
+
/* @__PURE__ */ jsxs(Tr, { children: [
|
3562
|
+
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(
|
3563
|
+
PublicationStatusSummary,
|
3564
|
+
{
|
3565
|
+
count: entriesModifiedCount,
|
3566
|
+
icon: /* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
|
3567
|
+
message: formatMessage({
|
3568
|
+
id: "content-manager.bulk-publish.modified",
|
3569
|
+
defaultMessage: "Ready to publish changes"
|
3570
|
+
})
|
3571
|
+
}
|
3572
|
+
) }),
|
3573
|
+
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(
|
3574
|
+
PublicationStatusSummary,
|
3575
|
+
{
|
3576
|
+
count: entriesWithErrorsCount,
|
3577
|
+
icon: /* @__PURE__ */ jsx(CrossCircle, { fill: "danger600" }),
|
3578
|
+
message: formatMessage({
|
3579
|
+
id: "content-manager.bulk-publish.waiting-for-action",
|
3580
|
+
defaultMessage: "Waiting for action"
|
3581
|
+
})
|
3582
|
+
}
|
3583
|
+
) })
|
3584
|
+
] })
|
3585
|
+
] }) }) });
|
3586
|
+
};
|
3127
3587
|
const SelectedEntriesModalContent = ({
|
3128
3588
|
listViewSelectedEntries,
|
3129
3589
|
toggleModal,
|
@@ -3156,7 +3616,13 @@ const SelectedEntriesModalContent = ({
|
|
3156
3616
|
);
|
3157
3617
|
const { rows, validationErrors } = React.useMemo(() => {
|
3158
3618
|
if (data.length > 0 && schema) {
|
3159
|
-
const validate = createYupSchema(
|
3619
|
+
const validate = createYupSchema(
|
3620
|
+
schema.attributes,
|
3621
|
+
components,
|
3622
|
+
// Since this is the "Publish" action, the validation
|
3623
|
+
// schema must enforce the rules for published entities
|
3624
|
+
{ status: "published" }
|
3625
|
+
);
|
3160
3626
|
const validationErrors2 = {};
|
3161
3627
|
const rows2 = data.map((entry) => {
|
3162
3628
|
try {
|
@@ -3176,7 +3642,6 @@ const SelectedEntriesModalContent = ({
|
|
3176
3642
|
validationErrors: {}
|
3177
3643
|
};
|
3178
3644
|
}, [components, data, schema]);
|
3179
|
-
const [publishedCount, setPublishedCount] = React.useState(0);
|
3180
3645
|
const [isDialogOpen, setIsDialogOpen] = React.useState(false);
|
3181
3646
|
const { publishMany: bulkPublishAction } = useDocumentActions();
|
3182
3647
|
const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
|
@@ -3188,53 +3653,36 @@ const SelectedEntriesModalContent = ({
|
|
3188
3653
|
const selectedEntriesWithErrorsCount = selectedEntries.filter(
|
3189
3654
|
({ documentId }) => validationErrors[documentId]
|
3190
3655
|
).length;
|
3191
|
-
const
|
3656
|
+
const selectedEntriesPublishedCount = selectedEntries.filter(
|
3192
3657
|
({ status }) => status === "published"
|
3193
3658
|
).length;
|
3194
|
-
const
|
3659
|
+
const selectedEntriesModifiedCount = selectedEntries.filter(
|
3660
|
+
({ status, documentId }) => status === "modified" && !validationErrors[documentId]
|
3661
|
+
).length;
|
3662
|
+
const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublishedCount;
|
3195
3663
|
const toggleDialog = () => setIsDialogOpen((prev) => !prev);
|
3196
3664
|
const handleConfirmBulkPublish = async () => {
|
3197
3665
|
toggleDialog();
|
3198
3666
|
const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
|
3199
3667
|
if (!("error" in res)) {
|
3200
|
-
setPublishedCount(res.count);
|
3201
3668
|
const unpublishedEntries = rows.filter((row) => {
|
3202
3669
|
return !entriesToPublish.includes(row.documentId);
|
3203
3670
|
});
|
3204
3671
|
setListViewSelectedDocuments(unpublishedEntries);
|
3205
3672
|
}
|
3206
3673
|
};
|
3207
|
-
const getFormattedCountMessage = () => {
|
3208
|
-
if (publishedCount) {
|
3209
|
-
return formatMessage(
|
3210
|
-
{
|
3211
|
-
id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
|
3212
|
-
defaultMessage: "<b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} published. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
|
3213
|
-
},
|
3214
|
-
{
|
3215
|
-
publishedCount,
|
3216
|
-
withErrorsCount: selectedEntriesWithErrorsCount,
|
3217
|
-
b: BoldChunk
|
3218
|
-
}
|
3219
|
-
);
|
3220
|
-
}
|
3221
|
-
return formatMessage(
|
3222
|
-
{
|
3223
|
-
id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
|
3224
|
-
defaultMessage: "<b>{alreadyPublishedCount}</b> {alreadyPublishedCount, plural, =0 {entries} one {entry} other {entries}} already published. <b>{readyToPublishCount}</b> {readyToPublishCount, plural, =0 {entries} one {entry} other {entries}} ready to publish. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
|
3225
|
-
},
|
3226
|
-
{
|
3227
|
-
readyToPublishCount: selectedEntriesWithNoErrorsCount,
|
3228
|
-
withErrorsCount: selectedEntriesWithErrorsCount,
|
3229
|
-
alreadyPublishedCount: selectedEntriesPublished,
|
3230
|
-
b: BoldChunk
|
3231
|
-
}
|
3232
|
-
);
|
3233
|
-
};
|
3234
3674
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
3235
3675
|
/* @__PURE__ */ jsxs(Modal.Body, { children: [
|
3236
|
-
/* @__PURE__ */ jsx(
|
3237
|
-
|
3676
|
+
/* @__PURE__ */ jsx(
|
3677
|
+
PublicationStatusGrid,
|
3678
|
+
{
|
3679
|
+
entriesReadyToPublishCount: selectedEntriesWithNoErrorsCount - selectedEntriesModifiedCount,
|
3680
|
+
entriesPublishedCount: selectedEntriesPublishedCount,
|
3681
|
+
entriesModifiedCount: selectedEntriesModifiedCount,
|
3682
|
+
entriesWithErrorsCount: selectedEntriesWithErrorsCount
|
3683
|
+
}
|
3684
|
+
),
|
3685
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 7, children: /* @__PURE__ */ jsx(
|
3238
3686
|
SelectedEntriesTableContent,
|
3239
3687
|
{
|
3240
3688
|
isPublishing: isSubmittingForm,
|
@@ -3255,7 +3703,7 @@ const SelectedEntriesModalContent = ({
|
|
3255
3703
|
Button,
|
3256
3704
|
{
|
3257
3705
|
onClick: toggleDialog,
|
3258
|
-
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount ||
|
3706
|
+
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublishedCount === selectedEntries.length || isLoading,
|
3259
3707
|
loading: isSubmittingForm,
|
3260
3708
|
children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
|
3261
3709
|
}
|
@@ -3281,8 +3729,7 @@ const PublishAction = ({ documents, model }) => {
|
|
3281
3729
|
const refetchList = () => {
|
3282
3730
|
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3283
3731
|
};
|
3284
|
-
if (!showPublishButton)
|
3285
|
-
return null;
|
3732
|
+
if (!showPublishButton) return null;
|
3286
3733
|
return {
|
3287
3734
|
actionType: "publish",
|
3288
3735
|
variant: "tertiary",
|
@@ -3350,8 +3797,7 @@ const DeleteAction = ({ documents, model }) => {
|
|
3350
3797
|
selectRow([]);
|
3351
3798
|
}
|
3352
3799
|
};
|
3353
|
-
if (!hasDeletePermission)
|
3354
|
-
return null;
|
3800
|
+
if (!hasDeletePermission) return null;
|
3355
3801
|
return {
|
3356
3802
|
variant: "danger-light",
|
3357
3803
|
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
@@ -3400,8 +3846,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3400
3846
|
}
|
3401
3847
|
};
|
3402
3848
|
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3403
|
-
if (!showUnpublishButton)
|
3404
|
-
return null;
|
3849
|
+
if (!showUnpublishButton) return null;
|
3405
3850
|
return {
|
3406
3851
|
variant: "tertiary",
|
3407
3852
|
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
@@ -3506,7 +3951,7 @@ const TableActions = ({ document }) => {
|
|
3506
3951
|
DescriptionComponentRenderer,
|
3507
3952
|
{
|
3508
3953
|
props,
|
3509
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3954
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("table-row").filter((action) => action.name !== "PublishAction"),
|
3510
3955
|
children: (actions2) => {
|
3511
3956
|
const tableRowActions = actions2.filter((action) => {
|
3512
3957
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3565,6 +4010,7 @@ const EditAction = ({ documentId }) => {
|
|
3565
4010
|
};
|
3566
4011
|
};
|
3567
4012
|
EditAction.type = "edit";
|
4013
|
+
EditAction.position = "table-row";
|
3568
4014
|
const StyledPencil = styled(Pencil)`
|
3569
4015
|
path {
|
3570
4016
|
fill: currentColor;
|
@@ -3617,7 +4063,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3617
4063
|
}),
|
3618
4064
|
content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3619
4065
|
footer: ({ onClose }) => {
|
3620
|
-
return /* @__PURE__ */ jsxs(
|
4066
|
+
return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3621
4067
|
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3622
4068
|
id: "cancel",
|
3623
4069
|
defaultMessage: "Cancel"
|
@@ -3641,6 +4087,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3641
4087
|
};
|
3642
4088
|
};
|
3643
4089
|
CloneAction.type = "clone";
|
4090
|
+
CloneAction.position = "table-row";
|
3644
4091
|
const StyledDuplicate = styled(Duplicate)`
|
3645
4092
|
path {
|
3646
4093
|
fill: currentColor;
|
@@ -3727,7 +4174,14 @@ class ContentManagerPlugin {
|
|
3727
4174
|
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3728
4175
|
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3729
4176
|
getBulkActions: () => this.bulkActions,
|
3730
|
-
getDocumentActions: () =>
|
4177
|
+
getDocumentActions: (position) => {
|
4178
|
+
if (position) {
|
4179
|
+
return this.documentActions.filter(
|
4180
|
+
(action) => action.position == void 0 || [action.position].flat().includes(position)
|
4181
|
+
);
|
4182
|
+
}
|
4183
|
+
return this.documentActions;
|
4184
|
+
},
|
3731
4185
|
getEditViewSidePanels: () => this.editViewSidePanels,
|
3732
4186
|
getHeaderActions: () => this.headerActions
|
3733
4187
|
}
|
@@ -3737,10 +4191,8 @@ class ContentManagerPlugin {
|
|
3737
4191
|
const getPrintableType = (value) => {
|
3738
4192
|
const nativeType = typeof value;
|
3739
4193
|
if (nativeType === "object") {
|
3740
|
-
if (value === null)
|
3741
|
-
|
3742
|
-
if (Array.isArray(value))
|
3743
|
-
return "array";
|
4194
|
+
if (value === null) return "null";
|
4195
|
+
if (Array.isArray(value)) return "array";
|
3744
4196
|
if (value instanceof Object && value.constructor.name !== "Object") {
|
3745
4197
|
return value.constructor.name;
|
3746
4198
|
}
|
@@ -3751,17 +4203,27 @@ const HistoryAction = ({ model, document }) => {
|
|
3751
4203
|
const { formatMessage } = useIntl();
|
3752
4204
|
const [{ query }] = useQueryParams();
|
3753
4205
|
const navigate = useNavigate();
|
4206
|
+
const { trackUsage } = useTracking();
|
4207
|
+
const { pathname } = useLocation();
|
3754
4208
|
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
3755
4209
|
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3756
4210
|
return null;
|
3757
4211
|
}
|
4212
|
+
const handleOnClick = () => {
|
4213
|
+
const destination = { pathname: "history", search: pluginsQueryParams };
|
4214
|
+
trackUsage("willNavigate", {
|
4215
|
+
from: pathname,
|
4216
|
+
to: `${pathname}/${destination.pathname}`
|
4217
|
+
});
|
4218
|
+
navigate(destination);
|
4219
|
+
};
|
3758
4220
|
return {
|
3759
4221
|
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
3760
4222
|
label: formatMessage({
|
3761
4223
|
id: "content-manager.history.document-action",
|
3762
4224
|
defaultMessage: "Content History"
|
3763
4225
|
}),
|
3764
|
-
onClick:
|
4226
|
+
onClick: handleOnClick,
|
3765
4227
|
disabled: (
|
3766
4228
|
/**
|
3767
4229
|
* The user is creating a new document.
|
@@ -3783,6 +4245,7 @@ const HistoryAction = ({ model, document }) => {
|
|
3783
4245
|
};
|
3784
4246
|
};
|
3785
4247
|
HistoryAction.type = "history";
|
4248
|
+
HistoryAction.position = "header";
|
3786
4249
|
const historyAdmin = {
|
3787
4250
|
bootstrap(app) {
|
3788
4251
|
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
@@ -3829,6 +4292,88 @@ const { setInitialData } = actions;
|
|
3829
4292
|
const reducer = combineReducers({
|
3830
4293
|
app: reducer$1
|
3831
4294
|
});
|
4295
|
+
const previewApi = contentManagerApi.injectEndpoints({
|
4296
|
+
endpoints: (builder) => ({
|
4297
|
+
getPreviewUrl: builder.query({
|
4298
|
+
query({ query, params }) {
|
4299
|
+
return {
|
4300
|
+
url: `/content-manager/preview/url/${params.contentType}`,
|
4301
|
+
method: "GET",
|
4302
|
+
config: {
|
4303
|
+
params: query
|
4304
|
+
}
|
4305
|
+
};
|
4306
|
+
}
|
4307
|
+
})
|
4308
|
+
})
|
4309
|
+
});
|
4310
|
+
const { useGetPreviewUrlQuery } = previewApi;
|
4311
|
+
const ConditionalTooltip = ({ isShown, label, children }) => {
|
4312
|
+
if (isShown) {
|
4313
|
+
return /* @__PURE__ */ jsx(Tooltip, { label, children });
|
4314
|
+
}
|
4315
|
+
return children;
|
4316
|
+
};
|
4317
|
+
const PreviewSidePanel = ({ model, documentId, document }) => {
|
4318
|
+
const { formatMessage } = useIntl();
|
4319
|
+
const { trackUsage } = useTracking();
|
4320
|
+
const { pathname } = useLocation();
|
4321
|
+
const [{ query }] = useQueryParams();
|
4322
|
+
const isModified = useForm("PreviewSidePanel", (state) => state.modified);
|
4323
|
+
const { data, error } = useGetPreviewUrlQuery({
|
4324
|
+
params: {
|
4325
|
+
contentType: model
|
4326
|
+
},
|
4327
|
+
query: {
|
4328
|
+
documentId,
|
4329
|
+
locale: document?.locale,
|
4330
|
+
status: document?.status
|
4331
|
+
}
|
4332
|
+
});
|
4333
|
+
if (!data?.data?.url || error) {
|
4334
|
+
return null;
|
4335
|
+
}
|
4336
|
+
const trackNavigation = () => {
|
4337
|
+
const destinationPathname = pathname.replace(/\/$/, "") + "/preview";
|
4338
|
+
trackUsage("willNavigate", { from: pathname, to: destinationPathname });
|
4339
|
+
};
|
4340
|
+
return {
|
4341
|
+
title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
|
4342
|
+
content: /* @__PURE__ */ jsx(
|
4343
|
+
ConditionalTooltip,
|
4344
|
+
{
|
4345
|
+
label: formatMessage({
|
4346
|
+
id: "content-manager.preview.panel.button-disabled-tooltip",
|
4347
|
+
defaultMessage: "Please save to open the preview"
|
4348
|
+
}),
|
4349
|
+
isShown: isModified,
|
4350
|
+
children: /* @__PURE__ */ jsx(Box, { cursor: "not-allowed", width: "100%", children: /* @__PURE__ */ jsx(
|
4351
|
+
Button,
|
4352
|
+
{
|
4353
|
+
variant: "tertiary",
|
4354
|
+
tag: Link,
|
4355
|
+
to: { pathname: "preview", search: stringify(query, { encode: false }) },
|
4356
|
+
onClick: trackNavigation,
|
4357
|
+
width: "100%",
|
4358
|
+
disabled: isModified,
|
4359
|
+
pointerEvents: isModified ? "none" : void 0,
|
4360
|
+
tabIndex: isModified ? -1 : void 0,
|
4361
|
+
children: formatMessage({
|
4362
|
+
id: "content-manager.preview.panel.button",
|
4363
|
+
defaultMessage: "Open preview"
|
4364
|
+
})
|
4365
|
+
}
|
4366
|
+
) })
|
4367
|
+
}
|
4368
|
+
)
|
4369
|
+
};
|
4370
|
+
};
|
4371
|
+
const previewAdmin = {
|
4372
|
+
bootstrap(app) {
|
4373
|
+
const contentManagerPluginApis = app.getPlugin("content-manager").apis;
|
4374
|
+
contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
|
4375
|
+
}
|
4376
|
+
};
|
3832
4377
|
const index = {
|
3833
4378
|
register(app) {
|
3834
4379
|
const cm = new ContentManagerPlugin();
|
@@ -3848,7 +4393,7 @@ const index = {
|
|
3848
4393
|
app.router.addRoute({
|
3849
4394
|
path: "content-manager/*",
|
3850
4395
|
lazy: async () => {
|
3851
|
-
const { Layout } = await import("./layout-
|
4396
|
+
const { Layout } = await import("./layout-CxDMdJ13.mjs");
|
3852
4397
|
return {
|
3853
4398
|
Component: Layout
|
3854
4399
|
};
|
@@ -3861,11 +4406,14 @@ const index = {
|
|
3861
4406
|
if (typeof historyAdmin.bootstrap === "function") {
|
3862
4407
|
historyAdmin.bootstrap(app);
|
3863
4408
|
}
|
4409
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
4410
|
+
previewAdmin.bootstrap(app);
|
4411
|
+
}
|
3864
4412
|
},
|
3865
4413
|
async registerTrads({ locales }) {
|
3866
4414
|
const importedTrads = await Promise.all(
|
3867
4415
|
locales.map((locale) => {
|
3868
|
-
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-
|
4416
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-D65uIF6Y.mjs"), "./translations/es.json": () => import("./es-D34tqjMw.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr-DBseuRuB.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-BHqhDq4V.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
|
3869
4417
|
return {
|
3870
4418
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3871
4419
|
locale
|
@@ -3882,21 +4430,27 @@ const index = {
|
|
3882
4430
|
}
|
3883
4431
|
};
|
3884
4432
|
export {
|
3885
|
-
|
4433
|
+
useUpdateContentTypeConfigurationMutation as A,
|
3886
4434
|
BulkActionsRenderer as B,
|
3887
4435
|
COLLECTION_TYPES as C,
|
3888
4436
|
DocumentStatus as D,
|
3889
|
-
|
3890
|
-
|
3891
|
-
|
4437
|
+
ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD as E,
|
4438
|
+
extractContentTypeComponents as F,
|
4439
|
+
DEFAULT_SETTINGS as G,
|
3892
4440
|
HOOKS as H,
|
3893
4441
|
InjectionZone as I,
|
3894
|
-
|
3895
|
-
|
4442
|
+
convertEditLayoutToFieldLayouts as J,
|
4443
|
+
removeFieldsThatDontExistOnSchema as K,
|
4444
|
+
prepareTempKeys as L,
|
4445
|
+
useDocument as M,
|
4446
|
+
useGetPreviewUrlQuery as N,
|
4447
|
+
index as O,
|
3896
4448
|
Panels as P,
|
4449
|
+
useContentManagerContext as Q,
|
3897
4450
|
RelativeTime as R,
|
3898
4451
|
SINGLE_TYPES as S,
|
3899
4452
|
TableActions as T,
|
4453
|
+
useDocumentActions as U,
|
3900
4454
|
useGetInitialDataQuery as a,
|
3901
4455
|
useGetAllContentTypeSettingsQuery as b,
|
3902
4456
|
useDoc as c,
|
@@ -3909,19 +4463,19 @@ export {
|
|
3909
4463
|
Header as j,
|
3910
4464
|
PERMISSIONS as k,
|
3911
4465
|
DocumentRBAC as l,
|
3912
|
-
|
3913
|
-
|
3914
|
-
|
3915
|
-
|
3916
|
-
|
3917
|
-
|
4466
|
+
useDocLayout as m,
|
4467
|
+
createDefaultForm as n,
|
4468
|
+
CLONE_PATH as o,
|
4469
|
+
useGetContentTypeConfigurationQuery as p,
|
4470
|
+
CREATOR_FIELDS as q,
|
4471
|
+
getMainField as r,
|
3918
4472
|
setInitialData as s,
|
3919
|
-
|
4473
|
+
transformDocument as t,
|
3920
4474
|
useContentTypeSchema as u,
|
3921
|
-
|
3922
|
-
|
3923
|
-
|
3924
|
-
|
3925
|
-
|
4475
|
+
getDisplayName as v,
|
4476
|
+
checkIfAttributeIsDisplayable as w,
|
4477
|
+
useGetAllDocumentsQuery as x,
|
4478
|
+
convertListLayoutToFieldLayouts as y,
|
4479
|
+
capitalise as z
|
3926
4480
|
};
|
3927
|
-
//# sourceMappingURL=index-
|
4481
|
+
//# sourceMappingURL=index-EH8ZtHd5.mjs.map
|