@strapi/content-manager 0.0.0-experimental.afa3b513b8f95459043f33fb94f4bac03af1474f → 0.0.0-experimental.b0240412a007bea5d73c29b17c8ce04802fca919
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-G4EIirP8.js → ComponentConfigurationPage-BLWQy8ru.js} +5 -6
- package/dist/_chunks/{ComponentConfigurationPage-G4EIirP8.js.map → ComponentConfigurationPage-BLWQy8ru.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-CnL10QYC.mjs → ComponentConfigurationPage-CtIa3aa2.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-CnL10QYC.mjs.map → ComponentConfigurationPage-CtIa3aa2.mjs.map} +1 -1
- package/dist/_chunks/{ComponentIcon-BXdiCGQp.js → ComponentIcon-CRbtQEUV.js} +2 -3
- package/dist/_chunks/{ComponentIcon-BXdiCGQp.js.map → ComponentIcon-CRbtQEUV.js.map} +1 -1
- package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -1
- package/dist/_chunks/{EditConfigurationPage-I2kKh9dx.mjs → EditConfigurationPage-DsPR2DVk.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-I2kKh9dx.mjs.map → EditConfigurationPage-DsPR2DVk.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-B2AA1kVF.js → EditConfigurationPage-RQkymxCy.js} +5 -6
- package/dist/_chunks/{EditConfigurationPage-B2AA1kVF.js.map → EditConfigurationPage-RQkymxCy.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-CHgoNwlc.js → EditViewPage-B-kExt8C.js} +50 -11
- package/dist/_chunks/EditViewPage-B-kExt8C.js.map +1 -0
- package/dist/_chunks/{EditViewPage-zFjJK0s8.mjs → EditViewPage-BPyVuPfM.mjs} +50 -10
- package/dist/_chunks/EditViewPage-BPyVuPfM.mjs.map +1 -0
- package/dist/_chunks/{Field-9DePZh-0.js → Field-DPIsQRre.js} +243 -144
- package/dist/_chunks/Field-DPIsQRre.js.map +1 -0
- package/dist/_chunks/{Field-DPAzUS1M.mjs → Field-Dltnt1km.mjs} +241 -142
- package/dist/_chunks/Field-Dltnt1km.mjs.map +1 -0
- package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
- package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
- package/dist/_chunks/{Form-DPm-KZ1A.js → Form-BFi4MXMT.js} +6 -7
- package/dist/_chunks/Form-BFi4MXMT.js.map +1 -0
- package/dist/_chunks/{Form-CEkENbkF.mjs → Form-C1IcWm1u.mjs} +4 -4
- package/dist/_chunks/Form-C1IcWm1u.mjs.map +1 -0
- package/dist/_chunks/{History-utls71em.mjs → History-04ChQ4pl.mjs} +71 -104
- package/dist/_chunks/History-04ChQ4pl.mjs.map +1 -0
- package/dist/_chunks/{History-DXSbTWez.js → History-wjcK4L0C.js} +70 -104
- package/dist/_chunks/History-wjcK4L0C.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-CuMXWWqb.mjs → ListConfigurationPage-BYqPYLSU.mjs} +7 -6
- package/dist/_chunks/ListConfigurationPage-BYqPYLSU.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-D5C7ACZ_.js → ListConfigurationPage-CRbxIC3J.js} +7 -7
- package/dist/_chunks/ListConfigurationPage-CRbxIC3J.js.map +1 -0
- package/dist/_chunks/{ListViewPage-DfuwH1tt.js → ListViewPage-D5NY9183.js} +64 -42
- package/dist/_chunks/ListViewPage-D5NY9183.js.map +1 -0
- package/dist/_chunks/{ListViewPage-CdKd-PS_.mjs → ListViewPage-FU2LBuhl.mjs} +63 -40
- package/dist/_chunks/ListViewPage-FU2LBuhl.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-BIxlkWWi.js → NoContentTypePage-BgQVE_Qb.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-BIxlkWWi.js.map → NoContentTypePage-BgQVE_Qb.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-DkToTT7u.mjs → NoContentTypePage-DCKUkwb8.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-DkToTT7u.mjs.map → NoContentTypePage-DCKUkwb8.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-Bu4GWYb-.js → NoPermissionsPage-C5jwn70o.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-Bu4GWYb-.js.map → NoPermissionsPage-C5jwn70o.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DlWi4BAH.mjs → NoPermissionsPage-jqve7C8l.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DlWi4BAH.mjs.map → NoPermissionsPage-jqve7C8l.mjs.map} +1 -1
- package/dist/_chunks/Preview-BMYN548c.mjs +294 -0
- package/dist/_chunks/Preview-BMYN548c.mjs.map +1 -0
- package/dist/_chunks/Preview-DaOihysv.js +312 -0
- package/dist/_chunks/Preview-DaOihysv.js.map +1 -0
- package/dist/_chunks/{Relations-CFjTESWQ.js → Relations-CTGM7Hv5.js} +75 -42
- package/dist/_chunks/Relations-CTGM7Hv5.js.map +1 -0
- package/dist/_chunks/{Relations-QP5yn9_z.mjs → Relations-gscPkxjF.mjs} +75 -41
- package/dist/_chunks/Relations-gscPkxjF.mjs.map +1 -0
- package/dist/_chunks/{en-BVzUkPxZ.js → en-BzQmavmK.js} +28 -11
- package/dist/_chunks/{en-BVzUkPxZ.js.map → en-BzQmavmK.js.map} +1 -1
- package/dist/_chunks/{en-CPTj6CjC.mjs → en-CSxLmrh1.mjs} +28 -11
- package/dist/_chunks/{en-CPTj6CjC.mjs.map → en-CSxLmrh1.mjs.map} +1 -1
- package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
- package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
- package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
- package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
- package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
- package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
- package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
- package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
- package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
- package/dist/_chunks/{index-DXiHxy70.js → index-Ca7YWlAA.js} +981 -722
- package/dist/_chunks/index-Ca7YWlAA.js.map +1 -0
- package/dist/_chunks/{index-BHfS6_D5.mjs → index-DqasUQ6Q.mjs} +983 -724
- package/dist/_chunks/index-DqasUQ6Q.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-bE-WUnQ0.js → layout-BW80JSCd.js} +5 -6
- package/dist/_chunks/{layout-bE-WUnQ0.js.map → layout-BW80JSCd.js.map} +1 -1
- package/dist/_chunks/{layout-DX_52HSH.mjs → layout-W3clJSCy.mjs} +4 -4
- package/dist/_chunks/{layout-DX_52HSH.mjs.map → layout-W3clJSCy.mjs.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-BlDkoeWh.mjs} +6 -7
- package/dist/_chunks/relations-BlDkoeWh.mjs.map +1 -0
- package/dist/_chunks/{relations-D706vblp.js → relations-C9Usz9k5.js} +6 -7
- package/dist/_chunks/relations-C9Usz9k5.js.map +1 -0
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -1
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -1
- package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
- package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
- package/dist/admin/index.js +3 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +5 -3
- package/dist/admin/src/content-manager.d.ts +3 -2
- package/dist/admin/src/exports.d.ts +2 -1
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +3 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +7 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/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/Header.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 +587 -331
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +588 -331
- 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 +14 -13
- 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
@@ -1,25 +1,33 @@
|
|
1
1
|
import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check, CrossCircle, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
|
2
2
|
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
3
|
-
import { useStrapiApp, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors,
|
3
|
+
import { useStrapiApp, createContext, useQueryParams, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useForm, useTracking, useGuidedTour, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
|
4
4
|
import * as React from "react";
|
5
5
|
import { lazy } from "react";
|
6
|
-
import {
|
6
|
+
import { Menu, Button, VisuallyHidden, Flex, Dialog, Modal, Typography, Radio, Status, Box, SingleSelect, SingleSelectOption, IconButton, Loader, Tooltip, LinkButton } from "@strapi/design-system";
|
7
|
+
import mapValues from "lodash/fp/mapValues";
|
7
8
|
import { useIntl } from "react-intl";
|
8
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 { stringify } from "qs";
|
11
14
|
import pipe from "lodash/fp/pipe";
|
12
15
|
import { intervalToDuration, isPast } from "date-fns";
|
13
|
-
import { styled } from "styled-components";
|
14
|
-
import { stringify } from "qs";
|
15
16
|
import { createSlice, combineReducers } from "@reduxjs/toolkit";
|
16
|
-
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
17
|
+
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
17
18
|
const v = glob[path];
|
18
19
|
if (v) {
|
19
20
|
return typeof v === "function" ? v() : Promise.resolve(v);
|
20
21
|
}
|
21
22
|
return new Promise((_, reject) => {
|
22
|
-
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
23
|
+
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
24
|
+
reject.bind(
|
25
|
+
null,
|
26
|
+
new Error(
|
27
|
+
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
28
|
+
)
|
29
|
+
)
|
30
|
+
);
|
23
31
|
});
|
24
32
|
};
|
25
33
|
const PLUGIN_ID = "content-manager";
|
@@ -100,6 +108,7 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
100
108
|
if (!slug) {
|
101
109
|
throw new Error("Cannot find the slug param in the URL");
|
102
110
|
}
|
111
|
+
const [{ rawQuery }] = useQueryParams();
|
103
112
|
const userPermissions = useAuth("DocumentRBAC", (state) => state.permissions);
|
104
113
|
const contentTypePermissions = React.useMemo(() => {
|
105
114
|
const contentTypePermissions2 = userPermissions.filter(
|
@@ -110,7 +119,14 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
110
119
|
return { ...acc, [action]: [permission] };
|
111
120
|
}, {});
|
112
121
|
}, [slug, userPermissions]);
|
113
|
-
const { isLoading, allowedActions } = useRBAC(
|
122
|
+
const { isLoading, allowedActions } = useRBAC(
|
123
|
+
contentTypePermissions,
|
124
|
+
permissions ?? void 0,
|
125
|
+
// TODO: useRBAC context should be typed and built differently
|
126
|
+
// We are passing raw query as context to the hook so that it can
|
127
|
+
// rely on the locale provided from DocumentRBAC for its permission calculations.
|
128
|
+
rawQuery
|
129
|
+
);
|
114
130
|
const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
|
115
131
|
const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
|
116
132
|
const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
|
@@ -159,7 +175,8 @@ const contentManagerApi = adminApi.enhanceEndpoints({
|
|
159
175
|
"InitialData",
|
160
176
|
"HistoryVersion",
|
161
177
|
"Relations",
|
162
|
-
"UidAvailability"
|
178
|
+
"UidAvailability",
|
179
|
+
"RecentDocumentList"
|
163
180
|
]
|
164
181
|
});
|
165
182
|
const documentApi = contentManagerApi.injectEndpoints({
|
@@ -177,7 +194,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
177
194
|
if (error) {
|
178
195
|
return [];
|
179
196
|
}
|
180
|
-
return [{ type: "Document", id: `${model}_LIST` }];
|
197
|
+
return [{ type: "Document", id: `${model}_LIST` }, "RecentDocumentList"];
|
181
198
|
}
|
182
199
|
}),
|
183
200
|
cloneDocument: builder.mutation({
|
@@ -191,7 +208,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
191
208
|
}),
|
192
209
|
invalidatesTags: (_result, _error, { model }) => [
|
193
210
|
{ type: "Document", id: `${model}_LIST` },
|
194
|
-
{ type: "UidAvailability", id: model }
|
211
|
+
{ type: "UidAvailability", id: model },
|
212
|
+
"RecentDocumentList"
|
195
213
|
]
|
196
214
|
}),
|
197
215
|
/**
|
@@ -210,8 +228,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
210
228
|
invalidatesTags: (result, _error, { model }) => [
|
211
229
|
{ type: "Document", id: `${model}_LIST` },
|
212
230
|
"Relations",
|
213
|
-
{ type: "UidAvailability", id: model }
|
214
|
-
|
231
|
+
{ type: "UidAvailability", id: model },
|
232
|
+
"RecentDocumentList"
|
233
|
+
],
|
234
|
+
transformResponse: (response, meta, arg) => {
|
235
|
+
if (!("data" in response) && arg.model === "plugin::users-permissions.user") {
|
236
|
+
return {
|
237
|
+
data: response,
|
238
|
+
meta: {
|
239
|
+
availableStatus: [],
|
240
|
+
availableLocales: []
|
241
|
+
}
|
242
|
+
};
|
243
|
+
}
|
244
|
+
return response;
|
245
|
+
}
|
215
246
|
}),
|
216
247
|
deleteDocument: builder.mutation({
|
217
248
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -222,7 +253,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
222
253
|
}
|
223
254
|
}),
|
224
255
|
invalidatesTags: (_result, _error, { collectionType, model }) => [
|
225
|
-
{ type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model }
|
256
|
+
{ type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model },
|
257
|
+
"RecentDocumentList"
|
226
258
|
]
|
227
259
|
}),
|
228
260
|
deleteManyDocuments: builder.mutation({
|
@@ -234,7 +266,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
234
266
|
params
|
235
267
|
}
|
236
268
|
}),
|
237
|
-
invalidatesTags: (_res, _error, { model }) => [
|
269
|
+
invalidatesTags: (_res, _error, { model }) => [
|
270
|
+
{ type: "Document", id: `${model}_LIST` },
|
271
|
+
"RecentDocumentList"
|
272
|
+
]
|
238
273
|
}),
|
239
274
|
discardDocument: builder.mutation({
|
240
275
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -252,7 +287,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
252
287
|
},
|
253
288
|
{ type: "Document", id: `${model}_LIST` },
|
254
289
|
"Relations",
|
255
|
-
{ type: "UidAvailability", id: model }
|
290
|
+
{ type: "UidAvailability", id: model },
|
291
|
+
"RecentDocumentList"
|
256
292
|
];
|
257
293
|
}
|
258
294
|
}),
|
@@ -265,7 +301,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
265
301
|
url: `/content-manager/collection-types/${model}`,
|
266
302
|
method: "GET",
|
267
303
|
config: {
|
268
|
-
params
|
304
|
+
params: stringify(params, { encode: true })
|
269
305
|
}
|
270
306
|
}),
|
271
307
|
providesTags: (result, _error, arg) => {
|
@@ -347,7 +383,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
347
383
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
348
384
|
},
|
349
385
|
{ type: "Document", id: `${model}_LIST` },
|
350
|
-
"Relations"
|
386
|
+
"Relations",
|
387
|
+
"RecentDocumentList"
|
351
388
|
];
|
352
389
|
}
|
353
390
|
}),
|
@@ -378,7 +415,9 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
378
415
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
379
416
|
},
|
380
417
|
"Relations",
|
381
|
-
{ type: "UidAvailability", id: model }
|
418
|
+
{ type: "UidAvailability", id: model },
|
419
|
+
"RecentDocumentList",
|
420
|
+
"RecentDocumentList"
|
382
421
|
];
|
383
422
|
},
|
384
423
|
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
@@ -408,7 +447,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
408
447
|
{
|
409
448
|
type: "Document",
|
410
449
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
411
|
-
}
|
450
|
+
},
|
451
|
+
"RecentDocumentList"
|
412
452
|
];
|
413
453
|
}
|
414
454
|
}),
|
@@ -421,7 +461,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
421
461
|
params
|
422
462
|
}
|
423
463
|
}),
|
424
|
-
invalidatesTags: (_res, _error, { model, documentIds }) =>
|
464
|
+
invalidatesTags: (_res, _error, { model, documentIds }) => [
|
465
|
+
...documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` })),
|
466
|
+
"RecentDocumentList"
|
467
|
+
]
|
425
468
|
})
|
426
469
|
})
|
427
470
|
});
|
@@ -444,8 +487,7 @@ const {
|
|
444
487
|
useUnpublishManyDocumentsMutation
|
445
488
|
} = documentApi;
|
446
489
|
const buildValidParams = (query) => {
|
447
|
-
if (!query)
|
448
|
-
return query;
|
490
|
+
if (!query) return query;
|
449
491
|
const { plugins: _, ...validQueryParams } = {
|
450
492
|
...query,
|
451
493
|
...Object.values(query?.plugins ?? {}).reduce(
|
@@ -453,14 +495,29 @@ const buildValidParams = (query) => {
|
|
453
495
|
{}
|
454
496
|
)
|
455
497
|
};
|
456
|
-
if ("_q" in validQueryParams) {
|
457
|
-
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
458
|
-
}
|
459
498
|
return validQueryParams;
|
460
499
|
};
|
461
500
|
const isBaseQueryError = (error) => {
|
462
501
|
return error.name !== void 0;
|
463
502
|
};
|
503
|
+
const arrayValidator = (attribute, options) => ({
|
504
|
+
message: translatedErrors.required,
|
505
|
+
test(value) {
|
506
|
+
if (options.status === "draft") {
|
507
|
+
return true;
|
508
|
+
}
|
509
|
+
if (!attribute.required) {
|
510
|
+
return true;
|
511
|
+
}
|
512
|
+
if (!value) {
|
513
|
+
return false;
|
514
|
+
}
|
515
|
+
if (Array.isArray(value) && value.length === 0) {
|
516
|
+
return false;
|
517
|
+
}
|
518
|
+
return true;
|
519
|
+
}
|
520
|
+
});
|
464
521
|
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
465
522
|
const createModelSchema = (attributes2) => yup.object().shape(
|
466
523
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
@@ -468,6 +525,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
468
525
|
return acc;
|
469
526
|
}
|
470
527
|
const validations = [
|
528
|
+
addNullableValidation,
|
471
529
|
addRequiredValidation,
|
472
530
|
addMinLengthValidation,
|
473
531
|
addMaxLengthValidation,
|
@@ -484,12 +542,12 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
484
542
|
...acc,
|
485
543
|
[name]: transformSchema(
|
486
544
|
yup.array().of(createModelSchema(attributes3).nullable(false))
|
487
|
-
)
|
545
|
+
).test(arrayValidator(attribute, options))
|
488
546
|
};
|
489
547
|
} else {
|
490
548
|
return {
|
491
549
|
...acc,
|
492
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
550
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
493
551
|
};
|
494
552
|
}
|
495
553
|
}
|
@@ -511,7 +569,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
511
569
|
}
|
512
570
|
)
|
513
571
|
)
|
514
|
-
)
|
572
|
+
).test(arrayValidator(attribute, options))
|
515
573
|
};
|
516
574
|
case "relation":
|
517
575
|
return {
|
@@ -523,7 +581,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
523
581
|
} else if (Array.isArray(value)) {
|
524
582
|
return yup.array().of(
|
525
583
|
yup.object().shape({
|
526
|
-
id: yup.
|
584
|
+
id: yup.number().required()
|
527
585
|
})
|
528
586
|
);
|
529
587
|
} else if (typeof value === "object") {
|
@@ -609,17 +667,17 @@ const nullableSchema = (schema) => {
|
|
609
667
|
schema
|
610
668
|
);
|
611
669
|
};
|
670
|
+
const addNullableValidation = () => (schema) => {
|
671
|
+
return nullableSchema(schema);
|
672
|
+
};
|
612
673
|
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);
|
674
|
+
if (options.status === "draft" || !attribute.required) {
|
675
|
+
return schema;
|
618
676
|
}
|
619
|
-
if (attribute.required &&
|
677
|
+
if (attribute.required && "required" in schema) {
|
620
678
|
return schema.required(translatedErrors.required);
|
621
679
|
}
|
622
|
-
return
|
680
|
+
return schema;
|
623
681
|
};
|
624
682
|
const addMinLengthValidation = (attribute, options) => (schema) => {
|
625
683
|
if (options.status === "draft") {
|
@@ -647,31 +705,12 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
647
705
|
return schema;
|
648
706
|
};
|
649
707
|
const addMinValidation = (attribute, options) => (schema) => {
|
650
|
-
if ("
|
708
|
+
if (options.status === "draft") {
|
709
|
+
return schema;
|
710
|
+
}
|
711
|
+
if ("min" in attribute && "min" in schema) {
|
651
712
|
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) {
|
713
|
+
if (min) {
|
675
714
|
return schema.min(min, {
|
676
715
|
...translatedErrors.min,
|
677
716
|
values: {
|
@@ -789,19 +828,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
789
828
|
}, {});
|
790
829
|
return componentsByKey;
|
791
830
|
};
|
792
|
-
const
|
831
|
+
const HOOKS = {
|
832
|
+
/**
|
833
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
834
|
+
* @constant
|
835
|
+
* @type {string}
|
836
|
+
*/
|
837
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
838
|
+
/**
|
839
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
840
|
+
* @constant
|
841
|
+
* @type {string}
|
842
|
+
*/
|
843
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
844
|
+
/**
|
845
|
+
* Hook that allows to mutate the CM's edit view layout
|
846
|
+
* @constant
|
847
|
+
* @type {string}
|
848
|
+
*/
|
849
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
850
|
+
/**
|
851
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
852
|
+
* @constant
|
853
|
+
* @type {string}
|
854
|
+
*/
|
855
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
856
|
+
};
|
857
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
858
|
+
endpoints: (builder) => ({
|
859
|
+
getContentTypeConfiguration: builder.query({
|
860
|
+
query: (uid) => ({
|
861
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
862
|
+
method: "GET"
|
863
|
+
}),
|
864
|
+
transformResponse: (response) => response.data,
|
865
|
+
providesTags: (_result, _error, uid) => [
|
866
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
867
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
868
|
+
]
|
869
|
+
}),
|
870
|
+
getAllContentTypeSettings: builder.query({
|
871
|
+
query: () => "/content-manager/content-types-settings",
|
872
|
+
transformResponse: (response) => response.data,
|
873
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
874
|
+
}),
|
875
|
+
updateContentTypeConfiguration: builder.mutation({
|
876
|
+
query: ({ uid, ...body }) => ({
|
877
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
878
|
+
method: "PUT",
|
879
|
+
data: body
|
880
|
+
}),
|
881
|
+
transformResponse: (response) => response.data,
|
882
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
883
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
884
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
885
|
+
// Is this necessary?
|
886
|
+
{ type: "InitialData" }
|
887
|
+
]
|
888
|
+
})
|
889
|
+
})
|
890
|
+
});
|
891
|
+
const {
|
892
|
+
useGetContentTypeConfigurationQuery,
|
893
|
+
useGetAllContentTypeSettingsQuery,
|
894
|
+
useUpdateContentTypeConfigurationMutation
|
895
|
+
} = contentTypesApi;
|
896
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
897
|
+
const { type } = attribute;
|
898
|
+
if (type === "relation") {
|
899
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
900
|
+
}
|
901
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
902
|
+
};
|
903
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
904
|
+
if (!mainFieldName) {
|
905
|
+
return void 0;
|
906
|
+
}
|
907
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
908
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
909
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
910
|
+
);
|
911
|
+
return {
|
912
|
+
name: mainFieldName,
|
913
|
+
type: mainFieldType ?? "string"
|
914
|
+
};
|
915
|
+
};
|
916
|
+
const DEFAULT_SETTINGS = {
|
917
|
+
bulkable: false,
|
918
|
+
filterable: false,
|
919
|
+
searchable: false,
|
920
|
+
pagination: false,
|
921
|
+
defaultSortBy: "",
|
922
|
+
defaultSortOrder: "asc",
|
923
|
+
mainField: "id",
|
924
|
+
pageSize: 10
|
925
|
+
};
|
926
|
+
const useDocumentLayout = (model) => {
|
927
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
928
|
+
const [{ query }] = useQueryParams();
|
929
|
+
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
793
930
|
const { toggleNotification } = useNotification();
|
794
931
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
932
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
795
933
|
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);
|
934
|
+
data,
|
935
|
+
isLoading: isLoadingConfigs,
|
936
|
+
error,
|
937
|
+
isFetching: isFetchingConfigs
|
938
|
+
} = useGetContentTypeConfigurationQuery(model);
|
939
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
805
940
|
React.useEffect(() => {
|
806
941
|
if (error) {
|
807
942
|
toggleNotification({
|
@@ -809,77 +944,331 @@ const useDocument = (args, opts) => {
|
|
809
944
|
message: formatAPIError(error)
|
810
945
|
});
|
811
946
|
}
|
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
|
-
}
|
947
|
+
}, [error, formatAPIError, toggleNotification]);
|
948
|
+
const editLayout = React.useMemo(
|
949
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
950
|
+
layout: [],
|
951
|
+
components: {},
|
952
|
+
metadatas: {},
|
953
|
+
options: {},
|
954
|
+
settings: DEFAULT_SETTINGS
|
835
955
|
},
|
836
|
-
[
|
956
|
+
[data, isLoading, schemas, schema, components]
|
957
|
+
);
|
958
|
+
const listLayout = React.useMemo(() => {
|
959
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
960
|
+
layout: [],
|
961
|
+
metadatas: {},
|
962
|
+
options: {},
|
963
|
+
settings: DEFAULT_SETTINGS
|
964
|
+
};
|
965
|
+
}, [data, isLoading, schemas, schema, components]);
|
966
|
+
const { layout: edit } = React.useMemo(
|
967
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
968
|
+
layout: editLayout,
|
969
|
+
query
|
970
|
+
}),
|
971
|
+
[editLayout, query, runHookWaterfall]
|
837
972
|
);
|
838
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
839
973
|
return {
|
840
|
-
|
841
|
-
document: data?.data,
|
842
|
-
meta: data?.meta,
|
974
|
+
error,
|
843
975
|
isLoading,
|
844
|
-
|
845
|
-
|
846
|
-
};
|
847
|
-
};
|
848
|
-
const useDoc = () => {
|
849
|
-
const { id, slug, collectionType, origin } = useParams();
|
850
|
-
const [{ query }] = useQueryParams();
|
851
|
-
const params = React.useMemo(() => buildValidParams(query), [query]);
|
852
|
-
if (!collectionType) {
|
853
|
-
throw new Error("Could not find collectionType in url params");
|
854
|
-
}
|
855
|
-
if (!slug) {
|
856
|
-
throw new Error("Could not find model in url params");
|
857
|
-
}
|
858
|
-
return {
|
859
|
-
collectionType,
|
860
|
-
model: slug,
|
861
|
-
id: origin || id === "create" ? void 0 : id,
|
862
|
-
...useDocument(
|
863
|
-
{ documentId: origin || id, model: slug, collectionType, params },
|
864
|
-
{
|
865
|
-
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
866
|
-
}
|
867
|
-
)
|
976
|
+
edit,
|
977
|
+
list: listLayout
|
868
978
|
};
|
869
979
|
};
|
870
|
-
const
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
}
|
879
|
-
|
880
|
-
const
|
881
|
-
|
882
|
-
|
980
|
+
const useDocLayout = () => {
|
981
|
+
const { model } = useDoc();
|
982
|
+
return useDocumentLayout(model);
|
983
|
+
};
|
984
|
+
const formatEditLayout = (data, {
|
985
|
+
schemas,
|
986
|
+
schema,
|
987
|
+
components
|
988
|
+
}) => {
|
989
|
+
let currentPanelIndex = 0;
|
990
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
991
|
+
data.contentType.layouts.edit,
|
992
|
+
schema?.attributes,
|
993
|
+
data.contentType.metadatas,
|
994
|
+
{ configurations: data.components, schemas: components },
|
995
|
+
schemas
|
996
|
+
).reduce((panels, row) => {
|
997
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
998
|
+
panels.push([row]);
|
999
|
+
currentPanelIndex += 2;
|
1000
|
+
} else {
|
1001
|
+
if (!panels[currentPanelIndex]) {
|
1002
|
+
panels.push([row]);
|
1003
|
+
} else {
|
1004
|
+
panels[currentPanelIndex].push(row);
|
1005
|
+
}
|
1006
|
+
}
|
1007
|
+
return panels;
|
1008
|
+
}, []);
|
1009
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
1010
|
+
(acc, [uid, configuration]) => {
|
1011
|
+
acc[uid] = {
|
1012
|
+
layout: convertEditLayoutToFieldLayouts(
|
1013
|
+
configuration.layouts.edit,
|
1014
|
+
components[uid].attributes,
|
1015
|
+
configuration.metadatas,
|
1016
|
+
{ configurations: data.components, schemas: components }
|
1017
|
+
),
|
1018
|
+
settings: {
|
1019
|
+
...configuration.settings,
|
1020
|
+
icon: components[uid].info.icon,
|
1021
|
+
displayName: components[uid].info.displayName
|
1022
|
+
}
|
1023
|
+
};
|
1024
|
+
return acc;
|
1025
|
+
},
|
1026
|
+
{}
|
1027
|
+
);
|
1028
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1029
|
+
(acc, [attribute, metadata]) => {
|
1030
|
+
return {
|
1031
|
+
...acc,
|
1032
|
+
[attribute]: metadata.edit
|
1033
|
+
};
|
1034
|
+
},
|
1035
|
+
{}
|
1036
|
+
);
|
1037
|
+
return {
|
1038
|
+
layout: panelledEditAttributes,
|
1039
|
+
components: componentEditAttributes,
|
1040
|
+
metadatas: editMetadatas,
|
1041
|
+
settings: {
|
1042
|
+
...data.contentType.settings,
|
1043
|
+
displayName: schema?.info.displayName
|
1044
|
+
},
|
1045
|
+
options: {
|
1046
|
+
...schema?.options,
|
1047
|
+
...schema?.pluginOptions,
|
1048
|
+
...data.contentType.options
|
1049
|
+
}
|
1050
|
+
};
|
1051
|
+
};
|
1052
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1053
|
+
return rows.map(
|
1054
|
+
(row) => row.map((field) => {
|
1055
|
+
const attribute = attributes[field.name];
|
1056
|
+
if (!attribute) {
|
1057
|
+
return null;
|
1058
|
+
}
|
1059
|
+
const { edit: metadata } = metadatas[field.name];
|
1060
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1061
|
+
return {
|
1062
|
+
attribute,
|
1063
|
+
disabled: !metadata.editable,
|
1064
|
+
hint: metadata.description,
|
1065
|
+
label: metadata.label ?? "",
|
1066
|
+
name: field.name,
|
1067
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1068
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1069
|
+
schemas,
|
1070
|
+
components: components?.schemas ?? {}
|
1071
|
+
}),
|
1072
|
+
placeholder: metadata.placeholder ?? "",
|
1073
|
+
required: attribute.required ?? false,
|
1074
|
+
size: field.size,
|
1075
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1076
|
+
visible: metadata.visible ?? true,
|
1077
|
+
type: attribute.type
|
1078
|
+
};
|
1079
|
+
}).filter((field) => field !== null)
|
1080
|
+
);
|
1081
|
+
};
|
1082
|
+
const formatListLayout = (data, {
|
1083
|
+
schemas,
|
1084
|
+
schema,
|
1085
|
+
components
|
1086
|
+
}) => {
|
1087
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1088
|
+
(acc, [attribute, metadata]) => {
|
1089
|
+
return {
|
1090
|
+
...acc,
|
1091
|
+
[attribute]: metadata.list
|
1092
|
+
};
|
1093
|
+
},
|
1094
|
+
{}
|
1095
|
+
);
|
1096
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1097
|
+
data.contentType.layouts.list,
|
1098
|
+
schema?.attributes,
|
1099
|
+
listMetadatas,
|
1100
|
+
{ configurations: data.components, schemas: components },
|
1101
|
+
schemas
|
1102
|
+
);
|
1103
|
+
return {
|
1104
|
+
layout: listAttributes,
|
1105
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1106
|
+
metadatas: listMetadatas,
|
1107
|
+
options: {
|
1108
|
+
...schema?.options,
|
1109
|
+
...schema?.pluginOptions,
|
1110
|
+
...data.contentType.options
|
1111
|
+
}
|
1112
|
+
};
|
1113
|
+
};
|
1114
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1115
|
+
return columns.map((name) => {
|
1116
|
+
const attribute = attributes[name];
|
1117
|
+
if (!attribute) {
|
1118
|
+
return null;
|
1119
|
+
}
|
1120
|
+
const metadata = metadatas[name];
|
1121
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1122
|
+
return {
|
1123
|
+
attribute,
|
1124
|
+
label: metadata.label ?? "",
|
1125
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1126
|
+
schemas,
|
1127
|
+
components: components?.schemas ?? {}
|
1128
|
+
}),
|
1129
|
+
name,
|
1130
|
+
searchable: metadata.searchable ?? true,
|
1131
|
+
sortable: metadata.sortable ?? true
|
1132
|
+
};
|
1133
|
+
}).filter((field) => field !== null);
|
1134
|
+
};
|
1135
|
+
const useDocument = (args, opts) => {
|
1136
|
+
const { toggleNotification } = useNotification();
|
1137
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1138
|
+
const {
|
1139
|
+
currentData: data,
|
1140
|
+
isLoading: isLoadingDocument,
|
1141
|
+
isFetching: isFetchingDocument,
|
1142
|
+
error
|
1143
|
+
} = useGetDocumentQuery(args, {
|
1144
|
+
...opts,
|
1145
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1146
|
+
});
|
1147
|
+
const {
|
1148
|
+
components,
|
1149
|
+
schema,
|
1150
|
+
schemas,
|
1151
|
+
isLoading: isLoadingSchema
|
1152
|
+
} = useContentTypeSchema(args.model);
|
1153
|
+
React.useEffect(() => {
|
1154
|
+
if (error) {
|
1155
|
+
toggleNotification({
|
1156
|
+
type: "danger",
|
1157
|
+
message: formatAPIError(error)
|
1158
|
+
});
|
1159
|
+
}
|
1160
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1161
|
+
const validationSchema = React.useMemo(() => {
|
1162
|
+
if (!schema) {
|
1163
|
+
return null;
|
1164
|
+
}
|
1165
|
+
return createYupSchema(schema.attributes, components);
|
1166
|
+
}, [schema, components]);
|
1167
|
+
const validate = React.useCallback(
|
1168
|
+
(document) => {
|
1169
|
+
if (!validationSchema) {
|
1170
|
+
throw new Error(
|
1171
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1172
|
+
);
|
1173
|
+
}
|
1174
|
+
try {
|
1175
|
+
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
1176
|
+
return null;
|
1177
|
+
} catch (error2) {
|
1178
|
+
if (error2 instanceof ValidationError) {
|
1179
|
+
return getYupValidationErrors(error2);
|
1180
|
+
}
|
1181
|
+
throw error2;
|
1182
|
+
}
|
1183
|
+
},
|
1184
|
+
[validationSchema]
|
1185
|
+
);
|
1186
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1187
|
+
const hasError = !!error;
|
1188
|
+
return {
|
1189
|
+
components,
|
1190
|
+
document: data?.data,
|
1191
|
+
meta: data?.meta,
|
1192
|
+
isLoading,
|
1193
|
+
hasError,
|
1194
|
+
schema,
|
1195
|
+
schemas,
|
1196
|
+
validate
|
1197
|
+
};
|
1198
|
+
};
|
1199
|
+
const useDoc = () => {
|
1200
|
+
const { id, slug, collectionType, origin } = useParams();
|
1201
|
+
const [{ query }] = useQueryParams();
|
1202
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1203
|
+
if (!collectionType) {
|
1204
|
+
throw new Error("Could not find collectionType in url params");
|
1205
|
+
}
|
1206
|
+
if (!slug) {
|
1207
|
+
throw new Error("Could not find model in url params");
|
1208
|
+
}
|
1209
|
+
const document = useDocument(
|
1210
|
+
{ documentId: origin || id, model: slug, collectionType, params },
|
1211
|
+
{
|
1212
|
+
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
1213
|
+
}
|
1214
|
+
);
|
1215
|
+
const returnId = origin || id === "create" ? void 0 : id;
|
1216
|
+
return {
|
1217
|
+
collectionType,
|
1218
|
+
model: slug,
|
1219
|
+
id: returnId,
|
1220
|
+
...document
|
1221
|
+
};
|
1222
|
+
};
|
1223
|
+
const useContentManagerContext = () => {
|
1224
|
+
const {
|
1225
|
+
collectionType,
|
1226
|
+
model,
|
1227
|
+
id,
|
1228
|
+
components,
|
1229
|
+
isLoading: isLoadingDoc,
|
1230
|
+
schema,
|
1231
|
+
schemas
|
1232
|
+
} = useDoc();
|
1233
|
+
const layout = useDocumentLayout(model);
|
1234
|
+
const form = useForm("useContentManagerContext", (state) => state);
|
1235
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1236
|
+
const slug = model;
|
1237
|
+
const isCreatingEntry = id === "create";
|
1238
|
+
useContentTypeSchema();
|
1239
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1240
|
+
const error = layout.error;
|
1241
|
+
return {
|
1242
|
+
error,
|
1243
|
+
isLoading,
|
1244
|
+
// Base metadata
|
1245
|
+
model,
|
1246
|
+
collectionType,
|
1247
|
+
id,
|
1248
|
+
slug,
|
1249
|
+
isCreatingEntry,
|
1250
|
+
isSingleType,
|
1251
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1252
|
+
// All schema infos
|
1253
|
+
components,
|
1254
|
+
contentType: schema,
|
1255
|
+
contentTypes: schemas,
|
1256
|
+
// Form state
|
1257
|
+
form,
|
1258
|
+
// layout infos
|
1259
|
+
layout
|
1260
|
+
};
|
1261
|
+
};
|
1262
|
+
const prefixPluginTranslations = (trad, pluginId) => {
|
1263
|
+
return Object.keys(trad).reduce((acc, current) => {
|
1264
|
+
acc[`${pluginId}.${current}`] = trad[current];
|
1265
|
+
return acc;
|
1266
|
+
}, {});
|
1267
|
+
};
|
1268
|
+
const getTranslation = (id) => `content-manager.${id}`;
|
1269
|
+
const DEFAULT_UNEXPECTED_ERROR_MSG = {
|
1270
|
+
id: "notification.error",
|
1271
|
+
defaultMessage: "An error occurred, please try again"
|
883
1272
|
};
|
884
1273
|
const useDocumentActions = () => {
|
885
1274
|
const { toggleNotification } = useNotification();
|
@@ -887,6 +1276,7 @@ const useDocumentActions = () => {
|
|
887
1276
|
const { trackUsage } = useTracking();
|
888
1277
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
889
1278
|
const navigate = useNavigate();
|
1279
|
+
const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
890
1280
|
const [deleteDocument] = useDeleteDocumentMutation();
|
891
1281
|
const _delete = React.useCallback(
|
892
1282
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1201,6 +1591,7 @@ const useDocumentActions = () => {
|
|
1201
1591
|
defaultMessage: "Saved document"
|
1202
1592
|
})
|
1203
1593
|
});
|
1594
|
+
setCurrentStep("contentManager.success");
|
1204
1595
|
return res.data;
|
1205
1596
|
} catch (err) {
|
1206
1597
|
toggleNotification({
|
@@ -1302,10 +1693,10 @@ const useDocumentActions = () => {
|
|
1302
1693
|
update
|
1303
1694
|
};
|
1304
1695
|
};
|
1305
|
-
const ProtectedHistoryPage = lazy(
|
1306
|
-
() => import("./History-
|
1696
|
+
const ProtectedHistoryPage = React.lazy(
|
1697
|
+
() => import("./History-04ChQ4pl.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1307
1698
|
);
|
1308
|
-
const routes$
|
1699
|
+
const routes$2 = [
|
1309
1700
|
{
|
1310
1701
|
path: ":collectionType/:slug/:id/history",
|
1311
1702
|
Component: ProtectedHistoryPage
|
@@ -1315,32 +1706,45 @@ const routes$1 = [
|
|
1315
1706
|
Component: ProtectedHistoryPage
|
1316
1707
|
}
|
1317
1708
|
];
|
1318
|
-
const
|
1319
|
-
() => import("./
|
1709
|
+
const ProtectedPreviewPage = React.lazy(
|
1710
|
+
() => import("./Preview-BMYN548c.mjs").then((mod) => ({ default: mod.ProtectedPreviewPage }))
|
1320
1711
|
);
|
1321
|
-
const
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1712
|
+
const routes$1 = [
|
1713
|
+
{
|
1714
|
+
path: ":collectionType/:slug/:id/preview",
|
1715
|
+
Component: ProtectedPreviewPage
|
1716
|
+
},
|
1717
|
+
{
|
1718
|
+
path: ":collectionType/:slug/preview",
|
1719
|
+
Component: ProtectedPreviewPage
|
1720
|
+
}
|
1721
|
+
];
|
1722
|
+
const ProtectedEditViewPage = lazy(
|
1723
|
+
() => import("./EditViewPage-BPyVuPfM.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1724
|
+
);
|
1725
|
+
const ProtectedListViewPage = lazy(
|
1726
|
+
() => import("./ListViewPage-FU2LBuhl.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1727
|
+
);
|
1728
|
+
const ProtectedListConfiguration = lazy(
|
1729
|
+
() => import("./ListConfigurationPage-BYqPYLSU.mjs").then((mod) => ({
|
1730
|
+
default: mod.ProtectedListConfiguration
|
1327
1731
|
}))
|
1328
1732
|
);
|
1329
1733
|
const ProtectedEditConfigurationPage = lazy(
|
1330
|
-
() => import("./EditConfigurationPage-
|
1734
|
+
() => import("./EditConfigurationPage-DsPR2DVk.mjs").then((mod) => ({
|
1331
1735
|
default: mod.ProtectedEditConfigurationPage
|
1332
1736
|
}))
|
1333
1737
|
);
|
1334
1738
|
const ProtectedComponentConfigurationPage = lazy(
|
1335
|
-
() => import("./ComponentConfigurationPage-
|
1739
|
+
() => import("./ComponentConfigurationPage-CtIa3aa2.mjs").then((mod) => ({
|
1336
1740
|
default: mod.ProtectedComponentConfigurationPage
|
1337
1741
|
}))
|
1338
1742
|
);
|
1339
1743
|
const NoPermissions = lazy(
|
1340
|
-
() => import("./NoPermissionsPage-
|
1744
|
+
() => import("./NoPermissionsPage-jqve7C8l.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1341
1745
|
);
|
1342
1746
|
const NoContentType = lazy(
|
1343
|
-
() => import("./NoContentTypePage-
|
1747
|
+
() => import("./NoContentTypePage-DCKUkwb8.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1344
1748
|
);
|
1345
1749
|
const CollectionTypePages = () => {
|
1346
1750
|
const { collectionType } = useParams();
|
@@ -1352,7 +1756,7 @@ const CollectionTypePages = () => {
|
|
1352
1756
|
const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
|
1353
1757
|
const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
|
1354
1758
|
const LIST_RELATIVE_PATH = ":collectionType/:slug";
|
1355
|
-
const LIST_PATH = `/content-manager
|
1759
|
+
const LIST_PATH = `/content-manager/collection-types/:slug`;
|
1356
1760
|
const routes = [
|
1357
1761
|
{
|
1358
1762
|
path: LIST_RELATIVE_PATH,
|
@@ -1386,6 +1790,7 @@ const routes = [
|
|
1386
1790
|
path: "no-content-types",
|
1387
1791
|
Component: NoContentType
|
1388
1792
|
},
|
1793
|
+
...routes$2,
|
1389
1794
|
...routes$1
|
1390
1795
|
];
|
1391
1796
|
const DocumentActions = ({ actions: actions2 }) => {
|
@@ -1484,6 +1889,11 @@ const DocumentActionButton = (action) => {
|
|
1484
1889
|
) : null
|
1485
1890
|
] });
|
1486
1891
|
};
|
1892
|
+
const MenuItem = styled(Menu.Item)`
|
1893
|
+
&:hover {
|
1894
|
+
background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
|
1895
|
+
}
|
1896
|
+
`;
|
1487
1897
|
const DocumentActionsMenu = ({
|
1488
1898
|
actions: actions2,
|
1489
1899
|
children,
|
@@ -1542,48 +1952,32 @@ const DocumentActionsMenu = ({
|
|
1542
1952
|
/* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1543
1953
|
actions2.map((action) => {
|
1544
1954
|
return /* @__PURE__ */ jsx(
|
1545
|
-
|
1955
|
+
MenuItem,
|
1546
1956
|
{
|
1547
1957
|
disabled: action.disabled,
|
1548
1958
|
onSelect: handleClick(action),
|
1549
1959
|
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
|
-
] })
|
1960
|
+
isVariantDanger: action.variant === "danger",
|
1961
|
+
isDisabled: action.disabled,
|
1962
|
+
children: /* @__PURE__ */ jsx(Flex, { justifyContent: "space-between", gap: 4, children: /* @__PURE__ */ jsxs(
|
1963
|
+
Flex,
|
1964
|
+
{
|
1965
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1966
|
+
gap: 2,
|
1967
|
+
tag: "span",
|
1968
|
+
children: [
|
1969
|
+
/* @__PURE__ */ jsx(
|
1970
|
+
Flex,
|
1971
|
+
{
|
1972
|
+
tag: "span",
|
1973
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1974
|
+
children: action.icon
|
1975
|
+
}
|
1976
|
+
),
|
1977
|
+
action.label
|
1978
|
+
]
|
1979
|
+
}
|
1980
|
+
) })
|
1587
1981
|
},
|
1588
1982
|
action.id
|
1589
1983
|
);
|
@@ -1694,6 +2088,18 @@ const DocumentActionModal = ({
|
|
1694
2088
|
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1695
2089
|
] }) });
|
1696
2090
|
};
|
2091
|
+
const transformData = (data) => {
|
2092
|
+
if (Array.isArray(data)) {
|
2093
|
+
return data.map(transformData);
|
2094
|
+
}
|
2095
|
+
if (typeof data === "object" && data !== null) {
|
2096
|
+
if ("apiData" in data) {
|
2097
|
+
return data.apiData;
|
2098
|
+
}
|
2099
|
+
return mapValues(transformData)(data);
|
2100
|
+
}
|
2101
|
+
return data;
|
2102
|
+
};
|
1697
2103
|
const PublishAction$1 = ({
|
1698
2104
|
activeTab,
|
1699
2105
|
documentId,
|
@@ -1708,6 +2114,7 @@ const PublishAction$1 = ({
|
|
1708
2114
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
1709
2115
|
const isListView = useMatch(LIST_PATH) !== null;
|
1710
2116
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2117
|
+
const { id } = useParams();
|
1711
2118
|
const { formatMessage } = useIntl();
|
1712
2119
|
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1713
2120
|
const { publish } = useDocumentActions();
|
@@ -1787,7 +2194,9 @@ const PublishAction$1 = ({
|
|
1787
2194
|
const performPublish = async () => {
|
1788
2195
|
setSubmitting(true);
|
1789
2196
|
try {
|
1790
|
-
const { errors } = await validate(
|
2197
|
+
const { errors } = await validate(true, {
|
2198
|
+
status: "published"
|
2199
|
+
});
|
1791
2200
|
if (errors) {
|
1792
2201
|
toggleNotification({
|
1793
2202
|
type: "danger",
|
@@ -1805,13 +2214,15 @@ const PublishAction$1 = ({
|
|
1805
2214
|
documentId,
|
1806
2215
|
params
|
1807
2216
|
},
|
1808
|
-
formValues
|
2217
|
+
transformData(formValues)
|
1809
2218
|
);
|
1810
2219
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
2220
|
+
if (id === "create") {
|
2221
|
+
navigate({
|
2222
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2223
|
+
search: rawQuery
|
2224
|
+
});
|
2225
|
+
}
|
1815
2226
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1816
2227
|
setErrors(formatValidationErrors(res.error));
|
1817
2228
|
}
|
@@ -1864,6 +2275,7 @@ const PublishAction$1 = ({
|
|
1864
2275
|
};
|
1865
2276
|
};
|
1866
2277
|
PublishAction$1.type = "publish";
|
2278
|
+
PublishAction$1.position = "panel";
|
1867
2279
|
const UpdateAction = ({
|
1868
2280
|
activeTab,
|
1869
2281
|
documentId,
|
@@ -1886,6 +2298,117 @@ const UpdateAction = ({
|
|
1886
2298
|
const validate = useForm("UpdateAction", (state) => state.validate);
|
1887
2299
|
const setErrors = useForm("UpdateAction", (state) => state.setErrors);
|
1888
2300
|
const resetForm = useForm("PublishAction", ({ resetForm: resetForm2 }) => resetForm2);
|
2301
|
+
const handleUpdate = React.useCallback(async () => {
|
2302
|
+
setSubmitting(true);
|
2303
|
+
try {
|
2304
|
+
if (!modified) {
|
2305
|
+
return;
|
2306
|
+
}
|
2307
|
+
const { errors } = await validate(true, {
|
2308
|
+
status: "draft"
|
2309
|
+
});
|
2310
|
+
if (errors) {
|
2311
|
+
toggleNotification({
|
2312
|
+
type: "danger",
|
2313
|
+
message: formatMessage({
|
2314
|
+
id: "content-manager.validation.error",
|
2315
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2316
|
+
})
|
2317
|
+
});
|
2318
|
+
return;
|
2319
|
+
}
|
2320
|
+
if (isCloning) {
|
2321
|
+
const res = await clone(
|
2322
|
+
{
|
2323
|
+
model,
|
2324
|
+
documentId: cloneMatch.params.origin,
|
2325
|
+
params
|
2326
|
+
},
|
2327
|
+
transformData(document)
|
2328
|
+
);
|
2329
|
+
if ("data" in res) {
|
2330
|
+
navigate(
|
2331
|
+
{
|
2332
|
+
pathname: `../${res.data.documentId}`,
|
2333
|
+
search: rawQuery
|
2334
|
+
},
|
2335
|
+
{ relative: "path" }
|
2336
|
+
);
|
2337
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2338
|
+
setErrors(formatValidationErrors(res.error));
|
2339
|
+
}
|
2340
|
+
} else if (documentId || collectionType === SINGLE_TYPES) {
|
2341
|
+
const res = await update(
|
2342
|
+
{
|
2343
|
+
collectionType,
|
2344
|
+
model,
|
2345
|
+
documentId,
|
2346
|
+
params
|
2347
|
+
},
|
2348
|
+
transformData(document)
|
2349
|
+
);
|
2350
|
+
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2351
|
+
setErrors(formatValidationErrors(res.error));
|
2352
|
+
} else {
|
2353
|
+
resetForm();
|
2354
|
+
}
|
2355
|
+
} else {
|
2356
|
+
const res = await create(
|
2357
|
+
{
|
2358
|
+
model,
|
2359
|
+
params
|
2360
|
+
},
|
2361
|
+
transformData(document)
|
2362
|
+
);
|
2363
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2364
|
+
navigate(
|
2365
|
+
{
|
2366
|
+
pathname: `../${res.data.documentId}`,
|
2367
|
+
search: rawQuery
|
2368
|
+
},
|
2369
|
+
{ replace: true, relative: "path" }
|
2370
|
+
);
|
2371
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2372
|
+
setErrors(formatValidationErrors(res.error));
|
2373
|
+
}
|
2374
|
+
}
|
2375
|
+
} finally {
|
2376
|
+
setSubmitting(false);
|
2377
|
+
}
|
2378
|
+
}, [
|
2379
|
+
clone,
|
2380
|
+
cloneMatch?.params.origin,
|
2381
|
+
collectionType,
|
2382
|
+
create,
|
2383
|
+
document,
|
2384
|
+
documentId,
|
2385
|
+
formatMessage,
|
2386
|
+
formatValidationErrors,
|
2387
|
+
isCloning,
|
2388
|
+
model,
|
2389
|
+
modified,
|
2390
|
+
navigate,
|
2391
|
+
params,
|
2392
|
+
rawQuery,
|
2393
|
+
resetForm,
|
2394
|
+
setErrors,
|
2395
|
+
setSubmitting,
|
2396
|
+
toggleNotification,
|
2397
|
+
update,
|
2398
|
+
validate
|
2399
|
+
]);
|
2400
|
+
React.useEffect(() => {
|
2401
|
+
const handleKeyDown = (e) => {
|
2402
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
2403
|
+
e.preventDefault();
|
2404
|
+
handleUpdate();
|
2405
|
+
}
|
2406
|
+
};
|
2407
|
+
window.addEventListener("keydown", handleKeyDown);
|
2408
|
+
return () => {
|
2409
|
+
window.removeEventListener("keydown", handleKeyDown);
|
2410
|
+
};
|
2411
|
+
}, [handleUpdate]);
|
1889
2412
|
return {
|
1890
2413
|
/**
|
1891
2414
|
* Disabled when:
|
@@ -1895,87 +2418,14 @@ const UpdateAction = ({
|
|
1895
2418
|
*/
|
1896
2419
|
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1897
2420
|
label: formatMessage({
|
1898
|
-
id: "
|
2421
|
+
id: "global.save",
|
1899
2422
|
defaultMessage: "Save"
|
1900
2423
|
}),
|
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
|
-
}
|
2424
|
+
onClick: handleUpdate
|
1976
2425
|
};
|
1977
2426
|
};
|
1978
2427
|
UpdateAction.type = "update";
|
2428
|
+
UpdateAction.position = "panel";
|
1979
2429
|
const UNPUBLISH_DRAFT_OPTIONS = {
|
1980
2430
|
KEEP: "keep",
|
1981
2431
|
DISCARD: "discard"
|
@@ -2098,6 +2548,7 @@ const UnpublishAction$1 = ({
|
|
2098
2548
|
};
|
2099
2549
|
};
|
2100
2550
|
UnpublishAction$1.type = "unpublish";
|
2551
|
+
UnpublishAction$1.position = "panel";
|
2101
2552
|
const DiscardAction = ({
|
2102
2553
|
activeTab,
|
2103
2554
|
documentId,
|
@@ -2148,6 +2599,7 @@ const DiscardAction = ({
|
|
2148
2599
|
};
|
2149
2600
|
};
|
2150
2601
|
DiscardAction.type = "discard";
|
2602
|
+
DiscardAction.position = "panel";
|
2151
2603
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2152
2604
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2153
2605
|
const RelativeTime = React.forwardRef(
|
@@ -2160,7 +2612,7 @@ const RelativeTime = React.forwardRef(
|
|
2160
2612
|
});
|
2161
2613
|
const unit = intervals.find((intervalUnit) => {
|
2162
2614
|
return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
|
2163
|
-
});
|
2615
|
+
}) ?? "seconds";
|
2164
2616
|
const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
|
2165
2617
|
const customInterval = customIntervals.find(
|
2166
2618
|
(custom) => interval[custom.unit] < custom.threshold
|
@@ -2194,19 +2646,29 @@ const getDisplayName = ({
|
|
2194
2646
|
return email ?? "";
|
2195
2647
|
};
|
2196
2648
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2197
|
-
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2649
|
+
const DocumentStatus = ({ status = "draft", size = "S", ...restProps }) => {
|
2198
2650
|
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2199
|
-
|
2651
|
+
const { formatMessage } = useIntl();
|
2652
|
+
return /* @__PURE__ */ jsx(Status, { ...restProps, size, variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: formatMessage({
|
2653
|
+
id: `content-manager.containers.List.${status}`,
|
2654
|
+
defaultMessage: capitalise(status)
|
2655
|
+
}) }) });
|
2200
2656
|
};
|
2201
2657
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2202
2658
|
const { formatMessage } = useIntl();
|
2203
2659
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2660
|
+
const params = useParams();
|
2204
2661
|
const title = isCreating ? formatMessage({
|
2205
2662
|
id: "content-manager.containers.edit.title.new",
|
2206
2663
|
defaultMessage: "Create an entry"
|
2207
2664
|
}) : documentTitle;
|
2208
2665
|
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2209
|
-
/* @__PURE__ */ jsx(
|
2666
|
+
/* @__PURE__ */ jsx(
|
2667
|
+
BackButton,
|
2668
|
+
{
|
2669
|
+
fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
|
2670
|
+
}
|
2671
|
+
),
|
2210
2672
|
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2211
2673
|
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2212
2674
|
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
@@ -2257,7 +2719,7 @@ const HeaderToolbar = () => {
|
|
2257
2719
|
meta: isCloning ? void 0 : meta,
|
2258
2720
|
collectionType
|
2259
2721
|
},
|
2260
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2722
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("header"),
|
2261
2723
|
children: (actions2) => {
|
2262
2724
|
const headerActions = actions2.filter((action) => {
|
2263
2725
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -2294,12 +2756,12 @@ const Information = ({ activeTab }) => {
|
|
2294
2756
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2295
2757
|
label: formatMessage({
|
2296
2758
|
id: "content-manager.containers.edit.information.last-published.label",
|
2297
|
-
defaultMessage: "
|
2759
|
+
defaultMessage: "Published"
|
2298
2760
|
}),
|
2299
2761
|
value: formatMessage(
|
2300
2762
|
{
|
2301
2763
|
id: "content-manager.containers.edit.information.last-published.value",
|
2302
|
-
defaultMessage: `
|
2764
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2303
2765
|
},
|
2304
2766
|
{
|
2305
2767
|
time: /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2312,12 +2774,12 @@ const Information = ({ activeTab }) => {
|
|
2312
2774
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2313
2775
|
label: formatMessage({
|
2314
2776
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2315
|
-
defaultMessage: "
|
2777
|
+
defaultMessage: "Updated"
|
2316
2778
|
}),
|
2317
2779
|
value: formatMessage(
|
2318
2780
|
{
|
2319
2781
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2320
|
-
defaultMessage: `
|
2782
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2321
2783
|
},
|
2322
2784
|
{
|
2323
2785
|
time: /* @__PURE__ */ jsx(
|
@@ -2335,12 +2797,12 @@ const Information = ({ activeTab }) => {
|
|
2335
2797
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2336
2798
|
label: formatMessage({
|
2337
2799
|
id: "content-manager.containers.edit.information.document.label",
|
2338
|
-
defaultMessage: "
|
2800
|
+
defaultMessage: "Created"
|
2339
2801
|
}),
|
2340
2802
|
value: formatMessage(
|
2341
2803
|
{
|
2342
2804
|
id: "content-manager.containers.edit.information.document.value",
|
2343
|
-
defaultMessage: `
|
2805
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2344
2806
|
},
|
2345
2807
|
{
|
2346
2808
|
time: /* @__PURE__ */ jsx(
|
@@ -2398,10 +2860,9 @@ const HeaderActions = ({ actions: actions2 }) => {
|
|
2398
2860
|
SingleSelect,
|
2399
2861
|
{
|
2400
2862
|
size: "S",
|
2401
|
-
disabled: action.disabled,
|
2402
|
-
"aria-label": action.label,
|
2403
2863
|
onChange: action.onSelect,
|
2404
|
-
|
2864
|
+
"aria-label": action.label,
|
2865
|
+
...action,
|
2405
2866
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
|
2406
2867
|
},
|
2407
2868
|
action.id
|
@@ -2466,6 +2927,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2466
2927
|
};
|
2467
2928
|
};
|
2468
2929
|
ConfigureTheViewAction.type = "configure-the-view";
|
2930
|
+
ConfigureTheViewAction.position = "header";
|
2469
2931
|
const EditTheModelAction = ({ model }) => {
|
2470
2932
|
const navigate = useNavigate();
|
2471
2933
|
const { formatMessage } = useIntl();
|
@@ -2482,6 +2944,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2482
2944
|
};
|
2483
2945
|
};
|
2484
2946
|
EditTheModelAction.type = "edit-the-model";
|
2947
|
+
EditTheModelAction.position = "header";
|
2485
2948
|
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2486
2949
|
const navigate = useNavigate();
|
2487
2950
|
const { formatMessage } = useIntl();
|
@@ -2490,12 +2953,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2490
2953
|
const { delete: deleteAction } = useDocumentActions();
|
2491
2954
|
const { toggleNotification } = useNotification();
|
2492
2955
|
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
2956
|
+
const isLocalized = document?.locale != null;
|
2493
2957
|
return {
|
2494
2958
|
disabled: !canDelete || !document,
|
2495
|
-
label: formatMessage(
|
2496
|
-
|
2497
|
-
|
2498
|
-
|
2959
|
+
label: formatMessage(
|
2960
|
+
{
|
2961
|
+
id: "content-manager.actions.delete.label",
|
2962
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2963
|
+
},
|
2964
|
+
{ isLocalized }
|
2965
|
+
),
|
2499
2966
|
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2500
2967
|
dialog: {
|
2501
2968
|
type: "dialog",
|
@@ -2534,421 +3001,119 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2534
3001
|
collectionType,
|
2535
3002
|
params: {
|
2536
3003
|
locale: "*"
|
2537
|
-
}
|
2538
|
-
});
|
2539
|
-
if (!("error" in res)) {
|
2540
|
-
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2541
|
-
}
|
2542
|
-
} finally {
|
2543
|
-
if (!listViewPathMatch) {
|
2544
|
-
setSubmitting(false);
|
2545
|
-
}
|
2546
|
-
}
|
2547
|
-
}
|
2548
|
-
},
|
2549
|
-
variant: "danger",
|
2550
|
-
position: ["header", "table-row"]
|
2551
|
-
};
|
2552
|
-
};
|
2553
|
-
DeleteAction$1.type = "delete";
|
2554
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2555
|
-
const Panels = () => {
|
2556
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2557
|
-
const [
|
2558
|
-
{
|
2559
|
-
query: { status }
|
2560
|
-
}
|
2561
|
-
] = useQueryParams({
|
2562
|
-
status: "draft"
|
2563
|
-
});
|
2564
|
-
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
|
3004
|
+
}
|
3005
|
+
});
|
3006
|
+
if (!("error" in res)) {
|
3007
|
+
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
3008
|
+
}
|
3009
|
+
} finally {
|
3010
|
+
if (!listViewPathMatch) {
|
3011
|
+
setSubmitting(false);
|
3012
|
+
}
|
2839
3013
|
}
|
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
|
3014
|
+
}
|
2861
3015
|
},
|
2862
|
-
|
2863
|
-
|
2864
|
-
...schema?.pluginOptions,
|
2865
|
-
...data.contentType.options
|
2866
|
-
}
|
3016
|
+
variant: "danger",
|
3017
|
+
position: ["header", "table-row"]
|
2867
3018
|
};
|
2868
3019
|
};
|
2869
|
-
|
2870
|
-
|
2871
|
-
|
2872
|
-
|
2873
|
-
|
2874
|
-
|
2875
|
-
|
2876
|
-
|
2877
|
-
|
2878
|
-
|
2879
|
-
|
2880
|
-
|
2881
|
-
|
2882
|
-
|
2883
|
-
|
2884
|
-
|
2885
|
-
|
2886
|
-
|
2887
|
-
|
2888
|
-
|
2889
|
-
|
2890
|
-
|
2891
|
-
|
2892
|
-
|
2893
|
-
|
2894
|
-
|
2895
|
-
|
2896
|
-
|
2897
|
-
|
3020
|
+
DeleteAction$1.type = "delete";
|
3021
|
+
DeleteAction$1.position = ["header", "table-row"];
|
3022
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
3023
|
+
const Panels = () => {
|
3024
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
3025
|
+
const [
|
3026
|
+
{
|
3027
|
+
query: { status }
|
3028
|
+
}
|
3029
|
+
] = useQueryParams({
|
3030
|
+
status: "draft"
|
3031
|
+
});
|
3032
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
3033
|
+
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
3034
|
+
const props = {
|
3035
|
+
activeTab: status,
|
3036
|
+
model,
|
3037
|
+
documentId: id,
|
3038
|
+
document: isCloning ? void 0 : document,
|
3039
|
+
meta: isCloning ? void 0 : meta,
|
3040
|
+
collectionType
|
3041
|
+
};
|
3042
|
+
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
3043
|
+
DescriptionComponentRenderer,
|
3044
|
+
{
|
3045
|
+
props,
|
3046
|
+
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
3047
|
+
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
3048
|
+
}
|
3049
|
+
) });
|
2898
3050
|
};
|
2899
|
-
const
|
2900
|
-
|
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
|
-
);
|
3051
|
+
const ActionsPanel = () => {
|
3052
|
+
const { formatMessage } = useIntl();
|
2920
3053
|
return {
|
2921
|
-
|
2922
|
-
|
2923
|
-
|
2924
|
-
|
2925
|
-
|
2926
|
-
...schema?.pluginOptions,
|
2927
|
-
...data.contentType.options
|
2928
|
-
}
|
3054
|
+
title: formatMessage({
|
3055
|
+
id: "content-manager.containers.edit.panels.default.title",
|
3056
|
+
defaultMessage: "Entry"
|
3057
|
+
}),
|
3058
|
+
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2929
3059
|
};
|
2930
3060
|
};
|
2931
|
-
|
2932
|
-
|
2933
|
-
|
2934
|
-
|
2935
|
-
|
3061
|
+
ActionsPanel.type = "actions";
|
3062
|
+
const ActionsPanelContent = () => {
|
3063
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
3064
|
+
const [
|
3065
|
+
{
|
3066
|
+
query: { status = "draft" }
|
2936
3067
|
}
|
2937
|
-
|
2938
|
-
|
2939
|
-
|
2940
|
-
|
2941
|
-
|
2942
|
-
|
2943
|
-
|
2944
|
-
|
2945
|
-
|
2946
|
-
|
2947
|
-
|
2948
|
-
|
2949
|
-
|
2950
|
-
|
3068
|
+
] = useQueryParams();
|
3069
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
3070
|
+
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
3071
|
+
const props = {
|
3072
|
+
activeTab: status,
|
3073
|
+
model,
|
3074
|
+
documentId: id,
|
3075
|
+
document: isCloning ? void 0 : document,
|
3076
|
+
meta: isCloning ? void 0 : meta,
|
3077
|
+
collectionType
|
3078
|
+
};
|
3079
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
3080
|
+
/* @__PURE__ */ jsx(
|
3081
|
+
DescriptionComponentRenderer,
|
3082
|
+
{
|
3083
|
+
props,
|
3084
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("panel"),
|
3085
|
+
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
3086
|
+
}
|
3087
|
+
),
|
3088
|
+
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
3089
|
+
] });
|
2951
3090
|
};
|
3091
|
+
const Panel = React.forwardRef(({ children, title }, ref) => {
|
3092
|
+
return /* @__PURE__ */ jsxs(
|
3093
|
+
Flex,
|
3094
|
+
{
|
3095
|
+
ref,
|
3096
|
+
tag: "aside",
|
3097
|
+
"aria-labelledby": "additional-information",
|
3098
|
+
background: "neutral0",
|
3099
|
+
borderColor: "neutral150",
|
3100
|
+
hasRadius: true,
|
3101
|
+
paddingBottom: 4,
|
3102
|
+
paddingLeft: 4,
|
3103
|
+
paddingRight: 4,
|
3104
|
+
paddingTop: 4,
|
3105
|
+
shadow: "tableShadow",
|
3106
|
+
gap: 3,
|
3107
|
+
direction: "column",
|
3108
|
+
justifyContent: "stretch",
|
3109
|
+
alignItems: "flex-start",
|
3110
|
+
children: [
|
3111
|
+
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", textColor: "neutral600", children: title }),
|
3112
|
+
children
|
3113
|
+
]
|
3114
|
+
}
|
3115
|
+
);
|
3116
|
+
});
|
2952
3117
|
const ConfirmBulkActionDialog = ({
|
2953
3118
|
onToggleDialog,
|
2954
3119
|
isOpen = false,
|
@@ -3193,18 +3358,10 @@ const SelectedEntriesTableContent = ({
|
|
3193
3358
|
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3194
3359
|
},
|
3195
3360
|
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
|
-
),
|
3361
|
+
label: formatMessage({
|
3362
|
+
id: "content-manager.bulk-publish.edit",
|
3363
|
+
defaultMessage: "Edit"
|
3364
|
+
}),
|
3208
3365
|
target: "_blank",
|
3209
3366
|
marginLeft: "auto",
|
3210
3367
|
variant: "ghost",
|
@@ -3378,8 +3535,7 @@ const PublishAction = ({ documents, model }) => {
|
|
3378
3535
|
const refetchList = () => {
|
3379
3536
|
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3380
3537
|
};
|
3381
|
-
if (!showPublishButton)
|
3382
|
-
return null;
|
3538
|
+
if (!showPublishButton) return null;
|
3383
3539
|
return {
|
3384
3540
|
actionType: "publish",
|
3385
3541
|
variant: "tertiary",
|
@@ -3447,8 +3603,7 @@ const DeleteAction = ({ documents, model }) => {
|
|
3447
3603
|
selectRow([]);
|
3448
3604
|
}
|
3449
3605
|
};
|
3450
|
-
if (!hasDeletePermission)
|
3451
|
-
return null;
|
3606
|
+
if (!hasDeletePermission) return null;
|
3452
3607
|
return {
|
3453
3608
|
variant: "danger-light",
|
3454
3609
|
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
@@ -3497,8 +3652,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3497
3652
|
}
|
3498
3653
|
};
|
3499
3654
|
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3500
|
-
if (!showUnpublishButton)
|
3501
|
-
return null;
|
3655
|
+
if (!showUnpublishButton) return null;
|
3502
3656
|
return {
|
3503
3657
|
variant: "tertiary",
|
3504
3658
|
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
@@ -3603,7 +3757,7 @@ const TableActions = ({ document }) => {
|
|
3603
3757
|
DescriptionComponentRenderer,
|
3604
3758
|
{
|
3605
3759
|
props,
|
3606
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3760
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("table-row").filter((action) => action.name !== "PublishAction"),
|
3607
3761
|
children: (actions2) => {
|
3608
3762
|
const tableRowActions = actions2.filter((action) => {
|
3609
3763
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3662,6 +3816,7 @@ const EditAction = ({ documentId }) => {
|
|
3662
3816
|
};
|
3663
3817
|
};
|
3664
3818
|
EditAction.type = "edit";
|
3819
|
+
EditAction.position = "table-row";
|
3665
3820
|
const StyledPencil = styled(Pencil)`
|
3666
3821
|
path {
|
3667
3822
|
fill: currentColor;
|
@@ -3738,6 +3893,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3738
3893
|
};
|
3739
3894
|
};
|
3740
3895
|
CloneAction.type = "clone";
|
3896
|
+
CloneAction.position = "table-row";
|
3741
3897
|
const StyledDuplicate = styled(Duplicate)`
|
3742
3898
|
path {
|
3743
3899
|
fill: currentColor;
|
@@ -3824,7 +3980,14 @@ class ContentManagerPlugin {
|
|
3824
3980
|
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3825
3981
|
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3826
3982
|
getBulkActions: () => this.bulkActions,
|
3827
|
-
getDocumentActions: () =>
|
3983
|
+
getDocumentActions: (position) => {
|
3984
|
+
if (position) {
|
3985
|
+
return this.documentActions.filter(
|
3986
|
+
(action) => action.position == void 0 || [action.position].flat().includes(position)
|
3987
|
+
);
|
3988
|
+
}
|
3989
|
+
return this.documentActions;
|
3990
|
+
},
|
3828
3991
|
getEditViewSidePanels: () => this.editViewSidePanels,
|
3829
3992
|
getHeaderActions: () => this.headerActions
|
3830
3993
|
}
|
@@ -3834,10 +3997,8 @@ class ContentManagerPlugin {
|
|
3834
3997
|
const getPrintableType = (value) => {
|
3835
3998
|
const nativeType = typeof value;
|
3836
3999
|
if (nativeType === "object") {
|
3837
|
-
if (value === null)
|
3838
|
-
|
3839
|
-
if (Array.isArray(value))
|
3840
|
-
return "array";
|
4000
|
+
if (value === null) return "null";
|
4001
|
+
if (Array.isArray(value)) return "array";
|
3841
4002
|
if (value instanceof Object && value.constructor.name !== "Object") {
|
3842
4003
|
return value.constructor.name;
|
3843
4004
|
}
|
@@ -3848,17 +4009,27 @@ const HistoryAction = ({ model, document }) => {
|
|
3848
4009
|
const { formatMessage } = useIntl();
|
3849
4010
|
const [{ query }] = useQueryParams();
|
3850
4011
|
const navigate = useNavigate();
|
4012
|
+
const { trackUsage } = useTracking();
|
4013
|
+
const { pathname } = useLocation();
|
3851
4014
|
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
3852
4015
|
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3853
4016
|
return null;
|
3854
4017
|
}
|
4018
|
+
const handleOnClick = () => {
|
4019
|
+
const destination = { pathname: "history", search: pluginsQueryParams };
|
4020
|
+
trackUsage("willNavigate", {
|
4021
|
+
from: pathname,
|
4022
|
+
to: `${pathname}/${destination.pathname}`
|
4023
|
+
});
|
4024
|
+
navigate(destination);
|
4025
|
+
};
|
3855
4026
|
return {
|
3856
4027
|
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
3857
4028
|
label: formatMessage({
|
3858
4029
|
id: "content-manager.history.document-action",
|
3859
4030
|
defaultMessage: "Content History"
|
3860
4031
|
}),
|
3861
|
-
onClick:
|
4032
|
+
onClick: handleOnClick,
|
3862
4033
|
disabled: (
|
3863
4034
|
/**
|
3864
4035
|
* The user is creating a new document.
|
@@ -3880,6 +4051,7 @@ const HistoryAction = ({ model, document }) => {
|
|
3880
4051
|
};
|
3881
4052
|
};
|
3882
4053
|
HistoryAction.type = "history";
|
4054
|
+
HistoryAction.position = "header";
|
3883
4055
|
const historyAdmin = {
|
3884
4056
|
bootstrap(app) {
|
3885
4057
|
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
@@ -3926,6 +4098,88 @@ const { setInitialData } = actions;
|
|
3926
4098
|
const reducer = combineReducers({
|
3927
4099
|
app: reducer$1
|
3928
4100
|
});
|
4101
|
+
const previewApi = contentManagerApi.injectEndpoints({
|
4102
|
+
endpoints: (builder) => ({
|
4103
|
+
getPreviewUrl: builder.query({
|
4104
|
+
query({ query, params }) {
|
4105
|
+
return {
|
4106
|
+
url: `/content-manager/preview/url/${params.contentType}`,
|
4107
|
+
method: "GET",
|
4108
|
+
config: {
|
4109
|
+
params: query
|
4110
|
+
}
|
4111
|
+
};
|
4112
|
+
}
|
4113
|
+
})
|
4114
|
+
})
|
4115
|
+
});
|
4116
|
+
const { useGetPreviewUrlQuery } = previewApi;
|
4117
|
+
const ConditionalTooltip = ({ isShown, label, children }) => {
|
4118
|
+
if (isShown) {
|
4119
|
+
return /* @__PURE__ */ jsx(Tooltip, { label, children });
|
4120
|
+
}
|
4121
|
+
return children;
|
4122
|
+
};
|
4123
|
+
const PreviewSidePanel = ({ model, documentId, document }) => {
|
4124
|
+
const { formatMessage } = useIntl();
|
4125
|
+
const { trackUsage } = useTracking();
|
4126
|
+
const { pathname } = useLocation();
|
4127
|
+
const [{ query }] = useQueryParams();
|
4128
|
+
const isModified = useForm("PreviewSidePanel", (state) => state.modified);
|
4129
|
+
const { data, error } = useGetPreviewUrlQuery({
|
4130
|
+
params: {
|
4131
|
+
contentType: model
|
4132
|
+
},
|
4133
|
+
query: {
|
4134
|
+
documentId,
|
4135
|
+
locale: document?.locale,
|
4136
|
+
status: document?.status
|
4137
|
+
}
|
4138
|
+
});
|
4139
|
+
if (!data?.data?.url || error) {
|
4140
|
+
return null;
|
4141
|
+
}
|
4142
|
+
const trackNavigation = () => {
|
4143
|
+
const destinationPathname = pathname.replace(/\/$/, "") + "/preview";
|
4144
|
+
trackUsage("willNavigate", { from: pathname, to: destinationPathname });
|
4145
|
+
};
|
4146
|
+
return {
|
4147
|
+
title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
|
4148
|
+
content: /* @__PURE__ */ jsx(
|
4149
|
+
ConditionalTooltip,
|
4150
|
+
{
|
4151
|
+
label: formatMessage({
|
4152
|
+
id: "content-manager.preview.panel.button-disabled-tooltip",
|
4153
|
+
defaultMessage: "Please save to open the preview"
|
4154
|
+
}),
|
4155
|
+
isShown: isModified,
|
4156
|
+
children: /* @__PURE__ */ jsx(Box, { cursor: "not-allowed", width: "100%", children: /* @__PURE__ */ jsx(
|
4157
|
+
Button,
|
4158
|
+
{
|
4159
|
+
variant: "tertiary",
|
4160
|
+
tag: Link,
|
4161
|
+
to: { pathname: "preview", search: stringify(query, { encode: false }) },
|
4162
|
+
onClick: trackNavigation,
|
4163
|
+
width: "100%",
|
4164
|
+
disabled: isModified,
|
4165
|
+
pointerEvents: isModified ? "none" : void 0,
|
4166
|
+
tabIndex: isModified ? -1 : void 0,
|
4167
|
+
children: formatMessage({
|
4168
|
+
id: "content-manager.preview.panel.button",
|
4169
|
+
defaultMessage: "Open preview"
|
4170
|
+
})
|
4171
|
+
}
|
4172
|
+
) })
|
4173
|
+
}
|
4174
|
+
)
|
4175
|
+
};
|
4176
|
+
};
|
4177
|
+
const previewAdmin = {
|
4178
|
+
bootstrap(app) {
|
4179
|
+
const contentManagerPluginApis = app.getPlugin("content-manager").apis;
|
4180
|
+
contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
|
4181
|
+
}
|
4182
|
+
};
|
3929
4183
|
const index = {
|
3930
4184
|
register(app) {
|
3931
4185
|
const cm = new ContentManagerPlugin();
|
@@ -3945,7 +4199,7 @@ const index = {
|
|
3945
4199
|
app.router.addRoute({
|
3946
4200
|
path: "content-manager/*",
|
3947
4201
|
lazy: async () => {
|
3948
|
-
const { Layout } = await import("./layout-
|
4202
|
+
const { Layout } = await import("./layout-W3clJSCy.mjs");
|
3949
4203
|
return {
|
3950
4204
|
Component: Layout
|
3951
4205
|
};
|
@@ -3958,11 +4212,14 @@ const index = {
|
|
3958
4212
|
if (typeof historyAdmin.bootstrap === "function") {
|
3959
4213
|
historyAdmin.bootstrap(app);
|
3960
4214
|
}
|
4215
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
4216
|
+
previewAdmin.bootstrap(app);
|
4217
|
+
}
|
3961
4218
|
},
|
3962
4219
|
async registerTrads({ locales }) {
|
3963
4220
|
const importedTrads = await Promise.all(
|
3964
4221
|
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-
|
4222
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-CSxLmrh1.mjs"), "./translations/es.json": () => import("./es-D34tqjMw.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr--pg5jUbt.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-BHqhDq4V.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
|
3966
4223
|
return {
|
3967
4224
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3968
4225
|
locale
|
@@ -3989,8 +4246,10 @@ export {
|
|
3989
4246
|
HOOKS as H,
|
3990
4247
|
InjectionZone as I,
|
3991
4248
|
useDocument as J,
|
3992
|
-
|
3993
|
-
|
4249
|
+
useGetPreviewUrlQuery as K,
|
4250
|
+
index as L,
|
4251
|
+
useContentManagerContext as M,
|
4252
|
+
useDocumentActions as N,
|
3994
4253
|
Panels as P,
|
3995
4254
|
RelativeTime as R,
|
3996
4255
|
SINGLE_TYPES as S,
|
@@ -4022,4 +4281,4 @@ export {
|
|
4022
4281
|
capitalise as y,
|
4023
4282
|
useUpdateContentTypeConfigurationMutation as z
|
4024
4283
|
};
|
4025
|
-
//# sourceMappingURL=index-
|
4284
|
+
//# sourceMappingURL=index-DqasUQ6Q.mjs.map
|