@strapi/content-manager 0.0.0-experimental.31a5317d54179a9ce6225bf1b6e1f9fb6c372fa9 → 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-BlAzljQ6.js → ComponentConfigurationPage-Br8hp2Xt.js} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-BlAzljQ6.js.map → ComponentConfigurationPage-Br8hp2Xt.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-Ccwb19Qj.mjs → ComponentConfigurationPage-DhwMhiRn.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-Ccwb19Qj.mjs.map → ComponentConfigurationPage-DhwMhiRn.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-BPoOzhCM.js → EditConfigurationPage-BG7rpPjL.js} +4 -4
- package/dist/_chunks/{EditConfigurationPage-BPoOzhCM.js.map → EditConfigurationPage-BG7rpPjL.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-C19b_9RL.mjs → EditConfigurationPage-CWao3CZ3.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-C19b_9RL.mjs.map → EditConfigurationPage-CWao3CZ3.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-D9xH8HYD.js → EditViewPage-BUtpHsMz.js} +23 -7
- package/dist/_chunks/EditViewPage-BUtpHsMz.js.map +1 -0
- package/dist/_chunks/{EditViewPage-nmrHNiJ9.mjs → EditViewPage-hiwZg61J.mjs} +24 -8
- package/dist/_chunks/EditViewPage-hiwZg61J.mjs.map +1 -0
- package/dist/_chunks/{Field--kmlJuSb.mjs → Field-BQQLwyUs.mjs} +71 -27
- package/dist/_chunks/Field-BQQLwyUs.mjs.map +1 -0
- package/dist/_chunks/{Field-BB_pHo6D.js → Field-DEdug-Ll.js} +71 -27
- package/dist/_chunks/Field-DEdug-Ll.js.map +1 -0
- package/dist/_chunks/{Form-CUtOiC4S.mjs → Form-DwJovCha.mjs} +3 -3
- package/dist/_chunks/Form-DwJovCha.mjs.map +1 -0
- package/dist/_chunks/{Form-iwbkoaAF.js → Form-v5pkY-X_.js} +3 -3
- package/dist/_chunks/Form-v5pkY-X_.js.map +1 -0
- package/dist/_chunks/{History-guuZF4lR.js → History-40apIShV.js} +37 -47
- package/dist/_chunks/History-40apIShV.js.map +1 -0
- package/dist/_chunks/{History-BKR3KyU3.mjs → History-B9uJsxZl.mjs} +38 -48
- package/dist/_chunks/History-B9uJsxZl.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-B_O3hiLT.mjs → ListConfigurationPage-CA4oi4Hj.mjs} +3 -3
- package/dist/_chunks/{ListConfigurationPage-B_O3hiLT.mjs.map → ListConfigurationPage-CA4oi4Hj.mjs.map} +1 -1
- package/dist/_chunks/{ListConfigurationPage-Cu26t5sE.js → ListConfigurationPage-DAGbWDIL.js} +3 -3
- package/dist/_chunks/{ListConfigurationPage-Cu26t5sE.js.map → ListConfigurationPage-DAGbWDIL.js.map} +1 -1
- package/dist/_chunks/{ListViewPage-B4sTBfu6.mjs → ListViewPage-Ca8F1NL-.mjs} +16 -5
- package/dist/_chunks/{ListViewPage-B4sTBfu6.mjs.map → ListViewPage-Ca8F1NL-.mjs.map} +1 -1
- package/dist/_chunks/{ListViewPage-DWqqGno8.js → ListViewPage-CjaHQ2_V.js} +16 -5
- package/dist/_chunks/ListViewPage-CjaHQ2_V.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-TTkwA8uk.js → NoContentTypePage-CGxqLI8j.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-TTkwA8uk.js.map → NoContentTypePage-CGxqLI8j.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-Daktt4t9.mjs → NoContentTypePage-CwfnU-aN.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-Daktt4t9.mjs.map → NoContentTypePage-CwfnU-aN.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-D8_k39Q0.js → NoPermissionsPage-CY3_QduF.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-D8_k39Q0.js.map → NoPermissionsPage-CY3_QduF.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-CBUXY2Pt.mjs → NoPermissionsPage-iPk2lFR6.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-CBUXY2Pt.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-DjvmZ_XQ.js → Relations-CGerEwji.js} +71 -35
- package/dist/_chunks/Relations-CGerEwji.js.map +1 -0
- package/dist/_chunks/{Relations-HKmXF7eO.mjs → Relations-DGWa9W2j.mjs} +72 -36
- package/dist/_chunks/Relations-DGWa9W2j.mjs.map +1 -0
- package/dist/_chunks/{en-BVzUkPxZ.js → en-CHOp_xJv.js} +18 -9
- package/dist/_chunks/{en-BVzUkPxZ.js.map → en-CHOp_xJv.js.map} +1 -1
- package/dist/_chunks/{en-CPTj6CjC.mjs → en-D_BMf0hT.mjs} +18 -9
- package/dist/_chunks/{en-CPTj6CjC.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-CB1AN26E.mjs → index-V8MWkDSd.mjs} +838 -676
- package/dist/_chunks/index-V8MWkDSd.mjs.map +1 -0
- package/dist/_chunks/{index-jDJgW_Lf.js → index-tN1hpOMN.js} +836 -673
- 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-BCzDsMgN.mjs → layout-Bue_C6ui.mjs} +3 -3
- package/dist/_chunks/{layout-BCzDsMgN.mjs.map → layout-Bue_C6ui.mjs.map} +1 -1
- package/dist/_chunks/{layout-D6A3K-ut.js → layout-BzX903CL.js} +3 -3
- package/dist/_chunks/{layout-D6A3K-ut.js.map → layout-BzX903CL.js.map} +1 -1
- package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
- package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
- package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
- package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
- package/dist/_chunks/{relations-C10QoukP.js → relations-C4HcWYYJ.js} +6 -7
- package/dist/_chunks/relations-C4HcWYYJ.js.map +1 -0
- package/dist/_chunks/{relations-B5Jnw32V.mjs → relations-C8eyDiIO.mjs} +6 -7
- package/dist/_chunks/relations-C8eyDiIO.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +4 -3
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
- package/dist/admin/src/pages/EditView/components/Header.d.ts +1 -0
- package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
- package/dist/admin/src/preview/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/server/index.js +374 -160
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +374 -160
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/metadata.d.ts +15 -1
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +2 -3
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +4 -4
- package/dist/server/src/preview/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/utils/configuration/index.d.ts +2 -2
- package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/shared/contracts/index.d.ts +1 -0
- package/dist/shared/contracts/index.d.ts.map +1 -1
- package/dist/shared/contracts/preview.d.ts +27 -0
- package/dist/shared/contracts/preview.d.ts.map +1 -0
- package/dist/shared/index.js +4 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +4 -0
- package/dist/shared/index.mjs.map +1 -1
- package/package.json +12 -12
- package/dist/_chunks/EditViewPage-D9xH8HYD.js.map +0 -1
- package/dist/_chunks/EditViewPage-nmrHNiJ9.mjs.map +0 -1
- package/dist/_chunks/Field--kmlJuSb.mjs.map +0 -1
- package/dist/_chunks/Field-BB_pHo6D.js.map +0 -1
- package/dist/_chunks/Form-CUtOiC4S.mjs.map +0 -1
- package/dist/_chunks/Form-iwbkoaAF.js.map +0 -1
- package/dist/_chunks/History-BKR3KyU3.mjs.map +0 -1
- package/dist/_chunks/History-guuZF4lR.js.map +0 -1
- package/dist/_chunks/ListViewPage-DWqqGno8.js.map +0 -1
- package/dist/_chunks/Relations-DjvmZ_XQ.js.map +0 -1
- package/dist/_chunks/Relations-HKmXF7eO.mjs.map +0 -1
- package/dist/_chunks/index-CB1AN26E.mjs.map +0 -1
- package/dist/_chunks/index-jDJgW_Lf.js.map +0 -1
- package/dist/_chunks/relations-B5Jnw32V.mjs.map +0 -1
- package/dist/_chunks/relations-C10QoukP.js.map +0 -1
- package/strapi-server.js +0 -3
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check, CrossCircle, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
|
|
2
2
|
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useStrapiApp, createContext, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors,
|
|
3
|
+
import { useStrapiApp, createContext, useQueryParams, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useForm, useTracking, useGuidedTour, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
import { lazy } from "react";
|
|
6
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
9
|
import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
|
9
10
|
import * as yup from "yup";
|
|
@@ -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) : [];
|
|
@@ -461,6 +470,24 @@ const buildValidParams = (query) => {
|
|
|
461
470
|
const isBaseQueryError = (error) => {
|
|
462
471
|
return error.name !== void 0;
|
|
463
472
|
};
|
|
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
|
+
});
|
|
464
491
|
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
|
465
492
|
const createModelSchema = (attributes2) => yup.object().shape(
|
|
466
493
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
|
@@ -468,6 +495,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
|
468
495
|
return acc;
|
|
469
496
|
}
|
|
470
497
|
const validations = [
|
|
498
|
+
addNullableValidation,
|
|
471
499
|
addRequiredValidation,
|
|
472
500
|
addMinLengthValidation,
|
|
473
501
|
addMaxLengthValidation,
|
|
@@ -484,12 +512,12 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
|
484
512
|
...acc,
|
|
485
513
|
[name]: transformSchema(
|
|
486
514
|
yup.array().of(createModelSchema(attributes3).nullable(false))
|
|
487
|
-
)
|
|
515
|
+
).test(arrayValidator(attribute, options))
|
|
488
516
|
};
|
|
489
517
|
} else {
|
|
490
518
|
return {
|
|
491
519
|
...acc,
|
|
492
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
|
520
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
|
493
521
|
};
|
|
494
522
|
}
|
|
495
523
|
}
|
|
@@ -511,7 +539,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
|
511
539
|
}
|
|
512
540
|
)
|
|
513
541
|
)
|
|
514
|
-
)
|
|
542
|
+
).test(arrayValidator(attribute, options))
|
|
515
543
|
};
|
|
516
544
|
case "relation":
|
|
517
545
|
return {
|
|
@@ -523,7 +551,7 @@ const createYupSchema = (attributes = {}, components = {}, options = { status: n
|
|
|
523
551
|
} else if (Array.isArray(value)) {
|
|
524
552
|
return yup.array().of(
|
|
525
553
|
yup.object().shape({
|
|
526
|
-
id: yup.
|
|
554
|
+
id: yup.number().required()
|
|
527
555
|
})
|
|
528
556
|
);
|
|
529
557
|
} else if (typeof value === "object") {
|
|
@@ -609,17 +637,17 @@ const nullableSchema = (schema) => {
|
|
|
609
637
|
schema
|
|
610
638
|
);
|
|
611
639
|
};
|
|
640
|
+
const addNullableValidation = () => (schema) => {
|
|
641
|
+
return nullableSchema(schema);
|
|
642
|
+
};
|
|
612
643
|
const addRequiredValidation = (attribute, options) => (schema) => {
|
|
613
|
-
if (options.status === "draft") {
|
|
614
|
-
return
|
|
615
|
-
}
|
|
616
|
-
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
|
617
|
-
return schema.min(1, translatedErrors.required);
|
|
644
|
+
if (options.status === "draft" || !attribute.required) {
|
|
645
|
+
return schema;
|
|
618
646
|
}
|
|
619
|
-
if (attribute.required &&
|
|
647
|
+
if (attribute.required && "required" in schema) {
|
|
620
648
|
return schema.required(translatedErrors.required);
|
|
621
649
|
}
|
|
622
|
-
return
|
|
650
|
+
return schema;
|
|
623
651
|
};
|
|
624
652
|
const addMinLengthValidation = (attribute, options) => (schema) => {
|
|
625
653
|
if (options.status === "draft") {
|
|
@@ -647,31 +675,12 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
|
647
675
|
return schema;
|
|
648
676
|
};
|
|
649
677
|
const addMinValidation = (attribute, options) => (schema) => {
|
|
650
|
-
if ("
|
|
678
|
+
if (options.status === "draft") {
|
|
679
|
+
return schema;
|
|
680
|
+
}
|
|
681
|
+
if ("min" in attribute && "min" in schema) {
|
|
651
682
|
const min = toInteger(attribute.min);
|
|
652
|
-
if (
|
|
653
|
-
if (options.status !== "draft" && !attribute.required && "test" in schema && min) {
|
|
654
|
-
return schema.test(
|
|
655
|
-
"custom-min",
|
|
656
|
-
{
|
|
657
|
-
...translatedErrors.min,
|
|
658
|
-
values: {
|
|
659
|
-
min: attribute.min
|
|
660
|
-
}
|
|
661
|
-
},
|
|
662
|
-
(value) => {
|
|
663
|
-
if (!value) {
|
|
664
|
-
return true;
|
|
665
|
-
}
|
|
666
|
-
if (Array.isArray(value) && value.length === 0) {
|
|
667
|
-
return true;
|
|
668
|
-
}
|
|
669
|
-
return value.length >= min;
|
|
670
|
-
}
|
|
671
|
-
);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
if ("min" in schema && min) {
|
|
683
|
+
if (min) {
|
|
675
684
|
return schema.min(min, {
|
|
676
685
|
...translatedErrors.min,
|
|
677
686
|
values: {
|
|
@@ -789,19 +798,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
|
789
798
|
}, {});
|
|
790
799
|
return componentsByKey;
|
|
791
800
|
};
|
|
792
|
-
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);
|
|
793
900
|
const { toggleNotification } = useNotification();
|
|
794
901
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
|
902
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
|
795
903
|
const {
|
|
796
|
-
|
|
797
|
-
isLoading:
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
} =
|
|
801
|
-
|
|
802
|
-
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
|
803
|
-
});
|
|
804
|
-
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
|
904
|
+
data,
|
|
905
|
+
isLoading: isLoadingConfigs,
|
|
906
|
+
error,
|
|
907
|
+
isFetching: isFetchingConfigs
|
|
908
|
+
} = useGetContentTypeConfigurationQuery(model);
|
|
909
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
|
805
910
|
React.useEffect(() => {
|
|
806
911
|
if (error) {
|
|
807
912
|
toggleNotification({
|
|
@@ -809,100 +914,355 @@ const useDocument = (args, opts) => {
|
|
|
809
914
|
message: formatAPIError(error)
|
|
810
915
|
});
|
|
811
916
|
}
|
|
812
|
-
}, [
|
|
813
|
-
const
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
(document) => {
|
|
821
|
-
if (!validationSchema) {
|
|
822
|
-
throw new Error(
|
|
823
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
|
824
|
-
);
|
|
825
|
-
}
|
|
826
|
-
try {
|
|
827
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
|
828
|
-
return null;
|
|
829
|
-
} catch (error2) {
|
|
830
|
-
if (error2 instanceof ValidationError) {
|
|
831
|
-
return getYupValidationErrors(error2);
|
|
832
|
-
}
|
|
833
|
-
throw error2;
|
|
834
|
-
}
|
|
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
|
|
835
925
|
},
|
|
836
|
-
[
|
|
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]
|
|
837
942
|
);
|
|
838
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
|
839
943
|
return {
|
|
840
|
-
|
|
841
|
-
document: data?.data,
|
|
842
|
-
meta: data?.meta,
|
|
944
|
+
error,
|
|
843
945
|
isLoading,
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
};
|
|
847
|
-
};
|
|
848
|
-
const useDoc = () => {
|
|
849
|
-
const { id, slug, collectionType, origin } = useParams();
|
|
850
|
-
const [{ query }] = useQueryParams();
|
|
851
|
-
const params = React.useMemo(() => buildValidParams(query), [query]);
|
|
852
|
-
if (!collectionType) {
|
|
853
|
-
throw new Error("Could not find collectionType in url params");
|
|
854
|
-
}
|
|
855
|
-
if (!slug) {
|
|
856
|
-
throw new Error("Could not find model in url params");
|
|
857
|
-
}
|
|
858
|
-
return {
|
|
859
|
-
collectionType,
|
|
860
|
-
model: slug,
|
|
861
|
-
id: origin || id === "create" ? void 0 : id,
|
|
862
|
-
...useDocument(
|
|
863
|
-
{ documentId: origin || id, model: slug, collectionType, params },
|
|
864
|
-
{
|
|
865
|
-
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
|
866
|
-
}
|
|
867
|
-
)
|
|
946
|
+
edit,
|
|
947
|
+
list: listLayout
|
|
868
948
|
};
|
|
869
949
|
};
|
|
870
|
-
const
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
}
|
|
874
|
-
return Object.keys(trad).reduce((acc, current) => {
|
|
875
|
-
acc[`${pluginId}.${current}`] = trad[current];
|
|
876
|
-
return acc;
|
|
877
|
-
}, {});
|
|
878
|
-
};
|
|
879
|
-
const getTranslation = (id) => `content-manager.${id}`;
|
|
880
|
-
const DEFAULT_UNEXPECTED_ERROR_MSG = {
|
|
881
|
-
id: "notification.error",
|
|
882
|
-
defaultMessage: "An error occurred, please try again"
|
|
950
|
+
const useDocLayout = () => {
|
|
951
|
+
const { model } = useDoc();
|
|
952
|
+
return useDocumentLayout(model);
|
|
883
953
|
};
|
|
884
|
-
const
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
const
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
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);
|
|
1255
|
+
const res = await deleteDocument({
|
|
1256
|
+
collectionType,
|
|
1257
|
+
model,
|
|
1258
|
+
documentId,
|
|
1259
|
+
params
|
|
1260
|
+
});
|
|
1261
|
+
if ("error" in res) {
|
|
1262
|
+
toggleNotification({
|
|
1263
|
+
type: "danger",
|
|
1264
|
+
message: formatAPIError(res.error)
|
|
1265
|
+
});
|
|
906
1266
|
return { error: res.error };
|
|
907
1267
|
}
|
|
908
1268
|
toggleNotification({
|
|
@@ -1201,6 +1561,7 @@ const useDocumentActions = () => {
|
|
|
1201
1561
|
defaultMessage: "Saved document"
|
|
1202
1562
|
})
|
|
1203
1563
|
});
|
|
1564
|
+
setCurrentStep("contentManager.success");
|
|
1204
1565
|
return res.data;
|
|
1205
1566
|
} catch (err) {
|
|
1206
1567
|
toggleNotification({
|
|
@@ -1302,10 +1663,10 @@ const useDocumentActions = () => {
|
|
|
1302
1663
|
update
|
|
1303
1664
|
};
|
|
1304
1665
|
};
|
|
1305
|
-
const ProtectedHistoryPage = lazy(
|
|
1306
|
-
() => import("./History-
|
|
1666
|
+
const ProtectedHistoryPage = React.lazy(
|
|
1667
|
+
() => import("./History-B9uJsxZl.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
|
1307
1668
|
);
|
|
1308
|
-
const routes$
|
|
1669
|
+
const routes$2 = [
|
|
1309
1670
|
{
|
|
1310
1671
|
path: ":collectionType/:slug/:id/history",
|
|
1311
1672
|
Component: ProtectedHistoryPage
|
|
@@ -1315,32 +1676,45 @@ const routes$1 = [
|
|
|
1315
1676
|
Component: ProtectedHistoryPage
|
|
1316
1677
|
}
|
|
1317
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
|
+
];
|
|
1318
1692
|
const ProtectedEditViewPage = lazy(
|
|
1319
|
-
() => import("./EditViewPage-
|
|
1693
|
+
() => import("./EditViewPage-hiwZg61J.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
|
1320
1694
|
);
|
|
1321
1695
|
const ProtectedListViewPage = lazy(
|
|
1322
|
-
() => import("./ListViewPage-
|
|
1696
|
+
() => import("./ListViewPage-Ca8F1NL-.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
|
1323
1697
|
);
|
|
1324
1698
|
const ProtectedListConfiguration = lazy(
|
|
1325
|
-
() => import("./ListConfigurationPage-
|
|
1699
|
+
() => import("./ListConfigurationPage-CA4oi4Hj.mjs").then((mod) => ({
|
|
1326
1700
|
default: mod.ProtectedListConfiguration
|
|
1327
1701
|
}))
|
|
1328
1702
|
);
|
|
1329
1703
|
const ProtectedEditConfigurationPage = lazy(
|
|
1330
|
-
() => import("./EditConfigurationPage-
|
|
1704
|
+
() => import("./EditConfigurationPage-CWao3CZ3.mjs").then((mod) => ({
|
|
1331
1705
|
default: mod.ProtectedEditConfigurationPage
|
|
1332
1706
|
}))
|
|
1333
1707
|
);
|
|
1334
1708
|
const ProtectedComponentConfigurationPage = lazy(
|
|
1335
|
-
() => import("./ComponentConfigurationPage-
|
|
1709
|
+
() => import("./ComponentConfigurationPage-DhwMhiRn.mjs").then((mod) => ({
|
|
1336
1710
|
default: mod.ProtectedComponentConfigurationPage
|
|
1337
1711
|
}))
|
|
1338
1712
|
);
|
|
1339
1713
|
const NoPermissions = lazy(
|
|
1340
|
-
() => import("./NoPermissionsPage-
|
|
1714
|
+
() => import("./NoPermissionsPage-iPk2lFR6.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
|
1341
1715
|
);
|
|
1342
1716
|
const NoContentType = lazy(
|
|
1343
|
-
() => import("./NoContentTypePage-
|
|
1717
|
+
() => import("./NoContentTypePage-CwfnU-aN.mjs").then((mod) => ({ default: mod.NoContentType }))
|
|
1344
1718
|
);
|
|
1345
1719
|
const CollectionTypePages = () => {
|
|
1346
1720
|
const { collectionType } = useParams();
|
|
@@ -1386,6 +1760,7 @@ const routes = [
|
|
|
1386
1760
|
path: "no-content-types",
|
|
1387
1761
|
Component: NoContentType
|
|
1388
1762
|
},
|
|
1763
|
+
...routes$2,
|
|
1389
1764
|
...routes$1
|
|
1390
1765
|
];
|
|
1391
1766
|
const DocumentActions = ({ actions: actions2 }) => {
|
|
@@ -1539,7 +1914,7 @@ const DocumentActionsMenu = ({
|
|
|
1539
1914
|
]
|
|
1540
1915
|
}
|
|
1541
1916
|
),
|
|
1542
|
-
/* @__PURE__ */ jsxs(Menu.Content, {
|
|
1917
|
+
/* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
|
1543
1918
|
actions2.map((action) => {
|
|
1544
1919
|
return /* @__PURE__ */ jsx(
|
|
1545
1920
|
Menu.Item,
|
|
@@ -1694,6 +2069,18 @@ const DocumentActionModal = ({
|
|
|
1694
2069
|
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
|
1695
2070
|
] }) });
|
|
1696
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
|
+
};
|
|
1697
2084
|
const PublishAction$1 = ({
|
|
1698
2085
|
activeTab,
|
|
1699
2086
|
documentId,
|
|
@@ -1787,7 +2174,9 @@ const PublishAction$1 = ({
|
|
|
1787
2174
|
const performPublish = async () => {
|
|
1788
2175
|
setSubmitting(true);
|
|
1789
2176
|
try {
|
|
1790
|
-
const { errors } = await validate(
|
|
2177
|
+
const { errors } = await validate(true, {
|
|
2178
|
+
status: "published"
|
|
2179
|
+
});
|
|
1791
2180
|
if (errors) {
|
|
1792
2181
|
toggleNotification({
|
|
1793
2182
|
type: "danger",
|
|
@@ -1805,7 +2194,7 @@ const PublishAction$1 = ({
|
|
|
1805
2194
|
documentId,
|
|
1806
2195
|
params
|
|
1807
2196
|
},
|
|
1808
|
-
formValues
|
|
2197
|
+
transformData(formValues)
|
|
1809
2198
|
);
|
|
1810
2199
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
|
1811
2200
|
navigate({
|
|
@@ -1901,18 +2290,18 @@ const UpdateAction = ({
|
|
|
1901
2290
|
onClick: async () => {
|
|
1902
2291
|
setSubmitting(true);
|
|
1903
2292
|
try {
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
})
|
|
1914
|
-
|
|
1915
|
-
|
|
2293
|
+
const { errors } = await validate(true, {
|
|
2294
|
+
status: "draft"
|
|
2295
|
+
});
|
|
2296
|
+
if (errors) {
|
|
2297
|
+
toggleNotification({
|
|
2298
|
+
type: "danger",
|
|
2299
|
+
message: formatMessage({
|
|
2300
|
+
id: "content-manager.validation.error",
|
|
2301
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
|
2302
|
+
})
|
|
2303
|
+
});
|
|
2304
|
+
return;
|
|
1916
2305
|
}
|
|
1917
2306
|
if (isCloning) {
|
|
1918
2307
|
const res = await clone(
|
|
@@ -1921,7 +2310,7 @@ const UpdateAction = ({
|
|
|
1921
2310
|
documentId: cloneMatch.params.origin,
|
|
1922
2311
|
params
|
|
1923
2312
|
},
|
|
1924
|
-
document
|
|
2313
|
+
transformData(document)
|
|
1925
2314
|
);
|
|
1926
2315
|
if ("data" in res) {
|
|
1927
2316
|
navigate(
|
|
@@ -1942,7 +2331,7 @@ const UpdateAction = ({
|
|
|
1942
2331
|
documentId,
|
|
1943
2332
|
params
|
|
1944
2333
|
},
|
|
1945
|
-
document
|
|
2334
|
+
transformData(document)
|
|
1946
2335
|
);
|
|
1947
2336
|
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
|
1948
2337
|
setErrors(formatValidationErrors(res.error));
|
|
@@ -1955,7 +2344,7 @@ const UpdateAction = ({
|
|
|
1955
2344
|
model,
|
|
1956
2345
|
params
|
|
1957
2346
|
},
|
|
1958
|
-
document
|
|
2347
|
+
transformData(document)
|
|
1959
2348
|
);
|
|
1960
2349
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
|
1961
2350
|
navigate(
|
|
@@ -2196,7 +2585,11 @@ const getDisplayName = ({
|
|
|
2196
2585
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
|
2197
2586
|
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
|
2198
2587
|
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
|
2199
|
-
|
|
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
|
+
}) }) });
|
|
2200
2593
|
};
|
|
2201
2594
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
|
2202
2595
|
const { formatMessage } = useIntl();
|
|
@@ -2294,12 +2687,12 @@ const Information = ({ activeTab }) => {
|
|
|
2294
2687
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
|
2295
2688
|
label: formatMessage({
|
|
2296
2689
|
id: "content-manager.containers.edit.information.last-published.label",
|
|
2297
|
-
defaultMessage: "
|
|
2690
|
+
defaultMessage: "Published"
|
|
2298
2691
|
}),
|
|
2299
2692
|
value: formatMessage(
|
|
2300
2693
|
{
|
|
2301
2694
|
id: "content-manager.containers.edit.information.last-published.value",
|
|
2302
|
-
defaultMessage: `
|
|
2695
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
|
2303
2696
|
},
|
|
2304
2697
|
{
|
|
2305
2698
|
time: /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
|
@@ -2312,12 +2705,12 @@ const Information = ({ activeTab }) => {
|
|
|
2312
2705
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
|
2313
2706
|
label: formatMessage({
|
|
2314
2707
|
id: "content-manager.containers.edit.information.last-draft.label",
|
|
2315
|
-
defaultMessage: "
|
|
2708
|
+
defaultMessage: "Updated"
|
|
2316
2709
|
}),
|
|
2317
2710
|
value: formatMessage(
|
|
2318
2711
|
{
|
|
2319
2712
|
id: "content-manager.containers.edit.information.last-draft.value",
|
|
2320
|
-
defaultMessage: `
|
|
2713
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
|
2321
2714
|
},
|
|
2322
2715
|
{
|
|
2323
2716
|
time: /* @__PURE__ */ jsx(
|
|
@@ -2335,12 +2728,12 @@ const Information = ({ activeTab }) => {
|
|
|
2335
2728
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
|
2336
2729
|
label: formatMessage({
|
|
2337
2730
|
id: "content-manager.containers.edit.information.document.label",
|
|
2338
|
-
defaultMessage: "
|
|
2731
|
+
defaultMessage: "Created"
|
|
2339
2732
|
}),
|
|
2340
2733
|
value: formatMessage(
|
|
2341
2734
|
{
|
|
2342
2735
|
id: "content-manager.containers.edit.information.document.value",
|
|
2343
|
-
defaultMessage: `
|
|
2736
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
|
2344
2737
|
},
|
|
2345
2738
|
{
|
|
2346
2739
|
time: /* @__PURE__ */ jsx(
|
|
@@ -2398,10 +2791,9 @@ const HeaderActions = ({ actions: actions2 }) => {
|
|
|
2398
2791
|
SingleSelect,
|
|
2399
2792
|
{
|
|
2400
2793
|
size: "S",
|
|
2401
|
-
disabled: action.disabled,
|
|
2402
|
-
"aria-label": action.label,
|
|
2403
2794
|
onChange: action.onSelect,
|
|
2404
|
-
|
|
2795
|
+
"aria-label": action.label,
|
|
2796
|
+
...action,
|
|
2405
2797
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
|
|
2406
2798
|
},
|
|
2407
2799
|
action.id
|
|
@@ -2431,524 +2823,225 @@ const HeaderActions = ({ actions: actions2 }) => {
|
|
|
2431
2823
|
}
|
|
2432
2824
|
}
|
|
2433
2825
|
}) });
|
|
2434
|
-
};
|
|
2435
|
-
const HeaderActionDialog = ({
|
|
2436
|
-
onClose,
|
|
2437
|
-
onCancel,
|
|
2438
|
-
title,
|
|
2439
|
-
content: Content,
|
|
2440
|
-
isOpen
|
|
2441
|
-
}) => {
|
|
2442
|
-
const handleClose = async () => {
|
|
2443
|
-
if (onCancel) {
|
|
2444
|
-
await onCancel();
|
|
2445
|
-
}
|
|
2446
|
-
onClose();
|
|
2447
|
-
};
|
|
2448
|
-
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
|
2449
|
-
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
|
2450
|
-
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content
|
|
2451
|
-
] }) });
|
|
2452
|
-
};
|
|
2453
|
-
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2454
|
-
const navigate = useNavigate();
|
|
2455
|
-
const { formatMessage } = useIntl();
|
|
2456
|
-
return {
|
|
2457
|
-
label: formatMessage({
|
|
2458
|
-
id: "app.links.configure-view",
|
|
2459
|
-
defaultMessage: "Configure the view"
|
|
2460
|
-
}),
|
|
2461
|
-
icon: /* @__PURE__ */ jsx(ListPlus, {}),
|
|
2462
|
-
onClick: () => {
|
|
2463
|
-
navigate(`../${collectionType}/${model}/configurations/edit`);
|
|
2464
|
-
},
|
|
2465
|
-
position: "header"
|
|
2466
|
-
};
|
|
2467
|
-
};
|
|
2468
|
-
ConfigureTheViewAction.type = "configure-the-view";
|
|
2469
|
-
const EditTheModelAction = ({ model }) => {
|
|
2470
|
-
const navigate = useNavigate();
|
|
2471
|
-
const { formatMessage } = useIntl();
|
|
2472
|
-
return {
|
|
2473
|
-
label: formatMessage({
|
|
2474
|
-
id: "content-manager.link-to-ctb",
|
|
2475
|
-
defaultMessage: "Edit the model"
|
|
2476
|
-
}),
|
|
2477
|
-
icon: /* @__PURE__ */ jsx(Pencil, {}),
|
|
2478
|
-
onClick: () => {
|
|
2479
|
-
navigate(`/plugins/content-type-builder/content-types/${model}`);
|
|
2480
|
-
},
|
|
2481
|
-
position: "header"
|
|
2482
|
-
};
|
|
2483
|
-
};
|
|
2484
|
-
EditTheModelAction.type = "edit-the-model";
|
|
2485
|
-
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2486
|
-
const navigate = useNavigate();
|
|
2487
|
-
const { formatMessage } = useIntl();
|
|
2488
|
-
const listViewPathMatch = useMatch(LIST_PATH);
|
|
2489
|
-
const canDelete = useDocumentRBAC("DeleteAction", (state) => state.canDelete);
|
|
2490
|
-
const { delete: deleteAction } = useDocumentActions();
|
|
2491
|
-
const { toggleNotification } = useNotification();
|
|
2492
|
-
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
|
2493
|
-
return {
|
|
2494
|
-
disabled: !canDelete || !document,
|
|
2495
|
-
label: formatMessage({
|
|
2496
|
-
id: "content-manager.actions.delete.label",
|
|
2497
|
-
defaultMessage: "Delete document"
|
|
2498
|
-
}),
|
|
2499
|
-
icon: /* @__PURE__ */ jsx(Trash, {}),
|
|
2500
|
-
dialog: {
|
|
2501
|
-
type: "dialog",
|
|
2502
|
-
title: formatMessage({
|
|
2503
|
-
id: "app.components.ConfirmDialog.title",
|
|
2504
|
-
defaultMessage: "Confirmation"
|
|
2505
|
-
}),
|
|
2506
|
-
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
|
2507
|
-
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
|
2508
|
-
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
|
2509
|
-
id: "content-manager.actions.delete.dialog.body",
|
|
2510
|
-
defaultMessage: "Are you sure?"
|
|
2511
|
-
}) })
|
|
2512
|
-
] }),
|
|
2513
|
-
onConfirm: async () => {
|
|
2514
|
-
if (!listViewPathMatch) {
|
|
2515
|
-
setSubmitting(true);
|
|
2516
|
-
}
|
|
2517
|
-
try {
|
|
2518
|
-
if (!documentId && collectionType !== SINGLE_TYPES) {
|
|
2519
|
-
console.error(
|
|
2520
|
-
"You're trying to delete a document without an id, this is likely a bug with Strapi. Please open an issue."
|
|
2521
|
-
);
|
|
2522
|
-
toggleNotification({
|
|
2523
|
-
message: formatMessage({
|
|
2524
|
-
id: "content-manager.actions.delete.error",
|
|
2525
|
-
defaultMessage: "An error occurred while trying to delete the document."
|
|
2526
|
-
}),
|
|
2527
|
-
type: "danger"
|
|
2528
|
-
});
|
|
2529
|
-
return;
|
|
2530
|
-
}
|
|
2531
|
-
const res = await deleteAction({
|
|
2532
|
-
documentId,
|
|
2533
|
-
model,
|
|
2534
|
-
collectionType,
|
|
2535
|
-
params: {
|
|
2536
|
-
locale: "*"
|
|
2537
|
-
}
|
|
2538
|
-
});
|
|
2539
|
-
if (!("error" in res)) {
|
|
2540
|
-
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
|
2541
|
-
}
|
|
2542
|
-
} finally {
|
|
2543
|
-
if (!listViewPathMatch) {
|
|
2544
|
-
setSubmitting(false);
|
|
2545
|
-
}
|
|
2546
|
-
}
|
|
2547
|
-
}
|
|
2548
|
-
},
|
|
2549
|
-
variant: "danger",
|
|
2550
|
-
position: ["header", "table-row"]
|
|
2551
|
-
};
|
|
2552
|
-
};
|
|
2553
|
-
DeleteAction$1.type = "delete";
|
|
2554
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
|
2555
|
-
const Panels = () => {
|
|
2556
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
|
2557
|
-
const [
|
|
2558
|
-
{
|
|
2559
|
-
query: { status }
|
|
2560
|
-
}
|
|
2561
|
-
] = useQueryParams({
|
|
2562
|
-
status: "draft"
|
|
2563
|
-
});
|
|
2564
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
|
2565
|
-
const plugins = useStrapiApp("Panels", (state) => state.plugins);
|
|
2566
|
-
const props = {
|
|
2567
|
-
activeTab: status,
|
|
2568
|
-
model,
|
|
2569
|
-
documentId: id,
|
|
2570
|
-
document: isCloning ? void 0 : document,
|
|
2571
|
-
meta: isCloning ? void 0 : meta,
|
|
2572
|
-
collectionType
|
|
2573
|
-
};
|
|
2574
|
-
return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
|
|
2575
|
-
DescriptionComponentRenderer,
|
|
2576
|
-
{
|
|
2577
|
-
props,
|
|
2578
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
|
2579
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
|
|
2580
|
-
}
|
|
2581
|
-
) });
|
|
2582
|
-
};
|
|
2583
|
-
const ActionsPanel = () => {
|
|
2584
|
-
const { formatMessage } = useIntl();
|
|
2585
|
-
return {
|
|
2586
|
-
title: formatMessage({
|
|
2587
|
-
id: "content-manager.containers.edit.panels.default.title",
|
|
2588
|
-
defaultMessage: "Entry"
|
|
2589
|
-
}),
|
|
2590
|
-
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
|
2591
|
-
};
|
|
2592
|
-
};
|
|
2593
|
-
ActionsPanel.type = "actions";
|
|
2594
|
-
const ActionsPanelContent = () => {
|
|
2595
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
|
2596
|
-
const [
|
|
2597
|
-
{
|
|
2598
|
-
query: { status = "draft" }
|
|
2599
|
-
}
|
|
2600
|
-
] = useQueryParams();
|
|
2601
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
|
2602
|
-
const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
|
|
2603
|
-
const props = {
|
|
2604
|
-
activeTab: status,
|
|
2605
|
-
model,
|
|
2606
|
-
documentId: id,
|
|
2607
|
-
document: isCloning ? void 0 : document,
|
|
2608
|
-
meta: isCloning ? void 0 : meta,
|
|
2609
|
-
collectionType
|
|
2610
|
-
};
|
|
2611
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
|
2612
|
-
/* @__PURE__ */ jsx(
|
|
2613
|
-
DescriptionComponentRenderer,
|
|
2614
|
-
{
|
|
2615
|
-
props,
|
|
2616
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
|
2617
|
-
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
|
2618
|
-
}
|
|
2619
|
-
),
|
|
2620
|
-
/* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
|
2621
|
-
] });
|
|
2622
|
-
};
|
|
2623
|
-
const Panel = React.forwardRef(({ children, title }, ref) => {
|
|
2624
|
-
return /* @__PURE__ */ jsxs(
|
|
2625
|
-
Flex,
|
|
2626
|
-
{
|
|
2627
|
-
ref,
|
|
2628
|
-
tag: "aside",
|
|
2629
|
-
"aria-labelledby": "additional-information",
|
|
2630
|
-
background: "neutral0",
|
|
2631
|
-
borderColor: "neutral150",
|
|
2632
|
-
hasRadius: true,
|
|
2633
|
-
paddingBottom: 4,
|
|
2634
|
-
paddingLeft: 4,
|
|
2635
|
-
paddingRight: 4,
|
|
2636
|
-
paddingTop: 4,
|
|
2637
|
-
shadow: "tableShadow",
|
|
2638
|
-
gap: 3,
|
|
2639
|
-
direction: "column",
|
|
2640
|
-
justifyContent: "stretch",
|
|
2641
|
-
alignItems: "flex-start",
|
|
2642
|
-
children: [
|
|
2643
|
-
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
|
2644
|
-
children
|
|
2645
|
-
]
|
|
2826
|
+
};
|
|
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();
|
|
2646
2837
|
}
|
|
2647
|
-
|
|
2648
|
-
}
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
* @type {string}
|
|
2654
|
-
*/
|
|
2655
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
|
2656
|
-
/**
|
|
2657
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
|
2658
|
-
* @constant
|
|
2659
|
-
* @type {string}
|
|
2660
|
-
*/
|
|
2661
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
|
2662
|
-
/**
|
|
2663
|
-
* Hook that allows to mutate the CM's edit view layout
|
|
2664
|
-
* @constant
|
|
2665
|
-
* @type {string}
|
|
2666
|
-
*/
|
|
2667
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
|
2668
|
-
/**
|
|
2669
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
|
2670
|
-
* @constant
|
|
2671
|
-
* @type {string}
|
|
2672
|
-
*/
|
|
2673
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
|
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
|
+
] }) });
|
|
2674
2844
|
};
|
|
2675
|
-
const
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
transformResponse: (response) => response.data,
|
|
2683
|
-
providesTags: (_result, _error, uid) => [
|
|
2684
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
|
2685
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
|
2686
|
-
]
|
|
2687
|
-
}),
|
|
2688
|
-
getAllContentTypeSettings: builder.query({
|
|
2689
|
-
query: () => "/content-manager/content-types-settings",
|
|
2690
|
-
transformResponse: (response) => response.data,
|
|
2691
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
|
2845
|
+
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2846
|
+
const navigate = useNavigate();
|
|
2847
|
+
const { formatMessage } = useIntl();
|
|
2848
|
+
return {
|
|
2849
|
+
label: formatMessage({
|
|
2850
|
+
id: "app.links.configure-view",
|
|
2851
|
+
defaultMessage: "Configure the view"
|
|
2692
2852
|
}),
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
transformResponse: (response) => response.data,
|
|
2700
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
|
2701
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
|
2702
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
|
2703
|
-
// Is this necessary?
|
|
2704
|
-
{ type: "InitialData" }
|
|
2705
|
-
]
|
|
2706
|
-
})
|
|
2707
|
-
})
|
|
2708
|
-
});
|
|
2709
|
-
const {
|
|
2710
|
-
useGetContentTypeConfigurationQuery,
|
|
2711
|
-
useGetAllContentTypeSettingsQuery,
|
|
2712
|
-
useUpdateContentTypeConfigurationMutation
|
|
2713
|
-
} = contentTypesApi;
|
|
2714
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
|
2715
|
-
const { type } = attribute;
|
|
2716
|
-
if (type === "relation") {
|
|
2717
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
|
2718
|
-
}
|
|
2719
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
|
2853
|
+
icon: /* @__PURE__ */ jsx(ListPlus, {}),
|
|
2854
|
+
onClick: () => {
|
|
2855
|
+
navigate(`../${collectionType}/${model}/configurations/edit`);
|
|
2856
|
+
},
|
|
2857
|
+
position: "header"
|
|
2858
|
+
};
|
|
2720
2859
|
};
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
}
|
|
2725
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
|
2726
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
|
2727
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
|
2728
|
-
);
|
|
2860
|
+
ConfigureTheViewAction.type = "configure-the-view";
|
|
2861
|
+
const EditTheModelAction = ({ model }) => {
|
|
2862
|
+
const navigate = useNavigate();
|
|
2863
|
+
const { formatMessage } = useIntl();
|
|
2729
2864
|
return {
|
|
2730
|
-
|
|
2731
|
-
|
|
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"
|
|
2732
2874
|
};
|
|
2733
2875
|
};
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
mainField: "id",
|
|
2742
|
-
pageSize: 10
|
|
2743
|
-
};
|
|
2744
|
-
const useDocumentLayout = (model) => {
|
|
2745
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
|
2746
|
-
const [{ query }] = useQueryParams();
|
|
2747
|
-
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
|
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();
|
|
2748
2883
|
const { toggleNotification } = useNotification();
|
|
2749
|
-
const
|
|
2750
|
-
const
|
|
2751
|
-
const {
|
|
2752
|
-
data,
|
|
2753
|
-
isLoading: isLoadingConfigs,
|
|
2754
|
-
error,
|
|
2755
|
-
isFetching: isFetchingConfigs
|
|
2756
|
-
} = useGetContentTypeConfigurationQuery(model);
|
|
2757
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
|
2758
|
-
React.useEffect(() => {
|
|
2759
|
-
if (error) {
|
|
2760
|
-
toggleNotification({
|
|
2761
|
-
type: "danger",
|
|
2762
|
-
message: formatAPIError(error)
|
|
2763
|
-
});
|
|
2764
|
-
}
|
|
2765
|
-
}, [error, formatAPIError, toggleNotification]);
|
|
2766
|
-
const editLayout = React.useMemo(
|
|
2767
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
|
2768
|
-
layout: [],
|
|
2769
|
-
components: {},
|
|
2770
|
-
metadatas: {},
|
|
2771
|
-
options: {},
|
|
2772
|
-
settings: DEFAULT_SETTINGS
|
|
2773
|
-
},
|
|
2774
|
-
[data, isLoading, schemas, schema, components]
|
|
2775
|
-
);
|
|
2776
|
-
const listLayout = React.useMemo(() => {
|
|
2777
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
|
2778
|
-
layout: [],
|
|
2779
|
-
metadatas: {},
|
|
2780
|
-
options: {},
|
|
2781
|
-
settings: DEFAULT_SETTINGS
|
|
2782
|
-
};
|
|
2783
|
-
}, [data, isLoading, schemas, schema, components]);
|
|
2784
|
-
const { layout: edit } = React.useMemo(
|
|
2785
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
|
2786
|
-
layout: editLayout,
|
|
2787
|
-
query
|
|
2788
|
-
}),
|
|
2789
|
-
[editLayout, query, runHookWaterfall]
|
|
2790
|
-
);
|
|
2884
|
+
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
|
2885
|
+
const isLocalized = document?.locale != null;
|
|
2791
2886
|
return {
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
}
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
})
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
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
|
+
}
|
|
2839
2942
|
}
|
|
2840
|
-
}
|
|
2841
|
-
return acc;
|
|
2842
|
-
},
|
|
2843
|
-
{}
|
|
2844
|
-
);
|
|
2845
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
|
2846
|
-
(acc, [attribute, metadata]) => {
|
|
2847
|
-
return {
|
|
2848
|
-
...acc,
|
|
2849
|
-
[attribute]: metadata.edit
|
|
2850
|
-
};
|
|
2851
|
-
},
|
|
2852
|
-
{}
|
|
2853
|
-
);
|
|
2854
|
-
return {
|
|
2855
|
-
layout: panelledEditAttributes,
|
|
2856
|
-
components: componentEditAttributes,
|
|
2857
|
-
metadatas: editMetadatas,
|
|
2858
|
-
settings: {
|
|
2859
|
-
...data.contentType.settings,
|
|
2860
|
-
displayName: schema?.info.displayName
|
|
2943
|
+
}
|
|
2861
2944
|
},
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
...schema?.pluginOptions,
|
|
2865
|
-
...data.contentType.options
|
|
2866
|
-
}
|
|
2945
|
+
variant: "danger",
|
|
2946
|
+
position: ["header", "table-row"]
|
|
2867
2947
|
};
|
|
2868
2948
|
};
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
}
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
}
|
|
2896
|
-
}
|
|
2897
|
-
);
|
|
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
|
+
) });
|
|
2898
2978
|
};
|
|
2899
|
-
const
|
|
2900
|
-
|
|
2901
|
-
schema,
|
|
2902
|
-
components
|
|
2903
|
-
}) => {
|
|
2904
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
|
2905
|
-
(acc, [attribute, metadata]) => {
|
|
2906
|
-
return {
|
|
2907
|
-
...acc,
|
|
2908
|
-
[attribute]: metadata.list
|
|
2909
|
-
};
|
|
2910
|
-
},
|
|
2911
|
-
{}
|
|
2912
|
-
);
|
|
2913
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
|
2914
|
-
data.contentType.layouts.list,
|
|
2915
|
-
schema?.attributes,
|
|
2916
|
-
listMetadatas,
|
|
2917
|
-
{ configurations: data.components, schemas: components },
|
|
2918
|
-
schemas
|
|
2919
|
-
);
|
|
2979
|
+
const ActionsPanel = () => {
|
|
2980
|
+
const { formatMessage } = useIntl();
|
|
2920
2981
|
return {
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
...schema?.pluginOptions,
|
|
2927
|
-
...data.contentType.options
|
|
2928
|
-
}
|
|
2982
|
+
title: formatMessage({
|
|
2983
|
+
id: "content-manager.containers.edit.panels.default.title",
|
|
2984
|
+
defaultMessage: "Entry"
|
|
2985
|
+
}),
|
|
2986
|
+
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
|
2929
2987
|
};
|
|
2930
2988
|
};
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2989
|
+
ActionsPanel.type = "actions";
|
|
2990
|
+
const ActionsPanelContent = () => {
|
|
2991
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
|
2992
|
+
const [
|
|
2993
|
+
{
|
|
2994
|
+
query: { status = "draft" }
|
|
2936
2995
|
}
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
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
|
+
] });
|
|
2951
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
|
+
});
|
|
2952
3045
|
const ConfirmBulkActionDialog = ({
|
|
2953
3046
|
onToggleDialog,
|
|
2954
3047
|
isOpen = false,
|
|
@@ -3926,6 +4019,70 @@ const { setInitialData } = actions;
|
|
|
3926
4019
|
const reducer = combineReducers({
|
|
3927
4020
|
app: reducer$1
|
|
3928
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
|
+
};
|
|
3929
4086
|
const index = {
|
|
3930
4087
|
register(app) {
|
|
3931
4088
|
const cm = new ContentManagerPlugin();
|
|
@@ -3945,7 +4102,7 @@ const index = {
|
|
|
3945
4102
|
app.router.addRoute({
|
|
3946
4103
|
path: "content-manager/*",
|
|
3947
4104
|
lazy: async () => {
|
|
3948
|
-
const { Layout } = await import("./layout-
|
|
4105
|
+
const { Layout } = await import("./layout-Bue_C6ui.mjs");
|
|
3949
4106
|
return {
|
|
3950
4107
|
Component: Layout
|
|
3951
4108
|
};
|
|
@@ -3958,11 +4115,14 @@ const index = {
|
|
|
3958
4115
|
if (typeof historyAdmin.bootstrap === "function") {
|
|
3959
4116
|
historyAdmin.bootstrap(app);
|
|
3960
4117
|
}
|
|
4118
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
|
4119
|
+
previewAdmin.bootstrap(app);
|
|
4120
|
+
}
|
|
3961
4121
|
},
|
|
3962
4122
|
async registerTrads({ locales }) {
|
|
3963
4123
|
const importedTrads = await Promise.all(
|
|
3964
4124
|
locales.map((locale) => {
|
|
3965
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-
|
|
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 }) => {
|
|
3966
4126
|
return {
|
|
3967
4127
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
|
3968
4128
|
locale
|
|
@@ -3989,8 +4149,10 @@ export {
|
|
|
3989
4149
|
HOOKS as H,
|
|
3990
4150
|
InjectionZone as I,
|
|
3991
4151
|
useDocument as J,
|
|
3992
|
-
|
|
3993
|
-
|
|
4152
|
+
useGetPreviewUrlQuery as K,
|
|
4153
|
+
index as L,
|
|
4154
|
+
useContentManagerContext as M,
|
|
4155
|
+
useDocumentActions as N,
|
|
3994
4156
|
Panels as P,
|
|
3995
4157
|
RelativeTime as R,
|
|
3996
4158
|
SINGLE_TYPES as S,
|
|
@@ -4022,4 +4184,4 @@ export {
|
|
|
4022
4184
|
capitalise as y,
|
|
4023
4185
|
useUpdateContentTypeConfigurationMutation as z
|
|
4024
4186
|
};
|
|
4025
|
-
//# sourceMappingURL=index-
|
|
4187
|
+
//# sourceMappingURL=index-V8MWkDSd.mjs.map
|