@strapi/content-manager 0.0.0-experimental.545ccead2ee1717bbc7ab950455dbb0ddb9924a3 → 0.0.0-experimental.550e739e36d7678bd8317b48acab2f24b1f4dcd6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -1
- package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-Bqgx7Mes.js → ComponentConfigurationPage-CJPoOvy3.js} +5 -6
- package/dist/_chunks/{ComponentConfigurationPage-Bqgx7Mes.js.map → ComponentConfigurationPage-CJPoOvy3.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-B1bIXVuX.mjs → ComponentConfigurationPage-CcRDqD0e.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-B1bIXVuX.mjs.map → ComponentConfigurationPage-CcRDqD0e.mjs.map} +1 -1
- package/dist/_chunks/{ComponentIcon-BXdiCGQp.js → ComponentIcon-CRbtQEUV.js} +2 -3
- package/dist/_chunks/{ComponentIcon-BXdiCGQp.js.map → ComponentIcon-CRbtQEUV.js.map} +1 -1
- package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -1
- package/dist/_chunks/{EditConfigurationPage-ZO0vOO8q.mjs → EditConfigurationPage-C1ddZ_zf.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-ZO0vOO8q.mjs.map → EditConfigurationPage-C1ddZ_zf.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-BFEwvdMW.js → EditConfigurationPage-CF3lxOy2.js} +5 -6
- package/dist/_chunks/{EditConfigurationPage-BFEwvdMW.js.map → EditConfigurationPage-CF3lxOy2.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-DlLEyUL6.mjs → EditViewPage-BPFcUbqi.mjs} +63 -12
- package/dist/_chunks/EditViewPage-BPFcUbqi.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-DA95Ha6J.js → EditViewPage-CDyTC6aU.js} +63 -13
- package/dist/_chunks/EditViewPage-CDyTC6aU.js.map +1 -0
- package/dist/_chunks/{Field-CnK8dO8N.js → Field-DuxAW9q2.js} +344 -220
- package/dist/_chunks/Field-DuxAW9q2.js.map +1 -0
- package/dist/_chunks/{Field-Dq7bDnuh.mjs → Field-fBnTwgU4.mjs} +340 -216
- package/dist/_chunks/Field-fBnTwgU4.mjs.map +1 -0
- package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
- package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
- package/dist/_chunks/{Form-B_JE0dbz.mjs → Form-BGl7PhlZ.mjs} +37 -18
- package/dist/_chunks/Form-BGl7PhlZ.mjs.map +1 -0
- package/dist/_chunks/{Form-BpiR4piS.js → Form-DSGh_zkz.js} +39 -21
- package/dist/_chunks/Form-DSGh_zkz.js.map +1 -0
- package/dist/_chunks/{History-CBNGU7a-.mjs → History-DTYB9CSB.mjs} +59 -106
- package/dist/_chunks/History-DTYB9CSB.mjs.map +1 -0
- package/dist/_chunks/{History-DdIstl8b.js → History-DrDJv698.js} +58 -106
- package/dist/_chunks/History-DrDJv698.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-5dr4qpue.mjs → ListConfigurationPage-qWx8r4D_.mjs} +19 -8
- package/dist/_chunks/ListConfigurationPage-qWx8r4D_.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DkKRparB.js → ListConfigurationPage-zurIlUZ7.js} +19 -9
- package/dist/_chunks/ListConfigurationPage-zurIlUZ7.js.map +1 -0
- package/dist/_chunks/{ListViewPage-wE0lXqoD.js → ListViewPage-DTM2uO_S.js} +109 -78
- package/dist/_chunks/ListViewPage-DTM2uO_S.js.map +1 -0
- package/dist/_chunks/{ListViewPage-DecLrYV6.mjs → ListViewPage-GKpL5p8A.mjs} +106 -74
- package/dist/_chunks/ListViewPage-GKpL5p8A.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-CiIcfYsd.mjs → NoContentTypePage-B5Vc5Cal.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CiIcfYsd.mjs.map → NoContentTypePage-B5Vc5Cal.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-DEKR6tf9.js → NoContentTypePage-BuZlNroO.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-DEKR6tf9.js.map → NoContentTypePage-BuZlNroO.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-CM5UD8ee.mjs → NoPermissionsPage-BAZlWgJ4.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-CM5UD8ee.mjs.map → NoPermissionsPage-BAZlWgJ4.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DmNfF2Bb.js → NoPermissionsPage-DLzkS4Hy.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DmNfF2Bb.js.map → NoPermissionsPage-DLzkS4Hy.js.map} +1 -1
- package/dist/_chunks/Preview-VOJ8RuQp.js +312 -0
- package/dist/_chunks/Preview-VOJ8RuQp.js.map +1 -0
- package/dist/_chunks/Preview-Zzjg2_K_.mjs +294 -0
- package/dist/_chunks/Preview-Zzjg2_K_.mjs.map +1 -0
- package/dist/_chunks/{Relations-Dqz0C1fz.mjs → Relations-BVdRfDkW.mjs} +76 -42
- package/dist/_chunks/Relations-BVdRfDkW.mjs.map +1 -0
- package/dist/_chunks/{Relations-L0xYRoSQ.js → Relations-Dsj0boFJ.js} +76 -43
- package/dist/_chunks/Relations-Dsj0boFJ.js.map +1 -0
- package/dist/_chunks/{en-uOUIxfcQ.js → en-BzQmavmK.js} +33 -15
- package/dist/_chunks/{en-uOUIxfcQ.js.map → en-BzQmavmK.js.map} +1 -1
- package/dist/_chunks/{en-BrCTWlZv.mjs → en-CSxLmrh1.mjs} +33 -15
- package/dist/_chunks/{en-BrCTWlZv.mjs.map → en-CSxLmrh1.mjs.map} +1 -1
- package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
- package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
- package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
- package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
- package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
- package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
- package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
- package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
- package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
- package/dist/_chunks/{index-BSn97i8U.mjs → index-Bu_-B7ZA.mjs} +1143 -767
- package/dist/_chunks/index-Bu_-B7ZA.mjs.map +1 -0
- package/dist/_chunks/{index-DyvUPg1a.js → index-Ct-GZ0iV.js} +1125 -749
- package/dist/_chunks/index-Ct-GZ0iV.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-TPqF2oJ5.js → layout-CDBEgRsM.js} +23 -11
- package/dist/_chunks/layout-CDBEgRsM.js.map +1 -0
- package/dist/_chunks/{layout-DPaHUusj.mjs → layout-COzAvgJh.mjs} +23 -10
- package/dist/_chunks/layout-COzAvgJh.mjs.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-BWYS9gkn.js → relations-BjiF1Aad.js} +6 -7
- package/dist/_chunks/relations-BjiF1Aad.js.map +1 -0
- package/dist/_chunks/{relations-Ck7-ecDT.mjs → relations-BtmMFBpM.mjs} +6 -7
- package/dist/_chunks/relations-BtmMFBpM.mjs.map +1 -0
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
- package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
- package/dist/admin/index.js +3 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +6 -4
- package/dist/admin/src/content-manager.d.ts +3 -2
- package/dist/admin/src/exports.d.ts +2 -1
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +3 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +7 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/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/PreviewContent.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
- package/dist/admin/src/preview/index.d.ts +4 -0
- package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
- package/dist/admin/src/preview/routes.d.ts +3 -0
- package/dist/admin/src/preview/services/preview.d.ts +3 -0
- package/dist/admin/src/router.d.ts +1 -1
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +19 -20
- 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 +682 -360
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +683 -360
- 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/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/metadata.d.ts +16 -1
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
- package/dist/server/src/controllers/validation/dimensions.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 +7 -6
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/preview/controllers/index.d.ts +2 -0
- package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/preview.d.ts +13 -0
- package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
- package/dist/server/src/preview/index.d.ts +4 -0
- package/dist/server/src/preview/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/index.d.ts +8 -0
- package/dist/server/src/preview/routes/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/preview.d.ts +4 -0
- package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
- package/dist/server/src/preview/services/index.d.ts +16 -0
- package/dist/server/src/preview/services/index.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview-config.d.ts +32 -0
- package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview.d.ts +12 -0
- package/dist/server/src/preview/services/preview.d.ts.map +1 -0
- package/dist/server/src/preview/utils.d.ts +19 -0
- package/dist/server/src/preview/utils.d.ts.map +1 -0
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +12 -10
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +7 -6
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.d.ts +2 -2
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/shared/contracts/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 +17 -15
- package/dist/_chunks/EditViewPage-DA95Ha6J.js.map +0 -1
- package/dist/_chunks/EditViewPage-DlLEyUL6.mjs.map +0 -1
- package/dist/_chunks/Field-CnK8dO8N.js.map +0 -1
- package/dist/_chunks/Field-Dq7bDnuh.mjs.map +0 -1
- package/dist/_chunks/Form-B_JE0dbz.mjs.map +0 -1
- package/dist/_chunks/Form-BpiR4piS.js.map +0 -1
- package/dist/_chunks/History-CBNGU7a-.mjs.map +0 -1
- package/dist/_chunks/History-DdIstl8b.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-5dr4qpue.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DkKRparB.js.map +0 -1
- package/dist/_chunks/ListViewPage-DecLrYV6.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-wE0lXqoD.js.map +0 -1
- package/dist/_chunks/Relations-Dqz0C1fz.mjs.map +0 -1
- package/dist/_chunks/Relations-L0xYRoSQ.js.map +0 -1
- package/dist/_chunks/index-BSn97i8U.mjs.map +0 -1
- package/dist/_chunks/index-DyvUPg1a.js.map +0 -1
- package/dist/_chunks/layout-DPaHUusj.mjs.map +0 -1
- package/dist/_chunks/layout-TPqF2oJ5.js.map +0 -1
- package/dist/_chunks/relations-BWYS9gkn.js.map +0 -1
- package/dist/_chunks/relations-Ck7-ecDT.mjs.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
@@ -4,18 +4,18 @@ const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const strapiAdmin = require("@strapi/admin/strapi-admin");
|
5
5
|
const React = require("react");
|
6
6
|
const designSystem = require("@strapi/design-system");
|
7
|
+
const mapValues = require("lodash/fp/mapValues");
|
7
8
|
const reactIntl = require("react-intl");
|
8
9
|
const reactRouterDom = require("react-router-dom");
|
9
10
|
const styledComponents = require("styled-components");
|
10
11
|
const yup = require("yup");
|
12
|
+
const qs = require("qs");
|
11
13
|
const pipe = require("lodash/fp/pipe");
|
12
14
|
const dateFns = require("date-fns");
|
13
|
-
const qs = require("qs");
|
14
15
|
const toolkit = require("@reduxjs/toolkit");
|
15
16
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
16
17
|
function _interopNamespace(e) {
|
17
|
-
if (e && e.__esModule)
|
18
|
-
return e;
|
18
|
+
if (e && e.__esModule) return e;
|
19
19
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
20
20
|
if (e) {
|
21
21
|
for (const k in e) {
|
@@ -32,15 +32,23 @@ function _interopNamespace(e) {
|
|
32
32
|
return Object.freeze(n);
|
33
33
|
}
|
34
34
|
const React__namespace = /* @__PURE__ */ _interopNamespace(React);
|
35
|
+
const mapValues__default = /* @__PURE__ */ _interopDefault(mapValues);
|
35
36
|
const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
|
36
37
|
const pipe__default = /* @__PURE__ */ _interopDefault(pipe);
|
37
|
-
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
38
|
+
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
38
39
|
const v = glob[path];
|
39
40
|
if (v) {
|
40
41
|
return typeof v === "function" ? v() : Promise.resolve(v);
|
41
42
|
}
|
42
43
|
return new Promise((_, reject) => {
|
43
|
-
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
44
|
+
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
45
|
+
reject.bind(
|
46
|
+
null,
|
47
|
+
new Error(
|
48
|
+
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
49
|
+
)
|
50
|
+
)
|
51
|
+
);
|
44
52
|
});
|
45
53
|
};
|
46
54
|
const PLUGIN_ID = "content-manager";
|
@@ -121,6 +129,7 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
121
129
|
if (!slug) {
|
122
130
|
throw new Error("Cannot find the slug param in the URL");
|
123
131
|
}
|
132
|
+
const [{ rawQuery }] = strapiAdmin.useQueryParams();
|
124
133
|
const userPermissions = strapiAdmin.useAuth("DocumentRBAC", (state) => state.permissions);
|
125
134
|
const contentTypePermissions = React__namespace.useMemo(() => {
|
126
135
|
const contentTypePermissions2 = userPermissions.filter(
|
@@ -131,7 +140,14 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
131
140
|
return { ...acc, [action]: [permission] };
|
132
141
|
}, {});
|
133
142
|
}, [slug, userPermissions]);
|
134
|
-
const { isLoading, allowedActions } = strapiAdmin.useRBAC(
|
143
|
+
const { isLoading, allowedActions } = strapiAdmin.useRBAC(
|
144
|
+
contentTypePermissions,
|
145
|
+
permissions ?? void 0,
|
146
|
+
// TODO: useRBAC context should be typed and built differently
|
147
|
+
// We are passing raw query as context to the hook so that it can
|
148
|
+
// rely on the locale provided from DocumentRBAC for its permission calculations.
|
149
|
+
rawQuery
|
150
|
+
);
|
135
151
|
const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
|
136
152
|
const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
|
137
153
|
const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
|
@@ -179,7 +195,9 @@ const contentManagerApi = strapiAdmin.adminApi.enhanceEndpoints({
|
|
179
195
|
"Document",
|
180
196
|
"InitialData",
|
181
197
|
"HistoryVersion",
|
182
|
-
"Relations"
|
198
|
+
"Relations",
|
199
|
+
"UidAvailability",
|
200
|
+
"RecentDocumentList"
|
183
201
|
]
|
184
202
|
});
|
185
203
|
const documentApi = contentManagerApi.injectEndpoints({
|
@@ -193,7 +211,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
193
211
|
params: query
|
194
212
|
}
|
195
213
|
}),
|
196
|
-
invalidatesTags: (_result,
|
214
|
+
invalidatesTags: (_result, error, { model }) => {
|
215
|
+
if (error) {
|
216
|
+
return [];
|
217
|
+
}
|
218
|
+
return [{ type: "Document", id: `${model}_LIST` }, "RecentDocumentList"];
|
219
|
+
}
|
197
220
|
}),
|
198
221
|
cloneDocument: builder.mutation({
|
199
222
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -204,7 +227,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
204
227
|
params
|
205
228
|
}
|
206
229
|
}),
|
207
|
-
invalidatesTags: (_result, _error, { model }) => [
|
230
|
+
invalidatesTags: (_result, _error, { model }) => [
|
231
|
+
{ type: "Document", id: `${model}_LIST` },
|
232
|
+
{ type: "UidAvailability", id: model },
|
233
|
+
"RecentDocumentList"
|
234
|
+
]
|
208
235
|
}),
|
209
236
|
/**
|
210
237
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -221,8 +248,22 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
221
248
|
}),
|
222
249
|
invalidatesTags: (result, _error, { model }) => [
|
223
250
|
{ type: "Document", id: `${model}_LIST` },
|
224
|
-
"Relations"
|
225
|
-
|
251
|
+
"Relations",
|
252
|
+
{ type: "UidAvailability", id: model },
|
253
|
+
"RecentDocumentList"
|
254
|
+
],
|
255
|
+
transformResponse: (response, meta, arg) => {
|
256
|
+
if (!("data" in response) && arg.model === "plugin::users-permissions.user") {
|
257
|
+
return {
|
258
|
+
data: response,
|
259
|
+
meta: {
|
260
|
+
availableStatus: [],
|
261
|
+
availableLocales: []
|
262
|
+
}
|
263
|
+
};
|
264
|
+
}
|
265
|
+
return response;
|
266
|
+
}
|
226
267
|
}),
|
227
268
|
deleteDocument: builder.mutation({
|
228
269
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -233,7 +274,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
233
274
|
}
|
234
275
|
}),
|
235
276
|
invalidatesTags: (_result, _error, { collectionType, model }) => [
|
236
|
-
{ type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model }
|
277
|
+
{ type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model },
|
278
|
+
"RecentDocumentList"
|
237
279
|
]
|
238
280
|
}),
|
239
281
|
deleteManyDocuments: builder.mutation({
|
@@ -245,7 +287,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
245
287
|
params
|
246
288
|
}
|
247
289
|
}),
|
248
|
-
invalidatesTags: (_res, _error, { model }) => [
|
290
|
+
invalidatesTags: (_res, _error, { model }) => [
|
291
|
+
{ type: "Document", id: `${model}_LIST` },
|
292
|
+
"RecentDocumentList"
|
293
|
+
]
|
249
294
|
}),
|
250
295
|
discardDocument: builder.mutation({
|
251
296
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -262,7 +307,9 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
262
307
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
263
308
|
},
|
264
309
|
{ type: "Document", id: `${model}_LIST` },
|
265
|
-
"Relations"
|
310
|
+
"Relations",
|
311
|
+
{ type: "UidAvailability", id: model },
|
312
|
+
"RecentDocumentList"
|
266
313
|
];
|
267
314
|
}
|
268
315
|
}),
|
@@ -275,11 +322,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
275
322
|
url: `/content-manager/collection-types/${model}`,
|
276
323
|
method: "GET",
|
277
324
|
config: {
|
278
|
-
params
|
325
|
+
params: qs.stringify(params, { encode: true })
|
279
326
|
}
|
280
327
|
}),
|
281
328
|
providesTags: (result, _error, arg) => {
|
282
329
|
return [
|
330
|
+
{ type: "Document", id: `ALL_LIST` },
|
283
331
|
{ type: "Document", id: `${arg.model}_LIST` },
|
284
332
|
...result?.results.map(({ documentId }) => ({
|
285
333
|
type: "Document",
|
@@ -318,6 +366,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
318
366
|
{
|
319
367
|
type: "Document",
|
320
368
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
369
|
+
},
|
370
|
+
// Make it easy to invalidate all individual documents queries for a model
|
371
|
+
{
|
372
|
+
type: "Document",
|
373
|
+
id: `${model}_ALL_ITEMS`
|
321
374
|
}
|
322
375
|
];
|
323
376
|
}
|
@@ -351,7 +404,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
351
404
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
352
405
|
},
|
353
406
|
{ type: "Document", id: `${model}_LIST` },
|
354
|
-
"Relations"
|
407
|
+
"Relations",
|
408
|
+
"RecentDocumentList"
|
355
409
|
];
|
356
410
|
}
|
357
411
|
}),
|
@@ -381,8 +435,23 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
381
435
|
type: "Document",
|
382
436
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
383
437
|
},
|
384
|
-
"Relations"
|
438
|
+
"Relations",
|
439
|
+
{ type: "UidAvailability", id: model },
|
440
|
+
"RecentDocumentList",
|
441
|
+
"RecentDocumentList"
|
385
442
|
];
|
443
|
+
},
|
444
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
445
|
+
const patchResult = dispatch(
|
446
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
447
|
+
Object.assign(draft.data, data);
|
448
|
+
})
|
449
|
+
);
|
450
|
+
try {
|
451
|
+
await queryFulfilled;
|
452
|
+
} catch {
|
453
|
+
patchResult.undo();
|
454
|
+
}
|
386
455
|
}
|
387
456
|
}),
|
388
457
|
unpublishDocument: builder.mutation({
|
@@ -399,7 +468,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
399
468
|
{
|
400
469
|
type: "Document",
|
401
470
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
402
|
-
}
|
471
|
+
},
|
472
|
+
"RecentDocumentList"
|
403
473
|
];
|
404
474
|
}
|
405
475
|
}),
|
@@ -412,7 +482,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
412
482
|
params
|
413
483
|
}
|
414
484
|
}),
|
415
|
-
invalidatesTags: (_res, _error, { model, documentIds }) =>
|
485
|
+
invalidatesTags: (_res, _error, { model, documentIds }) => [
|
486
|
+
...documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` })),
|
487
|
+
"RecentDocumentList"
|
488
|
+
]
|
416
489
|
})
|
417
490
|
})
|
418
491
|
});
|
@@ -435,8 +508,7 @@ const {
|
|
435
508
|
useUnpublishManyDocumentsMutation
|
436
509
|
} = documentApi;
|
437
510
|
const buildValidParams = (query) => {
|
438
|
-
if (!query)
|
439
|
-
return query;
|
511
|
+
if (!query) return query;
|
440
512
|
const { plugins: _, ...validQueryParams } = {
|
441
513
|
...query,
|
442
514
|
...Object.values(query?.plugins ?? {}).reduce(
|
@@ -444,28 +516,44 @@ const buildValidParams = (query) => {
|
|
444
516
|
{}
|
445
517
|
)
|
446
518
|
};
|
447
|
-
if ("_q" in validQueryParams) {
|
448
|
-
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
449
|
-
}
|
450
519
|
return validQueryParams;
|
451
520
|
};
|
452
521
|
const isBaseQueryError = (error) => {
|
453
522
|
return error.name !== void 0;
|
454
523
|
};
|
455
|
-
const
|
524
|
+
const arrayValidator = (attribute, options) => ({
|
525
|
+
message: strapiAdmin.translatedErrors.required,
|
526
|
+
test(value) {
|
527
|
+
if (options.status === "draft") {
|
528
|
+
return true;
|
529
|
+
}
|
530
|
+
if (!attribute.required) {
|
531
|
+
return true;
|
532
|
+
}
|
533
|
+
if (!value) {
|
534
|
+
return false;
|
535
|
+
}
|
536
|
+
if (Array.isArray(value) && value.length === 0) {
|
537
|
+
return false;
|
538
|
+
}
|
539
|
+
return true;
|
540
|
+
}
|
541
|
+
});
|
542
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
456
543
|
const createModelSchema = (attributes2) => yup__namespace.object().shape(
|
457
544
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
458
545
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
459
546
|
return acc;
|
460
547
|
}
|
461
548
|
const validations = [
|
549
|
+
addNullableValidation,
|
462
550
|
addRequiredValidation,
|
463
551
|
addMinLengthValidation,
|
464
552
|
addMaxLengthValidation,
|
465
553
|
addMinValidation,
|
466
554
|
addMaxValidation,
|
467
555
|
addRegexValidation
|
468
|
-
].map((fn) => fn(attribute));
|
556
|
+
].map((fn) => fn(attribute, options));
|
469
557
|
const transformSchema = pipe__default.default(...validations);
|
470
558
|
switch (attribute.type) {
|
471
559
|
case "component": {
|
@@ -475,12 +563,12 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
475
563
|
...acc,
|
476
564
|
[name]: transformSchema(
|
477
565
|
yup__namespace.array().of(createModelSchema(attributes3).nullable(false))
|
478
|
-
)
|
566
|
+
).test(arrayValidator(attribute, options))
|
479
567
|
};
|
480
568
|
} else {
|
481
569
|
return {
|
482
570
|
...acc,
|
483
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
571
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
484
572
|
};
|
485
573
|
}
|
486
574
|
}
|
@@ -502,7 +590,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
502
590
|
}
|
503
591
|
)
|
504
592
|
)
|
505
|
-
)
|
593
|
+
).test(arrayValidator(attribute, options))
|
506
594
|
};
|
507
595
|
case "relation":
|
508
596
|
return {
|
@@ -514,7 +602,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
514
602
|
} else if (Array.isArray(value)) {
|
515
603
|
return yup__namespace.array().of(
|
516
604
|
yup__namespace.object().shape({
|
517
|
-
id: yup__namespace.
|
605
|
+
id: yup__namespace.number().required()
|
518
606
|
})
|
519
607
|
);
|
520
608
|
} else if (typeof value === "object") {
|
@@ -566,6 +654,14 @@ const createAttributeSchema = (attribute) => {
|
|
566
654
|
if (!value || typeof value === "string" && value.length === 0) {
|
567
655
|
return true;
|
568
656
|
}
|
657
|
+
if (typeof value === "object") {
|
658
|
+
try {
|
659
|
+
JSON.stringify(value);
|
660
|
+
return true;
|
661
|
+
} catch (err) {
|
662
|
+
return false;
|
663
|
+
}
|
664
|
+
}
|
569
665
|
try {
|
570
666
|
JSON.parse(value);
|
571
667
|
return true;
|
@@ -584,13 +680,7 @@ const createAttributeSchema = (attribute) => {
|
|
584
680
|
return yup__namespace.mixed();
|
585
681
|
}
|
586
682
|
};
|
587
|
-
const
|
588
|
-
if ((attribute.type === "component" && attribute.repeatable || attribute.type === "dynamiczone") && attribute.required && "min" in schema) {
|
589
|
-
return schema.min(1, strapiAdmin.translatedErrors.required);
|
590
|
-
}
|
591
|
-
if (attribute.required && attribute.type !== "relation") {
|
592
|
-
return schema.required(strapiAdmin.translatedErrors.required);
|
593
|
-
}
|
683
|
+
const nullableSchema = (schema) => {
|
594
684
|
return schema?.nullable ? schema.nullable() : (
|
595
685
|
// In some cases '.nullable' will not be available on the schema.
|
596
686
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -598,7 +688,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
598
688
|
schema
|
599
689
|
);
|
600
690
|
};
|
601
|
-
const
|
691
|
+
const addNullableValidation = () => (schema) => {
|
692
|
+
return nullableSchema(schema);
|
693
|
+
};
|
694
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
695
|
+
if (options.status === "draft" || !attribute.required) {
|
696
|
+
return schema;
|
697
|
+
}
|
698
|
+
if (attribute.required && "required" in schema) {
|
699
|
+
return schema.required(strapiAdmin.translatedErrors.required);
|
700
|
+
}
|
701
|
+
return schema;
|
702
|
+
};
|
703
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
704
|
+
if (options.status === "draft") {
|
705
|
+
return schema;
|
706
|
+
}
|
602
707
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
603
708
|
return schema.min(attribute.minLength, {
|
604
709
|
...strapiAdmin.translatedErrors.minLength,
|
@@ -620,32 +725,13 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
620
725
|
}
|
621
726
|
return schema;
|
622
727
|
};
|
623
|
-
const addMinValidation = (attribute) => (schema) => {
|
624
|
-
if ("
|
728
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
729
|
+
if (options.status === "draft") {
|
730
|
+
return schema;
|
731
|
+
}
|
732
|
+
if ("min" in attribute && "min" in schema) {
|
625
733
|
const min = toInteger(attribute.min);
|
626
|
-
if (
|
627
|
-
if (!attribute.required && "test" in schema && min) {
|
628
|
-
return schema.test(
|
629
|
-
"custom-min",
|
630
|
-
{
|
631
|
-
...strapiAdmin.translatedErrors.min,
|
632
|
-
values: {
|
633
|
-
min: attribute.min
|
634
|
-
}
|
635
|
-
},
|
636
|
-
(value) => {
|
637
|
-
if (!value) {
|
638
|
-
return true;
|
639
|
-
}
|
640
|
-
if (Array.isArray(value) && value.length === 0) {
|
641
|
-
return true;
|
642
|
-
}
|
643
|
-
return value.length >= min;
|
644
|
-
}
|
645
|
-
);
|
646
|
-
}
|
647
|
-
}
|
648
|
-
if ("min" in schema && min) {
|
734
|
+
if (min) {
|
649
735
|
return schema.min(min, {
|
650
736
|
...strapiAdmin.translatedErrors.min,
|
651
737
|
values: {
|
@@ -763,19 +849,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
763
849
|
}, {});
|
764
850
|
return componentsByKey;
|
765
851
|
};
|
766
|
-
const
|
852
|
+
const HOOKS = {
|
853
|
+
/**
|
854
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
855
|
+
* @constant
|
856
|
+
* @type {string}
|
857
|
+
*/
|
858
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
859
|
+
/**
|
860
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
861
|
+
* @constant
|
862
|
+
* @type {string}
|
863
|
+
*/
|
864
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
865
|
+
/**
|
866
|
+
* Hook that allows to mutate the CM's edit view layout
|
867
|
+
* @constant
|
868
|
+
* @type {string}
|
869
|
+
*/
|
870
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
871
|
+
/**
|
872
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
873
|
+
* @constant
|
874
|
+
* @type {string}
|
875
|
+
*/
|
876
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
877
|
+
};
|
878
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
879
|
+
endpoints: (builder) => ({
|
880
|
+
getContentTypeConfiguration: builder.query({
|
881
|
+
query: (uid) => ({
|
882
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
883
|
+
method: "GET"
|
884
|
+
}),
|
885
|
+
transformResponse: (response) => response.data,
|
886
|
+
providesTags: (_result, _error, uid) => [
|
887
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
888
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
889
|
+
]
|
890
|
+
}),
|
891
|
+
getAllContentTypeSettings: builder.query({
|
892
|
+
query: () => "/content-manager/content-types-settings",
|
893
|
+
transformResponse: (response) => response.data,
|
894
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
895
|
+
}),
|
896
|
+
updateContentTypeConfiguration: builder.mutation({
|
897
|
+
query: ({ uid, ...body }) => ({
|
898
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
899
|
+
method: "PUT",
|
900
|
+
data: body
|
901
|
+
}),
|
902
|
+
transformResponse: (response) => response.data,
|
903
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
904
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
905
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
906
|
+
// Is this necessary?
|
907
|
+
{ type: "InitialData" }
|
908
|
+
]
|
909
|
+
})
|
910
|
+
})
|
911
|
+
});
|
912
|
+
const {
|
913
|
+
useGetContentTypeConfigurationQuery,
|
914
|
+
useGetAllContentTypeSettingsQuery,
|
915
|
+
useUpdateContentTypeConfigurationMutation
|
916
|
+
} = contentTypesApi;
|
917
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
918
|
+
const { type } = attribute;
|
919
|
+
if (type === "relation") {
|
920
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
921
|
+
}
|
922
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
923
|
+
};
|
924
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
925
|
+
if (!mainFieldName) {
|
926
|
+
return void 0;
|
927
|
+
}
|
928
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
929
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
930
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
931
|
+
);
|
932
|
+
return {
|
933
|
+
name: mainFieldName,
|
934
|
+
type: mainFieldType ?? "string"
|
935
|
+
};
|
936
|
+
};
|
937
|
+
const DEFAULT_SETTINGS = {
|
938
|
+
bulkable: false,
|
939
|
+
filterable: false,
|
940
|
+
searchable: false,
|
941
|
+
pagination: false,
|
942
|
+
defaultSortBy: "",
|
943
|
+
defaultSortOrder: "asc",
|
944
|
+
mainField: "id",
|
945
|
+
pageSize: 10
|
946
|
+
};
|
947
|
+
const useDocumentLayout = (model) => {
|
948
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
949
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
950
|
+
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
767
951
|
const { toggleNotification } = strapiAdmin.useNotification();
|
768
952
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
953
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
769
954
|
const {
|
770
|
-
|
771
|
-
isLoading:
|
772
|
-
|
773
|
-
|
774
|
-
} =
|
775
|
-
|
776
|
-
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
777
|
-
});
|
778
|
-
const { components, schema, isLoading: isLoadingSchema } = useContentTypeSchema(args.model);
|
955
|
+
data,
|
956
|
+
isLoading: isLoadingConfigs,
|
957
|
+
error,
|
958
|
+
isFetching: isFetchingConfigs
|
959
|
+
} = useGetContentTypeConfigurationQuery(model);
|
960
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
779
961
|
React__namespace.useEffect(() => {
|
780
962
|
if (error) {
|
781
963
|
toggleNotification({
|
@@ -783,68 +965,322 @@ const useDocument = (args, opts) => {
|
|
783
965
|
message: formatAPIError(error)
|
784
966
|
});
|
785
967
|
}
|
786
|
-
}, [
|
787
|
-
const
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
(document) => {
|
795
|
-
if (!validationSchema) {
|
796
|
-
throw new Error(
|
797
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
798
|
-
);
|
799
|
-
}
|
800
|
-
try {
|
801
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
802
|
-
return null;
|
803
|
-
} catch (error2) {
|
804
|
-
if (error2 instanceof yup.ValidationError) {
|
805
|
-
return strapiAdmin.getYupValidationErrors(error2);
|
806
|
-
}
|
807
|
-
throw error2;
|
808
|
-
}
|
968
|
+
}, [error, formatAPIError, toggleNotification]);
|
969
|
+
const editLayout = React__namespace.useMemo(
|
970
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
971
|
+
layout: [],
|
972
|
+
components: {},
|
973
|
+
metadatas: {},
|
974
|
+
options: {},
|
975
|
+
settings: DEFAULT_SETTINGS
|
809
976
|
},
|
810
|
-
[
|
977
|
+
[data, isLoading, schemas, schema, components]
|
978
|
+
);
|
979
|
+
const listLayout = React__namespace.useMemo(() => {
|
980
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
981
|
+
layout: [],
|
982
|
+
metadatas: {},
|
983
|
+
options: {},
|
984
|
+
settings: DEFAULT_SETTINGS
|
985
|
+
};
|
986
|
+
}, [data, isLoading, schemas, schema, components]);
|
987
|
+
const { layout: edit } = React__namespace.useMemo(
|
988
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
989
|
+
layout: editLayout,
|
990
|
+
query
|
991
|
+
}),
|
992
|
+
[editLayout, query, runHookWaterfall]
|
811
993
|
);
|
812
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
813
994
|
return {
|
814
|
-
|
815
|
-
document: data?.data,
|
816
|
-
meta: data?.meta,
|
995
|
+
error,
|
817
996
|
isLoading,
|
818
|
-
|
819
|
-
|
820
|
-
};
|
821
|
-
};
|
822
|
-
const useDoc = () => {
|
823
|
-
const { id, slug, collectionType, origin } = reactRouterDom.useParams();
|
824
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
825
|
-
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
826
|
-
if (!collectionType) {
|
827
|
-
throw new Error("Could not find collectionType in url params");
|
828
|
-
}
|
829
|
-
if (!slug) {
|
830
|
-
throw new Error("Could not find model in url params");
|
831
|
-
}
|
832
|
-
return {
|
833
|
-
collectionType,
|
834
|
-
model: slug,
|
835
|
-
id: origin || id === "create" ? void 0 : id,
|
836
|
-
...useDocument(
|
837
|
-
{ documentId: origin || id, model: slug, collectionType, params },
|
838
|
-
{
|
839
|
-
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
840
|
-
}
|
841
|
-
)
|
997
|
+
edit,
|
998
|
+
list: listLayout
|
842
999
|
};
|
843
1000
|
};
|
844
|
-
const
|
845
|
-
|
846
|
-
|
1001
|
+
const useDocLayout = () => {
|
1002
|
+
const { model } = useDoc();
|
1003
|
+
return useDocumentLayout(model);
|
1004
|
+
};
|
1005
|
+
const formatEditLayout = (data, {
|
1006
|
+
schemas,
|
1007
|
+
schema,
|
1008
|
+
components
|
1009
|
+
}) => {
|
1010
|
+
let currentPanelIndex = 0;
|
1011
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
1012
|
+
data.contentType.layouts.edit,
|
1013
|
+
schema?.attributes,
|
1014
|
+
data.contentType.metadatas,
|
1015
|
+
{ configurations: data.components, schemas: components },
|
1016
|
+
schemas
|
1017
|
+
).reduce((panels, row) => {
|
1018
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
1019
|
+
panels.push([row]);
|
1020
|
+
currentPanelIndex += 2;
|
1021
|
+
} else {
|
1022
|
+
if (!panels[currentPanelIndex]) {
|
1023
|
+
panels.push([row]);
|
1024
|
+
} else {
|
1025
|
+
panels[currentPanelIndex].push(row);
|
1026
|
+
}
|
1027
|
+
}
|
1028
|
+
return panels;
|
1029
|
+
}, []);
|
1030
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
1031
|
+
(acc, [uid, configuration]) => {
|
1032
|
+
acc[uid] = {
|
1033
|
+
layout: convertEditLayoutToFieldLayouts(
|
1034
|
+
configuration.layouts.edit,
|
1035
|
+
components[uid].attributes,
|
1036
|
+
configuration.metadatas,
|
1037
|
+
{ configurations: data.components, schemas: components }
|
1038
|
+
),
|
1039
|
+
settings: {
|
1040
|
+
...configuration.settings,
|
1041
|
+
icon: components[uid].info.icon,
|
1042
|
+
displayName: components[uid].info.displayName
|
1043
|
+
}
|
1044
|
+
};
|
1045
|
+
return acc;
|
1046
|
+
},
|
1047
|
+
{}
|
1048
|
+
);
|
1049
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1050
|
+
(acc, [attribute, metadata]) => {
|
1051
|
+
return {
|
1052
|
+
...acc,
|
1053
|
+
[attribute]: metadata.edit
|
1054
|
+
};
|
1055
|
+
},
|
1056
|
+
{}
|
1057
|
+
);
|
1058
|
+
return {
|
1059
|
+
layout: panelledEditAttributes,
|
1060
|
+
components: componentEditAttributes,
|
1061
|
+
metadatas: editMetadatas,
|
1062
|
+
settings: {
|
1063
|
+
...data.contentType.settings,
|
1064
|
+
displayName: schema?.info.displayName
|
1065
|
+
},
|
1066
|
+
options: {
|
1067
|
+
...schema?.options,
|
1068
|
+
...schema?.pluginOptions,
|
1069
|
+
...data.contentType.options
|
1070
|
+
}
|
1071
|
+
};
|
1072
|
+
};
|
1073
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1074
|
+
return rows.map(
|
1075
|
+
(row) => row.map((field) => {
|
1076
|
+
const attribute = attributes[field.name];
|
1077
|
+
if (!attribute) {
|
1078
|
+
return null;
|
1079
|
+
}
|
1080
|
+
const { edit: metadata } = metadatas[field.name];
|
1081
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1082
|
+
return {
|
1083
|
+
attribute,
|
1084
|
+
disabled: !metadata.editable,
|
1085
|
+
hint: metadata.description,
|
1086
|
+
label: metadata.label ?? "",
|
1087
|
+
name: field.name,
|
1088
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1089
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1090
|
+
schemas,
|
1091
|
+
components: components?.schemas ?? {}
|
1092
|
+
}),
|
1093
|
+
placeholder: metadata.placeholder ?? "",
|
1094
|
+
required: attribute.required ?? false,
|
1095
|
+
size: field.size,
|
1096
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1097
|
+
visible: metadata.visible ?? true,
|
1098
|
+
type: attribute.type
|
1099
|
+
};
|
1100
|
+
}).filter((field) => field !== null)
|
1101
|
+
);
|
1102
|
+
};
|
1103
|
+
const formatListLayout = (data, {
|
1104
|
+
schemas,
|
1105
|
+
schema,
|
1106
|
+
components
|
1107
|
+
}) => {
|
1108
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1109
|
+
(acc, [attribute, metadata]) => {
|
1110
|
+
return {
|
1111
|
+
...acc,
|
1112
|
+
[attribute]: metadata.list
|
1113
|
+
};
|
1114
|
+
},
|
1115
|
+
{}
|
1116
|
+
);
|
1117
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1118
|
+
data.contentType.layouts.list,
|
1119
|
+
schema?.attributes,
|
1120
|
+
listMetadatas,
|
1121
|
+
{ configurations: data.components, schemas: components },
|
1122
|
+
schemas
|
1123
|
+
);
|
1124
|
+
return {
|
1125
|
+
layout: listAttributes,
|
1126
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1127
|
+
metadatas: listMetadatas,
|
1128
|
+
options: {
|
1129
|
+
...schema?.options,
|
1130
|
+
...schema?.pluginOptions,
|
1131
|
+
...data.contentType.options
|
1132
|
+
}
|
1133
|
+
};
|
1134
|
+
};
|
1135
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1136
|
+
return columns.map((name) => {
|
1137
|
+
const attribute = attributes[name];
|
1138
|
+
if (!attribute) {
|
1139
|
+
return null;
|
1140
|
+
}
|
1141
|
+
const metadata = metadatas[name];
|
1142
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1143
|
+
return {
|
1144
|
+
attribute,
|
1145
|
+
label: metadata.label ?? "",
|
1146
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1147
|
+
schemas,
|
1148
|
+
components: components?.schemas ?? {}
|
1149
|
+
}),
|
1150
|
+
name,
|
1151
|
+
searchable: metadata.searchable ?? true,
|
1152
|
+
sortable: metadata.sortable ?? true
|
1153
|
+
};
|
1154
|
+
}).filter((field) => field !== null);
|
1155
|
+
};
|
1156
|
+
const useDocument = (args, opts) => {
|
1157
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
1158
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1159
|
+
const {
|
1160
|
+
currentData: data,
|
1161
|
+
isLoading: isLoadingDocument,
|
1162
|
+
isFetching: isFetchingDocument,
|
1163
|
+
error
|
1164
|
+
} = useGetDocumentQuery(args, {
|
1165
|
+
...opts,
|
1166
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1167
|
+
});
|
1168
|
+
const {
|
1169
|
+
components,
|
1170
|
+
schema,
|
1171
|
+
schemas,
|
1172
|
+
isLoading: isLoadingSchema
|
1173
|
+
} = useContentTypeSchema(args.model);
|
1174
|
+
React__namespace.useEffect(() => {
|
1175
|
+
if (error) {
|
1176
|
+
toggleNotification({
|
1177
|
+
type: "danger",
|
1178
|
+
message: formatAPIError(error)
|
1179
|
+
});
|
1180
|
+
}
|
1181
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1182
|
+
const validationSchema = React__namespace.useMemo(() => {
|
1183
|
+
if (!schema) {
|
1184
|
+
return null;
|
1185
|
+
}
|
1186
|
+
return createYupSchema(schema.attributes, components);
|
1187
|
+
}, [schema, components]);
|
1188
|
+
const validate = React__namespace.useCallback(
|
1189
|
+
(document) => {
|
1190
|
+
if (!validationSchema) {
|
1191
|
+
throw new Error(
|
1192
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1193
|
+
);
|
1194
|
+
}
|
1195
|
+
try {
|
1196
|
+
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
1197
|
+
return null;
|
1198
|
+
} catch (error2) {
|
1199
|
+
if (error2 instanceof yup.ValidationError) {
|
1200
|
+
return strapiAdmin.getYupValidationErrors(error2);
|
1201
|
+
}
|
1202
|
+
throw error2;
|
1203
|
+
}
|
1204
|
+
},
|
1205
|
+
[validationSchema]
|
1206
|
+
);
|
1207
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1208
|
+
const hasError = !!error;
|
1209
|
+
return {
|
1210
|
+
components,
|
1211
|
+
document: data?.data,
|
1212
|
+
meta: data?.meta,
|
1213
|
+
isLoading,
|
1214
|
+
hasError,
|
1215
|
+
schema,
|
1216
|
+
schemas,
|
1217
|
+
validate
|
1218
|
+
};
|
1219
|
+
};
|
1220
|
+
const useDoc = () => {
|
1221
|
+
const { id, slug, collectionType, origin } = reactRouterDom.useParams();
|
1222
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
1223
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1224
|
+
if (!collectionType) {
|
1225
|
+
throw new Error("Could not find collectionType in url params");
|
1226
|
+
}
|
1227
|
+
if (!slug) {
|
1228
|
+
throw new Error("Could not find model in url params");
|
847
1229
|
}
|
1230
|
+
const document = useDocument(
|
1231
|
+
{ documentId: origin || id, model: slug, collectionType, params },
|
1232
|
+
{
|
1233
|
+
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
1234
|
+
}
|
1235
|
+
);
|
1236
|
+
const returnId = origin || id === "create" ? void 0 : id;
|
1237
|
+
return {
|
1238
|
+
collectionType,
|
1239
|
+
model: slug,
|
1240
|
+
id: returnId,
|
1241
|
+
...document
|
1242
|
+
};
|
1243
|
+
};
|
1244
|
+
const useContentManagerContext = () => {
|
1245
|
+
const {
|
1246
|
+
collectionType,
|
1247
|
+
model,
|
1248
|
+
id,
|
1249
|
+
components,
|
1250
|
+
isLoading: isLoadingDoc,
|
1251
|
+
schema,
|
1252
|
+
schemas
|
1253
|
+
} = useDoc();
|
1254
|
+
const layout = useDocumentLayout(model);
|
1255
|
+
const form = strapiAdmin.useForm("useContentManagerContext", (state) => state);
|
1256
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1257
|
+
const slug = model;
|
1258
|
+
const isCreatingEntry = id === "create";
|
1259
|
+
useContentTypeSchema();
|
1260
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1261
|
+
const error = layout.error;
|
1262
|
+
return {
|
1263
|
+
error,
|
1264
|
+
isLoading,
|
1265
|
+
// Base metadata
|
1266
|
+
model,
|
1267
|
+
collectionType,
|
1268
|
+
id,
|
1269
|
+
slug,
|
1270
|
+
isCreatingEntry,
|
1271
|
+
isSingleType,
|
1272
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1273
|
+
// All schema infos
|
1274
|
+
components,
|
1275
|
+
contentType: schema,
|
1276
|
+
contentTypes: schemas,
|
1277
|
+
// Form state
|
1278
|
+
form,
|
1279
|
+
// layout infos
|
1280
|
+
layout
|
1281
|
+
};
|
1282
|
+
};
|
1283
|
+
const prefixPluginTranslations = (trad, pluginId) => {
|
848
1284
|
return Object.keys(trad).reduce((acc, current) => {
|
849
1285
|
acc[`${pluginId}.${current}`] = trad[current];
|
850
1286
|
return acc;
|
@@ -860,6 +1296,8 @@ const useDocumentActions = () => {
|
|
860
1296
|
const { formatMessage } = reactIntl.useIntl();
|
861
1297
|
const { trackUsage } = strapiAdmin.useTracking();
|
862
1298
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1299
|
+
const navigate = reactRouterDom.useNavigate();
|
1300
|
+
const setCurrentStep = strapiAdmin.useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
863
1301
|
const [deleteDocument] = useDeleteDocumentMutation();
|
864
1302
|
const _delete = React__namespace.useCallback(
|
865
1303
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1174,6 +1612,7 @@ const useDocumentActions = () => {
|
|
1174
1612
|
defaultMessage: "Saved document"
|
1175
1613
|
})
|
1176
1614
|
});
|
1615
|
+
setCurrentStep("contentManager.success");
|
1177
1616
|
return res.data;
|
1178
1617
|
} catch (err) {
|
1179
1618
|
toggleNotification({
|
@@ -1195,7 +1634,6 @@ const useDocumentActions = () => {
|
|
1195
1634
|
sourceId
|
1196
1635
|
});
|
1197
1636
|
if ("error" in res) {
|
1198
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1199
1637
|
return { error: res.error };
|
1200
1638
|
}
|
1201
1639
|
toggleNotification({
|
@@ -1214,7 +1652,7 @@ const useDocumentActions = () => {
|
|
1214
1652
|
throw err;
|
1215
1653
|
}
|
1216
1654
|
},
|
1217
|
-
[autoCloneDocument,
|
1655
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1218
1656
|
);
|
1219
1657
|
const [cloneDocument] = useCloneDocumentMutation();
|
1220
1658
|
const clone = React__namespace.useCallback(
|
@@ -1240,6 +1678,7 @@ const useDocumentActions = () => {
|
|
1240
1678
|
defaultMessage: "Cloned document"
|
1241
1679
|
})
|
1242
1680
|
});
|
1681
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1243
1682
|
return res.data;
|
1244
1683
|
} catch (err) {
|
1245
1684
|
toggleNotification({
|
@@ -1250,7 +1689,7 @@ const useDocumentActions = () => {
|
|
1250
1689
|
throw err;
|
1251
1690
|
}
|
1252
1691
|
},
|
1253
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1692
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1254
1693
|
);
|
1255
1694
|
const [getDoc] = useLazyGetDocumentQuery();
|
1256
1695
|
const getDocument = React__namespace.useCallback(
|
@@ -1275,10 +1714,10 @@ const useDocumentActions = () => {
|
|
1275
1714
|
update
|
1276
1715
|
};
|
1277
1716
|
};
|
1278
|
-
const ProtectedHistoryPage =
|
1279
|
-
() => Promise.resolve().then(() => require("./History-
|
1717
|
+
const ProtectedHistoryPage = React__namespace.lazy(
|
1718
|
+
() => Promise.resolve().then(() => require("./History-DrDJv698.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1280
1719
|
);
|
1281
|
-
const routes$
|
1720
|
+
const routes$2 = [
|
1282
1721
|
{
|
1283
1722
|
path: ":collectionType/:slug/:id/history",
|
1284
1723
|
Component: ProtectedHistoryPage
|
@@ -1288,32 +1727,45 @@ const routes$1 = [
|
|
1288
1727
|
Component: ProtectedHistoryPage
|
1289
1728
|
}
|
1290
1729
|
];
|
1730
|
+
const ProtectedPreviewPage = React__namespace.lazy(
|
1731
|
+
() => Promise.resolve().then(() => require("./Preview-VOJ8RuQp.js")).then((mod) => ({ default: mod.ProtectedPreviewPage }))
|
1732
|
+
);
|
1733
|
+
const routes$1 = [
|
1734
|
+
{
|
1735
|
+
path: ":collectionType/:slug/:id/preview",
|
1736
|
+
Component: ProtectedPreviewPage
|
1737
|
+
},
|
1738
|
+
{
|
1739
|
+
path: ":collectionType/:slug/preview",
|
1740
|
+
Component: ProtectedPreviewPage
|
1741
|
+
}
|
1742
|
+
];
|
1291
1743
|
const ProtectedEditViewPage = React.lazy(
|
1292
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1744
|
+
() => Promise.resolve().then(() => require("./EditViewPage-CDyTC6aU.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1293
1745
|
);
|
1294
1746
|
const ProtectedListViewPage = React.lazy(
|
1295
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1747
|
+
() => Promise.resolve().then(() => require("./ListViewPage-DTM2uO_S.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1296
1748
|
);
|
1297
1749
|
const ProtectedListConfiguration = React.lazy(
|
1298
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1750
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-zurIlUZ7.js")).then((mod) => ({
|
1299
1751
|
default: mod.ProtectedListConfiguration
|
1300
1752
|
}))
|
1301
1753
|
);
|
1302
1754
|
const ProtectedEditConfigurationPage = React.lazy(
|
1303
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1755
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-CF3lxOy2.js")).then((mod) => ({
|
1304
1756
|
default: mod.ProtectedEditConfigurationPage
|
1305
1757
|
}))
|
1306
1758
|
);
|
1307
1759
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1308
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-
|
1760
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-CJPoOvy3.js")).then((mod) => ({
|
1309
1761
|
default: mod.ProtectedComponentConfigurationPage
|
1310
1762
|
}))
|
1311
1763
|
);
|
1312
1764
|
const NoPermissions = React.lazy(
|
1313
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1765
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-DLzkS4Hy.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1314
1766
|
);
|
1315
1767
|
const NoContentType = React.lazy(
|
1316
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1768
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-BuZlNroO.js")).then((mod) => ({ default: mod.NoContentType }))
|
1317
1769
|
);
|
1318
1770
|
const CollectionTypePages = () => {
|
1319
1771
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1325,7 +1777,7 @@ const CollectionTypePages = () => {
|
|
1325
1777
|
const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
|
1326
1778
|
const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
|
1327
1779
|
const LIST_RELATIVE_PATH = ":collectionType/:slug";
|
1328
|
-
const LIST_PATH = `/content-manager
|
1780
|
+
const LIST_PATH = `/content-manager/collection-types/:slug`;
|
1329
1781
|
const routes = [
|
1330
1782
|
{
|
1331
1783
|
path: LIST_RELATIVE_PATH,
|
@@ -1359,6 +1811,7 @@ const routes = [
|
|
1359
1811
|
path: "no-content-types",
|
1360
1812
|
Component: NoContentType
|
1361
1813
|
},
|
1814
|
+
...routes$2,
|
1362
1815
|
...routes$1
|
1363
1816
|
];
|
1364
1817
|
const DocumentActions = ({ actions: actions2 }) => {
|
@@ -1427,12 +1880,14 @@ const DocumentActionButton = (action) => {
|
|
1427
1880
|
/* @__PURE__ */ jsxRuntime.jsx(
|
1428
1881
|
designSystem.Button,
|
1429
1882
|
{
|
1430
|
-
flex:
|
1883
|
+
flex: "auto",
|
1431
1884
|
startIcon: action.icon,
|
1432
1885
|
disabled: action.disabled,
|
1433
1886
|
onClick: handleClick(action),
|
1434
1887
|
justifyContent: "center",
|
1435
1888
|
variant: action.variant || "default",
|
1889
|
+
paddingTop: "7px",
|
1890
|
+
paddingBottom: "7px",
|
1436
1891
|
children: action.label
|
1437
1892
|
}
|
1438
1893
|
),
|
@@ -1455,6 +1910,11 @@ const DocumentActionButton = (action) => {
|
|
1455
1910
|
) : null
|
1456
1911
|
] });
|
1457
1912
|
};
|
1913
|
+
const MenuItem = styledComponents.styled(designSystem.Menu.Item)`
|
1914
|
+
&:hover {
|
1915
|
+
background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
|
1916
|
+
}
|
1917
|
+
`;
|
1458
1918
|
const DocumentActionsMenu = ({
|
1459
1919
|
actions: actions2,
|
1460
1920
|
children,
|
@@ -1497,9 +1957,9 @@ const DocumentActionsMenu = ({
|
|
1497
1957
|
disabled: isDisabled,
|
1498
1958
|
size: "S",
|
1499
1959
|
endIcon: null,
|
1500
|
-
paddingTop: "
|
1501
|
-
paddingLeft: "
|
1502
|
-
paddingRight: "
|
1960
|
+
paddingTop: "4px",
|
1961
|
+
paddingLeft: "7px",
|
1962
|
+
paddingRight: "7px",
|
1503
1963
|
variant,
|
1504
1964
|
children: [
|
1505
1965
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
|
@@ -1510,36 +1970,35 @@ const DocumentActionsMenu = ({
|
|
1510
1970
|
]
|
1511
1971
|
}
|
1512
1972
|
),
|
1513
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, {
|
1973
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1514
1974
|
actions2.map((action) => {
|
1515
1975
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
1516
|
-
|
1976
|
+
MenuItem,
|
1517
1977
|
{
|
1518
1978
|
disabled: action.disabled,
|
1519
1979
|
onSelect: handleClick(action),
|
1520
1980
|
display: "block",
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
] })
|
1981
|
+
isVariantDanger: action.variant === "danger",
|
1982
|
+
isDisabled: action.disabled,
|
1983
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
1984
|
+
designSystem.Flex,
|
1985
|
+
{
|
1986
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1987
|
+
gap: 2,
|
1988
|
+
tag: "span",
|
1989
|
+
children: [
|
1990
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
1991
|
+
designSystem.Flex,
|
1992
|
+
{
|
1993
|
+
tag: "span",
|
1994
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1995
|
+
children: action.icon
|
1996
|
+
}
|
1997
|
+
),
|
1998
|
+
action.label
|
1999
|
+
]
|
2000
|
+
}
|
2001
|
+
) })
|
1543
2002
|
},
|
1544
2003
|
action.id
|
1545
2004
|
);
|
@@ -1619,11 +2078,11 @@ const DocumentActionConfirmDialog = ({
|
|
1619
2078
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
1620
2079
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
|
1621
2080
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
1622
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({
|
2081
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
1623
2082
|
id: "app.components.Button.cancel",
|
1624
2083
|
defaultMessage: "Cancel"
|
1625
2084
|
}) }) }),
|
1626
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2085
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1627
2086
|
id: "app.components.Button.confirm",
|
1628
2087
|
defaultMessage: "Confirm"
|
1629
2088
|
}) })
|
@@ -1646,10 +2105,22 @@ const DocumentActionModal = ({
|
|
1646
2105
|
};
|
1647
2106
|
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
|
1648
2107
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: title }) }),
|
1649
|
-
|
1650
|
-
|
2108
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: Content }),
|
2109
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
|
1651
2110
|
] }) });
|
1652
2111
|
};
|
2112
|
+
const transformData = (data) => {
|
2113
|
+
if (Array.isArray(data)) {
|
2114
|
+
return data.map(transformData);
|
2115
|
+
}
|
2116
|
+
if (typeof data === "object" && data !== null) {
|
2117
|
+
if ("apiData" in data) {
|
2118
|
+
return data.apiData;
|
2119
|
+
}
|
2120
|
+
return mapValues__default.default(transformData)(data);
|
2121
|
+
}
|
2122
|
+
return data;
|
2123
|
+
};
|
1653
2124
|
const PublishAction$1 = ({
|
1654
2125
|
activeTab,
|
1655
2126
|
documentId,
|
@@ -1662,12 +2133,11 @@ const PublishAction$1 = ({
|
|
1662
2133
|
const navigate = reactRouterDom.useNavigate();
|
1663
2134
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1664
2135
|
const { _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
|
2136
|
+
const isListView = reactRouterDom.useMatch(LIST_PATH) !== null;
|
1665
2137
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2138
|
+
const { id } = reactRouterDom.useParams();
|
1666
2139
|
const { formatMessage } = reactIntl.useIntl();
|
1667
|
-
const { canPublish
|
1668
|
-
"PublishAction",
|
1669
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1670
|
-
);
|
2140
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1671
2141
|
const { publish } = useDocumentActions();
|
1672
2142
|
const [
|
1673
2143
|
countDraftRelations,
|
@@ -1719,24 +2189,25 @@ const PublishAction$1 = ({
|
|
1719
2189
|
}
|
1720
2190
|
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
1721
2191
|
React__namespace.useEffect(() => {
|
1722
|
-
if (documentId) {
|
1723
|
-
|
1724
|
-
const { data, error } = await countDraftRelations({
|
1725
|
-
collectionType,
|
1726
|
-
model,
|
1727
|
-
documentId,
|
1728
|
-
params
|
1729
|
-
});
|
1730
|
-
if (error) {
|
1731
|
-
throw error;
|
1732
|
-
}
|
1733
|
-
if (data) {
|
1734
|
-
setServerCountOfDraftRelations(data.data);
|
1735
|
-
}
|
1736
|
-
};
|
1737
|
-
fetchDraftRelationsCount();
|
2192
|
+
if (!document || !document.documentId || isListView) {
|
2193
|
+
return;
|
1738
2194
|
}
|
1739
|
-
|
2195
|
+
const fetchDraftRelationsCount = async () => {
|
2196
|
+
const { data, error } = await countDraftRelations({
|
2197
|
+
collectionType,
|
2198
|
+
model,
|
2199
|
+
documentId,
|
2200
|
+
params
|
2201
|
+
});
|
2202
|
+
if (error) {
|
2203
|
+
throw error;
|
2204
|
+
}
|
2205
|
+
if (data) {
|
2206
|
+
setServerCountOfDraftRelations(data.data);
|
2207
|
+
}
|
2208
|
+
};
|
2209
|
+
fetchDraftRelationsCount();
|
2210
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
1740
2211
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1741
2212
|
if (!schema?.options?.draftAndPublish) {
|
1742
2213
|
return null;
|
@@ -1744,7 +2215,9 @@ const PublishAction$1 = ({
|
|
1744
2215
|
const performPublish = async () => {
|
1745
2216
|
setSubmitting(true);
|
1746
2217
|
try {
|
1747
|
-
const { errors } = await validate(
|
2218
|
+
const { errors } = await validate(true, {
|
2219
|
+
status: "published"
|
2220
|
+
});
|
1748
2221
|
if (errors) {
|
1749
2222
|
toggleNotification({
|
1750
2223
|
type: "danger",
|
@@ -1762,13 +2235,15 @@ const PublishAction$1 = ({
|
|
1762
2235
|
documentId,
|
1763
2236
|
params
|
1764
2237
|
},
|
1765
|
-
formValues
|
2238
|
+
transformData(formValues)
|
1766
2239
|
);
|
1767
2240
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1771
|
-
|
2241
|
+
if (id === "create") {
|
2242
|
+
navigate({
|
2243
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2244
|
+
search: rawQuery
|
2245
|
+
});
|
2246
|
+
}
|
1772
2247
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1773
2248
|
setErrors(formatValidationErrors(res.error));
|
1774
2249
|
}
|
@@ -1777,7 +2252,8 @@ const PublishAction$1 = ({
|
|
1777
2252
|
}
|
1778
2253
|
};
|
1779
2254
|
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
1780
|
-
const
|
2255
|
+
const enableDraftRelationsCount = false;
|
2256
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1781
2257
|
return {
|
1782
2258
|
/**
|
1783
2259
|
* Disabled when:
|
@@ -1787,18 +2263,13 @@ const PublishAction$1 = ({
|
|
1787
2263
|
* - the document is already published & not modified
|
1788
2264
|
* - the document is being created & not modified
|
1789
2265
|
* - the user doesn't have the permission to publish
|
1790
|
-
* - the user doesn't have the permission to create a new document
|
1791
|
-
* - the user doesn't have the permission to update the document
|
1792
2266
|
*/
|
1793
|
-
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
2267
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1794
2268
|
label: formatMessage({
|
1795
2269
|
id: "app.utils.publish",
|
1796
2270
|
defaultMessage: "Publish"
|
1797
2271
|
}),
|
1798
2272
|
onClick: async () => {
|
1799
|
-
if (hasDraftRelations) {
|
1800
|
-
return;
|
1801
|
-
}
|
1802
2273
|
await performPublish();
|
1803
2274
|
},
|
1804
2275
|
dialog: hasDraftRelations ? {
|
@@ -1825,6 +2296,7 @@ const PublishAction$1 = ({
|
|
1825
2296
|
};
|
1826
2297
|
};
|
1827
2298
|
PublishAction$1.type = "publish";
|
2299
|
+
PublishAction$1.position = "panel";
|
1828
2300
|
const UpdateAction = ({
|
1829
2301
|
activeTab,
|
1830
2302
|
documentId,
|
@@ -1837,10 +2309,6 @@ const UpdateAction = ({
|
|
1837
2309
|
const cloneMatch = reactRouterDom.useMatch(CLONE_PATH);
|
1838
2310
|
const isCloning = cloneMatch !== null;
|
1839
2311
|
const { formatMessage } = reactIntl.useIntl();
|
1840
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1841
|
-
canCreate: canCreate2,
|
1842
|
-
canUpdate: canUpdate2
|
1843
|
-
}));
|
1844
2312
|
const { create, update, clone } = useDocumentActions();
|
1845
2313
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1846
2314
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
@@ -1851,93 +2319,134 @@ const UpdateAction = ({
|
|
1851
2319
|
const validate = strapiAdmin.useForm("UpdateAction", (state) => state.validate);
|
1852
2320
|
const setErrors = strapiAdmin.useForm("UpdateAction", (state) => state.setErrors);
|
1853
2321
|
const resetForm = strapiAdmin.useForm("PublishAction", ({ resetForm: resetForm2 }) => resetForm2);
|
1854
|
-
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
1859
|
-
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1866
|
-
|
1867
|
-
|
1868
|
-
|
1869
|
-
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1875
|
-
|
1876
|
-
|
1877
|
-
|
1878
|
-
|
1879
|
-
}
|
1880
|
-
|
1881
|
-
|
1882
|
-
if (
|
1883
|
-
|
2322
|
+
const handleUpdate = React__namespace.useCallback(async () => {
|
2323
|
+
setSubmitting(true);
|
2324
|
+
try {
|
2325
|
+
if (!modified) {
|
2326
|
+
return;
|
2327
|
+
}
|
2328
|
+
const { errors } = await validate(true, {
|
2329
|
+
status: "draft"
|
2330
|
+
});
|
2331
|
+
if (errors) {
|
2332
|
+
toggleNotification({
|
2333
|
+
type: "danger",
|
2334
|
+
message: formatMessage({
|
2335
|
+
id: "content-manager.validation.error",
|
2336
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2337
|
+
})
|
2338
|
+
});
|
2339
|
+
return;
|
2340
|
+
}
|
2341
|
+
if (isCloning) {
|
2342
|
+
const res = await clone(
|
2343
|
+
{
|
2344
|
+
model,
|
2345
|
+
documentId: cloneMatch.params.origin,
|
2346
|
+
params
|
2347
|
+
},
|
2348
|
+
transformData(document)
|
2349
|
+
);
|
2350
|
+
if ("data" in res) {
|
2351
|
+
navigate(
|
1884
2352
|
{
|
1885
|
-
|
1886
|
-
documentId: cloneMatch.params.origin,
|
1887
|
-
params
|
1888
|
-
},
|
1889
|
-
document
|
1890
|
-
);
|
1891
|
-
if ("data" in res) {
|
1892
|
-
navigate({
|
1893
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2353
|
+
pathname: `../${res.data.documentId}`,
|
1894
2354
|
search: rawQuery
|
1895
|
-
});
|
1896
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1897
|
-
setErrors(formatValidationErrors(res.error));
|
1898
|
-
}
|
1899
|
-
} else if (documentId || collectionType === SINGLE_TYPES) {
|
1900
|
-
const res = await update(
|
1901
|
-
{
|
1902
|
-
collectionType,
|
1903
|
-
model,
|
1904
|
-
documentId,
|
1905
|
-
params
|
1906
2355
|
},
|
1907
|
-
|
2356
|
+
{ relative: "path" }
|
1908
2357
|
);
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
1913
|
-
|
2358
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2359
|
+
setErrors(formatValidationErrors(res.error));
|
2360
|
+
}
|
2361
|
+
} else if (documentId || collectionType === SINGLE_TYPES) {
|
2362
|
+
const res = await update(
|
2363
|
+
{
|
2364
|
+
collectionType,
|
2365
|
+
model,
|
2366
|
+
documentId,
|
2367
|
+
params
|
2368
|
+
},
|
2369
|
+
transformData(document)
|
2370
|
+
);
|
2371
|
+
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2372
|
+
setErrors(formatValidationErrors(res.error));
|
1914
2373
|
} else {
|
1915
|
-
|
2374
|
+
resetForm();
|
2375
|
+
}
|
2376
|
+
} else {
|
2377
|
+
const res = await create(
|
2378
|
+
{
|
2379
|
+
model,
|
2380
|
+
params
|
2381
|
+
},
|
2382
|
+
transformData(document)
|
2383
|
+
);
|
2384
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2385
|
+
navigate(
|
1916
2386
|
{
|
1917
|
-
|
1918
|
-
|
2387
|
+
pathname: `../${res.data.documentId}`,
|
2388
|
+
search: rawQuery
|
1919
2389
|
},
|
1920
|
-
|
2390
|
+
{ replace: true, relative: "path" }
|
1921
2391
|
);
|
1922
|
-
|
1923
|
-
|
1924
|
-
{
|
1925
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1926
|
-
search: rawQuery
|
1927
|
-
},
|
1928
|
-
{ replace: true }
|
1929
|
-
);
|
1930
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1931
|
-
setErrors(formatValidationErrors(res.error));
|
1932
|
-
}
|
2392
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2393
|
+
setErrors(formatValidationErrors(res.error));
|
1933
2394
|
}
|
1934
|
-
} finally {
|
1935
|
-
setSubmitting(false);
|
1936
2395
|
}
|
2396
|
+
} finally {
|
2397
|
+
setSubmitting(false);
|
1937
2398
|
}
|
2399
|
+
}, [
|
2400
|
+
clone,
|
2401
|
+
cloneMatch?.params.origin,
|
2402
|
+
collectionType,
|
2403
|
+
create,
|
2404
|
+
document,
|
2405
|
+
documentId,
|
2406
|
+
formatMessage,
|
2407
|
+
formatValidationErrors,
|
2408
|
+
isCloning,
|
2409
|
+
model,
|
2410
|
+
modified,
|
2411
|
+
navigate,
|
2412
|
+
params,
|
2413
|
+
rawQuery,
|
2414
|
+
resetForm,
|
2415
|
+
setErrors,
|
2416
|
+
setSubmitting,
|
2417
|
+
toggleNotification,
|
2418
|
+
update,
|
2419
|
+
validate
|
2420
|
+
]);
|
2421
|
+
React__namespace.useEffect(() => {
|
2422
|
+
const handleKeyDown = (e) => {
|
2423
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
2424
|
+
e.preventDefault();
|
2425
|
+
handleUpdate();
|
2426
|
+
}
|
2427
|
+
};
|
2428
|
+
window.addEventListener("keydown", handleKeyDown);
|
2429
|
+
return () => {
|
2430
|
+
window.removeEventListener("keydown", handleKeyDown);
|
2431
|
+
};
|
2432
|
+
}, [handleUpdate]);
|
2433
|
+
return {
|
2434
|
+
/**
|
2435
|
+
* Disabled when:
|
2436
|
+
* - the form is submitting
|
2437
|
+
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
2438
|
+
* - the active tab is the published tab
|
2439
|
+
*/
|
2440
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
2441
|
+
label: formatMessage({
|
2442
|
+
id: "global.save",
|
2443
|
+
defaultMessage: "Save"
|
2444
|
+
}),
|
2445
|
+
onClick: handleUpdate
|
1938
2446
|
};
|
1939
2447
|
};
|
1940
2448
|
UpdateAction.type = "update";
|
2449
|
+
UpdateAction.position = "panel";
|
1941
2450
|
const UNPUBLISH_DRAFT_OPTIONS = {
|
1942
2451
|
KEEP: "keep",
|
1943
2452
|
DISCARD: "discard"
|
@@ -1970,7 +2479,7 @@ const UnpublishAction$1 = ({
|
|
1970
2479
|
id: "app.utils.unpublish",
|
1971
2480
|
defaultMessage: "Unpublish"
|
1972
2481
|
}),
|
1973
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2482
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
1974
2483
|
onClick: async () => {
|
1975
2484
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1976
2485
|
if (!documentId) {
|
@@ -2060,6 +2569,7 @@ const UnpublishAction$1 = ({
|
|
2060
2569
|
};
|
2061
2570
|
};
|
2062
2571
|
UnpublishAction$1.type = "unpublish";
|
2572
|
+
UnpublishAction$1.position = "panel";
|
2063
2573
|
const DiscardAction = ({
|
2064
2574
|
activeTab,
|
2065
2575
|
documentId,
|
@@ -2082,7 +2592,7 @@ const DiscardAction = ({
|
|
2082
2592
|
id: "content-manager.actions.discard.label",
|
2083
2593
|
defaultMessage: "Discard changes"
|
2084
2594
|
}),
|
2085
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2595
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
2086
2596
|
position: ["panel", "table-row"],
|
2087
2597
|
variant: "danger",
|
2088
2598
|
dialog: {
|
@@ -2110,11 +2620,7 @@ const DiscardAction = ({
|
|
2110
2620
|
};
|
2111
2621
|
};
|
2112
2622
|
DiscardAction.type = "discard";
|
2113
|
-
|
2114
|
-
path {
|
2115
|
-
fill: currentColor;
|
2116
|
-
}
|
2117
|
-
`;
|
2623
|
+
DiscardAction.position = "panel";
|
2118
2624
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2119
2625
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2120
2626
|
const RelativeTime = React__namespace.forwardRef(
|
@@ -2127,7 +2633,7 @@ const RelativeTime = React__namespace.forwardRef(
|
|
2127
2633
|
});
|
2128
2634
|
const unit = intervals.find((intervalUnit) => {
|
2129
2635
|
return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
|
2130
|
-
});
|
2636
|
+
}) ?? "seconds";
|
2131
2637
|
const relativeTime = dateFns.isPast(timestamp) ? -interval[unit] : interval[unit];
|
2132
2638
|
const customInterval = customIntervals.find(
|
2133
2639
|
(custom) => interval[custom.unit] < custom.threshold
|
@@ -2161,19 +2667,29 @@ const getDisplayName = ({
|
|
2161
2667
|
return email ?? "";
|
2162
2668
|
};
|
2163
2669
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2164
|
-
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2165
|
-
const statusVariant = status === "draft" ? "
|
2166
|
-
|
2670
|
+
const DocumentStatus = ({ status = "draft", size = "S", ...restProps }) => {
|
2671
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2672
|
+
const { formatMessage } = reactIntl.useIntl();
|
2673
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { ...restProps, size, variant: statusVariant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: formatMessage({
|
2674
|
+
id: `content-manager.containers.List.${status}`,
|
2675
|
+
defaultMessage: capitalise(status)
|
2676
|
+
}) }) });
|
2167
2677
|
};
|
2168
2678
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2169
2679
|
const { formatMessage } = reactIntl.useIntl();
|
2170
2680
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2681
|
+
const params = reactRouterDom.useParams();
|
2171
2682
|
const title = isCreating ? formatMessage({
|
2172
2683
|
id: "content-manager.containers.edit.title.new",
|
2173
2684
|
defaultMessage: "Create an entry"
|
2174
2685
|
}) : documentTitle;
|
2175
2686
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2176
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
2687
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2688
|
+
strapiAdmin.BackButton,
|
2689
|
+
{
|
2690
|
+
fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
|
2691
|
+
}
|
2692
|
+
),
|
2177
2693
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2178
2694
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2179
2695
|
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
@@ -2224,7 +2740,7 @@ const HeaderToolbar = () => {
|
|
2224
2740
|
meta: isCloning ? void 0 : meta,
|
2225
2741
|
collectionType
|
2226
2742
|
},
|
2227
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2743
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("header"),
|
2228
2744
|
children: (actions2) => {
|
2229
2745
|
const headerActions = actions2.filter((action) => {
|
2230
2746
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -2261,12 +2777,12 @@ const Information = ({ activeTab }) => {
|
|
2261
2777
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2262
2778
|
label: formatMessage({
|
2263
2779
|
id: "content-manager.containers.edit.information.last-published.label",
|
2264
|
-
defaultMessage: "
|
2780
|
+
defaultMessage: "Published"
|
2265
2781
|
}),
|
2266
2782
|
value: formatMessage(
|
2267
2783
|
{
|
2268
2784
|
id: "content-manager.containers.edit.information.last-published.value",
|
2269
|
-
defaultMessage: `
|
2785
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2270
2786
|
},
|
2271
2787
|
{
|
2272
2788
|
time: /* @__PURE__ */ jsxRuntime.jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2279,12 +2795,12 @@ const Information = ({ activeTab }) => {
|
|
2279
2795
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2280
2796
|
label: formatMessage({
|
2281
2797
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2282
|
-
defaultMessage: "
|
2798
|
+
defaultMessage: "Updated"
|
2283
2799
|
}),
|
2284
2800
|
value: formatMessage(
|
2285
2801
|
{
|
2286
2802
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2287
|
-
defaultMessage: `
|
2803
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2288
2804
|
},
|
2289
2805
|
{
|
2290
2806
|
time: /* @__PURE__ */ jsxRuntime.jsx(
|
@@ -2302,12 +2818,12 @@ const Information = ({ activeTab }) => {
|
|
2302
2818
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2303
2819
|
label: formatMessage({
|
2304
2820
|
id: "content-manager.containers.edit.information.document.label",
|
2305
|
-
defaultMessage: "
|
2821
|
+
defaultMessage: "Created"
|
2306
2822
|
}),
|
2307
2823
|
value: formatMessage(
|
2308
2824
|
{
|
2309
2825
|
id: "content-manager.containers.edit.information.document.value",
|
2310
|
-
defaultMessage: `
|
2826
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2311
2827
|
},
|
2312
2828
|
{
|
2313
2829
|
time: /* @__PURE__ */ jsxRuntime.jsx(
|
@@ -2345,25 +2861,77 @@ const Information = ({ activeTab }) => {
|
|
2345
2861
|
);
|
2346
2862
|
};
|
2347
2863
|
const HeaderActions = ({ actions: actions2 }) => {
|
2348
|
-
|
2349
|
-
|
2864
|
+
const [dialogId, setDialogId] = React__namespace.useState(null);
|
2865
|
+
const handleClick = (action) => async (e) => {
|
2866
|
+
if (!("options" in action)) {
|
2867
|
+
const { onClick = () => false, dialog, id } = action;
|
2868
|
+
const muteDialog = await onClick(e);
|
2869
|
+
if (dialog && !muteDialog) {
|
2870
|
+
e.preventDefault();
|
2871
|
+
setDialogId(id);
|
2872
|
+
}
|
2873
|
+
}
|
2874
|
+
};
|
2875
|
+
const handleClose = () => {
|
2876
|
+
setDialogId(null);
|
2877
|
+
};
|
2878
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, children: actions2.map((action) => {
|
2879
|
+
if (action.options) {
|
2350
2880
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
2351
2881
|
designSystem.SingleSelect,
|
2352
2882
|
{
|
2353
2883
|
size: "S",
|
2354
|
-
disabled: action.disabled,
|
2355
|
-
"aria-label": action.label,
|
2356
2884
|
onChange: action.onSelect,
|
2357
|
-
|
2885
|
+
"aria-label": action.label,
|
2886
|
+
...action,
|
2358
2887
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { ...option, children: label }, option.value))
|
2359
2888
|
},
|
2360
2889
|
action.id
|
2361
2890
|
);
|
2362
2891
|
} else {
|
2363
|
-
|
2892
|
+
if (action.type === "icon") {
|
2893
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
|
2894
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2895
|
+
designSystem.IconButton,
|
2896
|
+
{
|
2897
|
+
disabled: action.disabled,
|
2898
|
+
label: action.label,
|
2899
|
+
size: "S",
|
2900
|
+
onClick: handleClick(action),
|
2901
|
+
children: action.icon
|
2902
|
+
}
|
2903
|
+
),
|
2904
|
+
action.dialog ? /* @__PURE__ */ jsxRuntime.jsx(
|
2905
|
+
HeaderActionDialog,
|
2906
|
+
{
|
2907
|
+
...action.dialog,
|
2908
|
+
isOpen: dialogId === action.id,
|
2909
|
+
onClose: handleClose
|
2910
|
+
}
|
2911
|
+
) : null
|
2912
|
+
] }, action.id);
|
2913
|
+
}
|
2364
2914
|
}
|
2365
2915
|
}) });
|
2366
2916
|
};
|
2917
|
+
const HeaderActionDialog = ({
|
2918
|
+
onClose,
|
2919
|
+
onCancel,
|
2920
|
+
title,
|
2921
|
+
content: Content,
|
2922
|
+
isOpen
|
2923
|
+
}) => {
|
2924
|
+
const handleClose = async () => {
|
2925
|
+
if (onCancel) {
|
2926
|
+
await onCancel();
|
2927
|
+
}
|
2928
|
+
onClose();
|
2929
|
+
};
|
2930
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2931
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
2932
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : Content
|
2933
|
+
] }) });
|
2934
|
+
};
|
2367
2935
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2368
2936
|
const navigate = reactRouterDom.useNavigate();
|
2369
2937
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2380,6 +2948,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2380
2948
|
};
|
2381
2949
|
};
|
2382
2950
|
ConfigureTheViewAction.type = "configure-the-view";
|
2951
|
+
ConfigureTheViewAction.position = "header";
|
2383
2952
|
const EditTheModelAction = ({ model }) => {
|
2384
2953
|
const navigate = reactRouterDom.useNavigate();
|
2385
2954
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2396,6 +2965,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2396
2965
|
};
|
2397
2966
|
};
|
2398
2967
|
EditTheModelAction.type = "edit-the-model";
|
2968
|
+
EditTheModelAction.position = "header";
|
2399
2969
|
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2400
2970
|
const navigate = reactRouterDom.useNavigate();
|
2401
2971
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2404,12 +2974,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2404
2974
|
const { delete: deleteAction } = useDocumentActions();
|
2405
2975
|
const { toggleNotification } = strapiAdmin.useNotification();
|
2406
2976
|
const setSubmitting = strapiAdmin.useForm("DeleteAction", (state) => state.setSubmitting);
|
2977
|
+
const isLocalized = document?.locale != null;
|
2407
2978
|
return {
|
2408
2979
|
disabled: !canDelete || !document,
|
2409
|
-
label: formatMessage(
|
2410
|
-
|
2411
|
-
|
2412
|
-
|
2980
|
+
label: formatMessage(
|
2981
|
+
{
|
2982
|
+
id: "content-manager.actions.delete.label",
|
2983
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2984
|
+
},
|
2985
|
+
{ isLocalized }
|
2986
|
+
),
|
2413
2987
|
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2414
2988
|
dialog: {
|
2415
2989
|
type: "dialog",
|
@@ -2451,417 +3025,116 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2451
3025
|
}
|
2452
3026
|
});
|
2453
3027
|
if (!("error" in res)) {
|
2454
|
-
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
2455
|
-
}
|
2456
|
-
} finally {
|
2457
|
-
if (!listViewPathMatch) {
|
2458
|
-
setSubmitting(false);
|
2459
|
-
}
|
2460
|
-
}
|
2461
|
-
}
|
2462
|
-
},
|
2463
|
-
variant: "danger",
|
2464
|
-
position: ["header", "table-row"]
|
2465
|
-
};
|
2466
|
-
};
|
2467
|
-
DeleteAction$1.type = "delete";
|
2468
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2469
|
-
const Panels = () => {
|
2470
|
-
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2471
|
-
const [
|
2472
|
-
{
|
2473
|
-
query: { status }
|
2474
|
-
}
|
2475
|
-
] = strapiAdmin.useQueryParams({
|
2476
|
-
status: "draft"
|
2477
|
-
});
|
2478
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2479
|
-
const plugins = strapiAdmin.useStrapiApp("Panels", (state) => state.plugins);
|
2480
|
-
const props = {
|
2481
|
-
activeTab: status,
|
2482
|
-
model,
|
2483
|
-
documentId: id,
|
2484
|
-
document: isCloning ? void 0 : document,
|
2485
|
-
meta: isCloning ? void 0 : meta,
|
2486
|
-
collectionType
|
2487
|
-
};
|
2488
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
2489
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2490
|
-
{
|
2491
|
-
props,
|
2492
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2493
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsxRuntime.jsx(Panel, { ...description, children: content }, id2))
|
2494
|
-
}
|
2495
|
-
) });
|
2496
|
-
};
|
2497
|
-
const ActionsPanel = () => {
|
2498
|
-
const { formatMessage } = reactIntl.useIntl();
|
2499
|
-
return {
|
2500
|
-
title: formatMessage({
|
2501
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2502
|
-
defaultMessage: "Document"
|
2503
|
-
}),
|
2504
|
-
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2505
|
-
};
|
2506
|
-
};
|
2507
|
-
ActionsPanel.type = "actions";
|
2508
|
-
const ActionsPanelContent = () => {
|
2509
|
-
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2510
|
-
const [
|
2511
|
-
{
|
2512
|
-
query: { status = "draft" }
|
2513
|
-
}
|
2514
|
-
] = strapiAdmin.useQueryParams();
|
2515
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2516
|
-
const plugins = strapiAdmin.useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2517
|
-
const props = {
|
2518
|
-
activeTab: status,
|
2519
|
-
model,
|
2520
|
-
documentId: id,
|
2521
|
-
document: isCloning ? void 0 : document,
|
2522
|
-
meta: isCloning ? void 0 : meta,
|
2523
|
-
collectionType
|
2524
|
-
};
|
2525
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2526
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
2527
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2528
|
-
{
|
2529
|
-
props,
|
2530
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2531
|
-
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
2532
|
-
}
|
2533
|
-
),
|
2534
|
-
/* @__PURE__ */ jsxRuntime.jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2535
|
-
] });
|
2536
|
-
};
|
2537
|
-
const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
2538
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
2539
|
-
designSystem.Flex,
|
2540
|
-
{
|
2541
|
-
ref,
|
2542
|
-
tag: "aside",
|
2543
|
-
"aria-labelledby": "additional-information",
|
2544
|
-
background: "neutral0",
|
2545
|
-
borderColor: "neutral150",
|
2546
|
-
hasRadius: true,
|
2547
|
-
paddingBottom: 4,
|
2548
|
-
paddingLeft: 4,
|
2549
|
-
paddingRight: 4,
|
2550
|
-
paddingTop: 4,
|
2551
|
-
shadow: "tableShadow",
|
2552
|
-
gap: 3,
|
2553
|
-
direction: "column",
|
2554
|
-
justifyContent: "stretch",
|
2555
|
-
alignItems: "flex-start",
|
2556
|
-
children: [
|
2557
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2558
|
-
children
|
2559
|
-
]
|
2560
|
-
}
|
2561
|
-
);
|
2562
|
-
});
|
2563
|
-
const HOOKS = {
|
2564
|
-
/**
|
2565
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2566
|
-
* @constant
|
2567
|
-
* @type {string}
|
2568
|
-
*/
|
2569
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2570
|
-
/**
|
2571
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2572
|
-
* @constant
|
2573
|
-
* @type {string}
|
2574
|
-
*/
|
2575
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2576
|
-
/**
|
2577
|
-
* Hook that allows to mutate the CM's edit view layout
|
2578
|
-
* @constant
|
2579
|
-
* @type {string}
|
2580
|
-
*/
|
2581
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2582
|
-
/**
|
2583
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2584
|
-
* @constant
|
2585
|
-
* @type {string}
|
2586
|
-
*/
|
2587
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2588
|
-
};
|
2589
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2590
|
-
endpoints: (builder) => ({
|
2591
|
-
getContentTypeConfiguration: builder.query({
|
2592
|
-
query: (uid) => ({
|
2593
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2594
|
-
method: "GET"
|
2595
|
-
}),
|
2596
|
-
transformResponse: (response) => response.data,
|
2597
|
-
providesTags: (_result, _error, uid) => [
|
2598
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2599
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2600
|
-
]
|
2601
|
-
}),
|
2602
|
-
getAllContentTypeSettings: builder.query({
|
2603
|
-
query: () => "/content-manager/content-types-settings",
|
2604
|
-
transformResponse: (response) => response.data,
|
2605
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2606
|
-
}),
|
2607
|
-
updateContentTypeConfiguration: builder.mutation({
|
2608
|
-
query: ({ uid, ...body }) => ({
|
2609
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2610
|
-
method: "PUT",
|
2611
|
-
data: body
|
2612
|
-
}),
|
2613
|
-
transformResponse: (response) => response.data,
|
2614
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2615
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2616
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2617
|
-
// Is this necessary?
|
2618
|
-
{ type: "InitialData" }
|
2619
|
-
]
|
2620
|
-
})
|
2621
|
-
})
|
2622
|
-
});
|
2623
|
-
const {
|
2624
|
-
useGetContentTypeConfigurationQuery,
|
2625
|
-
useGetAllContentTypeSettingsQuery,
|
2626
|
-
useUpdateContentTypeConfigurationMutation
|
2627
|
-
} = contentTypesApi;
|
2628
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2629
|
-
const { type } = attribute;
|
2630
|
-
if (type === "relation") {
|
2631
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2632
|
-
}
|
2633
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2634
|
-
};
|
2635
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2636
|
-
if (!mainFieldName) {
|
2637
|
-
return void 0;
|
2638
|
-
}
|
2639
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2640
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2641
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2642
|
-
);
|
2643
|
-
return {
|
2644
|
-
name: mainFieldName,
|
2645
|
-
type: mainFieldType ?? "string"
|
2646
|
-
};
|
2647
|
-
};
|
2648
|
-
const DEFAULT_SETTINGS = {
|
2649
|
-
bulkable: false,
|
2650
|
-
filterable: false,
|
2651
|
-
searchable: false,
|
2652
|
-
pagination: false,
|
2653
|
-
defaultSortBy: "",
|
2654
|
-
defaultSortOrder: "asc",
|
2655
|
-
mainField: "id",
|
2656
|
-
pageSize: 10
|
2657
|
-
};
|
2658
|
-
const useDocumentLayout = (model) => {
|
2659
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2660
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
2661
|
-
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2662
|
-
const { toggleNotification } = strapiAdmin.useNotification();
|
2663
|
-
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
2664
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2665
|
-
const {
|
2666
|
-
data,
|
2667
|
-
isLoading: isLoadingConfigs,
|
2668
|
-
error,
|
2669
|
-
isFetching: isFetchingConfigs
|
2670
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2671
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2672
|
-
React__namespace.useEffect(() => {
|
2673
|
-
if (error) {
|
2674
|
-
toggleNotification({
|
2675
|
-
type: "danger",
|
2676
|
-
message: formatAPIError(error)
|
2677
|
-
});
|
2678
|
-
}
|
2679
|
-
}, [error, formatAPIError, toggleNotification]);
|
2680
|
-
const editLayout = React__namespace.useMemo(
|
2681
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2682
|
-
layout: [],
|
2683
|
-
components: {},
|
2684
|
-
metadatas: {},
|
2685
|
-
options: {},
|
2686
|
-
settings: DEFAULT_SETTINGS
|
2687
|
-
},
|
2688
|
-
[data, isLoading, schemas, schema, components]
|
2689
|
-
);
|
2690
|
-
const listLayout = React__namespace.useMemo(() => {
|
2691
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2692
|
-
layout: [],
|
2693
|
-
metadatas: {},
|
2694
|
-
options: {},
|
2695
|
-
settings: DEFAULT_SETTINGS
|
2696
|
-
};
|
2697
|
-
}, [data, isLoading, schemas, schema, components]);
|
2698
|
-
const { layout: edit } = React__namespace.useMemo(
|
2699
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2700
|
-
layout: editLayout,
|
2701
|
-
query
|
2702
|
-
}),
|
2703
|
-
[editLayout, query, runHookWaterfall]
|
2704
|
-
);
|
2705
|
-
return {
|
2706
|
-
error,
|
2707
|
-
isLoading,
|
2708
|
-
edit,
|
2709
|
-
list: listLayout
|
2710
|
-
};
|
2711
|
-
};
|
2712
|
-
const useDocLayout = () => {
|
2713
|
-
const { model } = useDoc();
|
2714
|
-
return useDocumentLayout(model);
|
2715
|
-
};
|
2716
|
-
const formatEditLayout = (data, {
|
2717
|
-
schemas,
|
2718
|
-
schema,
|
2719
|
-
components
|
2720
|
-
}) => {
|
2721
|
-
let currentPanelIndex = 0;
|
2722
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2723
|
-
data.contentType.layouts.edit,
|
2724
|
-
schema?.attributes,
|
2725
|
-
data.contentType.metadatas,
|
2726
|
-
{ configurations: data.components, schemas: components },
|
2727
|
-
schemas
|
2728
|
-
).reduce((panels, row) => {
|
2729
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2730
|
-
panels.push([row]);
|
2731
|
-
currentPanelIndex += 2;
|
2732
|
-
} else {
|
2733
|
-
if (!panels[currentPanelIndex]) {
|
2734
|
-
panels.push([]);
|
2735
|
-
}
|
2736
|
-
panels[currentPanelIndex].push(row);
|
2737
|
-
}
|
2738
|
-
return panels;
|
2739
|
-
}, []);
|
2740
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2741
|
-
(acc, [uid, configuration]) => {
|
2742
|
-
acc[uid] = {
|
2743
|
-
layout: convertEditLayoutToFieldLayouts(
|
2744
|
-
configuration.layouts.edit,
|
2745
|
-
components[uid].attributes,
|
2746
|
-
configuration.metadatas
|
2747
|
-
),
|
2748
|
-
settings: {
|
2749
|
-
...configuration.settings,
|
2750
|
-
icon: components[uid].info.icon,
|
2751
|
-
displayName: components[uid].info.displayName
|
3028
|
+
navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
|
3029
|
+
}
|
3030
|
+
} finally {
|
3031
|
+
if (!listViewPathMatch) {
|
3032
|
+
setSubmitting(false);
|
3033
|
+
}
|
2752
3034
|
}
|
2753
|
-
}
|
2754
|
-
return acc;
|
2755
|
-
},
|
2756
|
-
{}
|
2757
|
-
);
|
2758
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2759
|
-
(acc, [attribute, metadata]) => {
|
2760
|
-
return {
|
2761
|
-
...acc,
|
2762
|
-
[attribute]: metadata.edit
|
2763
|
-
};
|
2764
|
-
},
|
2765
|
-
{}
|
2766
|
-
);
|
2767
|
-
return {
|
2768
|
-
layout: panelledEditAttributes,
|
2769
|
-
components: componentEditAttributes,
|
2770
|
-
metadatas: editMetadatas,
|
2771
|
-
settings: {
|
2772
|
-
...data.contentType.settings,
|
2773
|
-
displayName: schema?.info.displayName
|
3035
|
+
}
|
2774
3036
|
},
|
2775
|
-
|
2776
|
-
|
2777
|
-
...schema?.pluginOptions,
|
2778
|
-
...data.contentType.options
|
2779
|
-
}
|
3037
|
+
variant: "danger",
|
3038
|
+
position: ["header", "table-row"]
|
2780
3039
|
};
|
2781
3040
|
};
|
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
|
-
|
2809
|
-
|
2810
|
-
|
3041
|
+
DeleteAction$1.type = "delete";
|
3042
|
+
DeleteAction$1.position = ["header", "table-row"];
|
3043
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
3044
|
+
const Panels = () => {
|
3045
|
+
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
3046
|
+
const [
|
3047
|
+
{
|
3048
|
+
query: { status }
|
3049
|
+
}
|
3050
|
+
] = strapiAdmin.useQueryParams({
|
3051
|
+
status: "draft"
|
3052
|
+
});
|
3053
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
3054
|
+
const plugins = strapiAdmin.useStrapiApp("Panels", (state) => state.plugins);
|
3055
|
+
const props = {
|
3056
|
+
activeTab: status,
|
3057
|
+
model,
|
3058
|
+
documentId: id,
|
3059
|
+
document: isCloning ? void 0 : document,
|
3060
|
+
meta: isCloning ? void 0 : meta,
|
3061
|
+
collectionType
|
3062
|
+
};
|
3063
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3064
|
+
strapiAdmin.DescriptionComponentRenderer,
|
3065
|
+
{
|
3066
|
+
props,
|
3067
|
+
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
3068
|
+
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsxRuntime.jsx(Panel, { ...description, children: content }, id2))
|
3069
|
+
}
|
3070
|
+
) });
|
2811
3071
|
};
|
2812
|
-
const
|
2813
|
-
|
2814
|
-
schema,
|
2815
|
-
components
|
2816
|
-
}) => {
|
2817
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2818
|
-
(acc, [attribute, metadata]) => {
|
2819
|
-
return {
|
2820
|
-
...acc,
|
2821
|
-
[attribute]: metadata.list
|
2822
|
-
};
|
2823
|
-
},
|
2824
|
-
{}
|
2825
|
-
);
|
2826
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2827
|
-
data.contentType.layouts.list,
|
2828
|
-
schema?.attributes,
|
2829
|
-
listMetadatas,
|
2830
|
-
{ configurations: data.components, schemas: components },
|
2831
|
-
schemas
|
2832
|
-
);
|
3072
|
+
const ActionsPanel = () => {
|
3073
|
+
const { formatMessage } = reactIntl.useIntl();
|
2833
3074
|
return {
|
2834
|
-
|
2835
|
-
|
2836
|
-
|
2837
|
-
|
2838
|
-
|
2839
|
-
...schema?.pluginOptions,
|
2840
|
-
...data.contentType.options
|
2841
|
-
}
|
3075
|
+
title: formatMessage({
|
3076
|
+
id: "content-manager.containers.edit.panels.default.title",
|
3077
|
+
defaultMessage: "Entry"
|
3078
|
+
}),
|
3079
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2842
3080
|
};
|
2843
3081
|
};
|
2844
|
-
|
2845
|
-
|
2846
|
-
|
2847
|
-
|
2848
|
-
|
3082
|
+
ActionsPanel.type = "actions";
|
3083
|
+
const ActionsPanelContent = () => {
|
3084
|
+
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
3085
|
+
const [
|
3086
|
+
{
|
3087
|
+
query: { status = "draft" }
|
2849
3088
|
}
|
2850
|
-
|
2851
|
-
|
2852
|
-
|
2853
|
-
|
2854
|
-
|
2855
|
-
|
2856
|
-
|
2857
|
-
|
2858
|
-
|
2859
|
-
|
2860
|
-
|
2861
|
-
|
2862
|
-
|
2863
|
-
|
3089
|
+
] = strapiAdmin.useQueryParams();
|
3090
|
+
const { model, id, document, meta, collectionType } = useDoc();
|
3091
|
+
const plugins = strapiAdmin.useStrapiApp("ActionsPanel", (state) => state.plugins);
|
3092
|
+
const props = {
|
3093
|
+
activeTab: status,
|
3094
|
+
model,
|
3095
|
+
documentId: id,
|
3096
|
+
document: isCloning ? void 0 : document,
|
3097
|
+
meta: isCloning ? void 0 : meta,
|
3098
|
+
collectionType
|
3099
|
+
};
|
3100
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, width: "100%", children: [
|
3101
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3102
|
+
strapiAdmin.DescriptionComponentRenderer,
|
3103
|
+
{
|
3104
|
+
props,
|
3105
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("panel"),
|
3106
|
+
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
3107
|
+
}
|
3108
|
+
),
|
3109
|
+
/* @__PURE__ */ jsxRuntime.jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
3110
|
+
] });
|
2864
3111
|
};
|
3112
|
+
const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
3113
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
3114
|
+
designSystem.Flex,
|
3115
|
+
{
|
3116
|
+
ref,
|
3117
|
+
tag: "aside",
|
3118
|
+
"aria-labelledby": "additional-information",
|
3119
|
+
background: "neutral0",
|
3120
|
+
borderColor: "neutral150",
|
3121
|
+
hasRadius: true,
|
3122
|
+
paddingBottom: 4,
|
3123
|
+
paddingLeft: 4,
|
3124
|
+
paddingRight: 4,
|
3125
|
+
paddingTop: 4,
|
3126
|
+
shadow: "tableShadow",
|
3127
|
+
gap: 3,
|
3128
|
+
direction: "column",
|
3129
|
+
justifyContent: "stretch",
|
3130
|
+
alignItems: "flex-start",
|
3131
|
+
children: [
|
3132
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", textColor: "neutral600", children: title }),
|
3133
|
+
children
|
3134
|
+
]
|
3135
|
+
}
|
3136
|
+
);
|
3137
|
+
});
|
2865
3138
|
const ConfirmBulkActionDialog = ({
|
2866
3139
|
onToggleDialog,
|
2867
3140
|
isOpen = false,
|
@@ -2900,6 +3173,7 @@ const ConfirmDialogPublishAll = ({
|
|
2900
3173
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
|
2901
3174
|
const { model, schema } = useDoc();
|
2902
3175
|
const [{ query }] = strapiAdmin.useQueryParams();
|
3176
|
+
const enableDraftRelationsCount = false;
|
2903
3177
|
const {
|
2904
3178
|
data: countDraftRelations = 0,
|
2905
3179
|
isLoading,
|
@@ -2911,7 +3185,7 @@ const ConfirmDialogPublishAll = ({
|
|
2911
3185
|
locale: query?.plugins?.i18n?.locale
|
2912
3186
|
},
|
2913
3187
|
{
|
2914
|
-
skip:
|
3188
|
+
skip: !enableDraftRelationsCount
|
2915
3189
|
}
|
2916
3190
|
);
|
2917
3191
|
React__namespace.useEffect(() => {
|
@@ -3096,7 +3370,7 @@ const SelectedEntriesTableContent = ({
|
|
3096
3370
|
status: row.status
|
3097
3371
|
}
|
3098
3372
|
) }),
|
3099
|
-
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3373
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3100
3374
|
designSystem.IconButton,
|
3101
3375
|
{
|
3102
3376
|
tag: reactRouterDom.Link,
|
@@ -3105,23 +3379,16 @@ const SelectedEntriesTableContent = ({
|
|
3105
3379
|
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3106
3380
|
},
|
3107
3381
|
state: { from: pathname },
|
3108
|
-
label: formatMessage(
|
3109
|
-
|
3110
|
-
|
3111
|
-
|
3112
|
-
{
|
3113
|
-
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3114
|
-
defaultMessage: "item line {number}"
|
3115
|
-
},
|
3116
|
-
{ number: index2 + 1 }
|
3117
|
-
)
|
3118
|
-
}
|
3119
|
-
),
|
3382
|
+
label: formatMessage({
|
3383
|
+
id: "content-manager.bulk-publish.edit",
|
3384
|
+
defaultMessage: "Edit"
|
3385
|
+
}),
|
3120
3386
|
target: "_blank",
|
3121
3387
|
marginLeft: "auto",
|
3122
|
-
|
3388
|
+
variant: "ghost",
|
3389
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, { width: "1.6rem", height: "1.6rem" })
|
3123
3390
|
}
|
3124
|
-
) })
|
3391
|
+
) }) })
|
3125
3392
|
] }, row.id)) })
|
3126
3393
|
] });
|
3127
3394
|
};
|
@@ -3158,7 +3425,13 @@ const SelectedEntriesModalContent = ({
|
|
3158
3425
|
);
|
3159
3426
|
const { rows, validationErrors } = React__namespace.useMemo(() => {
|
3160
3427
|
if (data.length > 0 && schema) {
|
3161
|
-
const validate = createYupSchema(
|
3428
|
+
const validate = createYupSchema(
|
3429
|
+
schema.attributes,
|
3430
|
+
components,
|
3431
|
+
// Since this is the "Publish" action, the validation
|
3432
|
+
// schema must enforce the rules for published entities
|
3433
|
+
{ status: "published" }
|
3434
|
+
);
|
3162
3435
|
const validationErrors2 = {};
|
3163
3436
|
const rows2 = data.map((entry) => {
|
3164
3437
|
try {
|
@@ -3283,8 +3556,7 @@ const PublishAction = ({ documents, model }) => {
|
|
3283
3556
|
const refetchList = () => {
|
3284
3557
|
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3285
3558
|
};
|
3286
|
-
if (!showPublishButton)
|
3287
|
-
return null;
|
3559
|
+
if (!showPublishButton) return null;
|
3288
3560
|
return {
|
3289
3561
|
actionType: "publish",
|
3290
3562
|
variant: "tertiary",
|
@@ -3352,8 +3624,7 @@ const DeleteAction = ({ documents, model }) => {
|
|
3352
3624
|
selectRow([]);
|
3353
3625
|
}
|
3354
3626
|
};
|
3355
|
-
if (!hasDeletePermission)
|
3356
|
-
return null;
|
3627
|
+
if (!hasDeletePermission) return null;
|
3357
3628
|
return {
|
3358
3629
|
variant: "danger-light",
|
3359
3630
|
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
@@ -3402,8 +3673,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3402
3673
|
}
|
3403
3674
|
};
|
3404
3675
|
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3405
|
-
if (!showUnpublishButton)
|
3406
|
-
return null;
|
3676
|
+
if (!showUnpublishButton) return null;
|
3407
3677
|
return {
|
3408
3678
|
variant: "tertiary",
|
3409
3679
|
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
@@ -3508,7 +3778,7 @@ const TableActions = ({ document }) => {
|
|
3508
3778
|
strapiAdmin.DescriptionComponentRenderer,
|
3509
3779
|
{
|
3510
3780
|
props,
|
3511
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3781
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("table-row").filter((action) => action.name !== "PublishAction"),
|
3512
3782
|
children: (actions2) => {
|
3513
3783
|
const tableRowActions = actions2.filter((action) => {
|
3514
3784
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3567,6 +3837,7 @@ const EditAction = ({ documentId }) => {
|
|
3567
3837
|
};
|
3568
3838
|
};
|
3569
3839
|
EditAction.type = "edit";
|
3840
|
+
EditAction.position = "table-row";
|
3570
3841
|
const StyledPencil = styledComponents.styled(Icons.Pencil)`
|
3571
3842
|
path {
|
3572
3843
|
fill: currentColor;
|
@@ -3619,7 +3890,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3619
3890
|
}),
|
3620
3891
|
content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3621
3892
|
footer: ({ onClose }) => {
|
3622
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.
|
3893
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3623
3894
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3624
3895
|
id: "cancel",
|
3625
3896
|
defaultMessage: "Cancel"
|
@@ -3643,6 +3914,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3643
3914
|
};
|
3644
3915
|
};
|
3645
3916
|
CloneAction.type = "clone";
|
3917
|
+
CloneAction.position = "table-row";
|
3646
3918
|
const StyledDuplicate = styledComponents.styled(Icons.Duplicate)`
|
3647
3919
|
path {
|
3648
3920
|
fill: currentColor;
|
@@ -3729,7 +4001,14 @@ class ContentManagerPlugin {
|
|
3729
4001
|
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3730
4002
|
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3731
4003
|
getBulkActions: () => this.bulkActions,
|
3732
|
-
getDocumentActions: () =>
|
4004
|
+
getDocumentActions: (position) => {
|
4005
|
+
if (position) {
|
4006
|
+
return this.documentActions.filter(
|
4007
|
+
(action) => action.position == void 0 || [action.position].flat().includes(position)
|
4008
|
+
);
|
4009
|
+
}
|
4010
|
+
return this.documentActions;
|
4011
|
+
},
|
3733
4012
|
getEditViewSidePanels: () => this.editViewSidePanels,
|
3734
4013
|
getHeaderActions: () => this.headerActions
|
3735
4014
|
}
|
@@ -3739,10 +4018,8 @@ class ContentManagerPlugin {
|
|
3739
4018
|
const getPrintableType = (value) => {
|
3740
4019
|
const nativeType = typeof value;
|
3741
4020
|
if (nativeType === "object") {
|
3742
|
-
if (value === null)
|
3743
|
-
|
3744
|
-
if (Array.isArray(value))
|
3745
|
-
return "array";
|
4021
|
+
if (value === null) return "null";
|
4022
|
+
if (Array.isArray(value)) return "array";
|
3746
4023
|
if (value instanceof Object && value.constructor.name !== "Object") {
|
3747
4024
|
return value.constructor.name;
|
3748
4025
|
}
|
@@ -3753,17 +4030,27 @@ const HistoryAction = ({ model, document }) => {
|
|
3753
4030
|
const { formatMessage } = reactIntl.useIntl();
|
3754
4031
|
const [{ query }] = strapiAdmin.useQueryParams();
|
3755
4032
|
const navigate = reactRouterDom.useNavigate();
|
4033
|
+
const { trackUsage } = strapiAdmin.useTracking();
|
4034
|
+
const { pathname } = reactRouterDom.useLocation();
|
3756
4035
|
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
3757
4036
|
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3758
4037
|
return null;
|
3759
4038
|
}
|
4039
|
+
const handleOnClick = () => {
|
4040
|
+
const destination = { pathname: "history", search: pluginsQueryParams };
|
4041
|
+
trackUsage("willNavigate", {
|
4042
|
+
from: pathname,
|
4043
|
+
to: `${pathname}/${destination.pathname}`
|
4044
|
+
});
|
4045
|
+
navigate(destination);
|
4046
|
+
};
|
3760
4047
|
return {
|
3761
4048
|
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
3762
4049
|
label: formatMessage({
|
3763
4050
|
id: "content-manager.history.document-action",
|
3764
4051
|
defaultMessage: "Content History"
|
3765
4052
|
}),
|
3766
|
-
onClick:
|
4053
|
+
onClick: handleOnClick,
|
3767
4054
|
disabled: (
|
3768
4055
|
/**
|
3769
4056
|
* The user is creating a new document.
|
@@ -3785,6 +4072,7 @@ const HistoryAction = ({ model, document }) => {
|
|
3785
4072
|
};
|
3786
4073
|
};
|
3787
4074
|
HistoryAction.type = "history";
|
4075
|
+
HistoryAction.position = "header";
|
3788
4076
|
const historyAdmin = {
|
3789
4077
|
bootstrap(app) {
|
3790
4078
|
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
@@ -3831,6 +4119,88 @@ const { setInitialData } = actions;
|
|
3831
4119
|
const reducer = toolkit.combineReducers({
|
3832
4120
|
app: reducer$1
|
3833
4121
|
});
|
4122
|
+
const previewApi = contentManagerApi.injectEndpoints({
|
4123
|
+
endpoints: (builder) => ({
|
4124
|
+
getPreviewUrl: builder.query({
|
4125
|
+
query({ query, params }) {
|
4126
|
+
return {
|
4127
|
+
url: `/content-manager/preview/url/${params.contentType}`,
|
4128
|
+
method: "GET",
|
4129
|
+
config: {
|
4130
|
+
params: query
|
4131
|
+
}
|
4132
|
+
};
|
4133
|
+
}
|
4134
|
+
})
|
4135
|
+
})
|
4136
|
+
});
|
4137
|
+
const { useGetPreviewUrlQuery } = previewApi;
|
4138
|
+
const ConditionalTooltip = ({ isShown, label, children }) => {
|
4139
|
+
if (isShown) {
|
4140
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { label, children });
|
4141
|
+
}
|
4142
|
+
return children;
|
4143
|
+
};
|
4144
|
+
const PreviewSidePanel = ({ model, documentId, document }) => {
|
4145
|
+
const { formatMessage } = reactIntl.useIntl();
|
4146
|
+
const { trackUsage } = strapiAdmin.useTracking();
|
4147
|
+
const { pathname } = reactRouterDom.useLocation();
|
4148
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
4149
|
+
const isModified = strapiAdmin.useForm("PreviewSidePanel", (state) => state.modified);
|
4150
|
+
const { data, error } = useGetPreviewUrlQuery({
|
4151
|
+
params: {
|
4152
|
+
contentType: model
|
4153
|
+
},
|
4154
|
+
query: {
|
4155
|
+
documentId,
|
4156
|
+
locale: document?.locale,
|
4157
|
+
status: document?.status
|
4158
|
+
}
|
4159
|
+
});
|
4160
|
+
if (!data?.data?.url || error) {
|
4161
|
+
return null;
|
4162
|
+
}
|
4163
|
+
const trackNavigation = () => {
|
4164
|
+
const destinationPathname = pathname.replace(/\/$/, "") + "/preview";
|
4165
|
+
trackUsage("willNavigate", { from: pathname, to: destinationPathname });
|
4166
|
+
};
|
4167
|
+
return {
|
4168
|
+
title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
|
4169
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(
|
4170
|
+
ConditionalTooltip,
|
4171
|
+
{
|
4172
|
+
label: formatMessage({
|
4173
|
+
id: "content-manager.preview.panel.button-disabled-tooltip",
|
4174
|
+
defaultMessage: "Please save to open the preview"
|
4175
|
+
}),
|
4176
|
+
isShown: isModified,
|
4177
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { cursor: "not-allowed", width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(
|
4178
|
+
designSystem.Button,
|
4179
|
+
{
|
4180
|
+
variant: "tertiary",
|
4181
|
+
tag: reactRouterDom.Link,
|
4182
|
+
to: { pathname: "preview", search: qs.stringify(query, { encode: false }) },
|
4183
|
+
onClick: trackNavigation,
|
4184
|
+
width: "100%",
|
4185
|
+
disabled: isModified,
|
4186
|
+
pointerEvents: isModified ? "none" : void 0,
|
4187
|
+
tabIndex: isModified ? -1 : void 0,
|
4188
|
+
children: formatMessage({
|
4189
|
+
id: "content-manager.preview.panel.button",
|
4190
|
+
defaultMessage: "Open preview"
|
4191
|
+
})
|
4192
|
+
}
|
4193
|
+
) })
|
4194
|
+
}
|
4195
|
+
)
|
4196
|
+
};
|
4197
|
+
};
|
4198
|
+
const previewAdmin = {
|
4199
|
+
bootstrap(app) {
|
4200
|
+
const contentManagerPluginApis = app.getPlugin("content-manager").apis;
|
4201
|
+
contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
|
4202
|
+
}
|
4203
|
+
};
|
3834
4204
|
const index = {
|
3835
4205
|
register(app) {
|
3836
4206
|
const cm = new ContentManagerPlugin();
|
@@ -3850,7 +4220,7 @@ const index = {
|
|
3850
4220
|
app.router.addRoute({
|
3851
4221
|
path: "content-manager/*",
|
3852
4222
|
lazy: async () => {
|
3853
|
-
const { Layout } = await Promise.resolve().then(() => require("./layout-
|
4223
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-CDBEgRsM.js"));
|
3854
4224
|
return {
|
3855
4225
|
Component: Layout
|
3856
4226
|
};
|
@@ -3863,11 +4233,14 @@ const index = {
|
|
3863
4233
|
if (typeof historyAdmin.bootstrap === "function") {
|
3864
4234
|
historyAdmin.bootstrap(app);
|
3865
4235
|
}
|
4236
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
4237
|
+
previewAdmin.bootstrap(app);
|
4238
|
+
}
|
3866
4239
|
},
|
3867
4240
|
async registerTrads({ locales }) {
|
3868
4241
|
const importedTrads = await Promise.all(
|
3869
4242
|
locales.map((locale) => {
|
3870
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-
|
4243
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => Promise.resolve().then(() => require("./ar-BUUWXIYu.js")), "./translations/ca.json": () => Promise.resolve().then(() => require("./ca-Cmk45QO6.js")), "./translations/cs.json": () => Promise.resolve().then(() => require("./cs-CkJy6B2v.js")), "./translations/de.json": () => Promise.resolve().then(() => require("./de-CCEmbAah.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-BzQmavmK.js")), "./translations/es.json": () => Promise.resolve().then(() => require("./es-9K52xZIr.js")), "./translations/eu.json": () => Promise.resolve().then(() => require("./eu-VDH-3ovk.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-B2Kyv8Z9.js")), "./translations/gu.json": () => Promise.resolve().then(() => require("./gu-BRmF601H.js")), "./translations/hi.json": () => Promise.resolve().then(() => require("./hi-CCJBptSq.js")), "./translations/hu.json": () => Promise.resolve().then(() => require("./hu-sNV_yLYy.js")), "./translations/id.json": () => Promise.resolve().then(() => require("./id-B5Ser98A.js")), "./translations/it.json": () => Promise.resolve().then(() => require("./it-DkBIs7vD.js")), "./translations/ja.json": () => Promise.resolve().then(() => require("./ja-7sfIbjxE.js")), "./translations/ko.json": () => Promise.resolve().then(() => require("./ko-woFZPmLk.js")), "./translations/ml.json": () => Promise.resolve().then(() => require("./ml-C2W8N8k1.js")), "./translations/ms.json": () => Promise.resolve().then(() => require("./ms-BuFotyP_.js")), "./translations/nl.json": () => Promise.resolve().then(() => require("./nl-bbEOHChV.js")), "./translations/pl.json": () => Promise.resolve().then(() => require("./pl-uzwG-hk7.js")), "./translations/pt-BR.json": () => Promise.resolve().then(() => require("./pt-BR-BiOz37D9.js")), "./translations/pt.json": () => Promise.resolve().then(() => require("./pt-CeXQuq50.js")), "./translations/ru.json": () => Promise.resolve().then(() => require("./ru-BT3ybNny.js")), "./translations/sa.json": () => Promise.resolve().then(() => require("./sa-CcvkYInH.js")), "./translations/sk.json": () => Promise.resolve().then(() => require("./sk-CvY09Xjv.js")), "./translations/sv.json": () => Promise.resolve().then(() => require("./sv-MYDuzgvT.js")), "./translations/th.json": () => Promise.resolve().then(() => require("./th-D9_GfAjc.js")), "./translations/tr.json": () => Promise.resolve().then(() => require("./tr-D9UH-O_R.js")), "./translations/uk.json": () => Promise.resolve().then(() => require("./uk-C8EiqJY7.js")), "./translations/vi.json": () => Promise.resolve().then(() => require("./vi-CJlYDheJ.js")), "./translations/zh-Hans.json": () => Promise.resolve().then(() => require("./zh-Hans-9kOncHGw.js")), "./translations/zh.json": () => Promise.resolve().then(() => require("./zh-CQQfszqR.js")) }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
|
3871
4244
|
return {
|
3872
4245
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3873
4246
|
locale
|
@@ -3885,6 +4258,7 @@ const index = {
|
|
3885
4258
|
};
|
3886
4259
|
exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
|
3887
4260
|
exports.BulkActionsRenderer = BulkActionsRenderer;
|
4261
|
+
exports.CLONE_PATH = CLONE_PATH;
|
3888
4262
|
exports.COLLECTION_TYPES = COLLECTION_TYPES;
|
3889
4263
|
exports.CREATOR_FIELDS = CREATOR_FIELDS;
|
3890
4264
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
@@ -3912,6 +4286,7 @@ exports.getMainField = getMainField;
|
|
3912
4286
|
exports.getTranslation = getTranslation;
|
3913
4287
|
exports.index = index;
|
3914
4288
|
exports.setInitialData = setInitialData;
|
4289
|
+
exports.useContentManagerContext = useContentManagerContext;
|
3915
4290
|
exports.useContentTypeSchema = useContentTypeSchema;
|
3916
4291
|
exports.useDoc = useDoc;
|
3917
4292
|
exports.useDocLayout = useDocLayout;
|
@@ -3923,5 +4298,6 @@ exports.useGetAllContentTypeSettingsQuery = useGetAllContentTypeSettingsQuery;
|
|
3923
4298
|
exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
3924
4299
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3925
4300
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
4301
|
+
exports.useGetPreviewUrlQuery = useGetPreviewUrlQuery;
|
3926
4302
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3927
|
-
//# sourceMappingURL=index-
|
4303
|
+
//# sourceMappingURL=index-Ct-GZ0iV.js.map
|