@strapi/content-manager 0.0.0-experimental.afa3b513b8f95459043f33fb94f4bac03af1474f → 0.0.0-experimental.b05633daea1bf090c66312b8ab30ec13bdb52f57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -1
- package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-CnL10QYC.mjs → ComponentConfigurationPage-A5f-t42A.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-CnL10QYC.mjs.map → ComponentConfigurationPage-A5f-t42A.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-G4EIirP8.js → ComponentConfigurationPage-BtmEfYUS.js} +5 -6
- package/dist/_chunks/{ComponentConfigurationPage-G4EIirP8.js.map → ComponentConfigurationPage-BtmEfYUS.js.map} +1 -1
- package/dist/_chunks/{ComponentIcon-BXdiCGQp.js → ComponentIcon-CRbtQEUV.js} +2 -3
- package/dist/_chunks/{ComponentIcon-BXdiCGQp.js.map → ComponentIcon-CRbtQEUV.js.map} +1 -1
- package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -1
- package/dist/_chunks/{EditConfigurationPage-B2AA1kVF.js → EditConfigurationPage-CXLQhPpj.js} +5 -6
- package/dist/_chunks/{EditConfigurationPage-B2AA1kVF.js.map → EditConfigurationPage-CXLQhPpj.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-I2kKh9dx.mjs → EditConfigurationPage-DN6yaDFZ.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-I2kKh9dx.mjs.map → EditConfigurationPage-DN6yaDFZ.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-CHgoNwlc.js → EditViewPage-BW-BJJVg.js} +50 -11
- package/dist/_chunks/EditViewPage-BW-BJJVg.js.map +1 -0
- package/dist/_chunks/{EditViewPage-zFjJK0s8.mjs → EditViewPage-ONky_-8U.mjs} +50 -10
- package/dist/_chunks/EditViewPage-ONky_-8U.mjs.map +1 -0
- package/dist/_chunks/{Field-DPAzUS1M.mjs → Field-B4gAYDmQ.mjs} +215 -92
- package/dist/_chunks/Field-B4gAYDmQ.mjs.map +1 -0
- package/dist/_chunks/{Field-9DePZh-0.js → Field-BMlzghtV.js} +217 -94
- package/dist/_chunks/Field-BMlzghtV.js.map +1 -0
- package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
- package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
- package/dist/_chunks/{Form-DPm-KZ1A.js → Form-DQPyv3UY.js} +6 -7
- package/dist/_chunks/Form-DQPyv3UY.js.map +1 -0
- package/dist/_chunks/{Form-CEkENbkF.mjs → Form-e4RpNQY0.mjs} +4 -4
- package/dist/_chunks/Form-e4RpNQY0.mjs.map +1 -0
- package/dist/_chunks/{History-utls71em.mjs → History-Bk2VCzmJ.mjs} +43 -100
- package/dist/_chunks/History-Bk2VCzmJ.mjs.map +1 -0
- package/dist/_chunks/{History-DXSbTWez.js → History-CzkXjAR0.js} +42 -100
- package/dist/_chunks/History-CzkXjAR0.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-D5C7ACZ_.js → ListConfigurationPage-B9TbaEqp.js} +7 -7
- package/dist/_chunks/ListConfigurationPage-B9TbaEqp.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-CuMXWWqb.mjs → ListConfigurationPage-BhNCzkQd.mjs} +7 -6
- package/dist/_chunks/ListConfigurationPage-BhNCzkQd.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-DfuwH1tt.js → ListViewPage-CIHO4H2J.js} +64 -42
- package/dist/_chunks/ListViewPage-CIHO4H2J.js.map +1 -0
- package/dist/_chunks/{ListViewPage-CdKd-PS_.mjs → ListViewPage-mK-sFVGU.mjs} +63 -40
- package/dist/_chunks/ListViewPage-mK-sFVGU.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DkToTT7u.mjs → NoContentTypePage-BSVg7nZI.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-DkToTT7u.mjs.map → NoContentTypePage-BSVg7nZI.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-BIxlkWWi.js → NoContentTypePage-Dbfi49ek.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-BIxlkWWi.js.map → NoContentTypePage-Dbfi49ek.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-Bu4GWYb-.js → NoPermissionsPage-CDvWOtEy.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-Bu4GWYb-.js.map → NoPermissionsPage-CDvWOtEy.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DlWi4BAH.mjs → NoPermissionsPage-zpYME1_X.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DlWi4BAH.mjs.map → NoPermissionsPage-zpYME1_X.mjs.map} +1 -1
- package/dist/_chunks/Preview-8U27vy1U.js +311 -0
- package/dist/_chunks/Preview-8U27vy1U.js.map +1 -0
- package/dist/_chunks/Preview-Dd3kQluA.mjs +293 -0
- package/dist/_chunks/Preview-Dd3kQluA.mjs.map +1 -0
- package/dist/_chunks/{Relations-QP5yn9_z.mjs → Relations-BvdARGTL.mjs} +75 -41
- package/dist/_chunks/Relations-BvdARGTL.mjs.map +1 -0
- package/dist/_chunks/{Relations-CFjTESWQ.js → Relations-CFMS6Dm8.js} +75 -42
- package/dist/_chunks/Relations-CFMS6Dm8.js.map +1 -0
- package/dist/_chunks/{en-BVzUkPxZ.js → en-BzQmavmK.js} +28 -11
- package/dist/_chunks/{en-BVzUkPxZ.js.map → en-BzQmavmK.js.map} +1 -1
- package/dist/_chunks/{en-CPTj6CjC.mjs → en-CSxLmrh1.mjs} +28 -11
- package/dist/_chunks/{en-CPTj6CjC.mjs.map → en-CSxLmrh1.mjs.map} +1 -1
- package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
- package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
- package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
- package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
- package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
- package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
- package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
- package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
- package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
- package/dist/_chunks/{index-BHfS6_D5.mjs → index-B3tHjkLZ.mjs} +971 -724
- package/dist/_chunks/index-B3tHjkLZ.mjs.map +1 -0
- package/dist/_chunks/{index-DXiHxy70.js → index-TSBwtMDV.js} +969 -722
- package/dist/_chunks/index-TSBwtMDV.js.map +1 -0
- package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
- package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
- package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
- package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
- package/dist/_chunks/{layout-DX_52HSH.mjs → layout-C71zeI19.mjs} +4 -4
- package/dist/_chunks/{layout-DX_52HSH.mjs.map → layout-C71zeI19.mjs.map} +1 -1
- package/dist/_chunks/{layout-bE-WUnQ0.js → layout-CB2vrWLp.js} +5 -6
- package/dist/_chunks/{layout-bE-WUnQ0.js.map → layout-CB2vrWLp.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-D706vblp.js → relations-8mON7ZVQ.js} +6 -7
- package/dist/_chunks/relations-8mON7ZVQ.js.map +1 -0
- package/dist/_chunks/{relations-SCVAL_aJ.mjs → relations-DcEHhh0U.mjs} +6 -7
- package/dist/_chunks/relations-DcEHhh0U.mjs.map +1 -0
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -1
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -1
- package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
- package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
- package/dist/admin/index.js +3 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +5 -3
- package/dist/admin/src/content-manager.d.ts +3 -2
- package/dist/admin/src/exports.d.ts +2 -1
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +3 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +7 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/Header.d.ts +1 -0
- package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
- package/dist/admin/src/preview/index.d.ts +4 -0
- package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
- package/dist/admin/src/preview/routes.d.ts +3 -0
- package/dist/admin/src/preview/services/preview.d.ts +3 -0
- package/dist/admin/src/router.d.ts +1 -1
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +16 -19
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/server/index.js +432 -194
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +432 -193
- 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 +15 -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 +4 -4
- 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 +8 -8
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +4 -4
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
- package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/shared/contracts/index.d.ts +1 -0
- package/dist/shared/contracts/index.d.ts.map +1 -1
- package/dist/shared/contracts/preview.d.ts +27 -0
- package/dist/shared/contracts/preview.d.ts.map +1 -0
- package/dist/shared/index.js +4 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +4 -0
- package/dist/shared/index.mjs.map +1 -1
- package/package.json +14 -12
- package/dist/_chunks/EditViewPage-CHgoNwlc.js.map +0 -1
- package/dist/_chunks/EditViewPage-zFjJK0s8.mjs.map +0 -1
- package/dist/_chunks/Field-9DePZh-0.js.map +0 -1
- package/dist/_chunks/Field-DPAzUS1M.mjs.map +0 -1
- package/dist/_chunks/Form-CEkENbkF.mjs.map +0 -1
- package/dist/_chunks/Form-DPm-KZ1A.js.map +0 -1
- package/dist/_chunks/History-DXSbTWez.js.map +0 -1
- package/dist/_chunks/History-utls71em.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-CuMXWWqb.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-D5C7ACZ_.js.map +0 -1
- package/dist/_chunks/ListViewPage-CdKd-PS_.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-DfuwH1tt.js.map +0 -1
- package/dist/_chunks/Relations-CFjTESWQ.js.map +0 -1
- package/dist/_chunks/Relations-QP5yn9_z.mjs.map +0 -1
- package/dist/_chunks/index-BHfS6_D5.mjs.map +0 -1
- package/dist/_chunks/index-DXiHxy70.js.map +0 -1
- package/dist/_chunks/relations-D706vblp.js.map +0 -1
- package/dist/_chunks/relations-SCVAL_aJ.mjs.map +0 -1
@@ -1,25 +1,33 @@
|
|
1
1
|
import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check, CrossCircle, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
|
2
2
|
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
3
|
-
import { useStrapiApp, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors,
|
3
|
+
import { useStrapiApp, createContext, useQueryParams, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useForm, useTracking, useGuidedTour, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
|
4
4
|
import * as React from "react";
|
5
5
|
import { lazy } from "react";
|
6
|
-
import {
|
6
|
+
import { Menu, Button, VisuallyHidden, Flex, Dialog, Modal, Typography, Radio, Status, Box, SingleSelect, SingleSelectOption, IconButton, Loader, Tooltip, LinkButton } from "@strapi/design-system";
|
7
|
+
import mapValues from "lodash/fp/mapValues";
|
7
8
|
import { useIntl } from "react-intl";
|
8
9
|
import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
10
|
+
import { styled } from "styled-components";
|
9
11
|
import * as yup from "yup";
|
10
12
|
import { ValidationError } from "yup";
|
13
|
+
import { stringify } from "qs";
|
11
14
|
import pipe from "lodash/fp/pipe";
|
12
15
|
import { intervalToDuration, isPast } from "date-fns";
|
13
|
-
import { styled } from "styled-components";
|
14
|
-
import { stringify } from "qs";
|
15
16
|
import { createSlice, combineReducers } from "@reduxjs/toolkit";
|
16
|
-
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
17
|
+
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
17
18
|
const v = glob[path];
|
18
19
|
if (v) {
|
19
20
|
return typeof v === "function" ? v() : Promise.resolve(v);
|
20
21
|
}
|
21
22
|
return new Promise((_, reject) => {
|
22
|
-
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
23
|
+
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
24
|
+
reject.bind(
|
25
|
+
null,
|
26
|
+
new Error(
|
27
|
+
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
28
|
+
)
|
29
|
+
)
|
30
|
+
);
|
23
31
|
});
|
24
32
|
};
|
25
33
|
const PLUGIN_ID = "content-manager";
|
@@ -100,6 +108,7 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
100
108
|
if (!slug) {
|
101
109
|
throw new Error("Cannot find the slug param in the URL");
|
102
110
|
}
|
111
|
+
const [{ rawQuery }] = useQueryParams();
|
103
112
|
const userPermissions = useAuth("DocumentRBAC", (state) => state.permissions);
|
104
113
|
const contentTypePermissions = React.useMemo(() => {
|
105
114
|
const contentTypePermissions2 = userPermissions.filter(
|
@@ -110,7 +119,14 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
110
119
|
return { ...acc, [action]: [permission] };
|
111
120
|
}, {});
|
112
121
|
}, [slug, userPermissions]);
|
113
|
-
const { isLoading, allowedActions } = useRBAC(
|
122
|
+
const { isLoading, allowedActions } = useRBAC(
|
123
|
+
contentTypePermissions,
|
124
|
+
permissions ?? void 0,
|
125
|
+
// TODO: useRBAC context should be typed and built differently
|
126
|
+
// We are passing raw query as context to the hook so that it can
|
127
|
+
// rely on the locale provided from DocumentRBAC for its permission calculations.
|
128
|
+
rawQuery
|
129
|
+
);
|
114
130
|
const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
|
115
131
|
const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
|
116
132
|
const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
|
@@ -159,7 +175,8 @@ const contentManagerApi = adminApi.enhanceEndpoints({
|
|
159
175
|
"InitialData",
|
160
176
|
"HistoryVersion",
|
161
177
|
"Relations",
|
162
|
-
"UidAvailability"
|
178
|
+
"UidAvailability",
|
179
|
+
"RecentDocumentList"
|
163
180
|
]
|
164
181
|
});
|
165
182
|
const documentApi = contentManagerApi.injectEndpoints({
|
@@ -177,7 +194,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
177
194
|
if (error) {
|
178
195
|
return [];
|
179
196
|
}
|
180
|
-
return [{ type: "Document", id: `${model}_LIST` }];
|
197
|
+
return [{ type: "Document", id: `${model}_LIST` }, "RecentDocumentList"];
|
181
198
|
}
|
182
199
|
}),
|
183
200
|
cloneDocument: builder.mutation({
|
@@ -191,7 +208,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
191
208
|
}),
|
192
209
|
invalidatesTags: (_result, _error, { model }) => [
|
193
210
|
{ type: "Document", id: `${model}_LIST` },
|
194
|
-
{ type: "UidAvailability", id: model }
|
211
|
+
{ type: "UidAvailability", id: model },
|
212
|
+
"RecentDocumentList"
|
195
213
|
]
|
196
214
|
}),
|
197
215
|
/**
|
@@ -210,7 +228,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
210
228
|
invalidatesTags: (result, _error, { model }) => [
|
211
229
|
{ type: "Document", id: `${model}_LIST` },
|
212
230
|
"Relations",
|
213
|
-
{ type: "UidAvailability", id: model }
|
231
|
+
{ type: "UidAvailability", id: model },
|
232
|
+
"RecentDocumentList"
|
214
233
|
]
|
215
234
|
}),
|
216
235
|
deleteDocument: builder.mutation({
|
@@ -222,7 +241,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
222
241
|
}
|
223
242
|
}),
|
224
243
|
invalidatesTags: (_result, _error, { collectionType, model }) => [
|
225
|
-
{ type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model }
|
244
|
+
{ type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model },
|
245
|
+
"RecentDocumentList"
|
226
246
|
]
|
227
247
|
}),
|
228
248
|
deleteManyDocuments: builder.mutation({
|
@@ -234,7 +254,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
234
254
|
params
|
235
255
|
}
|
236
256
|
}),
|
237
|
-
invalidatesTags: (_res, _error, { model }) => [
|
257
|
+
invalidatesTags: (_res, _error, { model }) => [
|
258
|
+
{ type: "Document", id: `${model}_LIST` },
|
259
|
+
"RecentDocumentList"
|
260
|
+
]
|
238
261
|
}),
|
239
262
|
discardDocument: builder.mutation({
|
240
263
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -252,7 +275,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
252
275
|
},
|
253
276
|
{ type: "Document", id: `${model}_LIST` },
|
254
277
|
"Relations",
|
255
|
-
{ type: "UidAvailability", id: model }
|
278
|
+
{ type: "UidAvailability", id: model },
|
279
|
+
"RecentDocumentList"
|
256
280
|
];
|
257
281
|
}
|
258
282
|
}),
|
@@ -265,7 +289,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
265
289
|
url: `/content-manager/collection-types/${model}`,
|
266
290
|
method: "GET",
|
267
291
|
config: {
|
268
|
-
params
|
292
|
+
params: stringify(params, { encode: true })
|
269
293
|
}
|
270
294
|
}),
|
271
295
|
providesTags: (result, _error, arg) => {
|
@@ -347,7 +371,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
347
371
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
348
372
|
},
|
349
373
|
{ type: "Document", id: `${model}_LIST` },
|
350
|
-
"Relations"
|
374
|
+
"Relations",
|
375
|
+
"RecentDocumentList"
|
351
376
|
];
|
352
377
|
}
|
353
378
|
}),
|
@@ -378,7 +403,9 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
378
403
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
379
404
|
},
|
380
405
|
"Relations",
|
381
|
-
{ type: "UidAvailability", id: model }
|
406
|
+
{ type: "UidAvailability", id: model },
|
407
|
+
"RecentDocumentList",
|
408
|
+
"RecentDocumentList"
|
382
409
|
];
|
383
410
|
},
|
384
411
|
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
@@ -408,7 +435,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
408
435
|
{
|
409
436
|
type: "Document",
|
410
437
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
411
|
-
}
|
438
|
+
},
|
439
|
+
"RecentDocumentList"
|
412
440
|
];
|
413
441
|
}
|
414
442
|
}),
|
@@ -421,7 +449,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
421
449
|
params
|
422
450
|
}
|
423
451
|
}),
|
424
|
-
invalidatesTags: (_res, _error, { model, documentIds }) =>
|
452
|
+
invalidatesTags: (_res, _error, { model, documentIds }) => [
|
453
|
+
...documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` })),
|
454
|
+
"RecentDocumentList"
|
455
|
+
]
|
425
456
|
})
|
426
457
|
})
|
427
458
|
});
|
@@ -444,8 +475,7 @@ const {
|
|
444
475
|
useUnpublishManyDocumentsMutation
|
445
476
|
} = documentApi;
|
446
477
|
const buildValidParams = (query) => {
|
447
|
-
if (!query)
|
448
|
-
return query;
|
478
|
+
if (!query) return query;
|
449
479
|
const { plugins: _, ...validQueryParams } = {
|
450
480
|
...query,
|
451
481
|
...Object.values(query?.plugins ?? {}).reduce(
|
@@ -453,14 +483,29 @@ const buildValidParams = (query) => {
|
|
453
483
|
{}
|
454
484
|
)
|
455
485
|
};
|
456
|
-
if ("_q" in validQueryParams) {
|
457
|
-
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
458
|
-
}
|
459
486
|
return validQueryParams;
|
460
487
|
};
|
461
488
|
const isBaseQueryError = (error) => {
|
462
489
|
return error.name !== void 0;
|
463
490
|
};
|
491
|
+
const arrayValidator = (attribute, options) => ({
|
492
|
+
message: translatedErrors.required,
|
493
|
+
test(value) {
|
494
|
+
if (options.status === "draft") {
|
495
|
+
return true;
|
496
|
+
}
|
497
|
+
if (!attribute.required) {
|
498
|
+
return true;
|
499
|
+
}
|
500
|
+
if (!value) {
|
501
|
+
return false;
|
502
|
+
}
|
503
|
+
if (Array.isArray(value) && value.length === 0) {
|
504
|
+
return false;
|
505
|
+
}
|
506
|
+
return true;
|
507
|
+
}
|
508
|
+
});
|
464
509
|
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
465
510
|
const createModelSchema = (attributes2) => yup.object().shape(
|
466
511
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
@@ -468,6 +513,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
468
513
|
return acc;
|
469
514
|
}
|
470
515
|
const validations = [
|
516
|
+
addNullableValidation,
|
471
517
|
addRequiredValidation,
|
472
518
|
addMinLengthValidation,
|
473
519
|
addMaxLengthValidation,
|
@@ -484,12 +530,12 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
484
530
|
...acc,
|
485
531
|
[name]: transformSchema(
|
486
532
|
yup.array().of(createModelSchema(attributes3).nullable(false))
|
487
|
-
)
|
533
|
+
).test(arrayValidator(attribute, options))
|
488
534
|
};
|
489
535
|
} else {
|
490
536
|
return {
|
491
537
|
...acc,
|
492
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
538
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
493
539
|
};
|
494
540
|
}
|
495
541
|
}
|
@@ -511,7 +557,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
511
557
|
}
|
512
558
|
)
|
513
559
|
)
|
514
|
-
)
|
560
|
+
).test(arrayValidator(attribute, options))
|
515
561
|
};
|
516
562
|
case "relation":
|
517
563
|
return {
|
@@ -523,7 +569,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
523
569
|
} else if (Array.isArray(value)) {
|
524
570
|
return yup.array().of(
|
525
571
|
yup.object().shape({
|
526
|
-
id: yup.
|
572
|
+
id: yup.number().required()
|
527
573
|
})
|
528
574
|
);
|
529
575
|
} else if (typeof value === "object") {
|
@@ -609,17 +655,17 @@ const nullableSchema = (schema) => {
|
|
609
655
|
schema
|
610
656
|
);
|
611
657
|
};
|
658
|
+
const addNullableValidation = () => (schema) => {
|
659
|
+
return nullableSchema(schema);
|
660
|
+
};
|
612
661
|
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);
|
662
|
+
if (options.status === "draft" || !attribute.required) {
|
663
|
+
return schema;
|
618
664
|
}
|
619
|
-
if (attribute.required &&
|
665
|
+
if (attribute.required && "required" in schema) {
|
620
666
|
return schema.required(translatedErrors.required);
|
621
667
|
}
|
622
|
-
return
|
668
|
+
return schema;
|
623
669
|
};
|
624
670
|
const addMinLengthValidation = (attribute, options) => (schema) => {
|
625
671
|
if (options.status === "draft") {
|
@@ -647,31 +693,12 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
647
693
|
return schema;
|
648
694
|
};
|
649
695
|
const addMinValidation = (attribute, options) => (schema) => {
|
650
|
-
if ("
|
696
|
+
if (options.status === "draft") {
|
697
|
+
return schema;
|
698
|
+
}
|
699
|
+
if ("min" in attribute && "min" in schema) {
|
651
700
|
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) {
|
701
|
+
if (min) {
|
675
702
|
return schema.min(min, {
|
676
703
|
...translatedErrors.min,
|
677
704
|
values: {
|
@@ -789,19 +816,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
789
816
|
}, {});
|
790
817
|
return componentsByKey;
|
791
818
|
};
|
792
|
-
const
|
819
|
+
const HOOKS = {
|
820
|
+
/**
|
821
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
822
|
+
* @constant
|
823
|
+
* @type {string}
|
824
|
+
*/
|
825
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
826
|
+
/**
|
827
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
828
|
+
* @constant
|
829
|
+
* @type {string}
|
830
|
+
*/
|
831
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
832
|
+
/**
|
833
|
+
* Hook that allows to mutate the CM's edit view layout
|
834
|
+
* @constant
|
835
|
+
* @type {string}
|
836
|
+
*/
|
837
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
838
|
+
/**
|
839
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
840
|
+
* @constant
|
841
|
+
* @type {string}
|
842
|
+
*/
|
843
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
844
|
+
};
|
845
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
846
|
+
endpoints: (builder) => ({
|
847
|
+
getContentTypeConfiguration: builder.query({
|
848
|
+
query: (uid) => ({
|
849
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
850
|
+
method: "GET"
|
851
|
+
}),
|
852
|
+
transformResponse: (response) => response.data,
|
853
|
+
providesTags: (_result, _error, uid) => [
|
854
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
855
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
856
|
+
]
|
857
|
+
}),
|
858
|
+
getAllContentTypeSettings: builder.query({
|
859
|
+
query: () => "/content-manager/content-types-settings",
|
860
|
+
transformResponse: (response) => response.data,
|
861
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
862
|
+
}),
|
863
|
+
updateContentTypeConfiguration: builder.mutation({
|
864
|
+
query: ({ uid, ...body }) => ({
|
865
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
866
|
+
method: "PUT",
|
867
|
+
data: body
|
868
|
+
}),
|
869
|
+
transformResponse: (response) => response.data,
|
870
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
871
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
872
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
873
|
+
// Is this necessary?
|
874
|
+
{ type: "InitialData" }
|
875
|
+
]
|
876
|
+
})
|
877
|
+
})
|
878
|
+
});
|
879
|
+
const {
|
880
|
+
useGetContentTypeConfigurationQuery,
|
881
|
+
useGetAllContentTypeSettingsQuery,
|
882
|
+
useUpdateContentTypeConfigurationMutation
|
883
|
+
} = contentTypesApi;
|
884
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
885
|
+
const { type } = attribute;
|
886
|
+
if (type === "relation") {
|
887
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
888
|
+
}
|
889
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
890
|
+
};
|
891
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
892
|
+
if (!mainFieldName) {
|
893
|
+
return void 0;
|
894
|
+
}
|
895
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
896
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
897
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
898
|
+
);
|
899
|
+
return {
|
900
|
+
name: mainFieldName,
|
901
|
+
type: mainFieldType ?? "string"
|
902
|
+
};
|
903
|
+
};
|
904
|
+
const DEFAULT_SETTINGS = {
|
905
|
+
bulkable: false,
|
906
|
+
filterable: false,
|
907
|
+
searchable: false,
|
908
|
+
pagination: false,
|
909
|
+
defaultSortBy: "",
|
910
|
+
defaultSortOrder: "asc",
|
911
|
+
mainField: "id",
|
912
|
+
pageSize: 10
|
913
|
+
};
|
914
|
+
const useDocumentLayout = (model) => {
|
915
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
916
|
+
const [{ query }] = useQueryParams();
|
917
|
+
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
793
918
|
const { toggleNotification } = useNotification();
|
794
919
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
920
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
795
921
|
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);
|
922
|
+
data,
|
923
|
+
isLoading: isLoadingConfigs,
|
924
|
+
error,
|
925
|
+
isFetching: isFetchingConfigs
|
926
|
+
} = useGetContentTypeConfigurationQuery(model);
|
927
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
805
928
|
React.useEffect(() => {
|
806
929
|
if (error) {
|
807
930
|
toggleNotification({
|
@@ -809,84 +932,339 @@ const useDocument = (args, opts) => {
|
|
809
932
|
message: formatAPIError(error)
|
810
933
|
});
|
811
934
|
}
|
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
|
-
}
|
935
|
+
}, [error, formatAPIError, toggleNotification]);
|
936
|
+
const editLayout = React.useMemo(
|
937
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
938
|
+
layout: [],
|
939
|
+
components: {},
|
940
|
+
metadatas: {},
|
941
|
+
options: {},
|
942
|
+
settings: DEFAULT_SETTINGS
|
835
943
|
},
|
836
|
-
[
|
944
|
+
[data, isLoading, schemas, schema, components]
|
945
|
+
);
|
946
|
+
const listLayout = React.useMemo(() => {
|
947
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
948
|
+
layout: [],
|
949
|
+
metadatas: {},
|
950
|
+
options: {},
|
951
|
+
settings: DEFAULT_SETTINGS
|
952
|
+
};
|
953
|
+
}, [data, isLoading, schemas, schema, components]);
|
954
|
+
const { layout: edit } = React.useMemo(
|
955
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
956
|
+
layout: editLayout,
|
957
|
+
query
|
958
|
+
}),
|
959
|
+
[editLayout, query, runHookWaterfall]
|
837
960
|
);
|
838
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
839
961
|
return {
|
840
|
-
|
841
|
-
document: data?.data,
|
842
|
-
meta: data?.meta,
|
962
|
+
error,
|
843
963
|
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
|
-
)
|
964
|
+
edit,
|
965
|
+
list: listLayout
|
868
966
|
};
|
869
967
|
};
|
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"
|
968
|
+
const useDocLayout = () => {
|
969
|
+
const { model } = useDoc();
|
970
|
+
return useDocumentLayout(model);
|
883
971
|
};
|
884
|
-
const
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
972
|
+
const formatEditLayout = (data, {
|
973
|
+
schemas,
|
974
|
+
schema,
|
975
|
+
components
|
976
|
+
}) => {
|
977
|
+
let currentPanelIndex = 0;
|
978
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
979
|
+
data.contentType.layouts.edit,
|
980
|
+
schema?.attributes,
|
981
|
+
data.contentType.metadatas,
|
982
|
+
{ configurations: data.components, schemas: components },
|
983
|
+
schemas
|
984
|
+
).reduce((panels, row) => {
|
985
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
986
|
+
panels.push([row]);
|
987
|
+
currentPanelIndex += 2;
|
988
|
+
} else {
|
989
|
+
if (!panels[currentPanelIndex]) {
|
990
|
+
panels.push([row]);
|
991
|
+
} else {
|
992
|
+
panels[currentPanelIndex].push(row);
|
993
|
+
}
|
994
|
+
}
|
995
|
+
return panels;
|
996
|
+
}, []);
|
997
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
998
|
+
(acc, [uid, configuration]) => {
|
999
|
+
acc[uid] = {
|
1000
|
+
layout: convertEditLayoutToFieldLayouts(
|
1001
|
+
configuration.layouts.edit,
|
1002
|
+
components[uid].attributes,
|
1003
|
+
configuration.metadatas,
|
1004
|
+
{ configurations: data.components, schemas: components }
|
1005
|
+
),
|
1006
|
+
settings: {
|
1007
|
+
...configuration.settings,
|
1008
|
+
icon: components[uid].info.icon,
|
1009
|
+
displayName: components[uid].info.displayName
|
1010
|
+
}
|
1011
|
+
};
|
1012
|
+
return acc;
|
1013
|
+
},
|
1014
|
+
{}
|
1015
|
+
);
|
1016
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1017
|
+
(acc, [attribute, metadata]) => {
|
1018
|
+
return {
|
1019
|
+
...acc,
|
1020
|
+
[attribute]: metadata.edit
|
1021
|
+
};
|
1022
|
+
},
|
1023
|
+
{}
|
1024
|
+
);
|
1025
|
+
return {
|
1026
|
+
layout: panelledEditAttributes,
|
1027
|
+
components: componentEditAttributes,
|
1028
|
+
metadatas: editMetadatas,
|
1029
|
+
settings: {
|
1030
|
+
...data.contentType.settings,
|
1031
|
+
displayName: schema?.info.displayName
|
1032
|
+
},
|
1033
|
+
options: {
|
1034
|
+
...schema?.options,
|
1035
|
+
...schema?.pluginOptions,
|
1036
|
+
...data.contentType.options
|
1037
|
+
}
|
1038
|
+
};
|
1039
|
+
};
|
1040
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1041
|
+
return rows.map(
|
1042
|
+
(row) => row.map((field) => {
|
1043
|
+
const attribute = attributes[field.name];
|
1044
|
+
if (!attribute) {
|
1045
|
+
return null;
|
1046
|
+
}
|
1047
|
+
const { edit: metadata } = metadatas[field.name];
|
1048
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1049
|
+
return {
|
1050
|
+
attribute,
|
1051
|
+
disabled: !metadata.editable,
|
1052
|
+
hint: metadata.description,
|
1053
|
+
label: metadata.label ?? "",
|
1054
|
+
name: field.name,
|
1055
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1056
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1057
|
+
schemas,
|
1058
|
+
components: components?.schemas ?? {}
|
1059
|
+
}),
|
1060
|
+
placeholder: metadata.placeholder ?? "",
|
1061
|
+
required: attribute.required ?? false,
|
1062
|
+
size: field.size,
|
1063
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1064
|
+
visible: metadata.visible ?? true,
|
1065
|
+
type: attribute.type
|
1066
|
+
};
|
1067
|
+
}).filter((field) => field !== null)
|
1068
|
+
);
|
1069
|
+
};
|
1070
|
+
const formatListLayout = (data, {
|
1071
|
+
schemas,
|
1072
|
+
schema,
|
1073
|
+
components
|
1074
|
+
}) => {
|
1075
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1076
|
+
(acc, [attribute, metadata]) => {
|
1077
|
+
return {
|
1078
|
+
...acc,
|
1079
|
+
[attribute]: metadata.list
|
1080
|
+
};
|
1081
|
+
},
|
1082
|
+
{}
|
1083
|
+
);
|
1084
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1085
|
+
data.contentType.layouts.list,
|
1086
|
+
schema?.attributes,
|
1087
|
+
listMetadatas,
|
1088
|
+
{ configurations: data.components, schemas: components },
|
1089
|
+
schemas
|
1090
|
+
);
|
1091
|
+
return {
|
1092
|
+
layout: listAttributes,
|
1093
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1094
|
+
metadatas: listMetadatas,
|
1095
|
+
options: {
|
1096
|
+
...schema?.options,
|
1097
|
+
...schema?.pluginOptions,
|
1098
|
+
...data.contentType.options
|
1099
|
+
}
|
1100
|
+
};
|
1101
|
+
};
|
1102
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1103
|
+
return columns.map((name) => {
|
1104
|
+
const attribute = attributes[name];
|
1105
|
+
if (!attribute) {
|
1106
|
+
return null;
|
1107
|
+
}
|
1108
|
+
const metadata = metadatas[name];
|
1109
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1110
|
+
return {
|
1111
|
+
attribute,
|
1112
|
+
label: metadata.label ?? "",
|
1113
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1114
|
+
schemas,
|
1115
|
+
components: components?.schemas ?? {}
|
1116
|
+
}),
|
1117
|
+
name,
|
1118
|
+
searchable: metadata.searchable ?? true,
|
1119
|
+
sortable: metadata.sortable ?? true
|
1120
|
+
};
|
1121
|
+
}).filter((field) => field !== null);
|
1122
|
+
};
|
1123
|
+
const useDocument = (args, opts) => {
|
1124
|
+
const { toggleNotification } = useNotification();
|
1125
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1126
|
+
const {
|
1127
|
+
currentData: data,
|
1128
|
+
isLoading: isLoadingDocument,
|
1129
|
+
isFetching: isFetchingDocument,
|
1130
|
+
error
|
1131
|
+
} = useGetDocumentQuery(args, {
|
1132
|
+
...opts,
|
1133
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1134
|
+
});
|
1135
|
+
const {
|
1136
|
+
components,
|
1137
|
+
schema,
|
1138
|
+
schemas,
|
1139
|
+
isLoading: isLoadingSchema
|
1140
|
+
} = useContentTypeSchema(args.model);
|
1141
|
+
React.useEffect(() => {
|
1142
|
+
if (error) {
|
1143
|
+
toggleNotification({
|
1144
|
+
type: "danger",
|
1145
|
+
message: formatAPIError(error)
|
1146
|
+
});
|
1147
|
+
}
|
1148
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1149
|
+
const validationSchema = React.useMemo(() => {
|
1150
|
+
if (!schema) {
|
1151
|
+
return null;
|
1152
|
+
}
|
1153
|
+
return createYupSchema(schema.attributes, components);
|
1154
|
+
}, [schema, components]);
|
1155
|
+
const validate = React.useCallback(
|
1156
|
+
(document) => {
|
1157
|
+
if (!validationSchema) {
|
1158
|
+
throw new Error(
|
1159
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1160
|
+
);
|
1161
|
+
}
|
1162
|
+
try {
|
1163
|
+
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
1164
|
+
return null;
|
1165
|
+
} catch (error2) {
|
1166
|
+
if (error2 instanceof ValidationError) {
|
1167
|
+
return getYupValidationErrors(error2);
|
1168
|
+
}
|
1169
|
+
throw error2;
|
1170
|
+
}
|
1171
|
+
},
|
1172
|
+
[validationSchema]
|
1173
|
+
);
|
1174
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1175
|
+
const hasError = !!error;
|
1176
|
+
return {
|
1177
|
+
components,
|
1178
|
+
document: data?.data,
|
1179
|
+
meta: data?.meta,
|
1180
|
+
isLoading,
|
1181
|
+
hasError,
|
1182
|
+
schema,
|
1183
|
+
schemas,
|
1184
|
+
validate
|
1185
|
+
};
|
1186
|
+
};
|
1187
|
+
const useDoc = () => {
|
1188
|
+
const { id, slug, collectionType, origin } = useParams();
|
1189
|
+
const [{ query }] = useQueryParams();
|
1190
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1191
|
+
if (!collectionType) {
|
1192
|
+
throw new Error("Could not find collectionType in url params");
|
1193
|
+
}
|
1194
|
+
if (!slug) {
|
1195
|
+
throw new Error("Could not find model in url params");
|
1196
|
+
}
|
1197
|
+
const document = useDocument(
|
1198
|
+
{ documentId: origin || id, model: slug, collectionType, params },
|
1199
|
+
{
|
1200
|
+
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
1201
|
+
}
|
1202
|
+
);
|
1203
|
+
const returnId = origin || id === "create" ? void 0 : id;
|
1204
|
+
return {
|
1205
|
+
collectionType,
|
1206
|
+
model: slug,
|
1207
|
+
id: returnId,
|
1208
|
+
...document
|
1209
|
+
};
|
1210
|
+
};
|
1211
|
+
const useContentManagerContext = () => {
|
1212
|
+
const {
|
1213
|
+
collectionType,
|
1214
|
+
model,
|
1215
|
+
id,
|
1216
|
+
components,
|
1217
|
+
isLoading: isLoadingDoc,
|
1218
|
+
schema,
|
1219
|
+
schemas
|
1220
|
+
} = useDoc();
|
1221
|
+
const layout = useDocumentLayout(model);
|
1222
|
+
const form = useForm("useContentManagerContext", (state) => state);
|
1223
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1224
|
+
const slug = model;
|
1225
|
+
const isCreatingEntry = id === "create";
|
1226
|
+
useContentTypeSchema();
|
1227
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1228
|
+
const error = layout.error;
|
1229
|
+
return {
|
1230
|
+
error,
|
1231
|
+
isLoading,
|
1232
|
+
// Base metadata
|
1233
|
+
model,
|
1234
|
+
collectionType,
|
1235
|
+
id,
|
1236
|
+
slug,
|
1237
|
+
isCreatingEntry,
|
1238
|
+
isSingleType,
|
1239
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1240
|
+
// All schema infos
|
1241
|
+
components,
|
1242
|
+
contentType: schema,
|
1243
|
+
contentTypes: schemas,
|
1244
|
+
// Form state
|
1245
|
+
form,
|
1246
|
+
// layout infos
|
1247
|
+
layout
|
1248
|
+
};
|
1249
|
+
};
|
1250
|
+
const prefixPluginTranslations = (trad, pluginId) => {
|
1251
|
+
return Object.keys(trad).reduce((acc, current) => {
|
1252
|
+
acc[`${pluginId}.${current}`] = trad[current];
|
1253
|
+
return acc;
|
1254
|
+
}, {});
|
1255
|
+
};
|
1256
|
+
const getTranslation = (id) => `content-manager.${id}`;
|
1257
|
+
const DEFAULT_UNEXPECTED_ERROR_MSG = {
|
1258
|
+
id: "notification.error",
|
1259
|
+
defaultMessage: "An error occurred, please try again"
|
1260
|
+
};
|
1261
|
+
const useDocumentActions = () => {
|
1262
|
+
const { toggleNotification } = useNotification();
|
1263
|
+
const { formatMessage } = useIntl();
|
1264
|
+
const { trackUsage } = useTracking();
|
1265
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1266
|
+
const navigate = useNavigate();
|
1267
|
+
const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
890
1268
|
const [deleteDocument] = useDeleteDocumentMutation();
|
891
1269
|
const _delete = React.useCallback(
|
892
1270
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1201,6 +1579,7 @@ const useDocumentActions = () => {
|
|
1201
1579
|
defaultMessage: "Saved document"
|
1202
1580
|
})
|
1203
1581
|
});
|
1582
|
+
setCurrentStep("contentManager.success");
|
1204
1583
|
return res.data;
|
1205
1584
|
} catch (err) {
|
1206
1585
|
toggleNotification({
|
@@ -1302,10 +1681,10 @@ const useDocumentActions = () => {
|
|
1302
1681
|
update
|
1303
1682
|
};
|
1304
1683
|
};
|
1305
|
-
const ProtectedHistoryPage = lazy(
|
1306
|
-
() => import("./History-
|
1684
|
+
const ProtectedHistoryPage = React.lazy(
|
1685
|
+
() => import("./History-Bk2VCzmJ.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1307
1686
|
);
|
1308
|
-
const routes$
|
1687
|
+
const routes$2 = [
|
1309
1688
|
{
|
1310
1689
|
path: ":collectionType/:slug/:id/history",
|
1311
1690
|
Component: ProtectedHistoryPage
|
@@ -1315,32 +1694,45 @@ const routes$1 = [
|
|
1315
1694
|
Component: ProtectedHistoryPage
|
1316
1695
|
}
|
1317
1696
|
];
|
1697
|
+
const ProtectedPreviewPage = React.lazy(
|
1698
|
+
() => import("./Preview-Dd3kQluA.mjs").then((mod) => ({ default: mod.ProtectedPreviewPage }))
|
1699
|
+
);
|
1700
|
+
const routes$1 = [
|
1701
|
+
{
|
1702
|
+
path: ":collectionType/:slug/:id/preview",
|
1703
|
+
Component: ProtectedPreviewPage
|
1704
|
+
},
|
1705
|
+
{
|
1706
|
+
path: ":collectionType/:slug/preview",
|
1707
|
+
Component: ProtectedPreviewPage
|
1708
|
+
}
|
1709
|
+
];
|
1318
1710
|
const ProtectedEditViewPage = lazy(
|
1319
|
-
() => import("./EditViewPage-
|
1711
|
+
() => import("./EditViewPage-ONky_-8U.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1320
1712
|
);
|
1321
1713
|
const ProtectedListViewPage = lazy(
|
1322
|
-
() => import("./ListViewPage-
|
1714
|
+
() => import("./ListViewPage-mK-sFVGU.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1323
1715
|
);
|
1324
1716
|
const ProtectedListConfiguration = lazy(
|
1325
|
-
() => import("./ListConfigurationPage-
|
1717
|
+
() => import("./ListConfigurationPage-BhNCzkQd.mjs").then((mod) => ({
|
1326
1718
|
default: mod.ProtectedListConfiguration
|
1327
1719
|
}))
|
1328
1720
|
);
|
1329
1721
|
const ProtectedEditConfigurationPage = lazy(
|
1330
|
-
() => import("./EditConfigurationPage-
|
1722
|
+
() => import("./EditConfigurationPage-DN6yaDFZ.mjs").then((mod) => ({
|
1331
1723
|
default: mod.ProtectedEditConfigurationPage
|
1332
1724
|
}))
|
1333
1725
|
);
|
1334
1726
|
const ProtectedComponentConfigurationPage = lazy(
|
1335
|
-
() => import("./ComponentConfigurationPage-
|
1727
|
+
() => import("./ComponentConfigurationPage-A5f-t42A.mjs").then((mod) => ({
|
1336
1728
|
default: mod.ProtectedComponentConfigurationPage
|
1337
1729
|
}))
|
1338
1730
|
);
|
1339
1731
|
const NoPermissions = lazy(
|
1340
|
-
() => import("./NoPermissionsPage-
|
1732
|
+
() => import("./NoPermissionsPage-zpYME1_X.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1341
1733
|
);
|
1342
1734
|
const NoContentType = lazy(
|
1343
|
-
() => import("./NoContentTypePage-
|
1735
|
+
() => import("./NoContentTypePage-BSVg7nZI.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1344
1736
|
);
|
1345
1737
|
const CollectionTypePages = () => {
|
1346
1738
|
const { collectionType } = useParams();
|
@@ -1352,7 +1744,7 @@ const CollectionTypePages = () => {
|
|
1352
1744
|
const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
|
1353
1745
|
const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
|
1354
1746
|
const LIST_RELATIVE_PATH = ":collectionType/:slug";
|
1355
|
-
const LIST_PATH = `/content-manager
|
1747
|
+
const LIST_PATH = `/content-manager/collection-types/:slug`;
|
1356
1748
|
const routes = [
|
1357
1749
|
{
|
1358
1750
|
path: LIST_RELATIVE_PATH,
|
@@ -1386,6 +1778,7 @@ const routes = [
|
|
1386
1778
|
path: "no-content-types",
|
1387
1779
|
Component: NoContentType
|
1388
1780
|
},
|
1781
|
+
...routes$2,
|
1389
1782
|
...routes$1
|
1390
1783
|
];
|
1391
1784
|
const DocumentActions = ({ actions: actions2 }) => {
|
@@ -1484,6 +1877,11 @@ const DocumentActionButton = (action) => {
|
|
1484
1877
|
) : null
|
1485
1878
|
] });
|
1486
1879
|
};
|
1880
|
+
const MenuItem = styled(Menu.Item)`
|
1881
|
+
&:hover {
|
1882
|
+
background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
|
1883
|
+
}
|
1884
|
+
`;
|
1487
1885
|
const DocumentActionsMenu = ({
|
1488
1886
|
actions: actions2,
|
1489
1887
|
children,
|
@@ -1542,48 +1940,32 @@ const DocumentActionsMenu = ({
|
|
1542
1940
|
/* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1543
1941
|
actions2.map((action) => {
|
1544
1942
|
return /* @__PURE__ */ jsx(
|
1545
|
-
|
1943
|
+
MenuItem,
|
1546
1944
|
{
|
1547
1945
|
disabled: action.disabled,
|
1548
1946
|
onSelect: handleClick(action),
|
1549
1947
|
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
|
-
] })
|
1948
|
+
isVariantDanger: action.variant === "danger",
|
1949
|
+
isDisabled: action.disabled,
|
1950
|
+
children: /* @__PURE__ */ jsx(Flex, { justifyContent: "space-between", gap: 4, children: /* @__PURE__ */ jsxs(
|
1951
|
+
Flex,
|
1952
|
+
{
|
1953
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1954
|
+
gap: 2,
|
1955
|
+
tag: "span",
|
1956
|
+
children: [
|
1957
|
+
/* @__PURE__ */ jsx(
|
1958
|
+
Flex,
|
1959
|
+
{
|
1960
|
+
tag: "span",
|
1961
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1962
|
+
children: action.icon
|
1963
|
+
}
|
1964
|
+
),
|
1965
|
+
action.label
|
1966
|
+
]
|
1967
|
+
}
|
1968
|
+
) })
|
1587
1969
|
},
|
1588
1970
|
action.id
|
1589
1971
|
);
|
@@ -1694,6 +2076,18 @@ const DocumentActionModal = ({
|
|
1694
2076
|
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1695
2077
|
] }) });
|
1696
2078
|
};
|
2079
|
+
const transformData = (data) => {
|
2080
|
+
if (Array.isArray(data)) {
|
2081
|
+
return data.map(transformData);
|
2082
|
+
}
|
2083
|
+
if (typeof data === "object" && data !== null) {
|
2084
|
+
if ("apiData" in data) {
|
2085
|
+
return data.apiData;
|
2086
|
+
}
|
2087
|
+
return mapValues(transformData)(data);
|
2088
|
+
}
|
2089
|
+
return data;
|
2090
|
+
};
|
1697
2091
|
const PublishAction$1 = ({
|
1698
2092
|
activeTab,
|
1699
2093
|
documentId,
|
@@ -1708,6 +2102,7 @@ const PublishAction$1 = ({
|
|
1708
2102
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
1709
2103
|
const isListView = useMatch(LIST_PATH) !== null;
|
1710
2104
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2105
|
+
const { id } = useParams();
|
1711
2106
|
const { formatMessage } = useIntl();
|
1712
2107
|
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1713
2108
|
const { publish } = useDocumentActions();
|
@@ -1787,7 +2182,9 @@ const PublishAction$1 = ({
|
|
1787
2182
|
const performPublish = async () => {
|
1788
2183
|
setSubmitting(true);
|
1789
2184
|
try {
|
1790
|
-
const { errors } = await validate(
|
2185
|
+
const { errors } = await validate(true, {
|
2186
|
+
status: "published"
|
2187
|
+
});
|
1791
2188
|
if (errors) {
|
1792
2189
|
toggleNotification({
|
1793
2190
|
type: "danger",
|
@@ -1805,13 +2202,15 @@ const PublishAction$1 = ({
|
|
1805
2202
|
documentId,
|
1806
2203
|
params
|
1807
2204
|
},
|
1808
|
-
formValues
|
2205
|
+
transformData(formValues)
|
1809
2206
|
);
|
1810
2207
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
2208
|
+
if (id === "create") {
|
2209
|
+
navigate({
|
2210
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2211
|
+
search: rawQuery
|
2212
|
+
});
|
2213
|
+
}
|
1815
2214
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1816
2215
|
setErrors(formatValidationErrors(res.error));
|
1817
2216
|
}
|
@@ -1864,6 +2263,7 @@ const PublishAction$1 = ({
|
|
1864
2263
|
};
|
1865
2264
|
};
|
1866
2265
|
PublishAction$1.type = "publish";
|
2266
|
+
PublishAction$1.position = "panel";
|
1867
2267
|
const UpdateAction = ({
|
1868
2268
|
activeTab,
|
1869
2269
|
documentId,
|
@@ -1886,6 +2286,117 @@ const UpdateAction = ({
|
|
1886
2286
|
const validate = useForm("UpdateAction", (state) => state.validate);
|
1887
2287
|
const setErrors = useForm("UpdateAction", (state) => state.setErrors);
|
1888
2288
|
const resetForm = useForm("PublishAction", ({ resetForm: resetForm2 }) => resetForm2);
|
2289
|
+
const handleUpdate = React.useCallback(async () => {
|
2290
|
+
setSubmitting(true);
|
2291
|
+
try {
|
2292
|
+
if (!modified) {
|
2293
|
+
return;
|
2294
|
+
}
|
2295
|
+
const { errors } = await validate(true, {
|
2296
|
+
status: "draft"
|
2297
|
+
});
|
2298
|
+
if (errors) {
|
2299
|
+
toggleNotification({
|
2300
|
+
type: "danger",
|
2301
|
+
message: formatMessage({
|
2302
|
+
id: "content-manager.validation.error",
|
2303
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2304
|
+
})
|
2305
|
+
});
|
2306
|
+
return;
|
2307
|
+
}
|
2308
|
+
if (isCloning) {
|
2309
|
+
const res = await clone(
|
2310
|
+
{
|
2311
|
+
model,
|
2312
|
+
documentId: cloneMatch.params.origin,
|
2313
|
+
params
|
2314
|
+
},
|
2315
|
+
transformData(document)
|
2316
|
+
);
|
2317
|
+
if ("data" in res) {
|
2318
|
+
navigate(
|
2319
|
+
{
|
2320
|
+
pathname: `../${res.data.documentId}`,
|
2321
|
+
search: rawQuery
|
2322
|
+
},
|
2323
|
+
{ relative: "path" }
|
2324
|
+
);
|
2325
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2326
|
+
setErrors(formatValidationErrors(res.error));
|
2327
|
+
}
|
2328
|
+
} else if (documentId || collectionType === SINGLE_TYPES) {
|
2329
|
+
const res = await update(
|
2330
|
+
{
|
2331
|
+
collectionType,
|
2332
|
+
model,
|
2333
|
+
documentId,
|
2334
|
+
params
|
2335
|
+
},
|
2336
|
+
transformData(document)
|
2337
|
+
);
|
2338
|
+
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2339
|
+
setErrors(formatValidationErrors(res.error));
|
2340
|
+
} else {
|
2341
|
+
resetForm();
|
2342
|
+
}
|
2343
|
+
} else {
|
2344
|
+
const res = await create(
|
2345
|
+
{
|
2346
|
+
model,
|
2347
|
+
params
|
2348
|
+
},
|
2349
|
+
transformData(document)
|
2350
|
+
);
|
2351
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2352
|
+
navigate(
|
2353
|
+
{
|
2354
|
+
pathname: `../${res.data.documentId}`,
|
2355
|
+
search: rawQuery
|
2356
|
+
},
|
2357
|
+
{ replace: true, relative: "path" }
|
2358
|
+
);
|
2359
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2360
|
+
setErrors(formatValidationErrors(res.error));
|
2361
|
+
}
|
2362
|
+
}
|
2363
|
+
} finally {
|
2364
|
+
setSubmitting(false);
|
2365
|
+
}
|
2366
|
+
}, [
|
2367
|
+
clone,
|
2368
|
+
cloneMatch?.params.origin,
|
2369
|
+
collectionType,
|
2370
|
+
create,
|
2371
|
+
document,
|
2372
|
+
documentId,
|
2373
|
+
formatMessage,
|
2374
|
+
formatValidationErrors,
|
2375
|
+
isCloning,
|
2376
|
+
model,
|
2377
|
+
modified,
|
2378
|
+
navigate,
|
2379
|
+
params,
|
2380
|
+
rawQuery,
|
2381
|
+
resetForm,
|
2382
|
+
setErrors,
|
2383
|
+
setSubmitting,
|
2384
|
+
toggleNotification,
|
2385
|
+
update,
|
2386
|
+
validate
|
2387
|
+
]);
|
2388
|
+
React.useEffect(() => {
|
2389
|
+
const handleKeyDown = (e) => {
|
2390
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
2391
|
+
e.preventDefault();
|
2392
|
+
handleUpdate();
|
2393
|
+
}
|
2394
|
+
};
|
2395
|
+
window.addEventListener("keydown", handleKeyDown);
|
2396
|
+
return () => {
|
2397
|
+
window.removeEventListener("keydown", handleKeyDown);
|
2398
|
+
};
|
2399
|
+
}, [handleUpdate]);
|
1889
2400
|
return {
|
1890
2401
|
/**
|
1891
2402
|
* Disabled when:
|
@@ -1895,87 +2406,14 @@ const UpdateAction = ({
|
|
1895
2406
|
*/
|
1896
2407
|
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1897
2408
|
label: formatMessage({
|
1898
|
-
id: "
|
2409
|
+
id: "global.save",
|
1899
2410
|
defaultMessage: "Save"
|
1900
2411
|
}),
|
1901
|
-
onClick:
|
1902
|
-
setSubmitting(true);
|
1903
|
-
try {
|
1904
|
-
if (activeTab !== "draft") {
|
1905
|
-
const { errors } = await validate();
|
1906
|
-
if (errors) {
|
1907
|
-
toggleNotification({
|
1908
|
-
type: "danger",
|
1909
|
-
message: formatMessage({
|
1910
|
-
id: "content-manager.validation.error",
|
1911
|
-
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
1912
|
-
})
|
1913
|
-
});
|
1914
|
-
return;
|
1915
|
-
}
|
1916
|
-
}
|
1917
|
-
if (isCloning) {
|
1918
|
-
const res = await clone(
|
1919
|
-
{
|
1920
|
-
model,
|
1921
|
-
documentId: cloneMatch.params.origin,
|
1922
|
-
params
|
1923
|
-
},
|
1924
|
-
document
|
1925
|
-
);
|
1926
|
-
if ("data" in res) {
|
1927
|
-
navigate(
|
1928
|
-
{
|
1929
|
-
pathname: `../${res.data.documentId}`,
|
1930
|
-
search: rawQuery
|
1931
|
-
},
|
1932
|
-
{ relative: "path" }
|
1933
|
-
);
|
1934
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1935
|
-
setErrors(formatValidationErrors(res.error));
|
1936
|
-
}
|
1937
|
-
} else if (documentId || collectionType === SINGLE_TYPES) {
|
1938
|
-
const res = await update(
|
1939
|
-
{
|
1940
|
-
collectionType,
|
1941
|
-
model,
|
1942
|
-
documentId,
|
1943
|
-
params
|
1944
|
-
},
|
1945
|
-
document
|
1946
|
-
);
|
1947
|
-
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1948
|
-
setErrors(formatValidationErrors(res.error));
|
1949
|
-
} else {
|
1950
|
-
resetForm();
|
1951
|
-
}
|
1952
|
-
} else {
|
1953
|
-
const res = await create(
|
1954
|
-
{
|
1955
|
-
model,
|
1956
|
-
params
|
1957
|
-
},
|
1958
|
-
document
|
1959
|
-
);
|
1960
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1961
|
-
navigate(
|
1962
|
-
{
|
1963
|
-
pathname: `../${res.data.documentId}`,
|
1964
|
-
search: rawQuery
|
1965
|
-
},
|
1966
|
-
{ replace: true, relative: "path" }
|
1967
|
-
);
|
1968
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1969
|
-
setErrors(formatValidationErrors(res.error));
|
1970
|
-
}
|
1971
|
-
}
|
1972
|
-
} finally {
|
1973
|
-
setSubmitting(false);
|
1974
|
-
}
|
1975
|
-
}
|
2412
|
+
onClick: handleUpdate
|
1976
2413
|
};
|
1977
2414
|
};
|
1978
2415
|
UpdateAction.type = "update";
|
2416
|
+
UpdateAction.position = "panel";
|
1979
2417
|
const UNPUBLISH_DRAFT_OPTIONS = {
|
1980
2418
|
KEEP: "keep",
|
1981
2419
|
DISCARD: "discard"
|
@@ -2098,6 +2536,7 @@ const UnpublishAction$1 = ({
|
|
2098
2536
|
};
|
2099
2537
|
};
|
2100
2538
|
UnpublishAction$1.type = "unpublish";
|
2539
|
+
UnpublishAction$1.position = "panel";
|
2101
2540
|
const DiscardAction = ({
|
2102
2541
|
activeTab,
|
2103
2542
|
documentId,
|
@@ -2148,6 +2587,7 @@ const DiscardAction = ({
|
|
2148
2587
|
};
|
2149
2588
|
};
|
2150
2589
|
DiscardAction.type = "discard";
|
2590
|
+
DiscardAction.position = "panel";
|
2151
2591
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2152
2592
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2153
2593
|
const RelativeTime = React.forwardRef(
|
@@ -2160,7 +2600,7 @@ const RelativeTime = React.forwardRef(
|
|
2160
2600
|
});
|
2161
2601
|
const unit = intervals.find((intervalUnit) => {
|
2162
2602
|
return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
|
2163
|
-
});
|
2603
|
+
}) ?? "seconds";
|
2164
2604
|
const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
|
2165
2605
|
const customInterval = customIntervals.find(
|
2166
2606
|
(custom) => interval[custom.unit] < custom.threshold
|
@@ -2194,19 +2634,29 @@ const getDisplayName = ({
|
|
2194
2634
|
return email ?? "";
|
2195
2635
|
};
|
2196
2636
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2197
|
-
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2637
|
+
const DocumentStatus = ({ status = "draft", size = "S", ...restProps }) => {
|
2198
2638
|
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2199
|
-
|
2639
|
+
const { formatMessage } = useIntl();
|
2640
|
+
return /* @__PURE__ */ jsx(Status, { ...restProps, size, variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: formatMessage({
|
2641
|
+
id: `content-manager.containers.List.${status}`,
|
2642
|
+
defaultMessage: capitalise(status)
|
2643
|
+
}) }) });
|
2200
2644
|
};
|
2201
2645
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2202
2646
|
const { formatMessage } = useIntl();
|
2203
2647
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2648
|
+
const params = useParams();
|
2204
2649
|
const title = isCreating ? formatMessage({
|
2205
2650
|
id: "content-manager.containers.edit.title.new",
|
2206
2651
|
defaultMessage: "Create an entry"
|
2207
2652
|
}) : documentTitle;
|
2208
2653
|
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2209
|
-
/* @__PURE__ */ jsx(
|
2654
|
+
/* @__PURE__ */ jsx(
|
2655
|
+
BackButton,
|
2656
|
+
{
|
2657
|
+
fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
|
2658
|
+
}
|
2659
|
+
),
|
2210
2660
|
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2211
2661
|
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2212
2662
|
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
@@ -2257,7 +2707,7 @@ const HeaderToolbar = () => {
|
|
2257
2707
|
meta: isCloning ? void 0 : meta,
|
2258
2708
|
collectionType
|
2259
2709
|
},
|
2260
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2710
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("header"),
|
2261
2711
|
children: (actions2) => {
|
2262
2712
|
const headerActions = actions2.filter((action) => {
|
2263
2713
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -2294,12 +2744,12 @@ const Information = ({ activeTab }) => {
|
|
2294
2744
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2295
2745
|
label: formatMessage({
|
2296
2746
|
id: "content-manager.containers.edit.information.last-published.label",
|
2297
|
-
defaultMessage: "
|
2747
|
+
defaultMessage: "Published"
|
2298
2748
|
}),
|
2299
2749
|
value: formatMessage(
|
2300
2750
|
{
|
2301
2751
|
id: "content-manager.containers.edit.information.last-published.value",
|
2302
|
-
defaultMessage: `
|
2752
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2303
2753
|
},
|
2304
2754
|
{
|
2305
2755
|
time: /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2312,12 +2762,12 @@ const Information = ({ activeTab }) => {
|
|
2312
2762
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2313
2763
|
label: formatMessage({
|
2314
2764
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2315
|
-
defaultMessage: "
|
2765
|
+
defaultMessage: "Updated"
|
2316
2766
|
}),
|
2317
2767
|
value: formatMessage(
|
2318
2768
|
{
|
2319
2769
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2320
|
-
defaultMessage: `
|
2770
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2321
2771
|
},
|
2322
2772
|
{
|
2323
2773
|
time: /* @__PURE__ */ jsx(
|
@@ -2335,12 +2785,12 @@ const Information = ({ activeTab }) => {
|
|
2335
2785
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2336
2786
|
label: formatMessage({
|
2337
2787
|
id: "content-manager.containers.edit.information.document.label",
|
2338
|
-
defaultMessage: "
|
2788
|
+
defaultMessage: "Created"
|
2339
2789
|
}),
|
2340
2790
|
value: formatMessage(
|
2341
2791
|
{
|
2342
2792
|
id: "content-manager.containers.edit.information.document.value",
|
2343
|
-
defaultMessage: `
|
2793
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2344
2794
|
},
|
2345
2795
|
{
|
2346
2796
|
time: /* @__PURE__ */ jsx(
|
@@ -2398,10 +2848,9 @@ const HeaderActions = ({ actions: actions2 }) => {
|
|
2398
2848
|
SingleSelect,
|
2399
2849
|
{
|
2400
2850
|
size: "S",
|
2401
|
-
disabled: action.disabled,
|
2402
|
-
"aria-label": action.label,
|
2403
2851
|
onChange: action.onSelect,
|
2404
|
-
|
2852
|
+
"aria-label": action.label,
|
2853
|
+
...action,
|
2405
2854
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
|
2406
2855
|
},
|
2407
2856
|
action.id
|
@@ -2466,6 +2915,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2466
2915
|
};
|
2467
2916
|
};
|
2468
2917
|
ConfigureTheViewAction.type = "configure-the-view";
|
2918
|
+
ConfigureTheViewAction.position = "header";
|
2469
2919
|
const EditTheModelAction = ({ model }) => {
|
2470
2920
|
const navigate = useNavigate();
|
2471
2921
|
const { formatMessage } = useIntl();
|
@@ -2482,6 +2932,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2482
2932
|
};
|
2483
2933
|
};
|
2484
2934
|
EditTheModelAction.type = "edit-the-model";
|
2935
|
+
EditTheModelAction.position = "header";
|
2485
2936
|
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2486
2937
|
const navigate = useNavigate();
|
2487
2938
|
const { formatMessage } = useIntl();
|
@@ -2490,12 +2941,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2490
2941
|
const { delete: deleteAction } = useDocumentActions();
|
2491
2942
|
const { toggleNotification } = useNotification();
|
2492
2943
|
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
2944
|
+
const isLocalized = document?.locale != null;
|
2493
2945
|
return {
|
2494
2946
|
disabled: !canDelete || !document,
|
2495
|
-
label: formatMessage(
|
2496
|
-
|
2497
|
-
|
2498
|
-
|
2947
|
+
label: formatMessage(
|
2948
|
+
{
|
2949
|
+
id: "content-manager.actions.delete.label",
|
2950
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2951
|
+
},
|
2952
|
+
{ isLocalized }
|
2953
|
+
),
|
2499
2954
|
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2500
2955
|
dialog: {
|
2501
2956
|
type: "dialog",
|
@@ -2534,421 +2989,119 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2534
2989
|
collectionType,
|
2535
2990
|
params: {
|
2536
2991
|
locale: "*"
|
2537
|
-
}
|
2538
|
-
});
|
2539
|
-
if (!("error" in res)) {
|
2540
|
-
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2541
|
-
}
|
2542
|
-
} finally {
|
2543
|
-
if (!listViewPathMatch) {
|
2544
|
-
setSubmitting(false);
|
2545
|
-
}
|
2546
|
-
}
|
2547
|
-
}
|
2548
|
-
},
|
2549
|
-
variant: "danger",
|
2550
|
-
position: ["header", "table-row"]
|
2551
|
-
};
|
2552
|
-
};
|
2553
|
-
DeleteAction$1.type = "delete";
|
2554
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2555
|
-
const Panels = () => {
|
2556
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2557
|
-
const [
|
2558
|
-
{
|
2559
|
-
query: { status }
|
2560
|
-
}
|
2561
|
-
] = useQueryParams({
|
2562
|
-
status: "draft"
|
2563
|
-
});
|
2564
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2565
|
-
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
2566
|
-
const props = {
|
2567
|
-
activeTab: status,
|
2568
|
-
model,
|
2569
|
-
documentId: id,
|
2570
|
-
document: isCloning ? void 0 : document,
|
2571
|
-
meta: isCloning ? void 0 : meta,
|
2572
|
-
collectionType
|
2573
|
-
};
|
2574
|
-
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
2575
|
-
DescriptionComponentRenderer,
|
2576
|
-
{
|
2577
|
-
props,
|
2578
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2579
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
2580
|
-
}
|
2581
|
-
) });
|
2582
|
-
};
|
2583
|
-
const ActionsPanel = () => {
|
2584
|
-
const { formatMessage } = useIntl();
|
2585
|
-
return {
|
2586
|
-
title: formatMessage({
|
2587
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2588
|
-
defaultMessage: "Entry"
|
2589
|
-
}),
|
2590
|
-
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2591
|
-
};
|
2592
|
-
};
|
2593
|
-
ActionsPanel.type = "actions";
|
2594
|
-
const ActionsPanelContent = () => {
|
2595
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2596
|
-
const [
|
2597
|
-
{
|
2598
|
-
query: { status = "draft" }
|
2599
|
-
}
|
2600
|
-
] = useQueryParams();
|
2601
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2602
|
-
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2603
|
-
const props = {
|
2604
|
-
activeTab: status,
|
2605
|
-
model,
|
2606
|
-
documentId: id,
|
2607
|
-
document: isCloning ? void 0 : document,
|
2608
|
-
meta: isCloning ? void 0 : meta,
|
2609
|
-
collectionType
|
2610
|
-
};
|
2611
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2612
|
-
/* @__PURE__ */ jsx(
|
2613
|
-
DescriptionComponentRenderer,
|
2614
|
-
{
|
2615
|
-
props,
|
2616
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2617
|
-
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
2618
|
-
}
|
2619
|
-
),
|
2620
|
-
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2621
|
-
] });
|
2622
|
-
};
|
2623
|
-
const Panel = React.forwardRef(({ children, title }, ref) => {
|
2624
|
-
return /* @__PURE__ */ jsxs(
|
2625
|
-
Flex,
|
2626
|
-
{
|
2627
|
-
ref,
|
2628
|
-
tag: "aside",
|
2629
|
-
"aria-labelledby": "additional-information",
|
2630
|
-
background: "neutral0",
|
2631
|
-
borderColor: "neutral150",
|
2632
|
-
hasRadius: true,
|
2633
|
-
paddingBottom: 4,
|
2634
|
-
paddingLeft: 4,
|
2635
|
-
paddingRight: 4,
|
2636
|
-
paddingTop: 4,
|
2637
|
-
shadow: "tableShadow",
|
2638
|
-
gap: 3,
|
2639
|
-
direction: "column",
|
2640
|
-
justifyContent: "stretch",
|
2641
|
-
alignItems: "flex-start",
|
2642
|
-
children: [
|
2643
|
-
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2644
|
-
children
|
2645
|
-
]
|
2646
|
-
}
|
2647
|
-
);
|
2648
|
-
});
|
2649
|
-
const HOOKS = {
|
2650
|
-
/**
|
2651
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2652
|
-
* @constant
|
2653
|
-
* @type {string}
|
2654
|
-
*/
|
2655
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2656
|
-
/**
|
2657
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2658
|
-
* @constant
|
2659
|
-
* @type {string}
|
2660
|
-
*/
|
2661
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2662
|
-
/**
|
2663
|
-
* Hook that allows to mutate the CM's edit view layout
|
2664
|
-
* @constant
|
2665
|
-
* @type {string}
|
2666
|
-
*/
|
2667
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2668
|
-
/**
|
2669
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2670
|
-
* @constant
|
2671
|
-
* @type {string}
|
2672
|
-
*/
|
2673
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2674
|
-
};
|
2675
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2676
|
-
endpoints: (builder) => ({
|
2677
|
-
getContentTypeConfiguration: builder.query({
|
2678
|
-
query: (uid) => ({
|
2679
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2680
|
-
method: "GET"
|
2681
|
-
}),
|
2682
|
-
transformResponse: (response) => response.data,
|
2683
|
-
providesTags: (_result, _error, uid) => [
|
2684
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2685
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2686
|
-
]
|
2687
|
-
}),
|
2688
|
-
getAllContentTypeSettings: builder.query({
|
2689
|
-
query: () => "/content-manager/content-types-settings",
|
2690
|
-
transformResponse: (response) => response.data,
|
2691
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2692
|
-
}),
|
2693
|
-
updateContentTypeConfiguration: builder.mutation({
|
2694
|
-
query: ({ uid, ...body }) => ({
|
2695
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2696
|
-
method: "PUT",
|
2697
|
-
data: body
|
2698
|
-
}),
|
2699
|
-
transformResponse: (response) => response.data,
|
2700
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2701
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2702
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2703
|
-
// Is this necessary?
|
2704
|
-
{ type: "InitialData" }
|
2705
|
-
]
|
2706
|
-
})
|
2707
|
-
})
|
2708
|
-
});
|
2709
|
-
const {
|
2710
|
-
useGetContentTypeConfigurationQuery,
|
2711
|
-
useGetAllContentTypeSettingsQuery,
|
2712
|
-
useUpdateContentTypeConfigurationMutation
|
2713
|
-
} = contentTypesApi;
|
2714
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2715
|
-
const { type } = attribute;
|
2716
|
-
if (type === "relation") {
|
2717
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2718
|
-
}
|
2719
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2720
|
-
};
|
2721
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2722
|
-
if (!mainFieldName) {
|
2723
|
-
return void 0;
|
2724
|
-
}
|
2725
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2726
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2727
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2728
|
-
);
|
2729
|
-
return {
|
2730
|
-
name: mainFieldName,
|
2731
|
-
type: mainFieldType ?? "string"
|
2732
|
-
};
|
2733
|
-
};
|
2734
|
-
const DEFAULT_SETTINGS = {
|
2735
|
-
bulkable: false,
|
2736
|
-
filterable: false,
|
2737
|
-
searchable: false,
|
2738
|
-
pagination: false,
|
2739
|
-
defaultSortBy: "",
|
2740
|
-
defaultSortOrder: "asc",
|
2741
|
-
mainField: "id",
|
2742
|
-
pageSize: 10
|
2743
|
-
};
|
2744
|
-
const useDocumentLayout = (model) => {
|
2745
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2746
|
-
const [{ query }] = useQueryParams();
|
2747
|
-
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2748
|
-
const { toggleNotification } = useNotification();
|
2749
|
-
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
2750
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2751
|
-
const {
|
2752
|
-
data,
|
2753
|
-
isLoading: isLoadingConfigs,
|
2754
|
-
error,
|
2755
|
-
isFetching: isFetchingConfigs
|
2756
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2757
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2758
|
-
React.useEffect(() => {
|
2759
|
-
if (error) {
|
2760
|
-
toggleNotification({
|
2761
|
-
type: "danger",
|
2762
|
-
message: formatAPIError(error)
|
2763
|
-
});
|
2764
|
-
}
|
2765
|
-
}, [error, formatAPIError, toggleNotification]);
|
2766
|
-
const editLayout = React.useMemo(
|
2767
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2768
|
-
layout: [],
|
2769
|
-
components: {},
|
2770
|
-
metadatas: {},
|
2771
|
-
options: {},
|
2772
|
-
settings: DEFAULT_SETTINGS
|
2773
|
-
},
|
2774
|
-
[data, isLoading, schemas, schema, components]
|
2775
|
-
);
|
2776
|
-
const listLayout = React.useMemo(() => {
|
2777
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2778
|
-
layout: [],
|
2779
|
-
metadatas: {},
|
2780
|
-
options: {},
|
2781
|
-
settings: DEFAULT_SETTINGS
|
2782
|
-
};
|
2783
|
-
}, [data, isLoading, schemas, schema, components]);
|
2784
|
-
const { layout: edit } = React.useMemo(
|
2785
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2786
|
-
layout: editLayout,
|
2787
|
-
query
|
2788
|
-
}),
|
2789
|
-
[editLayout, query, runHookWaterfall]
|
2790
|
-
);
|
2791
|
-
return {
|
2792
|
-
error,
|
2793
|
-
isLoading,
|
2794
|
-
edit,
|
2795
|
-
list: listLayout
|
2796
|
-
};
|
2797
|
-
};
|
2798
|
-
const useDocLayout = () => {
|
2799
|
-
const { model } = useDoc();
|
2800
|
-
return useDocumentLayout(model);
|
2801
|
-
};
|
2802
|
-
const formatEditLayout = (data, {
|
2803
|
-
schemas,
|
2804
|
-
schema,
|
2805
|
-
components
|
2806
|
-
}) => {
|
2807
|
-
let currentPanelIndex = 0;
|
2808
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2809
|
-
data.contentType.layouts.edit,
|
2810
|
-
schema?.attributes,
|
2811
|
-
data.contentType.metadatas,
|
2812
|
-
{ configurations: data.components, schemas: components },
|
2813
|
-
schemas
|
2814
|
-
).reduce((panels, row) => {
|
2815
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2816
|
-
panels.push([row]);
|
2817
|
-
currentPanelIndex += 2;
|
2818
|
-
} else {
|
2819
|
-
if (!panels[currentPanelIndex]) {
|
2820
|
-
panels.push([]);
|
2821
|
-
}
|
2822
|
-
panels[currentPanelIndex].push(row);
|
2823
|
-
}
|
2824
|
-
return panels;
|
2825
|
-
}, []);
|
2826
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2827
|
-
(acc, [uid, configuration]) => {
|
2828
|
-
acc[uid] = {
|
2829
|
-
layout: convertEditLayoutToFieldLayouts(
|
2830
|
-
configuration.layouts.edit,
|
2831
|
-
components[uid].attributes,
|
2832
|
-
configuration.metadatas,
|
2833
|
-
{ configurations: data.components, schemas: components }
|
2834
|
-
),
|
2835
|
-
settings: {
|
2836
|
-
...configuration.settings,
|
2837
|
-
icon: components[uid].info.icon,
|
2838
|
-
displayName: components[uid].info.displayName
|
2992
|
+
}
|
2993
|
+
});
|
2994
|
+
if (!("error" in res)) {
|
2995
|
+
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2996
|
+
}
|
2997
|
+
} finally {
|
2998
|
+
if (!listViewPathMatch) {
|
2999
|
+
setSubmitting(false);
|
3000
|
+
}
|
2839
3001
|
}
|
2840
|
-
}
|
2841
|
-
return acc;
|
2842
|
-
},
|
2843
|
-
{}
|
2844
|
-
);
|
2845
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2846
|
-
(acc, [attribute, metadata]) => {
|
2847
|
-
return {
|
2848
|
-
...acc,
|
2849
|
-
[attribute]: metadata.edit
|
2850
|
-
};
|
2851
|
-
},
|
2852
|
-
{}
|
2853
|
-
);
|
2854
|
-
return {
|
2855
|
-
layout: panelledEditAttributes,
|
2856
|
-
components: componentEditAttributes,
|
2857
|
-
metadatas: editMetadatas,
|
2858
|
-
settings: {
|
2859
|
-
...data.contentType.settings,
|
2860
|
-
displayName: schema?.info.displayName
|
3002
|
+
}
|
2861
3003
|
},
|
2862
|
-
|
2863
|
-
|
2864
|
-
...schema?.pluginOptions,
|
2865
|
-
...data.contentType.options
|
2866
|
-
}
|
3004
|
+
variant: "danger",
|
3005
|
+
position: ["header", "table-row"]
|
2867
3006
|
};
|
2868
3007
|
};
|
2869
|
-
|
2870
|
-
|
2871
|
-
|
2872
|
-
|
2873
|
-
|
2874
|
-
|
2875
|
-
|
2876
|
-
|
2877
|
-
|
2878
|
-
|
2879
|
-
|
2880
|
-
|
2881
|
-
|
2882
|
-
|
2883
|
-
|
2884
|
-
|
2885
|
-
|
2886
|
-
|
2887
|
-
|
2888
|
-
|
2889
|
-
|
2890
|
-
|
2891
|
-
|
2892
|
-
|
2893
|
-
|
2894
|
-
|
2895
|
-
|
2896
|
-
|
2897
|
-
|
3008
|
+
DeleteAction$1.type = "delete";
|
3009
|
+
DeleteAction$1.position = ["header", "table-row"];
|
3010
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
3011
|
+
const Panels = () => {
|
3012
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
3013
|
+
const [
|
3014
|
+
{
|
3015
|
+
query: { status }
|
3016
|
+
}
|
3017
|
+
] = useQueryParams({
|
3018
|
+
status: "draft"
|
3019
|
+
});
|
3020
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
3021
|
+
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
3022
|
+
const props = {
|
3023
|
+
activeTab: status,
|
3024
|
+
model,
|
3025
|
+
documentId: id,
|
3026
|
+
document: isCloning ? void 0 : document,
|
3027
|
+
meta: isCloning ? void 0 : meta,
|
3028
|
+
collectionType
|
3029
|
+
};
|
3030
|
+
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
3031
|
+
DescriptionComponentRenderer,
|
3032
|
+
{
|
3033
|
+
props,
|
3034
|
+
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
3035
|
+
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
3036
|
+
}
|
3037
|
+
) });
|
2898
3038
|
};
|
2899
|
-
const
|
2900
|
-
|
2901
|
-
schema,
|
2902
|
-
components
|
2903
|
-
}) => {
|
2904
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2905
|
-
(acc, [attribute, metadata]) => {
|
2906
|
-
return {
|
2907
|
-
...acc,
|
2908
|
-
[attribute]: metadata.list
|
2909
|
-
};
|
2910
|
-
},
|
2911
|
-
{}
|
2912
|
-
);
|
2913
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2914
|
-
data.contentType.layouts.list,
|
2915
|
-
schema?.attributes,
|
2916
|
-
listMetadatas,
|
2917
|
-
{ configurations: data.components, schemas: components },
|
2918
|
-
schemas
|
2919
|
-
);
|
3039
|
+
const ActionsPanel = () => {
|
3040
|
+
const { formatMessage } = useIntl();
|
2920
3041
|
return {
|
2921
|
-
|
2922
|
-
|
2923
|
-
|
2924
|
-
|
2925
|
-
|
2926
|
-
...schema?.pluginOptions,
|
2927
|
-
...data.contentType.options
|
2928
|
-
}
|
3042
|
+
title: formatMessage({
|
3043
|
+
id: "content-manager.containers.edit.panels.default.title",
|
3044
|
+
defaultMessage: "Entry"
|
3045
|
+
}),
|
3046
|
+
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2929
3047
|
};
|
2930
3048
|
};
|
2931
|
-
|
2932
|
-
|
2933
|
-
|
2934
|
-
|
2935
|
-
|
3049
|
+
ActionsPanel.type = "actions";
|
3050
|
+
const ActionsPanelContent = () => {
|
3051
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
3052
|
+
const [
|
3053
|
+
{
|
3054
|
+
query: { status = "draft" }
|
2936
3055
|
}
|
2937
|
-
|
2938
|
-
|
2939
|
-
|
2940
|
-
|
2941
|
-
|
2942
|
-
|
2943
|
-
|
2944
|
-
|
2945
|
-
|
2946
|
-
|
2947
|
-
|
2948
|
-
|
2949
|
-
|
2950
|
-
|
3056
|
+
] = useQueryParams();
|
3057
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
3058
|
+
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
3059
|
+
const props = {
|
3060
|
+
activeTab: status,
|
3061
|
+
model,
|
3062
|
+
documentId: id,
|
3063
|
+
document: isCloning ? void 0 : document,
|
3064
|
+
meta: isCloning ? void 0 : meta,
|
3065
|
+
collectionType
|
3066
|
+
};
|
3067
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
3068
|
+
/* @__PURE__ */ jsx(
|
3069
|
+
DescriptionComponentRenderer,
|
3070
|
+
{
|
3071
|
+
props,
|
3072
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("panel"),
|
3073
|
+
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
3074
|
+
}
|
3075
|
+
),
|
3076
|
+
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
3077
|
+
] });
|
2951
3078
|
};
|
3079
|
+
const Panel = React.forwardRef(({ children, title }, ref) => {
|
3080
|
+
return /* @__PURE__ */ jsxs(
|
3081
|
+
Flex,
|
3082
|
+
{
|
3083
|
+
ref,
|
3084
|
+
tag: "aside",
|
3085
|
+
"aria-labelledby": "additional-information",
|
3086
|
+
background: "neutral0",
|
3087
|
+
borderColor: "neutral150",
|
3088
|
+
hasRadius: true,
|
3089
|
+
paddingBottom: 4,
|
3090
|
+
paddingLeft: 4,
|
3091
|
+
paddingRight: 4,
|
3092
|
+
paddingTop: 4,
|
3093
|
+
shadow: "tableShadow",
|
3094
|
+
gap: 3,
|
3095
|
+
direction: "column",
|
3096
|
+
justifyContent: "stretch",
|
3097
|
+
alignItems: "flex-start",
|
3098
|
+
children: [
|
3099
|
+
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", textColor: "neutral600", children: title }),
|
3100
|
+
children
|
3101
|
+
]
|
3102
|
+
}
|
3103
|
+
);
|
3104
|
+
});
|
2952
3105
|
const ConfirmBulkActionDialog = ({
|
2953
3106
|
onToggleDialog,
|
2954
3107
|
isOpen = false,
|
@@ -3193,18 +3346,10 @@ const SelectedEntriesTableContent = ({
|
|
3193
3346
|
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3194
3347
|
},
|
3195
3348
|
state: { from: pathname },
|
3196
|
-
label: formatMessage(
|
3197
|
-
|
3198
|
-
|
3199
|
-
|
3200
|
-
{
|
3201
|
-
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3202
|
-
defaultMessage: "item line {number}"
|
3203
|
-
},
|
3204
|
-
{ number: index2 + 1 }
|
3205
|
-
)
|
3206
|
-
}
|
3207
|
-
),
|
3349
|
+
label: formatMessage({
|
3350
|
+
id: "content-manager.bulk-publish.edit",
|
3351
|
+
defaultMessage: "Edit"
|
3352
|
+
}),
|
3208
3353
|
target: "_blank",
|
3209
3354
|
marginLeft: "auto",
|
3210
3355
|
variant: "ghost",
|
@@ -3378,8 +3523,7 @@ const PublishAction = ({ documents, model }) => {
|
|
3378
3523
|
const refetchList = () => {
|
3379
3524
|
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3380
3525
|
};
|
3381
|
-
if (!showPublishButton)
|
3382
|
-
return null;
|
3526
|
+
if (!showPublishButton) return null;
|
3383
3527
|
return {
|
3384
3528
|
actionType: "publish",
|
3385
3529
|
variant: "tertiary",
|
@@ -3447,8 +3591,7 @@ const DeleteAction = ({ documents, model }) => {
|
|
3447
3591
|
selectRow([]);
|
3448
3592
|
}
|
3449
3593
|
};
|
3450
|
-
if (!hasDeletePermission)
|
3451
|
-
return null;
|
3594
|
+
if (!hasDeletePermission) return null;
|
3452
3595
|
return {
|
3453
3596
|
variant: "danger-light",
|
3454
3597
|
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
@@ -3497,8 +3640,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3497
3640
|
}
|
3498
3641
|
};
|
3499
3642
|
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3500
|
-
if (!showUnpublishButton)
|
3501
|
-
return null;
|
3643
|
+
if (!showUnpublishButton) return null;
|
3502
3644
|
return {
|
3503
3645
|
variant: "tertiary",
|
3504
3646
|
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
@@ -3603,7 +3745,7 @@ const TableActions = ({ document }) => {
|
|
3603
3745
|
DescriptionComponentRenderer,
|
3604
3746
|
{
|
3605
3747
|
props,
|
3606
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3748
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("table-row").filter((action) => action.name !== "PublishAction"),
|
3607
3749
|
children: (actions2) => {
|
3608
3750
|
const tableRowActions = actions2.filter((action) => {
|
3609
3751
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3662,6 +3804,7 @@ const EditAction = ({ documentId }) => {
|
|
3662
3804
|
};
|
3663
3805
|
};
|
3664
3806
|
EditAction.type = "edit";
|
3807
|
+
EditAction.position = "table-row";
|
3665
3808
|
const StyledPencil = styled(Pencil)`
|
3666
3809
|
path {
|
3667
3810
|
fill: currentColor;
|
@@ -3738,6 +3881,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3738
3881
|
};
|
3739
3882
|
};
|
3740
3883
|
CloneAction.type = "clone";
|
3884
|
+
CloneAction.position = "table-row";
|
3741
3885
|
const StyledDuplicate = styled(Duplicate)`
|
3742
3886
|
path {
|
3743
3887
|
fill: currentColor;
|
@@ -3824,7 +3968,14 @@ class ContentManagerPlugin {
|
|
3824
3968
|
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3825
3969
|
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3826
3970
|
getBulkActions: () => this.bulkActions,
|
3827
|
-
getDocumentActions: () =>
|
3971
|
+
getDocumentActions: (position) => {
|
3972
|
+
if (position) {
|
3973
|
+
return this.documentActions.filter(
|
3974
|
+
(action) => action.position == void 0 || [action.position].flat().includes(position)
|
3975
|
+
);
|
3976
|
+
}
|
3977
|
+
return this.documentActions;
|
3978
|
+
},
|
3828
3979
|
getEditViewSidePanels: () => this.editViewSidePanels,
|
3829
3980
|
getHeaderActions: () => this.headerActions
|
3830
3981
|
}
|
@@ -3834,10 +3985,8 @@ class ContentManagerPlugin {
|
|
3834
3985
|
const getPrintableType = (value) => {
|
3835
3986
|
const nativeType = typeof value;
|
3836
3987
|
if (nativeType === "object") {
|
3837
|
-
if (value === null)
|
3838
|
-
|
3839
|
-
if (Array.isArray(value))
|
3840
|
-
return "array";
|
3988
|
+
if (value === null) return "null";
|
3989
|
+
if (Array.isArray(value)) return "array";
|
3841
3990
|
if (value instanceof Object && value.constructor.name !== "Object") {
|
3842
3991
|
return value.constructor.name;
|
3843
3992
|
}
|
@@ -3848,17 +3997,27 @@ const HistoryAction = ({ model, document }) => {
|
|
3848
3997
|
const { formatMessage } = useIntl();
|
3849
3998
|
const [{ query }] = useQueryParams();
|
3850
3999
|
const navigate = useNavigate();
|
4000
|
+
const { trackUsage } = useTracking();
|
4001
|
+
const { pathname } = useLocation();
|
3851
4002
|
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
3852
4003
|
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3853
4004
|
return null;
|
3854
4005
|
}
|
4006
|
+
const handleOnClick = () => {
|
4007
|
+
const destination = { pathname: "history", search: pluginsQueryParams };
|
4008
|
+
trackUsage("willNavigate", {
|
4009
|
+
from: pathname,
|
4010
|
+
to: `${pathname}/${destination.pathname}`
|
4011
|
+
});
|
4012
|
+
navigate(destination);
|
4013
|
+
};
|
3855
4014
|
return {
|
3856
4015
|
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
3857
4016
|
label: formatMessage({
|
3858
4017
|
id: "content-manager.history.document-action",
|
3859
4018
|
defaultMessage: "Content History"
|
3860
4019
|
}),
|
3861
|
-
onClick:
|
4020
|
+
onClick: handleOnClick,
|
3862
4021
|
disabled: (
|
3863
4022
|
/**
|
3864
4023
|
* The user is creating a new document.
|
@@ -3880,6 +4039,7 @@ const HistoryAction = ({ model, document }) => {
|
|
3880
4039
|
};
|
3881
4040
|
};
|
3882
4041
|
HistoryAction.type = "history";
|
4042
|
+
HistoryAction.position = "header";
|
3883
4043
|
const historyAdmin = {
|
3884
4044
|
bootstrap(app) {
|
3885
4045
|
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
@@ -3926,6 +4086,88 @@ const { setInitialData } = actions;
|
|
3926
4086
|
const reducer = combineReducers({
|
3927
4087
|
app: reducer$1
|
3928
4088
|
});
|
4089
|
+
const previewApi = contentManagerApi.injectEndpoints({
|
4090
|
+
endpoints: (builder) => ({
|
4091
|
+
getPreviewUrl: builder.query({
|
4092
|
+
query({ query, params }) {
|
4093
|
+
return {
|
4094
|
+
url: `/content-manager/preview/url/${params.contentType}`,
|
4095
|
+
method: "GET",
|
4096
|
+
config: {
|
4097
|
+
params: query
|
4098
|
+
}
|
4099
|
+
};
|
4100
|
+
}
|
4101
|
+
})
|
4102
|
+
})
|
4103
|
+
});
|
4104
|
+
const { useGetPreviewUrlQuery } = previewApi;
|
4105
|
+
const ConditionalTooltip = ({ isShown, label, children }) => {
|
4106
|
+
if (isShown) {
|
4107
|
+
return /* @__PURE__ */ jsx(Tooltip, { label, children });
|
4108
|
+
}
|
4109
|
+
return children;
|
4110
|
+
};
|
4111
|
+
const PreviewSidePanel = ({ model, documentId, document }) => {
|
4112
|
+
const { formatMessage } = useIntl();
|
4113
|
+
const { trackUsage } = useTracking();
|
4114
|
+
const { pathname } = useLocation();
|
4115
|
+
const [{ query }] = useQueryParams();
|
4116
|
+
const isModified = useForm("PreviewSidePanel", (state) => state.modified);
|
4117
|
+
const { data, error } = useGetPreviewUrlQuery({
|
4118
|
+
params: {
|
4119
|
+
contentType: model
|
4120
|
+
},
|
4121
|
+
query: {
|
4122
|
+
documentId,
|
4123
|
+
locale: document?.locale,
|
4124
|
+
status: document?.status
|
4125
|
+
}
|
4126
|
+
});
|
4127
|
+
if (!data?.data?.url || error) {
|
4128
|
+
return null;
|
4129
|
+
}
|
4130
|
+
const trackNavigation = () => {
|
4131
|
+
const destinationPathname = pathname.replace(/\/$/, "") + "/preview";
|
4132
|
+
trackUsage("willNavigate", { from: pathname, to: destinationPathname });
|
4133
|
+
};
|
4134
|
+
return {
|
4135
|
+
title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
|
4136
|
+
content: /* @__PURE__ */ jsx(
|
4137
|
+
ConditionalTooltip,
|
4138
|
+
{
|
4139
|
+
label: formatMessage({
|
4140
|
+
id: "content-manager.preview.panel.button-disabled-tooltip",
|
4141
|
+
defaultMessage: "Please save to open the preview"
|
4142
|
+
}),
|
4143
|
+
isShown: isModified,
|
4144
|
+
children: /* @__PURE__ */ jsx(Box, { cursor: "not-allowed", width: "100%", children: /* @__PURE__ */ jsx(
|
4145
|
+
Button,
|
4146
|
+
{
|
4147
|
+
variant: "tertiary",
|
4148
|
+
tag: Link,
|
4149
|
+
to: { pathname: "preview", search: stringify(query, { encode: false }) },
|
4150
|
+
onClick: trackNavigation,
|
4151
|
+
width: "100%",
|
4152
|
+
disabled: isModified,
|
4153
|
+
pointerEvents: isModified ? "none" : void 0,
|
4154
|
+
tabIndex: isModified ? -1 : void 0,
|
4155
|
+
children: formatMessage({
|
4156
|
+
id: "content-manager.preview.panel.button",
|
4157
|
+
defaultMessage: "Open preview"
|
4158
|
+
})
|
4159
|
+
}
|
4160
|
+
) })
|
4161
|
+
}
|
4162
|
+
)
|
4163
|
+
};
|
4164
|
+
};
|
4165
|
+
const previewAdmin = {
|
4166
|
+
bootstrap(app) {
|
4167
|
+
const contentManagerPluginApis = app.getPlugin("content-manager").apis;
|
4168
|
+
contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
|
4169
|
+
}
|
4170
|
+
};
|
3929
4171
|
const index = {
|
3930
4172
|
register(app) {
|
3931
4173
|
const cm = new ContentManagerPlugin();
|
@@ -3945,7 +4187,7 @@ const index = {
|
|
3945
4187
|
app.router.addRoute({
|
3946
4188
|
path: "content-manager/*",
|
3947
4189
|
lazy: async () => {
|
3948
|
-
const { Layout } = await import("./layout-
|
4190
|
+
const { Layout } = await import("./layout-C71zeI19.mjs");
|
3949
4191
|
return {
|
3950
4192
|
Component: Layout
|
3951
4193
|
};
|
@@ -3958,11 +4200,14 @@ const index = {
|
|
3958
4200
|
if (typeof historyAdmin.bootstrap === "function") {
|
3959
4201
|
historyAdmin.bootstrap(app);
|
3960
4202
|
}
|
4203
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
4204
|
+
previewAdmin.bootstrap(app);
|
4205
|
+
}
|
3961
4206
|
},
|
3962
4207
|
async registerTrads({ locales }) {
|
3963
4208
|
const importedTrads = await Promise.all(
|
3964
4209
|
locales.map((locale) => {
|
3965
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-
|
4210
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-CSxLmrh1.mjs"), "./translations/es.json": () => import("./es-D34tqjMw.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr--pg5jUbt.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-BHqhDq4V.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
|
3966
4211
|
return {
|
3967
4212
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3968
4213
|
locale
|
@@ -3989,8 +4234,10 @@ export {
|
|
3989
4234
|
HOOKS as H,
|
3990
4235
|
InjectionZone as I,
|
3991
4236
|
useDocument as J,
|
3992
|
-
|
3993
|
-
|
4237
|
+
useGetPreviewUrlQuery as K,
|
4238
|
+
index as L,
|
4239
|
+
useContentManagerContext as M,
|
4240
|
+
useDocumentActions as N,
|
3994
4241
|
Panels as P,
|
3995
4242
|
RelativeTime as R,
|
3996
4243
|
SINGLE_TYPES as S,
|
@@ -4022,4 +4269,4 @@ export {
|
|
4022
4269
|
capitalise as y,
|
4023
4270
|
useUpdateContentTypeConfigurationMutation as z
|
4024
4271
|
};
|
4025
|
-
//# sourceMappingURL=index-
|
4272
|
+
//# sourceMappingURL=index-B3tHjkLZ.mjs.map
|