@strapi/content-manager 0.0.0-experimental.32c4b04580cc12400710050c8198e46b3644cfd4 → 0.0.0-experimental.36632203b17974c18103c138ffbef53a82e448c3
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/{ComponentConfigurationPage-5ukroXAh.js → ComponentConfigurationPage-Br8hp2Xt.js} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-5ukroXAh.js.map → ComponentConfigurationPage-Br8hp2Xt.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-BAgyHiMm.mjs → ComponentConfigurationPage-DhwMhiRn.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-BAgyHiMm.mjs.map → ComponentConfigurationPage-DhwMhiRn.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-Xp7lun0f.js → EditConfigurationPage-BG7rpPjL.js} +4 -4
- package/dist/_chunks/{EditConfigurationPage-Xp7lun0f.js.map → EditConfigurationPage-BG7rpPjL.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DmoXawIh.mjs → EditConfigurationPage-CWao3CZ3.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-DmoXawIh.mjs.map → EditConfigurationPage-CWao3CZ3.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-C-ukDOB7.js → EditViewPage-BUtpHsMz.js} +38 -11
- package/dist/_chunks/EditViewPage-BUtpHsMz.js.map +1 -0
- package/dist/_chunks/{EditViewPage-BLsjc5F-.mjs → EditViewPage-hiwZg61J.mjs} +39 -12
- package/dist/_chunks/EditViewPage-hiwZg61J.mjs.map +1 -0
- package/dist/_chunks/{Field-Cs7duwWd.mjs → Field-BQQLwyUs.mjs} +174 -102
- package/dist/_chunks/Field-BQQLwyUs.mjs.map +1 -0
- package/dist/_chunks/{Field-Bfph5SOd.js → Field-DEdug-Ll.js} +176 -104
- package/dist/_chunks/Field-DEdug-Ll.js.map +1 -0
- package/dist/_chunks/{Form-Dg_GS5TQ.mjs → Form-DwJovCha.mjs} +36 -17
- package/dist/_chunks/Form-DwJovCha.mjs.map +1 -0
- package/dist/_chunks/{Form-CPYqIWDG.js → Form-v5pkY-X_.js} +36 -17
- package/dist/_chunks/Form-v5pkY-X_.js.map +1 -0
- package/dist/_chunks/{History-DNQkXANT.js → History-40apIShV.js} +37 -47
- package/dist/_chunks/History-40apIShV.js.map +1 -0
- package/dist/_chunks/{History-wrnHqf09.mjs → History-B9uJsxZl.mjs} +38 -48
- package/dist/_chunks/History-B9uJsxZl.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DScmJVkW.mjs → ListConfigurationPage-CA4oi4Hj.mjs} +15 -5
- package/dist/_chunks/ListConfigurationPage-CA4oi4Hj.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-CUQxfpjT.js → ListConfigurationPage-DAGbWDIL.js} +15 -5
- package/dist/_chunks/ListConfigurationPage-DAGbWDIL.js.map +1 -0
- package/dist/_chunks/{ListViewPage-C4IvrMgY.mjs → ListViewPage-Ca8F1NL-.mjs} +59 -39
- package/dist/_chunks/ListViewPage-Ca8F1NL-.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-BsLiH2-2.js → ListViewPage-CjaHQ2_V.js} +61 -41
- package/dist/_chunks/ListViewPage-CjaHQ2_V.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-BZ-PnGAf.js → NoContentTypePage-CGxqLI8j.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-BZ-PnGAf.js.map → NoContentTypePage-CGxqLI8j.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-Djg8nPlj.mjs → NoContentTypePage-CwfnU-aN.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-Djg8nPlj.mjs.map → NoContentTypePage-CwfnU-aN.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-_lUqjGW3.js → NoPermissionsPage-CY3_QduF.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-_lUqjGW3.js.map → NoPermissionsPage-CY3_QduF.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DSP7R-hv.mjs → NoPermissionsPage-iPk2lFR6.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DSP7R-hv.mjs.map → NoPermissionsPage-iPk2lFR6.mjs.map} +1 -1
- package/dist/_chunks/Preview-DRJhcaIO.mjs +267 -0
- package/dist/_chunks/Preview-DRJhcaIO.mjs.map +1 -0
- package/dist/_chunks/Preview-V8XOfrQf.js +286 -0
- package/dist/_chunks/Preview-V8XOfrQf.js.map +1 -0
- package/dist/_chunks/{Relations-CtELXYIK.js → Relations-CGerEwji.js} +72 -36
- package/dist/_chunks/Relations-CGerEwji.js.map +1 -0
- package/dist/_chunks/{Relations-BZr8tL0R.mjs → Relations-DGWa9W2j.mjs} +73 -37
- package/dist/_chunks/Relations-DGWa9W2j.mjs.map +1 -0
- package/dist/_chunks/{en-uOUIxfcQ.js → en-CHOp_xJv.js} +23 -13
- package/dist/_chunks/{en-uOUIxfcQ.js.map → en-CHOp_xJv.js.map} +1 -1
- package/dist/_chunks/{en-BrCTWlZv.mjs → en-D_BMf0hT.mjs} +23 -13
- package/dist/_chunks/{en-BrCTWlZv.mjs.map → en-D_BMf0hT.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/{index-c_5DdJi-.mjs → index-V8MWkDSd.mjs} +987 -727
- package/dist/_chunks/index-V8MWkDSd.mjs.map +1 -0
- package/dist/_chunks/{index-OerGjbAN.js → index-tN1hpOMN.js} +968 -707
- package/dist/_chunks/index-tN1hpOMN.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-oPBiO7RY.mjs → layout-Bue_C6ui.mjs} +22 -9
- package/dist/_chunks/layout-Bue_C6ui.mjs.map +1 -0
- package/dist/_chunks/{layout-Ci7qHlFb.js → layout-BzX903CL.js} +21 -8
- package/dist/_chunks/layout-BzX903CL.js.map +1 -0
- package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
- package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
- package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
- package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
- package/dist/_chunks/{relations-COBpStiF.js → relations-C4HcWYYJ.js} +6 -7
- package/dist/_chunks/relations-C4HcWYYJ.js.map +1 -0
- package/dist/_chunks/{relations-BIdWFjdq.mjs → relations-C8eyDiIO.mjs} +6 -7
- package/dist/_chunks/relations-C8eyDiIO.mjs.map +1 -0
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +5 -4
- package/dist/admin/src/exports.d.ts +1 -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/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +4 -48
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- 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/constants.d.ts +1 -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/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +19 -17
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/validation.d.ts +4 -1
- package/dist/server/index.js +513 -235
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +514 -236
- 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 +4 -4
- 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/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/preview/constants.d.ts +2 -0
- package/dist/server/src/preview/constants.d.ts.map +1 -0
- 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 +15 -0
- package/dist/server/src/preview/services/index.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview-config.d.ts +30 -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 +18 -0
- package/dist/server/src/preview/utils.d.ts.map +1 -0
- package/dist/server/src/routes/index.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/permission-checker.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/collection-types.d.ts +3 -1
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/dist/shared/contracts/index.d.ts +1 -0
- package/dist/shared/contracts/index.d.ts.map +1 -1
- package/dist/shared/contracts/preview.d.ts +27 -0
- package/dist/shared/contracts/preview.d.ts.map +1 -0
- package/dist/shared/index.js +4 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +4 -0
- package/dist/shared/index.mjs.map +1 -1
- package/package.json +13 -13
- package/dist/_chunks/EditViewPage-BLsjc5F-.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-C-ukDOB7.js.map +0 -1
- package/dist/_chunks/Field-Bfph5SOd.js.map +0 -1
- package/dist/_chunks/Field-Cs7duwWd.mjs.map +0 -1
- package/dist/_chunks/Form-CPYqIWDG.js.map +0 -1
- package/dist/_chunks/Form-Dg_GS5TQ.mjs.map +0 -1
- package/dist/_chunks/History-DNQkXANT.js.map +0 -1
- package/dist/_chunks/History-wrnHqf09.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-CUQxfpjT.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DScmJVkW.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-BsLiH2-2.js.map +0 -1
- package/dist/_chunks/ListViewPage-C4IvrMgY.mjs.map +0 -1
- package/dist/_chunks/Relations-BZr8tL0R.mjs.map +0 -1
- package/dist/_chunks/Relations-CtELXYIK.js.map +0 -1
- package/dist/_chunks/index-OerGjbAN.js.map +0 -1
- package/dist/_chunks/index-c_5DdJi-.mjs.map +0 -1
- package/dist/_chunks/layout-Ci7qHlFb.js.map +0 -1
- package/dist/_chunks/layout-oPBiO7RY.mjs.map +0 -1
- package/dist/_chunks/relations-BIdWFjdq.mjs.map +0 -1
- package/dist/_chunks/relations-COBpStiF.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
@@ -1,16 +1,17 @@
|
|
1
|
-
import {
|
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 { Button, Menu, VisuallyHidden, Flex,
|
6
|
+
import { Button, Menu, VisuallyHidden, Flex, Typography, Dialog, Modal, 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
|
-
import { useParams,
|
9
|
-
import { styled } from "styled-components";
|
9
|
+
import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
10
10
|
import * as yup from "yup";
|
11
11
|
import { ValidationError } from "yup";
|
12
12
|
import pipe from "lodash/fp/pipe";
|
13
13
|
import { intervalToDuration, isPast } from "date-fns";
|
14
|
+
import { styled } from "styled-components";
|
14
15
|
import { stringify } from "qs";
|
15
16
|
import { createSlice, combineReducers } from "@reduxjs/toolkit";
|
16
17
|
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
@@ -100,6 +101,7 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
100
101
|
if (!slug) {
|
101
102
|
throw new Error("Cannot find the slug param in the URL");
|
102
103
|
}
|
104
|
+
const [{ rawQuery }] = useQueryParams();
|
103
105
|
const userPermissions = useAuth("DocumentRBAC", (state) => state.permissions);
|
104
106
|
const contentTypePermissions = React.useMemo(() => {
|
105
107
|
const contentTypePermissions2 = userPermissions.filter(
|
@@ -110,7 +112,14 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
110
112
|
return { ...acc, [action]: [permission] };
|
111
113
|
}, {});
|
112
114
|
}, [slug, userPermissions]);
|
113
|
-
const { isLoading, allowedActions } = useRBAC(
|
115
|
+
const { isLoading, allowedActions } = useRBAC(
|
116
|
+
contentTypePermissions,
|
117
|
+
permissions ?? void 0,
|
118
|
+
// TODO: useRBAC context should be typed and built differently
|
119
|
+
// We are passing raw query as context to the hook so that it can
|
120
|
+
// rely on the locale provided from DocumentRBAC for its permission calculations.
|
121
|
+
rawQuery
|
122
|
+
);
|
114
123
|
const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
|
115
124
|
const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
|
116
125
|
const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
|
@@ -158,7 +167,8 @@ const contentManagerApi = adminApi.enhanceEndpoints({
|
|
158
167
|
"Document",
|
159
168
|
"InitialData",
|
160
169
|
"HistoryVersion",
|
161
|
-
"Relations"
|
170
|
+
"Relations",
|
171
|
+
"UidAvailability"
|
162
172
|
]
|
163
173
|
});
|
164
174
|
const documentApi = contentManagerApi.injectEndpoints({
|
@@ -188,7 +198,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
188
198
|
params
|
189
199
|
}
|
190
200
|
}),
|
191
|
-
invalidatesTags: (_result, _error, { model }) => [
|
201
|
+
invalidatesTags: (_result, _error, { model }) => [
|
202
|
+
{ type: "Document", id: `${model}_LIST` },
|
203
|
+
{ type: "UidAvailability", id: model }
|
204
|
+
]
|
192
205
|
}),
|
193
206
|
/**
|
194
207
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -205,7 +218,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
205
218
|
}),
|
206
219
|
invalidatesTags: (result, _error, { model }) => [
|
207
220
|
{ type: "Document", id: `${model}_LIST` },
|
208
|
-
"Relations"
|
221
|
+
"Relations",
|
222
|
+
{ type: "UidAvailability", id: model }
|
209
223
|
]
|
210
224
|
}),
|
211
225
|
deleteDocument: builder.mutation({
|
@@ -246,7 +260,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
246
260
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
247
261
|
},
|
248
262
|
{ type: "Document", id: `${model}_LIST` },
|
249
|
-
"Relations"
|
263
|
+
"Relations",
|
264
|
+
{ type: "UidAvailability", id: model }
|
250
265
|
];
|
251
266
|
}
|
252
267
|
}),
|
@@ -264,6 +279,7 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
264
279
|
}),
|
265
280
|
providesTags: (result, _error, arg) => {
|
266
281
|
return [
|
282
|
+
{ type: "Document", id: `ALL_LIST` },
|
267
283
|
{ type: "Document", id: `${arg.model}_LIST` },
|
268
284
|
...result?.results.map(({ documentId }) => ({
|
269
285
|
type: "Document",
|
@@ -302,6 +318,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
302
318
|
{
|
303
319
|
type: "Document",
|
304
320
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
321
|
+
},
|
322
|
+
// Make it easy to invalidate all individual documents queries for a model
|
323
|
+
{
|
324
|
+
type: "Document",
|
325
|
+
id: `${model}_ALL_ITEMS`
|
305
326
|
}
|
306
327
|
];
|
307
328
|
}
|
@@ -365,7 +386,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
365
386
|
type: "Document",
|
366
387
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
367
388
|
},
|
368
|
-
"Relations"
|
389
|
+
"Relations",
|
390
|
+
{ type: "UidAvailability", id: model }
|
369
391
|
];
|
370
392
|
},
|
371
393
|
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
@@ -448,20 +470,39 @@ const buildValidParams = (query) => {
|
|
448
470
|
const isBaseQueryError = (error) => {
|
449
471
|
return error.name !== void 0;
|
450
472
|
};
|
451
|
-
const
|
473
|
+
const arrayValidator = (attribute, options) => ({
|
474
|
+
message: translatedErrors.required,
|
475
|
+
test(value) {
|
476
|
+
if (options.status === "draft") {
|
477
|
+
return true;
|
478
|
+
}
|
479
|
+
if (!attribute.required) {
|
480
|
+
return true;
|
481
|
+
}
|
482
|
+
if (!value) {
|
483
|
+
return false;
|
484
|
+
}
|
485
|
+
if (Array.isArray(value) && value.length === 0) {
|
486
|
+
return false;
|
487
|
+
}
|
488
|
+
return true;
|
489
|
+
}
|
490
|
+
});
|
491
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
452
492
|
const createModelSchema = (attributes2) => yup.object().shape(
|
453
493
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
454
494
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
455
495
|
return acc;
|
456
496
|
}
|
457
497
|
const validations = [
|
498
|
+
addNullableValidation,
|
458
499
|
addRequiredValidation,
|
459
500
|
addMinLengthValidation,
|
460
501
|
addMaxLengthValidation,
|
461
502
|
addMinValidation,
|
462
503
|
addMaxValidation,
|
463
504
|
addRegexValidation
|
464
|
-
].map((fn) => fn(attribute));
|
505
|
+
].map((fn) => fn(attribute, options));
|
465
506
|
const transformSchema = pipe(...validations);
|
466
507
|
switch (attribute.type) {
|
467
508
|
case "component": {
|
@@ -471,12 +512,12 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
471
512
|
...acc,
|
472
513
|
[name]: transformSchema(
|
473
514
|
yup.array().of(createModelSchema(attributes3).nullable(false))
|
474
|
-
)
|
515
|
+
).test(arrayValidator(attribute, options))
|
475
516
|
};
|
476
517
|
} else {
|
477
518
|
return {
|
478
519
|
...acc,
|
479
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
520
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
480
521
|
};
|
481
522
|
}
|
482
523
|
}
|
@@ -498,7 +539,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
498
539
|
}
|
499
540
|
)
|
500
541
|
)
|
501
|
-
)
|
542
|
+
).test(arrayValidator(attribute, options))
|
502
543
|
};
|
503
544
|
case "relation":
|
504
545
|
return {
|
@@ -510,7 +551,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
510
551
|
} else if (Array.isArray(value)) {
|
511
552
|
return yup.array().of(
|
512
553
|
yup.object().shape({
|
513
|
-
id: yup.
|
554
|
+
id: yup.number().required()
|
514
555
|
})
|
515
556
|
);
|
516
557
|
} else if (typeof value === "object") {
|
@@ -562,6 +603,14 @@ const createAttributeSchema = (attribute) => {
|
|
562
603
|
if (!value || typeof value === "string" && value.length === 0) {
|
563
604
|
return true;
|
564
605
|
}
|
606
|
+
if (typeof value === "object") {
|
607
|
+
try {
|
608
|
+
JSON.stringify(value);
|
609
|
+
return true;
|
610
|
+
} catch (err) {
|
611
|
+
return false;
|
612
|
+
}
|
613
|
+
}
|
565
614
|
try {
|
566
615
|
JSON.parse(value);
|
567
616
|
return true;
|
@@ -580,13 +629,7 @@ const createAttributeSchema = (attribute) => {
|
|
580
629
|
return yup.mixed();
|
581
630
|
}
|
582
631
|
};
|
583
|
-
const
|
584
|
-
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
585
|
-
return schema.min(1, translatedErrors.required);
|
586
|
-
}
|
587
|
-
if (attribute.required && attribute.type !== "relation") {
|
588
|
-
return schema.required(translatedErrors.required);
|
589
|
-
}
|
632
|
+
const nullableSchema = (schema) => {
|
590
633
|
return schema?.nullable ? schema.nullable() : (
|
591
634
|
// In some cases '.nullable' will not be available on the schema.
|
592
635
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -594,7 +637,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
594
637
|
schema
|
595
638
|
);
|
596
639
|
};
|
597
|
-
const
|
640
|
+
const addNullableValidation = () => (schema) => {
|
641
|
+
return nullableSchema(schema);
|
642
|
+
};
|
643
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
644
|
+
if (options.status === "draft" || !attribute.required) {
|
645
|
+
return schema;
|
646
|
+
}
|
647
|
+
if (attribute.required && "required" in schema) {
|
648
|
+
return schema.required(translatedErrors.required);
|
649
|
+
}
|
650
|
+
return schema;
|
651
|
+
};
|
652
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
653
|
+
if (options.status === "draft") {
|
654
|
+
return schema;
|
655
|
+
}
|
598
656
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
599
657
|
return schema.min(attribute.minLength, {
|
600
658
|
...translatedErrors.minLength,
|
@@ -616,32 +674,13 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
616
674
|
}
|
617
675
|
return schema;
|
618
676
|
};
|
619
|
-
const addMinValidation = (attribute) => (schema) => {
|
620
|
-
if ("
|
677
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
678
|
+
if (options.status === "draft") {
|
679
|
+
return schema;
|
680
|
+
}
|
681
|
+
if ("min" in attribute && "min" in schema) {
|
621
682
|
const min = toInteger(attribute.min);
|
622
|
-
if (
|
623
|
-
if (!attribute.required && "test" in schema && min) {
|
624
|
-
return schema.test(
|
625
|
-
"custom-min",
|
626
|
-
{
|
627
|
-
...translatedErrors.min,
|
628
|
-
values: {
|
629
|
-
min: attribute.min
|
630
|
-
}
|
631
|
-
},
|
632
|
-
(value) => {
|
633
|
-
if (!value) {
|
634
|
-
return true;
|
635
|
-
}
|
636
|
-
if (Array.isArray(value) && value.length === 0) {
|
637
|
-
return true;
|
638
|
-
}
|
639
|
-
return value.length >= min;
|
640
|
-
}
|
641
|
-
);
|
642
|
-
}
|
643
|
-
}
|
644
|
-
if ("min" in schema && min) {
|
683
|
+
if (min) {
|
645
684
|
return schema.min(min, {
|
646
685
|
...translatedErrors.min,
|
647
686
|
values: {
|
@@ -759,19 +798,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
759
798
|
}, {});
|
760
799
|
return componentsByKey;
|
761
800
|
};
|
762
|
-
const
|
801
|
+
const HOOKS = {
|
802
|
+
/**
|
803
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
804
|
+
* @constant
|
805
|
+
* @type {string}
|
806
|
+
*/
|
807
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
808
|
+
/**
|
809
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
810
|
+
* @constant
|
811
|
+
* @type {string}
|
812
|
+
*/
|
813
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
814
|
+
/**
|
815
|
+
* Hook that allows to mutate the CM's edit view layout
|
816
|
+
* @constant
|
817
|
+
* @type {string}
|
818
|
+
*/
|
819
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
820
|
+
/**
|
821
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
822
|
+
* @constant
|
823
|
+
* @type {string}
|
824
|
+
*/
|
825
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
826
|
+
};
|
827
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
828
|
+
endpoints: (builder) => ({
|
829
|
+
getContentTypeConfiguration: builder.query({
|
830
|
+
query: (uid) => ({
|
831
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
832
|
+
method: "GET"
|
833
|
+
}),
|
834
|
+
transformResponse: (response) => response.data,
|
835
|
+
providesTags: (_result, _error, uid) => [
|
836
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
837
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
838
|
+
]
|
839
|
+
}),
|
840
|
+
getAllContentTypeSettings: builder.query({
|
841
|
+
query: () => "/content-manager/content-types-settings",
|
842
|
+
transformResponse: (response) => response.data,
|
843
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
844
|
+
}),
|
845
|
+
updateContentTypeConfiguration: builder.mutation({
|
846
|
+
query: ({ uid, ...body }) => ({
|
847
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
848
|
+
method: "PUT",
|
849
|
+
data: body
|
850
|
+
}),
|
851
|
+
transformResponse: (response) => response.data,
|
852
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
853
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
854
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
855
|
+
// Is this necessary?
|
856
|
+
{ type: "InitialData" }
|
857
|
+
]
|
858
|
+
})
|
859
|
+
})
|
860
|
+
});
|
861
|
+
const {
|
862
|
+
useGetContentTypeConfigurationQuery,
|
863
|
+
useGetAllContentTypeSettingsQuery,
|
864
|
+
useUpdateContentTypeConfigurationMutation
|
865
|
+
} = contentTypesApi;
|
866
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
867
|
+
const { type } = attribute;
|
868
|
+
if (type === "relation") {
|
869
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
870
|
+
}
|
871
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
872
|
+
};
|
873
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
874
|
+
if (!mainFieldName) {
|
875
|
+
return void 0;
|
876
|
+
}
|
877
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
878
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
879
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
880
|
+
);
|
881
|
+
return {
|
882
|
+
name: mainFieldName,
|
883
|
+
type: mainFieldType ?? "string"
|
884
|
+
};
|
885
|
+
};
|
886
|
+
const DEFAULT_SETTINGS = {
|
887
|
+
bulkable: false,
|
888
|
+
filterable: false,
|
889
|
+
searchable: false,
|
890
|
+
pagination: false,
|
891
|
+
defaultSortBy: "",
|
892
|
+
defaultSortOrder: "asc",
|
893
|
+
mainField: "id",
|
894
|
+
pageSize: 10
|
895
|
+
};
|
896
|
+
const useDocumentLayout = (model) => {
|
897
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
898
|
+
const [{ query }] = useQueryParams();
|
899
|
+
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
763
900
|
const { toggleNotification } = useNotification();
|
764
901
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
902
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
765
903
|
const {
|
766
|
-
|
767
|
-
isLoading:
|
768
|
-
|
769
|
-
|
770
|
-
} =
|
771
|
-
|
772
|
-
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
773
|
-
});
|
774
|
-
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
904
|
+
data,
|
905
|
+
isLoading: isLoadingConfigs,
|
906
|
+
error,
|
907
|
+
isFetching: isFetchingConfigs
|
908
|
+
} = useGetContentTypeConfigurationQuery(model);
|
909
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
775
910
|
React.useEffect(() => {
|
776
911
|
if (error) {
|
777
912
|
toggleNotification({
|
@@ -779,88 +914,344 @@ const useDocument = (args, opts) => {
|
|
779
914
|
message: formatAPIError(error)
|
780
915
|
});
|
781
916
|
}
|
782
|
-
}, [
|
783
|
-
const
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
(document) => {
|
791
|
-
if (!validationSchema) {
|
792
|
-
throw new Error(
|
793
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
794
|
-
);
|
795
|
-
}
|
796
|
-
try {
|
797
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
798
|
-
return null;
|
799
|
-
} catch (error2) {
|
800
|
-
if (error2 instanceof ValidationError) {
|
801
|
-
return getYupValidationErrors(error2);
|
802
|
-
}
|
803
|
-
throw error2;
|
804
|
-
}
|
917
|
+
}, [error, formatAPIError, toggleNotification]);
|
918
|
+
const editLayout = React.useMemo(
|
919
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
920
|
+
layout: [],
|
921
|
+
components: {},
|
922
|
+
metadatas: {},
|
923
|
+
options: {},
|
924
|
+
settings: DEFAULT_SETTINGS
|
805
925
|
},
|
806
|
-
[
|
926
|
+
[data, isLoading, schemas, schema, components]
|
927
|
+
);
|
928
|
+
const listLayout = React.useMemo(() => {
|
929
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
930
|
+
layout: [],
|
931
|
+
metadatas: {},
|
932
|
+
options: {},
|
933
|
+
settings: DEFAULT_SETTINGS
|
934
|
+
};
|
935
|
+
}, [data, isLoading, schemas, schema, components]);
|
936
|
+
const { layout: edit } = React.useMemo(
|
937
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
938
|
+
layout: editLayout,
|
939
|
+
query
|
940
|
+
}),
|
941
|
+
[editLayout, query, runHookWaterfall]
|
807
942
|
);
|
808
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
809
943
|
return {
|
810
|
-
|
811
|
-
document: data?.data,
|
812
|
-
meta: data?.meta,
|
944
|
+
error,
|
813
945
|
isLoading,
|
814
|
-
|
815
|
-
|
816
|
-
};
|
817
|
-
};
|
818
|
-
const useDoc = () => {
|
819
|
-
const { id, slug, collectionType, origin } = useParams();
|
820
|
-
const [{ query }] = useQueryParams();
|
821
|
-
const params = React.useMemo(() => buildValidParams(query), [query]);
|
822
|
-
if (!collectionType) {
|
823
|
-
throw new Error("Could not find collectionType in url params");
|
824
|
-
}
|
825
|
-
if (!slug) {
|
826
|
-
throw new Error("Could not find model in url params");
|
827
|
-
}
|
828
|
-
return {
|
829
|
-
collectionType,
|
830
|
-
model: slug,
|
831
|
-
id: origin || id === "create" ? void 0 : id,
|
832
|
-
...useDocument(
|
833
|
-
{ documentId: origin || id, model: slug, collectionType, params },
|
834
|
-
{
|
835
|
-
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
836
|
-
}
|
837
|
-
)
|
946
|
+
edit,
|
947
|
+
list: listLayout
|
838
948
|
};
|
839
949
|
};
|
840
|
-
const
|
841
|
-
|
842
|
-
|
843
|
-
}
|
844
|
-
return Object.keys(trad).reduce((acc, current) => {
|
845
|
-
acc[`${pluginId}.${current}`] = trad[current];
|
846
|
-
return acc;
|
847
|
-
}, {});
|
848
|
-
};
|
849
|
-
const getTranslation = (id) => `content-manager.${id}`;
|
850
|
-
const DEFAULT_UNEXPECTED_ERROR_MSG = {
|
851
|
-
id: "notification.error",
|
852
|
-
defaultMessage: "An error occurred, please try again"
|
950
|
+
const useDocLayout = () => {
|
951
|
+
const { model } = useDoc();
|
952
|
+
return useDocumentLayout(model);
|
853
953
|
};
|
854
|
-
const
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
const
|
861
|
-
|
862
|
-
|
863
|
-
|
954
|
+
const formatEditLayout = (data, {
|
955
|
+
schemas,
|
956
|
+
schema,
|
957
|
+
components
|
958
|
+
}) => {
|
959
|
+
let currentPanelIndex = 0;
|
960
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
961
|
+
data.contentType.layouts.edit,
|
962
|
+
schema?.attributes,
|
963
|
+
data.contentType.metadatas,
|
964
|
+
{ configurations: data.components, schemas: components },
|
965
|
+
schemas
|
966
|
+
).reduce((panels, row) => {
|
967
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
968
|
+
panels.push([row]);
|
969
|
+
currentPanelIndex += 2;
|
970
|
+
} else {
|
971
|
+
if (!panels[currentPanelIndex]) {
|
972
|
+
panels.push([row]);
|
973
|
+
} else {
|
974
|
+
panels[currentPanelIndex].push(row);
|
975
|
+
}
|
976
|
+
}
|
977
|
+
return panels;
|
978
|
+
}, []);
|
979
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
980
|
+
(acc, [uid, configuration]) => {
|
981
|
+
acc[uid] = {
|
982
|
+
layout: convertEditLayoutToFieldLayouts(
|
983
|
+
configuration.layouts.edit,
|
984
|
+
components[uid].attributes,
|
985
|
+
configuration.metadatas,
|
986
|
+
{ configurations: data.components, schemas: components }
|
987
|
+
),
|
988
|
+
settings: {
|
989
|
+
...configuration.settings,
|
990
|
+
icon: components[uid].info.icon,
|
991
|
+
displayName: components[uid].info.displayName
|
992
|
+
}
|
993
|
+
};
|
994
|
+
return acc;
|
995
|
+
},
|
996
|
+
{}
|
997
|
+
);
|
998
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
999
|
+
(acc, [attribute, metadata]) => {
|
1000
|
+
return {
|
1001
|
+
...acc,
|
1002
|
+
[attribute]: metadata.edit
|
1003
|
+
};
|
1004
|
+
},
|
1005
|
+
{}
|
1006
|
+
);
|
1007
|
+
return {
|
1008
|
+
layout: panelledEditAttributes,
|
1009
|
+
components: componentEditAttributes,
|
1010
|
+
metadatas: editMetadatas,
|
1011
|
+
settings: {
|
1012
|
+
...data.contentType.settings,
|
1013
|
+
displayName: schema?.info.displayName
|
1014
|
+
},
|
1015
|
+
options: {
|
1016
|
+
...schema?.options,
|
1017
|
+
...schema?.pluginOptions,
|
1018
|
+
...data.contentType.options
|
1019
|
+
}
|
1020
|
+
};
|
1021
|
+
};
|
1022
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1023
|
+
return rows.map(
|
1024
|
+
(row) => row.map((field) => {
|
1025
|
+
const attribute = attributes[field.name];
|
1026
|
+
if (!attribute) {
|
1027
|
+
return null;
|
1028
|
+
}
|
1029
|
+
const { edit: metadata } = metadatas[field.name];
|
1030
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1031
|
+
return {
|
1032
|
+
attribute,
|
1033
|
+
disabled: !metadata.editable,
|
1034
|
+
hint: metadata.description,
|
1035
|
+
label: metadata.label ?? "",
|
1036
|
+
name: field.name,
|
1037
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1038
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1039
|
+
schemas,
|
1040
|
+
components: components?.schemas ?? {}
|
1041
|
+
}),
|
1042
|
+
placeholder: metadata.placeholder ?? "",
|
1043
|
+
required: attribute.required ?? false,
|
1044
|
+
size: field.size,
|
1045
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1046
|
+
visible: metadata.visible ?? true,
|
1047
|
+
type: attribute.type
|
1048
|
+
};
|
1049
|
+
}).filter((field) => field !== null)
|
1050
|
+
);
|
1051
|
+
};
|
1052
|
+
const formatListLayout = (data, {
|
1053
|
+
schemas,
|
1054
|
+
schema,
|
1055
|
+
components
|
1056
|
+
}) => {
|
1057
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1058
|
+
(acc, [attribute, metadata]) => {
|
1059
|
+
return {
|
1060
|
+
...acc,
|
1061
|
+
[attribute]: metadata.list
|
1062
|
+
};
|
1063
|
+
},
|
1064
|
+
{}
|
1065
|
+
);
|
1066
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1067
|
+
data.contentType.layouts.list,
|
1068
|
+
schema?.attributes,
|
1069
|
+
listMetadatas,
|
1070
|
+
{ configurations: data.components, schemas: components },
|
1071
|
+
schemas
|
1072
|
+
);
|
1073
|
+
return {
|
1074
|
+
layout: listAttributes,
|
1075
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1076
|
+
metadatas: listMetadatas,
|
1077
|
+
options: {
|
1078
|
+
...schema?.options,
|
1079
|
+
...schema?.pluginOptions,
|
1080
|
+
...data.contentType.options
|
1081
|
+
}
|
1082
|
+
};
|
1083
|
+
};
|
1084
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1085
|
+
return columns.map((name) => {
|
1086
|
+
const attribute = attributes[name];
|
1087
|
+
if (!attribute) {
|
1088
|
+
return null;
|
1089
|
+
}
|
1090
|
+
const metadata = metadatas[name];
|
1091
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1092
|
+
return {
|
1093
|
+
attribute,
|
1094
|
+
label: metadata.label ?? "",
|
1095
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1096
|
+
schemas,
|
1097
|
+
components: components?.schemas ?? {}
|
1098
|
+
}),
|
1099
|
+
name,
|
1100
|
+
searchable: metadata.searchable ?? true,
|
1101
|
+
sortable: metadata.sortable ?? true
|
1102
|
+
};
|
1103
|
+
}).filter((field) => field !== null);
|
1104
|
+
};
|
1105
|
+
const useDocument = (args, opts) => {
|
1106
|
+
const { toggleNotification } = useNotification();
|
1107
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1108
|
+
const {
|
1109
|
+
currentData: data,
|
1110
|
+
isLoading: isLoadingDocument,
|
1111
|
+
isFetching: isFetchingDocument,
|
1112
|
+
error
|
1113
|
+
} = useGetDocumentQuery(args, {
|
1114
|
+
...opts,
|
1115
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1116
|
+
});
|
1117
|
+
const {
|
1118
|
+
components,
|
1119
|
+
schema,
|
1120
|
+
schemas,
|
1121
|
+
isLoading: isLoadingSchema
|
1122
|
+
} = useContentTypeSchema(args.model);
|
1123
|
+
React.useEffect(() => {
|
1124
|
+
if (error) {
|
1125
|
+
toggleNotification({
|
1126
|
+
type: "danger",
|
1127
|
+
message: formatAPIError(error)
|
1128
|
+
});
|
1129
|
+
}
|
1130
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1131
|
+
const validationSchema = React.useMemo(() => {
|
1132
|
+
if (!schema) {
|
1133
|
+
return null;
|
1134
|
+
}
|
1135
|
+
return createYupSchema(schema.attributes, components);
|
1136
|
+
}, [schema, components]);
|
1137
|
+
const validate = React.useCallback(
|
1138
|
+
(document) => {
|
1139
|
+
if (!validationSchema) {
|
1140
|
+
throw new Error(
|
1141
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1142
|
+
);
|
1143
|
+
}
|
1144
|
+
try {
|
1145
|
+
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
1146
|
+
return null;
|
1147
|
+
} catch (error2) {
|
1148
|
+
if (error2 instanceof ValidationError) {
|
1149
|
+
return getYupValidationErrors(error2);
|
1150
|
+
}
|
1151
|
+
throw error2;
|
1152
|
+
}
|
1153
|
+
},
|
1154
|
+
[validationSchema]
|
1155
|
+
);
|
1156
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1157
|
+
const hasError = !!error;
|
1158
|
+
return {
|
1159
|
+
components,
|
1160
|
+
document: data?.data,
|
1161
|
+
meta: data?.meta,
|
1162
|
+
isLoading,
|
1163
|
+
hasError,
|
1164
|
+
schema,
|
1165
|
+
schemas,
|
1166
|
+
validate
|
1167
|
+
};
|
1168
|
+
};
|
1169
|
+
const useDoc = () => {
|
1170
|
+
const { id, slug, collectionType, origin } = useParams();
|
1171
|
+
const [{ query }] = useQueryParams();
|
1172
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1173
|
+
if (!collectionType) {
|
1174
|
+
throw new Error("Could not find collectionType in url params");
|
1175
|
+
}
|
1176
|
+
if (!slug) {
|
1177
|
+
throw new Error("Could not find model in url params");
|
1178
|
+
}
|
1179
|
+
const document = useDocument(
|
1180
|
+
{ documentId: origin || id, model: slug, collectionType, params },
|
1181
|
+
{
|
1182
|
+
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
1183
|
+
}
|
1184
|
+
);
|
1185
|
+
const returnId = origin || id === "create" ? void 0 : id;
|
1186
|
+
return {
|
1187
|
+
collectionType,
|
1188
|
+
model: slug,
|
1189
|
+
id: returnId,
|
1190
|
+
...document
|
1191
|
+
};
|
1192
|
+
};
|
1193
|
+
const useContentManagerContext = () => {
|
1194
|
+
const {
|
1195
|
+
collectionType,
|
1196
|
+
model,
|
1197
|
+
id,
|
1198
|
+
components,
|
1199
|
+
isLoading: isLoadingDoc,
|
1200
|
+
schema,
|
1201
|
+
schemas
|
1202
|
+
} = useDoc();
|
1203
|
+
const layout = useDocumentLayout(model);
|
1204
|
+
const form = useForm("useContentManagerContext", (state) => state);
|
1205
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1206
|
+
const slug = model;
|
1207
|
+
const isCreatingEntry = id === "create";
|
1208
|
+
useContentTypeSchema();
|
1209
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1210
|
+
const error = layout.error;
|
1211
|
+
return {
|
1212
|
+
error,
|
1213
|
+
isLoading,
|
1214
|
+
// Base metadata
|
1215
|
+
model,
|
1216
|
+
collectionType,
|
1217
|
+
id,
|
1218
|
+
slug,
|
1219
|
+
isCreatingEntry,
|
1220
|
+
isSingleType,
|
1221
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1222
|
+
// All schema infos
|
1223
|
+
components,
|
1224
|
+
contentType: schema,
|
1225
|
+
contentTypes: schemas,
|
1226
|
+
// Form state
|
1227
|
+
form,
|
1228
|
+
// layout infos
|
1229
|
+
layout
|
1230
|
+
};
|
1231
|
+
};
|
1232
|
+
const prefixPluginTranslations = (trad, pluginId) => {
|
1233
|
+
return Object.keys(trad).reduce((acc, current) => {
|
1234
|
+
acc[`${pluginId}.${current}`] = trad[current];
|
1235
|
+
return acc;
|
1236
|
+
}, {});
|
1237
|
+
};
|
1238
|
+
const getTranslation = (id) => `content-manager.${id}`;
|
1239
|
+
const DEFAULT_UNEXPECTED_ERROR_MSG = {
|
1240
|
+
id: "notification.error",
|
1241
|
+
defaultMessage: "An error occurred, please try again"
|
1242
|
+
};
|
1243
|
+
const useDocumentActions = () => {
|
1244
|
+
const { toggleNotification } = useNotification();
|
1245
|
+
const { formatMessage } = useIntl();
|
1246
|
+
const { trackUsage } = useTracking();
|
1247
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1248
|
+
const navigate = useNavigate();
|
1249
|
+
const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
1250
|
+
const [deleteDocument] = useDeleteDocumentMutation();
|
1251
|
+
const _delete = React.useCallback(
|
1252
|
+
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
1253
|
+
try {
|
1254
|
+
trackUsage("willDeleteEntry", trackerProperty);
|
864
1255
|
const res = await deleteDocument({
|
865
1256
|
collectionType,
|
866
1257
|
model,
|
@@ -1170,6 +1561,7 @@ const useDocumentActions = () => {
|
|
1170
1561
|
defaultMessage: "Saved document"
|
1171
1562
|
})
|
1172
1563
|
});
|
1564
|
+
setCurrentStep("contentManager.success");
|
1173
1565
|
return res.data;
|
1174
1566
|
} catch (err) {
|
1175
1567
|
toggleNotification({
|
@@ -1209,7 +1601,7 @@ const useDocumentActions = () => {
|
|
1209
1601
|
throw err;
|
1210
1602
|
}
|
1211
1603
|
},
|
1212
|
-
[autoCloneDocument,
|
1604
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1213
1605
|
);
|
1214
1606
|
const [cloneDocument] = useCloneDocumentMutation();
|
1215
1607
|
const clone = React.useCallback(
|
@@ -1235,6 +1627,7 @@ const useDocumentActions = () => {
|
|
1235
1627
|
defaultMessage: "Cloned document"
|
1236
1628
|
})
|
1237
1629
|
});
|
1630
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1238
1631
|
return res.data;
|
1239
1632
|
} catch (err) {
|
1240
1633
|
toggleNotification({
|
@@ -1245,7 +1638,7 @@ const useDocumentActions = () => {
|
|
1245
1638
|
throw err;
|
1246
1639
|
}
|
1247
1640
|
},
|
1248
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1641
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1249
1642
|
);
|
1250
1643
|
const [getDoc] = useLazyGetDocumentQuery();
|
1251
1644
|
const getDocument = React.useCallback(
|
@@ -1270,10 +1663,10 @@ const useDocumentActions = () => {
|
|
1270
1663
|
update
|
1271
1664
|
};
|
1272
1665
|
};
|
1273
|
-
const ProtectedHistoryPage = lazy(
|
1274
|
-
() => import("./History-
|
1666
|
+
const ProtectedHistoryPage = React.lazy(
|
1667
|
+
() => import("./History-B9uJsxZl.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1275
1668
|
);
|
1276
|
-
const routes$
|
1669
|
+
const routes$2 = [
|
1277
1670
|
{
|
1278
1671
|
path: ":collectionType/:slug/:id/history",
|
1279
1672
|
Component: ProtectedHistoryPage
|
@@ -1283,32 +1676,45 @@ const routes$1 = [
|
|
1283
1676
|
Component: ProtectedHistoryPage
|
1284
1677
|
}
|
1285
1678
|
];
|
1679
|
+
const ProtectedPreviewPage = React.lazy(
|
1680
|
+
() => import("./Preview-DRJhcaIO.mjs").then((mod) => ({ default: mod.ProtectedPreviewPage }))
|
1681
|
+
);
|
1682
|
+
const routes$1 = [
|
1683
|
+
{
|
1684
|
+
path: ":collectionType/:slug/:id/preview",
|
1685
|
+
Component: ProtectedPreviewPage
|
1686
|
+
},
|
1687
|
+
{
|
1688
|
+
path: ":collectionType/:slug/preview",
|
1689
|
+
Component: ProtectedPreviewPage
|
1690
|
+
}
|
1691
|
+
];
|
1286
1692
|
const ProtectedEditViewPage = lazy(
|
1287
|
-
() => import("./EditViewPage-
|
1693
|
+
() => import("./EditViewPage-hiwZg61J.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1288
1694
|
);
|
1289
1695
|
const ProtectedListViewPage = lazy(
|
1290
|
-
() => import("./ListViewPage-
|
1696
|
+
() => import("./ListViewPage-Ca8F1NL-.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1291
1697
|
);
|
1292
1698
|
const ProtectedListConfiguration = lazy(
|
1293
|
-
() => import("./ListConfigurationPage-
|
1699
|
+
() => import("./ListConfigurationPage-CA4oi4Hj.mjs").then((mod) => ({
|
1294
1700
|
default: mod.ProtectedListConfiguration
|
1295
1701
|
}))
|
1296
1702
|
);
|
1297
1703
|
const ProtectedEditConfigurationPage = lazy(
|
1298
|
-
() => import("./EditConfigurationPage-
|
1704
|
+
() => import("./EditConfigurationPage-CWao3CZ3.mjs").then((mod) => ({
|
1299
1705
|
default: mod.ProtectedEditConfigurationPage
|
1300
1706
|
}))
|
1301
1707
|
);
|
1302
1708
|
const ProtectedComponentConfigurationPage = lazy(
|
1303
|
-
() => import("./ComponentConfigurationPage-
|
1709
|
+
() => import("./ComponentConfigurationPage-DhwMhiRn.mjs").then((mod) => ({
|
1304
1710
|
default: mod.ProtectedComponentConfigurationPage
|
1305
1711
|
}))
|
1306
1712
|
);
|
1307
1713
|
const NoPermissions = lazy(
|
1308
|
-
() => import("./NoPermissionsPage-
|
1714
|
+
() => import("./NoPermissionsPage-iPk2lFR6.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1309
1715
|
);
|
1310
1716
|
const NoContentType = lazy(
|
1311
|
-
() => import("./NoContentTypePage-
|
1717
|
+
() => import("./NoContentTypePage-CwfnU-aN.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1312
1718
|
);
|
1313
1719
|
const CollectionTypePages = () => {
|
1314
1720
|
const { collectionType } = useParams();
|
@@ -1354,6 +1760,7 @@ const routes = [
|
|
1354
1760
|
path: "no-content-types",
|
1355
1761
|
Component: NoContentType
|
1356
1762
|
},
|
1763
|
+
...routes$2,
|
1357
1764
|
...routes$1
|
1358
1765
|
];
|
1359
1766
|
const DocumentActions = ({ actions: actions2 }) => {
|
@@ -1422,12 +1829,14 @@ const DocumentActionButton = (action) => {
|
|
1422
1829
|
/* @__PURE__ */ jsx(
|
1423
1830
|
Button,
|
1424
1831
|
{
|
1425
|
-
flex:
|
1832
|
+
flex: "auto",
|
1426
1833
|
startIcon: action.icon,
|
1427
1834
|
disabled: action.disabled,
|
1428
1835
|
onClick: handleClick(action),
|
1429
1836
|
justifyContent: "center",
|
1430
1837
|
variant: action.variant || "default",
|
1838
|
+
paddingTop: "7px",
|
1839
|
+
paddingBottom: "7px",
|
1431
1840
|
children: action.label
|
1432
1841
|
}
|
1433
1842
|
),
|
@@ -1492,9 +1901,9 @@ const DocumentActionsMenu = ({
|
|
1492
1901
|
disabled: isDisabled,
|
1493
1902
|
size: "S",
|
1494
1903
|
endIcon: null,
|
1495
|
-
paddingTop: "
|
1496
|
-
paddingLeft: "
|
1497
|
-
paddingRight: "
|
1904
|
+
paddingTop: "4px",
|
1905
|
+
paddingLeft: "7px",
|
1906
|
+
paddingRight: "7px",
|
1498
1907
|
variant,
|
1499
1908
|
children: [
|
1500
1909
|
/* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
|
@@ -1505,7 +1914,7 @@ const DocumentActionsMenu = ({
|
|
1505
1914
|
]
|
1506
1915
|
}
|
1507
1916
|
),
|
1508
|
-
/* @__PURE__ */ jsxs(Menu.Content, {
|
1917
|
+
/* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1509
1918
|
actions2.map((action) => {
|
1510
1919
|
return /* @__PURE__ */ jsx(
|
1511
1920
|
Menu.Item,
|
@@ -1514,10 +1923,25 @@ const DocumentActionsMenu = ({
|
|
1514
1923
|
onSelect: handleClick(action),
|
1515
1924
|
display: "block",
|
1516
1925
|
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
|
1517
|
-
/* @__PURE__ */ jsxs(
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1926
|
+
/* @__PURE__ */ jsxs(
|
1927
|
+
Flex,
|
1928
|
+
{
|
1929
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1930
|
+
gap: 2,
|
1931
|
+
tag: "span",
|
1932
|
+
children: [
|
1933
|
+
/* @__PURE__ */ jsx(
|
1934
|
+
Flex,
|
1935
|
+
{
|
1936
|
+
tag: "span",
|
1937
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1938
|
+
children: action.icon
|
1939
|
+
}
|
1940
|
+
),
|
1941
|
+
action.label
|
1942
|
+
]
|
1943
|
+
}
|
1944
|
+
),
|
1521
1945
|
action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
|
1522
1946
|
Flex,
|
1523
1947
|
{
|
@@ -1614,11 +2038,11 @@ const DocumentActionConfirmDialog = ({
|
|
1614
2038
|
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
1615
2039
|
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
1616
2040
|
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
1617
|
-
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", children: formatMessage({
|
2041
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
1618
2042
|
id: "app.components.Button.cancel",
|
1619
2043
|
defaultMessage: "Cancel"
|
1620
2044
|
}) }) }),
|
1621
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2045
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1622
2046
|
id: "app.components.Button.confirm",
|
1623
2047
|
defaultMessage: "Confirm"
|
1624
2048
|
}) })
|
@@ -1645,6 +2069,18 @@ const DocumentActionModal = ({
|
|
1645
2069
|
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
1646
2070
|
] }) });
|
1647
2071
|
};
|
2072
|
+
const transformData = (data) => {
|
2073
|
+
if (Array.isArray(data)) {
|
2074
|
+
return data.map(transformData);
|
2075
|
+
}
|
2076
|
+
if (typeof data === "object" && data !== null) {
|
2077
|
+
if ("apiData" in data) {
|
2078
|
+
return data.apiData;
|
2079
|
+
}
|
2080
|
+
return mapValues(transformData)(data);
|
2081
|
+
}
|
2082
|
+
return data;
|
2083
|
+
};
|
1648
2084
|
const PublishAction$1 = ({
|
1649
2085
|
activeTab,
|
1650
2086
|
documentId,
|
@@ -1657,12 +2093,10 @@ const PublishAction$1 = ({
|
|
1657
2093
|
const navigate = useNavigate();
|
1658
2094
|
const { toggleNotification } = useNotification();
|
1659
2095
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
2096
|
+
const isListView = useMatch(LIST_PATH) !== null;
|
1660
2097
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
1661
2098
|
const { formatMessage } = useIntl();
|
1662
|
-
const { canPublish
|
1663
|
-
"PublishAction",
|
1664
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1665
|
-
);
|
2099
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1666
2100
|
const { publish } = useDocumentActions();
|
1667
2101
|
const [
|
1668
2102
|
countDraftRelations,
|
@@ -1714,24 +2148,25 @@ const PublishAction$1 = ({
|
|
1714
2148
|
}
|
1715
2149
|
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1716
2150
|
React.useEffect(() => {
|
1717
|
-
if (documentId) {
|
1718
|
-
|
1719
|
-
const { data, error } = await countDraftRelations({
|
1720
|
-
collectionType,
|
1721
|
-
model,
|
1722
|
-
documentId,
|
1723
|
-
params
|
1724
|
-
});
|
1725
|
-
if (error) {
|
1726
|
-
throw error;
|
1727
|
-
}
|
1728
|
-
if (data) {
|
1729
|
-
setServerCountOfDraftRelations(data.data);
|
1730
|
-
}
|
1731
|
-
};
|
1732
|
-
fetchDraftRelationsCount();
|
2151
|
+
if (!document || !document.documentId || isListView) {
|
2152
|
+
return;
|
1733
2153
|
}
|
1734
|
-
|
2154
|
+
const fetchDraftRelationsCount = async () => {
|
2155
|
+
const { data, error } = await countDraftRelations({
|
2156
|
+
collectionType,
|
2157
|
+
model,
|
2158
|
+
documentId,
|
2159
|
+
params
|
2160
|
+
});
|
2161
|
+
if (error) {
|
2162
|
+
throw error;
|
2163
|
+
}
|
2164
|
+
if (data) {
|
2165
|
+
setServerCountOfDraftRelations(data.data);
|
2166
|
+
}
|
2167
|
+
};
|
2168
|
+
fetchDraftRelationsCount();
|
2169
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
1735
2170
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1736
2171
|
if (!schema?.options?.draftAndPublish) {
|
1737
2172
|
return null;
|
@@ -1739,7 +2174,9 @@ const PublishAction$1 = ({
|
|
1739
2174
|
const performPublish = async () => {
|
1740
2175
|
setSubmitting(true);
|
1741
2176
|
try {
|
1742
|
-
const { errors } = await validate(
|
2177
|
+
const { errors } = await validate(true, {
|
2178
|
+
status: "published"
|
2179
|
+
});
|
1743
2180
|
if (errors) {
|
1744
2181
|
toggleNotification({
|
1745
2182
|
type: "danger",
|
@@ -1757,7 +2194,7 @@ const PublishAction$1 = ({
|
|
1757
2194
|
documentId,
|
1758
2195
|
params
|
1759
2196
|
},
|
1760
|
-
formValues
|
2197
|
+
transformData(formValues)
|
1761
2198
|
);
|
1762
2199
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1763
2200
|
navigate({
|
@@ -1772,7 +2209,8 @@ const PublishAction$1 = ({
|
|
1772
2209
|
}
|
1773
2210
|
};
|
1774
2211
|
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1775
|
-
const
|
2212
|
+
const enableDraftRelationsCount = false;
|
2213
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1776
2214
|
return {
|
1777
2215
|
/**
|
1778
2216
|
* Disabled when:
|
@@ -1782,18 +2220,13 @@ const PublishAction$1 = ({
|
|
1782
2220
|
* - the document is already published & not modified
|
1783
2221
|
* - the document is being created & not modified
|
1784
2222
|
* - the user doesn't have the permission to publish
|
1785
|
-
* - the user doesn't have the permission to create a new document
|
1786
|
-
* - the user doesn't have the permission to update the document
|
1787
2223
|
*/
|
1788
|
-
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
2224
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1789
2225
|
label: formatMessage({
|
1790
2226
|
id: "app.utils.publish",
|
1791
2227
|
defaultMessage: "Publish"
|
1792
2228
|
}),
|
1793
2229
|
onClick: async () => {
|
1794
|
-
if (hasDraftRelations) {
|
1795
|
-
return;
|
1796
|
-
}
|
1797
2230
|
await performPublish();
|
1798
2231
|
},
|
1799
2232
|
dialog: hasDraftRelations ? {
|
@@ -1832,10 +2265,6 @@ const UpdateAction = ({
|
|
1832
2265
|
const cloneMatch = useMatch(CLONE_PATH);
|
1833
2266
|
const isCloning = cloneMatch !== null;
|
1834
2267
|
const { formatMessage } = useIntl();
|
1835
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1836
|
-
canCreate: canCreate2,
|
1837
|
-
canUpdate: canUpdate2
|
1838
|
-
}));
|
1839
2268
|
const { create, update, clone } = useDocumentActions();
|
1840
2269
|
const [{ query, rawQuery }] = useQueryParams();
|
1841
2270
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
@@ -1852,10 +2281,8 @@ const UpdateAction = ({
|
|
1852
2281
|
* - the form is submitting
|
1853
2282
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1854
2283
|
* - the active tab is the published tab
|
1855
|
-
* - the user doesn't have the permission to create a new document
|
1856
|
-
* - the user doesn't have the permission to update the document
|
1857
2284
|
*/
|
1858
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
2285
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1859
2286
|
label: formatMessage({
|
1860
2287
|
id: "content-manager.containers.Edit.save",
|
1861
2288
|
defaultMessage: "Save"
|
@@ -1863,7 +2290,9 @@ const UpdateAction = ({
|
|
1863
2290
|
onClick: async () => {
|
1864
2291
|
setSubmitting(true);
|
1865
2292
|
try {
|
1866
|
-
const { errors } = await validate(
|
2293
|
+
const { errors } = await validate(true, {
|
2294
|
+
status: "draft"
|
2295
|
+
});
|
1867
2296
|
if (errors) {
|
1868
2297
|
toggleNotification({
|
1869
2298
|
type: "danger",
|
@@ -1881,7 +2310,7 @@ const UpdateAction = ({
|
|
1881
2310
|
documentId: cloneMatch.params.origin,
|
1882
2311
|
params
|
1883
2312
|
},
|
1884
|
-
document
|
2313
|
+
transformData(document)
|
1885
2314
|
);
|
1886
2315
|
if ("data" in res) {
|
1887
2316
|
navigate(
|
@@ -1902,7 +2331,7 @@ const UpdateAction = ({
|
|
1902
2331
|
documentId,
|
1903
2332
|
params
|
1904
2333
|
},
|
1905
|
-
document
|
2334
|
+
transformData(document)
|
1906
2335
|
);
|
1907
2336
|
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1908
2337
|
setErrors(formatValidationErrors(res.error));
|
@@ -1915,7 +2344,7 @@ const UpdateAction = ({
|
|
1915
2344
|
model,
|
1916
2345
|
params
|
1917
2346
|
},
|
1918
|
-
document
|
2347
|
+
transformData(document)
|
1919
2348
|
);
|
1920
2349
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1921
2350
|
navigate(
|
@@ -1968,7 +2397,7 @@ const UnpublishAction$1 = ({
|
|
1968
2397
|
id: "app.utils.unpublish",
|
1969
2398
|
defaultMessage: "Unpublish"
|
1970
2399
|
}),
|
1971
|
-
icon: /* @__PURE__ */ jsx(
|
2400
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1972
2401
|
onClick: async () => {
|
1973
2402
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1974
2403
|
if (!documentId) {
|
@@ -2080,7 +2509,7 @@ const DiscardAction = ({
|
|
2080
2509
|
id: "content-manager.actions.discard.label",
|
2081
2510
|
defaultMessage: "Discard changes"
|
2082
2511
|
}),
|
2083
|
-
icon: /* @__PURE__ */ jsx(
|
2512
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
2084
2513
|
position: ["panel", "table-row"],
|
2085
2514
|
variant: "danger",
|
2086
2515
|
dialog: {
|
@@ -2108,11 +2537,6 @@ const DiscardAction = ({
|
|
2108
2537
|
};
|
2109
2538
|
};
|
2110
2539
|
DiscardAction.type = "discard";
|
2111
|
-
const StyledCrossCircle = styled(CrossCircle)`
|
2112
|
-
path {
|
2113
|
-
fill: currentColor;
|
2114
|
-
}
|
2115
|
-
`;
|
2116
2540
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2117
2541
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2118
2542
|
const RelativeTime = React.forwardRef(
|
@@ -2160,8 +2584,12 @@ const getDisplayName = ({
|
|
2160
2584
|
};
|
2161
2585
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2162
2586
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2163
|
-
const statusVariant = status === "draft" ? "
|
2164
|
-
|
2587
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2588
|
+
const { formatMessage } = useIntl();
|
2589
|
+
return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: formatMessage({
|
2590
|
+
id: `content-manager.containers.List.${status}`,
|
2591
|
+
defaultMessage: capitalise(status)
|
2592
|
+
}) }) });
|
2165
2593
|
};
|
2166
2594
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2167
2595
|
const { formatMessage } = useIntl();
|
@@ -2259,12 +2687,12 @@ const Information = ({ activeTab }) => {
|
|
2259
2687
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2260
2688
|
label: formatMessage({
|
2261
2689
|
id: "content-manager.containers.edit.information.last-published.label",
|
2262
|
-
defaultMessage: "
|
2690
|
+
defaultMessage: "Published"
|
2263
2691
|
}),
|
2264
2692
|
value: formatMessage(
|
2265
2693
|
{
|
2266
2694
|
id: "content-manager.containers.edit.information.last-published.value",
|
2267
|
-
defaultMessage: `
|
2695
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2268
2696
|
},
|
2269
2697
|
{
|
2270
2698
|
time: /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2277,12 +2705,12 @@ const Information = ({ activeTab }) => {
|
|
2277
2705
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2278
2706
|
label: formatMessage({
|
2279
2707
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2280
|
-
defaultMessage: "
|
2708
|
+
defaultMessage: "Updated"
|
2281
2709
|
}),
|
2282
2710
|
value: formatMessage(
|
2283
2711
|
{
|
2284
2712
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2285
|
-
defaultMessage: `
|
2713
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2286
2714
|
},
|
2287
2715
|
{
|
2288
2716
|
time: /* @__PURE__ */ jsx(
|
@@ -2300,12 +2728,12 @@ const Information = ({ activeTab }) => {
|
|
2300
2728
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2301
2729
|
label: formatMessage({
|
2302
2730
|
id: "content-manager.containers.edit.information.document.label",
|
2303
|
-
defaultMessage: "
|
2731
|
+
defaultMessage: "Created"
|
2304
2732
|
}),
|
2305
2733
|
value: formatMessage(
|
2306
2734
|
{
|
2307
2735
|
id: "content-manager.containers.edit.information.document.value",
|
2308
|
-
defaultMessage: `
|
2736
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2309
2737
|
},
|
2310
2738
|
{
|
2311
2739
|
time: /* @__PURE__ */ jsx(
|
@@ -2343,523 +2771,277 @@ const Information = ({ activeTab }) => {
|
|
2343
2771
|
);
|
2344
2772
|
};
|
2345
2773
|
const HeaderActions = ({ actions: actions2 }) => {
|
2346
|
-
|
2347
|
-
|
2774
|
+
const [dialogId, setDialogId] = React.useState(null);
|
2775
|
+
const handleClick = (action) => async (e) => {
|
2776
|
+
if (!("options" in action)) {
|
2777
|
+
const { onClick = () => false, dialog, id } = action;
|
2778
|
+
const muteDialog = await onClick(e);
|
2779
|
+
if (dialog && !muteDialog) {
|
2780
|
+
e.preventDefault();
|
2781
|
+
setDialogId(id);
|
2782
|
+
}
|
2783
|
+
}
|
2784
|
+
};
|
2785
|
+
const handleClose = () => {
|
2786
|
+
setDialogId(null);
|
2787
|
+
};
|
2788
|
+
return /* @__PURE__ */ jsx(Flex, { gap: 1, children: actions2.map((action) => {
|
2789
|
+
if (action.options) {
|
2348
2790
|
return /* @__PURE__ */ jsx(
|
2349
2791
|
SingleSelect,
|
2350
2792
|
{
|
2351
2793
|
size: "S",
|
2352
|
-
disabled: action.disabled,
|
2353
|
-
"aria-label": action.label,
|
2354
2794
|
onChange: action.onSelect,
|
2355
|
-
|
2795
|
+
"aria-label": action.label,
|
2796
|
+
...action,
|
2356
2797
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
|
2357
2798
|
},
|
2358
2799
|
action.id
|
2359
2800
|
);
|
2360
2801
|
} else {
|
2361
|
-
|
2362
|
-
|
2363
|
-
|
2364
|
-
|
2365
|
-
|
2366
|
-
|
2367
|
-
|
2368
|
-
|
2369
|
-
|
2370
|
-
|
2371
|
-
defaultMessage: "Configure the view"
|
2372
|
-
}),
|
2373
|
-
icon: /* @__PURE__ */ jsx(ListPlus, {}),
|
2374
|
-
onClick: () => {
|
2375
|
-
navigate(`../${collectionType}/${model}/configurations/edit`);
|
2376
|
-
},
|
2377
|
-
position: "header"
|
2378
|
-
};
|
2379
|
-
};
|
2380
|
-
ConfigureTheViewAction.type = "configure-the-view";
|
2381
|
-
const EditTheModelAction = ({ model }) => {
|
2382
|
-
const navigate = useNavigate();
|
2383
|
-
const { formatMessage } = useIntl();
|
2384
|
-
return {
|
2385
|
-
label: formatMessage({
|
2386
|
-
id: "content-manager.link-to-ctb",
|
2387
|
-
defaultMessage: "Edit the model"
|
2388
|
-
}),
|
2389
|
-
icon: /* @__PURE__ */ jsx(Pencil, {}),
|
2390
|
-
onClick: () => {
|
2391
|
-
navigate(`/plugins/content-type-builder/content-types/${model}`);
|
2392
|
-
},
|
2393
|
-
position: "header"
|
2394
|
-
};
|
2395
|
-
};
|
2396
|
-
EditTheModelAction.type = "edit-the-model";
|
2397
|
-
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2398
|
-
const navigate = useNavigate();
|
2399
|
-
const { formatMessage } = useIntl();
|
2400
|
-
const listViewPathMatch = useMatch(LIST_PATH);
|
2401
|
-
const canDelete = useDocumentRBAC("DeleteAction", (state) => state.canDelete);
|
2402
|
-
const { delete: deleteAction } = useDocumentActions();
|
2403
|
-
const { toggleNotification } = useNotification();
|
2404
|
-
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
2405
|
-
return {
|
2406
|
-
disabled: !canDelete || !document,
|
2407
|
-
label: formatMessage({
|
2408
|
-
id: "content-manager.actions.delete.label",
|
2409
|
-
defaultMessage: "Delete document"
|
2410
|
-
}),
|
2411
|
-
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2412
|
-
dialog: {
|
2413
|
-
type: "dialog",
|
2414
|
-
title: formatMessage({
|
2415
|
-
id: "app.components.ConfirmDialog.title",
|
2416
|
-
defaultMessage: "Confirmation"
|
2417
|
-
}),
|
2418
|
-
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
2419
|
-
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2420
|
-
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2421
|
-
id: "content-manager.actions.delete.dialog.body",
|
2422
|
-
defaultMessage: "Are you sure?"
|
2423
|
-
}) })
|
2424
|
-
] }),
|
2425
|
-
onConfirm: async () => {
|
2426
|
-
if (!listViewPathMatch) {
|
2427
|
-
setSubmitting(true);
|
2428
|
-
}
|
2429
|
-
try {
|
2430
|
-
if (!documentId && collectionType !== SINGLE_TYPES) {
|
2431
|
-
console.error(
|
2432
|
-
"You're trying to delete a document without an id, this is likely a bug with Strapi. Please open an issue."
|
2433
|
-
);
|
2434
|
-
toggleNotification({
|
2435
|
-
message: formatMessage({
|
2436
|
-
id: "content-manager.actions.delete.error",
|
2437
|
-
defaultMessage: "An error occurred while trying to delete the document."
|
2438
|
-
}),
|
2439
|
-
type: "danger"
|
2440
|
-
});
|
2441
|
-
return;
|
2442
|
-
}
|
2443
|
-
const res = await deleteAction({
|
2444
|
-
documentId,
|
2445
|
-
model,
|
2446
|
-
collectionType,
|
2447
|
-
params: {
|
2448
|
-
locale: "*"
|
2802
|
+
if (action.type === "icon") {
|
2803
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
2804
|
+
/* @__PURE__ */ jsx(
|
2805
|
+
IconButton,
|
2806
|
+
{
|
2807
|
+
disabled: action.disabled,
|
2808
|
+
label: action.label,
|
2809
|
+
size: "S",
|
2810
|
+
onClick: handleClick(action),
|
2811
|
+
children: action.icon
|
2449
2812
|
}
|
2450
|
-
|
2451
|
-
|
2452
|
-
|
2453
|
-
|
2454
|
-
|
2455
|
-
|
2456
|
-
|
2457
|
-
|
2458
|
-
|
2459
|
-
|
2460
|
-
|
2461
|
-
variant: "danger",
|
2462
|
-
position: ["header", "table-row"]
|
2463
|
-
};
|
2464
|
-
};
|
2465
|
-
DeleteAction$1.type = "delete";
|
2466
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2467
|
-
const Panels = () => {
|
2468
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2469
|
-
const [
|
2470
|
-
{
|
2471
|
-
query: { status }
|
2472
|
-
}
|
2473
|
-
] = useQueryParams({
|
2474
|
-
status: "draft"
|
2475
|
-
});
|
2476
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2477
|
-
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
2478
|
-
const props = {
|
2479
|
-
activeTab: status,
|
2480
|
-
model,
|
2481
|
-
documentId: id,
|
2482
|
-
document: isCloning ? void 0 : document,
|
2483
|
-
meta: isCloning ? void 0 : meta,
|
2484
|
-
collectionType
|
2485
|
-
};
|
2486
|
-
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
2487
|
-
DescriptionComponentRenderer,
|
2488
|
-
{
|
2489
|
-
props,
|
2490
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2491
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
2492
|
-
}
|
2493
|
-
) });
|
2494
|
-
};
|
2495
|
-
const ActionsPanel = () => {
|
2496
|
-
const { formatMessage } = useIntl();
|
2497
|
-
return {
|
2498
|
-
title: formatMessage({
|
2499
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2500
|
-
defaultMessage: "Document"
|
2501
|
-
}),
|
2502
|
-
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2503
|
-
};
|
2504
|
-
};
|
2505
|
-
ActionsPanel.type = "actions";
|
2506
|
-
const ActionsPanelContent = () => {
|
2507
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
2508
|
-
const [
|
2509
|
-
{
|
2510
|
-
query: { status = "draft" }
|
2511
|
-
}
|
2512
|
-
] = useQueryParams();
|
2513
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2514
|
-
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2515
|
-
const props = {
|
2516
|
-
activeTab: status,
|
2517
|
-
model,
|
2518
|
-
documentId: id,
|
2519
|
-
document: isCloning ? void 0 : document,
|
2520
|
-
meta: isCloning ? void 0 : meta,
|
2521
|
-
collectionType
|
2522
|
-
};
|
2523
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2524
|
-
/* @__PURE__ */ jsx(
|
2525
|
-
DescriptionComponentRenderer,
|
2526
|
-
{
|
2527
|
-
props,
|
2528
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2529
|
-
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
2530
|
-
}
|
2531
|
-
),
|
2532
|
-
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2533
|
-
] });
|
2534
|
-
};
|
2535
|
-
const Panel = React.forwardRef(({ children, title }, ref) => {
|
2536
|
-
return /* @__PURE__ */ jsxs(
|
2537
|
-
Flex,
|
2538
|
-
{
|
2539
|
-
ref,
|
2540
|
-
tag: "aside",
|
2541
|
-
"aria-labelledby": "additional-information",
|
2542
|
-
background: "neutral0",
|
2543
|
-
borderColor: "neutral150",
|
2544
|
-
hasRadius: true,
|
2545
|
-
paddingBottom: 4,
|
2546
|
-
paddingLeft: 4,
|
2547
|
-
paddingRight: 4,
|
2548
|
-
paddingTop: 4,
|
2549
|
-
shadow: "tableShadow",
|
2550
|
-
gap: 3,
|
2551
|
-
direction: "column",
|
2552
|
-
justifyContent: "stretch",
|
2553
|
-
alignItems: "flex-start",
|
2554
|
-
children: [
|
2555
|
-
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2556
|
-
children
|
2557
|
-
]
|
2813
|
+
),
|
2814
|
+
action.dialog ? /* @__PURE__ */ jsx(
|
2815
|
+
HeaderActionDialog,
|
2816
|
+
{
|
2817
|
+
...action.dialog,
|
2818
|
+
isOpen: dialogId === action.id,
|
2819
|
+
onClose: handleClose
|
2820
|
+
}
|
2821
|
+
) : null
|
2822
|
+
] }, action.id);
|
2823
|
+
}
|
2558
2824
|
}
|
2559
|
-
);
|
2560
|
-
});
|
2561
|
-
const HOOKS = {
|
2562
|
-
/**
|
2563
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2564
|
-
* @constant
|
2565
|
-
* @type {string}
|
2566
|
-
*/
|
2567
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2568
|
-
/**
|
2569
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2570
|
-
* @constant
|
2571
|
-
* @type {string}
|
2572
|
-
*/
|
2573
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2574
|
-
/**
|
2575
|
-
* Hook that allows to mutate the CM's edit view layout
|
2576
|
-
* @constant
|
2577
|
-
* @type {string}
|
2578
|
-
*/
|
2579
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2580
|
-
/**
|
2581
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2582
|
-
* @constant
|
2583
|
-
* @type {string}
|
2584
|
-
*/
|
2585
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2825
|
+
}) });
|
2586
2826
|
};
|
2587
|
-
const
|
2588
|
-
|
2589
|
-
|
2590
|
-
|
2591
|
-
|
2592
|
-
|
2593
|
-
|
2594
|
-
|
2595
|
-
|
2596
|
-
|
2597
|
-
|
2598
|
-
|
2599
|
-
|
2600
|
-
|
2601
|
-
|
2602
|
-
|
2603
|
-
|
2604
|
-
}),
|
2605
|
-
updateContentTypeConfiguration: builder.mutation({
|
2606
|
-
query: ({ uid, ...body }) => ({
|
2607
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2608
|
-
method: "PUT",
|
2609
|
-
data: body
|
2610
|
-
}),
|
2611
|
-
transformResponse: (response) => response.data,
|
2612
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2613
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2614
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2615
|
-
// Is this necessary?
|
2616
|
-
{ type: "InitialData" }
|
2617
|
-
]
|
2618
|
-
})
|
2619
|
-
})
|
2620
|
-
});
|
2621
|
-
const {
|
2622
|
-
useGetContentTypeConfigurationQuery,
|
2623
|
-
useGetAllContentTypeSettingsQuery,
|
2624
|
-
useUpdateContentTypeConfigurationMutation
|
2625
|
-
} = contentTypesApi;
|
2626
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2627
|
-
const { type } = attribute;
|
2628
|
-
if (type === "relation") {
|
2629
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2630
|
-
}
|
2631
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2827
|
+
const HeaderActionDialog = ({
|
2828
|
+
onClose,
|
2829
|
+
onCancel,
|
2830
|
+
title,
|
2831
|
+
content: Content,
|
2832
|
+
isOpen
|
2833
|
+
}) => {
|
2834
|
+
const handleClose = async () => {
|
2835
|
+
if (onCancel) {
|
2836
|
+
await onCancel();
|
2837
|
+
}
|
2838
|
+
onClose();
|
2839
|
+
};
|
2840
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2841
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
2842
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content
|
2843
|
+
] }) });
|
2632
2844
|
};
|
2633
|
-
const
|
2634
|
-
|
2635
|
-
|
2636
|
-
}
|
2637
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2638
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2639
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2640
|
-
);
|
2845
|
+
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2846
|
+
const navigate = useNavigate();
|
2847
|
+
const { formatMessage } = useIntl();
|
2641
2848
|
return {
|
2642
|
-
|
2643
|
-
|
2849
|
+
label: formatMessage({
|
2850
|
+
id: "app.links.configure-view",
|
2851
|
+
defaultMessage: "Configure the view"
|
2852
|
+
}),
|
2853
|
+
icon: /* @__PURE__ */ jsx(ListPlus, {}),
|
2854
|
+
onClick: () => {
|
2855
|
+
navigate(`../${collectionType}/${model}/configurations/edit`);
|
2856
|
+
},
|
2857
|
+
position: "header"
|
2644
2858
|
};
|
2645
2859
|
};
|
2646
|
-
|
2647
|
-
|
2648
|
-
|
2649
|
-
|
2650
|
-
pagination: false,
|
2651
|
-
defaultSortBy: "",
|
2652
|
-
defaultSortOrder: "asc",
|
2653
|
-
mainField: "id",
|
2654
|
-
pageSize: 10
|
2655
|
-
};
|
2656
|
-
const useDocumentLayout = (model) => {
|
2657
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2658
|
-
const [{ query }] = useQueryParams();
|
2659
|
-
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2660
|
-
const { toggleNotification } = useNotification();
|
2661
|
-
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
2662
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2663
|
-
const {
|
2664
|
-
data,
|
2665
|
-
isLoading: isLoadingConfigs,
|
2666
|
-
error,
|
2667
|
-
isFetching: isFetchingConfigs
|
2668
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2669
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2670
|
-
React.useEffect(() => {
|
2671
|
-
if (error) {
|
2672
|
-
toggleNotification({
|
2673
|
-
type: "danger",
|
2674
|
-
message: formatAPIError(error)
|
2675
|
-
});
|
2676
|
-
}
|
2677
|
-
}, [error, formatAPIError, toggleNotification]);
|
2678
|
-
const editLayout = React.useMemo(
|
2679
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2680
|
-
layout: [],
|
2681
|
-
components: {},
|
2682
|
-
metadatas: {},
|
2683
|
-
options: {},
|
2684
|
-
settings: DEFAULT_SETTINGS
|
2685
|
-
},
|
2686
|
-
[data, isLoading, schemas, schema, components]
|
2687
|
-
);
|
2688
|
-
const listLayout = React.useMemo(() => {
|
2689
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2690
|
-
layout: [],
|
2691
|
-
metadatas: {},
|
2692
|
-
options: {},
|
2693
|
-
settings: DEFAULT_SETTINGS
|
2694
|
-
};
|
2695
|
-
}, [data, isLoading, schemas, schema, components]);
|
2696
|
-
const { layout: edit } = React.useMemo(
|
2697
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2698
|
-
layout: editLayout,
|
2699
|
-
query
|
2700
|
-
}),
|
2701
|
-
[editLayout, query, runHookWaterfall]
|
2702
|
-
);
|
2860
|
+
ConfigureTheViewAction.type = "configure-the-view";
|
2861
|
+
const EditTheModelAction = ({ model }) => {
|
2862
|
+
const navigate = useNavigate();
|
2863
|
+
const { formatMessage } = useIntl();
|
2703
2864
|
return {
|
2704
|
-
|
2705
|
-
|
2706
|
-
|
2707
|
-
|
2865
|
+
label: formatMessage({
|
2866
|
+
id: "content-manager.link-to-ctb",
|
2867
|
+
defaultMessage: "Edit the model"
|
2868
|
+
}),
|
2869
|
+
icon: /* @__PURE__ */ jsx(Pencil, {}),
|
2870
|
+
onClick: () => {
|
2871
|
+
navigate(`/plugins/content-type-builder/content-types/${model}`);
|
2872
|
+
},
|
2873
|
+
position: "header"
|
2708
2874
|
};
|
2709
2875
|
};
|
2710
|
-
|
2711
|
-
|
2712
|
-
|
2713
|
-
};
|
2714
|
-
const
|
2715
|
-
|
2716
|
-
|
2717
|
-
|
2718
|
-
|
2719
|
-
|
2720
|
-
|
2721
|
-
|
2722
|
-
|
2723
|
-
|
2724
|
-
|
2725
|
-
|
2726
|
-
|
2727
|
-
|
2728
|
-
|
2729
|
-
|
2730
|
-
|
2731
|
-
|
2732
|
-
|
2733
|
-
|
2734
|
-
|
2735
|
-
|
2736
|
-
|
2737
|
-
|
2738
|
-
|
2739
|
-
|
2740
|
-
|
2741
|
-
|
2742
|
-
|
2743
|
-
|
2744
|
-
|
2745
|
-
|
2746
|
-
|
2747
|
-
|
2748
|
-
|
2749
|
-
|
2876
|
+
EditTheModelAction.type = "edit-the-model";
|
2877
|
+
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2878
|
+
const navigate = useNavigate();
|
2879
|
+
const { formatMessage } = useIntl();
|
2880
|
+
const listViewPathMatch = useMatch(LIST_PATH);
|
2881
|
+
const canDelete = useDocumentRBAC("DeleteAction", (state) => state.canDelete);
|
2882
|
+
const { delete: deleteAction } = useDocumentActions();
|
2883
|
+
const { toggleNotification } = useNotification();
|
2884
|
+
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
2885
|
+
const isLocalized = document?.locale != null;
|
2886
|
+
return {
|
2887
|
+
disabled: !canDelete || !document,
|
2888
|
+
label: formatMessage(
|
2889
|
+
{
|
2890
|
+
id: "content-manager.actions.delete.label",
|
2891
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2892
|
+
},
|
2893
|
+
{ isLocalized }
|
2894
|
+
),
|
2895
|
+
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2896
|
+
dialog: {
|
2897
|
+
type: "dialog",
|
2898
|
+
title: formatMessage({
|
2899
|
+
id: "app.components.ConfirmDialog.title",
|
2900
|
+
defaultMessage: "Confirmation"
|
2901
|
+
}),
|
2902
|
+
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
2903
|
+
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2904
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2905
|
+
id: "content-manager.actions.delete.dialog.body",
|
2906
|
+
defaultMessage: "Are you sure?"
|
2907
|
+
}) })
|
2908
|
+
] }),
|
2909
|
+
onConfirm: async () => {
|
2910
|
+
if (!listViewPathMatch) {
|
2911
|
+
setSubmitting(true);
|
2912
|
+
}
|
2913
|
+
try {
|
2914
|
+
if (!documentId && collectionType !== SINGLE_TYPES) {
|
2915
|
+
console.error(
|
2916
|
+
"You're trying to delete a document without an id, this is likely a bug with Strapi. Please open an issue."
|
2917
|
+
);
|
2918
|
+
toggleNotification({
|
2919
|
+
message: formatMessage({
|
2920
|
+
id: "content-manager.actions.delete.error",
|
2921
|
+
defaultMessage: "An error occurred while trying to delete the document."
|
2922
|
+
}),
|
2923
|
+
type: "danger"
|
2924
|
+
});
|
2925
|
+
return;
|
2926
|
+
}
|
2927
|
+
const res = await deleteAction({
|
2928
|
+
documentId,
|
2929
|
+
model,
|
2930
|
+
collectionType,
|
2931
|
+
params: {
|
2932
|
+
locale: "*"
|
2933
|
+
}
|
2934
|
+
});
|
2935
|
+
if (!("error" in res)) {
|
2936
|
+
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2937
|
+
}
|
2938
|
+
} finally {
|
2939
|
+
if (!listViewPathMatch) {
|
2940
|
+
setSubmitting(false);
|
2941
|
+
}
|
2750
2942
|
}
|
2751
|
-
}
|
2752
|
-
return acc;
|
2753
|
-
},
|
2754
|
-
{}
|
2755
|
-
);
|
2756
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2757
|
-
(acc, [attribute, metadata]) => {
|
2758
|
-
return {
|
2759
|
-
...acc,
|
2760
|
-
[attribute]: metadata.edit
|
2761
|
-
};
|
2762
|
-
},
|
2763
|
-
{}
|
2764
|
-
);
|
2765
|
-
return {
|
2766
|
-
layout: panelledEditAttributes,
|
2767
|
-
components: componentEditAttributes,
|
2768
|
-
metadatas: editMetadatas,
|
2769
|
-
settings: {
|
2770
|
-
...data.contentType.settings,
|
2771
|
-
displayName: schema?.info.displayName
|
2943
|
+
}
|
2772
2944
|
},
|
2773
|
-
|
2774
|
-
|
2775
|
-
...schema?.pluginOptions,
|
2776
|
-
...data.contentType.options
|
2777
|
-
}
|
2945
|
+
variant: "danger",
|
2946
|
+
position: ["header", "table-row"]
|
2778
2947
|
};
|
2779
2948
|
};
|
2780
|
-
|
2781
|
-
|
2782
|
-
|
2783
|
-
|
2784
|
-
|
2785
|
-
|
2786
|
-
}
|
2787
|
-
|
2788
|
-
|
2789
|
-
|
2790
|
-
|
2791
|
-
|
2792
|
-
|
2793
|
-
|
2794
|
-
|
2795
|
-
|
2796
|
-
|
2797
|
-
|
2798
|
-
|
2799
|
-
|
2800
|
-
|
2801
|
-
|
2802
|
-
|
2803
|
-
|
2804
|
-
|
2805
|
-
|
2806
|
-
}
|
2807
|
-
}
|
2808
|
-
);
|
2949
|
+
DeleteAction$1.type = "delete";
|
2950
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2951
|
+
const Panels = () => {
|
2952
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
2953
|
+
const [
|
2954
|
+
{
|
2955
|
+
query: { status }
|
2956
|
+
}
|
2957
|
+
] = useQueryParams({
|
2958
|
+
status: "draft"
|
2959
|
+
});
|
2960
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
2961
|
+
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
2962
|
+
const props = {
|
2963
|
+
activeTab: status,
|
2964
|
+
model,
|
2965
|
+
documentId: id,
|
2966
|
+
document: isCloning ? void 0 : document,
|
2967
|
+
meta: isCloning ? void 0 : meta,
|
2968
|
+
collectionType
|
2969
|
+
};
|
2970
|
+
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
2971
|
+
DescriptionComponentRenderer,
|
2972
|
+
{
|
2973
|
+
props,
|
2974
|
+
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2975
|
+
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
2976
|
+
}
|
2977
|
+
) });
|
2809
2978
|
};
|
2810
|
-
const
|
2811
|
-
|
2812
|
-
schema,
|
2813
|
-
components
|
2814
|
-
}) => {
|
2815
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2816
|
-
(acc, [attribute, metadata]) => {
|
2817
|
-
return {
|
2818
|
-
...acc,
|
2819
|
-
[attribute]: metadata.list
|
2820
|
-
};
|
2821
|
-
},
|
2822
|
-
{}
|
2823
|
-
);
|
2824
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2825
|
-
data.contentType.layouts.list,
|
2826
|
-
schema?.attributes,
|
2827
|
-
listMetadatas,
|
2828
|
-
{ configurations: data.components, schemas: components },
|
2829
|
-
schemas
|
2830
|
-
);
|
2979
|
+
const ActionsPanel = () => {
|
2980
|
+
const { formatMessage } = useIntl();
|
2831
2981
|
return {
|
2832
|
-
|
2833
|
-
|
2834
|
-
|
2835
|
-
|
2836
|
-
|
2837
|
-
...schema?.pluginOptions,
|
2838
|
-
...data.contentType.options
|
2839
|
-
}
|
2982
|
+
title: formatMessage({
|
2983
|
+
id: "content-manager.containers.edit.panels.default.title",
|
2984
|
+
defaultMessage: "Entry"
|
2985
|
+
}),
|
2986
|
+
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2840
2987
|
};
|
2841
2988
|
};
|
2842
|
-
|
2843
|
-
|
2844
|
-
|
2845
|
-
|
2846
|
-
|
2989
|
+
ActionsPanel.type = "actions";
|
2990
|
+
const ActionsPanelContent = () => {
|
2991
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
2992
|
+
const [
|
2993
|
+
{
|
2994
|
+
query: { status = "draft" }
|
2847
2995
|
}
|
2848
|
-
|
2849
|
-
|
2850
|
-
|
2851
|
-
|
2852
|
-
|
2853
|
-
|
2854
|
-
|
2855
|
-
|
2856
|
-
|
2857
|
-
|
2858
|
-
|
2859
|
-
|
2860
|
-
|
2861
|
-
|
2996
|
+
] = useQueryParams();
|
2997
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
2998
|
+
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2999
|
+
const props = {
|
3000
|
+
activeTab: status,
|
3001
|
+
model,
|
3002
|
+
documentId: id,
|
3003
|
+
document: isCloning ? void 0 : document,
|
3004
|
+
meta: isCloning ? void 0 : meta,
|
3005
|
+
collectionType
|
3006
|
+
};
|
3007
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
3008
|
+
/* @__PURE__ */ jsx(
|
3009
|
+
DescriptionComponentRenderer,
|
3010
|
+
{
|
3011
|
+
props,
|
3012
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3013
|
+
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
3014
|
+
}
|
3015
|
+
),
|
3016
|
+
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
3017
|
+
] });
|
2862
3018
|
};
|
3019
|
+
const Panel = React.forwardRef(({ children, title }, ref) => {
|
3020
|
+
return /* @__PURE__ */ jsxs(
|
3021
|
+
Flex,
|
3022
|
+
{
|
3023
|
+
ref,
|
3024
|
+
tag: "aside",
|
3025
|
+
"aria-labelledby": "additional-information",
|
3026
|
+
background: "neutral0",
|
3027
|
+
borderColor: "neutral150",
|
3028
|
+
hasRadius: true,
|
3029
|
+
paddingBottom: 4,
|
3030
|
+
paddingLeft: 4,
|
3031
|
+
paddingRight: 4,
|
3032
|
+
paddingTop: 4,
|
3033
|
+
shadow: "tableShadow",
|
3034
|
+
gap: 3,
|
3035
|
+
direction: "column",
|
3036
|
+
justifyContent: "stretch",
|
3037
|
+
alignItems: "flex-start",
|
3038
|
+
children: [
|
3039
|
+
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", textColor: "neutral600", children: title }),
|
3040
|
+
children
|
3041
|
+
]
|
3042
|
+
}
|
3043
|
+
);
|
3044
|
+
});
|
2863
3045
|
const ConfirmBulkActionDialog = ({
|
2864
3046
|
onToggleDialog,
|
2865
3047
|
isOpen = false,
|
@@ -2898,6 +3080,7 @@ const ConfirmDialogPublishAll = ({
|
|
2898
3080
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
|
2899
3081
|
const { model, schema } = useDoc();
|
2900
3082
|
const [{ query }] = useQueryParams();
|
3083
|
+
const enableDraftRelationsCount = false;
|
2901
3084
|
const {
|
2902
3085
|
data: countDraftRelations = 0,
|
2903
3086
|
isLoading,
|
@@ -2909,7 +3092,7 @@ const ConfirmDialogPublishAll = ({
|
|
2909
3092
|
locale: query?.plugins?.i18n?.locale
|
2910
3093
|
},
|
2911
3094
|
{
|
2912
|
-
skip:
|
3095
|
+
skip: !enableDraftRelationsCount
|
2913
3096
|
}
|
2914
3097
|
);
|
2915
3098
|
React.useEffect(() => {
|
@@ -3094,7 +3277,7 @@ const SelectedEntriesTableContent = ({
|
|
3094
3277
|
status: row.status
|
3095
3278
|
}
|
3096
3279
|
) }),
|
3097
|
-
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(
|
3280
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
|
3098
3281
|
IconButton,
|
3099
3282
|
{
|
3100
3283
|
tag: Link,
|
@@ -3117,9 +3300,10 @@ const SelectedEntriesTableContent = ({
|
|
3117
3300
|
),
|
3118
3301
|
target: "_blank",
|
3119
3302
|
marginLeft: "auto",
|
3120
|
-
|
3303
|
+
variant: "ghost",
|
3304
|
+
children: /* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" })
|
3121
3305
|
}
|
3122
|
-
) })
|
3306
|
+
) }) })
|
3123
3307
|
] }, row.id)) })
|
3124
3308
|
] });
|
3125
3309
|
};
|
@@ -3156,7 +3340,13 @@ const SelectedEntriesModalContent = ({
|
|
3156
3340
|
);
|
3157
3341
|
const { rows, validationErrors } = React.useMemo(() => {
|
3158
3342
|
if (data.length > 0 && schema) {
|
3159
|
-
const validate = createYupSchema(
|
3343
|
+
const validate = createYupSchema(
|
3344
|
+
schema.attributes,
|
3345
|
+
components,
|
3346
|
+
// Since this is the "Publish" action, the validation
|
3347
|
+
// schema must enforce the rules for published entities
|
3348
|
+
{ status: "published" }
|
3349
|
+
);
|
3160
3350
|
const validationErrors2 = {};
|
3161
3351
|
const rows2 = data.map((entry) => {
|
3162
3352
|
try {
|
@@ -3506,7 +3696,7 @@ const TableActions = ({ document }) => {
|
|
3506
3696
|
DescriptionComponentRenderer,
|
3507
3697
|
{
|
3508
3698
|
props,
|
3509
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3699
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
3510
3700
|
children: (actions2) => {
|
3511
3701
|
const tableRowActions = actions2.filter((action) => {
|
3512
3702
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3617,7 +3807,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3617
3807
|
}),
|
3618
3808
|
content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3619
3809
|
footer: ({ onClose }) => {
|
3620
|
-
return /* @__PURE__ */ jsxs(
|
3810
|
+
return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3621
3811
|
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3622
3812
|
id: "cancel",
|
3623
3813
|
defaultMessage: "Cancel"
|
@@ -3829,6 +4019,70 @@ const { setInitialData } = actions;
|
|
3829
4019
|
const reducer = combineReducers({
|
3830
4020
|
app: reducer$1
|
3831
4021
|
});
|
4022
|
+
const previewApi = contentManagerApi.injectEndpoints({
|
4023
|
+
endpoints: (builder) => ({
|
4024
|
+
getPreviewUrl: builder.query({
|
4025
|
+
query({ query, params }) {
|
4026
|
+
return {
|
4027
|
+
url: `/content-manager/preview/url/${params.contentType}`,
|
4028
|
+
method: "GET",
|
4029
|
+
config: {
|
4030
|
+
params: query
|
4031
|
+
}
|
4032
|
+
};
|
4033
|
+
}
|
4034
|
+
})
|
4035
|
+
})
|
4036
|
+
});
|
4037
|
+
const { useGetPreviewUrlQuery } = previewApi;
|
4038
|
+
const PreviewSidePanel = ({ model, documentId, document }) => {
|
4039
|
+
const { formatMessage } = useIntl();
|
4040
|
+
const { trackUsage } = useTracking();
|
4041
|
+
const [{ query }] = useQueryParams();
|
4042
|
+
const { data, error } = useGetPreviewUrlQuery({
|
4043
|
+
params: {
|
4044
|
+
contentType: model
|
4045
|
+
},
|
4046
|
+
query: {
|
4047
|
+
documentId,
|
4048
|
+
locale: document?.locale,
|
4049
|
+
status: document?.status
|
4050
|
+
}
|
4051
|
+
});
|
4052
|
+
if (!data?.data?.url || error) {
|
4053
|
+
return null;
|
4054
|
+
}
|
4055
|
+
const handleClick = () => {
|
4056
|
+
trackUsage("willOpenPreview");
|
4057
|
+
};
|
4058
|
+
return {
|
4059
|
+
title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
|
4060
|
+
content: /* @__PURE__ */ jsx(Flex, { gap: 2, width: "100%", children: /* @__PURE__ */ jsx(
|
4061
|
+
Button,
|
4062
|
+
{
|
4063
|
+
variant: "tertiary",
|
4064
|
+
tag: Link,
|
4065
|
+
to: { pathname: "preview", search: stringify(query, { encode: false }) },
|
4066
|
+
onClick: handleClick,
|
4067
|
+
flex: "auto",
|
4068
|
+
children: formatMessage({
|
4069
|
+
id: "content-manager.preview.panel.button",
|
4070
|
+
defaultMessage: "Open preview"
|
4071
|
+
})
|
4072
|
+
}
|
4073
|
+
) })
|
4074
|
+
};
|
4075
|
+
};
|
4076
|
+
const FEATURE_ID = "preview";
|
4077
|
+
const previewAdmin = {
|
4078
|
+
bootstrap(app) {
|
4079
|
+
if (!window.strapi.future.isEnabled(FEATURE_ID)) {
|
4080
|
+
return;
|
4081
|
+
}
|
4082
|
+
const contentManagerPluginApis = app.getPlugin("content-manager").apis;
|
4083
|
+
contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
|
4084
|
+
}
|
4085
|
+
};
|
3832
4086
|
const index = {
|
3833
4087
|
register(app) {
|
3834
4088
|
const cm = new ContentManagerPlugin();
|
@@ -3848,7 +4102,7 @@ const index = {
|
|
3848
4102
|
app.router.addRoute({
|
3849
4103
|
path: "content-manager/*",
|
3850
4104
|
lazy: async () => {
|
3851
|
-
const { Layout } = await import("./layout-
|
4105
|
+
const { Layout } = await import("./layout-Bue_C6ui.mjs");
|
3852
4106
|
return {
|
3853
4107
|
Component: Layout
|
3854
4108
|
};
|
@@ -3861,11 +4115,14 @@ const index = {
|
|
3861
4115
|
if (typeof historyAdmin.bootstrap === "function") {
|
3862
4116
|
historyAdmin.bootstrap(app);
|
3863
4117
|
}
|
4118
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
4119
|
+
previewAdmin.bootstrap(app);
|
4120
|
+
}
|
3864
4121
|
},
|
3865
4122
|
async registerTrads({ locales }) {
|
3866
4123
|
const importedTrads = await Promise.all(
|
3867
4124
|
locales.map((locale) => {
|
3868
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-
|
4125
|
+
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-D_BMf0hT.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`).then(({ default: data }) => {
|
3869
4126
|
return {
|
3870
4127
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3871
4128
|
locale
|
@@ -3886,13 +4143,16 @@ export {
|
|
3886
4143
|
BulkActionsRenderer as B,
|
3887
4144
|
COLLECTION_TYPES as C,
|
3888
4145
|
DocumentStatus as D,
|
3889
|
-
|
3890
|
-
|
3891
|
-
|
4146
|
+
extractContentTypeComponents as E,
|
4147
|
+
DEFAULT_SETTINGS as F,
|
4148
|
+
convertEditLayoutToFieldLayouts as G,
|
3892
4149
|
HOOKS as H,
|
3893
4150
|
InjectionZone as I,
|
3894
|
-
|
3895
|
-
|
4151
|
+
useDocument as J,
|
4152
|
+
useGetPreviewUrlQuery as K,
|
4153
|
+
index as L,
|
4154
|
+
useContentManagerContext as M,
|
4155
|
+
useDocumentActions as N,
|
3896
4156
|
Panels as P,
|
3897
4157
|
RelativeTime as R,
|
3898
4158
|
SINGLE_TYPES as S,
|
@@ -3910,18 +4170,18 @@ export {
|
|
3910
4170
|
PERMISSIONS as k,
|
3911
4171
|
DocumentRBAC as l,
|
3912
4172
|
DOCUMENT_META_FIELDS as m,
|
3913
|
-
|
3914
|
-
|
3915
|
-
|
3916
|
-
|
3917
|
-
|
4173
|
+
CLONE_PATH as n,
|
4174
|
+
useDocLayout as o,
|
4175
|
+
useGetContentTypeConfigurationQuery as p,
|
4176
|
+
CREATOR_FIELDS as q,
|
4177
|
+
getMainField as r,
|
3918
4178
|
setInitialData as s,
|
3919
|
-
|
4179
|
+
getDisplayName as t,
|
3920
4180
|
useContentTypeSchema as u,
|
3921
|
-
|
3922
|
-
|
3923
|
-
|
3924
|
-
|
3925
|
-
|
4181
|
+
checkIfAttributeIsDisplayable as v,
|
4182
|
+
useGetAllDocumentsQuery as w,
|
4183
|
+
convertListLayoutToFieldLayouts as x,
|
4184
|
+
capitalise as y,
|
4185
|
+
useUpdateContentTypeConfigurationMutation as z
|
3926
4186
|
};
|
3927
|
-
//# sourceMappingURL=index-
|
4187
|
+
//# sourceMappingURL=index-V8MWkDSd.mjs.map
|