@strapi/content-manager 0.0.0-experimental.745741d19e90275ca6f7c928ca19f9bb0fd9d933 → 0.0.0-experimental.76d3543c13df7ef0095963ae2c20b792f179eef0
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-BvHtG7uH.js → ComponentConfigurationPage-CJPoOvy3.js} +5 -6
- package/dist/_chunks/{ComponentConfigurationPage-BvHtG7uH.js.map → ComponentConfigurationPage-CJPoOvy3.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DHNM3YBz.mjs → ComponentConfigurationPage-CcRDqD0e.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-DHNM3YBz.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-Cp6HAEzN.mjs → EditConfigurationPage-C1ddZ_zf.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-Cp6HAEzN.mjs.map → EditConfigurationPage-C1ddZ_zf.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DOmfCEMo.js → EditConfigurationPage-CF3lxOy2.js} +5 -6
- package/dist/_chunks/{EditConfigurationPage-DOmfCEMo.js.map → EditConfigurationPage-CF3lxOy2.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-BtkEx339.mjs → EditViewPage-BPFcUbqi.mjs} +63 -12
- package/dist/_chunks/EditViewPage-BPFcUbqi.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-BqNpC6hO.js → EditViewPage-CDyTC6aU.js} +63 -13
- package/dist/_chunks/EditViewPage-CDyTC6aU.js.map +1 -0
- package/dist/_chunks/{Field-lsPFnAmH.js → Field-DuxAW9q2.js} +409 -260
- package/dist/_chunks/Field-DuxAW9q2.js.map +1 -0
- package/dist/_chunks/{Field-R5NbffTB.mjs → Field-fBnTwgU4.mjs} +405 -256
- 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-BHmXSfyy.mjs → Form-BGl7PhlZ.mjs} +37 -18
- package/dist/_chunks/Form-BGl7PhlZ.mjs.map +1 -0
- package/dist/_chunks/{Form-CcGboku8.js → Form-DSGh_zkz.js} +39 -21
- package/dist/_chunks/Form-DSGh_zkz.js.map +1 -0
- package/dist/_chunks/{History-ByUPL3T3.mjs → History-DTYB9CSB.mjs} +66 -113
- package/dist/_chunks/History-DTYB9CSB.mjs.map +1 -0
- package/dist/_chunks/{History-Bsud8jwh.js → History-DrDJv698.js} +65 -113
- package/dist/_chunks/History-DrDJv698.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Bm5HACXf.mjs → ListConfigurationPage-qWx8r4D_.mjs} +25 -12
- package/dist/_chunks/ListConfigurationPage-qWx8r4D_.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DiT463qx.js → ListConfigurationPage-zurIlUZ7.js} +25 -13
- package/dist/_chunks/ListConfigurationPage-zurIlUZ7.js.map +1 -0
- package/dist/_chunks/{ListViewPage-CsrC9L_d.js → ListViewPage-DTM2uO_S.js} +109 -78
- package/dist/_chunks/ListViewPage-DTM2uO_S.js.map +1 -0
- package/dist/_chunks/{ListViewPage-JSyNAAYu.mjs → ListViewPage-GKpL5p8A.mjs} +106 -74
- package/dist/_chunks/ListViewPage-GKpL5p8A.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-CsrQUpBE.mjs → NoContentTypePage-B5Vc5Cal.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CsrQUpBE.mjs.map → NoContentTypePage-B5Vc5Cal.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-Bsvng4II.js → NoContentTypePage-BuZlNroO.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-Bsvng4II.js.map → NoContentTypePage-BuZlNroO.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DNmf_pj0.mjs → NoPermissionsPage-BAZlWgJ4.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DNmf_pj0.mjs.map → NoPermissionsPage-BAZlWgJ4.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-CdHNJtEf.js → NoPermissionsPage-DLzkS4Hy.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-CdHNJtEf.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-u8-37jK0.mjs → Relations-BVdRfDkW.mjs} +76 -42
- package/dist/_chunks/Relations-BVdRfDkW.mjs.map +1 -0
- package/dist/_chunks/{Relations-CghaPv2D.js → Relations-Dsj0boFJ.js} +76 -43
- package/dist/_chunks/Relations-Dsj0boFJ.js.map +1 -0
- package/dist/_chunks/{en-fbKQxLGn.js → en-BzQmavmK.js} +37 -18
- package/dist/_chunks/{en-fbKQxLGn.js.map → en-BzQmavmK.js.map} +1 -1
- package/dist/_chunks/{en-Ux26r5pl.mjs → en-CSxLmrh1.mjs} +37 -18
- package/dist/_chunks/{en-Ux26r5pl.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-CaE6NG4a.mjs → index-Bu_-B7ZA.mjs} +1263 -772
- package/dist/_chunks/index-Bu_-B7ZA.mjs.map +1 -0
- package/dist/_chunks/{index-BOZx6IMg.js → index-Ct-GZ0iV.js} +1246 -755
- 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-Ciz224q5.js → layout-CDBEgRsM.js} +24 -12
- package/dist/_chunks/layout-CDBEgRsM.js.map +1 -0
- package/dist/_chunks/{layout-Bx7svTbY.mjs → layout-COzAvgJh.mjs} +24 -11
- 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-CP8sB2YZ.js → relations-BjiF1Aad.js} +6 -7
- package/dist/_chunks/relations-BjiF1Aad.js.map +1 -0
- package/dist/_chunks/{relations-Cxc1cEv3.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/index.d.ts +3 -0
- 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/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +2 -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/Relations.d.ts +20 -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-BqNpC6hO.js.map +0 -1
- package/dist/_chunks/EditViewPage-BtkEx339.mjs.map +0 -1
- package/dist/_chunks/Field-R5NbffTB.mjs.map +0 -1
- package/dist/_chunks/Field-lsPFnAmH.js.map +0 -1
- package/dist/_chunks/Form-BHmXSfyy.mjs.map +0 -1
- package/dist/_chunks/Form-CcGboku8.js.map +0 -1
- package/dist/_chunks/History-Bsud8jwh.js.map +0 -1
- package/dist/_chunks/History-ByUPL3T3.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Bm5HACXf.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DiT463qx.js.map +0 -1
- package/dist/_chunks/ListViewPage-CsrC9L_d.js.map +0 -1
- package/dist/_chunks/ListViewPage-JSyNAAYu.mjs.map +0 -1
- package/dist/_chunks/Relations-CghaPv2D.js.map +0 -1
- package/dist/_chunks/Relations-u8-37jK0.mjs.map +0 -1
- package/dist/_chunks/index-BOZx6IMg.js.map +0 -1
- package/dist/_chunks/index-CaE6NG4a.mjs.map +0 -1
- package/dist/_chunks/layout-Bx7svTbY.mjs.map +0 -1
- package/dist/_chunks/layout-Ciz224q5.js.map +0 -1
- package/dist/_chunks/relations-CP8sB2YZ.js.map +0 -1
- package/dist/_chunks/relations-Cxc1cEv3.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
@@ -2,20 +2,20 @@
|
|
2
2
|
const Icons = require("@strapi/icons");
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
4
4
|
const strapiAdmin = require("@strapi/admin/strapi-admin");
|
5
|
-
const qs = require("qs");
|
6
|
-
const reactIntl = require("react-intl");
|
7
|
-
const reactRouterDom = require("react-router-dom");
|
8
5
|
const React = require("react");
|
9
6
|
const designSystem = require("@strapi/design-system");
|
7
|
+
const mapValues = require("lodash/fp/mapValues");
|
8
|
+
const reactIntl = require("react-intl");
|
9
|
+
const reactRouterDom = require("react-router-dom");
|
10
10
|
const styledComponents = require("styled-components");
|
11
11
|
const yup = require("yup");
|
12
|
+
const qs = require("qs");
|
12
13
|
const pipe = require("lodash/fp/pipe");
|
13
14
|
const dateFns = require("date-fns");
|
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";
|
@@ -70,42 +78,6 @@ const useInjectionZone = (area) => {
|
|
70
78
|
const [page, position] = area.split(".");
|
71
79
|
return contentManagerPlugin.getInjectedComponents(page, position);
|
72
80
|
};
|
73
|
-
const HistoryAction = ({ model, document }) => {
|
74
|
-
const { formatMessage } = reactIntl.useIntl();
|
75
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
76
|
-
const navigate = reactRouterDom.useNavigate();
|
77
|
-
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
78
|
-
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
79
|
-
return null;
|
80
|
-
}
|
81
|
-
return {
|
82
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
83
|
-
label: formatMessage({
|
84
|
-
id: "content-manager.history.document-action",
|
85
|
-
defaultMessage: "Content History"
|
86
|
-
}),
|
87
|
-
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
88
|
-
disabled: (
|
89
|
-
/**
|
90
|
-
* The user is creating a new document.
|
91
|
-
* It hasn't been saved yet, so there's no history to go to
|
92
|
-
*/
|
93
|
-
!document || /**
|
94
|
-
* The document has been created but the current dimension has never been saved.
|
95
|
-
* For example, the user is creating a new locale in an existing document,
|
96
|
-
* so there's no history for the document in that locale
|
97
|
-
*/
|
98
|
-
!document.id || /**
|
99
|
-
* History is only available for content types created by the user.
|
100
|
-
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
101
|
-
* which start with `admin::` or `plugin::`
|
102
|
-
*/
|
103
|
-
!model.startsWith("api::")
|
104
|
-
),
|
105
|
-
position: "header"
|
106
|
-
};
|
107
|
-
};
|
108
|
-
HistoryAction.type = "history";
|
109
81
|
const ID = "id";
|
110
82
|
const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
|
111
83
|
const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
|
@@ -157,6 +129,7 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
157
129
|
if (!slug) {
|
158
130
|
throw new Error("Cannot find the slug param in the URL");
|
159
131
|
}
|
132
|
+
const [{ rawQuery }] = strapiAdmin.useQueryParams();
|
160
133
|
const userPermissions = strapiAdmin.useAuth("DocumentRBAC", (state) => state.permissions);
|
161
134
|
const contentTypePermissions = React__namespace.useMemo(() => {
|
162
135
|
const contentTypePermissions2 = userPermissions.filter(
|
@@ -167,7 +140,14 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
167
140
|
return { ...acc, [action]: [permission] };
|
168
141
|
}, {});
|
169
142
|
}, [slug, userPermissions]);
|
170
|
-
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
|
+
);
|
171
151
|
const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
|
172
152
|
const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
|
173
153
|
const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
|
@@ -215,7 +195,9 @@ const contentManagerApi = strapiAdmin.adminApi.enhanceEndpoints({
|
|
215
195
|
"Document",
|
216
196
|
"InitialData",
|
217
197
|
"HistoryVersion",
|
218
|
-
"Relations"
|
198
|
+
"Relations",
|
199
|
+
"UidAvailability",
|
200
|
+
"RecentDocumentList"
|
219
201
|
]
|
220
202
|
});
|
221
203
|
const documentApi = contentManagerApi.injectEndpoints({
|
@@ -229,7 +211,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
229
211
|
params: query
|
230
212
|
}
|
231
213
|
}),
|
232
|
-
invalidatesTags: (_result,
|
214
|
+
invalidatesTags: (_result, error, { model }) => {
|
215
|
+
if (error) {
|
216
|
+
return [];
|
217
|
+
}
|
218
|
+
return [{ type: "Document", id: `${model}_LIST` }, "RecentDocumentList"];
|
219
|
+
}
|
233
220
|
}),
|
234
221
|
cloneDocument: builder.mutation({
|
235
222
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -240,7 +227,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
240
227
|
params
|
241
228
|
}
|
242
229
|
}),
|
243
|
-
invalidatesTags: (_result, _error, { model }) => [
|
230
|
+
invalidatesTags: (_result, _error, { model }) => [
|
231
|
+
{ type: "Document", id: `${model}_LIST` },
|
232
|
+
{ type: "UidAvailability", id: model },
|
233
|
+
"RecentDocumentList"
|
234
|
+
]
|
244
235
|
}),
|
245
236
|
/**
|
246
237
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -257,8 +248,22 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
257
248
|
}),
|
258
249
|
invalidatesTags: (result, _error, { model }) => [
|
259
250
|
{ type: "Document", id: `${model}_LIST` },
|
260
|
-
"Relations"
|
261
|
-
|
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
|
+
}
|
262
267
|
}),
|
263
268
|
deleteDocument: builder.mutation({
|
264
269
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -269,7 +274,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
269
274
|
}
|
270
275
|
}),
|
271
276
|
invalidatesTags: (_result, _error, { collectionType, model }) => [
|
272
|
-
{ type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model }
|
277
|
+
{ type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model },
|
278
|
+
"RecentDocumentList"
|
273
279
|
]
|
274
280
|
}),
|
275
281
|
deleteManyDocuments: builder.mutation({
|
@@ -281,7 +287,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
281
287
|
params
|
282
288
|
}
|
283
289
|
}),
|
284
|
-
invalidatesTags: (_res, _error, { model }) => [
|
290
|
+
invalidatesTags: (_res, _error, { model }) => [
|
291
|
+
{ type: "Document", id: `${model}_LIST` },
|
292
|
+
"RecentDocumentList"
|
293
|
+
]
|
285
294
|
}),
|
286
295
|
discardDocument: builder.mutation({
|
287
296
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -298,7 +307,9 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
298
307
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
299
308
|
},
|
300
309
|
{ type: "Document", id: `${model}_LIST` },
|
301
|
-
"Relations"
|
310
|
+
"Relations",
|
311
|
+
{ type: "UidAvailability", id: model },
|
312
|
+
"RecentDocumentList"
|
302
313
|
];
|
303
314
|
}
|
304
315
|
}),
|
@@ -311,11 +322,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
311
322
|
url: `/content-manager/collection-types/${model}`,
|
312
323
|
method: "GET",
|
313
324
|
config: {
|
314
|
-
params
|
325
|
+
params: qs.stringify(params, { encode: true })
|
315
326
|
}
|
316
327
|
}),
|
317
328
|
providesTags: (result, _error, arg) => {
|
318
329
|
return [
|
330
|
+
{ type: "Document", id: `ALL_LIST` },
|
319
331
|
{ type: "Document", id: `${arg.model}_LIST` },
|
320
332
|
...result?.results.map(({ documentId }) => ({
|
321
333
|
type: "Document",
|
@@ -354,6 +366,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
354
366
|
{
|
355
367
|
type: "Document",
|
356
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`
|
357
374
|
}
|
358
375
|
];
|
359
376
|
}
|
@@ -387,7 +404,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
387
404
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
388
405
|
},
|
389
406
|
{ type: "Document", id: `${model}_LIST` },
|
390
|
-
"Relations"
|
407
|
+
"Relations",
|
408
|
+
"RecentDocumentList"
|
391
409
|
];
|
392
410
|
}
|
393
411
|
}),
|
@@ -417,8 +435,23 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
417
435
|
type: "Document",
|
418
436
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
419
437
|
},
|
420
|
-
"Relations"
|
438
|
+
"Relations",
|
439
|
+
{ type: "UidAvailability", id: model },
|
440
|
+
"RecentDocumentList",
|
441
|
+
"RecentDocumentList"
|
421
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
|
+
}
|
422
455
|
}
|
423
456
|
}),
|
424
457
|
unpublishDocument: builder.mutation({
|
@@ -435,7 +468,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
435
468
|
{
|
436
469
|
type: "Document",
|
437
470
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
438
|
-
}
|
471
|
+
},
|
472
|
+
"RecentDocumentList"
|
439
473
|
];
|
440
474
|
}
|
441
475
|
}),
|
@@ -448,7 +482,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
448
482
|
params
|
449
483
|
}
|
450
484
|
}),
|
451
|
-
invalidatesTags: (_res, _error, { model, documentIds }) =>
|
485
|
+
invalidatesTags: (_res, _error, { model, documentIds }) => [
|
486
|
+
...documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` })),
|
487
|
+
"RecentDocumentList"
|
488
|
+
]
|
452
489
|
})
|
453
490
|
})
|
454
491
|
});
|
@@ -471,8 +508,7 @@ const {
|
|
471
508
|
useUnpublishManyDocumentsMutation
|
472
509
|
} = documentApi;
|
473
510
|
const buildValidParams = (query) => {
|
474
|
-
if (!query)
|
475
|
-
return query;
|
511
|
+
if (!query) return query;
|
476
512
|
const { plugins: _, ...validQueryParams } = {
|
477
513
|
...query,
|
478
514
|
...Object.values(query?.plugins ?? {}).reduce(
|
@@ -480,28 +516,44 @@ const buildValidParams = (query) => {
|
|
480
516
|
{}
|
481
517
|
)
|
482
518
|
};
|
483
|
-
if ("_q" in validQueryParams) {
|
484
|
-
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
485
|
-
}
|
486
519
|
return validQueryParams;
|
487
520
|
};
|
488
521
|
const isBaseQueryError = (error) => {
|
489
522
|
return error.name !== void 0;
|
490
523
|
};
|
491
|
-
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 }) => {
|
492
543
|
const createModelSchema = (attributes2) => yup__namespace.object().shape(
|
493
544
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
494
545
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
495
546
|
return acc;
|
496
547
|
}
|
497
548
|
const validations = [
|
549
|
+
addNullableValidation,
|
498
550
|
addRequiredValidation,
|
499
551
|
addMinLengthValidation,
|
500
552
|
addMaxLengthValidation,
|
501
553
|
addMinValidation,
|
502
554
|
addMaxValidation,
|
503
555
|
addRegexValidation
|
504
|
-
].map((fn) => fn(attribute));
|
556
|
+
].map((fn) => fn(attribute, options));
|
505
557
|
const transformSchema = pipe__default.default(...validations);
|
506
558
|
switch (attribute.type) {
|
507
559
|
case "component": {
|
@@ -511,12 +563,12 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
511
563
|
...acc,
|
512
564
|
[name]: transformSchema(
|
513
565
|
yup__namespace.array().of(createModelSchema(attributes3).nullable(false))
|
514
|
-
)
|
566
|
+
).test(arrayValidator(attribute, options))
|
515
567
|
};
|
516
568
|
} else {
|
517
569
|
return {
|
518
570
|
...acc,
|
519
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
571
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
520
572
|
};
|
521
573
|
}
|
522
574
|
}
|
@@ -538,7 +590,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
538
590
|
}
|
539
591
|
)
|
540
592
|
)
|
541
|
-
)
|
593
|
+
).test(arrayValidator(attribute, options))
|
542
594
|
};
|
543
595
|
case "relation":
|
544
596
|
return {
|
@@ -550,7 +602,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
550
602
|
} else if (Array.isArray(value)) {
|
551
603
|
return yup__namespace.array().of(
|
552
604
|
yup__namespace.object().shape({
|
553
|
-
id: yup__namespace.
|
605
|
+
id: yup__namespace.number().required()
|
554
606
|
})
|
555
607
|
);
|
556
608
|
} else if (typeof value === "object") {
|
@@ -602,6 +654,14 @@ const createAttributeSchema = (attribute) => {
|
|
602
654
|
if (!value || typeof value === "string" && value.length === 0) {
|
603
655
|
return true;
|
604
656
|
}
|
657
|
+
if (typeof value === "object") {
|
658
|
+
try {
|
659
|
+
JSON.stringify(value);
|
660
|
+
return true;
|
661
|
+
} catch (err) {
|
662
|
+
return false;
|
663
|
+
}
|
664
|
+
}
|
605
665
|
try {
|
606
666
|
JSON.parse(value);
|
607
667
|
return true;
|
@@ -620,13 +680,7 @@ const createAttributeSchema = (attribute) => {
|
|
620
680
|
return yup__namespace.mixed();
|
621
681
|
}
|
622
682
|
};
|
623
|
-
const
|
624
|
-
if (attribute.required && attribute.type !== "relation") {
|
625
|
-
return schema.required({
|
626
|
-
id: strapiAdmin.translatedErrors.required.id,
|
627
|
-
defaultMessage: "This field is required."
|
628
|
-
});
|
629
|
-
}
|
683
|
+
const nullableSchema = (schema) => {
|
630
684
|
return schema?.nullable ? schema.nullable() : (
|
631
685
|
// In some cases '.nullable' will not be available on the schema.
|
632
686
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -634,7 +688,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
634
688
|
schema
|
635
689
|
);
|
636
690
|
};
|
637
|
-
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
|
+
}
|
638
707
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
639
708
|
return schema.min(attribute.minLength, {
|
640
709
|
...strapiAdmin.translatedErrors.minLength,
|
@@ -656,10 +725,13 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
656
725
|
}
|
657
726
|
return schema;
|
658
727
|
};
|
659
|
-
const addMinValidation = (attribute) => (schema) => {
|
660
|
-
if ("
|
728
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
729
|
+
if (options.status === "draft") {
|
730
|
+
return schema;
|
731
|
+
}
|
732
|
+
if ("min" in attribute && "min" in schema) {
|
661
733
|
const min = toInteger(attribute.min);
|
662
|
-
if (
|
734
|
+
if (min) {
|
663
735
|
return schema.min(min, {
|
664
736
|
...strapiAdmin.translatedErrors.min,
|
665
737
|
values: {
|
@@ -777,19 +849,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
777
849
|
}, {});
|
778
850
|
return componentsByKey;
|
779
851
|
};
|
780
|
-
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);
|
781
951
|
const { toggleNotification } = strapiAdmin.useNotification();
|
782
952
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
953
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
783
954
|
const {
|
784
|
-
|
785
|
-
isLoading:
|
786
|
-
|
787
|
-
|
788
|
-
} =
|
789
|
-
|
790
|
-
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
791
|
-
});
|
792
|
-
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;
|
793
961
|
React__namespace.useEffect(() => {
|
794
962
|
if (error) {
|
795
963
|
toggleNotification({
|
@@ -797,39 +965,255 @@ const useDocument = (args, opts) => {
|
|
797
965
|
message: formatAPIError(error)
|
798
966
|
});
|
799
967
|
}
|
800
|
-
}, [
|
801
|
-
const
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
(document) => {
|
809
|
-
if (!validationSchema) {
|
810
|
-
throw new Error(
|
811
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
812
|
-
);
|
813
|
-
}
|
814
|
-
try {
|
815
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
816
|
-
return null;
|
817
|
-
} catch (error2) {
|
818
|
-
if (error2 instanceof yup.ValidationError) {
|
819
|
-
return strapiAdmin.getYupValidationErrors(error2);
|
820
|
-
}
|
821
|
-
throw error2;
|
822
|
-
}
|
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
|
823
976
|
},
|
824
|
-
[
|
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]
|
825
993
|
);
|
826
|
-
|
994
|
+
return {
|
995
|
+
error,
|
996
|
+
isLoading,
|
997
|
+
edit,
|
998
|
+
list: listLayout
|
999
|
+
};
|
1000
|
+
};
|
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;
|
827
1209
|
return {
|
828
1210
|
components,
|
829
1211
|
document: data?.data,
|
830
1212
|
meta: data?.meta,
|
831
1213
|
isLoading,
|
1214
|
+
hasError,
|
832
1215
|
schema,
|
1216
|
+
schemas,
|
833
1217
|
validate
|
834
1218
|
};
|
835
1219
|
};
|
@@ -843,22 +1227,60 @@ const useDoc = () => {
|
|
843
1227
|
if (!slug) {
|
844
1228
|
throw new Error("Could not find model in url params");
|
845
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;
|
846
1237
|
return {
|
847
1238
|
collectionType,
|
848
1239
|
model: slug,
|
849
|
-
id:
|
850
|
-
...
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
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
|
856
1281
|
};
|
857
1282
|
};
|
858
1283
|
const prefixPluginTranslations = (trad, pluginId) => {
|
859
|
-
if (!pluginId) {
|
860
|
-
throw new TypeError("pluginId can't be empty");
|
861
|
-
}
|
862
1284
|
return Object.keys(trad).reduce((acc, current) => {
|
863
1285
|
acc[`${pluginId}.${current}`] = trad[current];
|
864
1286
|
return acc;
|
@@ -874,6 +1296,8 @@ const useDocumentActions = () => {
|
|
874
1296
|
const { formatMessage } = reactIntl.useIntl();
|
875
1297
|
const { trackUsage } = strapiAdmin.useTracking();
|
876
1298
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1299
|
+
const navigate = reactRouterDom.useNavigate();
|
1300
|
+
const setCurrentStep = strapiAdmin.useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
877
1301
|
const [deleteDocument] = useDeleteDocumentMutation();
|
878
1302
|
const _delete = React__namespace.useCallback(
|
879
1303
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -1188,6 +1612,7 @@ const useDocumentActions = () => {
|
|
1188
1612
|
defaultMessage: "Saved document"
|
1189
1613
|
})
|
1190
1614
|
});
|
1615
|
+
setCurrentStep("contentManager.success");
|
1191
1616
|
return res.data;
|
1192
1617
|
} catch (err) {
|
1193
1618
|
toggleNotification({
|
@@ -1209,7 +1634,6 @@ const useDocumentActions = () => {
|
|
1209
1634
|
sourceId
|
1210
1635
|
});
|
1211
1636
|
if ("error" in res) {
|
1212
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1213
1637
|
return { error: res.error };
|
1214
1638
|
}
|
1215
1639
|
toggleNotification({
|
@@ -1228,7 +1652,7 @@ const useDocumentActions = () => {
|
|
1228
1652
|
throw err;
|
1229
1653
|
}
|
1230
1654
|
},
|
1231
|
-
[autoCloneDocument,
|
1655
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1232
1656
|
);
|
1233
1657
|
const [cloneDocument] = useCloneDocumentMutation();
|
1234
1658
|
const clone = React__namespace.useCallback(
|
@@ -1254,6 +1678,7 @@ const useDocumentActions = () => {
|
|
1254
1678
|
defaultMessage: "Cloned document"
|
1255
1679
|
})
|
1256
1680
|
});
|
1681
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1257
1682
|
return res.data;
|
1258
1683
|
} catch (err) {
|
1259
1684
|
toggleNotification({
|
@@ -1264,7 +1689,7 @@ const useDocumentActions = () => {
|
|
1264
1689
|
throw err;
|
1265
1690
|
}
|
1266
1691
|
},
|
1267
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1692
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1268
1693
|
);
|
1269
1694
|
const [getDoc] = useLazyGetDocumentQuery();
|
1270
1695
|
const getDocument = React__namespace.useCallback(
|
@@ -1289,10 +1714,10 @@ const useDocumentActions = () => {
|
|
1289
1714
|
update
|
1290
1715
|
};
|
1291
1716
|
};
|
1292
|
-
const ProtectedHistoryPage =
|
1293
|
-
() => Promise.resolve().then(() => require("./History-
|
1717
|
+
const ProtectedHistoryPage = React__namespace.lazy(
|
1718
|
+
() => Promise.resolve().then(() => require("./History-DrDJv698.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1294
1719
|
);
|
1295
|
-
const routes$
|
1720
|
+
const routes$2 = [
|
1296
1721
|
{
|
1297
1722
|
path: ":collectionType/:slug/:id/history",
|
1298
1723
|
Component: ProtectedHistoryPage
|
@@ -1302,32 +1727,45 @@ const routes$1 = [
|
|
1302
1727
|
Component: ProtectedHistoryPage
|
1303
1728
|
}
|
1304
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
|
+
];
|
1305
1743
|
const ProtectedEditViewPage = React.lazy(
|
1306
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1744
|
+
() => Promise.resolve().then(() => require("./EditViewPage-CDyTC6aU.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1307
1745
|
);
|
1308
1746
|
const ProtectedListViewPage = React.lazy(
|
1309
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1747
|
+
() => Promise.resolve().then(() => require("./ListViewPage-DTM2uO_S.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1310
1748
|
);
|
1311
1749
|
const ProtectedListConfiguration = React.lazy(
|
1312
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1750
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-zurIlUZ7.js")).then((mod) => ({
|
1313
1751
|
default: mod.ProtectedListConfiguration
|
1314
1752
|
}))
|
1315
1753
|
);
|
1316
1754
|
const ProtectedEditConfigurationPage = React.lazy(
|
1317
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1755
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-CF3lxOy2.js")).then((mod) => ({
|
1318
1756
|
default: mod.ProtectedEditConfigurationPage
|
1319
1757
|
}))
|
1320
1758
|
);
|
1321
1759
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1322
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-
|
1760
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-CJPoOvy3.js")).then((mod) => ({
|
1323
1761
|
default: mod.ProtectedComponentConfigurationPage
|
1324
1762
|
}))
|
1325
1763
|
);
|
1326
1764
|
const NoPermissions = React.lazy(
|
1327
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1765
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-DLzkS4Hy.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1328
1766
|
);
|
1329
1767
|
const NoContentType = React.lazy(
|
1330
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1768
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-BuZlNroO.js")).then((mod) => ({ default: mod.NoContentType }))
|
1331
1769
|
);
|
1332
1770
|
const CollectionTypePages = () => {
|
1333
1771
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1339,7 +1777,7 @@ const CollectionTypePages = () => {
|
|
1339
1777
|
const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
|
1340
1778
|
const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
|
1341
1779
|
const LIST_RELATIVE_PATH = ":collectionType/:slug";
|
1342
|
-
const LIST_PATH = `/content-manager
|
1780
|
+
const LIST_PATH = `/content-manager/collection-types/:slug`;
|
1343
1781
|
const routes = [
|
1344
1782
|
{
|
1345
1783
|
path: LIST_RELATIVE_PATH,
|
@@ -1373,6 +1811,7 @@ const routes = [
|
|
1373
1811
|
path: "no-content-types",
|
1374
1812
|
Component: NoContentType
|
1375
1813
|
},
|
1814
|
+
...routes$2,
|
1376
1815
|
...routes$1
|
1377
1816
|
];
|
1378
1817
|
const DocumentActions = ({ actions: actions2 }) => {
|
@@ -1441,12 +1880,14 @@ const DocumentActionButton = (action) => {
|
|
1441
1880
|
/* @__PURE__ */ jsxRuntime.jsx(
|
1442
1881
|
designSystem.Button,
|
1443
1882
|
{
|
1444
|
-
flex:
|
1883
|
+
flex: "auto",
|
1445
1884
|
startIcon: action.icon,
|
1446
1885
|
disabled: action.disabled,
|
1447
1886
|
onClick: handleClick(action),
|
1448
1887
|
justifyContent: "center",
|
1449
1888
|
variant: action.variant || "default",
|
1889
|
+
paddingTop: "7px",
|
1890
|
+
paddingBottom: "7px",
|
1450
1891
|
children: action.label
|
1451
1892
|
}
|
1452
1893
|
),
|
@@ -1454,7 +1895,7 @@ const DocumentActionButton = (action) => {
|
|
1454
1895
|
DocumentActionConfirmDialog,
|
1455
1896
|
{
|
1456
1897
|
...action.dialog,
|
1457
|
-
variant: action.variant,
|
1898
|
+
variant: action.dialog?.variant ?? action.variant,
|
1458
1899
|
isOpen: dialogId === action.id,
|
1459
1900
|
onClose: handleClose
|
1460
1901
|
}
|
@@ -1469,6 +1910,11 @@ const DocumentActionButton = (action) => {
|
|
1469
1910
|
) : null
|
1470
1911
|
] });
|
1471
1912
|
};
|
1913
|
+
const MenuItem = styledComponents.styled(designSystem.Menu.Item)`
|
1914
|
+
&:hover {
|
1915
|
+
background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
|
1916
|
+
}
|
1917
|
+
`;
|
1472
1918
|
const DocumentActionsMenu = ({
|
1473
1919
|
actions: actions2,
|
1474
1920
|
children,
|
@@ -1511,9 +1957,9 @@ const DocumentActionsMenu = ({
|
|
1511
1957
|
disabled: isDisabled,
|
1512
1958
|
size: "S",
|
1513
1959
|
endIcon: null,
|
1514
|
-
paddingTop: "
|
1515
|
-
paddingLeft: "
|
1516
|
-
paddingRight: "
|
1960
|
+
paddingTop: "4px",
|
1961
|
+
paddingLeft: "7px",
|
1962
|
+
paddingRight: "7px",
|
1517
1963
|
variant,
|
1518
1964
|
children: [
|
1519
1965
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
|
@@ -1524,36 +1970,35 @@ const DocumentActionsMenu = ({
|
|
1524
1970
|
]
|
1525
1971
|
}
|
1526
1972
|
),
|
1527
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, {
|
1973
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1528
1974
|
actions2.map((action) => {
|
1529
1975
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
1530
|
-
|
1976
|
+
MenuItem,
|
1531
1977
|
{
|
1532
1978
|
disabled: action.disabled,
|
1533
1979
|
onSelect: handleClick(action),
|
1534
1980
|
display: "block",
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
] })
|
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
|
+
) })
|
1557
2002
|
},
|
1558
2003
|
action.id
|
1559
2004
|
);
|
@@ -1633,11 +2078,11 @@ const DocumentActionConfirmDialog = ({
|
|
1633
2078
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
1634
2079
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
|
1635
2080
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
1636
|
-
/* @__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({
|
1637
2082
|
id: "app.components.Button.cancel",
|
1638
2083
|
defaultMessage: "Cancel"
|
1639
2084
|
}) }) }),
|
1640
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, children: formatMessage({
|
2085
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
1641
2086
|
id: "app.components.Button.confirm",
|
1642
2087
|
defaultMessage: "Confirm"
|
1643
2088
|
}) })
|
@@ -1660,10 +2105,22 @@ const DocumentActionModal = ({
|
|
1660
2105
|
};
|
1661
2106
|
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
|
1662
2107
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: title }) }),
|
1663
|
-
|
1664
|
-
|
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
|
1665
2110
|
] }) });
|
1666
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
|
+
};
|
1667
2124
|
const PublishAction$1 = ({
|
1668
2125
|
activeTab,
|
1669
2126
|
documentId,
|
@@ -1676,13 +2133,18 @@ const PublishAction$1 = ({
|
|
1676
2133
|
const navigate = reactRouterDom.useNavigate();
|
1677
2134
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1678
2135
|
const { _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
|
2136
|
+
const isListView = reactRouterDom.useMatch(LIST_PATH) !== null;
|
1679
2137
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2138
|
+
const { id } = reactRouterDom.useParams();
|
1680
2139
|
const { formatMessage } = reactIntl.useIntl();
|
1681
|
-
const { canPublish
|
1682
|
-
"PublishAction",
|
1683
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1684
|
-
);
|
2140
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1685
2141
|
const { publish } = useDocumentActions();
|
2142
|
+
const [
|
2143
|
+
countDraftRelations,
|
2144
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
2145
|
+
] = useLazyGetDraftRelationCountQuery();
|
2146
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React__namespace.useState(0);
|
2147
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React__namespace.useState(0);
|
1686
2148
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1687
2149
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1688
2150
|
const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1691,10 +2153,107 @@ const PublishAction$1 = ({
|
|
1691
2153
|
const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
|
1692
2154
|
const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
|
1693
2155
|
const formValues = strapiAdmin.useForm("PublishAction", ({ values }) => values);
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
2156
|
+
React__namespace.useEffect(() => {
|
2157
|
+
if (isErrorDraftRelations) {
|
2158
|
+
toggleNotification({
|
2159
|
+
type: "danger",
|
2160
|
+
message: formatMessage({
|
2161
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
2162
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
2163
|
+
})
|
2164
|
+
});
|
2165
|
+
}
|
2166
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
2167
|
+
React__namespace.useEffect(() => {
|
2168
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
2169
|
+
const extractDraftRelations = (data) => {
|
2170
|
+
const relations = data.connect || [];
|
2171
|
+
relations.forEach((relation) => {
|
2172
|
+
if (relation.status === "draft") {
|
2173
|
+
localDraftRelations.add(relation.id);
|
2174
|
+
}
|
2175
|
+
});
|
2176
|
+
};
|
2177
|
+
const traverseAndExtract = (data) => {
|
2178
|
+
Object.entries(data).forEach(([key, value]) => {
|
2179
|
+
if (key === "connect" && Array.isArray(value)) {
|
2180
|
+
extractDraftRelations({ connect: value });
|
2181
|
+
} else if (typeof value === "object" && value !== null) {
|
2182
|
+
traverseAndExtract(value);
|
2183
|
+
}
|
2184
|
+
});
|
2185
|
+
};
|
2186
|
+
if (!documentId || modified) {
|
2187
|
+
traverseAndExtract(formValues);
|
2188
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
2189
|
+
}
|
2190
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
2191
|
+
React__namespace.useEffect(() => {
|
2192
|
+
if (!document || !document.documentId || isListView) {
|
2193
|
+
return;
|
2194
|
+
}
|
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]);
|
2211
|
+
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
2212
|
+
if (!schema?.options?.draftAndPublish) {
|
2213
|
+
return null;
|
1697
2214
|
}
|
2215
|
+
const performPublish = async () => {
|
2216
|
+
setSubmitting(true);
|
2217
|
+
try {
|
2218
|
+
const { errors } = await validate(true, {
|
2219
|
+
status: "published"
|
2220
|
+
});
|
2221
|
+
if (errors) {
|
2222
|
+
toggleNotification({
|
2223
|
+
type: "danger",
|
2224
|
+
message: formatMessage({
|
2225
|
+
id: "content-manager.validation.error",
|
2226
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2227
|
+
})
|
2228
|
+
});
|
2229
|
+
return;
|
2230
|
+
}
|
2231
|
+
const res = await publish(
|
2232
|
+
{
|
2233
|
+
collectionType,
|
2234
|
+
model,
|
2235
|
+
documentId,
|
2236
|
+
params
|
2237
|
+
},
|
2238
|
+
transformData(formValues)
|
2239
|
+
);
|
2240
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2241
|
+
if (id === "create") {
|
2242
|
+
navigate({
|
2243
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2244
|
+
search: rawQuery
|
2245
|
+
});
|
2246
|
+
}
|
2247
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2248
|
+
setErrors(formatValidationErrors(res.error));
|
2249
|
+
}
|
2250
|
+
} finally {
|
2251
|
+
setSubmitting(false);
|
2252
|
+
}
|
2253
|
+
};
|
2254
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
2255
|
+
const enableDraftRelationsCount = false;
|
2256
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1698
2257
|
return {
|
1699
2258
|
/**
|
1700
2259
|
* Disabled when:
|
@@ -1704,52 +2263,40 @@ const PublishAction$1 = ({
|
|
1704
2263
|
* - the document is already published & not modified
|
1705
2264
|
* - the document is being created & not modified
|
1706
2265
|
* - the user doesn't have the permission to publish
|
1707
|
-
* - the user doesn't have the permission to create a new document
|
1708
|
-
* - the user doesn't have the permission to update the document
|
1709
2266
|
*/
|
1710
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
2267
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1711
2268
|
label: formatMessage({
|
1712
2269
|
id: "app.utils.publish",
|
1713
2270
|
defaultMessage: "Publish"
|
1714
2271
|
}),
|
1715
2272
|
onClick: async () => {
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1731
|
-
|
1732
|
-
|
1733
|
-
documentId,
|
1734
|
-
params
|
1735
|
-
},
|
1736
|
-
formValues
|
1737
|
-
);
|
1738
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1739
|
-
navigate({
|
1740
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1741
|
-
search: rawQuery
|
1742
|
-
});
|
1743
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1744
|
-
setErrors(formatValidationErrors(res.error));
|
2273
|
+
await performPublish();
|
2274
|
+
},
|
2275
|
+
dialog: hasDraftRelations ? {
|
2276
|
+
type: "dialog",
|
2277
|
+
variant: "danger",
|
2278
|
+
footer: null,
|
2279
|
+
title: formatMessage({
|
2280
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
2281
|
+
defaultMessage: "Confirmation"
|
2282
|
+
}),
|
2283
|
+
content: formatMessage(
|
2284
|
+
{
|
2285
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
2286
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
2287
|
+
},
|
2288
|
+
{
|
2289
|
+
count: totalDraftRelations
|
1745
2290
|
}
|
1746
|
-
|
1747
|
-
|
2291
|
+
),
|
2292
|
+
onConfirm: async () => {
|
2293
|
+
await performPublish();
|
1748
2294
|
}
|
1749
|
-
}
|
2295
|
+
} : void 0
|
1750
2296
|
};
|
1751
2297
|
};
|
1752
2298
|
PublishAction$1.type = "publish";
|
2299
|
+
PublishAction$1.position = "panel";
|
1753
2300
|
const UpdateAction = ({
|
1754
2301
|
activeTab,
|
1755
2302
|
documentId,
|
@@ -1762,10 +2309,6 @@ const UpdateAction = ({
|
|
1762
2309
|
const cloneMatch = reactRouterDom.useMatch(CLONE_PATH);
|
1763
2310
|
const isCloning = cloneMatch !== null;
|
1764
2311
|
const { formatMessage } = reactIntl.useIntl();
|
1765
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1766
|
-
canCreate: canCreate2,
|
1767
|
-
canUpdate: canUpdate2
|
1768
|
-
}));
|
1769
2312
|
const { create, update, clone } = useDocumentActions();
|
1770
2313
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1771
2314
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
@@ -1776,93 +2319,134 @@ const UpdateAction = ({
|
|
1776
2319
|
const validate = strapiAdmin.useForm("UpdateAction", (state) => state.validate);
|
1777
2320
|
const setErrors = strapiAdmin.useForm("UpdateAction", (state) => state.setErrors);
|
1778
2321
|
const resetForm = strapiAdmin.useForm("PublishAction", ({ resetForm: resetForm2 }) => resetForm2);
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
}
|
1805
|
-
|
1806
|
-
|
1807
|
-
if (
|
1808
|
-
|
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(
|
1809
2352
|
{
|
1810
|
-
|
1811
|
-
documentId: cloneMatch.params.origin,
|
1812
|
-
params
|
1813
|
-
},
|
1814
|
-
document
|
1815
|
-
);
|
1816
|
-
if ("data" in res) {
|
1817
|
-
navigate({
|
1818
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2353
|
+
pathname: `../${res.data.documentId}`,
|
1819
2354
|
search: rawQuery
|
1820
|
-
});
|
1821
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1822
|
-
setErrors(formatValidationErrors(res.error));
|
1823
|
-
}
|
1824
|
-
} else if (documentId || collectionType === SINGLE_TYPES) {
|
1825
|
-
const res = await update(
|
1826
|
-
{
|
1827
|
-
collectionType,
|
1828
|
-
model,
|
1829
|
-
documentId,
|
1830
|
-
params
|
1831
2355
|
},
|
1832
|
-
|
2356
|
+
{ relative: "path" }
|
1833
2357
|
);
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
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));
|
1839
2373
|
} else {
|
1840
|
-
|
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(
|
1841
2386
|
{
|
1842
|
-
|
1843
|
-
|
2387
|
+
pathname: `../${res.data.documentId}`,
|
2388
|
+
search: rawQuery
|
1844
2389
|
},
|
1845
|
-
|
2390
|
+
{ replace: true, relative: "path" }
|
1846
2391
|
);
|
1847
|
-
|
1848
|
-
|
1849
|
-
{
|
1850
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1851
|
-
search: rawQuery
|
1852
|
-
},
|
1853
|
-
{ replace: true }
|
1854
|
-
);
|
1855
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1856
|
-
setErrors(formatValidationErrors(res.error));
|
1857
|
-
}
|
2392
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2393
|
+
setErrors(formatValidationErrors(res.error));
|
1858
2394
|
}
|
1859
|
-
} finally {
|
1860
|
-
setSubmitting(false);
|
1861
2395
|
}
|
2396
|
+
} finally {
|
2397
|
+
setSubmitting(false);
|
1862
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
|
1863
2446
|
};
|
1864
2447
|
};
|
1865
2448
|
UpdateAction.type = "update";
|
2449
|
+
UpdateAction.position = "panel";
|
1866
2450
|
const UNPUBLISH_DRAFT_OPTIONS = {
|
1867
2451
|
KEEP: "keep",
|
1868
2452
|
DISCARD: "discard"
|
@@ -1895,7 +2479,7 @@ const UnpublishAction$1 = ({
|
|
1895
2479
|
id: "app.utils.unpublish",
|
1896
2480
|
defaultMessage: "Unpublish"
|
1897
2481
|
}),
|
1898
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2482
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
1899
2483
|
onClick: async () => {
|
1900
2484
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1901
2485
|
if (!documentId) {
|
@@ -1985,6 +2569,7 @@ const UnpublishAction$1 = ({
|
|
1985
2569
|
};
|
1986
2570
|
};
|
1987
2571
|
UnpublishAction$1.type = "unpublish";
|
2572
|
+
UnpublishAction$1.position = "panel";
|
1988
2573
|
const DiscardAction = ({
|
1989
2574
|
activeTab,
|
1990
2575
|
documentId,
|
@@ -2007,7 +2592,7 @@ const DiscardAction = ({
|
|
2007
2592
|
id: "content-manager.actions.discard.label",
|
2008
2593
|
defaultMessage: "Discard changes"
|
2009
2594
|
}),
|
2010
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2595
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
2011
2596
|
position: ["panel", "table-row"],
|
2012
2597
|
variant: "danger",
|
2013
2598
|
dialog: {
|
@@ -2035,11 +2620,7 @@ const DiscardAction = ({
|
|
2035
2620
|
};
|
2036
2621
|
};
|
2037
2622
|
DiscardAction.type = "discard";
|
2038
|
-
|
2039
|
-
path {
|
2040
|
-
fill: currentColor;
|
2041
|
-
}
|
2042
|
-
`;
|
2623
|
+
DiscardAction.position = "panel";
|
2043
2624
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2044
2625
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2045
2626
|
const RelativeTime = React__namespace.forwardRef(
|
@@ -2052,7 +2633,7 @@ const RelativeTime = React__namespace.forwardRef(
|
|
2052
2633
|
});
|
2053
2634
|
const unit = intervals.find((intervalUnit) => {
|
2054
2635
|
return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
|
2055
|
-
});
|
2636
|
+
}) ?? "seconds";
|
2056
2637
|
const relativeTime = dateFns.isPast(timestamp) ? -interval[unit] : interval[unit];
|
2057
2638
|
const customInterval = customIntervals.find(
|
2058
2639
|
(custom) => interval[custom.unit] < custom.threshold
|
@@ -2086,34 +2667,34 @@ const getDisplayName = ({
|
|
2086
2667
|
return email ?? "";
|
2087
2668
|
};
|
2088
2669
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2089
|
-
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2090
|
-
const statusVariant = status === "draft" ? "
|
2091
|
-
|
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
|
+
}) }) });
|
2092
2677
|
};
|
2093
2678
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2094
2679
|
const { formatMessage } = reactIntl.useIntl();
|
2095
2680
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2681
|
+
const params = reactRouterDom.useParams();
|
2096
2682
|
const title = isCreating ? formatMessage({
|
2097
2683
|
id: "content-manager.containers.edit.title.new",
|
2098
2684
|
defaultMessage: "Create an entry"
|
2099
2685
|
}) : documentTitle;
|
2100
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2101
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
2102
|
-
|
2103
|
-
designSystem.Flex,
|
2686
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2687
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2688
|
+
strapiAdmin.BackButton,
|
2104
2689
|
{
|
2105
|
-
|
2106
|
-
justifyContent: "space-between",
|
2107
|
-
paddingTop: 1,
|
2108
|
-
gap: "80px",
|
2109
|
-
alignItems: "flex-start",
|
2110
|
-
children: [
|
2111
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2112
|
-
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2113
|
-
]
|
2690
|
+
fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
|
2114
2691
|
}
|
2115
2692
|
),
|
2116
|
-
|
2693
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2694
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2695
|
+
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2696
|
+
] }),
|
2697
|
+
status ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2117
2698
|
] });
|
2118
2699
|
};
|
2119
2700
|
const HeaderToolbar = () => {
|
@@ -2159,7 +2740,7 @@ const HeaderToolbar = () => {
|
|
2159
2740
|
meta: isCloning ? void 0 : meta,
|
2160
2741
|
collectionType
|
2161
2742
|
},
|
2162
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2743
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("header"),
|
2163
2744
|
children: (actions2) => {
|
2164
2745
|
const headerActions = actions2.filter((action) => {
|
2165
2746
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -2196,12 +2777,12 @@ const Information = ({ activeTab }) => {
|
|
2196
2777
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2197
2778
|
label: formatMessage({
|
2198
2779
|
id: "content-manager.containers.edit.information.last-published.label",
|
2199
|
-
defaultMessage: "
|
2780
|
+
defaultMessage: "Published"
|
2200
2781
|
}),
|
2201
2782
|
value: formatMessage(
|
2202
2783
|
{
|
2203
2784
|
id: "content-manager.containers.edit.information.last-published.value",
|
2204
|
-
defaultMessage: `
|
2785
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2205
2786
|
},
|
2206
2787
|
{
|
2207
2788
|
time: /* @__PURE__ */ jsxRuntime.jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2214,12 +2795,12 @@ const Information = ({ activeTab }) => {
|
|
2214
2795
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2215
2796
|
label: formatMessage({
|
2216
2797
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2217
|
-
defaultMessage: "
|
2798
|
+
defaultMessage: "Updated"
|
2218
2799
|
}),
|
2219
2800
|
value: formatMessage(
|
2220
2801
|
{
|
2221
2802
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2222
|
-
defaultMessage: `
|
2803
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2223
2804
|
},
|
2224
2805
|
{
|
2225
2806
|
time: /* @__PURE__ */ jsxRuntime.jsx(
|
@@ -2237,12 +2818,12 @@ const Information = ({ activeTab }) => {
|
|
2237
2818
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2238
2819
|
label: formatMessage({
|
2239
2820
|
id: "content-manager.containers.edit.information.document.label",
|
2240
|
-
defaultMessage: "
|
2821
|
+
defaultMessage: "Created"
|
2241
2822
|
}),
|
2242
2823
|
value: formatMessage(
|
2243
2824
|
{
|
2244
2825
|
id: "content-manager.containers.edit.information.document.value",
|
2245
|
-
defaultMessage: `
|
2826
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2246
2827
|
},
|
2247
2828
|
{
|
2248
2829
|
time: /* @__PURE__ */ jsxRuntime.jsx(
|
@@ -2280,25 +2861,77 @@ const Information = ({ activeTab }) => {
|
|
2280
2861
|
);
|
2281
2862
|
};
|
2282
2863
|
const HeaderActions = ({ actions: actions2 }) => {
|
2283
|
-
|
2284
|
-
|
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) {
|
2285
2880
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
2286
2881
|
designSystem.SingleSelect,
|
2287
2882
|
{
|
2288
2883
|
size: "S",
|
2289
|
-
disabled: action.disabled,
|
2290
|
-
"aria-label": action.label,
|
2291
2884
|
onChange: action.onSelect,
|
2292
|
-
|
2885
|
+
"aria-label": action.label,
|
2886
|
+
...action,
|
2293
2887
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { ...option, children: label }, option.value))
|
2294
2888
|
},
|
2295
2889
|
action.id
|
2296
2890
|
);
|
2297
2891
|
} else {
|
2298
|
-
|
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
|
+
}
|
2299
2914
|
}
|
2300
2915
|
}) });
|
2301
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
|
+
};
|
2302
2935
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2303
2936
|
const navigate = reactRouterDom.useNavigate();
|
2304
2937
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2315,6 +2948,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2315
2948
|
};
|
2316
2949
|
};
|
2317
2950
|
ConfigureTheViewAction.type = "configure-the-view";
|
2951
|
+
ConfigureTheViewAction.position = "header";
|
2318
2952
|
const EditTheModelAction = ({ model }) => {
|
2319
2953
|
const navigate = reactRouterDom.useNavigate();
|
2320
2954
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2331,6 +2965,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2331
2965
|
};
|
2332
2966
|
};
|
2333
2967
|
EditTheModelAction.type = "edit-the-model";
|
2968
|
+
EditTheModelAction.position = "header";
|
2334
2969
|
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2335
2970
|
const navigate = reactRouterDom.useNavigate();
|
2336
2971
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2339,12 +2974,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2339
2974
|
const { delete: deleteAction } = useDocumentActions();
|
2340
2975
|
const { toggleNotification } = strapiAdmin.useNotification();
|
2341
2976
|
const setSubmitting = strapiAdmin.useForm("DeleteAction", (state) => state.setSubmitting);
|
2977
|
+
const isLocalized = document?.locale != null;
|
2342
2978
|
return {
|
2343
2979
|
disabled: !canDelete || !document,
|
2344
|
-
label: formatMessage(
|
2345
|
-
|
2346
|
-
|
2347
|
-
|
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
|
+
),
|
2348
2987
|
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2349
2988
|
dialog: {
|
2350
2989
|
type: "dialog",
|
@@ -2400,403 +3039,102 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2400
3039
|
};
|
2401
3040
|
};
|
2402
3041
|
DeleteAction$1.type = "delete";
|
3042
|
+
DeleteAction$1.position = ["header", "table-row"];
|
2403
3043
|
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2404
3044
|
const Panels = () => {
|
2405
|
-
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2406
|
-
const [
|
2407
|
-
{
|
2408
|
-
query: { status }
|
2409
|
-
}
|
2410
|
-
] = strapiAdmin.useQueryParams({
|
2411
|
-
status: "draft"
|
2412
|
-
});
|
2413
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2414
|
-
const plugins = strapiAdmin.useStrapiApp("Panels", (state) => state.plugins);
|
2415
|
-
const props = {
|
2416
|
-
activeTab: status,
|
2417
|
-
model,
|
2418
|
-
documentId: id,
|
2419
|
-
document: isCloning ? void 0 : document,
|
2420
|
-
meta: isCloning ? void 0 : meta,
|
2421
|
-
collectionType
|
2422
|
-
};
|
2423
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
2424
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2425
|
-
{
|
2426
|
-
props,
|
2427
|
-
descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
|
2428
|
-
children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsxRuntime.jsx(Panel, { ...description, children: content }, id2))
|
2429
|
-
}
|
2430
|
-
) });
|
2431
|
-
};
|
2432
|
-
const ActionsPanel = () => {
|
2433
|
-
const { formatMessage } = reactIntl.useIntl();
|
2434
|
-
return {
|
2435
|
-
title: formatMessage({
|
2436
|
-
id: "content-manager.containers.edit.panels.default.title",
|
2437
|
-
defaultMessage: "Document"
|
2438
|
-
}),
|
2439
|
-
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2440
|
-
};
|
2441
|
-
};
|
2442
|
-
ActionsPanel.type = "actions";
|
2443
|
-
const ActionsPanelContent = () => {
|
2444
|
-
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2445
|
-
const [
|
2446
|
-
{
|
2447
|
-
query: { status = "draft" }
|
2448
|
-
}
|
2449
|
-
] = strapiAdmin.useQueryParams();
|
2450
|
-
const { model, id, document, meta, collectionType } = useDoc();
|
2451
|
-
const plugins = strapiAdmin.useStrapiApp("ActionsPanel", (state) => state.plugins);
|
2452
|
-
const props = {
|
2453
|
-
activeTab: status,
|
2454
|
-
model,
|
2455
|
-
documentId: id,
|
2456
|
-
document: isCloning ? void 0 : document,
|
2457
|
-
meta: isCloning ? void 0 : meta,
|
2458
|
-
collectionType
|
2459
|
-
};
|
2460
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, width: "100%", children: [
|
2461
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
2462
|
-
strapiAdmin.DescriptionComponentRenderer,
|
2463
|
-
{
|
2464
|
-
props,
|
2465
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2466
|
-
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
2467
|
-
}
|
2468
|
-
),
|
2469
|
-
/* @__PURE__ */ jsxRuntime.jsx(InjectionZone, { area: "editView.right-links", slug: model })
|
2470
|
-
] });
|
2471
|
-
};
|
2472
|
-
const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
2473
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
2474
|
-
designSystem.Flex,
|
2475
|
-
{
|
2476
|
-
ref,
|
2477
|
-
tag: "aside",
|
2478
|
-
"aria-labelledby": "additional-information",
|
2479
|
-
background: "neutral0",
|
2480
|
-
borderColor: "neutral150",
|
2481
|
-
hasRadius: true,
|
2482
|
-
paddingBottom: 4,
|
2483
|
-
paddingLeft: 4,
|
2484
|
-
paddingRight: 4,
|
2485
|
-
paddingTop: 4,
|
2486
|
-
shadow: "tableShadow",
|
2487
|
-
gap: 3,
|
2488
|
-
direction: "column",
|
2489
|
-
justifyContent: "stretch",
|
2490
|
-
alignItems: "flex-start",
|
2491
|
-
children: [
|
2492
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
2493
|
-
children
|
2494
|
-
]
|
2495
|
-
}
|
2496
|
-
);
|
2497
|
-
});
|
2498
|
-
const HOOKS = {
|
2499
|
-
/**
|
2500
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2501
|
-
* @constant
|
2502
|
-
* @type {string}
|
2503
|
-
*/
|
2504
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2505
|
-
/**
|
2506
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2507
|
-
* @constant
|
2508
|
-
* @type {string}
|
2509
|
-
*/
|
2510
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2511
|
-
/**
|
2512
|
-
* Hook that allows to mutate the CM's edit view layout
|
2513
|
-
* @constant
|
2514
|
-
* @type {string}
|
2515
|
-
*/
|
2516
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2517
|
-
/**
|
2518
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2519
|
-
* @constant
|
2520
|
-
* @type {string}
|
2521
|
-
*/
|
2522
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2523
|
-
};
|
2524
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2525
|
-
endpoints: (builder) => ({
|
2526
|
-
getContentTypeConfiguration: builder.query({
|
2527
|
-
query: (uid) => ({
|
2528
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2529
|
-
method: "GET"
|
2530
|
-
}),
|
2531
|
-
transformResponse: (response) => response.data,
|
2532
|
-
providesTags: (_result, _error, uid) => [
|
2533
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2534
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2535
|
-
]
|
2536
|
-
}),
|
2537
|
-
getAllContentTypeSettings: builder.query({
|
2538
|
-
query: () => "/content-manager/content-types-settings",
|
2539
|
-
transformResponse: (response) => response.data,
|
2540
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2541
|
-
}),
|
2542
|
-
updateContentTypeConfiguration: builder.mutation({
|
2543
|
-
query: ({ uid, ...body }) => ({
|
2544
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2545
|
-
method: "PUT",
|
2546
|
-
data: body
|
2547
|
-
}),
|
2548
|
-
transformResponse: (response) => response.data,
|
2549
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2550
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2551
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2552
|
-
// Is this necessary?
|
2553
|
-
{ type: "InitialData" }
|
2554
|
-
]
|
2555
|
-
})
|
2556
|
-
})
|
2557
|
-
});
|
2558
|
-
const {
|
2559
|
-
useGetContentTypeConfigurationQuery,
|
2560
|
-
useGetAllContentTypeSettingsQuery,
|
2561
|
-
useUpdateContentTypeConfigurationMutation
|
2562
|
-
} = contentTypesApi;
|
2563
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2564
|
-
const { type } = attribute;
|
2565
|
-
if (type === "relation") {
|
2566
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2567
|
-
}
|
2568
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2569
|
-
};
|
2570
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2571
|
-
if (!mainFieldName) {
|
2572
|
-
return void 0;
|
2573
|
-
}
|
2574
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2575
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2576
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2577
|
-
);
|
2578
|
-
return {
|
2579
|
-
name: mainFieldName,
|
2580
|
-
type: mainFieldType ?? "string"
|
2581
|
-
};
|
2582
|
-
};
|
2583
|
-
const DEFAULT_SETTINGS = {
|
2584
|
-
bulkable: false,
|
2585
|
-
filterable: false,
|
2586
|
-
searchable: false,
|
2587
|
-
pagination: false,
|
2588
|
-
defaultSortBy: "",
|
2589
|
-
defaultSortOrder: "asc",
|
2590
|
-
mainField: "id",
|
2591
|
-
pageSize: 10
|
2592
|
-
};
|
2593
|
-
const useDocumentLayout = (model) => {
|
2594
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2595
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
2596
|
-
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2597
|
-
const { toggleNotification } = strapiAdmin.useNotification();
|
2598
|
-
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
2599
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2600
|
-
const {
|
2601
|
-
data,
|
2602
|
-
isLoading: isLoadingConfigs,
|
2603
|
-
error,
|
2604
|
-
isFetching: isFetchingConfigs
|
2605
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2606
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2607
|
-
React__namespace.useEffect(() => {
|
2608
|
-
if (error) {
|
2609
|
-
toggleNotification({
|
2610
|
-
type: "danger",
|
2611
|
-
message: formatAPIError(error)
|
2612
|
-
});
|
2613
|
-
}
|
2614
|
-
}, [error, formatAPIError, toggleNotification]);
|
2615
|
-
const editLayout = React__namespace.useMemo(
|
2616
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2617
|
-
layout: [],
|
2618
|
-
components: {},
|
2619
|
-
metadatas: {},
|
2620
|
-
options: {},
|
2621
|
-
settings: DEFAULT_SETTINGS
|
2622
|
-
},
|
2623
|
-
[data, isLoading, schemas, schema, components]
|
2624
|
-
);
|
2625
|
-
const listLayout = React__namespace.useMemo(() => {
|
2626
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2627
|
-
layout: [],
|
2628
|
-
metadatas: {},
|
2629
|
-
options: {},
|
2630
|
-
settings: DEFAULT_SETTINGS
|
2631
|
-
};
|
2632
|
-
}, [data, isLoading, schemas, schema, components]);
|
2633
|
-
const { layout: edit } = React__namespace.useMemo(
|
2634
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2635
|
-
layout: editLayout,
|
2636
|
-
query
|
2637
|
-
}),
|
2638
|
-
[editLayout, query, runHookWaterfall]
|
2639
|
-
);
|
2640
|
-
return {
|
2641
|
-
error,
|
2642
|
-
isLoading,
|
2643
|
-
edit,
|
2644
|
-
list: listLayout
|
2645
|
-
};
|
2646
|
-
};
|
2647
|
-
const useDocLayout = () => {
|
2648
|
-
const { model } = useDoc();
|
2649
|
-
return useDocumentLayout(model);
|
2650
|
-
};
|
2651
|
-
const formatEditLayout = (data, {
|
2652
|
-
schemas,
|
2653
|
-
schema,
|
2654
|
-
components
|
2655
|
-
}) => {
|
2656
|
-
let currentPanelIndex = 0;
|
2657
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2658
|
-
data.contentType.layouts.edit,
|
2659
|
-
schema?.attributes,
|
2660
|
-
data.contentType.metadatas,
|
2661
|
-
{ configurations: data.components, schemas: components },
|
2662
|
-
schemas
|
2663
|
-
).reduce((panels, row) => {
|
2664
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2665
|
-
panels.push([row]);
|
2666
|
-
currentPanelIndex += 2;
|
2667
|
-
} else {
|
2668
|
-
if (!panels[currentPanelIndex]) {
|
2669
|
-
panels.push([]);
|
2670
|
-
}
|
2671
|
-
panels[currentPanelIndex].push(row);
|
2672
|
-
}
|
2673
|
-
return panels;
|
2674
|
-
}, []);
|
2675
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2676
|
-
(acc, [uid, configuration]) => {
|
2677
|
-
acc[uid] = {
|
2678
|
-
layout: convertEditLayoutToFieldLayouts(
|
2679
|
-
configuration.layouts.edit,
|
2680
|
-
components[uid].attributes,
|
2681
|
-
configuration.metadatas
|
2682
|
-
),
|
2683
|
-
settings: {
|
2684
|
-
...configuration.settings,
|
2685
|
-
icon: components[uid].info.icon,
|
2686
|
-
displayName: components[uid].info.displayName
|
2687
|
-
}
|
2688
|
-
};
|
2689
|
-
return acc;
|
2690
|
-
},
|
2691
|
-
{}
|
2692
|
-
);
|
2693
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2694
|
-
(acc, [attribute, metadata]) => {
|
2695
|
-
return {
|
2696
|
-
...acc,
|
2697
|
-
[attribute]: metadata.edit
|
2698
|
-
};
|
2699
|
-
},
|
2700
|
-
{}
|
2701
|
-
);
|
2702
|
-
return {
|
2703
|
-
layout: panelledEditAttributes,
|
2704
|
-
components: componentEditAttributes,
|
2705
|
-
metadatas: editMetadatas,
|
2706
|
-
settings: {
|
2707
|
-
...data.contentType.settings,
|
2708
|
-
displayName: schema?.info.displayName
|
2709
|
-
},
|
2710
|
-
options: {
|
2711
|
-
...schema?.options,
|
2712
|
-
...schema?.pluginOptions,
|
2713
|
-
...data.contentType.options
|
3045
|
+
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
3046
|
+
const [
|
3047
|
+
{
|
3048
|
+
query: { status }
|
2714
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
|
2715
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
|
+
) });
|
2716
3071
|
};
|
2717
|
-
const
|
2718
|
-
|
2719
|
-
(row) => row.map((field) => {
|
2720
|
-
const attribute = attributes[field.name];
|
2721
|
-
if (!attribute) {
|
2722
|
-
return null;
|
2723
|
-
}
|
2724
|
-
const { edit: metadata } = metadatas[field.name];
|
2725
|
-
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2726
|
-
return {
|
2727
|
-
attribute,
|
2728
|
-
disabled: !metadata.editable,
|
2729
|
-
hint: metadata.description,
|
2730
|
-
label: metadata.label ?? "",
|
2731
|
-
name: field.name,
|
2732
|
-
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
2733
|
-
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2734
|
-
schemas,
|
2735
|
-
components: components?.schemas ?? {}
|
2736
|
-
}),
|
2737
|
-
placeholder: metadata.placeholder ?? "",
|
2738
|
-
required: attribute.required ?? false,
|
2739
|
-
size: field.size,
|
2740
|
-
unique: "unique" in attribute ? attribute.unique : false,
|
2741
|
-
visible: metadata.visible ?? true,
|
2742
|
-
type: attribute.type
|
2743
|
-
};
|
2744
|
-
}).filter((field) => field !== null)
|
2745
|
-
);
|
2746
|
-
};
|
2747
|
-
const formatListLayout = (data, {
|
2748
|
-
schemas,
|
2749
|
-
schema,
|
2750
|
-
components
|
2751
|
-
}) => {
|
2752
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2753
|
-
(acc, [attribute, metadata]) => {
|
2754
|
-
return {
|
2755
|
-
...acc,
|
2756
|
-
[attribute]: metadata.list
|
2757
|
-
};
|
2758
|
-
},
|
2759
|
-
{}
|
2760
|
-
);
|
2761
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2762
|
-
data.contentType.layouts.list,
|
2763
|
-
schema?.attributes,
|
2764
|
-
listMetadatas,
|
2765
|
-
{ configurations: data.components, schemas: components },
|
2766
|
-
schemas
|
2767
|
-
);
|
3072
|
+
const ActionsPanel = () => {
|
3073
|
+
const { formatMessage } = reactIntl.useIntl();
|
2768
3074
|
return {
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
|
2774
|
-
...schema?.pluginOptions,
|
2775
|
-
...data.contentType.options
|
2776
|
-
}
|
3075
|
+
title: formatMessage({
|
3076
|
+
id: "content-manager.containers.edit.panels.default.title",
|
3077
|
+
defaultMessage: "Entry"
|
3078
|
+
}),
|
3079
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2777
3080
|
};
|
2778
3081
|
};
|
2779
|
-
|
2780
|
-
|
2781
|
-
|
2782
|
-
|
2783
|
-
|
3082
|
+
ActionsPanel.type = "actions";
|
3083
|
+
const ActionsPanelContent = () => {
|
3084
|
+
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
3085
|
+
const [
|
3086
|
+
{
|
3087
|
+
query: { status = "draft" }
|
2784
3088
|
}
|
2785
|
-
|
2786
|
-
|
2787
|
-
|
2788
|
-
|
2789
|
-
|
2790
|
-
|
2791
|
-
|
2792
|
-
|
2793
|
-
|
2794
|
-
|
2795
|
-
|
2796
|
-
|
2797
|
-
|
2798
|
-
|
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
|
+
] });
|
2799
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
|
+
});
|
2800
3138
|
const ConfirmBulkActionDialog = ({
|
2801
3139
|
onToggleDialog,
|
2802
3140
|
isOpen = false,
|
@@ -2804,7 +3142,7 @@ const ConfirmBulkActionDialog = ({
|
|
2804
3142
|
endAction
|
2805
3143
|
}) => {
|
2806
3144
|
const { formatMessage } = reactIntl.useIntl();
|
2807
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, {
|
3145
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2808
3146
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
|
2809
3147
|
id: "app.components.ConfirmDialog.title",
|
2810
3148
|
defaultMessage: "Confirmation"
|
@@ -2835,6 +3173,7 @@ const ConfirmDialogPublishAll = ({
|
|
2835
3173
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
|
2836
3174
|
const { model, schema } = useDoc();
|
2837
3175
|
const [{ query }] = strapiAdmin.useQueryParams();
|
3176
|
+
const enableDraftRelationsCount = false;
|
2838
3177
|
const {
|
2839
3178
|
data: countDraftRelations = 0,
|
2840
3179
|
isLoading,
|
@@ -2846,7 +3185,7 @@ const ConfirmDialogPublishAll = ({
|
|
2846
3185
|
locale: query?.plugins?.i18n?.locale
|
2847
3186
|
},
|
2848
3187
|
{
|
2849
|
-
skip:
|
3188
|
+
skip: !enableDraftRelationsCount
|
2850
3189
|
}
|
2851
3190
|
);
|
2852
3191
|
React__namespace.useEffect(() => {
|
@@ -3031,7 +3370,7 @@ const SelectedEntriesTableContent = ({
|
|
3031
3370
|
status: row.status
|
3032
3371
|
}
|
3033
3372
|
) }),
|
3034
|
-
/* @__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(
|
3035
3374
|
designSystem.IconButton,
|
3036
3375
|
{
|
3037
3376
|
tag: reactRouterDom.Link,
|
@@ -3040,23 +3379,16 @@ const SelectedEntriesTableContent = ({
|
|
3040
3379
|
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3041
3380
|
},
|
3042
3381
|
state: { from: pathname },
|
3043
|
-
label: formatMessage(
|
3044
|
-
|
3045
|
-
|
3046
|
-
|
3047
|
-
{
|
3048
|
-
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3049
|
-
defaultMessage: "item line {number}"
|
3050
|
-
},
|
3051
|
-
{ number: index2 + 1 }
|
3052
|
-
)
|
3053
|
-
}
|
3054
|
-
),
|
3382
|
+
label: formatMessage({
|
3383
|
+
id: "content-manager.bulk-publish.edit",
|
3384
|
+
defaultMessage: "Edit"
|
3385
|
+
}),
|
3055
3386
|
target: "_blank",
|
3056
3387
|
marginLeft: "auto",
|
3057
|
-
|
3388
|
+
variant: "ghost",
|
3389
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, { width: "1.6rem", height: "1.6rem" })
|
3058
3390
|
}
|
3059
|
-
) })
|
3391
|
+
) }) })
|
3060
3392
|
] }, row.id)) })
|
3061
3393
|
] });
|
3062
3394
|
};
|
@@ -3093,7 +3425,13 @@ const SelectedEntriesModalContent = ({
|
|
3093
3425
|
);
|
3094
3426
|
const { rows, validationErrors } = React__namespace.useMemo(() => {
|
3095
3427
|
if (data.length > 0 && schema) {
|
3096
|
-
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
|
+
);
|
3097
3435
|
const validationErrors2 = {};
|
3098
3436
|
const rows2 = data.map((entry) => {
|
3099
3437
|
try {
|
@@ -3218,8 +3556,7 @@ const PublishAction = ({ documents, model }) => {
|
|
3218
3556
|
const refetchList = () => {
|
3219
3557
|
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3220
3558
|
};
|
3221
|
-
if (!showPublishButton)
|
3222
|
-
return null;
|
3559
|
+
if (!showPublishButton) return null;
|
3223
3560
|
return {
|
3224
3561
|
actionType: "publish",
|
3225
3562
|
variant: "tertiary",
|
@@ -3287,8 +3624,7 @@ const DeleteAction = ({ documents, model }) => {
|
|
3287
3624
|
selectRow([]);
|
3288
3625
|
}
|
3289
3626
|
};
|
3290
|
-
if (!hasDeletePermission)
|
3291
|
-
return null;
|
3627
|
+
if (!hasDeletePermission) return null;
|
3292
3628
|
return {
|
3293
3629
|
variant: "danger-light",
|
3294
3630
|
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
@@ -3337,8 +3673,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3337
3673
|
}
|
3338
3674
|
};
|
3339
3675
|
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3340
|
-
if (!showUnpublishButton)
|
3341
|
-
return null;
|
3676
|
+
if (!showUnpublishButton) return null;
|
3342
3677
|
return {
|
3343
3678
|
variant: "tertiary",
|
3344
3679
|
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
@@ -3443,7 +3778,7 @@ const TableActions = ({ document }) => {
|
|
3443
3778
|
strapiAdmin.DescriptionComponentRenderer,
|
3444
3779
|
{
|
3445
3780
|
props,
|
3446
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3781
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("table-row").filter((action) => action.name !== "PublishAction"),
|
3447
3782
|
children: (actions2) => {
|
3448
3783
|
const tableRowActions = actions2.filter((action) => {
|
3449
3784
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3502,6 +3837,7 @@ const EditAction = ({ documentId }) => {
|
|
3502
3837
|
};
|
3503
3838
|
};
|
3504
3839
|
EditAction.type = "edit";
|
3840
|
+
EditAction.position = "table-row";
|
3505
3841
|
const StyledPencil = styledComponents.styled(Icons.Pencil)`
|
3506
3842
|
path {
|
3507
3843
|
fill: currentColor;
|
@@ -3554,7 +3890,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3554
3890
|
}),
|
3555
3891
|
content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3556
3892
|
footer: ({ onClose }) => {
|
3557
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.
|
3893
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3558
3894
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3559
3895
|
id: "cancel",
|
3560
3896
|
defaultMessage: "Cancel"
|
@@ -3578,6 +3914,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3578
3914
|
};
|
3579
3915
|
};
|
3580
3916
|
CloneAction.type = "clone";
|
3917
|
+
CloneAction.position = "table-row";
|
3581
3918
|
const StyledDuplicate = styledComponents.styled(Icons.Duplicate)`
|
3582
3919
|
path {
|
3583
3920
|
fill: currentColor;
|
@@ -3595,8 +3932,7 @@ class ContentManagerPlugin {
|
|
3595
3932
|
documentActions = [
|
3596
3933
|
...DEFAULT_ACTIONS,
|
3597
3934
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3598
|
-
...DEFAULT_HEADER_ACTIONS
|
3599
|
-
HistoryAction
|
3935
|
+
...DEFAULT_HEADER_ACTIONS
|
3600
3936
|
];
|
3601
3937
|
editViewSidePanels = [ActionsPanel];
|
3602
3938
|
headerActions = [];
|
@@ -3665,7 +4001,14 @@ class ContentManagerPlugin {
|
|
3665
4001
|
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3666
4002
|
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3667
4003
|
getBulkActions: () => this.bulkActions,
|
3668
|
-
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
|
+
},
|
3669
4012
|
getEditViewSidePanels: () => this.editViewSidePanels,
|
3670
4013
|
getHeaderActions: () => this.headerActions
|
3671
4014
|
}
|
@@ -3675,16 +4018,71 @@ class ContentManagerPlugin {
|
|
3675
4018
|
const getPrintableType = (value) => {
|
3676
4019
|
const nativeType = typeof value;
|
3677
4020
|
if (nativeType === "object") {
|
3678
|
-
if (value === null)
|
3679
|
-
|
3680
|
-
if (Array.isArray(value))
|
3681
|
-
return "array";
|
4021
|
+
if (value === null) return "null";
|
4022
|
+
if (Array.isArray(value)) return "array";
|
3682
4023
|
if (value instanceof Object && value.constructor.name !== "Object") {
|
3683
4024
|
return value.constructor.name;
|
3684
4025
|
}
|
3685
4026
|
}
|
3686
4027
|
return nativeType;
|
3687
4028
|
};
|
4029
|
+
const HistoryAction = ({ model, document }) => {
|
4030
|
+
const { formatMessage } = reactIntl.useIntl();
|
4031
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
4032
|
+
const navigate = reactRouterDom.useNavigate();
|
4033
|
+
const { trackUsage } = strapiAdmin.useTracking();
|
4034
|
+
const { pathname } = reactRouterDom.useLocation();
|
4035
|
+
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
4036
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
4037
|
+
return null;
|
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
|
+
};
|
4047
|
+
return {
|
4048
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
4049
|
+
label: formatMessage({
|
4050
|
+
id: "content-manager.history.document-action",
|
4051
|
+
defaultMessage: "Content History"
|
4052
|
+
}),
|
4053
|
+
onClick: handleOnClick,
|
4054
|
+
disabled: (
|
4055
|
+
/**
|
4056
|
+
* The user is creating a new document.
|
4057
|
+
* It hasn't been saved yet, so there's no history to go to
|
4058
|
+
*/
|
4059
|
+
!document || /**
|
4060
|
+
* The document has been created but the current dimension has never been saved.
|
4061
|
+
* For example, the user is creating a new locale in an existing document,
|
4062
|
+
* so there's no history for the document in that locale
|
4063
|
+
*/
|
4064
|
+
!document.id || /**
|
4065
|
+
* History is only available for content types created by the user.
|
4066
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
4067
|
+
* which start with `admin::` or `plugin::`
|
4068
|
+
*/
|
4069
|
+
!model.startsWith("api::")
|
4070
|
+
),
|
4071
|
+
position: "header"
|
4072
|
+
};
|
4073
|
+
};
|
4074
|
+
HistoryAction.type = "history";
|
4075
|
+
HistoryAction.position = "header";
|
4076
|
+
const historyAdmin = {
|
4077
|
+
bootstrap(app) {
|
4078
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
4079
|
+
addDocumentAction((actions2) => {
|
4080
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
4081
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
4082
|
+
return actions2;
|
4083
|
+
});
|
4084
|
+
}
|
4085
|
+
};
|
3688
4086
|
const initialState = {
|
3689
4087
|
collectionTypeLinks: [],
|
3690
4088
|
components: [],
|
@@ -3721,6 +4119,88 @@ const { setInitialData } = actions;
|
|
3721
4119
|
const reducer = toolkit.combineReducers({
|
3722
4120
|
app: reducer$1
|
3723
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
|
+
};
|
3724
4204
|
const index = {
|
3725
4205
|
register(app) {
|
3726
4206
|
const cm = new ContentManagerPlugin();
|
@@ -3740,7 +4220,7 @@ const index = {
|
|
3740
4220
|
app.router.addRoute({
|
3741
4221
|
path: "content-manager/*",
|
3742
4222
|
lazy: async () => {
|
3743
|
-
const { Layout } = await Promise.resolve().then(() => require("./layout-
|
4223
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-CDBEgRsM.js"));
|
3744
4224
|
return {
|
3745
4225
|
Component: Layout
|
3746
4226
|
};
|
@@ -3749,10 +4229,18 @@ const index = {
|
|
3749
4229
|
});
|
3750
4230
|
app.registerPlugin(cm.config);
|
3751
4231
|
},
|
4232
|
+
bootstrap(app) {
|
4233
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
4234
|
+
historyAdmin.bootstrap(app);
|
4235
|
+
}
|
4236
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
4237
|
+
previewAdmin.bootstrap(app);
|
4238
|
+
}
|
4239
|
+
},
|
3752
4240
|
async registerTrads({ locales }) {
|
3753
4241
|
const importedTrads = await Promise.all(
|
3754
4242
|
locales.map((locale) => {
|
3755
|
-
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 }) => {
|
3756
4244
|
return {
|
3757
4245
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3758
4246
|
locale
|
@@ -3770,6 +4258,7 @@ const index = {
|
|
3770
4258
|
};
|
3771
4259
|
exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
|
3772
4260
|
exports.BulkActionsRenderer = BulkActionsRenderer;
|
4261
|
+
exports.CLONE_PATH = CLONE_PATH;
|
3773
4262
|
exports.COLLECTION_TYPES = COLLECTION_TYPES;
|
3774
4263
|
exports.CREATOR_FIELDS = CREATOR_FIELDS;
|
3775
4264
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
@@ -3797,6 +4286,7 @@ exports.getMainField = getMainField;
|
|
3797
4286
|
exports.getTranslation = getTranslation;
|
3798
4287
|
exports.index = index;
|
3799
4288
|
exports.setInitialData = setInitialData;
|
4289
|
+
exports.useContentManagerContext = useContentManagerContext;
|
3800
4290
|
exports.useContentTypeSchema = useContentTypeSchema;
|
3801
4291
|
exports.useDoc = useDoc;
|
3802
4292
|
exports.useDocLayout = useDocLayout;
|
@@ -3808,5 +4298,6 @@ exports.useGetAllContentTypeSettingsQuery = useGetAllContentTypeSettingsQuery;
|
|
3808
4298
|
exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
3809
4299
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3810
4300
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
4301
|
+
exports.useGetPreviewUrlQuery = useGetPreviewUrlQuery;
|
3811
4302
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3812
|
-
//# sourceMappingURL=index-
|
4303
|
+
//# sourceMappingURL=index-Ct-GZ0iV.js.map
|