@strapi/content-manager 0.0.0-experimental.145e7d7ddefd1aef71aaf3d9bb86440d013035bf → 0.0.0-experimental.15989d13d8be058bf37afc84b7a8377ef1da3263
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-D_g11bYV.js → ComponentConfigurationPage-BSEZcJVB.js} +5 -6
- package/dist/_chunks/{ComponentConfigurationPage-D_g11bYV.js.map → ComponentConfigurationPage-BSEZcJVB.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DJEJ49QD.mjs → ComponentConfigurationPage-BiASGi7x.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-DJEJ49QD.mjs.map → ComponentConfigurationPage-BiASGi7x.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-CeL712KW.js → EditConfigurationPage-D2rtvneE.js} +5 -6
- package/dist/_chunks/{EditConfigurationPage-CeL712KW.js.map → EditConfigurationPage-D2rtvneE.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-QBZdUYyG.mjs → EditConfigurationPage-vN4zupij.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-QBZdUYyG.mjs.map → EditConfigurationPage-vN4zupij.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-g5TwrgRY.js → EditViewPage-BwisF04Q.js} +50 -11
- package/dist/_chunks/EditViewPage-BwisF04Q.js.map +1 -0
- package/dist/_chunks/{EditViewPage-CvRUUpVh.mjs → EditViewPage-_A31Cl4g.mjs} +50 -10
- package/dist/_chunks/EditViewPage-_A31Cl4g.mjs.map +1 -0
- package/dist/_chunks/{Field-reyvfnop.mjs → Field-CvIunNOj.mjs} +238 -152
- package/dist/_chunks/Field-CvIunNOj.mjs.map +1 -0
- package/dist/_chunks/{Field-ncdInvxS.js → Field-Dsu6-FrM.js} +244 -158
- package/dist/_chunks/Field-Dsu6-FrM.js.map +1 -0
- package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
- package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
- package/dist/_chunks/{Form-DoMGsYxH.mjs → Form-DK0fG0Gj.mjs} +15 -9
- package/dist/_chunks/Form-DK0fG0Gj.mjs.map +1 -0
- package/dist/_chunks/{Form-BJ7bYiUx.js → Form-DUwWcCmA.js} +17 -12
- package/dist/_chunks/Form-DUwWcCmA.js.map +1 -0
- package/dist/_chunks/{History-pbhkxIrf.js → History-CeCDhoJG.js} +42 -100
- package/dist/_chunks/History-CeCDhoJG.js.map +1 -0
- package/dist/_chunks/{History-BseDJOrj.mjs → History-DP8gmXpm.mjs} +43 -100
- package/dist/_chunks/History-DP8gmXpm.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DWE_fr5B.mjs → ListConfigurationPage-BCkO5iuN.mjs} +7 -6
- package/dist/_chunks/ListConfigurationPage-BCkO5iuN.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Bna8zfjr.js → ListConfigurationPage-C-bAd44a.js} +7 -7
- package/dist/_chunks/ListConfigurationPage-C-bAd44a.js.map +1 -0
- package/dist/_chunks/{ListViewPage-Dymsvnv6.js → ListViewPage-BKTZFhsM.js} +88 -54
- package/dist/_chunks/ListViewPage-BKTZFhsM.js.map +1 -0
- package/dist/_chunks/{ListViewPage-lQ-VLV2G.mjs → ListViewPage-Cf_DgaFV.mjs} +83 -48
- package/dist/_chunks/ListViewPage-Cf_DgaFV.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-B4t_OsDR.js → NoContentTypePage-D3Cm3v3q.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-B4t_OsDR.js.map → NoContentTypePage-D3Cm3v3q.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-VCQOMwlf.mjs → NoContentTypePage-nHIyvJcB.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-VCQOMwlf.mjs.map → NoContentTypePage-nHIyvJcB.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-TV830k4P.mjs → NoPermissionsPage-BALVSJ7x.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-TV830k4P.mjs.map → NoPermissionsPage-BALVSJ7x.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BOwB6hki.js → NoPermissionsPage-CChGWBj5.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BOwB6hki.js.map → NoPermissionsPage-CChGWBj5.js.map} +1 -1
- package/dist/_chunks/Preview-C4NBzKUV.mjs +294 -0
- package/dist/_chunks/Preview-C4NBzKUV.mjs.map +1 -0
- package/dist/_chunks/Preview-CT28Ckpg.js +312 -0
- package/dist/_chunks/Preview-CT28Ckpg.js.map +1 -0
- package/dist/_chunks/{Relations-D6NAlnsl.mjs → Relations-C8uC89cT.mjs} +75 -41
- package/dist/_chunks/Relations-C8uC89cT.mjs.map +1 -0
- package/dist/_chunks/{Relations-DdlstXTu.js → Relations-CvkPCng_.js} +75 -42
- package/dist/_chunks/Relations-CvkPCng_.js.map +1 -0
- package/dist/_chunks/{en-Cf41pH5f.js → en-BK8Xyl5I.js} +24 -12
- package/dist/_chunks/{en-Cf41pH5f.js.map → en-BK8Xyl5I.js.map} +1 -1
- package/dist/_chunks/{en-DCszE74t.mjs → en-Dtk_ot79.mjs} +24 -12
- package/dist/_chunks/{en-DCszE74t.mjs.map → en-Dtk_ot79.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-CQos-KS0.js → index-CnX_j5h-.js} +1239 -942
- package/dist/_chunks/index-CnX_j5h-.js.map +1 -0
- package/dist/_chunks/{index-BYSWwHBJ.mjs → index-Dh2aGTGJ.mjs} +1241 -944
- package/dist/_chunks/index-Dh2aGTGJ.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-0TY7UtKO.mjs → layout-B5qsPihj.mjs} +6 -5
- package/dist/_chunks/{layout-0TY7UtKO.mjs.map → layout-B5qsPihj.mjs.map} +1 -1
- package/dist/_chunks/{layout-B4XAqu1v.js → layout-B_qdWGny.js} +7 -7
- package/dist/_chunks/{layout-B4XAqu1v.js.map → layout-B_qdWGny.js.map} +1 -1
- package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
- package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
- package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
- package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
- package/dist/_chunks/{relations-xZ2tMj1G.js → relations-ChcieiF5.js} +6 -7
- package/dist/_chunks/relations-ChcieiF5.js.map +1 -0
- package/dist/_chunks/{relations-DFDWfa0s.mjs → relations-DMXpNY-e.mjs} +6 -7
- package/dist/_chunks/relations-DMXpNY-e.mjs.map +1 -0
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
- package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +4 -3
- package/dist/admin/src/content-manager.d.ts +3 -2
- package/dist/admin/src/exports.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 +2 -2
- 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/Header.d.ts +11 -11
- package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
- package/dist/admin/src/preview/index.d.ts +4 -0
- package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
- package/dist/admin/src/preview/routes.d.ts +3 -0
- package/dist/admin/src/preview/services/preview.d.ts +3 -0
- package/dist/admin/src/router.d.ts +1 -1
- package/dist/admin/src/services/documents.d.ts +0 -3
- package/dist/server/index.js +513 -260
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +514 -260
- 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/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 +2 -3
- 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 +17 -15
- package/dist/_chunks/EditViewPage-CvRUUpVh.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-g5TwrgRY.js.map +0 -1
- package/dist/_chunks/Field-ncdInvxS.js.map +0 -1
- package/dist/_chunks/Field-reyvfnop.mjs.map +0 -1
- package/dist/_chunks/Form-BJ7bYiUx.js.map +0 -1
- package/dist/_chunks/Form-DoMGsYxH.mjs.map +0 -1
- package/dist/_chunks/History-BseDJOrj.mjs.map +0 -1
- package/dist/_chunks/History-pbhkxIrf.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Bna8zfjr.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DWE_fr5B.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-Dymsvnv6.js.map +0 -1
- package/dist/_chunks/ListViewPage-lQ-VLV2G.mjs.map +0 -1
- package/dist/_chunks/Relations-D6NAlnsl.mjs.map +0 -1
- package/dist/_chunks/Relations-DdlstXTu.js.map +0 -1
- package/dist/_chunks/index-BYSWwHBJ.mjs.map +0 -1
- package/dist/_chunks/index-CQos-KS0.js.map +0 -1
- package/dist/_chunks/relations-DFDWfa0s.mjs.map +0 -1
- package/dist/_chunks/relations-xZ2tMj1G.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
@@ -1,25 +1,33 @@
|
|
1
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) : [];
|
@@ -211,7 +227,19 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
211
227
|
{ type: "Document", id: `${model}_LIST` },
|
212
228
|
"Relations",
|
213
229
|
{ type: "UidAvailability", id: model }
|
214
|
-
]
|
230
|
+
],
|
231
|
+
transformResponse: (response, meta, arg) => {
|
232
|
+
if (!("data" in response) && arg.model === "plugin::users-permissions.user") {
|
233
|
+
return {
|
234
|
+
data: response,
|
235
|
+
meta: {
|
236
|
+
availableStatus: [],
|
237
|
+
availableLocales: []
|
238
|
+
}
|
239
|
+
};
|
240
|
+
}
|
241
|
+
return response;
|
242
|
+
}
|
215
243
|
}),
|
216
244
|
deleteDocument: builder.mutation({
|
217
245
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -265,7 +293,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
265
293
|
url: `/content-manager/collection-types/${model}`,
|
266
294
|
method: "GET",
|
267
295
|
config: {
|
268
|
-
params
|
296
|
+
params: stringify(params, { encode: true })
|
269
297
|
}
|
270
298
|
}),
|
271
299
|
providesTags: (result, _error, arg) => {
|
@@ -444,8 +472,7 @@ const {
|
|
444
472
|
useUnpublishManyDocumentsMutation
|
445
473
|
} = documentApi;
|
446
474
|
const buildValidParams = (query) => {
|
447
|
-
if (!query)
|
448
|
-
return query;
|
475
|
+
if (!query) return query;
|
449
476
|
const { plugins: _, ...validQueryParams } = {
|
450
477
|
...query,
|
451
478
|
...Object.values(query?.plugins ?? {}).reduce(
|
@@ -453,14 +480,29 @@ const buildValidParams = (query) => {
|
|
453
480
|
{}
|
454
481
|
)
|
455
482
|
};
|
456
|
-
if ("_q" in validQueryParams) {
|
457
|
-
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
458
|
-
}
|
459
483
|
return validQueryParams;
|
460
484
|
};
|
461
485
|
const isBaseQueryError = (error) => {
|
462
486
|
return error.name !== void 0;
|
463
487
|
};
|
488
|
+
const arrayValidator = (attribute, options) => ({
|
489
|
+
message: translatedErrors.required,
|
490
|
+
test(value) {
|
491
|
+
if (options.status === "draft") {
|
492
|
+
return true;
|
493
|
+
}
|
494
|
+
if (!attribute.required) {
|
495
|
+
return true;
|
496
|
+
}
|
497
|
+
if (!value) {
|
498
|
+
return false;
|
499
|
+
}
|
500
|
+
if (Array.isArray(value) && value.length === 0) {
|
501
|
+
return false;
|
502
|
+
}
|
503
|
+
return true;
|
504
|
+
}
|
505
|
+
});
|
464
506
|
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
465
507
|
const createModelSchema = (attributes2) => yup.object().shape(
|
466
508
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
@@ -468,6 +510,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
468
510
|
return acc;
|
469
511
|
}
|
470
512
|
const validations = [
|
513
|
+
addNullableValidation,
|
471
514
|
addRequiredValidation,
|
472
515
|
addMinLengthValidation,
|
473
516
|
addMaxLengthValidation,
|
@@ -484,12 +527,12 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
484
527
|
...acc,
|
485
528
|
[name]: transformSchema(
|
486
529
|
yup.array().of(createModelSchema(attributes3).nullable(false))
|
487
|
-
)
|
530
|
+
).test(arrayValidator(attribute, options))
|
488
531
|
};
|
489
532
|
} else {
|
490
533
|
return {
|
491
534
|
...acc,
|
492
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
535
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
493
536
|
};
|
494
537
|
}
|
495
538
|
}
|
@@ -511,7 +554,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
511
554
|
}
|
512
555
|
)
|
513
556
|
)
|
514
|
-
)
|
557
|
+
).test(arrayValidator(attribute, options))
|
515
558
|
};
|
516
559
|
case "relation":
|
517
560
|
return {
|
@@ -523,7 +566,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
523
566
|
} else if (Array.isArray(value)) {
|
524
567
|
return yup.array().of(
|
525
568
|
yup.object().shape({
|
526
|
-
id: yup.
|
569
|
+
id: yup.number().required()
|
527
570
|
})
|
528
571
|
);
|
529
572
|
} else if (typeof value === "object") {
|
@@ -609,17 +652,17 @@ const nullableSchema = (schema) => {
|
|
609
652
|
schema
|
610
653
|
);
|
611
654
|
};
|
655
|
+
const addNullableValidation = () => (schema) => {
|
656
|
+
return nullableSchema(schema);
|
657
|
+
};
|
612
658
|
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);
|
659
|
+
if (options.status === "draft" || !attribute.required) {
|
660
|
+
return schema;
|
618
661
|
}
|
619
|
-
if (attribute.required &&
|
662
|
+
if (attribute.required && "required" in schema) {
|
620
663
|
return schema.required(translatedErrors.required);
|
621
664
|
}
|
622
|
-
return
|
665
|
+
return schema;
|
623
666
|
};
|
624
667
|
const addMinLengthValidation = (attribute, options) => (schema) => {
|
625
668
|
if (options.status === "draft") {
|
@@ -647,31 +690,12 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
647
690
|
return schema;
|
648
691
|
};
|
649
692
|
const addMinValidation = (attribute, options) => (schema) => {
|
650
|
-
if ("
|
693
|
+
if (options.status === "draft") {
|
694
|
+
return schema;
|
695
|
+
}
|
696
|
+
if ("min" in attribute && "min" in schema) {
|
651
697
|
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) {
|
698
|
+
if (min) {
|
675
699
|
return schema.min(min, {
|
676
700
|
...translatedErrors.min,
|
677
701
|
values: {
|
@@ -789,19 +813,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
789
813
|
}, {});
|
790
814
|
return componentsByKey;
|
791
815
|
};
|
792
|
-
const
|
816
|
+
const HOOKS = {
|
817
|
+
/**
|
818
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
819
|
+
* @constant
|
820
|
+
* @type {string}
|
821
|
+
*/
|
822
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
823
|
+
/**
|
824
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
825
|
+
* @constant
|
826
|
+
* @type {string}
|
827
|
+
*/
|
828
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
829
|
+
/**
|
830
|
+
* Hook that allows to mutate the CM's edit view layout
|
831
|
+
* @constant
|
832
|
+
* @type {string}
|
833
|
+
*/
|
834
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
835
|
+
/**
|
836
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
837
|
+
* @constant
|
838
|
+
* @type {string}
|
839
|
+
*/
|
840
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
841
|
+
};
|
842
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
843
|
+
endpoints: (builder) => ({
|
844
|
+
getContentTypeConfiguration: builder.query({
|
845
|
+
query: (uid) => ({
|
846
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
847
|
+
method: "GET"
|
848
|
+
}),
|
849
|
+
transformResponse: (response) => response.data,
|
850
|
+
providesTags: (_result, _error, uid) => [
|
851
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
852
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
853
|
+
]
|
854
|
+
}),
|
855
|
+
getAllContentTypeSettings: builder.query({
|
856
|
+
query: () => "/content-manager/content-types-settings",
|
857
|
+
transformResponse: (response) => response.data,
|
858
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
859
|
+
}),
|
860
|
+
updateContentTypeConfiguration: builder.mutation({
|
861
|
+
query: ({ uid, ...body }) => ({
|
862
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
863
|
+
method: "PUT",
|
864
|
+
data: body
|
865
|
+
}),
|
866
|
+
transformResponse: (response) => response.data,
|
867
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
868
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
869
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
870
|
+
// Is this necessary?
|
871
|
+
{ type: "InitialData" }
|
872
|
+
]
|
873
|
+
})
|
874
|
+
})
|
875
|
+
});
|
876
|
+
const {
|
877
|
+
useGetContentTypeConfigurationQuery,
|
878
|
+
useGetAllContentTypeSettingsQuery,
|
879
|
+
useUpdateContentTypeConfigurationMutation
|
880
|
+
} = contentTypesApi;
|
881
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
882
|
+
const { type } = attribute;
|
883
|
+
if (type === "relation") {
|
884
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
885
|
+
}
|
886
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
887
|
+
};
|
888
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
889
|
+
if (!mainFieldName) {
|
890
|
+
return void 0;
|
891
|
+
}
|
892
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
893
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
894
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
895
|
+
);
|
896
|
+
return {
|
897
|
+
name: mainFieldName,
|
898
|
+
type: mainFieldType ?? "string"
|
899
|
+
};
|
900
|
+
};
|
901
|
+
const DEFAULT_SETTINGS = {
|
902
|
+
bulkable: false,
|
903
|
+
filterable: false,
|
904
|
+
searchable: false,
|
905
|
+
pagination: false,
|
906
|
+
defaultSortBy: "",
|
907
|
+
defaultSortOrder: "asc",
|
908
|
+
mainField: "id",
|
909
|
+
pageSize: 10
|
910
|
+
};
|
911
|
+
const useDocumentLayout = (model) => {
|
912
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
913
|
+
const [{ query }] = useQueryParams();
|
914
|
+
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
793
915
|
const { toggleNotification } = useNotification();
|
794
916
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
917
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
795
918
|
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);
|
919
|
+
data,
|
920
|
+
isLoading: isLoadingConfigs,
|
921
|
+
error,
|
922
|
+
isFetching: isFetchingConfigs
|
923
|
+
} = useGetContentTypeConfigurationQuery(model);
|
924
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
805
925
|
React.useEffect(() => {
|
806
926
|
if (error) {
|
807
927
|
toggleNotification({
|
@@ -809,363 +929,438 @@ const useDocument = (args, opts) => {
|
|
809
929
|
message: formatAPIError(error)
|
810
930
|
});
|
811
931
|
}
|
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
|
-
}
|
932
|
+
}, [error, formatAPIError, toggleNotification]);
|
933
|
+
const editLayout = React.useMemo(
|
934
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
935
|
+
layout: [],
|
936
|
+
components: {},
|
937
|
+
metadatas: {},
|
938
|
+
options: {},
|
939
|
+
settings: DEFAULT_SETTINGS
|
835
940
|
},
|
836
|
-
[
|
941
|
+
[data, isLoading, schemas, schema, components]
|
942
|
+
);
|
943
|
+
const listLayout = React.useMemo(() => {
|
944
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
945
|
+
layout: [],
|
946
|
+
metadatas: {},
|
947
|
+
options: {},
|
948
|
+
settings: DEFAULT_SETTINGS
|
949
|
+
};
|
950
|
+
}, [data, isLoading, schemas, schema, components]);
|
951
|
+
const { layout: edit } = React.useMemo(
|
952
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
953
|
+
layout: editLayout,
|
954
|
+
query
|
955
|
+
}),
|
956
|
+
[editLayout, query, runHookWaterfall]
|
837
957
|
);
|
838
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
839
958
|
return {
|
840
|
-
|
841
|
-
document: data?.data,
|
842
|
-
meta: data?.meta,
|
959
|
+
error,
|
843
960
|
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
|
-
)
|
961
|
+
edit,
|
962
|
+
list: listLayout
|
868
963
|
};
|
869
964
|
};
|
870
|
-
const
|
871
|
-
|
872
|
-
|
873
|
-
}
|
874
|
-
return Object.keys(trad).reduce((acc, current) => {
|
875
|
-
acc[`${pluginId}.${current}`] = trad[current];
|
876
|
-
return acc;
|
877
|
-
}, {});
|
878
|
-
};
|
879
|
-
const getTranslation = (id) => `content-manager.${id}`;
|
880
|
-
const DEFAULT_UNEXPECTED_ERROR_MSG = {
|
881
|
-
id: "notification.error",
|
882
|
-
defaultMessage: "An error occurred, please try again"
|
965
|
+
const useDocLayout = () => {
|
966
|
+
const { model } = useDoc();
|
967
|
+
return useDocumentLayout(model);
|
883
968
|
};
|
884
|
-
const
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
const
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
});
|
906
|
-
return { error: res.error };
|
907
|
-
}
|
908
|
-
toggleNotification({
|
909
|
-
type: "success",
|
910
|
-
message: formatMessage({
|
911
|
-
id: getTranslation("success.record.delete"),
|
912
|
-
defaultMessage: "Deleted document"
|
913
|
-
})
|
914
|
-
});
|
915
|
-
trackUsage("didDeleteEntry", trackerProperty);
|
916
|
-
return res.data;
|
917
|
-
} catch (err) {
|
918
|
-
toggleNotification({
|
919
|
-
type: "danger",
|
920
|
-
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
921
|
-
});
|
922
|
-
trackUsage("didNotDeleteEntry", { error: err, ...trackerProperty });
|
923
|
-
throw err;
|
969
|
+
const formatEditLayout = (data, {
|
970
|
+
schemas,
|
971
|
+
schema,
|
972
|
+
components
|
973
|
+
}) => {
|
974
|
+
let currentPanelIndex = 0;
|
975
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
976
|
+
data.contentType.layouts.edit,
|
977
|
+
schema?.attributes,
|
978
|
+
data.contentType.metadatas,
|
979
|
+
{ configurations: data.components, schemas: components },
|
980
|
+
schemas
|
981
|
+
).reduce((panels, row) => {
|
982
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
983
|
+
panels.push([row]);
|
984
|
+
currentPanelIndex += 2;
|
985
|
+
} else {
|
986
|
+
if (!panels[currentPanelIndex]) {
|
987
|
+
panels.push([row]);
|
988
|
+
} else {
|
989
|
+
panels[currentPanelIndex].push(row);
|
924
990
|
}
|
925
|
-
}
|
926
|
-
|
927
|
-
);
|
928
|
-
const
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
message: formatAPIError(res.error)
|
942
|
-
});
|
943
|
-
return { error: res.error };
|
991
|
+
}
|
992
|
+
return panels;
|
993
|
+
}, []);
|
994
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
995
|
+
(acc, [uid, configuration]) => {
|
996
|
+
acc[uid] = {
|
997
|
+
layout: convertEditLayoutToFieldLayouts(
|
998
|
+
configuration.layouts.edit,
|
999
|
+
components[uid].attributes,
|
1000
|
+
configuration.metadatas,
|
1001
|
+
{ configurations: data.components, schemas: components }
|
1002
|
+
),
|
1003
|
+
settings: {
|
1004
|
+
...configuration.settings,
|
1005
|
+
icon: components[uid].info.icon,
|
1006
|
+
displayName: components[uid].info.displayName
|
944
1007
|
}
|
945
|
-
|
946
|
-
|
947
|
-
title: formatMessage({
|
948
|
-
id: getTranslation("success.records.delete"),
|
949
|
-
defaultMessage: "Successfully deleted."
|
950
|
-
}),
|
951
|
-
message: ""
|
952
|
-
});
|
953
|
-
trackUsage("didBulkDeleteEntries");
|
954
|
-
return res.data;
|
955
|
-
} catch (err) {
|
956
|
-
toggleNotification({
|
957
|
-
type: "danger",
|
958
|
-
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
959
|
-
});
|
960
|
-
trackUsage("didNotBulkDeleteEntries");
|
961
|
-
throw err;
|
962
|
-
}
|
1008
|
+
};
|
1009
|
+
return acc;
|
963
1010
|
},
|
964
|
-
|
1011
|
+
{}
|
965
1012
|
);
|
966
|
-
const
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
model,
|
973
|
-
documentId,
|
974
|
-
params
|
975
|
-
});
|
976
|
-
if ("error" in res) {
|
977
|
-
toggleNotification({
|
978
|
-
type: "danger",
|
979
|
-
message: formatAPIError(res.error)
|
980
|
-
});
|
981
|
-
return { error: res.error };
|
982
|
-
}
|
983
|
-
toggleNotification({
|
984
|
-
type: "success",
|
985
|
-
message: formatMessage({
|
986
|
-
id: "content-manager.success.record.discard",
|
987
|
-
defaultMessage: "Changes discarded"
|
988
|
-
})
|
989
|
-
});
|
990
|
-
return res.data;
|
991
|
-
} catch (err) {
|
992
|
-
toggleNotification({
|
993
|
-
type: "danger",
|
994
|
-
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
995
|
-
});
|
996
|
-
throw err;
|
997
|
-
}
|
1013
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1014
|
+
(acc, [attribute, metadata]) => {
|
1015
|
+
return {
|
1016
|
+
...acc,
|
1017
|
+
[attribute]: metadata.edit
|
1018
|
+
};
|
998
1019
|
},
|
999
|
-
|
1020
|
+
{}
|
1000
1021
|
);
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
defaultMessage: "Published document"
|
1023
|
-
})
|
1024
|
-
});
|
1025
|
-
return res.data;
|
1026
|
-
} catch (err) {
|
1027
|
-
toggleNotification({
|
1028
|
-
type: "danger",
|
1029
|
-
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1030
|
-
});
|
1031
|
-
throw err;
|
1022
|
+
return {
|
1023
|
+
layout: panelledEditAttributes,
|
1024
|
+
components: componentEditAttributes,
|
1025
|
+
metadatas: editMetadatas,
|
1026
|
+
settings: {
|
1027
|
+
...data.contentType.settings,
|
1028
|
+
displayName: schema?.info.displayName
|
1029
|
+
},
|
1030
|
+
options: {
|
1031
|
+
...schema?.options,
|
1032
|
+
...schema?.pluginOptions,
|
1033
|
+
...data.contentType.options
|
1034
|
+
}
|
1035
|
+
};
|
1036
|
+
};
|
1037
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1038
|
+
return rows.map(
|
1039
|
+
(row) => row.map((field) => {
|
1040
|
+
const attribute = attributes[field.name];
|
1041
|
+
if (!attribute) {
|
1042
|
+
return null;
|
1032
1043
|
}
|
1044
|
+
const { edit: metadata } = metadatas[field.name];
|
1045
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1046
|
+
return {
|
1047
|
+
attribute,
|
1048
|
+
disabled: !metadata.editable,
|
1049
|
+
hint: metadata.description,
|
1050
|
+
label: metadata.label ?? "",
|
1051
|
+
name: field.name,
|
1052
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1053
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1054
|
+
schemas,
|
1055
|
+
components: components?.schemas ?? {}
|
1056
|
+
}),
|
1057
|
+
placeholder: metadata.placeholder ?? "",
|
1058
|
+
required: attribute.required ?? false,
|
1059
|
+
size: field.size,
|
1060
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1061
|
+
visible: metadata.visible ?? true,
|
1062
|
+
type: attribute.type
|
1063
|
+
};
|
1064
|
+
}).filter((field) => field !== null)
|
1065
|
+
);
|
1066
|
+
};
|
1067
|
+
const formatListLayout = (data, {
|
1068
|
+
schemas,
|
1069
|
+
schema,
|
1070
|
+
components
|
1071
|
+
}) => {
|
1072
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1073
|
+
(acc, [attribute, metadata]) => {
|
1074
|
+
return {
|
1075
|
+
...acc,
|
1076
|
+
[attribute]: metadata.list
|
1077
|
+
};
|
1033
1078
|
},
|
1034
|
-
|
1079
|
+
{}
|
1035
1080
|
);
|
1036
|
-
const
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1081
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1082
|
+
data.contentType.layouts.list,
|
1083
|
+
schema?.attributes,
|
1084
|
+
listMetadatas,
|
1085
|
+
{ configurations: data.components, schemas: components },
|
1086
|
+
schemas
|
1087
|
+
);
|
1088
|
+
return {
|
1089
|
+
layout: listAttributes,
|
1090
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1091
|
+
metadatas: listMetadatas,
|
1092
|
+
options: {
|
1093
|
+
...schema?.options,
|
1094
|
+
...schema?.pluginOptions,
|
1095
|
+
...data.contentType.options
|
1096
|
+
}
|
1097
|
+
};
|
1098
|
+
};
|
1099
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1100
|
+
return columns.map((name) => {
|
1101
|
+
const attribute = attributes[name];
|
1102
|
+
if (!attribute) {
|
1103
|
+
return null;
|
1104
|
+
}
|
1105
|
+
const metadata = metadatas[name];
|
1106
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1107
|
+
return {
|
1108
|
+
attribute,
|
1109
|
+
label: metadata.label ?? "",
|
1110
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1111
|
+
schemas,
|
1112
|
+
components: components?.schemas ?? {}
|
1113
|
+
}),
|
1114
|
+
name,
|
1115
|
+
searchable: metadata.searchable ?? true,
|
1116
|
+
sortable: metadata.sortable ?? true
|
1117
|
+
};
|
1118
|
+
}).filter((field) => field !== null);
|
1119
|
+
};
|
1120
|
+
const useDocument = (args, opts) => {
|
1121
|
+
const { toggleNotification } = useNotification();
|
1122
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1123
|
+
const {
|
1124
|
+
currentData: data,
|
1125
|
+
isLoading: isLoadingDocument,
|
1126
|
+
isFetching: isFetchingDocument,
|
1127
|
+
error
|
1128
|
+
} = useGetDocumentQuery(args, {
|
1129
|
+
...opts,
|
1130
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1131
|
+
});
|
1132
|
+
const {
|
1133
|
+
components,
|
1134
|
+
schema,
|
1135
|
+
schemas,
|
1136
|
+
isLoading: isLoadingSchema
|
1137
|
+
} = useContentTypeSchema(args.model);
|
1138
|
+
React.useEffect(() => {
|
1139
|
+
if (error) {
|
1140
|
+
toggleNotification({
|
1141
|
+
type: "danger",
|
1142
|
+
message: formatAPIError(error)
|
1143
|
+
});
|
1144
|
+
}
|
1145
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1146
|
+
const validationSchema = React.useMemo(() => {
|
1147
|
+
if (!schema) {
|
1148
|
+
return null;
|
1149
|
+
}
|
1150
|
+
return createYupSchema(schema.attributes, components);
|
1151
|
+
}, [schema, components]);
|
1152
|
+
const validate = React.useCallback(
|
1153
|
+
(document) => {
|
1154
|
+
if (!validationSchema) {
|
1155
|
+
throw new Error(
|
1156
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1157
|
+
);
|
1158
|
+
}
|
1159
|
+
try {
|
1160
|
+
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
1161
|
+
return null;
|
1162
|
+
} catch (error2) {
|
1163
|
+
if (error2 instanceof ValidationError) {
|
1164
|
+
return getYupValidationErrors(error2);
|
1165
|
+
}
|
1166
|
+
throw error2;
|
1063
1167
|
}
|
1064
1168
|
},
|
1065
|
-
[
|
1066
|
-
// trackUsage,
|
1067
|
-
publishManyDocuments,
|
1068
|
-
toggleNotification,
|
1069
|
-
formatMessage,
|
1070
|
-
formatAPIError
|
1071
|
-
]
|
1169
|
+
[validationSchema]
|
1072
1170
|
);
|
1073
|
-
const
|
1074
|
-
const
|
1075
|
-
|
1171
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1172
|
+
const hasError = !!error;
|
1173
|
+
return {
|
1174
|
+
components,
|
1175
|
+
document: data?.data,
|
1176
|
+
meta: data?.meta,
|
1177
|
+
isLoading,
|
1178
|
+
hasError,
|
1179
|
+
schema,
|
1180
|
+
schemas,
|
1181
|
+
validate
|
1182
|
+
};
|
1183
|
+
};
|
1184
|
+
const useDoc = () => {
|
1185
|
+
const { id, slug, collectionType, origin } = useParams();
|
1186
|
+
const [{ query }] = useQueryParams();
|
1187
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1188
|
+
if (!collectionType) {
|
1189
|
+
throw new Error("Could not find collectionType in url params");
|
1190
|
+
}
|
1191
|
+
if (!slug) {
|
1192
|
+
throw new Error("Could not find model in url params");
|
1193
|
+
}
|
1194
|
+
const document = useDocument(
|
1195
|
+
{ documentId: origin || id, model: slug, collectionType, params },
|
1196
|
+
{
|
1197
|
+
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
1198
|
+
}
|
1199
|
+
);
|
1200
|
+
const returnId = origin || id === "create" ? void 0 : id;
|
1201
|
+
return {
|
1202
|
+
collectionType,
|
1203
|
+
model: slug,
|
1204
|
+
id: returnId,
|
1205
|
+
...document
|
1206
|
+
};
|
1207
|
+
};
|
1208
|
+
const useContentManagerContext = () => {
|
1209
|
+
const {
|
1210
|
+
collectionType,
|
1211
|
+
model,
|
1212
|
+
id,
|
1213
|
+
components,
|
1214
|
+
isLoading: isLoadingDoc,
|
1215
|
+
schema,
|
1216
|
+
schemas
|
1217
|
+
} = useDoc();
|
1218
|
+
const layout = useDocumentLayout(model);
|
1219
|
+
const form = useForm("useContentManagerContext", (state) => state);
|
1220
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1221
|
+
const slug = model;
|
1222
|
+
const isCreatingEntry = id === "create";
|
1223
|
+
useContentTypeSchema();
|
1224
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1225
|
+
const error = layout.error;
|
1226
|
+
return {
|
1227
|
+
error,
|
1228
|
+
isLoading,
|
1229
|
+
// Base metadata
|
1230
|
+
model,
|
1231
|
+
collectionType,
|
1232
|
+
id,
|
1233
|
+
slug,
|
1234
|
+
isCreatingEntry,
|
1235
|
+
isSingleType,
|
1236
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1237
|
+
// All schema infos
|
1238
|
+
components,
|
1239
|
+
contentType: schema,
|
1240
|
+
contentTypes: schemas,
|
1241
|
+
// Form state
|
1242
|
+
form,
|
1243
|
+
// layout infos
|
1244
|
+
layout
|
1245
|
+
};
|
1246
|
+
};
|
1247
|
+
const prefixPluginTranslations = (trad, pluginId) => {
|
1248
|
+
return Object.keys(trad).reduce((acc, current) => {
|
1249
|
+
acc[`${pluginId}.${current}`] = trad[current];
|
1250
|
+
return acc;
|
1251
|
+
}, {});
|
1252
|
+
};
|
1253
|
+
const getTranslation = (id) => `content-manager.${id}`;
|
1254
|
+
const DEFAULT_UNEXPECTED_ERROR_MSG = {
|
1255
|
+
id: "notification.error",
|
1256
|
+
defaultMessage: "An error occurred, please try again"
|
1257
|
+
};
|
1258
|
+
const useDocumentActions = () => {
|
1259
|
+
const { toggleNotification } = useNotification();
|
1260
|
+
const { formatMessage } = useIntl();
|
1261
|
+
const { trackUsage } = useTracking();
|
1262
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1263
|
+
const navigate = useNavigate();
|
1264
|
+
const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
1265
|
+
const [deleteDocument] = useDeleteDocumentMutation();
|
1266
|
+
const _delete = React.useCallback(
|
1267
|
+
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
1076
1268
|
try {
|
1077
|
-
trackUsage("
|
1078
|
-
const res = await
|
1269
|
+
trackUsage("willDeleteEntry", trackerProperty);
|
1270
|
+
const res = await deleteDocument({
|
1079
1271
|
collectionType,
|
1080
1272
|
model,
|
1081
1273
|
documentId,
|
1082
|
-
data,
|
1083
1274
|
params
|
1084
1275
|
});
|
1085
1276
|
if ("error" in res) {
|
1086
|
-
toggleNotification({
|
1087
|
-
|
1277
|
+
toggleNotification({
|
1278
|
+
type: "danger",
|
1279
|
+
message: formatAPIError(res.error)
|
1280
|
+
});
|
1088
1281
|
return { error: res.error };
|
1089
1282
|
}
|
1090
|
-
trackUsage("didEditEntry", trackerProperty);
|
1091
1283
|
toggleNotification({
|
1092
1284
|
type: "success",
|
1093
1285
|
message: formatMessage({
|
1094
|
-
id: getTranslation("success.record.
|
1095
|
-
defaultMessage: "
|
1286
|
+
id: getTranslation("success.record.delete"),
|
1287
|
+
defaultMessage: "Deleted document"
|
1096
1288
|
})
|
1097
1289
|
});
|
1290
|
+
trackUsage("didDeleteEntry", trackerProperty);
|
1098
1291
|
return res.data;
|
1099
1292
|
} catch (err) {
|
1100
|
-
trackUsage("didNotEditEntry", { error: err, ...trackerProperty });
|
1101
1293
|
toggleNotification({
|
1102
1294
|
type: "danger",
|
1103
1295
|
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1104
1296
|
});
|
1297
|
+
trackUsage("didNotDeleteEntry", { error: err, ...trackerProperty });
|
1105
1298
|
throw err;
|
1106
1299
|
}
|
1107
1300
|
},
|
1108
|
-
[trackUsage,
|
1301
|
+
[trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
|
1109
1302
|
);
|
1110
|
-
const [
|
1111
|
-
const
|
1112
|
-
async ({
|
1303
|
+
const [deleteManyDocuments] = useDeleteManyDocumentsMutation();
|
1304
|
+
const deleteMany = React.useCallback(
|
1305
|
+
async ({ model, documentIds, params }) => {
|
1113
1306
|
try {
|
1114
|
-
trackUsage("
|
1115
|
-
const res = await
|
1116
|
-
collectionType,
|
1307
|
+
trackUsage("willBulkDeleteEntries");
|
1308
|
+
const res = await deleteManyDocuments({
|
1117
1309
|
model,
|
1118
|
-
|
1119
|
-
params
|
1120
|
-
data: {
|
1121
|
-
discardDraft
|
1122
|
-
}
|
1310
|
+
documentIds,
|
1311
|
+
params
|
1123
1312
|
});
|
1124
1313
|
if ("error" in res) {
|
1125
|
-
toggleNotification({
|
1314
|
+
toggleNotification({
|
1315
|
+
type: "danger",
|
1316
|
+
message: formatAPIError(res.error)
|
1317
|
+
});
|
1126
1318
|
return { error: res.error };
|
1127
1319
|
}
|
1128
|
-
trackUsage("didUnpublishEntry");
|
1129
1320
|
toggleNotification({
|
1130
1321
|
type: "success",
|
1131
|
-
|
1132
|
-
id: getTranslation("success.
|
1133
|
-
defaultMessage: "
|
1134
|
-
})
|
1322
|
+
title: formatMessage({
|
1323
|
+
id: getTranslation("success.records.delete"),
|
1324
|
+
defaultMessage: "Successfully deleted."
|
1325
|
+
}),
|
1326
|
+
message: ""
|
1135
1327
|
});
|
1328
|
+
trackUsage("didBulkDeleteEntries");
|
1136
1329
|
return res.data;
|
1137
1330
|
} catch (err) {
|
1138
1331
|
toggleNotification({
|
1139
1332
|
type: "danger",
|
1140
1333
|
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1141
1334
|
});
|
1335
|
+
trackUsage("didNotBulkDeleteEntries");
|
1142
1336
|
throw err;
|
1143
1337
|
}
|
1144
1338
|
},
|
1145
|
-
[trackUsage,
|
1339
|
+
[trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
1146
1340
|
);
|
1147
|
-
const [
|
1148
|
-
const
|
1149
|
-
async ({ model,
|
1341
|
+
const [discardDocument] = useDiscardDocumentMutation();
|
1342
|
+
const discard = React.useCallback(
|
1343
|
+
async ({ collectionType, model, documentId, params }) => {
|
1150
1344
|
try {
|
1151
|
-
|
1152
|
-
|
1345
|
+
const res = await discardDocument({
|
1346
|
+
collectionType,
|
1153
1347
|
model,
|
1154
|
-
|
1348
|
+
documentId,
|
1155
1349
|
params
|
1156
1350
|
});
|
1157
1351
|
if ("error" in res) {
|
1158
|
-
toggleNotification({
|
1352
|
+
toggleNotification({
|
1353
|
+
type: "danger",
|
1354
|
+
message: formatAPIError(res.error)
|
1355
|
+
});
|
1159
1356
|
return { error: res.error };
|
1160
1357
|
}
|
1161
|
-
trackUsage("didBulkUnpublishEntries");
|
1162
1358
|
toggleNotification({
|
1163
1359
|
type: "success",
|
1164
|
-
|
1165
|
-
id:
|
1166
|
-
defaultMessage: "
|
1167
|
-
})
|
1168
|
-
message: ""
|
1360
|
+
message: formatMessage({
|
1361
|
+
id: "content-manager.success.record.discard",
|
1362
|
+
defaultMessage: "Changes discarded"
|
1363
|
+
})
|
1169
1364
|
});
|
1170
1365
|
return res.data;
|
1171
1366
|
} catch (err) {
|
@@ -1173,16 +1368,196 @@ const useDocumentActions = () => {
|
|
1173
1368
|
type: "danger",
|
1174
1369
|
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1175
1370
|
});
|
1176
|
-
trackUsage("didNotBulkUnpublishEntries");
|
1177
1371
|
throw err;
|
1178
1372
|
}
|
1179
1373
|
},
|
1180
|
-
[
|
1374
|
+
[discardDocument, formatAPIError, formatMessage, toggleNotification]
|
1181
1375
|
);
|
1182
|
-
const [
|
1183
|
-
const
|
1184
|
-
async ({ model, params }, data
|
1185
|
-
try {
|
1376
|
+
const [publishDocument] = usePublishDocumentMutation();
|
1377
|
+
const publish = React.useCallback(
|
1378
|
+
async ({ collectionType, model, documentId, params }, data) => {
|
1379
|
+
try {
|
1380
|
+
trackUsage("willPublishEntry");
|
1381
|
+
const res = await publishDocument({
|
1382
|
+
collectionType,
|
1383
|
+
model,
|
1384
|
+
documentId,
|
1385
|
+
data,
|
1386
|
+
params
|
1387
|
+
});
|
1388
|
+
if ("error" in res) {
|
1389
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1390
|
+
return { error: res.error };
|
1391
|
+
}
|
1392
|
+
trackUsage("didPublishEntry");
|
1393
|
+
toggleNotification({
|
1394
|
+
type: "success",
|
1395
|
+
message: formatMessage({
|
1396
|
+
id: getTranslation("success.record.publish"),
|
1397
|
+
defaultMessage: "Published document"
|
1398
|
+
})
|
1399
|
+
});
|
1400
|
+
return res.data;
|
1401
|
+
} catch (err) {
|
1402
|
+
toggleNotification({
|
1403
|
+
type: "danger",
|
1404
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1405
|
+
});
|
1406
|
+
throw err;
|
1407
|
+
}
|
1408
|
+
},
|
1409
|
+
[trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
|
1410
|
+
);
|
1411
|
+
const [publishManyDocuments] = usePublishManyDocumentsMutation();
|
1412
|
+
const publishMany = React.useCallback(
|
1413
|
+
async ({ model, documentIds, params }) => {
|
1414
|
+
try {
|
1415
|
+
const res = await publishManyDocuments({
|
1416
|
+
model,
|
1417
|
+
documentIds,
|
1418
|
+
params
|
1419
|
+
});
|
1420
|
+
if ("error" in res) {
|
1421
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1422
|
+
return { error: res.error };
|
1423
|
+
}
|
1424
|
+
toggleNotification({
|
1425
|
+
type: "success",
|
1426
|
+
message: formatMessage({
|
1427
|
+
id: getTranslation("success.record.publish"),
|
1428
|
+
defaultMessage: "Published document"
|
1429
|
+
})
|
1430
|
+
});
|
1431
|
+
return res.data;
|
1432
|
+
} catch (err) {
|
1433
|
+
toggleNotification({
|
1434
|
+
type: "danger",
|
1435
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1436
|
+
});
|
1437
|
+
throw err;
|
1438
|
+
}
|
1439
|
+
},
|
1440
|
+
[
|
1441
|
+
// trackUsage,
|
1442
|
+
publishManyDocuments,
|
1443
|
+
toggleNotification,
|
1444
|
+
formatMessage,
|
1445
|
+
formatAPIError
|
1446
|
+
]
|
1447
|
+
);
|
1448
|
+
const [updateDocument] = useUpdateDocumentMutation();
|
1449
|
+
const update = React.useCallback(
|
1450
|
+
async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
|
1451
|
+
try {
|
1452
|
+
trackUsage("willEditEntry", trackerProperty);
|
1453
|
+
const res = await updateDocument({
|
1454
|
+
collectionType,
|
1455
|
+
model,
|
1456
|
+
documentId,
|
1457
|
+
data,
|
1458
|
+
params
|
1459
|
+
});
|
1460
|
+
if ("error" in res) {
|
1461
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1462
|
+
trackUsage("didNotEditEntry", { error: res.error, ...trackerProperty });
|
1463
|
+
return { error: res.error };
|
1464
|
+
}
|
1465
|
+
trackUsage("didEditEntry", trackerProperty);
|
1466
|
+
toggleNotification({
|
1467
|
+
type: "success",
|
1468
|
+
message: formatMessage({
|
1469
|
+
id: getTranslation("success.record.save"),
|
1470
|
+
defaultMessage: "Saved document"
|
1471
|
+
})
|
1472
|
+
});
|
1473
|
+
return res.data;
|
1474
|
+
} catch (err) {
|
1475
|
+
trackUsage("didNotEditEntry", { error: err, ...trackerProperty });
|
1476
|
+
toggleNotification({
|
1477
|
+
type: "danger",
|
1478
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1479
|
+
});
|
1480
|
+
throw err;
|
1481
|
+
}
|
1482
|
+
},
|
1483
|
+
[trackUsage, updateDocument, toggleNotification, formatMessage, formatAPIError]
|
1484
|
+
);
|
1485
|
+
const [unpublishDocument] = useUnpublishDocumentMutation();
|
1486
|
+
const unpublish = React.useCallback(
|
1487
|
+
async ({ collectionType, model, documentId, params }, discardDraft = false) => {
|
1488
|
+
try {
|
1489
|
+
trackUsage("willUnpublishEntry");
|
1490
|
+
const res = await unpublishDocument({
|
1491
|
+
collectionType,
|
1492
|
+
model,
|
1493
|
+
documentId,
|
1494
|
+
params,
|
1495
|
+
data: {
|
1496
|
+
discardDraft
|
1497
|
+
}
|
1498
|
+
});
|
1499
|
+
if ("error" in res) {
|
1500
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1501
|
+
return { error: res.error };
|
1502
|
+
}
|
1503
|
+
trackUsage("didUnpublishEntry");
|
1504
|
+
toggleNotification({
|
1505
|
+
type: "success",
|
1506
|
+
message: formatMessage({
|
1507
|
+
id: getTranslation("success.record.unpublish"),
|
1508
|
+
defaultMessage: "Unpublished document"
|
1509
|
+
})
|
1510
|
+
});
|
1511
|
+
return res.data;
|
1512
|
+
} catch (err) {
|
1513
|
+
toggleNotification({
|
1514
|
+
type: "danger",
|
1515
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1516
|
+
});
|
1517
|
+
throw err;
|
1518
|
+
}
|
1519
|
+
},
|
1520
|
+
[trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
|
1521
|
+
);
|
1522
|
+
const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
|
1523
|
+
const unpublishMany = React.useCallback(
|
1524
|
+
async ({ model, documentIds, params }) => {
|
1525
|
+
try {
|
1526
|
+
trackUsage("willBulkUnpublishEntries");
|
1527
|
+
const res = await unpublishManyDocuments({
|
1528
|
+
model,
|
1529
|
+
documentIds,
|
1530
|
+
params
|
1531
|
+
});
|
1532
|
+
if ("error" in res) {
|
1533
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1534
|
+
return { error: res.error };
|
1535
|
+
}
|
1536
|
+
trackUsage("didBulkUnpublishEntries");
|
1537
|
+
toggleNotification({
|
1538
|
+
type: "success",
|
1539
|
+
title: formatMessage({
|
1540
|
+
id: getTranslation("success.records.unpublish"),
|
1541
|
+
defaultMessage: "Successfully unpublished."
|
1542
|
+
}),
|
1543
|
+
message: ""
|
1544
|
+
});
|
1545
|
+
return res.data;
|
1546
|
+
} catch (err) {
|
1547
|
+
toggleNotification({
|
1548
|
+
type: "danger",
|
1549
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1550
|
+
});
|
1551
|
+
trackUsage("didNotBulkUnpublishEntries");
|
1552
|
+
throw err;
|
1553
|
+
}
|
1554
|
+
},
|
1555
|
+
[trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
1556
|
+
);
|
1557
|
+
const [createDocument] = useCreateDocumentMutation();
|
1558
|
+
const create = React.useCallback(
|
1559
|
+
async ({ model, params }, data, trackerProperty) => {
|
1560
|
+
try {
|
1186
1561
|
const res = await createDocument({
|
1187
1562
|
model,
|
1188
1563
|
data,
|
@@ -1201,6 +1576,7 @@ const useDocumentActions = () => {
|
|
1201
1576
|
defaultMessage: "Saved document"
|
1202
1577
|
})
|
1203
1578
|
});
|
1579
|
+
setCurrentStep("contentManager.success");
|
1204
1580
|
return res.data;
|
1205
1581
|
} catch (err) {
|
1206
1582
|
toggleNotification({
|
@@ -1302,10 +1678,10 @@ const useDocumentActions = () => {
|
|
1302
1678
|
update
|
1303
1679
|
};
|
1304
1680
|
};
|
1305
|
-
const ProtectedHistoryPage = lazy(
|
1306
|
-
() => import("./History-
|
1681
|
+
const ProtectedHistoryPage = React.lazy(
|
1682
|
+
() => import("./History-DP8gmXpm.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1307
1683
|
);
|
1308
|
-
const routes$
|
1684
|
+
const routes$2 = [
|
1309
1685
|
{
|
1310
1686
|
path: ":collectionType/:slug/:id/history",
|
1311
1687
|
Component: ProtectedHistoryPage
|
@@ -1315,32 +1691,45 @@ const routes$1 = [
|
|
1315
1691
|
Component: ProtectedHistoryPage
|
1316
1692
|
}
|
1317
1693
|
];
|
1694
|
+
const ProtectedPreviewPage = React.lazy(
|
1695
|
+
() => import("./Preview-C4NBzKUV.mjs").then((mod) => ({ default: mod.ProtectedPreviewPage }))
|
1696
|
+
);
|
1697
|
+
const routes$1 = [
|
1698
|
+
{
|
1699
|
+
path: ":collectionType/:slug/:id/preview",
|
1700
|
+
Component: ProtectedPreviewPage
|
1701
|
+
},
|
1702
|
+
{
|
1703
|
+
path: ":collectionType/:slug/preview",
|
1704
|
+
Component: ProtectedPreviewPage
|
1705
|
+
}
|
1706
|
+
];
|
1318
1707
|
const ProtectedEditViewPage = lazy(
|
1319
|
-
() => import("./EditViewPage-
|
1708
|
+
() => import("./EditViewPage-_A31Cl4g.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1320
1709
|
);
|
1321
1710
|
const ProtectedListViewPage = lazy(
|
1322
|
-
() => import("./ListViewPage-
|
1711
|
+
() => import("./ListViewPage-Cf_DgaFV.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1323
1712
|
);
|
1324
1713
|
const ProtectedListConfiguration = lazy(
|
1325
|
-
() => import("./ListConfigurationPage-
|
1714
|
+
() => import("./ListConfigurationPage-BCkO5iuN.mjs").then((mod) => ({
|
1326
1715
|
default: mod.ProtectedListConfiguration
|
1327
1716
|
}))
|
1328
1717
|
);
|
1329
1718
|
const ProtectedEditConfigurationPage = lazy(
|
1330
|
-
() => import("./EditConfigurationPage-
|
1719
|
+
() => import("./EditConfigurationPage-vN4zupij.mjs").then((mod) => ({
|
1331
1720
|
default: mod.ProtectedEditConfigurationPage
|
1332
1721
|
}))
|
1333
1722
|
);
|
1334
1723
|
const ProtectedComponentConfigurationPage = lazy(
|
1335
|
-
() => import("./ComponentConfigurationPage-
|
1724
|
+
() => import("./ComponentConfigurationPage-BiASGi7x.mjs").then((mod) => ({
|
1336
1725
|
default: mod.ProtectedComponentConfigurationPage
|
1337
1726
|
}))
|
1338
1727
|
);
|
1339
1728
|
const NoPermissions = lazy(
|
1340
|
-
() => import("./NoPermissionsPage-
|
1729
|
+
() => import("./NoPermissionsPage-BALVSJ7x.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1341
1730
|
);
|
1342
1731
|
const NoContentType = lazy(
|
1343
|
-
() => import("./NoContentTypePage-
|
1732
|
+
() => import("./NoContentTypePage-nHIyvJcB.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1344
1733
|
);
|
1345
1734
|
const CollectionTypePages = () => {
|
1346
1735
|
const { collectionType } = useParams();
|
@@ -1352,7 +1741,7 @@ const CollectionTypePages = () => {
|
|
1352
1741
|
const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
|
1353
1742
|
const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
|
1354
1743
|
const LIST_RELATIVE_PATH = ":collectionType/:slug";
|
1355
|
-
const LIST_PATH = `/content-manager
|
1744
|
+
const LIST_PATH = `/content-manager/collection-types/:slug`;
|
1356
1745
|
const routes = [
|
1357
1746
|
{
|
1358
1747
|
path: LIST_RELATIVE_PATH,
|
@@ -1386,6 +1775,7 @@ const routes = [
|
|
1386
1775
|
path: "no-content-types",
|
1387
1776
|
Component: NoContentType
|
1388
1777
|
},
|
1778
|
+
...routes$2,
|
1389
1779
|
...routes$1
|
1390
1780
|
];
|
1391
1781
|
const DocumentActions = ({ actions: actions2 }) => {
|
@@ -1484,6 +1874,11 @@ const DocumentActionButton = (action) => {
|
|
1484
1874
|
) : null
|
1485
1875
|
] });
|
1486
1876
|
};
|
1877
|
+
const MenuItem = styled(Menu.Item)`
|
1878
|
+
&:hover {
|
1879
|
+
background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
|
1880
|
+
}
|
1881
|
+
`;
|
1487
1882
|
const DocumentActionsMenu = ({
|
1488
1883
|
actions: actions2,
|
1489
1884
|
children,
|
@@ -1539,51 +1934,35 @@ const DocumentActionsMenu = ({
|
|
1539
1934
|
]
|
1540
1935
|
}
|
1541
1936
|
),
|
1542
|
-
/* @__PURE__ */ jsxs(Menu.Content, {
|
1937
|
+
/* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1543
1938
|
actions2.map((action) => {
|
1544
1939
|
return /* @__PURE__ */ jsx(
|
1545
|
-
|
1940
|
+
MenuItem,
|
1546
1941
|
{
|
1547
1942
|
disabled: action.disabled,
|
1548
1943
|
onSelect: handleClick(action),
|
1549
1944
|
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
|
-
] })
|
1945
|
+
isVariantDanger: action.variant === "danger",
|
1946
|
+
isDisabled: action.disabled,
|
1947
|
+
children: /* @__PURE__ */ jsx(Flex, { justifyContent: "space-between", gap: 4, children: /* @__PURE__ */ jsxs(
|
1948
|
+
Flex,
|
1949
|
+
{
|
1950
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1951
|
+
gap: 2,
|
1952
|
+
tag: "span",
|
1953
|
+
children: [
|
1954
|
+
/* @__PURE__ */ jsx(
|
1955
|
+
Flex,
|
1956
|
+
{
|
1957
|
+
tag: "span",
|
1958
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1959
|
+
children: action.icon
|
1960
|
+
}
|
1961
|
+
),
|
1962
|
+
action.label
|
1963
|
+
]
|
1964
|
+
}
|
1965
|
+
) })
|
1587
1966
|
},
|
1588
1967
|
action.id
|
1589
1968
|
);
|
@@ -1663,11 +2042,11 @@ const DocumentActionConfirmDialog = ({
|
|
1663
2042
|
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
1664
2043
|
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
1665
2044
|
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
1666
|
-
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
|
2045
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
1667
2046
|
id: "app.components.Button.cancel",
|
1668
2047
|
defaultMessage: "Cancel"
|
1669
2048
|
}) }) }),
|
1670
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2049
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1671
2050
|
id: "app.components.Button.confirm",
|
1672
2051
|
defaultMessage: "Confirm"
|
1673
2052
|
}) })
|
@@ -1694,6 +2073,18 @@ const DocumentActionModal = ({
|
|
1694
2073
|
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1695
2074
|
] }) });
|
1696
2075
|
};
|
2076
|
+
const transformData = (data) => {
|
2077
|
+
if (Array.isArray(data)) {
|
2078
|
+
return data.map(transformData);
|
2079
|
+
}
|
2080
|
+
if (typeof data === "object" && data !== null) {
|
2081
|
+
if ("apiData" in data) {
|
2082
|
+
return data.apiData;
|
2083
|
+
}
|
2084
|
+
return mapValues(transformData)(data);
|
2085
|
+
}
|
2086
|
+
return data;
|
2087
|
+
};
|
1697
2088
|
const PublishAction$1 = ({
|
1698
2089
|
activeTab,
|
1699
2090
|
documentId,
|
@@ -1708,6 +2099,7 @@ const PublishAction$1 = ({
|
|
1708
2099
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
1709
2100
|
const isListView = useMatch(LIST_PATH) !== null;
|
1710
2101
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2102
|
+
const { id } = useParams();
|
1711
2103
|
const { formatMessage } = useIntl();
|
1712
2104
|
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1713
2105
|
const { publish } = useDocumentActions();
|
@@ -1787,7 +2179,9 @@ const PublishAction$1 = ({
|
|
1787
2179
|
const performPublish = async () => {
|
1788
2180
|
setSubmitting(true);
|
1789
2181
|
try {
|
1790
|
-
const { errors } = await validate(
|
2182
|
+
const { errors } = await validate(true, {
|
2183
|
+
status: "published"
|
2184
|
+
});
|
1791
2185
|
if (errors) {
|
1792
2186
|
toggleNotification({
|
1793
2187
|
type: "danger",
|
@@ -1805,13 +2199,15 @@ const PublishAction$1 = ({
|
|
1805
2199
|
documentId,
|
1806
2200
|
params
|
1807
2201
|
},
|
1808
|
-
formValues
|
2202
|
+
transformData(formValues)
|
1809
2203
|
);
|
1810
2204
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
2205
|
+
if (id === "create") {
|
2206
|
+
navigate({
|
2207
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2208
|
+
search: rawQuery
|
2209
|
+
});
|
2210
|
+
}
|
1815
2211
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1816
2212
|
setErrors(formatValidationErrors(res.error));
|
1817
2213
|
}
|
@@ -1864,6 +2260,7 @@ const PublishAction$1 = ({
|
|
1864
2260
|
};
|
1865
2261
|
};
|
1866
2262
|
PublishAction$1.type = "publish";
|
2263
|
+
PublishAction$1.position = "panel";
|
1867
2264
|
const UpdateAction = ({
|
1868
2265
|
activeTab,
|
1869
2266
|
documentId,
|
@@ -1886,96 +2283,134 @@ const UpdateAction = ({
|
|
1886
2283
|
const validate = useForm("UpdateAction", (state) => state.validate);
|
1887
2284
|
const setErrors = useForm("UpdateAction", (state) => state.setErrors);
|
1888
2285
|
const resetForm = useForm("PublishAction", ({ resetForm: resetForm2 }) => resetForm2);
|
1889
|
-
|
1890
|
-
|
1891
|
-
|
1892
|
-
|
1893
|
-
|
1894
|
-
|
1895
|
-
|
1896
|
-
|
1897
|
-
|
1898
|
-
|
1899
|
-
|
1900
|
-
|
1901
|
-
|
1902
|
-
|
1903
|
-
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
1913
|
-
|
1914
|
-
|
1915
|
-
|
1916
|
-
|
1917
|
-
if (
|
1918
|
-
|
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(
|
2286
|
+
const handleUpdate = React.useCallback(async () => {
|
2287
|
+
setSubmitting(true);
|
2288
|
+
try {
|
2289
|
+
if (!modified) {
|
2290
|
+
return;
|
2291
|
+
}
|
2292
|
+
const { errors } = await validate(true, {
|
2293
|
+
status: "draft"
|
2294
|
+
});
|
2295
|
+
if (errors) {
|
2296
|
+
toggleNotification({
|
2297
|
+
type: "danger",
|
2298
|
+
message: formatMessage({
|
2299
|
+
id: "content-manager.validation.error",
|
2300
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2301
|
+
})
|
2302
|
+
});
|
2303
|
+
return;
|
2304
|
+
}
|
2305
|
+
if (isCloning) {
|
2306
|
+
const res = await clone(
|
2307
|
+
{
|
2308
|
+
model,
|
2309
|
+
documentId: cloneMatch.params.origin,
|
2310
|
+
params
|
2311
|
+
},
|
2312
|
+
transformData(document)
|
2313
|
+
);
|
2314
|
+
if ("data" in res) {
|
2315
|
+
navigate(
|
1939
2316
|
{
|
1940
|
-
|
1941
|
-
|
1942
|
-
documentId,
|
1943
|
-
params
|
2317
|
+
pathname: `../${res.data.documentId}`,
|
2318
|
+
search: rawQuery
|
1944
2319
|
},
|
1945
|
-
|
2320
|
+
{ relative: "path" }
|
1946
2321
|
);
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
2322
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2323
|
+
setErrors(formatValidationErrors(res.error));
|
2324
|
+
}
|
2325
|
+
} else if (documentId || collectionType === SINGLE_TYPES) {
|
2326
|
+
const res = await update(
|
2327
|
+
{
|
2328
|
+
collectionType,
|
2329
|
+
model,
|
2330
|
+
documentId,
|
2331
|
+
params
|
2332
|
+
},
|
2333
|
+
transformData(document)
|
2334
|
+
);
|
2335
|
+
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2336
|
+
setErrors(formatValidationErrors(res.error));
|
1952
2337
|
} else {
|
1953
|
-
|
2338
|
+
resetForm();
|
2339
|
+
}
|
2340
|
+
} else {
|
2341
|
+
const res = await create(
|
2342
|
+
{
|
2343
|
+
model,
|
2344
|
+
params
|
2345
|
+
},
|
2346
|
+
transformData(document)
|
2347
|
+
);
|
2348
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2349
|
+
navigate(
|
1954
2350
|
{
|
1955
|
-
|
1956
|
-
|
2351
|
+
pathname: `../${res.data.documentId}`,
|
2352
|
+
search: rawQuery
|
1957
2353
|
},
|
1958
|
-
|
2354
|
+
{ replace: true, relative: "path" }
|
1959
2355
|
);
|
1960
|
-
|
1961
|
-
|
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
|
-
}
|
2356
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2357
|
+
setErrors(formatValidationErrors(res.error));
|
1971
2358
|
}
|
1972
|
-
} finally {
|
1973
|
-
setSubmitting(false);
|
1974
2359
|
}
|
2360
|
+
} finally {
|
2361
|
+
setSubmitting(false);
|
1975
2362
|
}
|
2363
|
+
}, [
|
2364
|
+
clone,
|
2365
|
+
cloneMatch?.params.origin,
|
2366
|
+
collectionType,
|
2367
|
+
create,
|
2368
|
+
document,
|
2369
|
+
documentId,
|
2370
|
+
formatMessage,
|
2371
|
+
formatValidationErrors,
|
2372
|
+
isCloning,
|
2373
|
+
model,
|
2374
|
+
modified,
|
2375
|
+
navigate,
|
2376
|
+
params,
|
2377
|
+
rawQuery,
|
2378
|
+
resetForm,
|
2379
|
+
setErrors,
|
2380
|
+
setSubmitting,
|
2381
|
+
toggleNotification,
|
2382
|
+
update,
|
2383
|
+
validate
|
2384
|
+
]);
|
2385
|
+
React.useEffect(() => {
|
2386
|
+
const handleKeyDown = (e) => {
|
2387
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
2388
|
+
e.preventDefault();
|
2389
|
+
handleUpdate();
|
2390
|
+
}
|
2391
|
+
};
|
2392
|
+
window.addEventListener("keydown", handleKeyDown);
|
2393
|
+
return () => {
|
2394
|
+
window.removeEventListener("keydown", handleKeyDown);
|
2395
|
+
};
|
2396
|
+
}, [handleUpdate]);
|
2397
|
+
return {
|
2398
|
+
/**
|
2399
|
+
* Disabled when:
|
2400
|
+
* - the form is submitting
|
2401
|
+
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
2402
|
+
* - the active tab is the published tab
|
2403
|
+
*/
|
2404
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
2405
|
+
label: formatMessage({
|
2406
|
+
id: "global.save",
|
2407
|
+
defaultMessage: "Save"
|
2408
|
+
}),
|
2409
|
+
onClick: handleUpdate
|
1976
2410
|
};
|
1977
2411
|
};
|
1978
2412
|
UpdateAction.type = "update";
|
2413
|
+
UpdateAction.position = "panel";
|
1979
2414
|
const UNPUBLISH_DRAFT_OPTIONS = {
|
1980
2415
|
KEEP: "keep",
|
1981
2416
|
DISCARD: "discard"
|
@@ -2098,6 +2533,7 @@ const UnpublishAction$1 = ({
|
|
2098
2533
|
};
|
2099
2534
|
};
|
2100
2535
|
UnpublishAction$1.type = "unpublish";
|
2536
|
+
UnpublishAction$1.position = "panel";
|
2101
2537
|
const DiscardAction = ({
|
2102
2538
|
activeTab,
|
2103
2539
|
documentId,
|
@@ -2148,6 +2584,7 @@ const DiscardAction = ({
|
|
2148
2584
|
};
|
2149
2585
|
};
|
2150
2586
|
DiscardAction.type = "discard";
|
2587
|
+
DiscardAction.position = "panel";
|
2151
2588
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2152
2589
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2153
2590
|
const RelativeTime = React.forwardRef(
|
@@ -2160,7 +2597,7 @@ const RelativeTime = React.forwardRef(
|
|
2160
2597
|
});
|
2161
2598
|
const unit = intervals.find((intervalUnit) => {
|
2162
2599
|
return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
|
2163
|
-
});
|
2600
|
+
}) ?? "seconds";
|
2164
2601
|
const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
|
2165
2602
|
const customInterval = customIntervals.find(
|
2166
2603
|
(custom) => interval[custom.unit] < custom.threshold
|
@@ -2194,19 +2631,29 @@ const getDisplayName = ({
|
|
2194
2631
|
return email ?? "";
|
2195
2632
|
};
|
2196
2633
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2197
|
-
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2198
|
-
const statusVariant = status === "draft" ? "
|
2199
|
-
|
2634
|
+
const DocumentStatus = ({ status = "draft", size = "S", ...restProps }) => {
|
2635
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2636
|
+
const { formatMessage } = useIntl();
|
2637
|
+
return /* @__PURE__ */ jsx(Status, { ...restProps, size, variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: formatMessage({
|
2638
|
+
id: `content-manager.containers.List.${status}`,
|
2639
|
+
defaultMessage: capitalise(status)
|
2640
|
+
}) }) });
|
2200
2641
|
};
|
2201
2642
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2202
2643
|
const { formatMessage } = useIntl();
|
2203
2644
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2645
|
+
const params = useParams();
|
2204
2646
|
const title = isCreating ? formatMessage({
|
2205
2647
|
id: "content-manager.containers.edit.title.new",
|
2206
2648
|
defaultMessage: "Create an entry"
|
2207
2649
|
}) : documentTitle;
|
2208
2650
|
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2209
|
-
/* @__PURE__ */ jsx(
|
2651
|
+
/* @__PURE__ */ jsx(
|
2652
|
+
BackButton,
|
2653
|
+
{
|
2654
|
+
fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
|
2655
|
+
}
|
2656
|
+
),
|
2210
2657
|
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2211
2658
|
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2212
2659
|
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
@@ -2257,7 +2704,7 @@ const HeaderToolbar = () => {
|
|
2257
2704
|
meta: isCloning ? void 0 : meta,
|
2258
2705
|
collectionType
|
2259
2706
|
},
|
2260
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2707
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("header"),
|
2261
2708
|
children: (actions2) => {
|
2262
2709
|
const headerActions = actions2.filter((action) => {
|
2263
2710
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -2294,12 +2741,12 @@ const Information = ({ activeTab }) => {
|
|
2294
2741
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2295
2742
|
label: formatMessage({
|
2296
2743
|
id: "content-manager.containers.edit.information.last-published.label",
|
2297
|
-
defaultMessage: "
|
2744
|
+
defaultMessage: "Published"
|
2298
2745
|
}),
|
2299
2746
|
value: formatMessage(
|
2300
2747
|
{
|
2301
2748
|
id: "content-manager.containers.edit.information.last-published.value",
|
2302
|
-
defaultMessage: `
|
2749
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2303
2750
|
},
|
2304
2751
|
{
|
2305
2752
|
time: /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2312,12 +2759,12 @@ const Information = ({ activeTab }) => {
|
|
2312
2759
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2313
2760
|
label: formatMessage({
|
2314
2761
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2315
|
-
defaultMessage: "
|
2762
|
+
defaultMessage: "Updated"
|
2316
2763
|
}),
|
2317
2764
|
value: formatMessage(
|
2318
2765
|
{
|
2319
2766
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2320
|
-
defaultMessage: `
|
2767
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2321
2768
|
},
|
2322
2769
|
{
|
2323
2770
|
time: /* @__PURE__ */ jsx(
|
@@ -2335,12 +2782,12 @@ const Information = ({ activeTab }) => {
|
|
2335
2782
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2336
2783
|
label: formatMessage({
|
2337
2784
|
id: "content-manager.containers.edit.information.document.label",
|
2338
|
-
defaultMessage: "
|
2785
|
+
defaultMessage: "Created"
|
2339
2786
|
}),
|
2340
2787
|
value: formatMessage(
|
2341
2788
|
{
|
2342
2789
|
id: "content-manager.containers.edit.information.document.value",
|
2343
|
-
defaultMessage: `
|
2790
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2344
2791
|
},
|
2345
2792
|
{
|
2346
2793
|
time: /* @__PURE__ */ jsx(
|
@@ -2378,25 +2825,77 @@ const Information = ({ activeTab }) => {
|
|
2378
2825
|
);
|
2379
2826
|
};
|
2380
2827
|
const HeaderActions = ({ actions: actions2 }) => {
|
2381
|
-
|
2382
|
-
|
2828
|
+
const [dialogId, setDialogId] = React.useState(null);
|
2829
|
+
const handleClick = (action) => async (e) => {
|
2830
|
+
if (!("options" in action)) {
|
2831
|
+
const { onClick = () => false, dialog, id } = action;
|
2832
|
+
const muteDialog = await onClick(e);
|
2833
|
+
if (dialog && !muteDialog) {
|
2834
|
+
e.preventDefault();
|
2835
|
+
setDialogId(id);
|
2836
|
+
}
|
2837
|
+
}
|
2838
|
+
};
|
2839
|
+
const handleClose = () => {
|
2840
|
+
setDialogId(null);
|
2841
|
+
};
|
2842
|
+
return /* @__PURE__ */ jsx(Flex, { gap: 1, children: actions2.map((action) => {
|
2843
|
+
if (action.options) {
|
2383
2844
|
return /* @__PURE__ */ jsx(
|
2384
2845
|
SingleSelect,
|
2385
2846
|
{
|
2386
2847
|
size: "S",
|
2387
|
-
disabled: action.disabled,
|
2388
|
-
"aria-label": action.label,
|
2389
2848
|
onChange: action.onSelect,
|
2390
|
-
|
2849
|
+
"aria-label": action.label,
|
2850
|
+
...action,
|
2391
2851
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
|
2392
2852
|
},
|
2393
2853
|
action.id
|
2394
2854
|
);
|
2395
2855
|
} else {
|
2396
|
-
|
2856
|
+
if (action.type === "icon") {
|
2857
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
2858
|
+
/* @__PURE__ */ jsx(
|
2859
|
+
IconButton,
|
2860
|
+
{
|
2861
|
+
disabled: action.disabled,
|
2862
|
+
label: action.label,
|
2863
|
+
size: "S",
|
2864
|
+
onClick: handleClick(action),
|
2865
|
+
children: action.icon
|
2866
|
+
}
|
2867
|
+
),
|
2868
|
+
action.dialog ? /* @__PURE__ */ jsx(
|
2869
|
+
HeaderActionDialog,
|
2870
|
+
{
|
2871
|
+
...action.dialog,
|
2872
|
+
isOpen: dialogId === action.id,
|
2873
|
+
onClose: handleClose
|
2874
|
+
}
|
2875
|
+
) : null
|
2876
|
+
] }, action.id);
|
2877
|
+
}
|
2397
2878
|
}
|
2398
2879
|
}) });
|
2399
2880
|
};
|
2881
|
+
const HeaderActionDialog = ({
|
2882
|
+
onClose,
|
2883
|
+
onCancel,
|
2884
|
+
title,
|
2885
|
+
content: Content,
|
2886
|
+
isOpen
|
2887
|
+
}) => {
|
2888
|
+
const handleClose = async () => {
|
2889
|
+
if (onCancel) {
|
2890
|
+
await onCancel();
|
2891
|
+
}
|
2892
|
+
onClose();
|
2893
|
+
};
|
2894
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2895
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
2896
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content
|
2897
|
+
] }) });
|
2898
|
+
};
|
2400
2899
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2401
2900
|
const navigate = useNavigate();
|
2402
2901
|
const { formatMessage } = useIntl();
|
@@ -2413,6 +2912,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2413
2912
|
};
|
2414
2913
|
};
|
2415
2914
|
ConfigureTheViewAction.type = "configure-the-view";
|
2915
|
+
ConfigureTheViewAction.position = "header";
|
2416
2916
|
const EditTheModelAction = ({ model }) => {
|
2417
2917
|
const navigate = useNavigate();
|
2418
2918
|
const { formatMessage } = useIntl();
|
@@ -2429,6 +2929,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2429
2929
|
};
|
2430
2930
|
};
|
2431
2931
|
EditTheModelAction.type = "edit-the-model";
|
2932
|
+
EditTheModelAction.position = "header";
|
2432
2933
|
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2433
2934
|
const navigate = useNavigate();
|
2434
2935
|
const { formatMessage } = useIntl();
|
@@ -2437,12 +2938,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2437
2938
|
const { delete: deleteAction } = useDocumentActions();
|
2438
2939
|
const { toggleNotification } = useNotification();
|
2439
2940
|
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
2941
|
+
const isLocalized = document?.locale != null;
|
2440
2942
|
return {
|
2441
2943
|
disabled: !canDelete || !document,
|
2442
|
-
label: formatMessage(
|
2443
|
-
|
2444
|
-
|
2445
|
-
|
2944
|
+
label: formatMessage(
|
2945
|
+
{
|
2946
|
+
id: "content-manager.actions.delete.label",
|
2947
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2948
|
+
},
|
2949
|
+
{ isLocalized }
|
2950
|
+
),
|
2446
2951
|
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2447
2952
|
dialog: {
|
2448
2953
|
type: "dialog",
|
@@ -2480,422 +2985,120 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2480
2985
|
model,
|
2481
2986
|
collectionType,
|
2482
2987
|
params: {
|
2483
|
-
locale: "*"
|
2484
|
-
}
|
2485
|
-
});
|
2486
|
-
if (!("error" in res)) {
|
2487
|
-
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2488
|
-
}
|
2489
|
-
} finally {
|
2490
|
-
if (!listViewPathMatch) {
|
2491
|
-
setSubmitting(false);
|
2492
|
-
}
|
2493
|
-
}
|
2494
|
-
}
|
2495
|
-
},
|
2496
|
-
variant: "danger",
|
2497
|
-
position: ["header", "table-row"]
|
2498
|
-
};
|
2499
|
-
};
|
2500
|
-
DeleteAction$1.type = "delete";
|
2501
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2502
|
-
const Panels = () => {
|
2503
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2504
|
-
const [
|
2505
|
-
{
|
2506
|
-
query: { status }
|
2507
|
-
}
|
2508
|
-
] = useQueryParams({
|
2509
|
-
status: "draft"
|
2510
|
-
});
|
2511
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2512
|
-
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
2513
|
-
const props = {
|
2514
|
-
activeTab: status,
|
2515
|
-
model,
|
2516
|
-
documentId: id,
|
2517
|
-
document: isCloning ? void 0 : document,
|
2518
|
-
meta: isCloning ? void 0 : meta,
|
2519
|
-
collectionType
|
2520
|
-
};
|
2521
|
-
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
2522
|
-
DescriptionComponentRenderer,
|
2523
|
-
{
|
2524
|
-
props,
|
2525
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2526
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
2527
|
-
}
|
2528
|
-
) });
|
2529
|
-
};
|
2530
|
-
const ActionsPanel = () => {
|
2531
|
-
const { formatMessage } = useIntl();
|
2532
|
-
return {
|
2533
|
-
title: formatMessage({
|
2534
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2535
|
-
defaultMessage: "Document"
|
2536
|
-
}),
|
2537
|
-
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2538
|
-
};
|
2539
|
-
};
|
2540
|
-
ActionsPanel.type = "actions";
|
2541
|
-
const ActionsPanelContent = () => {
|
2542
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2543
|
-
const [
|
2544
|
-
{
|
2545
|
-
query: { status = "draft" }
|
2546
|
-
}
|
2547
|
-
] = useQueryParams();
|
2548
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2549
|
-
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2550
|
-
const props = {
|
2551
|
-
activeTab: status,
|
2552
|
-
model,
|
2553
|
-
documentId: id,
|
2554
|
-
document: isCloning ? void 0 : document,
|
2555
|
-
meta: isCloning ? void 0 : meta,
|
2556
|
-
collectionType
|
2557
|
-
};
|
2558
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2559
|
-
/* @__PURE__ */ jsx(
|
2560
|
-
DescriptionComponentRenderer,
|
2561
|
-
{
|
2562
|
-
props,
|
2563
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2564
|
-
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
2565
|
-
}
|
2566
|
-
),
|
2567
|
-
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2568
|
-
] });
|
2569
|
-
};
|
2570
|
-
const Panel = React.forwardRef(({ children, title }, ref) => {
|
2571
|
-
return /* @__PURE__ */ jsxs(
|
2572
|
-
Flex,
|
2573
|
-
{
|
2574
|
-
ref,
|
2575
|
-
tag: "aside",
|
2576
|
-
"aria-labelledby": "additional-information",
|
2577
|
-
background: "neutral0",
|
2578
|
-
borderColor: "neutral150",
|
2579
|
-
hasRadius: true,
|
2580
|
-
paddingBottom: 4,
|
2581
|
-
paddingLeft: 4,
|
2582
|
-
paddingRight: 4,
|
2583
|
-
paddingTop: 4,
|
2584
|
-
shadow: "tableShadow",
|
2585
|
-
gap: 3,
|
2586
|
-
direction: "column",
|
2587
|
-
justifyContent: "stretch",
|
2588
|
-
alignItems: "flex-start",
|
2589
|
-
children: [
|
2590
|
-
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2591
|
-
children
|
2592
|
-
]
|
2593
|
-
}
|
2594
|
-
);
|
2595
|
-
});
|
2596
|
-
const HOOKS = {
|
2597
|
-
/**
|
2598
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2599
|
-
* @constant
|
2600
|
-
* @type {string}
|
2601
|
-
*/
|
2602
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2603
|
-
/**
|
2604
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2605
|
-
* @constant
|
2606
|
-
* @type {string}
|
2607
|
-
*/
|
2608
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2609
|
-
/**
|
2610
|
-
* Hook that allows to mutate the CM's edit view layout
|
2611
|
-
* @constant
|
2612
|
-
* @type {string}
|
2613
|
-
*/
|
2614
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2615
|
-
/**
|
2616
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2617
|
-
* @constant
|
2618
|
-
* @type {string}
|
2619
|
-
*/
|
2620
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2621
|
-
};
|
2622
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2623
|
-
endpoints: (builder) => ({
|
2624
|
-
getContentTypeConfiguration: builder.query({
|
2625
|
-
query: (uid) => ({
|
2626
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2627
|
-
method: "GET"
|
2628
|
-
}),
|
2629
|
-
transformResponse: (response) => response.data,
|
2630
|
-
providesTags: (_result, _error, uid) => [
|
2631
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2632
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2633
|
-
]
|
2634
|
-
}),
|
2635
|
-
getAllContentTypeSettings: builder.query({
|
2636
|
-
query: () => "/content-manager/content-types-settings",
|
2637
|
-
transformResponse: (response) => response.data,
|
2638
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2639
|
-
}),
|
2640
|
-
updateContentTypeConfiguration: builder.mutation({
|
2641
|
-
query: ({ uid, ...body }) => ({
|
2642
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2643
|
-
method: "PUT",
|
2644
|
-
data: body
|
2645
|
-
}),
|
2646
|
-
transformResponse: (response) => response.data,
|
2647
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2648
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2649
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2650
|
-
// Is this necessary?
|
2651
|
-
{ type: "InitialData" }
|
2652
|
-
]
|
2653
|
-
})
|
2654
|
-
})
|
2655
|
-
});
|
2656
|
-
const {
|
2657
|
-
useGetContentTypeConfigurationQuery,
|
2658
|
-
useGetAllContentTypeSettingsQuery,
|
2659
|
-
useUpdateContentTypeConfigurationMutation
|
2660
|
-
} = contentTypesApi;
|
2661
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2662
|
-
const { type } = attribute;
|
2663
|
-
if (type === "relation") {
|
2664
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2665
|
-
}
|
2666
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2667
|
-
};
|
2668
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2669
|
-
if (!mainFieldName) {
|
2670
|
-
return void 0;
|
2671
|
-
}
|
2672
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2673
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2674
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2675
|
-
);
|
2676
|
-
return {
|
2677
|
-
name: mainFieldName,
|
2678
|
-
type: mainFieldType ?? "string"
|
2679
|
-
};
|
2680
|
-
};
|
2681
|
-
const DEFAULT_SETTINGS = {
|
2682
|
-
bulkable: false,
|
2683
|
-
filterable: false,
|
2684
|
-
searchable: false,
|
2685
|
-
pagination: false,
|
2686
|
-
defaultSortBy: "",
|
2687
|
-
defaultSortOrder: "asc",
|
2688
|
-
mainField: "id",
|
2689
|
-
pageSize: 10
|
2690
|
-
};
|
2691
|
-
const useDocumentLayout = (model) => {
|
2692
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2693
|
-
const [{ query }] = useQueryParams();
|
2694
|
-
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2695
|
-
const { toggleNotification } = useNotification();
|
2696
|
-
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
2697
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2698
|
-
const {
|
2699
|
-
data,
|
2700
|
-
isLoading: isLoadingConfigs,
|
2701
|
-
error,
|
2702
|
-
isFetching: isFetchingConfigs
|
2703
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2704
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2705
|
-
React.useEffect(() => {
|
2706
|
-
if (error) {
|
2707
|
-
toggleNotification({
|
2708
|
-
type: "danger",
|
2709
|
-
message: formatAPIError(error)
|
2710
|
-
});
|
2711
|
-
}
|
2712
|
-
}, [error, formatAPIError, toggleNotification]);
|
2713
|
-
const editLayout = React.useMemo(
|
2714
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2715
|
-
layout: [],
|
2716
|
-
components: {},
|
2717
|
-
metadatas: {},
|
2718
|
-
options: {},
|
2719
|
-
settings: DEFAULT_SETTINGS
|
2720
|
-
},
|
2721
|
-
[data, isLoading, schemas, schema, components]
|
2722
|
-
);
|
2723
|
-
const listLayout = React.useMemo(() => {
|
2724
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2725
|
-
layout: [],
|
2726
|
-
metadatas: {},
|
2727
|
-
options: {},
|
2728
|
-
settings: DEFAULT_SETTINGS
|
2729
|
-
};
|
2730
|
-
}, [data, isLoading, schemas, schema, components]);
|
2731
|
-
const { layout: edit } = React.useMemo(
|
2732
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2733
|
-
layout: editLayout,
|
2734
|
-
query
|
2735
|
-
}),
|
2736
|
-
[editLayout, query, runHookWaterfall]
|
2737
|
-
);
|
2738
|
-
return {
|
2739
|
-
error,
|
2740
|
-
isLoading,
|
2741
|
-
edit,
|
2742
|
-
list: listLayout
|
2743
|
-
};
|
2744
|
-
};
|
2745
|
-
const useDocLayout = () => {
|
2746
|
-
const { model } = useDoc();
|
2747
|
-
return useDocumentLayout(model);
|
2748
|
-
};
|
2749
|
-
const formatEditLayout = (data, {
|
2750
|
-
schemas,
|
2751
|
-
schema,
|
2752
|
-
components
|
2753
|
-
}) => {
|
2754
|
-
let currentPanelIndex = 0;
|
2755
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2756
|
-
data.contentType.layouts.edit,
|
2757
|
-
schema?.attributes,
|
2758
|
-
data.contentType.metadatas,
|
2759
|
-
{ configurations: data.components, schemas: components },
|
2760
|
-
schemas
|
2761
|
-
).reduce((panels, row) => {
|
2762
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2763
|
-
panels.push([row]);
|
2764
|
-
currentPanelIndex += 2;
|
2765
|
-
} else {
|
2766
|
-
if (!panels[currentPanelIndex]) {
|
2767
|
-
panels.push([]);
|
2768
|
-
}
|
2769
|
-
panels[currentPanelIndex].push(row);
|
2770
|
-
}
|
2771
|
-
return panels;
|
2772
|
-
}, []);
|
2773
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2774
|
-
(acc, [uid, configuration]) => {
|
2775
|
-
acc[uid] = {
|
2776
|
-
layout: convertEditLayoutToFieldLayouts(
|
2777
|
-
configuration.layouts.edit,
|
2778
|
-
components[uid].attributes,
|
2779
|
-
configuration.metadatas,
|
2780
|
-
{ configurations: data.components, schemas: components }
|
2781
|
-
),
|
2782
|
-
settings: {
|
2783
|
-
...configuration.settings,
|
2784
|
-
icon: components[uid].info.icon,
|
2785
|
-
displayName: components[uid].info.displayName
|
2988
|
+
locale: "*"
|
2989
|
+
}
|
2990
|
+
});
|
2991
|
+
if (!("error" in res)) {
|
2992
|
+
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2993
|
+
}
|
2994
|
+
} finally {
|
2995
|
+
if (!listViewPathMatch) {
|
2996
|
+
setSubmitting(false);
|
2997
|
+
}
|
2786
2998
|
}
|
2787
|
-
}
|
2788
|
-
return acc;
|
2789
|
-
},
|
2790
|
-
{}
|
2791
|
-
);
|
2792
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2793
|
-
(acc, [attribute, metadata]) => {
|
2794
|
-
return {
|
2795
|
-
...acc,
|
2796
|
-
[attribute]: metadata.edit
|
2797
|
-
};
|
2798
|
-
},
|
2799
|
-
{}
|
2800
|
-
);
|
2801
|
-
return {
|
2802
|
-
layout: panelledEditAttributes,
|
2803
|
-
components: componentEditAttributes,
|
2804
|
-
metadatas: editMetadatas,
|
2805
|
-
settings: {
|
2806
|
-
...data.contentType.settings,
|
2807
|
-
displayName: schema?.info.displayName
|
2999
|
+
}
|
2808
3000
|
},
|
2809
|
-
|
2810
|
-
|
2811
|
-
...schema?.pluginOptions,
|
2812
|
-
...data.contentType.options
|
2813
|
-
}
|
3001
|
+
variant: "danger",
|
3002
|
+
position: ["header", "table-row"]
|
2814
3003
|
};
|
2815
3004
|
};
|
2816
|
-
|
2817
|
-
|
2818
|
-
|
2819
|
-
|
2820
|
-
|
2821
|
-
|
2822
|
-
|
2823
|
-
|
2824
|
-
|
2825
|
-
|
2826
|
-
|
2827
|
-
|
2828
|
-
|
2829
|
-
|
2830
|
-
|
2831
|
-
|
2832
|
-
|
2833
|
-
|
2834
|
-
|
2835
|
-
|
2836
|
-
|
2837
|
-
|
2838
|
-
|
2839
|
-
|
2840
|
-
|
2841
|
-
|
2842
|
-
|
2843
|
-
|
2844
|
-
|
3005
|
+
DeleteAction$1.type = "delete";
|
3006
|
+
DeleteAction$1.position = ["header", "table-row"];
|
3007
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
3008
|
+
const Panels = () => {
|
3009
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
3010
|
+
const [
|
3011
|
+
{
|
3012
|
+
query: { status }
|
3013
|
+
}
|
3014
|
+
] = useQueryParams({
|
3015
|
+
status: "draft"
|
3016
|
+
});
|
3017
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
3018
|
+
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
3019
|
+
const props = {
|
3020
|
+
activeTab: status,
|
3021
|
+
model,
|
3022
|
+
documentId: id,
|
3023
|
+
document: isCloning ? void 0 : document,
|
3024
|
+
meta: isCloning ? void 0 : meta,
|
3025
|
+
collectionType
|
3026
|
+
};
|
3027
|
+
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
3028
|
+
DescriptionComponentRenderer,
|
3029
|
+
{
|
3030
|
+
props,
|
3031
|
+
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
3032
|
+
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
3033
|
+
}
|
3034
|
+
) });
|
2845
3035
|
};
|
2846
|
-
const
|
2847
|
-
|
2848
|
-
schema,
|
2849
|
-
components
|
2850
|
-
}) => {
|
2851
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2852
|
-
(acc, [attribute, metadata]) => {
|
2853
|
-
return {
|
2854
|
-
...acc,
|
2855
|
-
[attribute]: metadata.list
|
2856
|
-
};
|
2857
|
-
},
|
2858
|
-
{}
|
2859
|
-
);
|
2860
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2861
|
-
data.contentType.layouts.list,
|
2862
|
-
schema?.attributes,
|
2863
|
-
listMetadatas,
|
2864
|
-
{ configurations: data.components, schemas: components },
|
2865
|
-
schemas
|
2866
|
-
);
|
3036
|
+
const ActionsPanel = () => {
|
3037
|
+
const { formatMessage } = useIntl();
|
2867
3038
|
return {
|
2868
|
-
|
2869
|
-
|
2870
|
-
|
2871
|
-
|
2872
|
-
|
2873
|
-
...schema?.pluginOptions,
|
2874
|
-
...data.contentType.options
|
2875
|
-
}
|
3039
|
+
title: formatMessage({
|
3040
|
+
id: "content-manager.containers.edit.panels.default.title",
|
3041
|
+
defaultMessage: "Entry"
|
3042
|
+
}),
|
3043
|
+
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2876
3044
|
};
|
2877
3045
|
};
|
2878
|
-
|
2879
|
-
|
2880
|
-
|
2881
|
-
|
2882
|
-
|
3046
|
+
ActionsPanel.type = "actions";
|
3047
|
+
const ActionsPanelContent = () => {
|
3048
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
3049
|
+
const [
|
3050
|
+
{
|
3051
|
+
query: { status = "draft" }
|
2883
3052
|
}
|
2884
|
-
|
2885
|
-
|
2886
|
-
|
2887
|
-
|
2888
|
-
|
2889
|
-
|
2890
|
-
|
2891
|
-
|
2892
|
-
|
2893
|
-
|
2894
|
-
|
2895
|
-
|
2896
|
-
|
2897
|
-
|
3053
|
+
] = useQueryParams();
|
3054
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
3055
|
+
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
3056
|
+
const props = {
|
3057
|
+
activeTab: status,
|
3058
|
+
model,
|
3059
|
+
documentId: id,
|
3060
|
+
document: isCloning ? void 0 : document,
|
3061
|
+
meta: isCloning ? void 0 : meta,
|
3062
|
+
collectionType
|
3063
|
+
};
|
3064
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
3065
|
+
/* @__PURE__ */ jsx(
|
3066
|
+
DescriptionComponentRenderer,
|
3067
|
+
{
|
3068
|
+
props,
|
3069
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("panel"),
|
3070
|
+
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
3071
|
+
}
|
3072
|
+
),
|
3073
|
+
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
3074
|
+
] });
|
2898
3075
|
};
|
3076
|
+
const Panel = React.forwardRef(({ children, title }, ref) => {
|
3077
|
+
return /* @__PURE__ */ jsxs(
|
3078
|
+
Flex,
|
3079
|
+
{
|
3080
|
+
ref,
|
3081
|
+
tag: "aside",
|
3082
|
+
"aria-labelledby": "additional-information",
|
3083
|
+
background: "neutral0",
|
3084
|
+
borderColor: "neutral150",
|
3085
|
+
hasRadius: true,
|
3086
|
+
paddingBottom: 4,
|
3087
|
+
paddingLeft: 4,
|
3088
|
+
paddingRight: 4,
|
3089
|
+
paddingTop: 4,
|
3090
|
+
shadow: "tableShadow",
|
3091
|
+
gap: 3,
|
3092
|
+
direction: "column",
|
3093
|
+
justifyContent: "stretch",
|
3094
|
+
alignItems: "flex-start",
|
3095
|
+
children: [
|
3096
|
+
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", textColor: "neutral600", children: title }),
|
3097
|
+
children
|
3098
|
+
]
|
3099
|
+
}
|
3100
|
+
);
|
3101
|
+
});
|
2899
3102
|
const ConfirmBulkActionDialog = ({
|
2900
3103
|
onToggleDialog,
|
2901
3104
|
isOpen = false,
|
@@ -3140,18 +3343,10 @@ const SelectedEntriesTableContent = ({
|
|
3140
3343
|
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3141
3344
|
},
|
3142
3345
|
state: { from: pathname },
|
3143
|
-
label: formatMessage(
|
3144
|
-
|
3145
|
-
|
3146
|
-
|
3147
|
-
{
|
3148
|
-
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3149
|
-
defaultMessage: "item line {number}"
|
3150
|
-
},
|
3151
|
-
{ number: index2 + 1 }
|
3152
|
-
)
|
3153
|
-
}
|
3154
|
-
),
|
3346
|
+
label: formatMessage({
|
3347
|
+
id: "content-manager.bulk-publish.edit",
|
3348
|
+
defaultMessage: "Edit"
|
3349
|
+
}),
|
3155
3350
|
target: "_blank",
|
3156
3351
|
marginLeft: "auto",
|
3157
3352
|
variant: "ghost",
|
@@ -3325,8 +3520,7 @@ const PublishAction = ({ documents, model }) => {
|
|
3325
3520
|
const refetchList = () => {
|
3326
3521
|
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3327
3522
|
};
|
3328
|
-
if (!showPublishButton)
|
3329
|
-
return null;
|
3523
|
+
if (!showPublishButton) return null;
|
3330
3524
|
return {
|
3331
3525
|
actionType: "publish",
|
3332
3526
|
variant: "tertiary",
|
@@ -3394,8 +3588,7 @@ const DeleteAction = ({ documents, model }) => {
|
|
3394
3588
|
selectRow([]);
|
3395
3589
|
}
|
3396
3590
|
};
|
3397
|
-
if (!hasDeletePermission)
|
3398
|
-
return null;
|
3591
|
+
if (!hasDeletePermission) return null;
|
3399
3592
|
return {
|
3400
3593
|
variant: "danger-light",
|
3401
3594
|
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
@@ -3444,8 +3637,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3444
3637
|
}
|
3445
3638
|
};
|
3446
3639
|
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3447
|
-
if (!showUnpublishButton)
|
3448
|
-
return null;
|
3640
|
+
if (!showUnpublishButton) return null;
|
3449
3641
|
return {
|
3450
3642
|
variant: "tertiary",
|
3451
3643
|
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
@@ -3550,7 +3742,7 @@ const TableActions = ({ document }) => {
|
|
3550
3742
|
DescriptionComponentRenderer,
|
3551
3743
|
{
|
3552
3744
|
props,
|
3553
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3745
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("table-row").filter((action) => action.name !== "PublishAction"),
|
3554
3746
|
children: (actions2) => {
|
3555
3747
|
const tableRowActions = actions2.filter((action) => {
|
3556
3748
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3609,6 +3801,7 @@ const EditAction = ({ documentId }) => {
|
|
3609
3801
|
};
|
3610
3802
|
};
|
3611
3803
|
EditAction.type = "edit";
|
3804
|
+
EditAction.position = "table-row";
|
3612
3805
|
const StyledPencil = styled(Pencil)`
|
3613
3806
|
path {
|
3614
3807
|
fill: currentColor;
|
@@ -3685,6 +3878,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3685
3878
|
};
|
3686
3879
|
};
|
3687
3880
|
CloneAction.type = "clone";
|
3881
|
+
CloneAction.position = "table-row";
|
3688
3882
|
const StyledDuplicate = styled(Duplicate)`
|
3689
3883
|
path {
|
3690
3884
|
fill: currentColor;
|
@@ -3771,7 +3965,14 @@ class ContentManagerPlugin {
|
|
3771
3965
|
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3772
3966
|
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3773
3967
|
getBulkActions: () => this.bulkActions,
|
3774
|
-
getDocumentActions: () =>
|
3968
|
+
getDocumentActions: (position) => {
|
3969
|
+
if (position) {
|
3970
|
+
return this.documentActions.filter(
|
3971
|
+
(action) => action.position == void 0 || [action.position].flat().includes(position)
|
3972
|
+
);
|
3973
|
+
}
|
3974
|
+
return this.documentActions;
|
3975
|
+
},
|
3775
3976
|
getEditViewSidePanels: () => this.editViewSidePanels,
|
3776
3977
|
getHeaderActions: () => this.headerActions
|
3777
3978
|
}
|
@@ -3781,10 +3982,8 @@ class ContentManagerPlugin {
|
|
3781
3982
|
const getPrintableType = (value) => {
|
3782
3983
|
const nativeType = typeof value;
|
3783
3984
|
if (nativeType === "object") {
|
3784
|
-
if (value === null)
|
3785
|
-
|
3786
|
-
if (Array.isArray(value))
|
3787
|
-
return "array";
|
3985
|
+
if (value === null) return "null";
|
3986
|
+
if (Array.isArray(value)) return "array";
|
3788
3987
|
if (value instanceof Object && value.constructor.name !== "Object") {
|
3789
3988
|
return value.constructor.name;
|
3790
3989
|
}
|
@@ -3795,17 +3994,27 @@ const HistoryAction = ({ model, document }) => {
|
|
3795
3994
|
const { formatMessage } = useIntl();
|
3796
3995
|
const [{ query }] = useQueryParams();
|
3797
3996
|
const navigate = useNavigate();
|
3997
|
+
const { trackUsage } = useTracking();
|
3998
|
+
const { pathname } = useLocation();
|
3798
3999
|
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
3799
4000
|
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3800
4001
|
return null;
|
3801
4002
|
}
|
4003
|
+
const handleOnClick = () => {
|
4004
|
+
const destination = { pathname: "history", search: pluginsQueryParams };
|
4005
|
+
trackUsage("willNavigate", {
|
4006
|
+
from: pathname,
|
4007
|
+
to: `${pathname}/${destination.pathname}`
|
4008
|
+
});
|
4009
|
+
navigate(destination);
|
4010
|
+
};
|
3802
4011
|
return {
|
3803
4012
|
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
3804
4013
|
label: formatMessage({
|
3805
4014
|
id: "content-manager.history.document-action",
|
3806
4015
|
defaultMessage: "Content History"
|
3807
4016
|
}),
|
3808
|
-
onClick:
|
4017
|
+
onClick: handleOnClick,
|
3809
4018
|
disabled: (
|
3810
4019
|
/**
|
3811
4020
|
* The user is creating a new document.
|
@@ -3827,6 +4036,7 @@ const HistoryAction = ({ model, document }) => {
|
|
3827
4036
|
};
|
3828
4037
|
};
|
3829
4038
|
HistoryAction.type = "history";
|
4039
|
+
HistoryAction.position = "header";
|
3830
4040
|
const historyAdmin = {
|
3831
4041
|
bootstrap(app) {
|
3832
4042
|
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
@@ -3873,6 +4083,88 @@ const { setInitialData } = actions;
|
|
3873
4083
|
const reducer = combineReducers({
|
3874
4084
|
app: reducer$1
|
3875
4085
|
});
|
4086
|
+
const previewApi = contentManagerApi.injectEndpoints({
|
4087
|
+
endpoints: (builder) => ({
|
4088
|
+
getPreviewUrl: builder.query({
|
4089
|
+
query({ query, params }) {
|
4090
|
+
return {
|
4091
|
+
url: `/content-manager/preview/url/${params.contentType}`,
|
4092
|
+
method: "GET",
|
4093
|
+
config: {
|
4094
|
+
params: query
|
4095
|
+
}
|
4096
|
+
};
|
4097
|
+
}
|
4098
|
+
})
|
4099
|
+
})
|
4100
|
+
});
|
4101
|
+
const { useGetPreviewUrlQuery } = previewApi;
|
4102
|
+
const ConditionalTooltip = ({ isShown, label, children }) => {
|
4103
|
+
if (isShown) {
|
4104
|
+
return /* @__PURE__ */ jsx(Tooltip, { label, children });
|
4105
|
+
}
|
4106
|
+
return children;
|
4107
|
+
};
|
4108
|
+
const PreviewSidePanel = ({ model, documentId, document }) => {
|
4109
|
+
const { formatMessage } = useIntl();
|
4110
|
+
const { trackUsage } = useTracking();
|
4111
|
+
const { pathname } = useLocation();
|
4112
|
+
const [{ query }] = useQueryParams();
|
4113
|
+
const isModified = useForm("PreviewSidePanel", (state) => state.modified);
|
4114
|
+
const { data, error } = useGetPreviewUrlQuery({
|
4115
|
+
params: {
|
4116
|
+
contentType: model
|
4117
|
+
},
|
4118
|
+
query: {
|
4119
|
+
documentId,
|
4120
|
+
locale: document?.locale,
|
4121
|
+
status: document?.status
|
4122
|
+
}
|
4123
|
+
});
|
4124
|
+
if (!data?.data?.url || error) {
|
4125
|
+
return null;
|
4126
|
+
}
|
4127
|
+
const trackNavigation = () => {
|
4128
|
+
const destinationPathname = pathname.replace(/\/$/, "") + "/preview";
|
4129
|
+
trackUsage("willNavigate", { from: pathname, to: destinationPathname });
|
4130
|
+
};
|
4131
|
+
return {
|
4132
|
+
title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
|
4133
|
+
content: /* @__PURE__ */ jsx(
|
4134
|
+
ConditionalTooltip,
|
4135
|
+
{
|
4136
|
+
label: formatMessage({
|
4137
|
+
id: "content-manager.preview.panel.button-disabled-tooltip",
|
4138
|
+
defaultMessage: "Please save to open the preview"
|
4139
|
+
}),
|
4140
|
+
isShown: isModified,
|
4141
|
+
children: /* @__PURE__ */ jsx(Box, { cursor: "not-allowed", width: "100%", children: /* @__PURE__ */ jsx(
|
4142
|
+
Button,
|
4143
|
+
{
|
4144
|
+
variant: "tertiary",
|
4145
|
+
tag: Link,
|
4146
|
+
to: { pathname: "preview", search: stringify(query, { encode: false }) },
|
4147
|
+
onClick: trackNavigation,
|
4148
|
+
width: "100%",
|
4149
|
+
disabled: isModified,
|
4150
|
+
pointerEvents: isModified ? "none" : void 0,
|
4151
|
+
tabIndex: isModified ? -1 : void 0,
|
4152
|
+
children: formatMessage({
|
4153
|
+
id: "content-manager.preview.panel.button",
|
4154
|
+
defaultMessage: "Open preview"
|
4155
|
+
})
|
4156
|
+
}
|
4157
|
+
) })
|
4158
|
+
}
|
4159
|
+
)
|
4160
|
+
};
|
4161
|
+
};
|
4162
|
+
const previewAdmin = {
|
4163
|
+
bootstrap(app) {
|
4164
|
+
const contentManagerPluginApis = app.getPlugin("content-manager").apis;
|
4165
|
+
contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
|
4166
|
+
}
|
4167
|
+
};
|
3876
4168
|
const index = {
|
3877
4169
|
register(app) {
|
3878
4170
|
const cm = new ContentManagerPlugin();
|
@@ -3892,7 +4184,7 @@ const index = {
|
|
3892
4184
|
app.router.addRoute({
|
3893
4185
|
path: "content-manager/*",
|
3894
4186
|
lazy: async () => {
|
3895
|
-
const { Layout } = await import("./layout-
|
4187
|
+
const { Layout } = await import("./layout-B5qsPihj.mjs");
|
3896
4188
|
return {
|
3897
4189
|
Component: Layout
|
3898
4190
|
};
|
@@ -3905,11 +4197,14 @@ const index = {
|
|
3905
4197
|
if (typeof historyAdmin.bootstrap === "function") {
|
3906
4198
|
historyAdmin.bootstrap(app);
|
3907
4199
|
}
|
4200
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
4201
|
+
previewAdmin.bootstrap(app);
|
4202
|
+
}
|
3908
4203
|
},
|
3909
4204
|
async registerTrads({ locales }) {
|
3910
4205
|
const importedTrads = await Promise.all(
|
3911
4206
|
locales.map((locale) => {
|
3912
|
-
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-
|
4207
|
+
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-Dtk_ot79.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 }) => {
|
3913
4208
|
return {
|
3914
4209
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3915
4210
|
locale
|
@@ -3936,8 +4231,10 @@ export {
|
|
3936
4231
|
HOOKS as H,
|
3937
4232
|
InjectionZone as I,
|
3938
4233
|
useDocument as J,
|
3939
|
-
|
3940
|
-
|
4234
|
+
useGetPreviewUrlQuery as K,
|
4235
|
+
index as L,
|
4236
|
+
useContentManagerContext as M,
|
4237
|
+
useDocumentActions as N,
|
3941
4238
|
Panels as P,
|
3942
4239
|
RelativeTime as R,
|
3943
4240
|
SINGLE_TYPES as S,
|
@@ -3969,4 +4266,4 @@ export {
|
|
3969
4266
|
capitalise as y,
|
3970
4267
|
useUpdateContentTypeConfigurationMutation as z
|
3971
4268
|
};
|
3972
|
-
//# sourceMappingURL=index-
|
4269
|
+
//# sourceMappingURL=index-Dh2aGTGJ.mjs.map
|