@strapi/content-manager 0.0.0-experimental.f6c00790e260ea5a9b6b86abac5fea02b05d569c → 0.0.0-experimental.f6f58027a6338ed795382f2d1c8882158b242361
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-CnL10QYC.mjs → ComponentConfigurationPage-D4H-v0et.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-CnL10QYC.mjs.map → ComponentConfigurationPage-D4H-v0et.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-G4EIirP8.js → ComponentConfigurationPage-DdkVGfXC.js} +5 -6
- package/dist/_chunks/{ComponentConfigurationPage-G4EIirP8.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-I2kKh9dx.mjs → EditConfigurationPage-D1nvB7Br.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-I2kKh9dx.mjs.map → EditConfigurationPage-D1nvB7Br.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-B2AA1kVF.js → EditConfigurationPage-LYEvR4fW.js} +5 -6
- package/dist/_chunks/{EditConfigurationPage-B2AA1kVF.js.map → EditConfigurationPage-LYEvR4fW.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-zFjJK0s8.mjs → EditViewPage-Bcnff6Vd.mjs} +32 -55
- package/dist/_chunks/EditViewPage-Bcnff6Vd.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-CHgoNwlc.js → EditViewPage-DqelJ9UK.js} +34 -58
- 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-DPm-KZ1A.js → Form-CnHfBeiB.js} +6 -7
- package/dist/_chunks/Form-CnHfBeiB.js.map +1 -0
- package/dist/_chunks/{Form-CEkENbkF.mjs → Form-CzPCJi3B.mjs} +4 -4
- package/dist/_chunks/Form-CzPCJi3B.mjs.map +1 -0
- package/dist/_chunks/{History-utls71em.mjs → History-CcmSn3Mj.mjs} +71 -104
- package/dist/_chunks/History-CcmSn3Mj.mjs.map +1 -0
- package/dist/_chunks/{History-DXSbTWez.js → History-zArjENzj.js} +81 -115
- package/dist/_chunks/History-zArjENzj.js.map +1 -0
- package/dist/_chunks/{Field-9DePZh-0.js → Input-CDHKQd7o.js} +1304 -1237
- package/dist/_chunks/Input-CDHKQd7o.js.map +1 -0
- package/dist/_chunks/{Field-DPAzUS1M.mjs → Input-aV8SSoTa.mjs} +1288 -1221
- package/dist/_chunks/Input-aV8SSoTa.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-CuMXWWqb.mjs → ListConfigurationPage-BPvzENJJ.mjs} +7 -6
- package/dist/_chunks/ListConfigurationPage-BPvzENJJ.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-D5C7ACZ_.js → ListConfigurationPage-ByZAO_9H.js} +7 -7
- package/dist/_chunks/ListConfigurationPage-ByZAO_9H.js.map +1 -0
- package/dist/_chunks/{ListViewPage-DfuwH1tt.js → ListViewPage-BVKBeQAA.js} +74 -49
- package/dist/_chunks/ListViewPage-BVKBeQAA.js.map +1 -0
- package/dist/_chunks/{ListViewPage-CdKd-PS_.mjs → ListViewPage-HljQVnFH.mjs} +68 -42
- package/dist/_chunks/ListViewPage-HljQVnFH.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-BIxlkWWi.js → NoContentTypePage-BV5zfDxr.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-BIxlkWWi.js.map → NoContentTypePage-BV5zfDxr.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-DkToTT7u.mjs → NoContentTypePage-BfHaSM-K.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-DkToTT7u.mjs.map → NoContentTypePage-BfHaSM-K.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DlWi4BAH.mjs → NoPermissionsPage-D6ze2nQL.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DlWi4BAH.mjs.map → NoPermissionsPage-D6ze2nQL.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-Bu4GWYb-.js → NoPermissionsPage-vdNpc6jb.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-Bu4GWYb-.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-QP5yn9_z.mjs → Relations-B7_hbF0w.mjs} +78 -43
- package/dist/_chunks/Relations-B7_hbF0w.mjs.map +1 -0
- package/dist/_chunks/{Relations-CFjTESWQ.js → Relations-DcoOBejP.js} +78 -44
- package/dist/_chunks/Relations-DcoOBejP.js.map +1 -0
- package/dist/_chunks/{en-BVzUkPxZ.js → en-BR48D_RH.js} +30 -11
- package/dist/_chunks/{en-BVzUkPxZ.js.map → en-BR48D_RH.js.map} +1 -1
- package/dist/_chunks/{en-CPTj6CjC.mjs → en-D65uIF6Y.mjs} +30 -11
- package/dist/_chunks/{en-CPTj6CjC.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-DXiHxy70.js → index-CxLSGwnk.js} +1162 -706
- package/dist/_chunks/index-CxLSGwnk.js.map +1 -0
- package/dist/_chunks/{index-BHfS6_D5.mjs → index-EH8ZtHd5.mjs} +1178 -722
- 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-DX_52HSH.mjs → layout-CxDMdJ13.mjs} +4 -4
- package/dist/_chunks/{layout-DX_52HSH.mjs.map → layout-CxDMdJ13.mjs.map} +1 -1
- package/dist/_chunks/{layout-bE-WUnQ0.js → layout-DSeUTfMv.js} +5 -6
- package/dist/_chunks/{layout-bE-WUnQ0.js.map → layout-DSeUTfMv.js.map} +1 -1
- 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-SCVAL_aJ.mjs → relations-B8_Uu38Q.mjs} +21 -8
- package/dist/_chunks/relations-B8_Uu38Q.mjs.map +1 -0
- package/dist/_chunks/{relations-D706vblp.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/{useDebounce-CtcjDB3L.js → usePrev-B9w_-eYc.js} +1 -14
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +1 -0
- package/dist/_chunks/usePrev-DH6iah0A.mjs +16 -0
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +1 -0
- 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/FormLayout.d.ts +27 -0
- package/dist/admin/src/pages/EditView/components/Header.d.ts +1 -0
- 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 +16 -19
- 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/server/index.js +590 -333
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +591 -333
- 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 +6 -11
- 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/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/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/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 +16 -15
- package/dist/_chunks/EditViewPage-CHgoNwlc.js.map +0 -1
- package/dist/_chunks/EditViewPage-zFjJK0s8.mjs.map +0 -1
- package/dist/_chunks/Field-9DePZh-0.js.map +0 -1
- package/dist/_chunks/Field-DPAzUS1M.mjs.map +0 -1
- package/dist/_chunks/Form-CEkENbkF.mjs.map +0 -1
- package/dist/_chunks/Form-DPm-KZ1A.js.map +0 -1
- package/dist/_chunks/History-DXSbTWez.js.map +0 -1
- package/dist/_chunks/History-utls71em.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-CuMXWWqb.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-D5C7ACZ_.js.map +0 -1
- package/dist/_chunks/ListViewPage-CdKd-PS_.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-DfuwH1tt.js.map +0 -1
- package/dist/_chunks/Relations-CFjTESWQ.js.map +0 -1
- package/dist/_chunks/Relations-QP5yn9_z.mjs.map +0 -1
- package/dist/_chunks/index-BHfS6_D5.mjs.map +0 -1
- package/dist/_chunks/index-DXiHxy70.js.map +0 -1
- package/dist/_chunks/relations-D706vblp.js.map +0 -1
- package/dist/_chunks/relations-SCVAL_aJ.mjs.map +0 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +0 -1
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +0 -29
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +0 -1
- package/strapi-server.js +0 -3
@@ -1,25 +1,34 @@
|
|
1
|
-
import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check,
|
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
9
|
import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
10
|
+
import { styled } from "styled-components";
|
9
11
|
import * as yup from "yup";
|
10
12
|
import { ValidationError } from "yup";
|
13
|
+
import { generateNKeysBetween } from "fractional-indexing";
|
11
14
|
import pipe from "lodash/fp/pipe";
|
12
|
-
import { intervalToDuration, isPast } from "date-fns";
|
13
|
-
import { styled } from "styled-components";
|
14
15
|
import { stringify } from "qs";
|
16
|
+
import { intervalToDuration, isPast } from "date-fns";
|
15
17
|
import { createSlice, combineReducers } from "@reduxjs/toolkit";
|
16
|
-
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
18
|
+
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
17
19
|
const v = glob[path];
|
18
20
|
if (v) {
|
19
21
|
return typeof v === "function" ? v() : Promise.resolve(v);
|
20
22
|
}
|
21
23
|
return new Promise((_, reject) => {
|
22
|
-
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
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",
|
@@ -159,7 +283,8 @@ const contentManagerApi = adminApi.enhanceEndpoints({
|
|
159
283
|
"InitialData",
|
160
284
|
"HistoryVersion",
|
161
285
|
"Relations",
|
162
|
-
"UidAvailability"
|
286
|
+
"UidAvailability",
|
287
|
+
"RecentDocumentList"
|
163
288
|
]
|
164
289
|
});
|
165
290
|
const documentApi = contentManagerApi.injectEndpoints({
|
@@ -177,7 +302,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
177
302
|
if (error) {
|
178
303
|
return [];
|
179
304
|
}
|
180
|
-
return [{ type: "Document", id: `${model}_LIST` }];
|
305
|
+
return [{ type: "Document", id: `${model}_LIST` }, "RecentDocumentList"];
|
181
306
|
}
|
182
307
|
}),
|
183
308
|
cloneDocument: builder.mutation({
|
@@ -191,7 +316,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
191
316
|
}),
|
192
317
|
invalidatesTags: (_result, _error, { model }) => [
|
193
318
|
{ type: "Document", id: `${model}_LIST` },
|
194
|
-
{ type: "UidAvailability", id: model }
|
319
|
+
{ type: "UidAvailability", id: model },
|
320
|
+
"RecentDocumentList"
|
195
321
|
]
|
196
322
|
}),
|
197
323
|
/**
|
@@ -210,8 +336,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
210
336
|
invalidatesTags: (result, _error, { model }) => [
|
211
337
|
{ type: "Document", id: `${model}_LIST` },
|
212
338
|
"Relations",
|
213
|
-
{ type: "UidAvailability", id: model }
|
214
|
-
|
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
|
+
}
|
215
354
|
}),
|
216
355
|
deleteDocument: builder.mutation({
|
217
356
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -222,7 +361,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
222
361
|
}
|
223
362
|
}),
|
224
363
|
invalidatesTags: (_result, _error, { collectionType, model }) => [
|
225
|
-
{ type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model }
|
364
|
+
{ type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model },
|
365
|
+
"RecentDocumentList"
|
226
366
|
]
|
227
367
|
}),
|
228
368
|
deleteManyDocuments: builder.mutation({
|
@@ -234,7 +374,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
234
374
|
params
|
235
375
|
}
|
236
376
|
}),
|
237
|
-
invalidatesTags: (_res, _error, { model }) => [
|
377
|
+
invalidatesTags: (_res, _error, { model }) => [
|
378
|
+
{ type: "Document", id: `${model}_LIST` },
|
379
|
+
"RecentDocumentList"
|
380
|
+
]
|
238
381
|
}),
|
239
382
|
discardDocument: builder.mutation({
|
240
383
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -252,7 +395,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
252
395
|
},
|
253
396
|
{ type: "Document", id: `${model}_LIST` },
|
254
397
|
"Relations",
|
255
|
-
{ type: "UidAvailability", id: model }
|
398
|
+
{ type: "UidAvailability", id: model },
|
399
|
+
"RecentDocumentList"
|
256
400
|
];
|
257
401
|
}
|
258
402
|
}),
|
@@ -265,7 +409,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
265
409
|
url: `/content-manager/collection-types/${model}`,
|
266
410
|
method: "GET",
|
267
411
|
config: {
|
268
|
-
params
|
412
|
+
params: stringify(params, { encode: true })
|
269
413
|
}
|
270
414
|
}),
|
271
415
|
providesTags: (result, _error, arg) => {
|
@@ -347,7 +491,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
347
491
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
348
492
|
},
|
349
493
|
{ type: "Document", id: `${model}_LIST` },
|
350
|
-
"Relations"
|
494
|
+
"Relations",
|
495
|
+
"RecentDocumentList"
|
351
496
|
];
|
352
497
|
}
|
353
498
|
}),
|
@@ -378,7 +523,9 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
378
523
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
379
524
|
},
|
380
525
|
"Relations",
|
381
|
-
{ type: "UidAvailability", id: model }
|
526
|
+
{ type: "UidAvailability", id: model },
|
527
|
+
"RecentDocumentList",
|
528
|
+
"RecentDocumentList"
|
382
529
|
];
|
383
530
|
},
|
384
531
|
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
@@ -408,7 +555,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
408
555
|
{
|
409
556
|
type: "Document",
|
410
557
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
411
|
-
}
|
558
|
+
},
|
559
|
+
"RecentDocumentList"
|
412
560
|
];
|
413
561
|
}
|
414
562
|
}),
|
@@ -421,7 +569,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
421
569
|
params
|
422
570
|
}
|
423
571
|
}),
|
424
|
-
invalidatesTags: (_res, _error, { model, documentIds }) =>
|
572
|
+
invalidatesTags: (_res, _error, { model, documentIds }) => [
|
573
|
+
...documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` })),
|
574
|
+
"RecentDocumentList"
|
575
|
+
]
|
425
576
|
})
|
426
577
|
})
|
427
578
|
});
|
@@ -444,8 +595,7 @@ const {
|
|
444
595
|
useUnpublishManyDocumentsMutation
|
445
596
|
} = documentApi;
|
446
597
|
const buildValidParams = (query) => {
|
447
|
-
if (!query)
|
448
|
-
return query;
|
598
|
+
if (!query) return query;
|
449
599
|
const { plugins: _, ...validQueryParams } = {
|
450
600
|
...query,
|
451
601
|
...Object.values(query?.plugins ?? {}).reduce(
|
@@ -453,14 +603,29 @@ const buildValidParams = (query) => {
|
|
453
603
|
{}
|
454
604
|
)
|
455
605
|
};
|
456
|
-
if ("_q" in validQueryParams) {
|
457
|
-
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
458
|
-
}
|
459
606
|
return validQueryParams;
|
460
607
|
};
|
461
608
|
const isBaseQueryError = (error) => {
|
462
609
|
return error.name !== void 0;
|
463
610
|
};
|
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
|
+
});
|
464
629
|
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
465
630
|
const createModelSchema = (attributes2) => yup.object().shape(
|
466
631
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
@@ -468,6 +633,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
468
633
|
return acc;
|
469
634
|
}
|
470
635
|
const validations = [
|
636
|
+
addNullableValidation,
|
471
637
|
addRequiredValidation,
|
472
638
|
addMinLengthValidation,
|
473
639
|
addMaxLengthValidation,
|
@@ -484,12 +650,12 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
484
650
|
...acc,
|
485
651
|
[name]: transformSchema(
|
486
652
|
yup.array().of(createModelSchema(attributes3).nullable(false))
|
487
|
-
)
|
653
|
+
).test(arrayValidator(attribute, options))
|
488
654
|
};
|
489
655
|
} else {
|
490
656
|
return {
|
491
657
|
...acc,
|
492
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
658
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
493
659
|
};
|
494
660
|
}
|
495
661
|
}
|
@@ -511,7 +677,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
511
677
|
}
|
512
678
|
)
|
513
679
|
)
|
514
|
-
)
|
680
|
+
).test(arrayValidator(attribute, options))
|
515
681
|
};
|
516
682
|
case "relation":
|
517
683
|
return {
|
@@ -523,7 +689,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
523
689
|
} else if (Array.isArray(value)) {
|
524
690
|
return yup.array().of(
|
525
691
|
yup.object().shape({
|
526
|
-
id: yup.
|
692
|
+
id: yup.number().required()
|
527
693
|
})
|
528
694
|
);
|
529
695
|
} else if (typeof value === "object") {
|
@@ -609,17 +775,17 @@ const nullableSchema = (schema) => {
|
|
609
775
|
schema
|
610
776
|
);
|
611
777
|
};
|
778
|
+
const addNullableValidation = () => (schema) => {
|
779
|
+
return nullableSchema(schema);
|
780
|
+
};
|
612
781
|
const addRequiredValidation = (attribute, options) => (schema) => {
|
613
|
-
if (options.status === "draft") {
|
614
|
-
return
|
615
|
-
}
|
616
|
-
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
617
|
-
return schema.min(1, translatedErrors.required);
|
782
|
+
if (options.status === "draft" || !attribute.required) {
|
783
|
+
return schema;
|
618
784
|
}
|
619
|
-
if (attribute.required &&
|
785
|
+
if (attribute.required && "required" in schema) {
|
620
786
|
return schema.required(translatedErrors.required);
|
621
787
|
}
|
622
|
-
return
|
788
|
+
return schema;
|
623
789
|
};
|
624
790
|
const addMinLengthValidation = (attribute, options) => (schema) => {
|
625
791
|
if (options.status === "draft") {
|
@@ -647,31 +813,12 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
647
813
|
return schema;
|
648
814
|
};
|
649
815
|
const addMinValidation = (attribute, options) => (schema) => {
|
650
|
-
if ("
|
816
|
+
if (options.status === "draft") {
|
817
|
+
return schema;
|
818
|
+
}
|
819
|
+
if ("min" in attribute && "min" in schema) {
|
651
820
|
const min = toInteger(attribute.min);
|
652
|
-
if (
|
653
|
-
if (options.status !== "draft" && !attribute.required && "test" in schema && min) {
|
654
|
-
return schema.test(
|
655
|
-
"custom-min",
|
656
|
-
{
|
657
|
-
...translatedErrors.min,
|
658
|
-
values: {
|
659
|
-
min: attribute.min
|
660
|
-
}
|
661
|
-
},
|
662
|
-
(value) => {
|
663
|
-
if (!value) {
|
664
|
-
return true;
|
665
|
-
}
|
666
|
-
if (Array.isArray(value) && value.length === 0) {
|
667
|
-
return true;
|
668
|
-
}
|
669
|
-
return value.length >= min;
|
670
|
-
}
|
671
|
-
);
|
672
|
-
}
|
673
|
-
}
|
674
|
-
if ("min" in schema && min) {
|
821
|
+
if (min) {
|
675
822
|
return schema.min(min, {
|
676
823
|
...translatedErrors.min,
|
677
824
|
values: {
|
@@ -789,19 +936,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
789
936
|
}, {});
|
790
937
|
return componentsByKey;
|
791
938
|
};
|
792
|
-
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);
|
793
1038
|
const { toggleNotification } = useNotification();
|
794
1039
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1040
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
795
1041
|
const {
|
796
|
-
|
797
|
-
isLoading:
|
798
|
-
|
799
|
-
|
800
|
-
} =
|
801
|
-
|
802
|
-
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
803
|
-
});
|
804
|
-
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;
|
805
1048
|
React.useEffect(() => {
|
806
1049
|
if (error) {
|
807
1050
|
toggleNotification({
|
@@ -809,40 +1052,284 @@ const useDocument = (args, opts) => {
|
|
809
1052
|
message: formatAPIError(error)
|
810
1053
|
});
|
811
1054
|
}
|
812
|
-
}, [
|
813
|
-
const
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
(document) => {
|
821
|
-
if (!validationSchema) {
|
822
|
-
throw new Error(
|
823
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
824
|
-
);
|
825
|
-
}
|
826
|
-
try {
|
827
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
828
|
-
return null;
|
829
|
-
} catch (error2) {
|
830
|
-
if (error2 instanceof ValidationError) {
|
831
|
-
return getYupValidationErrors(error2);
|
832
|
-
}
|
833
|
-
throw error2;
|
834
|
-
}
|
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
|
835
1063
|
},
|
836
|
-
[
|
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]
|
837
1080
|
);
|
838
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
839
1081
|
return {
|
840
|
-
|
841
|
-
document: data?.data,
|
842
|
-
meta: data?.meta,
|
1082
|
+
error,
|
843
1083
|
isLoading,
|
844
|
-
|
845
|
-
|
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,
|
1326
|
+
isLoading,
|
1327
|
+
hasError,
|
1328
|
+
schema,
|
1329
|
+
schemas,
|
1330
|
+
validate,
|
1331
|
+
getTitle,
|
1332
|
+
getInitialFormValues
|
846
1333
|
};
|
847
1334
|
};
|
848
1335
|
const useDoc = () => {
|
@@ -855,22 +1342,60 @@ const useDoc = () => {
|
|
855
1342
|
if (!slug) {
|
856
1343
|
throw new Error("Could not find model in url params");
|
857
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;
|
858
1352
|
return {
|
859
1353
|
collectionType,
|
860
1354
|
model: slug,
|
861
|
-
id:
|
862
|
-
...
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
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
|
868
1396
|
};
|
869
1397
|
};
|
870
1398
|
const prefixPluginTranslations = (trad, pluginId) => {
|
871
|
-
if (!pluginId) {
|
872
|
-
throw new TypeError("pluginId can't be empty");
|
873
|
-
}
|
874
1399
|
return Object.keys(trad).reduce((acc, current) => {
|
875
1400
|
acc[`${pluginId}.${current}`] = trad[current];
|
876
1401
|
return acc;
|
@@ -887,6 +1412,7 @@ const useDocumentActions = () => {
|
|
887
1412
|
const { trackUsage } = useTracking();
|
888
1413
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
889
1414
|
const navigate = useNavigate();
|
1415
|
+
const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
890
1416
|
const [deleteDocument] = useDeleteDocumentMutation();
|
891
1417
|
const _delete = React.useCallback(
|
892
1418
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1201,6 +1727,7 @@ const useDocumentActions = () => {
|
|
1201
1727
|
defaultMessage: "Saved document"
|
1202
1728
|
})
|
1203
1729
|
});
|
1730
|
+
setCurrentStep("contentManager.success");
|
1204
1731
|
return res.data;
|
1205
1732
|
} catch (err) {
|
1206
1733
|
toggleNotification({
|
@@ -1302,10 +1829,10 @@ const useDocumentActions = () => {
|
|
1302
1829
|
update
|
1303
1830
|
};
|
1304
1831
|
};
|
1305
|
-
const ProtectedHistoryPage = lazy(
|
1306
|
-
() => import("./History-
|
1832
|
+
const ProtectedHistoryPage = React.lazy(
|
1833
|
+
() => import("./History-CcmSn3Mj.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1307
1834
|
);
|
1308
|
-
const routes$
|
1835
|
+
const routes$2 = [
|
1309
1836
|
{
|
1310
1837
|
path: ":collectionType/:slug/:id/history",
|
1311
1838
|
Component: ProtectedHistoryPage
|
@@ -1315,32 +1842,45 @@ const routes$1 = [
|
|
1315
1842
|
Component: ProtectedHistoryPage
|
1316
1843
|
}
|
1317
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
|
+
];
|
1318
1858
|
const ProtectedEditViewPage = lazy(
|
1319
|
-
() => import("./EditViewPage-
|
1859
|
+
() => import("./EditViewPage-Bcnff6Vd.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1320
1860
|
);
|
1321
1861
|
const ProtectedListViewPage = lazy(
|
1322
|
-
() => import("./ListViewPage-
|
1862
|
+
() => import("./ListViewPage-HljQVnFH.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1323
1863
|
);
|
1324
1864
|
const ProtectedListConfiguration = lazy(
|
1325
|
-
() => import("./ListConfigurationPage-
|
1865
|
+
() => import("./ListConfigurationPage-BPvzENJJ.mjs").then((mod) => ({
|
1326
1866
|
default: mod.ProtectedListConfiguration
|
1327
1867
|
}))
|
1328
1868
|
);
|
1329
1869
|
const ProtectedEditConfigurationPage = lazy(
|
1330
|
-
() => import("./EditConfigurationPage-
|
1870
|
+
() => import("./EditConfigurationPage-D1nvB7Br.mjs").then((mod) => ({
|
1331
1871
|
default: mod.ProtectedEditConfigurationPage
|
1332
1872
|
}))
|
1333
1873
|
);
|
1334
1874
|
const ProtectedComponentConfigurationPage = lazy(
|
1335
|
-
() => import("./ComponentConfigurationPage-
|
1875
|
+
() => import("./ComponentConfigurationPage-D4H-v0et.mjs").then((mod) => ({
|
1336
1876
|
default: mod.ProtectedComponentConfigurationPage
|
1337
1877
|
}))
|
1338
1878
|
);
|
1339
1879
|
const NoPermissions = lazy(
|
1340
|
-
() => import("./NoPermissionsPage-
|
1880
|
+
() => import("./NoPermissionsPage-D6ze2nQL.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1341
1881
|
);
|
1342
1882
|
const NoContentType = lazy(
|
1343
|
-
() => import("./NoContentTypePage-
|
1883
|
+
() => import("./NoContentTypePage-BfHaSM-K.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1344
1884
|
);
|
1345
1885
|
const CollectionTypePages = () => {
|
1346
1886
|
const { collectionType } = useParams();
|
@@ -1352,7 +1892,7 @@ const CollectionTypePages = () => {
|
|
1352
1892
|
const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
|
1353
1893
|
const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
|
1354
1894
|
const LIST_RELATIVE_PATH = ":collectionType/:slug";
|
1355
|
-
const LIST_PATH = `/content-manager
|
1895
|
+
const LIST_PATH = `/content-manager/collection-types/:slug`;
|
1356
1896
|
const routes = [
|
1357
1897
|
{
|
1358
1898
|
path: LIST_RELATIVE_PATH,
|
@@ -1386,6 +1926,7 @@ const routes = [
|
|
1386
1926
|
path: "no-content-types",
|
1387
1927
|
Component: NoContentType
|
1388
1928
|
},
|
1929
|
+
...routes$2,
|
1389
1930
|
...routes$1
|
1390
1931
|
];
|
1391
1932
|
const DocumentActions = ({ actions: actions2 }) => {
|
@@ -1484,6 +2025,11 @@ const DocumentActionButton = (action) => {
|
|
1484
2025
|
) : null
|
1485
2026
|
] });
|
1486
2027
|
};
|
2028
|
+
const MenuItem = styled(Menu.Item)`
|
2029
|
+
&:hover {
|
2030
|
+
background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
|
2031
|
+
}
|
2032
|
+
`;
|
1487
2033
|
const DocumentActionsMenu = ({
|
1488
2034
|
actions: actions2,
|
1489
2035
|
children,
|
@@ -1542,48 +2088,32 @@ const DocumentActionsMenu = ({
|
|
1542
2088
|
/* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1543
2089
|
actions2.map((action) => {
|
1544
2090
|
return /* @__PURE__ */ jsx(
|
1545
|
-
|
2091
|
+
MenuItem,
|
1546
2092
|
{
|
1547
2093
|
disabled: action.disabled,
|
1548
2094
|
onSelect: handleClick(action),
|
1549
2095
|
display: "block",
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1571
|
-
Flex,
|
1572
|
-
{
|
1573
|
-
alignItems: "center",
|
1574
|
-
background: "alternative100",
|
1575
|
-
borderStyle: "solid",
|
1576
|
-
borderColor: "alternative200",
|
1577
|
-
borderWidth: "1px",
|
1578
|
-
height: 5,
|
1579
|
-
paddingLeft: 2,
|
1580
|
-
paddingRight: 2,
|
1581
|
-
hasRadius: true,
|
1582
|
-
color: "alternative600",
|
1583
|
-
children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", fontWeight: "bold", lineHeight: 1, children: formatMessage({ id: "global.new", defaultMessage: "New" }) })
|
1584
|
-
}
|
1585
|
-
)
|
1586
|
-
] })
|
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
|
+
) })
|
1587
2117
|
},
|
1588
2118
|
action.id
|
1589
2119
|
);
|
@@ -1694,6 +2224,18 @@ const DocumentActionModal = ({
|
|
1694
2224
|
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1695
2225
|
] }) });
|
1696
2226
|
};
|
2227
|
+
const transformData = (data) => {
|
2228
|
+
if (Array.isArray(data)) {
|
2229
|
+
return data.map(transformData);
|
2230
|
+
}
|
2231
|
+
if (typeof data === "object" && data !== null) {
|
2232
|
+
if ("apiData" in data) {
|
2233
|
+
return data.apiData;
|
2234
|
+
}
|
2235
|
+
return mapValues(transformData)(data);
|
2236
|
+
}
|
2237
|
+
return data;
|
2238
|
+
};
|
1697
2239
|
const PublishAction$1 = ({
|
1698
2240
|
activeTab,
|
1699
2241
|
documentId,
|
@@ -1708,6 +2250,7 @@ const PublishAction$1 = ({
|
|
1708
2250
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
1709
2251
|
const isListView = useMatch(LIST_PATH) !== null;
|
1710
2252
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2253
|
+
const { id } = useParams();
|
1711
2254
|
const { formatMessage } = useIntl();
|
1712
2255
|
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1713
2256
|
const { publish } = useDocumentActions();
|
@@ -1787,7 +2330,9 @@ const PublishAction$1 = ({
|
|
1787
2330
|
const performPublish = async () => {
|
1788
2331
|
setSubmitting(true);
|
1789
2332
|
try {
|
1790
|
-
const { errors } = await validate(
|
2333
|
+
const { errors } = await validate(true, {
|
2334
|
+
status: "published"
|
2335
|
+
});
|
1791
2336
|
if (errors) {
|
1792
2337
|
toggleNotification({
|
1793
2338
|
type: "danger",
|
@@ -1805,13 +2350,15 @@ const PublishAction$1 = ({
|
|
1805
2350
|
documentId,
|
1806
2351
|
params
|
1807
2352
|
},
|
1808
|
-
formValues
|
2353
|
+
transformData(formValues)
|
1809
2354
|
);
|
1810
2355
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
2356
|
+
if (id === "create") {
|
2357
|
+
navigate({
|
2358
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2359
|
+
search: rawQuery
|
2360
|
+
});
|
2361
|
+
}
|
1815
2362
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1816
2363
|
setErrors(formatValidationErrors(res.error));
|
1817
2364
|
}
|
@@ -1864,6 +2411,7 @@ const PublishAction$1 = ({
|
|
1864
2411
|
};
|
1865
2412
|
};
|
1866
2413
|
PublishAction$1.type = "publish";
|
2414
|
+
PublishAction$1.position = "panel";
|
1867
2415
|
const UpdateAction = ({
|
1868
2416
|
activeTab,
|
1869
2417
|
documentId,
|
@@ -1886,6 +2434,117 @@ const UpdateAction = ({
|
|
1886
2434
|
const validate = useForm("UpdateAction", (state) => state.validate);
|
1887
2435
|
const setErrors = useForm("UpdateAction", (state) => state.setErrors);
|
1888
2436
|
const resetForm = useForm("PublishAction", ({ resetForm: resetForm2 }) => resetForm2);
|
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(
|
2467
|
+
{
|
2468
|
+
pathname: `../${res.data.documentId}`,
|
2469
|
+
search: rawQuery
|
2470
|
+
},
|
2471
|
+
{ relative: "path" }
|
2472
|
+
);
|
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));
|
2488
|
+
} else {
|
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(
|
2501
|
+
{
|
2502
|
+
pathname: `../${res.data.documentId}`,
|
2503
|
+
search: rawQuery
|
2504
|
+
},
|
2505
|
+
{ replace: true, relative: "path" }
|
2506
|
+
);
|
2507
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2508
|
+
setErrors(formatValidationErrors(res.error));
|
2509
|
+
}
|
2510
|
+
}
|
2511
|
+
} finally {
|
2512
|
+
setSubmitting(false);
|
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]);
|
1889
2548
|
return {
|
1890
2549
|
/**
|
1891
2550
|
* Disabled when:
|
@@ -1895,87 +2554,14 @@ const UpdateAction = ({
|
|
1895
2554
|
*/
|
1896
2555
|
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1897
2556
|
label: formatMessage({
|
1898
|
-
id: "
|
2557
|
+
id: "global.save",
|
1899
2558
|
defaultMessage: "Save"
|
1900
2559
|
}),
|
1901
|
-
onClick:
|
1902
|
-
setSubmitting(true);
|
1903
|
-
try {
|
1904
|
-
if (activeTab !== "draft") {
|
1905
|
-
const { errors } = await validate();
|
1906
|
-
if (errors) {
|
1907
|
-
toggleNotification({
|
1908
|
-
type: "danger",
|
1909
|
-
message: formatMessage({
|
1910
|
-
id: "content-manager.validation.error",
|
1911
|
-
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1912
|
-
})
|
1913
|
-
});
|
1914
|
-
return;
|
1915
|
-
}
|
1916
|
-
}
|
1917
|
-
if (isCloning) {
|
1918
|
-
const res = await clone(
|
1919
|
-
{
|
1920
|
-
model,
|
1921
|
-
documentId: cloneMatch.params.origin,
|
1922
|
-
params
|
1923
|
-
},
|
1924
|
-
document
|
1925
|
-
);
|
1926
|
-
if ("data" in res) {
|
1927
|
-
navigate(
|
1928
|
-
{
|
1929
|
-
pathname: `../${res.data.documentId}`,
|
1930
|
-
search: rawQuery
|
1931
|
-
},
|
1932
|
-
{ relative: "path" }
|
1933
|
-
);
|
1934
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1935
|
-
setErrors(formatValidationErrors(res.error));
|
1936
|
-
}
|
1937
|
-
} else if (documentId || collectionType === SINGLE_TYPES) {
|
1938
|
-
const res = await update(
|
1939
|
-
{
|
1940
|
-
collectionType,
|
1941
|
-
model,
|
1942
|
-
documentId,
|
1943
|
-
params
|
1944
|
-
},
|
1945
|
-
document
|
1946
|
-
);
|
1947
|
-
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1948
|
-
setErrors(formatValidationErrors(res.error));
|
1949
|
-
} else {
|
1950
|
-
resetForm();
|
1951
|
-
}
|
1952
|
-
} else {
|
1953
|
-
const res = await create(
|
1954
|
-
{
|
1955
|
-
model,
|
1956
|
-
params
|
1957
|
-
},
|
1958
|
-
document
|
1959
|
-
);
|
1960
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1961
|
-
navigate(
|
1962
|
-
{
|
1963
|
-
pathname: `../${res.data.documentId}`,
|
1964
|
-
search: rawQuery
|
1965
|
-
},
|
1966
|
-
{ replace: true, relative: "path" }
|
1967
|
-
);
|
1968
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1969
|
-
setErrors(formatValidationErrors(res.error));
|
1970
|
-
}
|
1971
|
-
}
|
1972
|
-
} finally {
|
1973
|
-
setSubmitting(false);
|
1974
|
-
}
|
1975
|
-
}
|
2560
|
+
onClick: handleUpdate
|
1976
2561
|
};
|
1977
2562
|
};
|
1978
2563
|
UpdateAction.type = "update";
|
2564
|
+
UpdateAction.position = "panel";
|
1979
2565
|
const UNPUBLISH_DRAFT_OPTIONS = {
|
1980
2566
|
KEEP: "keep",
|
1981
2567
|
DISCARD: "discard"
|
@@ -2098,6 +2684,7 @@ const UnpublishAction$1 = ({
|
|
2098
2684
|
};
|
2099
2685
|
};
|
2100
2686
|
UnpublishAction$1.type = "unpublish";
|
2687
|
+
UnpublishAction$1.position = "panel";
|
2101
2688
|
const DiscardAction = ({
|
2102
2689
|
activeTab,
|
2103
2690
|
documentId,
|
@@ -2148,6 +2735,7 @@ const DiscardAction = ({
|
|
2148
2735
|
};
|
2149
2736
|
};
|
2150
2737
|
DiscardAction.type = "discard";
|
2738
|
+
DiscardAction.position = "panel";
|
2151
2739
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2152
2740
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2153
2741
|
const RelativeTime = React.forwardRef(
|
@@ -2160,7 +2748,7 @@ const RelativeTime = React.forwardRef(
|
|
2160
2748
|
});
|
2161
2749
|
const unit = intervals.find((intervalUnit) => {
|
2162
2750
|
return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
|
2163
|
-
});
|
2751
|
+
}) ?? "seconds";
|
2164
2752
|
const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
|
2165
2753
|
const customInterval = customIntervals.find(
|
2166
2754
|
(custom) => interval[custom.unit] < custom.threshold
|
@@ -2194,19 +2782,29 @@ const getDisplayName = ({
|
|
2194
2782
|
return email ?? "";
|
2195
2783
|
};
|
2196
2784
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2197
|
-
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2785
|
+
const DocumentStatus = ({ status = "draft", size = "S", ...restProps }) => {
|
2198
2786
|
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2199
|
-
|
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
|
+
}) }) });
|
2200
2792
|
};
|
2201
2793
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2202
2794
|
const { formatMessage } = useIntl();
|
2203
2795
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2796
|
+
const params = useParams();
|
2204
2797
|
const title = isCreating ? formatMessage({
|
2205
2798
|
id: "content-manager.containers.edit.title.new",
|
2206
2799
|
defaultMessage: "Create an entry"
|
2207
2800
|
}) : documentTitle;
|
2208
2801
|
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2209
|
-
/* @__PURE__ */ jsx(
|
2802
|
+
/* @__PURE__ */ jsx(
|
2803
|
+
BackButton,
|
2804
|
+
{
|
2805
|
+
fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
|
2806
|
+
}
|
2807
|
+
),
|
2210
2808
|
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2211
2809
|
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2212
2810
|
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
@@ -2257,7 +2855,7 @@ const HeaderToolbar = () => {
|
|
2257
2855
|
meta: isCloning ? void 0 : meta,
|
2258
2856
|
collectionType
|
2259
2857
|
},
|
2260
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2858
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("header"),
|
2261
2859
|
children: (actions2) => {
|
2262
2860
|
const headerActions = actions2.filter((action) => {
|
2263
2861
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -2294,12 +2892,12 @@ const Information = ({ activeTab }) => {
|
|
2294
2892
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2295
2893
|
label: formatMessage({
|
2296
2894
|
id: "content-manager.containers.edit.information.last-published.label",
|
2297
|
-
defaultMessage: "
|
2895
|
+
defaultMessage: "Published"
|
2298
2896
|
}),
|
2299
2897
|
value: formatMessage(
|
2300
2898
|
{
|
2301
2899
|
id: "content-manager.containers.edit.information.last-published.value",
|
2302
|
-
defaultMessage: `
|
2900
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2303
2901
|
},
|
2304
2902
|
{
|
2305
2903
|
time: /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2312,12 +2910,12 @@ const Information = ({ activeTab }) => {
|
|
2312
2910
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2313
2911
|
label: formatMessage({
|
2314
2912
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2315
|
-
defaultMessage: "
|
2913
|
+
defaultMessage: "Updated"
|
2316
2914
|
}),
|
2317
2915
|
value: formatMessage(
|
2318
2916
|
{
|
2319
2917
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2320
|
-
defaultMessage: `
|
2918
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2321
2919
|
},
|
2322
2920
|
{
|
2323
2921
|
time: /* @__PURE__ */ jsx(
|
@@ -2335,12 +2933,12 @@ const Information = ({ activeTab }) => {
|
|
2335
2933
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2336
2934
|
label: formatMessage({
|
2337
2935
|
id: "content-manager.containers.edit.information.document.label",
|
2338
|
-
defaultMessage: "
|
2936
|
+
defaultMessage: "Created"
|
2339
2937
|
}),
|
2340
2938
|
value: formatMessage(
|
2341
2939
|
{
|
2342
2940
|
id: "content-manager.containers.edit.information.document.value",
|
2343
|
-
defaultMessage: `
|
2941
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2344
2942
|
},
|
2345
2943
|
{
|
2346
2944
|
time: /* @__PURE__ */ jsx(
|
@@ -2398,10 +2996,9 @@ const HeaderActions = ({ actions: actions2 }) => {
|
|
2398
2996
|
SingleSelect,
|
2399
2997
|
{
|
2400
2998
|
size: "S",
|
2401
|
-
disabled: action.disabled,
|
2402
|
-
"aria-label": action.label,
|
2403
2999
|
onChange: action.onSelect,
|
2404
|
-
|
3000
|
+
"aria-label": action.label,
|
3001
|
+
...action,
|
2405
3002
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
|
2406
3003
|
},
|
2407
3004
|
action.id
|
@@ -2466,6 +3063,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2466
3063
|
};
|
2467
3064
|
};
|
2468
3065
|
ConfigureTheViewAction.type = "configure-the-view";
|
3066
|
+
ConfigureTheViewAction.position = "header";
|
2469
3067
|
const EditTheModelAction = ({ model }) => {
|
2470
3068
|
const navigate = useNavigate();
|
2471
3069
|
const { formatMessage } = useIntl();
|
@@ -2482,6 +3080,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2482
3080
|
};
|
2483
3081
|
};
|
2484
3082
|
EditTheModelAction.type = "edit-the-model";
|
3083
|
+
EditTheModelAction.position = "header";
|
2485
3084
|
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2486
3085
|
const navigate = useNavigate();
|
2487
3086
|
const { formatMessage } = useIntl();
|
@@ -2490,12 +3089,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2490
3089
|
const { delete: deleteAction } = useDocumentActions();
|
2491
3090
|
const { toggleNotification } = useNotification();
|
2492
3091
|
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
3092
|
+
const isLocalized = document?.locale != null;
|
2493
3093
|
return {
|
2494
3094
|
disabled: !canDelete || !document,
|
2495
|
-
label: formatMessage(
|
2496
|
-
|
2497
|
-
|
2498
|
-
|
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
|
+
),
|
2499
3102
|
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2500
3103
|
dialog: {
|
2501
3104
|
type: "dialog",
|
@@ -2551,6 +3154,7 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2551
3154
|
};
|
2552
3155
|
};
|
2553
3156
|
DeleteAction$1.type = "delete";
|
3157
|
+
DeleteAction$1.position = ["header", "table-row"];
|
2554
3158
|
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2555
3159
|
const Panels = () => {
|
2556
3160
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
@@ -2562,393 +3166,90 @@ const Panels = () => {
|
|
2562
3166
|
status: "draft"
|
2563
3167
|
});
|
2564
3168
|
const { model, id, document, meta, collectionType } = useDoc();
|
2565
|
-
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
2566
|
-
const props = {
|
2567
|
-
activeTab: status,
|
2568
|
-
model,
|
2569
|
-
documentId: id,
|
2570
|
-
document: isCloning ? void 0 : document,
|
2571
|
-
meta: isCloning ? void 0 : meta,
|
2572
|
-
collectionType
|
2573
|
-
};
|
2574
|
-
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
2575
|
-
DescriptionComponentRenderer,
|
2576
|
-
{
|
2577
|
-
props,
|
2578
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2579
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
2580
|
-
}
|
2581
|
-
) });
|
2582
|
-
};
|
2583
|
-
const ActionsPanel = () => {
|
2584
|
-
const { formatMessage } = useIntl();
|
2585
|
-
return {
|
2586
|
-
title: formatMessage({
|
2587
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2588
|
-
defaultMessage: "Entry"
|
2589
|
-
}),
|
2590
|
-
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2591
|
-
};
|
2592
|
-
};
|
2593
|
-
ActionsPanel.type = "actions";
|
2594
|
-
const ActionsPanelContent = () => {
|
2595
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2596
|
-
const [
|
2597
|
-
{
|
2598
|
-
query: { status = "draft" }
|
2599
|
-
}
|
2600
|
-
] = useQueryParams();
|
2601
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2602
|
-
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2603
|
-
const props = {
|
2604
|
-
activeTab: status,
|
2605
|
-
model,
|
2606
|
-
documentId: id,
|
2607
|
-
document: isCloning ? void 0 : document,
|
2608
|
-
meta: isCloning ? void 0 : meta,
|
2609
|
-
collectionType
|
2610
|
-
};
|
2611
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2612
|
-
/* @__PURE__ */ jsx(
|
2613
|
-
DescriptionComponentRenderer,
|
2614
|
-
{
|
2615
|
-
props,
|
2616
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2617
|
-
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
2618
|
-
}
|
2619
|
-
),
|
2620
|
-
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2621
|
-
] });
|
2622
|
-
};
|
2623
|
-
const Panel = React.forwardRef(({ children, title }, ref) => {
|
2624
|
-
return /* @__PURE__ */ jsxs(
|
2625
|
-
Flex,
|
2626
|
-
{
|
2627
|
-
ref,
|
2628
|
-
tag: "aside",
|
2629
|
-
"aria-labelledby": "additional-information",
|
2630
|
-
background: "neutral0",
|
2631
|
-
borderColor: "neutral150",
|
2632
|
-
hasRadius: true,
|
2633
|
-
paddingBottom: 4,
|
2634
|
-
paddingLeft: 4,
|
2635
|
-
paddingRight: 4,
|
2636
|
-
paddingTop: 4,
|
2637
|
-
shadow: "tableShadow",
|
2638
|
-
gap: 3,
|
2639
|
-
direction: "column",
|
2640
|
-
justifyContent: "stretch",
|
2641
|
-
alignItems: "flex-start",
|
2642
|
-
children: [
|
2643
|
-
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2644
|
-
children
|
2645
|
-
]
|
2646
|
-
}
|
2647
|
-
);
|
2648
|
-
});
|
2649
|
-
const HOOKS = {
|
2650
|
-
/**
|
2651
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2652
|
-
* @constant
|
2653
|
-
* @type {string}
|
2654
|
-
*/
|
2655
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2656
|
-
/**
|
2657
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2658
|
-
* @constant
|
2659
|
-
* @type {string}
|
2660
|
-
*/
|
2661
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2662
|
-
/**
|
2663
|
-
* Hook that allows to mutate the CM's edit view layout
|
2664
|
-
* @constant
|
2665
|
-
* @type {string}
|
2666
|
-
*/
|
2667
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2668
|
-
/**
|
2669
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2670
|
-
* @constant
|
2671
|
-
* @type {string}
|
2672
|
-
*/
|
2673
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2674
|
-
};
|
2675
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2676
|
-
endpoints: (builder) => ({
|
2677
|
-
getContentTypeConfiguration: builder.query({
|
2678
|
-
query: (uid) => ({
|
2679
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2680
|
-
method: "GET"
|
2681
|
-
}),
|
2682
|
-
transformResponse: (response) => response.data,
|
2683
|
-
providesTags: (_result, _error, uid) => [
|
2684
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2685
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2686
|
-
]
|
2687
|
-
}),
|
2688
|
-
getAllContentTypeSettings: builder.query({
|
2689
|
-
query: () => "/content-manager/content-types-settings",
|
2690
|
-
transformResponse: (response) => response.data,
|
2691
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2692
|
-
}),
|
2693
|
-
updateContentTypeConfiguration: builder.mutation({
|
2694
|
-
query: ({ uid, ...body }) => ({
|
2695
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2696
|
-
method: "PUT",
|
2697
|
-
data: body
|
2698
|
-
}),
|
2699
|
-
transformResponse: (response) => response.data,
|
2700
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2701
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2702
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2703
|
-
// Is this necessary?
|
2704
|
-
{ type: "InitialData" }
|
2705
|
-
]
|
2706
|
-
})
|
2707
|
-
})
|
2708
|
-
});
|
2709
|
-
const {
|
2710
|
-
useGetContentTypeConfigurationQuery,
|
2711
|
-
useGetAllContentTypeSettingsQuery,
|
2712
|
-
useUpdateContentTypeConfigurationMutation
|
2713
|
-
} = contentTypesApi;
|
2714
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2715
|
-
const { type } = attribute;
|
2716
|
-
if (type === "relation") {
|
2717
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2718
|
-
}
|
2719
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2720
|
-
};
|
2721
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2722
|
-
if (!mainFieldName) {
|
2723
|
-
return void 0;
|
2724
|
-
}
|
2725
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2726
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2727
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2728
|
-
);
|
2729
|
-
return {
|
2730
|
-
name: mainFieldName,
|
2731
|
-
type: mainFieldType ?? "string"
|
2732
|
-
};
|
2733
|
-
};
|
2734
|
-
const DEFAULT_SETTINGS = {
|
2735
|
-
bulkable: false,
|
2736
|
-
filterable: false,
|
2737
|
-
searchable: false,
|
2738
|
-
pagination: false,
|
2739
|
-
defaultSortBy: "",
|
2740
|
-
defaultSortOrder: "asc",
|
2741
|
-
mainField: "id",
|
2742
|
-
pageSize: 10
|
2743
|
-
};
|
2744
|
-
const useDocumentLayout = (model) => {
|
2745
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2746
|
-
const [{ query }] = useQueryParams();
|
2747
|
-
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2748
|
-
const { toggleNotification } = useNotification();
|
2749
|
-
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
2750
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2751
|
-
const {
|
2752
|
-
data,
|
2753
|
-
isLoading: isLoadingConfigs,
|
2754
|
-
error,
|
2755
|
-
isFetching: isFetchingConfigs
|
2756
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2757
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2758
|
-
React.useEffect(() => {
|
2759
|
-
if (error) {
|
2760
|
-
toggleNotification({
|
2761
|
-
type: "danger",
|
2762
|
-
message: formatAPIError(error)
|
2763
|
-
});
|
2764
|
-
}
|
2765
|
-
}, [error, formatAPIError, toggleNotification]);
|
2766
|
-
const editLayout = React.useMemo(
|
2767
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2768
|
-
layout: [],
|
2769
|
-
components: {},
|
2770
|
-
metadatas: {},
|
2771
|
-
options: {},
|
2772
|
-
settings: DEFAULT_SETTINGS
|
2773
|
-
},
|
2774
|
-
[data, isLoading, schemas, schema, components]
|
2775
|
-
);
|
2776
|
-
const listLayout = React.useMemo(() => {
|
2777
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2778
|
-
layout: [],
|
2779
|
-
metadatas: {},
|
2780
|
-
options: {},
|
2781
|
-
settings: DEFAULT_SETTINGS
|
2782
|
-
};
|
2783
|
-
}, [data, isLoading, schemas, schema, components]);
|
2784
|
-
const { layout: edit } = React.useMemo(
|
2785
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2786
|
-
layout: editLayout,
|
2787
|
-
query
|
2788
|
-
}),
|
2789
|
-
[editLayout, query, runHookWaterfall]
|
2790
|
-
);
|
2791
|
-
return {
|
2792
|
-
error,
|
2793
|
-
isLoading,
|
2794
|
-
edit,
|
2795
|
-
list: listLayout
|
2796
|
-
};
|
2797
|
-
};
|
2798
|
-
const useDocLayout = () => {
|
2799
|
-
const { model } = useDoc();
|
2800
|
-
return useDocumentLayout(model);
|
2801
|
-
};
|
2802
|
-
const formatEditLayout = (data, {
|
2803
|
-
schemas,
|
2804
|
-
schema,
|
2805
|
-
components
|
2806
|
-
}) => {
|
2807
|
-
let currentPanelIndex = 0;
|
2808
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2809
|
-
data.contentType.layouts.edit,
|
2810
|
-
schema?.attributes,
|
2811
|
-
data.contentType.metadatas,
|
2812
|
-
{ configurations: data.components, schemas: components },
|
2813
|
-
schemas
|
2814
|
-
).reduce((panels, row) => {
|
2815
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2816
|
-
panels.push([row]);
|
2817
|
-
currentPanelIndex += 2;
|
2818
|
-
} else {
|
2819
|
-
if (!panels[currentPanelIndex]) {
|
2820
|
-
panels.push([]);
|
2821
|
-
}
|
2822
|
-
panels[currentPanelIndex].push(row);
|
2823
|
-
}
|
2824
|
-
return panels;
|
2825
|
-
}, []);
|
2826
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2827
|
-
(acc, [uid, configuration]) => {
|
2828
|
-
acc[uid] = {
|
2829
|
-
layout: convertEditLayoutToFieldLayouts(
|
2830
|
-
configuration.layouts.edit,
|
2831
|
-
components[uid].attributes,
|
2832
|
-
configuration.metadatas,
|
2833
|
-
{ configurations: data.components, schemas: components }
|
2834
|
-
),
|
2835
|
-
settings: {
|
2836
|
-
...configuration.settings,
|
2837
|
-
icon: components[uid].info.icon,
|
2838
|
-
displayName: components[uid].info.displayName
|
2839
|
-
}
|
2840
|
-
};
|
2841
|
-
return acc;
|
2842
|
-
},
|
2843
|
-
{}
|
2844
|
-
);
|
2845
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2846
|
-
(acc, [attribute, metadata]) => {
|
2847
|
-
return {
|
2848
|
-
...acc,
|
2849
|
-
[attribute]: metadata.edit
|
2850
|
-
};
|
2851
|
-
},
|
2852
|
-
{}
|
2853
|
-
);
|
2854
|
-
return {
|
2855
|
-
layout: panelledEditAttributes,
|
2856
|
-
components: componentEditAttributes,
|
2857
|
-
metadatas: editMetadatas,
|
2858
|
-
settings: {
|
2859
|
-
...data.contentType.settings,
|
2860
|
-
displayName: schema?.info.displayName
|
2861
|
-
},
|
2862
|
-
options: {
|
2863
|
-
...schema?.options,
|
2864
|
-
...schema?.pluginOptions,
|
2865
|
-
...data.contentType.options
|
2866
|
-
}
|
3169
|
+
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
3170
|
+
const props = {
|
3171
|
+
activeTab: status,
|
3172
|
+
model,
|
3173
|
+
documentId: id,
|
3174
|
+
document: isCloning ? void 0 : document,
|
3175
|
+
meta: isCloning ? void 0 : meta,
|
3176
|
+
collectionType
|
2867
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
|
+
) });
|
2868
3186
|
};
|
2869
|
-
const
|
2870
|
-
|
2871
|
-
(row) => row.map((field) => {
|
2872
|
-
const attribute = attributes[field.name];
|
2873
|
-
if (!attribute) {
|
2874
|
-
return null;
|
2875
|
-
}
|
2876
|
-
const { edit: metadata } = metadatas[field.name];
|
2877
|
-
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2878
|
-
return {
|
2879
|
-
attribute,
|
2880
|
-
disabled: !metadata.editable,
|
2881
|
-
hint: metadata.description,
|
2882
|
-
label: metadata.label ?? "",
|
2883
|
-
name: field.name,
|
2884
|
-
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
2885
|
-
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2886
|
-
schemas,
|
2887
|
-
components: components?.schemas ?? {}
|
2888
|
-
}),
|
2889
|
-
placeholder: metadata.placeholder ?? "",
|
2890
|
-
required: attribute.required ?? false,
|
2891
|
-
size: field.size,
|
2892
|
-
unique: "unique" in attribute ? attribute.unique : false,
|
2893
|
-
visible: metadata.visible ?? true,
|
2894
|
-
type: attribute.type
|
2895
|
-
};
|
2896
|
-
}).filter((field) => field !== null)
|
2897
|
-
);
|
2898
|
-
};
|
2899
|
-
const formatListLayout = (data, {
|
2900
|
-
schemas,
|
2901
|
-
schema,
|
2902
|
-
components
|
2903
|
-
}) => {
|
2904
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2905
|
-
(acc, [attribute, metadata]) => {
|
2906
|
-
return {
|
2907
|
-
...acc,
|
2908
|
-
[attribute]: metadata.list
|
2909
|
-
};
|
2910
|
-
},
|
2911
|
-
{}
|
2912
|
-
);
|
2913
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2914
|
-
data.contentType.layouts.list,
|
2915
|
-
schema?.attributes,
|
2916
|
-
listMetadatas,
|
2917
|
-
{ configurations: data.components, schemas: components },
|
2918
|
-
schemas
|
2919
|
-
);
|
3187
|
+
const ActionsPanel = () => {
|
3188
|
+
const { formatMessage } = useIntl();
|
2920
3189
|
return {
|
2921
|
-
|
2922
|
-
|
2923
|
-
|
2924
|
-
|
2925
|
-
|
2926
|
-
...schema?.pluginOptions,
|
2927
|
-
...data.contentType.options
|
2928
|
-
}
|
3190
|
+
title: formatMessage({
|
3191
|
+
id: "content-manager.containers.edit.panels.default.title",
|
3192
|
+
defaultMessage: "Entry"
|
3193
|
+
}),
|
3194
|
+
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2929
3195
|
};
|
2930
3196
|
};
|
2931
|
-
|
2932
|
-
|
2933
|
-
|
2934
|
-
|
2935
|
-
|
3197
|
+
ActionsPanel.type = "actions";
|
3198
|
+
const ActionsPanelContent = () => {
|
3199
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
3200
|
+
const [
|
3201
|
+
{
|
3202
|
+
query: { status = "draft" }
|
2936
3203
|
}
|
2937
|
-
|
2938
|
-
|
2939
|
-
|
2940
|
-
|
2941
|
-
|
2942
|
-
|
2943
|
-
|
2944
|
-
|
2945
|
-
|
2946
|
-
|
2947
|
-
|
2948
|
-
|
2949
|
-
|
2950
|
-
|
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
|
+
] });
|
2951
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
|
+
});
|
2952
3253
|
const ConfirmBulkActionDialog = ({
|
2953
3254
|
onToggleDialog,
|
2954
3255
|
isOpen = false,
|
@@ -2974,7 +3275,7 @@ const ConfirmBulkActionDialog = ({
|
|
2974
3275
|
] })
|
2975
3276
|
] }) });
|
2976
3277
|
};
|
2977
|
-
const BoldChunk
|
3278
|
+
const BoldChunk = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
|
2978
3279
|
const ConfirmDialogPublishAll = ({
|
2979
3280
|
isOpen,
|
2980
3281
|
onToggleDialog,
|
@@ -3023,7 +3324,7 @@ const ConfirmDialogPublishAll = ({
|
|
3023
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. "
|
3024
3325
|
},
|
3025
3326
|
{
|
3026
|
-
b: BoldChunk
|
3327
|
+
b: BoldChunk,
|
3027
3328
|
count: countDraftRelations,
|
3028
3329
|
entities: selectedEntries.length
|
3029
3330
|
}
|
@@ -3062,6 +3363,16 @@ const ConfirmDialogPublishAll = ({
|
|
3062
3363
|
const TypographyMaxWidth = styled(Typography)`
|
3063
3364
|
max-width: 300px;
|
3064
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
|
+
`;
|
3065
3376
|
const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
3066
3377
|
const messages = [];
|
3067
3378
|
Object.entries(errors).forEach(([key, value]) => {
|
@@ -3166,7 +3477,7 @@ const SelectedEntriesTableContent = ({
|
|
3166
3477
|
)
|
3167
3478
|
] }),
|
3168
3479
|
/* @__PURE__ */ jsx(Table.Loading, {}),
|
3169
|
-
/* @__PURE__ */ jsx(Table.Body, { children: rowsToDisplay.map((row
|
3480
|
+
/* @__PURE__ */ jsx(Table.Body, { children: rowsToDisplay.map((row) => /* @__PURE__ */ jsxs(Table.Row, { children: [
|
3170
3481
|
/* @__PURE__ */ jsx(Table.CheckboxCell, { id: row.id }),
|
3171
3482
|
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row.id }) }),
|
3172
3483
|
shouldDisplayMainField && /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row[mainField] }) }),
|
@@ -3193,18 +3504,10 @@ const SelectedEntriesTableContent = ({
|
|
3193
3504
|
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3194
3505
|
},
|
3195
3506
|
state: { from: pathname },
|
3196
|
-
label: formatMessage(
|
3197
|
-
|
3198
|
-
|
3199
|
-
|
3200
|
-
{
|
3201
|
-
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3202
|
-
defaultMessage: "item line {number}"
|
3203
|
-
},
|
3204
|
-
{ number: index2 + 1 }
|
3205
|
-
)
|
3206
|
-
}
|
3207
|
-
),
|
3507
|
+
label: formatMessage({
|
3508
|
+
id: "content-manager.bulk-publish.edit",
|
3509
|
+
defaultMessage: "Edit"
|
3510
|
+
}),
|
3208
3511
|
target: "_blank",
|
3209
3512
|
marginLeft: "auto",
|
3210
3513
|
variant: "ghost",
|
@@ -3214,7 +3517,73 @@ const SelectedEntriesTableContent = ({
|
|
3214
3517
|
] }, row.id)) })
|
3215
3518
|
] });
|
3216
3519
|
};
|
3217
|
-
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
|
+
};
|
3218
3587
|
const SelectedEntriesModalContent = ({
|
3219
3588
|
listViewSelectedEntries,
|
3220
3589
|
toggleModal,
|
@@ -3273,7 +3642,6 @@ const SelectedEntriesModalContent = ({
|
|
3273
3642
|
validationErrors: {}
|
3274
3643
|
};
|
3275
3644
|
}, [components, data, schema]);
|
3276
|
-
const [publishedCount, setPublishedCount] = React.useState(0);
|
3277
3645
|
const [isDialogOpen, setIsDialogOpen] = React.useState(false);
|
3278
3646
|
const { publishMany: bulkPublishAction } = useDocumentActions();
|
3279
3647
|
const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
|
@@ -3285,53 +3653,36 @@ const SelectedEntriesModalContent = ({
|
|
3285
3653
|
const selectedEntriesWithErrorsCount = selectedEntries.filter(
|
3286
3654
|
({ documentId }) => validationErrors[documentId]
|
3287
3655
|
).length;
|
3288
|
-
const
|
3656
|
+
const selectedEntriesPublishedCount = selectedEntries.filter(
|
3289
3657
|
({ status }) => status === "published"
|
3290
3658
|
).length;
|
3291
|
-
const
|
3659
|
+
const selectedEntriesModifiedCount = selectedEntries.filter(
|
3660
|
+
({ status, documentId }) => status === "modified" && !validationErrors[documentId]
|
3661
|
+
).length;
|
3662
|
+
const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublishedCount;
|
3292
3663
|
const toggleDialog = () => setIsDialogOpen((prev) => !prev);
|
3293
3664
|
const handleConfirmBulkPublish = async () => {
|
3294
3665
|
toggleDialog();
|
3295
3666
|
const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
|
3296
3667
|
if (!("error" in res)) {
|
3297
|
-
setPublishedCount(res.count);
|
3298
3668
|
const unpublishedEntries = rows.filter((row) => {
|
3299
3669
|
return !entriesToPublish.includes(row.documentId);
|
3300
3670
|
});
|
3301
3671
|
setListViewSelectedDocuments(unpublishedEntries);
|
3302
3672
|
}
|
3303
3673
|
};
|
3304
|
-
const getFormattedCountMessage = () => {
|
3305
|
-
if (publishedCount) {
|
3306
|
-
return formatMessage(
|
3307
|
-
{
|
3308
|
-
id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
|
3309
|
-
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."
|
3310
|
-
},
|
3311
|
-
{
|
3312
|
-
publishedCount,
|
3313
|
-
withErrorsCount: selectedEntriesWithErrorsCount,
|
3314
|
-
b: BoldChunk
|
3315
|
-
}
|
3316
|
-
);
|
3317
|
-
}
|
3318
|
-
return formatMessage(
|
3319
|
-
{
|
3320
|
-
id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
|
3321
|
-
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."
|
3322
|
-
},
|
3323
|
-
{
|
3324
|
-
readyToPublishCount: selectedEntriesWithNoErrorsCount,
|
3325
|
-
withErrorsCount: selectedEntriesWithErrorsCount,
|
3326
|
-
alreadyPublishedCount: selectedEntriesPublished,
|
3327
|
-
b: BoldChunk
|
3328
|
-
}
|
3329
|
-
);
|
3330
|
-
};
|
3331
3674
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
3332
3675
|
/* @__PURE__ */ jsxs(Modal.Body, { children: [
|
3333
|
-
/* @__PURE__ */ jsx(
|
3334
|
-
|
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(
|
3335
3686
|
SelectedEntriesTableContent,
|
3336
3687
|
{
|
3337
3688
|
isPublishing: isSubmittingForm,
|
@@ -3352,7 +3703,7 @@ const SelectedEntriesModalContent = ({
|
|
3352
3703
|
Button,
|
3353
3704
|
{
|
3354
3705
|
onClick: toggleDialog,
|
3355
|
-
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount ||
|
3706
|
+
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublishedCount === selectedEntries.length || isLoading,
|
3356
3707
|
loading: isSubmittingForm,
|
3357
3708
|
children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
|
3358
3709
|
}
|
@@ -3378,8 +3729,7 @@ const PublishAction = ({ documents, model }) => {
|
|
3378
3729
|
const refetchList = () => {
|
3379
3730
|
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3380
3731
|
};
|
3381
|
-
if (!showPublishButton)
|
3382
|
-
return null;
|
3732
|
+
if (!showPublishButton) return null;
|
3383
3733
|
return {
|
3384
3734
|
actionType: "publish",
|
3385
3735
|
variant: "tertiary",
|
@@ -3447,8 +3797,7 @@ const DeleteAction = ({ documents, model }) => {
|
|
3447
3797
|
selectRow([]);
|
3448
3798
|
}
|
3449
3799
|
};
|
3450
|
-
if (!hasDeletePermission)
|
3451
|
-
return null;
|
3800
|
+
if (!hasDeletePermission) return null;
|
3452
3801
|
return {
|
3453
3802
|
variant: "danger-light",
|
3454
3803
|
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
@@ -3497,8 +3846,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3497
3846
|
}
|
3498
3847
|
};
|
3499
3848
|
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3500
|
-
if (!showUnpublishButton)
|
3501
|
-
return null;
|
3849
|
+
if (!showUnpublishButton) return null;
|
3502
3850
|
return {
|
3503
3851
|
variant: "tertiary",
|
3504
3852
|
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
@@ -3603,7 +3951,7 @@ const TableActions = ({ document }) => {
|
|
3603
3951
|
DescriptionComponentRenderer,
|
3604
3952
|
{
|
3605
3953
|
props,
|
3606
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3954
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("table-row").filter((action) => action.name !== "PublishAction"),
|
3607
3955
|
children: (actions2) => {
|
3608
3956
|
const tableRowActions = actions2.filter((action) => {
|
3609
3957
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3662,6 +4010,7 @@ const EditAction = ({ documentId }) => {
|
|
3662
4010
|
};
|
3663
4011
|
};
|
3664
4012
|
EditAction.type = "edit";
|
4013
|
+
EditAction.position = "table-row";
|
3665
4014
|
const StyledPencil = styled(Pencil)`
|
3666
4015
|
path {
|
3667
4016
|
fill: currentColor;
|
@@ -3738,6 +4087,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3738
4087
|
};
|
3739
4088
|
};
|
3740
4089
|
CloneAction.type = "clone";
|
4090
|
+
CloneAction.position = "table-row";
|
3741
4091
|
const StyledDuplicate = styled(Duplicate)`
|
3742
4092
|
path {
|
3743
4093
|
fill: currentColor;
|
@@ -3824,7 +4174,14 @@ class ContentManagerPlugin {
|
|
3824
4174
|
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3825
4175
|
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3826
4176
|
getBulkActions: () => this.bulkActions,
|
3827
|
-
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
|
+
},
|
3828
4185
|
getEditViewSidePanels: () => this.editViewSidePanels,
|
3829
4186
|
getHeaderActions: () => this.headerActions
|
3830
4187
|
}
|
@@ -3834,10 +4191,8 @@ class ContentManagerPlugin {
|
|
3834
4191
|
const getPrintableType = (value) => {
|
3835
4192
|
const nativeType = typeof value;
|
3836
4193
|
if (nativeType === "object") {
|
3837
|
-
if (value === null)
|
3838
|
-
|
3839
|
-
if (Array.isArray(value))
|
3840
|
-
return "array";
|
4194
|
+
if (value === null) return "null";
|
4195
|
+
if (Array.isArray(value)) return "array";
|
3841
4196
|
if (value instanceof Object && value.constructor.name !== "Object") {
|
3842
4197
|
return value.constructor.name;
|
3843
4198
|
}
|
@@ -3848,17 +4203,27 @@ const HistoryAction = ({ model, document }) => {
|
|
3848
4203
|
const { formatMessage } = useIntl();
|
3849
4204
|
const [{ query }] = useQueryParams();
|
3850
4205
|
const navigate = useNavigate();
|
4206
|
+
const { trackUsage } = useTracking();
|
4207
|
+
const { pathname } = useLocation();
|
3851
4208
|
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
3852
4209
|
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3853
4210
|
return null;
|
3854
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
|
+
};
|
3855
4220
|
return {
|
3856
4221
|
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
3857
4222
|
label: formatMessage({
|
3858
4223
|
id: "content-manager.history.document-action",
|
3859
4224
|
defaultMessage: "Content History"
|
3860
4225
|
}),
|
3861
|
-
onClick:
|
4226
|
+
onClick: handleOnClick,
|
3862
4227
|
disabled: (
|
3863
4228
|
/**
|
3864
4229
|
* The user is creating a new document.
|
@@ -3880,6 +4245,7 @@ const HistoryAction = ({ model, document }) => {
|
|
3880
4245
|
};
|
3881
4246
|
};
|
3882
4247
|
HistoryAction.type = "history";
|
4248
|
+
HistoryAction.position = "header";
|
3883
4249
|
const historyAdmin = {
|
3884
4250
|
bootstrap(app) {
|
3885
4251
|
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
@@ -3926,6 +4292,88 @@ const { setInitialData } = actions;
|
|
3926
4292
|
const reducer = combineReducers({
|
3927
4293
|
app: reducer$1
|
3928
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
|
+
};
|
3929
4377
|
const index = {
|
3930
4378
|
register(app) {
|
3931
4379
|
const cm = new ContentManagerPlugin();
|
@@ -3945,7 +4393,7 @@ const index = {
|
|
3945
4393
|
app.router.addRoute({
|
3946
4394
|
path: "content-manager/*",
|
3947
4395
|
lazy: async () => {
|
3948
|
-
const { Layout } = await import("./layout-
|
4396
|
+
const { Layout } = await import("./layout-CxDMdJ13.mjs");
|
3949
4397
|
return {
|
3950
4398
|
Component: Layout
|
3951
4399
|
};
|
@@ -3958,11 +4406,14 @@ const index = {
|
|
3958
4406
|
if (typeof historyAdmin.bootstrap === "function") {
|
3959
4407
|
historyAdmin.bootstrap(app);
|
3960
4408
|
}
|
4409
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
4410
|
+
previewAdmin.bootstrap(app);
|
4411
|
+
}
|
3961
4412
|
},
|
3962
4413
|
async registerTrads({ locales }) {
|
3963
4414
|
const importedTrads = await Promise.all(
|
3964
4415
|
locales.map((locale) => {
|
3965
|
-
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 }) => {
|
3966
4417
|
return {
|
3967
4418
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3968
4419
|
locale
|
@@ -3979,22 +4430,27 @@ const index = {
|
|
3979
4430
|
}
|
3980
4431
|
};
|
3981
4432
|
export {
|
3982
|
-
|
4433
|
+
useUpdateContentTypeConfigurationMutation as A,
|
3983
4434
|
BulkActionsRenderer as B,
|
3984
4435
|
COLLECTION_TYPES as C,
|
3985
4436
|
DocumentStatus as D,
|
3986
|
-
|
3987
|
-
|
3988
|
-
|
4437
|
+
ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD as E,
|
4438
|
+
extractContentTypeComponents as F,
|
4439
|
+
DEFAULT_SETTINGS as G,
|
3989
4440
|
HOOKS as H,
|
3990
4441
|
InjectionZone as I,
|
3991
|
-
|
3992
|
-
|
3993
|
-
|
4442
|
+
convertEditLayoutToFieldLayouts as J,
|
4443
|
+
removeFieldsThatDontExistOnSchema as K,
|
4444
|
+
prepareTempKeys as L,
|
4445
|
+
useDocument as M,
|
4446
|
+
useGetPreviewUrlQuery as N,
|
4447
|
+
index as O,
|
3994
4448
|
Panels as P,
|
4449
|
+
useContentManagerContext as Q,
|
3995
4450
|
RelativeTime as R,
|
3996
4451
|
SINGLE_TYPES as S,
|
3997
4452
|
TableActions as T,
|
4453
|
+
useDocumentActions as U,
|
3998
4454
|
useGetInitialDataQuery as a,
|
3999
4455
|
useGetAllContentTypeSettingsQuery as b,
|
4000
4456
|
useDoc as c,
|
@@ -4007,19 +4463,19 @@ export {
|
|
4007
4463
|
Header as j,
|
4008
4464
|
PERMISSIONS as k,
|
4009
4465
|
DocumentRBAC as l,
|
4010
|
-
|
4011
|
-
|
4012
|
-
|
4466
|
+
useDocLayout as m,
|
4467
|
+
createDefaultForm as n,
|
4468
|
+
CLONE_PATH as o,
|
4013
4469
|
useGetContentTypeConfigurationQuery as p,
|
4014
4470
|
CREATOR_FIELDS as q,
|
4015
4471
|
getMainField as r,
|
4016
4472
|
setInitialData as s,
|
4017
|
-
|
4473
|
+
transformDocument as t,
|
4018
4474
|
useContentTypeSchema as u,
|
4019
|
-
|
4020
|
-
|
4021
|
-
|
4022
|
-
|
4023
|
-
|
4475
|
+
getDisplayName as v,
|
4476
|
+
checkIfAttributeIsDisplayable as w,
|
4477
|
+
useGetAllDocumentsQuery as x,
|
4478
|
+
convertListLayoutToFieldLayouts as y,
|
4479
|
+
capitalise as z
|
4024
4480
|
};
|
4025
|
-
//# sourceMappingURL=index-
|
4481
|
+
//# sourceMappingURL=index-EH8ZtHd5.mjs.map
|