@strapi/content-manager 0.0.0-experimental.7afdc9b682bc83a53ce599c4fb7c9e4506b31fff → 0.0.0-experimental.7bc5339b0393e53f9f568301594621e7fb466e2f
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/LICENSE +18 -3
- package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -1
- package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DJcn1DrO.js → ComponentConfigurationPage-BPiQrhZ6.js} +5 -6
- package/dist/_chunks/{ComponentConfigurationPage-DJcn1DrO.js.map → ComponentConfigurationPage-BPiQrhZ6.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs → ComponentConfigurationPage-viOAdZM6.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs.map → ComponentConfigurationPage-viOAdZM6.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-tDtWj7R2.js → EditConfigurationPage-CZRKq8CN.js} +5 -6
- package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js.map → EditConfigurationPage-CZRKq8CN.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs → EditConfigurationPage-DKtPyjs_.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs.map → EditConfigurationPage-DKtPyjs_.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-CoQEnFlC.js → EditViewPage-C-TZmK5r.js} +101 -51
- package/dist/_chunks/EditViewPage-C-TZmK5r.js.map +1 -0
- package/dist/_chunks/{EditViewPage-DvaV7U9b.mjs → EditViewPage-D2FPb5Mh.mjs} +102 -51
- package/dist/_chunks/EditViewPage-D2FPb5Mh.mjs.map +1 -0
- package/dist/_chunks/{Field-ZdrmmQ4Y.js → Field-IMBnqF-k.js} +634 -283
- package/dist/_chunks/Field-IMBnqF-k.js.map +1 -0
- package/dist/_chunks/{Field-Cz_J9551.mjs → Field-hD0Y00Mt.mjs} +631 -279
- package/dist/_chunks/Field-hD0Y00Mt.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-Bpig5rch.js → Form-BaURS01O.js} +55 -38
- package/dist/_chunks/Form-BaURS01O.js.map +1 -0
- package/dist/_chunks/{Form-Dxmihyw8.mjs → Form-ZQ9fzWkd.mjs} +55 -37
- package/dist/_chunks/Form-ZQ9fzWkd.mjs.map +1 -0
- package/dist/_chunks/{History-BfX6XmZK.js → History-BqRQm2Lc.js} +175 -129
- package/dist/_chunks/History-BqRQm2Lc.js.map +1 -0
- package/dist/_chunks/{History-BZP8n7KT.mjs → History-C4X3jiQJ.mjs} +176 -129
- package/dist/_chunks/History-C4X3jiQJ.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-B3CXj8PY.js → ListConfigurationPage-BT69-TvF.js} +62 -51
- package/dist/_chunks/ListConfigurationPage-BT69-TvF.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DxKuVkKz.mjs → ListConfigurationPage-CwMU6tWQ.mjs} +63 -52
- package/dist/_chunks/ListConfigurationPage-CwMU6tWQ.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-Bk9VO__I.js → ListViewPage-CYkrfWsm.js} +155 -132
- package/dist/_chunks/ListViewPage-CYkrfWsm.js.map +1 -0
- package/dist/_chunks/{ListViewPage-D5D3tVPq.mjs → ListViewPage-CvxfiNTc.mjs} +152 -128
- package/dist/_chunks/ListViewPage-CvxfiNTc.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js → NoContentTypePage-BZMfRsrg.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js.map → NoContentTypePage-BZMfRsrg.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs → NoContentTypePage-Dy6sa9LT.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs.map → NoContentTypePage-Dy6sa9LT.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs → NoPermissionsPage-DiW-TIzq.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs.map → NoPermissionsPage-DiW-TIzq.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js → NoPermissionsPage-DjUdvhJ6.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js.map → NoPermissionsPage-DjUdvhJ6.js.map} +1 -1
- package/dist/_chunks/Preview-BqRUSbFU.js +296 -0
- package/dist/_chunks/Preview-BqRUSbFU.js.map +1 -0
- package/dist/_chunks/Preview-DwWET-X7.mjs +278 -0
- package/dist/_chunks/Preview-DwWET-X7.mjs.map +1 -0
- package/dist/_chunks/{Relations-BOYZmuWy.mjs → Relations-BOTC_ZqE.mjs} +76 -42
- package/dist/_chunks/Relations-BOTC_ZqE.mjs.map +1 -0
- package/dist/_chunks/{Relations-B6B3A3mb.js → Relations-DnCdLzq_.js} +76 -43
- package/dist/_chunks/Relations-DnCdLzq_.js.map +1 -0
- package/dist/_chunks/{en-BN1bvFK7.js → en-BK8Xyl5I.js} +35 -18
- package/dist/_chunks/{en-BN1bvFK7.js.map → en-BK8Xyl5I.js.map} +1 -1
- package/dist/_chunks/{en-Dzv55oQw.mjs → en-Dtk_ot79.mjs} +35 -18
- package/dist/_chunks/{en-Dzv55oQw.mjs.map → en-Dtk_ot79.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-VHviNMeW.mjs → index-BeYsz0Vi.mjs} +1203 -899
- package/dist/_chunks/index-BeYsz0Vi.mjs.map +1 -0
- package/dist/_chunks/{index-DzN3kBgx.js → index-CptTdHNy.js} +1183 -879
- package/dist/_chunks/index-CptTdHNy.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-CPn1PM6x.mjs → layout-CzSSEy9b.mjs} +42 -24
- package/dist/_chunks/layout-CzSSEy9b.mjs.map +1 -0
- package/dist/_chunks/{layout-b91XRlD2.js → layout-szfTCeYm.js} +41 -24
- package/dist/_chunks/layout-szfTCeYm.js.map +1 -0
- package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
- package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
- package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
- package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
- package/dist/_chunks/{relations-BsqxS6tR.mjs → relations-DvzmDbWc.mjs} +6 -7
- package/dist/_chunks/relations-DvzmDbWc.mjs.map +1 -0
- package/dist/_chunks/{relations-CA7IYmcP.js → relations-qssSbh1V.js} +6 -7
- package/dist/_chunks/relations-qssSbh1V.js.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 +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +8 -7
- package/dist/admin/src/content-manager.d.ts +3 -2
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/history/components/VersionInputRenderer.d.ts +1 -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 +9 -4
- package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -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 +6 -58
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
- package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
- 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/constants.d.ts +1 -0
- package/dist/admin/src/preview/index.d.ts +4 -0
- package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
- package/dist/admin/src/preview/routes.d.ts +3 -0
- package/dist/admin/src/preview/services/preview.d.ts +3 -0
- package/dist/admin/src/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 +614 -297
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +614 -296
- 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 +15 -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 +4 -4
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/preview/constants.d.ts +2 -0
- package/dist/server/src/preview/constants.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/index.d.ts +2 -0
- package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/preview.d.ts +13 -0
- package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
- package/dist/server/src/preview/index.d.ts +4 -0
- package/dist/server/src/preview/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/index.d.ts +8 -0
- package/dist/server/src/preview/routes/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/preview.d.ts +4 -0
- package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
- package/dist/server/src/preview/services/index.d.ts +16 -0
- package/dist/server/src/preview/services/index.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview-config.d.ts +32 -0
- package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview.d.ts +12 -0
- package/dist/server/src/preview/services/preview.d.ts.map +1 -0
- package/dist/server/src/preview/utils.d.ts +19 -0
- package/dist/server/src/preview/utils.d.ts.map +1 -0
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +8 -8
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +4 -4
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
- package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
- package/dist/server/src/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 +15 -15
- package/dist/_chunks/EditViewPage-CoQEnFlC.js.map +0 -1
- package/dist/_chunks/EditViewPage-DvaV7U9b.mjs.map +0 -1
- package/dist/_chunks/Field-Cz_J9551.mjs.map +0 -1
- package/dist/_chunks/Field-ZdrmmQ4Y.js.map +0 -1
- package/dist/_chunks/Form-Bpig5rch.js.map +0 -1
- package/dist/_chunks/Form-Dxmihyw8.mjs.map +0 -1
- package/dist/_chunks/History-BZP8n7KT.mjs.map +0 -1
- package/dist/_chunks/History-BfX6XmZK.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-B3CXj8PY.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DxKuVkKz.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-Bk9VO__I.js.map +0 -1
- package/dist/_chunks/ListViewPage-D5D3tVPq.mjs.map +0 -1
- package/dist/_chunks/Relations-B6B3A3mb.js.map +0 -1
- package/dist/_chunks/Relations-BOYZmuWy.mjs.map +0 -1
- package/dist/_chunks/index-DzN3kBgx.js.map +0 -1
- package/dist/_chunks/index-VHviNMeW.mjs.map +0 -1
- package/dist/_chunks/layout-CPn1PM6x.mjs.map +0 -1
- package/dist/_chunks/layout-b91XRlD2.js.map +0 -1
- package/dist/_chunks/relations-BsqxS6tR.mjs.map +0 -1
- package/dist/_chunks/relations-CA7IYmcP.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
@@ -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,10 +195,12 @@ const contentManagerApi = strapiAdmin.adminApi.enhanceEndpoints({
|
|
215
195
|
"Document",
|
216
196
|
"InitialData",
|
217
197
|
"HistoryVersion",
|
218
|
-
"Relations"
|
198
|
+
"Relations",
|
199
|
+
"UidAvailability"
|
219
200
|
]
|
220
201
|
});
|
221
202
|
const documentApi = contentManagerApi.injectEndpoints({
|
203
|
+
overrideExisting: true,
|
222
204
|
endpoints: (builder) => ({
|
223
205
|
autoCloneDocument: builder.mutation({
|
224
206
|
query: ({ model, sourceId, query }) => ({
|
@@ -228,7 +210,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
228
210
|
params: query
|
229
211
|
}
|
230
212
|
}),
|
231
|
-
invalidatesTags: (_result,
|
213
|
+
invalidatesTags: (_result, error, { model }) => {
|
214
|
+
if (error) {
|
215
|
+
return [];
|
216
|
+
}
|
217
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
218
|
+
}
|
232
219
|
}),
|
233
220
|
cloneDocument: builder.mutation({
|
234
221
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -239,7 +226,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
239
226
|
params
|
240
227
|
}
|
241
228
|
}),
|
242
|
-
invalidatesTags: (_result, _error, { model }) => [
|
229
|
+
invalidatesTags: (_result, _error, { model }) => [
|
230
|
+
{ type: "Document", id: `${model}_LIST` },
|
231
|
+
{ type: "UidAvailability", id: model }
|
232
|
+
]
|
243
233
|
}),
|
244
234
|
/**
|
245
235
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -256,7 +246,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
256
246
|
}),
|
257
247
|
invalidatesTags: (result, _error, { model }) => [
|
258
248
|
{ type: "Document", id: `${model}_LIST` },
|
259
|
-
"Relations"
|
249
|
+
"Relations",
|
250
|
+
{ type: "UidAvailability", id: model }
|
260
251
|
]
|
261
252
|
}),
|
262
253
|
deleteDocument: builder.mutation({
|
@@ -297,7 +288,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
297
288
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
298
289
|
},
|
299
290
|
{ type: "Document", id: `${model}_LIST` },
|
300
|
-
"Relations"
|
291
|
+
"Relations",
|
292
|
+
{ type: "UidAvailability", id: model }
|
301
293
|
];
|
302
294
|
}
|
303
295
|
}),
|
@@ -310,11 +302,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
310
302
|
url: `/content-manager/collection-types/${model}`,
|
311
303
|
method: "GET",
|
312
304
|
config: {
|
313
|
-
params
|
305
|
+
params: qs.stringify(params, { encode: true })
|
314
306
|
}
|
315
307
|
}),
|
316
308
|
providesTags: (result, _error, arg) => {
|
317
309
|
return [
|
310
|
+
{ type: "Document", id: `ALL_LIST` },
|
318
311
|
{ type: "Document", id: `${arg.model}_LIST` },
|
319
312
|
...result?.results.map(({ documentId }) => ({
|
320
313
|
type: "Document",
|
@@ -353,6 +346,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
353
346
|
{
|
354
347
|
type: "Document",
|
355
348
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
349
|
+
},
|
350
|
+
// Make it easy to invalidate all individual documents queries for a model
|
351
|
+
{
|
352
|
+
type: "Document",
|
353
|
+
id: `${model}_ALL_ITEMS`
|
356
354
|
}
|
357
355
|
];
|
358
356
|
}
|
@@ -416,8 +414,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
416
414
|
type: "Document",
|
417
415
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
418
416
|
},
|
419
|
-
"Relations"
|
417
|
+
"Relations",
|
418
|
+
{ type: "UidAvailability", id: model }
|
420
419
|
];
|
420
|
+
},
|
421
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
422
|
+
const patchResult = dispatch(
|
423
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
424
|
+
Object.assign(draft.data, data);
|
425
|
+
})
|
426
|
+
);
|
427
|
+
try {
|
428
|
+
await queryFulfilled;
|
429
|
+
} catch {
|
430
|
+
patchResult.undo();
|
431
|
+
}
|
421
432
|
}
|
422
433
|
}),
|
423
434
|
unpublishDocument: builder.mutation({
|
@@ -470,8 +481,7 @@ const {
|
|
470
481
|
useUnpublishManyDocumentsMutation
|
471
482
|
} = documentApi;
|
472
483
|
const buildValidParams = (query) => {
|
473
|
-
if (!query)
|
474
|
-
return query;
|
484
|
+
if (!query) return query;
|
475
485
|
const { plugins: _, ...validQueryParams } = {
|
476
486
|
...query,
|
477
487
|
...Object.values(query?.plugins ?? {}).reduce(
|
@@ -479,28 +489,44 @@ const buildValidParams = (query) => {
|
|
479
489
|
{}
|
480
490
|
)
|
481
491
|
};
|
482
|
-
if ("_q" in validQueryParams) {
|
483
|
-
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
484
|
-
}
|
485
492
|
return validQueryParams;
|
486
493
|
};
|
487
494
|
const isBaseQueryError = (error) => {
|
488
495
|
return error.name !== void 0;
|
489
496
|
};
|
490
|
-
const
|
497
|
+
const arrayValidator = (attribute, options) => ({
|
498
|
+
message: strapiAdmin.translatedErrors.required,
|
499
|
+
test(value) {
|
500
|
+
if (options.status === "draft") {
|
501
|
+
return true;
|
502
|
+
}
|
503
|
+
if (!attribute.required) {
|
504
|
+
return true;
|
505
|
+
}
|
506
|
+
if (!value) {
|
507
|
+
return false;
|
508
|
+
}
|
509
|
+
if (Array.isArray(value) && value.length === 0) {
|
510
|
+
return false;
|
511
|
+
}
|
512
|
+
return true;
|
513
|
+
}
|
514
|
+
});
|
515
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
491
516
|
const createModelSchema = (attributes2) => yup__namespace.object().shape(
|
492
517
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
493
518
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
494
519
|
return acc;
|
495
520
|
}
|
496
521
|
const validations = [
|
522
|
+
addNullableValidation,
|
497
523
|
addRequiredValidation,
|
498
524
|
addMinLengthValidation,
|
499
525
|
addMaxLengthValidation,
|
500
526
|
addMinValidation,
|
501
527
|
addMaxValidation,
|
502
528
|
addRegexValidation
|
503
|
-
].map((fn) => fn(attribute));
|
529
|
+
].map((fn) => fn(attribute, options));
|
504
530
|
const transformSchema = pipe__default.default(...validations);
|
505
531
|
switch (attribute.type) {
|
506
532
|
case "component": {
|
@@ -510,12 +536,12 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
510
536
|
...acc,
|
511
537
|
[name]: transformSchema(
|
512
538
|
yup__namespace.array().of(createModelSchema(attributes3).nullable(false))
|
513
|
-
)
|
539
|
+
).test(arrayValidator(attribute, options))
|
514
540
|
};
|
515
541
|
} else {
|
516
542
|
return {
|
517
543
|
...acc,
|
518
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
544
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
519
545
|
};
|
520
546
|
}
|
521
547
|
}
|
@@ -537,7 +563,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
537
563
|
}
|
538
564
|
)
|
539
565
|
)
|
540
|
-
)
|
566
|
+
).test(arrayValidator(attribute, options))
|
541
567
|
};
|
542
568
|
case "relation":
|
543
569
|
return {
|
@@ -549,7 +575,7 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
549
575
|
} else if (Array.isArray(value)) {
|
550
576
|
return yup__namespace.array().of(
|
551
577
|
yup__namespace.object().shape({
|
552
|
-
id: yup__namespace.
|
578
|
+
id: yup__namespace.number().required()
|
553
579
|
})
|
554
580
|
);
|
555
581
|
} else if (typeof value === "object") {
|
@@ -601,6 +627,14 @@ const createAttributeSchema = (attribute) => {
|
|
601
627
|
if (!value || typeof value === "string" && value.length === 0) {
|
602
628
|
return true;
|
603
629
|
}
|
630
|
+
if (typeof value === "object") {
|
631
|
+
try {
|
632
|
+
JSON.stringify(value);
|
633
|
+
return true;
|
634
|
+
} catch (err) {
|
635
|
+
return false;
|
636
|
+
}
|
637
|
+
}
|
604
638
|
try {
|
605
639
|
JSON.parse(value);
|
606
640
|
return true;
|
@@ -619,13 +653,7 @@ const createAttributeSchema = (attribute) => {
|
|
619
653
|
return yup__namespace.mixed();
|
620
654
|
}
|
621
655
|
};
|
622
|
-
const
|
623
|
-
if (attribute.required) {
|
624
|
-
return schema.required({
|
625
|
-
id: strapiAdmin.translatedErrors.required.id,
|
626
|
-
defaultMessage: "This field is required."
|
627
|
-
});
|
628
|
-
}
|
656
|
+
const nullableSchema = (schema) => {
|
629
657
|
return schema?.nullable ? schema.nullable() : (
|
630
658
|
// In some cases '.nullable' will not be available on the schema.
|
631
659
|
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
@@ -633,7 +661,22 @@ const addRequiredValidation = (attribute) => (schema) => {
|
|
633
661
|
schema
|
634
662
|
);
|
635
663
|
};
|
636
|
-
const
|
664
|
+
const addNullableValidation = () => (schema) => {
|
665
|
+
return nullableSchema(schema);
|
666
|
+
};
|
667
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
668
|
+
if (options.status === "draft" || !attribute.required) {
|
669
|
+
return schema;
|
670
|
+
}
|
671
|
+
if (attribute.required && "required" in schema) {
|
672
|
+
return schema.required(strapiAdmin.translatedErrors.required);
|
673
|
+
}
|
674
|
+
return schema;
|
675
|
+
};
|
676
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
677
|
+
if (options.status === "draft") {
|
678
|
+
return schema;
|
679
|
+
}
|
637
680
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
638
681
|
return schema.min(attribute.minLength, {
|
639
682
|
...strapiAdmin.translatedErrors.minLength,
|
@@ -655,10 +698,13 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
655
698
|
}
|
656
699
|
return schema;
|
657
700
|
};
|
658
|
-
const addMinValidation = (attribute) => (schema) => {
|
659
|
-
if ("
|
701
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
702
|
+
if (options.status === "draft") {
|
703
|
+
return schema;
|
704
|
+
}
|
705
|
+
if ("min" in attribute && "min" in schema) {
|
660
706
|
const min = toInteger(attribute.min);
|
661
|
-
if (
|
707
|
+
if (min) {
|
662
708
|
return schema.min(min, {
|
663
709
|
...strapiAdmin.translatedErrors.min,
|
664
710
|
values: {
|
@@ -776,16 +822,115 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
776
822
|
}, {});
|
777
823
|
return componentsByKey;
|
778
824
|
};
|
779
|
-
const
|
825
|
+
const HOOKS = {
|
826
|
+
/**
|
827
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
828
|
+
* @constant
|
829
|
+
* @type {string}
|
830
|
+
*/
|
831
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
832
|
+
/**
|
833
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
834
|
+
* @constant
|
835
|
+
* @type {string}
|
836
|
+
*/
|
837
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
838
|
+
/**
|
839
|
+
* Hook that allows to mutate the CM's edit view layout
|
840
|
+
* @constant
|
841
|
+
* @type {string}
|
842
|
+
*/
|
843
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
844
|
+
/**
|
845
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
846
|
+
* @constant
|
847
|
+
* @type {string}
|
848
|
+
*/
|
849
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
850
|
+
};
|
851
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
852
|
+
endpoints: (builder) => ({
|
853
|
+
getContentTypeConfiguration: builder.query({
|
854
|
+
query: (uid) => ({
|
855
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
856
|
+
method: "GET"
|
857
|
+
}),
|
858
|
+
transformResponse: (response) => response.data,
|
859
|
+
providesTags: (_result, _error, uid) => [
|
860
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
861
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
862
|
+
]
|
863
|
+
}),
|
864
|
+
getAllContentTypeSettings: builder.query({
|
865
|
+
query: () => "/content-manager/content-types-settings",
|
866
|
+
transformResponse: (response) => response.data,
|
867
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
868
|
+
}),
|
869
|
+
updateContentTypeConfiguration: builder.mutation({
|
870
|
+
query: ({ uid, ...body }) => ({
|
871
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
872
|
+
method: "PUT",
|
873
|
+
data: body
|
874
|
+
}),
|
875
|
+
transformResponse: (response) => response.data,
|
876
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
877
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
878
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
879
|
+
// Is this necessary?
|
880
|
+
{ type: "InitialData" }
|
881
|
+
]
|
882
|
+
})
|
883
|
+
})
|
884
|
+
});
|
885
|
+
const {
|
886
|
+
useGetContentTypeConfigurationQuery,
|
887
|
+
useGetAllContentTypeSettingsQuery,
|
888
|
+
useUpdateContentTypeConfigurationMutation
|
889
|
+
} = contentTypesApi;
|
890
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
891
|
+
const { type } = attribute;
|
892
|
+
if (type === "relation") {
|
893
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
894
|
+
}
|
895
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
896
|
+
};
|
897
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
898
|
+
if (!mainFieldName) {
|
899
|
+
return void 0;
|
900
|
+
}
|
901
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
902
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
903
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
904
|
+
);
|
905
|
+
return {
|
906
|
+
name: mainFieldName,
|
907
|
+
type: mainFieldType ?? "string"
|
908
|
+
};
|
909
|
+
};
|
910
|
+
const DEFAULT_SETTINGS = {
|
911
|
+
bulkable: false,
|
912
|
+
filterable: false,
|
913
|
+
searchable: false,
|
914
|
+
pagination: false,
|
915
|
+
defaultSortBy: "",
|
916
|
+
defaultSortOrder: "asc",
|
917
|
+
mainField: "id",
|
918
|
+
pageSize: 10
|
919
|
+
};
|
920
|
+
const useDocumentLayout = (model) => {
|
921
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
922
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
923
|
+
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
780
924
|
const { toggleNotification } = strapiAdmin.useNotification();
|
781
925
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
926
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
782
927
|
const {
|
783
|
-
|
784
|
-
isLoading:
|
785
|
-
|
786
|
-
|
787
|
-
} =
|
788
|
-
const
|
928
|
+
data,
|
929
|
+
isLoading: isLoadingConfigs,
|
930
|
+
error,
|
931
|
+
isFetching: isFetchingConfigs
|
932
|
+
} = useGetContentTypeConfigurationQuery(model);
|
933
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
789
934
|
React__namespace.useEffect(() => {
|
790
935
|
if (error) {
|
791
936
|
toggleNotification({
|
@@ -793,68 +938,322 @@ const useDocument = (args, opts) => {
|
|
793
938
|
message: formatAPIError(error)
|
794
939
|
});
|
795
940
|
}
|
796
|
-
}, [
|
797
|
-
const
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
(document) => {
|
805
|
-
if (!validationSchema) {
|
806
|
-
throw new Error(
|
807
|
-
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
808
|
-
);
|
809
|
-
}
|
810
|
-
try {
|
811
|
-
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
812
|
-
return null;
|
813
|
-
} catch (error2) {
|
814
|
-
if (error2 instanceof yup.ValidationError) {
|
815
|
-
return strapiAdmin.getYupValidationErrors(error2);
|
816
|
-
}
|
817
|
-
throw error2;
|
818
|
-
}
|
941
|
+
}, [error, formatAPIError, toggleNotification]);
|
942
|
+
const editLayout = React__namespace.useMemo(
|
943
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
944
|
+
layout: [],
|
945
|
+
components: {},
|
946
|
+
metadatas: {},
|
947
|
+
options: {},
|
948
|
+
settings: DEFAULT_SETTINGS
|
819
949
|
},
|
820
|
-
[
|
950
|
+
[data, isLoading, schemas, schema, components]
|
951
|
+
);
|
952
|
+
const listLayout = React__namespace.useMemo(() => {
|
953
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
954
|
+
layout: [],
|
955
|
+
metadatas: {},
|
956
|
+
options: {},
|
957
|
+
settings: DEFAULT_SETTINGS
|
958
|
+
};
|
959
|
+
}, [data, isLoading, schemas, schema, components]);
|
960
|
+
const { layout: edit } = React__namespace.useMemo(
|
961
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
962
|
+
layout: editLayout,
|
963
|
+
query
|
964
|
+
}),
|
965
|
+
[editLayout, query, runHookWaterfall]
|
821
966
|
);
|
822
|
-
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
823
967
|
return {
|
824
|
-
|
825
|
-
document: data?.data,
|
826
|
-
meta: data?.meta,
|
968
|
+
error,
|
827
969
|
isLoading,
|
828
|
-
|
829
|
-
|
970
|
+
edit,
|
971
|
+
list: listLayout
|
830
972
|
};
|
831
973
|
};
|
832
|
-
const
|
833
|
-
const {
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
974
|
+
const useDocLayout = () => {
|
975
|
+
const { model } = useDoc();
|
976
|
+
return useDocumentLayout(model);
|
977
|
+
};
|
978
|
+
const formatEditLayout = (data, {
|
979
|
+
schemas,
|
980
|
+
schema,
|
981
|
+
components
|
982
|
+
}) => {
|
983
|
+
let currentPanelIndex = 0;
|
984
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
985
|
+
data.contentType.layouts.edit,
|
986
|
+
schema?.attributes,
|
987
|
+
data.contentType.metadatas,
|
988
|
+
{ configurations: data.components, schemas: components },
|
989
|
+
schemas
|
990
|
+
).reduce((panels, row) => {
|
991
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
992
|
+
panels.push([row]);
|
993
|
+
currentPanelIndex += 2;
|
994
|
+
} else {
|
995
|
+
if (!panels[currentPanelIndex]) {
|
996
|
+
panels.push([row]);
|
997
|
+
} else {
|
998
|
+
panels[currentPanelIndex].push(row);
|
999
|
+
}
|
1000
|
+
}
|
1001
|
+
return panels;
|
1002
|
+
}, []);
|
1003
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
1004
|
+
(acc, [uid, configuration]) => {
|
1005
|
+
acc[uid] = {
|
1006
|
+
layout: convertEditLayoutToFieldLayouts(
|
1007
|
+
configuration.layouts.edit,
|
1008
|
+
components[uid].attributes,
|
1009
|
+
configuration.metadatas,
|
1010
|
+
{ configurations: data.components, schemas: components }
|
1011
|
+
),
|
1012
|
+
settings: {
|
1013
|
+
...configuration.settings,
|
1014
|
+
icon: components[uid].info.icon,
|
1015
|
+
displayName: components[uid].info.displayName
|
1016
|
+
}
|
1017
|
+
};
|
1018
|
+
return acc;
|
1019
|
+
},
|
1020
|
+
{}
|
1021
|
+
);
|
1022
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1023
|
+
(acc, [attribute, metadata]) => {
|
1024
|
+
return {
|
1025
|
+
...acc,
|
1026
|
+
[attribute]: metadata.edit
|
1027
|
+
};
|
1028
|
+
},
|
1029
|
+
{}
|
1030
|
+
);
|
1031
|
+
return {
|
1032
|
+
layout: panelledEditAttributes,
|
1033
|
+
components: componentEditAttributes,
|
1034
|
+
metadatas: editMetadatas,
|
1035
|
+
settings: {
|
1036
|
+
...data.contentType.settings,
|
1037
|
+
displayName: schema?.info.displayName
|
1038
|
+
},
|
1039
|
+
options: {
|
1040
|
+
...schema?.options,
|
1041
|
+
...schema?.pluginOptions,
|
1042
|
+
...data.contentType.options
|
1043
|
+
}
|
1044
|
+
};
|
1045
|
+
};
|
1046
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1047
|
+
return rows.map(
|
1048
|
+
(row) => row.map((field) => {
|
1049
|
+
const attribute = attributes[field.name];
|
1050
|
+
if (!attribute) {
|
1051
|
+
return null;
|
1052
|
+
}
|
1053
|
+
const { edit: metadata } = metadatas[field.name];
|
1054
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1055
|
+
return {
|
1056
|
+
attribute,
|
1057
|
+
disabled: !metadata.editable,
|
1058
|
+
hint: metadata.description,
|
1059
|
+
label: metadata.label ?? "",
|
1060
|
+
name: field.name,
|
1061
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1062
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1063
|
+
schemas,
|
1064
|
+
components: components?.schemas ?? {}
|
1065
|
+
}),
|
1066
|
+
placeholder: metadata.placeholder ?? "",
|
1067
|
+
required: attribute.required ?? false,
|
1068
|
+
size: field.size,
|
1069
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1070
|
+
visible: metadata.visible ?? true,
|
1071
|
+
type: attribute.type
|
1072
|
+
};
|
1073
|
+
}).filter((field) => field !== null)
|
1074
|
+
);
|
1075
|
+
};
|
1076
|
+
const formatListLayout = (data, {
|
1077
|
+
schemas,
|
1078
|
+
schema,
|
1079
|
+
components
|
1080
|
+
}) => {
|
1081
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1082
|
+
(acc, [attribute, metadata]) => {
|
1083
|
+
return {
|
1084
|
+
...acc,
|
1085
|
+
[attribute]: metadata.list
|
1086
|
+
};
|
1087
|
+
},
|
1088
|
+
{}
|
1089
|
+
);
|
1090
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1091
|
+
data.contentType.layouts.list,
|
1092
|
+
schema?.attributes,
|
1093
|
+
listMetadatas,
|
1094
|
+
{ configurations: data.components, schemas: components },
|
1095
|
+
schemas
|
1096
|
+
);
|
1097
|
+
return {
|
1098
|
+
layout: listAttributes,
|
1099
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1100
|
+
metadatas: listMetadatas,
|
1101
|
+
options: {
|
1102
|
+
...schema?.options,
|
1103
|
+
...schema?.pluginOptions,
|
1104
|
+
...data.contentType.options
|
1105
|
+
}
|
1106
|
+
};
|
1107
|
+
};
|
1108
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1109
|
+
return columns.map((name) => {
|
1110
|
+
const attribute = attributes[name];
|
1111
|
+
if (!attribute) {
|
1112
|
+
return null;
|
1113
|
+
}
|
1114
|
+
const metadata = metadatas[name];
|
1115
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1116
|
+
return {
|
1117
|
+
attribute,
|
1118
|
+
label: metadata.label ?? "",
|
1119
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1120
|
+
schemas,
|
1121
|
+
components: components?.schemas ?? {}
|
1122
|
+
}),
|
1123
|
+
name,
|
1124
|
+
searchable: metadata.searchable ?? true,
|
1125
|
+
sortable: metadata.sortable ?? true
|
1126
|
+
};
|
1127
|
+
}).filter((field) => field !== null);
|
1128
|
+
};
|
1129
|
+
const useDocument = (args, opts) => {
|
1130
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
1131
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1132
|
+
const {
|
1133
|
+
currentData: data,
|
1134
|
+
isLoading: isLoadingDocument,
|
1135
|
+
isFetching: isFetchingDocument,
|
1136
|
+
error
|
1137
|
+
} = useGetDocumentQuery(args, {
|
1138
|
+
...opts,
|
1139
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1140
|
+
});
|
1141
|
+
const {
|
1142
|
+
components,
|
1143
|
+
schema,
|
1144
|
+
schemas,
|
1145
|
+
isLoading: isLoadingSchema
|
1146
|
+
} = useContentTypeSchema(args.model);
|
1147
|
+
React__namespace.useEffect(() => {
|
1148
|
+
if (error) {
|
1149
|
+
toggleNotification({
|
1150
|
+
type: "danger",
|
1151
|
+
message: formatAPIError(error)
|
1152
|
+
});
|
1153
|
+
}
|
1154
|
+
}, [toggleNotification, error, formatAPIError, args.collectionType]);
|
1155
|
+
const validationSchema = React__namespace.useMemo(() => {
|
1156
|
+
if (!schema) {
|
1157
|
+
return null;
|
1158
|
+
}
|
1159
|
+
return createYupSchema(schema.attributes, components);
|
1160
|
+
}, [schema, components]);
|
1161
|
+
const validate = React__namespace.useCallback(
|
1162
|
+
(document) => {
|
1163
|
+
if (!validationSchema) {
|
1164
|
+
throw new Error(
|
1165
|
+
"There is no validation schema generated, this is likely due to the schema not being loaded yet."
|
1166
|
+
);
|
1167
|
+
}
|
1168
|
+
try {
|
1169
|
+
validationSchema.validateSync(document, { abortEarly: false, strict: true });
|
1170
|
+
return null;
|
1171
|
+
} catch (error2) {
|
1172
|
+
if (error2 instanceof yup.ValidationError) {
|
1173
|
+
return strapiAdmin.getYupValidationErrors(error2);
|
1174
|
+
}
|
1175
|
+
throw error2;
|
1176
|
+
}
|
1177
|
+
},
|
1178
|
+
[validationSchema]
|
1179
|
+
);
|
1180
|
+
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1181
|
+
const hasError = !!error;
|
1182
|
+
return {
|
1183
|
+
components,
|
1184
|
+
document: data?.data,
|
1185
|
+
meta: data?.meta,
|
1186
|
+
isLoading,
|
1187
|
+
hasError,
|
1188
|
+
schema,
|
1189
|
+
schemas,
|
1190
|
+
validate
|
1191
|
+
};
|
1192
|
+
};
|
1193
|
+
const useDoc = () => {
|
1194
|
+
const { id, slug, collectionType, origin } = reactRouterDom.useParams();
|
1195
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
1196
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1197
|
+
if (!collectionType) {
|
1198
|
+
throw new Error("Could not find collectionType in url params");
|
838
1199
|
}
|
839
1200
|
if (!slug) {
|
840
1201
|
throw new Error("Could not find model in url params");
|
841
1202
|
}
|
1203
|
+
const document = useDocument(
|
1204
|
+
{ documentId: origin || id, model: slug, collectionType, params },
|
1205
|
+
{
|
1206
|
+
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
1207
|
+
}
|
1208
|
+
);
|
1209
|
+
const returnId = origin || id === "create" ? void 0 : id;
|
842
1210
|
return {
|
843
1211
|
collectionType,
|
844
1212
|
model: slug,
|
845
|
-
id:
|
846
|
-
...
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
1213
|
+
id: returnId,
|
1214
|
+
...document
|
1215
|
+
};
|
1216
|
+
};
|
1217
|
+
const useContentManagerContext = () => {
|
1218
|
+
const {
|
1219
|
+
collectionType,
|
1220
|
+
model,
|
1221
|
+
id,
|
1222
|
+
components,
|
1223
|
+
isLoading: isLoadingDoc,
|
1224
|
+
schema,
|
1225
|
+
schemas
|
1226
|
+
} = useDoc();
|
1227
|
+
const layout = useDocumentLayout(model);
|
1228
|
+
const form = strapiAdmin.useForm("useContentManagerContext", (state) => state);
|
1229
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1230
|
+
const slug = model;
|
1231
|
+
const isCreatingEntry = id === "create";
|
1232
|
+
useContentTypeSchema();
|
1233
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1234
|
+
const error = layout.error;
|
1235
|
+
return {
|
1236
|
+
error,
|
1237
|
+
isLoading,
|
1238
|
+
// Base metadata
|
1239
|
+
model,
|
1240
|
+
collectionType,
|
1241
|
+
id,
|
1242
|
+
slug,
|
1243
|
+
isCreatingEntry,
|
1244
|
+
isSingleType,
|
1245
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1246
|
+
// All schema infos
|
1247
|
+
components,
|
1248
|
+
contentType: schema,
|
1249
|
+
contentTypes: schemas,
|
1250
|
+
// Form state
|
1251
|
+
form,
|
1252
|
+
// layout infos
|
1253
|
+
layout
|
852
1254
|
};
|
853
1255
|
};
|
854
1256
|
const prefixPluginTranslations = (trad, pluginId) => {
|
855
|
-
if (!pluginId) {
|
856
|
-
throw new TypeError("pluginId can't be empty");
|
857
|
-
}
|
858
1257
|
return Object.keys(trad).reduce((acc, current) => {
|
859
1258
|
acc[`${pluginId}.${current}`] = trad[current];
|
860
1259
|
return acc;
|
@@ -870,6 +1269,8 @@ const useDocumentActions = () => {
|
|
870
1269
|
const { formatMessage } = reactIntl.useIntl();
|
871
1270
|
const { trackUsage } = strapiAdmin.useTracking();
|
872
1271
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1272
|
+
const navigate = reactRouterDom.useNavigate();
|
1273
|
+
const setCurrentStep = strapiAdmin.useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
873
1274
|
const [deleteDocument] = useDeleteDocumentMutation();
|
874
1275
|
const _delete = React__namespace.useCallback(
|
875
1276
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -948,12 +1349,13 @@ const useDocumentActions = () => {
|
|
948
1349
|
);
|
949
1350
|
const [discardDocument] = useDiscardDocumentMutation();
|
950
1351
|
const discard = React__namespace.useCallback(
|
951
|
-
async ({ collectionType, model, documentId }) => {
|
1352
|
+
async ({ collectionType, model, documentId, params }) => {
|
952
1353
|
try {
|
953
1354
|
const res = await discardDocument({
|
954
1355
|
collectionType,
|
955
1356
|
model,
|
956
|
-
documentId
|
1357
|
+
documentId,
|
1358
|
+
params
|
957
1359
|
});
|
958
1360
|
if ("error" in res) {
|
959
1361
|
toggleNotification({
|
@@ -1183,6 +1585,7 @@ const useDocumentActions = () => {
|
|
1183
1585
|
defaultMessage: "Saved document"
|
1184
1586
|
})
|
1185
1587
|
});
|
1588
|
+
setCurrentStep("contentManager.success");
|
1186
1589
|
return res.data;
|
1187
1590
|
} catch (err) {
|
1188
1591
|
toggleNotification({
|
@@ -1204,7 +1607,6 @@ const useDocumentActions = () => {
|
|
1204
1607
|
sourceId
|
1205
1608
|
});
|
1206
1609
|
if ("error" in res) {
|
1207
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1208
1610
|
return { error: res.error };
|
1209
1611
|
}
|
1210
1612
|
toggleNotification({
|
@@ -1223,7 +1625,7 @@ const useDocumentActions = () => {
|
|
1223
1625
|
throw err;
|
1224
1626
|
}
|
1225
1627
|
},
|
1226
|
-
[autoCloneDocument,
|
1628
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1227
1629
|
);
|
1228
1630
|
const [cloneDocument] = useCloneDocumentMutation();
|
1229
1631
|
const clone = React__namespace.useCallback(
|
@@ -1249,6 +1651,7 @@ const useDocumentActions = () => {
|
|
1249
1651
|
defaultMessage: "Cloned document"
|
1250
1652
|
})
|
1251
1653
|
});
|
1654
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1252
1655
|
return res.data;
|
1253
1656
|
} catch (err) {
|
1254
1657
|
toggleNotification({
|
@@ -1259,7 +1662,7 @@ const useDocumentActions = () => {
|
|
1259
1662
|
throw err;
|
1260
1663
|
}
|
1261
1664
|
},
|
1262
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1665
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1263
1666
|
);
|
1264
1667
|
const [getDoc] = useLazyGetDocumentQuery();
|
1265
1668
|
const getDocument = React__namespace.useCallback(
|
@@ -1284,10 +1687,10 @@ const useDocumentActions = () => {
|
|
1284
1687
|
update
|
1285
1688
|
};
|
1286
1689
|
};
|
1287
|
-
const ProtectedHistoryPage =
|
1288
|
-
() => Promise.resolve().then(() => require("./History-
|
1690
|
+
const ProtectedHistoryPage = React__namespace.lazy(
|
1691
|
+
() => Promise.resolve().then(() => require("./History-BqRQm2Lc.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1289
1692
|
);
|
1290
|
-
const routes$
|
1693
|
+
const routes$2 = [
|
1291
1694
|
{
|
1292
1695
|
path: ":collectionType/:slug/:id/history",
|
1293
1696
|
Component: ProtectedHistoryPage
|
@@ -1297,32 +1700,45 @@ const routes$1 = [
|
|
1297
1700
|
Component: ProtectedHistoryPage
|
1298
1701
|
}
|
1299
1702
|
];
|
1703
|
+
const ProtectedPreviewPage = React__namespace.lazy(
|
1704
|
+
() => Promise.resolve().then(() => require("./Preview-BqRUSbFU.js")).then((mod) => ({ default: mod.ProtectedPreviewPage }))
|
1705
|
+
);
|
1706
|
+
const routes$1 = [
|
1707
|
+
{
|
1708
|
+
path: ":collectionType/:slug/:id/preview",
|
1709
|
+
Component: ProtectedPreviewPage
|
1710
|
+
},
|
1711
|
+
{
|
1712
|
+
path: ":collectionType/:slug/preview",
|
1713
|
+
Component: ProtectedPreviewPage
|
1714
|
+
}
|
1715
|
+
];
|
1300
1716
|
const ProtectedEditViewPage = React.lazy(
|
1301
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1717
|
+
() => Promise.resolve().then(() => require("./EditViewPage-C-TZmK5r.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1302
1718
|
);
|
1303
1719
|
const ProtectedListViewPage = React.lazy(
|
1304
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1720
|
+
() => Promise.resolve().then(() => require("./ListViewPage-CYkrfWsm.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1305
1721
|
);
|
1306
1722
|
const ProtectedListConfiguration = React.lazy(
|
1307
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1723
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-BT69-TvF.js")).then((mod) => ({
|
1308
1724
|
default: mod.ProtectedListConfiguration
|
1309
1725
|
}))
|
1310
1726
|
);
|
1311
1727
|
const ProtectedEditConfigurationPage = React.lazy(
|
1312
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1728
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-CZRKq8CN.js")).then((mod) => ({
|
1313
1729
|
default: mod.ProtectedEditConfigurationPage
|
1314
1730
|
}))
|
1315
1731
|
);
|
1316
1732
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1317
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-
|
1733
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-BPiQrhZ6.js")).then((mod) => ({
|
1318
1734
|
default: mod.ProtectedComponentConfigurationPage
|
1319
1735
|
}))
|
1320
1736
|
);
|
1321
1737
|
const NoPermissions = React.lazy(
|
1322
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1738
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-DjUdvhJ6.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1323
1739
|
);
|
1324
1740
|
const NoContentType = React.lazy(
|
1325
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1741
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-BZMfRsrg.js")).then((mod) => ({ default: mod.NoContentType }))
|
1326
1742
|
);
|
1327
1743
|
const CollectionTypePages = () => {
|
1328
1744
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1334,7 +1750,7 @@ const CollectionTypePages = () => {
|
|
1334
1750
|
const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
|
1335
1751
|
const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
|
1336
1752
|
const LIST_RELATIVE_PATH = ":collectionType/:slug";
|
1337
|
-
const LIST_PATH = `/content-manager
|
1753
|
+
const LIST_PATH = `/content-manager/collection-types/:slug`;
|
1338
1754
|
const routes = [
|
1339
1755
|
{
|
1340
1756
|
path: LIST_RELATIVE_PATH,
|
@@ -1368,6 +1784,7 @@ const routes = [
|
|
1368
1784
|
path: "no-content-types",
|
1369
1785
|
Component: NoContentType
|
1370
1786
|
},
|
1787
|
+
...routes$2,
|
1371
1788
|
...routes$1
|
1372
1789
|
];
|
1373
1790
|
const DocumentActions = ({ actions: actions2 }) => {
|
@@ -1436,12 +1853,14 @@ const DocumentActionButton = (action) => {
|
|
1436
1853
|
/* @__PURE__ */ jsxRuntime.jsx(
|
1437
1854
|
designSystem.Button,
|
1438
1855
|
{
|
1439
|
-
flex:
|
1856
|
+
flex: "auto",
|
1440
1857
|
startIcon: action.icon,
|
1441
1858
|
disabled: action.disabled,
|
1442
1859
|
onClick: handleClick(action),
|
1443
1860
|
justifyContent: "center",
|
1444
1861
|
variant: action.variant || "default",
|
1862
|
+
paddingTop: "7px",
|
1863
|
+
paddingBottom: "7px",
|
1445
1864
|
children: action.label
|
1446
1865
|
}
|
1447
1866
|
),
|
@@ -1449,7 +1868,7 @@ const DocumentActionButton = (action) => {
|
|
1449
1868
|
DocumentActionConfirmDialog,
|
1450
1869
|
{
|
1451
1870
|
...action.dialog,
|
1452
|
-
variant: action.variant,
|
1871
|
+
variant: action.dialog?.variant ?? action.variant,
|
1453
1872
|
isOpen: dialogId === action.id,
|
1454
1873
|
onClose: handleClose
|
1455
1874
|
}
|
@@ -1464,6 +1883,11 @@ const DocumentActionButton = (action) => {
|
|
1464
1883
|
) : null
|
1465
1884
|
] });
|
1466
1885
|
};
|
1886
|
+
const MenuItem = styledComponents.styled(designSystem.Menu.Item)`
|
1887
|
+
&:hover {
|
1888
|
+
background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
|
1889
|
+
}
|
1890
|
+
`;
|
1467
1891
|
const DocumentActionsMenu = ({
|
1468
1892
|
actions: actions2,
|
1469
1893
|
children,
|
@@ -1506,9 +1930,9 @@ const DocumentActionsMenu = ({
|
|
1506
1930
|
disabled: isDisabled,
|
1507
1931
|
size: "S",
|
1508
1932
|
endIcon: null,
|
1509
|
-
paddingTop: "
|
1510
|
-
paddingLeft: "
|
1511
|
-
paddingRight: "
|
1933
|
+
paddingTop: "4px",
|
1934
|
+
paddingLeft: "7px",
|
1935
|
+
paddingRight: "7px",
|
1512
1936
|
variant,
|
1513
1937
|
children: [
|
1514
1938
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
|
@@ -1519,36 +1943,35 @@ const DocumentActionsMenu = ({
|
|
1519
1943
|
]
|
1520
1944
|
}
|
1521
1945
|
),
|
1522
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, {
|
1946
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1523
1947
|
actions2.map((action) => {
|
1524
1948
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
1525
|
-
|
1949
|
+
MenuItem,
|
1526
1950
|
{
|
1527
1951
|
disabled: action.disabled,
|
1528
1952
|
onSelect: handleClick(action),
|
1529
1953
|
display: "block",
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
] })
|
1954
|
+
isVariantDanger: action.variant === "danger",
|
1955
|
+
isDisabled: action.disabled,
|
1956
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
1957
|
+
designSystem.Flex,
|
1958
|
+
{
|
1959
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1960
|
+
gap: 2,
|
1961
|
+
tag: "span",
|
1962
|
+
children: [
|
1963
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
1964
|
+
designSystem.Flex,
|
1965
|
+
{
|
1966
|
+
tag: "span",
|
1967
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1968
|
+
children: action.icon
|
1969
|
+
}
|
1970
|
+
),
|
1971
|
+
action.label
|
1972
|
+
]
|
1973
|
+
}
|
1974
|
+
) })
|
1552
1975
|
},
|
1553
1976
|
action.id
|
1554
1977
|
);
|
@@ -1590,8 +2013,20 @@ const convertActionVariantToColor = (variant = "secondary") => {
|
|
1590
2013
|
return "primary600";
|
1591
2014
|
}
|
1592
2015
|
};
|
1593
|
-
const
|
1594
|
-
|
2016
|
+
const convertActionVariantToIconColor = (variant = "secondary") => {
|
2017
|
+
switch (variant) {
|
2018
|
+
case "danger":
|
2019
|
+
return "danger600";
|
2020
|
+
case "secondary":
|
2021
|
+
return "neutral500";
|
2022
|
+
case "success":
|
2023
|
+
return "success600";
|
2024
|
+
default:
|
2025
|
+
return "primary600";
|
2026
|
+
}
|
2027
|
+
};
|
2028
|
+
const DocumentActionConfirmDialog = ({
|
2029
|
+
onClose,
|
1595
2030
|
onCancel,
|
1596
2031
|
onConfirm,
|
1597
2032
|
title,
|
@@ -1612,22 +2047,20 @@ const DocumentActionConfirmDialog = ({
|
|
1612
2047
|
}
|
1613
2048
|
onClose();
|
1614
2049
|
};
|
1615
|
-
return /* @__PURE__ */ jsxRuntime.
|
1616
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
1617
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
1618
|
-
|
1619
|
-
{
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
)
|
1630
|
-
] });
|
2050
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2051
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
2052
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
|
2053
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
2054
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
2055
|
+
id: "app.components.Button.cancel",
|
2056
|
+
defaultMessage: "Cancel"
|
2057
|
+
}) }) }),
|
2058
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
2059
|
+
id: "app.components.Button.confirm",
|
2060
|
+
defaultMessage: "Confirm"
|
2061
|
+
}) })
|
2062
|
+
] })
|
2063
|
+
] }) });
|
1631
2064
|
};
|
1632
2065
|
const DocumentActionModal = ({
|
1633
2066
|
isOpen,
|
@@ -1637,34 +2070,29 @@ const DocumentActionModal = ({
|
|
1637
2070
|
content: Content,
|
1638
2071
|
onModalClose
|
1639
2072
|
}) => {
|
1640
|
-
const id = React__namespace.useId();
|
1641
|
-
if (!isOpen) {
|
1642
|
-
return null;
|
1643
|
-
}
|
1644
2073
|
const handleClose = () => {
|
1645
2074
|
if (onClose) {
|
1646
2075
|
onClose();
|
1647
2076
|
}
|
1648
2077
|
onModalClose();
|
1649
2078
|
};
|
1650
|
-
return /* @__PURE__ */ jsxRuntime.
|
1651
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
1652
|
-
|
1653
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
] });
|
2079
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
|
2080
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: title }) }),
|
2081
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: Content }),
|
2082
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
|
2083
|
+
] }) });
|
2084
|
+
};
|
2085
|
+
const transformData = (data) => {
|
2086
|
+
if (Array.isArray(data)) {
|
2087
|
+
return data.map(transformData);
|
2088
|
+
}
|
2089
|
+
if (typeof data === "object" && data !== null) {
|
2090
|
+
if ("apiData" in data) {
|
2091
|
+
return data.apiData;
|
2092
|
+
}
|
2093
|
+
return mapValues__default.default(transformData)(data);
|
2094
|
+
}
|
2095
|
+
return data;
|
1668
2096
|
};
|
1669
2097
|
const PublishAction$1 = ({
|
1670
2098
|
activeTab,
|
@@ -1678,13 +2106,18 @@ const PublishAction$1 = ({
|
|
1678
2106
|
const navigate = reactRouterDom.useNavigate();
|
1679
2107
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1680
2108
|
const { _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
|
2109
|
+
const isListView = reactRouterDom.useMatch(LIST_PATH) !== null;
|
1681
2110
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2111
|
+
const { id } = reactRouterDom.useParams();
|
1682
2112
|
const { formatMessage } = reactIntl.useIntl();
|
1683
|
-
const { canPublish
|
1684
|
-
"PublishAction",
|
1685
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1686
|
-
);
|
2113
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1687
2114
|
const { publish } = useDocumentActions();
|
2115
|
+
const [
|
2116
|
+
countDraftRelations,
|
2117
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
2118
|
+
] = useLazyGetDraftRelationCountQuery();
|
2119
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React__namespace.useState(0);
|
2120
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React__namespace.useState(0);
|
1688
2121
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1689
2122
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1690
2123
|
const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1693,10 +2126,107 @@ const PublishAction$1 = ({
|
|
1693
2126
|
const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
|
1694
2127
|
const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
|
1695
2128
|
const formValues = strapiAdmin.useForm("PublishAction", ({ values }) => values);
|
2129
|
+
React__namespace.useEffect(() => {
|
2130
|
+
if (isErrorDraftRelations) {
|
2131
|
+
toggleNotification({
|
2132
|
+
type: "danger",
|
2133
|
+
message: formatMessage({
|
2134
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
2135
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
2136
|
+
})
|
2137
|
+
});
|
2138
|
+
}
|
2139
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
2140
|
+
React__namespace.useEffect(() => {
|
2141
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
2142
|
+
const extractDraftRelations = (data) => {
|
2143
|
+
const relations = data.connect || [];
|
2144
|
+
relations.forEach((relation) => {
|
2145
|
+
if (relation.status === "draft") {
|
2146
|
+
localDraftRelations.add(relation.id);
|
2147
|
+
}
|
2148
|
+
});
|
2149
|
+
};
|
2150
|
+
const traverseAndExtract = (data) => {
|
2151
|
+
Object.entries(data).forEach(([key, value]) => {
|
2152
|
+
if (key === "connect" && Array.isArray(value)) {
|
2153
|
+
extractDraftRelations({ connect: value });
|
2154
|
+
} else if (typeof value === "object" && value !== null) {
|
2155
|
+
traverseAndExtract(value);
|
2156
|
+
}
|
2157
|
+
});
|
2158
|
+
};
|
2159
|
+
if (!documentId || modified) {
|
2160
|
+
traverseAndExtract(formValues);
|
2161
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
2162
|
+
}
|
2163
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
2164
|
+
React__namespace.useEffect(() => {
|
2165
|
+
if (!document || !document.documentId || isListView) {
|
2166
|
+
return;
|
2167
|
+
}
|
2168
|
+
const fetchDraftRelationsCount = async () => {
|
2169
|
+
const { data, error } = await countDraftRelations({
|
2170
|
+
collectionType,
|
2171
|
+
model,
|
2172
|
+
documentId,
|
2173
|
+
params
|
2174
|
+
});
|
2175
|
+
if (error) {
|
2176
|
+
throw error;
|
2177
|
+
}
|
2178
|
+
if (data) {
|
2179
|
+
setServerCountOfDraftRelations(data.data);
|
2180
|
+
}
|
2181
|
+
};
|
2182
|
+
fetchDraftRelationsCount();
|
2183
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
1696
2184
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1697
2185
|
if (!schema?.options?.draftAndPublish) {
|
1698
2186
|
return null;
|
1699
2187
|
}
|
2188
|
+
const performPublish = async () => {
|
2189
|
+
setSubmitting(true);
|
2190
|
+
try {
|
2191
|
+
const { errors } = await validate(true, {
|
2192
|
+
status: "published"
|
2193
|
+
});
|
2194
|
+
if (errors) {
|
2195
|
+
toggleNotification({
|
2196
|
+
type: "danger",
|
2197
|
+
message: formatMessage({
|
2198
|
+
id: "content-manager.validation.error",
|
2199
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2200
|
+
})
|
2201
|
+
});
|
2202
|
+
return;
|
2203
|
+
}
|
2204
|
+
const res = await publish(
|
2205
|
+
{
|
2206
|
+
collectionType,
|
2207
|
+
model,
|
2208
|
+
documentId,
|
2209
|
+
params
|
2210
|
+
},
|
2211
|
+
transformData(formValues)
|
2212
|
+
);
|
2213
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2214
|
+
if (id === "create") {
|
2215
|
+
navigate({
|
2216
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2217
|
+
search: rawQuery
|
2218
|
+
});
|
2219
|
+
}
|
2220
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2221
|
+
setErrors(formatValidationErrors(res.error));
|
2222
|
+
}
|
2223
|
+
} finally {
|
2224
|
+
setSubmitting(false);
|
2225
|
+
}
|
2226
|
+
};
|
2227
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
2228
|
+
const enableDraftRelationsCount = false;
|
2229
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1700
2230
|
return {
|
1701
2231
|
/**
|
1702
2232
|
* Disabled when:
|
@@ -1706,52 +2236,40 @@ const PublishAction$1 = ({
|
|
1706
2236
|
* - the document is already published & not modified
|
1707
2237
|
* - the document is being created & not modified
|
1708
2238
|
* - the user doesn't have the permission to publish
|
1709
|
-
* - the user doesn't have the permission to create a new document
|
1710
|
-
* - the user doesn't have the permission to update the document
|
1711
2239
|
*/
|
1712
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
2240
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1713
2241
|
label: formatMessage({
|
1714
2242
|
id: "app.utils.publish",
|
1715
2243
|
defaultMessage: "Publish"
|
1716
2244
|
}),
|
1717
2245
|
onClick: async () => {
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1731
|
-
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
documentId,
|
1736
|
-
params
|
1737
|
-
},
|
1738
|
-
formValues
|
1739
|
-
);
|
1740
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1741
|
-
navigate({
|
1742
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1743
|
-
search: rawQuery
|
1744
|
-
});
|
1745
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1746
|
-
setErrors(formatValidationErrors(res.error));
|
2246
|
+
await performPublish();
|
2247
|
+
},
|
2248
|
+
dialog: hasDraftRelations ? {
|
2249
|
+
type: "dialog",
|
2250
|
+
variant: "danger",
|
2251
|
+
footer: null,
|
2252
|
+
title: formatMessage({
|
2253
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
2254
|
+
defaultMessage: "Confirmation"
|
2255
|
+
}),
|
2256
|
+
content: formatMessage(
|
2257
|
+
{
|
2258
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
2259
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
2260
|
+
},
|
2261
|
+
{
|
2262
|
+
count: totalDraftRelations
|
1747
2263
|
}
|
1748
|
-
|
1749
|
-
|
2264
|
+
),
|
2265
|
+
onConfirm: async () => {
|
2266
|
+
await performPublish();
|
1750
2267
|
}
|
1751
|
-
}
|
2268
|
+
} : void 0
|
1752
2269
|
};
|
1753
2270
|
};
|
1754
2271
|
PublishAction$1.type = "publish";
|
2272
|
+
PublishAction$1.position = "panel";
|
1755
2273
|
const UpdateAction = ({
|
1756
2274
|
activeTab,
|
1757
2275
|
documentId,
|
@@ -1764,10 +2282,6 @@ const UpdateAction = ({
|
|
1764
2282
|
const cloneMatch = reactRouterDom.useMatch(CLONE_PATH);
|
1765
2283
|
const isCloning = cloneMatch !== null;
|
1766
2284
|
const { formatMessage } = reactIntl.useIntl();
|
1767
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1768
|
-
canCreate: canCreate2,
|
1769
|
-
canUpdate: canUpdate2
|
1770
|
-
}));
|
1771
2285
|
const { create, update, clone } = useDocumentActions();
|
1772
2286
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1773
2287
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
@@ -1784,18 +2298,18 @@ const UpdateAction = ({
|
|
1784
2298
|
* - the form is submitting
|
1785
2299
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1786
2300
|
* - the active tab is the published tab
|
1787
|
-
* - the user doesn't have the permission to create a new document
|
1788
|
-
* - the user doesn't have the permission to update the document
|
1789
2301
|
*/
|
1790
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
2302
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1791
2303
|
label: formatMessage({
|
1792
|
-
id: "
|
2304
|
+
id: "global.save",
|
1793
2305
|
defaultMessage: "Save"
|
1794
2306
|
}),
|
1795
2307
|
onClick: async () => {
|
1796
2308
|
setSubmitting(true);
|
1797
2309
|
try {
|
1798
|
-
const { errors } = await validate(
|
2310
|
+
const { errors } = await validate(true, {
|
2311
|
+
status: "draft"
|
2312
|
+
});
|
1799
2313
|
if (errors) {
|
1800
2314
|
toggleNotification({
|
1801
2315
|
type: "danger",
|
@@ -1813,13 +2327,16 @@ const UpdateAction = ({
|
|
1813
2327
|
documentId: cloneMatch.params.origin,
|
1814
2328
|
params
|
1815
2329
|
},
|
1816
|
-
document
|
2330
|
+
transformData(document)
|
1817
2331
|
);
|
1818
2332
|
if ("data" in res) {
|
1819
|
-
navigate(
|
1820
|
-
|
1821
|
-
|
1822
|
-
|
2333
|
+
navigate(
|
2334
|
+
{
|
2335
|
+
pathname: `../${res.data.documentId}`,
|
2336
|
+
search: rawQuery
|
2337
|
+
},
|
2338
|
+
{ relative: "path" }
|
2339
|
+
);
|
1823
2340
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1824
2341
|
setErrors(formatValidationErrors(res.error));
|
1825
2342
|
}
|
@@ -1831,7 +2348,7 @@ const UpdateAction = ({
|
|
1831
2348
|
documentId,
|
1832
2349
|
params
|
1833
2350
|
},
|
1834
|
-
document
|
2351
|
+
transformData(document)
|
1835
2352
|
);
|
1836
2353
|
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1837
2354
|
setErrors(formatValidationErrors(res.error));
|
@@ -1844,13 +2361,16 @@ const UpdateAction = ({
|
|
1844
2361
|
model,
|
1845
2362
|
params
|
1846
2363
|
},
|
1847
|
-
document
|
2364
|
+
transformData(document)
|
1848
2365
|
);
|
1849
2366
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1850
|
-
navigate(
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
2367
|
+
navigate(
|
2368
|
+
{
|
2369
|
+
pathname: `../${res.data.documentId}`,
|
2370
|
+
search: rawQuery
|
2371
|
+
},
|
2372
|
+
{ replace: true, relative: "path" }
|
2373
|
+
);
|
1854
2374
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1855
2375
|
setErrors(formatValidationErrors(res.error));
|
1856
2376
|
}
|
@@ -1862,6 +2382,7 @@ const UpdateAction = ({
|
|
1862
2382
|
};
|
1863
2383
|
};
|
1864
2384
|
UpdateAction.type = "update";
|
2385
|
+
UpdateAction.position = "panel";
|
1865
2386
|
const UNPUBLISH_DRAFT_OPTIONS = {
|
1866
2387
|
KEEP: "keep",
|
1867
2388
|
DISCARD: "discard"
|
@@ -1882,10 +2403,8 @@ const UnpublishAction$1 = ({
|
|
1882
2403
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1883
2404
|
const [shouldKeepDraft, setShouldKeepDraft] = React__namespace.useState(true);
|
1884
2405
|
const isDocumentModified = document?.status === "modified";
|
1885
|
-
const handleChange = (
|
1886
|
-
|
1887
|
-
setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1888
|
-
}
|
2406
|
+
const handleChange = (value) => {
|
2407
|
+
setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1889
2408
|
};
|
1890
2409
|
if (!schema?.options?.draftAndPublish) {
|
1891
2410
|
return null;
|
@@ -1896,7 +2415,7 @@ const UnpublishAction$1 = ({
|
|
1896
2415
|
id: "app.utils.unpublish",
|
1897
2416
|
defaultMessage: "Unpublish"
|
1898
2417
|
}),
|
1899
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2418
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
1900
2419
|
onClick: async () => {
|
1901
2420
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1902
2421
|
if (!documentId) {
|
@@ -1935,40 +2454,24 @@ const UnpublishAction$1 = ({
|
|
1935
2454
|
}) })
|
1936
2455
|
] }),
|
1937
2456
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
1938
|
-
designSystem.
|
2457
|
+
designSystem.Radio.Group,
|
1939
2458
|
{
|
1940
|
-
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
1945
|
-
|
2459
|
+
defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
|
2460
|
+
name: "discard-options",
|
2461
|
+
"aria-label": formatMessage({
|
2462
|
+
id: "content-manager.actions.unpublish.dialog.radio-label",
|
2463
|
+
defaultMessage: "Choose an option to unpublish the document."
|
2464
|
+
}),
|
2465
|
+
onValueChange: handleChange,
|
1946
2466
|
children: [
|
1947
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
1956
|
-
defaultMessage: "Keep draft"
|
1957
|
-
})
|
1958
|
-
}
|
1959
|
-
),
|
1960
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
1961
|
-
designSystem.Radio,
|
1962
|
-
{
|
1963
|
-
checked: !shouldKeepDraft,
|
1964
|
-
value: UNPUBLISH_DRAFT_OPTIONS.DISCARD,
|
1965
|
-
name: "discard-options",
|
1966
|
-
children: formatMessage({
|
1967
|
-
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
1968
|
-
defaultMessage: "Replace draft"
|
1969
|
-
})
|
1970
|
-
}
|
1971
|
-
)
|
2467
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
|
2468
|
+
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
2469
|
+
defaultMessage: "Keep draft"
|
2470
|
+
}) }),
|
2471
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
|
2472
|
+
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
2473
|
+
defaultMessage: "Replace draft"
|
2474
|
+
}) })
|
1972
2475
|
]
|
1973
2476
|
}
|
1974
2477
|
)
|
@@ -2002,6 +2505,7 @@ const UnpublishAction$1 = ({
|
|
2002
2505
|
};
|
2003
2506
|
};
|
2004
2507
|
UnpublishAction$1.type = "unpublish";
|
2508
|
+
UnpublishAction$1.position = "panel";
|
2005
2509
|
const DiscardAction = ({
|
2006
2510
|
activeTab,
|
2007
2511
|
documentId,
|
@@ -2024,7 +2528,7 @@ const DiscardAction = ({
|
|
2024
2528
|
id: "content-manager.actions.discard.label",
|
2025
2529
|
defaultMessage: "Discard changes"
|
2026
2530
|
}),
|
2027
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2531
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
2028
2532
|
position: ["panel", "table-row"],
|
2029
2533
|
variant: "danger",
|
2030
2534
|
dialog: {
|
@@ -2052,11 +2556,7 @@ const DiscardAction = ({
|
|
2052
2556
|
};
|
2053
2557
|
};
|
2054
2558
|
DiscardAction.type = "discard";
|
2055
|
-
|
2056
|
-
path {
|
2057
|
-
fill: currentColor;
|
2058
|
-
}
|
2059
|
-
`;
|
2559
|
+
DiscardAction.position = "panel";
|
2060
2560
|
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
2061
2561
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
2062
2562
|
const RelativeTime = React__namespace.forwardRef(
|
@@ -2069,7 +2569,7 @@ const RelativeTime = React__namespace.forwardRef(
|
|
2069
2569
|
});
|
2070
2570
|
const unit = intervals.find((intervalUnit) => {
|
2071
2571
|
return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
|
2072
|
-
});
|
2572
|
+
}) ?? "seconds";
|
2073
2573
|
const relativeTime = dateFns.isPast(timestamp) ? -interval[unit] : interval[unit];
|
2074
2574
|
const customInterval = customIntervals.find(
|
2075
2575
|
(custom) => interval[custom.unit] < custom.threshold
|
@@ -2103,34 +2603,34 @@ const getDisplayName = ({
|
|
2103
2603
|
return email ?? "";
|
2104
2604
|
};
|
2105
2605
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2106
|
-
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2107
|
-
const statusVariant = status === "draft" ? "
|
2108
|
-
|
2606
|
+
const DocumentStatus = ({ status = "draft", size = "S", ...restProps }) => {
|
2607
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2608
|
+
const { formatMessage } = reactIntl.useIntl();
|
2609
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { ...restProps, size, variant: statusVariant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: formatMessage({
|
2610
|
+
id: `content-manager.containers.List.${status}`,
|
2611
|
+
defaultMessage: capitalise(status)
|
2612
|
+
}) }) });
|
2109
2613
|
};
|
2110
2614
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2111
2615
|
const { formatMessage } = reactIntl.useIntl();
|
2112
2616
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2617
|
+
const params = reactRouterDom.useParams();
|
2113
2618
|
const title = isCreating ? formatMessage({
|
2114
2619
|
id: "content-manager.containers.edit.title.new",
|
2115
2620
|
defaultMessage: "Create an entry"
|
2116
2621
|
}) : documentTitle;
|
2117
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2118
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
2119
|
-
|
2120
|
-
designSystem.Flex,
|
2622
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2623
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2624
|
+
strapiAdmin.BackButton,
|
2121
2625
|
{
|
2122
|
-
|
2123
|
-
justifyContent: "space-between",
|
2124
|
-
paddingTop: 1,
|
2125
|
-
gap: "80px",
|
2126
|
-
alignItems: "flex-start",
|
2127
|
-
children: [
|
2128
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2129
|
-
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2130
|
-
]
|
2626
|
+
fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
|
2131
2627
|
}
|
2132
2628
|
),
|
2133
|
-
|
2629
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2630
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2631
|
+
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2632
|
+
] }),
|
2633
|
+
status ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2134
2634
|
] });
|
2135
2635
|
};
|
2136
2636
|
const HeaderToolbar = () => {
|
@@ -2176,7 +2676,7 @@ const HeaderToolbar = () => {
|
|
2176
2676
|
meta: isCloning ? void 0 : meta,
|
2177
2677
|
collectionType
|
2178
2678
|
},
|
2179
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2679
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("header"),
|
2180
2680
|
children: (actions2) => {
|
2181
2681
|
const headerActions = actions2.filter((action) => {
|
2182
2682
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -2213,12 +2713,12 @@ const Information = ({ activeTab }) => {
|
|
2213
2713
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2214
2714
|
label: formatMessage({
|
2215
2715
|
id: "content-manager.containers.edit.information.last-published.label",
|
2216
|
-
defaultMessage: "
|
2716
|
+
defaultMessage: "Published"
|
2217
2717
|
}),
|
2218
2718
|
value: formatMessage(
|
2219
2719
|
{
|
2220
2720
|
id: "content-manager.containers.edit.information.last-published.value",
|
2221
|
-
defaultMessage: `
|
2721
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2222
2722
|
},
|
2223
2723
|
{
|
2224
2724
|
time: /* @__PURE__ */ jsxRuntime.jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2231,12 +2731,12 @@ const Information = ({ activeTab }) => {
|
|
2231
2731
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2232
2732
|
label: formatMessage({
|
2233
2733
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2234
|
-
defaultMessage: "
|
2734
|
+
defaultMessage: "Updated"
|
2235
2735
|
}),
|
2236
2736
|
value: formatMessage(
|
2237
2737
|
{
|
2238
2738
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2239
|
-
defaultMessage: `
|
2739
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2240
2740
|
},
|
2241
2741
|
{
|
2242
2742
|
time: /* @__PURE__ */ jsxRuntime.jsx(
|
@@ -2254,12 +2754,12 @@ const Information = ({ activeTab }) => {
|
|
2254
2754
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2255
2755
|
label: formatMessage({
|
2256
2756
|
id: "content-manager.containers.edit.information.document.label",
|
2257
|
-
defaultMessage: "
|
2757
|
+
defaultMessage: "Created"
|
2258
2758
|
}),
|
2259
2759
|
value: formatMessage(
|
2260
2760
|
{
|
2261
2761
|
id: "content-manager.containers.edit.information.document.value",
|
2262
|
-
defaultMessage: `
|
2762
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2263
2763
|
},
|
2264
2764
|
{
|
2265
2765
|
time: /* @__PURE__ */ jsxRuntime.jsx(
|
@@ -2297,25 +2797,77 @@ const Information = ({ activeTab }) => {
|
|
2297
2797
|
);
|
2298
2798
|
};
|
2299
2799
|
const HeaderActions = ({ actions: actions2 }) => {
|
2300
|
-
|
2301
|
-
|
2800
|
+
const [dialogId, setDialogId] = React__namespace.useState(null);
|
2801
|
+
const handleClick = (action) => async (e) => {
|
2802
|
+
if (!("options" in action)) {
|
2803
|
+
const { onClick = () => false, dialog, id } = action;
|
2804
|
+
const muteDialog = await onClick(e);
|
2805
|
+
if (dialog && !muteDialog) {
|
2806
|
+
e.preventDefault();
|
2807
|
+
setDialogId(id);
|
2808
|
+
}
|
2809
|
+
}
|
2810
|
+
};
|
2811
|
+
const handleClose = () => {
|
2812
|
+
setDialogId(null);
|
2813
|
+
};
|
2814
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, children: actions2.map((action) => {
|
2815
|
+
if (action.options) {
|
2302
2816
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
2303
2817
|
designSystem.SingleSelect,
|
2304
2818
|
{
|
2305
2819
|
size: "S",
|
2306
|
-
disabled: action.disabled,
|
2307
|
-
"aria-label": action.label,
|
2308
2820
|
onChange: action.onSelect,
|
2309
|
-
|
2821
|
+
"aria-label": action.label,
|
2822
|
+
...action,
|
2310
2823
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { ...option, children: label }, option.value))
|
2311
2824
|
},
|
2312
2825
|
action.id
|
2313
2826
|
);
|
2314
2827
|
} else {
|
2315
|
-
|
2828
|
+
if (action.type === "icon") {
|
2829
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
|
2830
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2831
|
+
designSystem.IconButton,
|
2832
|
+
{
|
2833
|
+
disabled: action.disabled,
|
2834
|
+
label: action.label,
|
2835
|
+
size: "S",
|
2836
|
+
onClick: handleClick(action),
|
2837
|
+
children: action.icon
|
2838
|
+
}
|
2839
|
+
),
|
2840
|
+
action.dialog ? /* @__PURE__ */ jsxRuntime.jsx(
|
2841
|
+
HeaderActionDialog,
|
2842
|
+
{
|
2843
|
+
...action.dialog,
|
2844
|
+
isOpen: dialogId === action.id,
|
2845
|
+
onClose: handleClose
|
2846
|
+
}
|
2847
|
+
) : null
|
2848
|
+
] }, action.id);
|
2849
|
+
}
|
2316
2850
|
}
|
2317
2851
|
}) });
|
2318
2852
|
};
|
2853
|
+
const HeaderActionDialog = ({
|
2854
|
+
onClose,
|
2855
|
+
onCancel,
|
2856
|
+
title,
|
2857
|
+
content: Content,
|
2858
|
+
isOpen
|
2859
|
+
}) => {
|
2860
|
+
const handleClose = async () => {
|
2861
|
+
if (onCancel) {
|
2862
|
+
await onCancel();
|
2863
|
+
}
|
2864
|
+
onClose();
|
2865
|
+
};
|
2866
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2867
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
2868
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : Content
|
2869
|
+
] }) });
|
2870
|
+
};
|
2319
2871
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2320
2872
|
const navigate = reactRouterDom.useNavigate();
|
2321
2873
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2332,6 +2884,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2332
2884
|
};
|
2333
2885
|
};
|
2334
2886
|
ConfigureTheViewAction.type = "configure-the-view";
|
2887
|
+
ConfigureTheViewAction.position = "header";
|
2335
2888
|
const EditTheModelAction = ({ model }) => {
|
2336
2889
|
const navigate = reactRouterDom.useNavigate();
|
2337
2890
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2348,6 +2901,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2348
2901
|
};
|
2349
2902
|
};
|
2350
2903
|
EditTheModelAction.type = "edit-the-model";
|
2904
|
+
EditTheModelAction.position = "header";
|
2351
2905
|
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2352
2906
|
const navigate = reactRouterDom.useNavigate();
|
2353
2907
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2356,12 +2910,16 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2356
2910
|
const { delete: deleteAction } = useDocumentActions();
|
2357
2911
|
const { toggleNotification } = strapiAdmin.useNotification();
|
2358
2912
|
const setSubmitting = strapiAdmin.useForm("DeleteAction", (state) => state.setSubmitting);
|
2913
|
+
const isLocalized = document?.locale != null;
|
2359
2914
|
return {
|
2360
2915
|
disabled: !canDelete || !document,
|
2361
|
-
label: formatMessage(
|
2362
|
-
|
2363
|
-
|
2364
|
-
|
2916
|
+
label: formatMessage(
|
2917
|
+
{
|
2918
|
+
id: "content-manager.actions.delete.label",
|
2919
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2920
|
+
},
|
2921
|
+
{ isLocalized }
|
2922
|
+
),
|
2365
2923
|
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2366
2924
|
dialog: {
|
2367
2925
|
type: "dialog",
|
@@ -2417,6 +2975,7 @@ const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
|
2417
2975
|
};
|
2418
2976
|
};
|
2419
2977
|
DeleteAction$1.type = "delete";
|
2978
|
+
DeleteAction$1.position = ["header", "table-row"];
|
2420
2979
|
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2421
2980
|
const Panels = () => {
|
2422
2981
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
@@ -2451,7 +3010,7 @@ const ActionsPanel = () => {
|
|
2451
3010
|
return {
|
2452
3011
|
title: formatMessage({
|
2453
3012
|
id: "content-manager.containers.edit.panels.default.title",
|
2454
|
-
defaultMessage: "
|
3013
|
+
defaultMessage: "Entry"
|
2455
3014
|
}),
|
2456
3015
|
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2457
3016
|
};
|
@@ -2479,7 +3038,7 @@ const ActionsPanelContent = () => {
|
|
2479
3038
|
strapiAdmin.DescriptionComponentRenderer,
|
2480
3039
|
{
|
2481
3040
|
props,
|
2482
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3041
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("panel"),
|
2483
3042
|
children: (actions2) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActions, { actions: actions2 })
|
2484
3043
|
}
|
2485
3044
|
),
|
@@ -2506,314 +3065,12 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
|
2506
3065
|
justifyContent: "stretch",
|
2507
3066
|
alignItems: "flex-start",
|
2508
3067
|
children: [
|
2509
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
|
3068
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", textColor: "neutral600", children: title }),
|
2510
3069
|
children
|
2511
3070
|
]
|
2512
3071
|
}
|
2513
|
-
);
|
2514
|
-
});
|
2515
|
-
const HOOKS = {
|
2516
|
-
/**
|
2517
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2518
|
-
* @constant
|
2519
|
-
* @type {string}
|
2520
|
-
*/
|
2521
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2522
|
-
/**
|
2523
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2524
|
-
* @constant
|
2525
|
-
* @type {string}
|
2526
|
-
*/
|
2527
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2528
|
-
/**
|
2529
|
-
* Hook that allows to mutate the CM's edit view layout
|
2530
|
-
* @constant
|
2531
|
-
* @type {string}
|
2532
|
-
*/
|
2533
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2534
|
-
/**
|
2535
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2536
|
-
* @constant
|
2537
|
-
* @type {string}
|
2538
|
-
*/
|
2539
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2540
|
-
};
|
2541
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2542
|
-
endpoints: (builder) => ({
|
2543
|
-
getContentTypeConfiguration: builder.query({
|
2544
|
-
query: (uid) => ({
|
2545
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2546
|
-
method: "GET"
|
2547
|
-
}),
|
2548
|
-
transformResponse: (response) => response.data,
|
2549
|
-
providesTags: (_result, _error, uid) => [
|
2550
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2551
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2552
|
-
]
|
2553
|
-
}),
|
2554
|
-
getAllContentTypeSettings: builder.query({
|
2555
|
-
query: () => "/content-manager/content-types-settings",
|
2556
|
-
transformResponse: (response) => response.data,
|
2557
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2558
|
-
}),
|
2559
|
-
updateContentTypeConfiguration: builder.mutation({
|
2560
|
-
query: ({ uid, ...body }) => ({
|
2561
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2562
|
-
method: "PUT",
|
2563
|
-
data: body
|
2564
|
-
}),
|
2565
|
-
transformResponse: (response) => response.data,
|
2566
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2567
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2568
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2569
|
-
// Is this necessary?
|
2570
|
-
{ type: "InitialData" }
|
2571
|
-
]
|
2572
|
-
})
|
2573
|
-
})
|
2574
|
-
});
|
2575
|
-
const {
|
2576
|
-
useGetContentTypeConfigurationQuery,
|
2577
|
-
useGetAllContentTypeSettingsQuery,
|
2578
|
-
useUpdateContentTypeConfigurationMutation
|
2579
|
-
} = contentTypesApi;
|
2580
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2581
|
-
const { type } = attribute;
|
2582
|
-
if (type === "relation") {
|
2583
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2584
|
-
}
|
2585
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2586
|
-
};
|
2587
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2588
|
-
if (!mainFieldName) {
|
2589
|
-
return void 0;
|
2590
|
-
}
|
2591
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2592
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2593
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2594
|
-
);
|
2595
|
-
return {
|
2596
|
-
name: mainFieldName,
|
2597
|
-
type: mainFieldType ?? "string"
|
2598
|
-
};
|
2599
|
-
};
|
2600
|
-
const DEFAULT_SETTINGS = {
|
2601
|
-
bulkable: false,
|
2602
|
-
filterable: false,
|
2603
|
-
searchable: false,
|
2604
|
-
pagination: false,
|
2605
|
-
defaultSortBy: "",
|
2606
|
-
defaultSortOrder: "asc",
|
2607
|
-
mainField: "id",
|
2608
|
-
pageSize: 10
|
2609
|
-
};
|
2610
|
-
const useDocumentLayout = (model) => {
|
2611
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2612
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
2613
|
-
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2614
|
-
const { toggleNotification } = strapiAdmin.useNotification();
|
2615
|
-
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
2616
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2617
|
-
const {
|
2618
|
-
data,
|
2619
|
-
isLoading: isLoadingConfigs,
|
2620
|
-
error,
|
2621
|
-
isFetching: isFetchingConfigs
|
2622
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2623
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2624
|
-
React__namespace.useEffect(() => {
|
2625
|
-
if (error) {
|
2626
|
-
toggleNotification({
|
2627
|
-
type: "danger",
|
2628
|
-
message: formatAPIError(error)
|
2629
|
-
});
|
2630
|
-
}
|
2631
|
-
}, [error, formatAPIError, toggleNotification]);
|
2632
|
-
const editLayout = React__namespace.useMemo(
|
2633
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2634
|
-
layout: [],
|
2635
|
-
components: {},
|
2636
|
-
metadatas: {},
|
2637
|
-
options: {},
|
2638
|
-
settings: DEFAULT_SETTINGS
|
2639
|
-
},
|
2640
|
-
[data, isLoading, schemas, schema, components]
|
2641
|
-
);
|
2642
|
-
const listLayout = React__namespace.useMemo(() => {
|
2643
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2644
|
-
layout: [],
|
2645
|
-
metadatas: {},
|
2646
|
-
options: {},
|
2647
|
-
settings: DEFAULT_SETTINGS
|
2648
|
-
};
|
2649
|
-
}, [data, isLoading, schemas, schema, components]);
|
2650
|
-
const { layout: edit } = React__namespace.useMemo(
|
2651
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2652
|
-
layout: editLayout,
|
2653
|
-
query
|
2654
|
-
}),
|
2655
|
-
[editLayout, query, runHookWaterfall]
|
2656
|
-
);
|
2657
|
-
return {
|
2658
|
-
error,
|
2659
|
-
isLoading,
|
2660
|
-
edit,
|
2661
|
-
list: listLayout
|
2662
|
-
};
|
2663
|
-
};
|
2664
|
-
const useDocLayout = () => {
|
2665
|
-
const { model } = useDoc();
|
2666
|
-
return useDocumentLayout(model);
|
2667
|
-
};
|
2668
|
-
const formatEditLayout = (data, {
|
2669
|
-
schemas,
|
2670
|
-
schema,
|
2671
|
-
components
|
2672
|
-
}) => {
|
2673
|
-
let currentPanelIndex = 0;
|
2674
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2675
|
-
data.contentType.layouts.edit,
|
2676
|
-
schema?.attributes,
|
2677
|
-
data.contentType.metadatas,
|
2678
|
-
{ configurations: data.components, schemas: components },
|
2679
|
-
schemas
|
2680
|
-
).reduce((panels, row) => {
|
2681
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2682
|
-
panels.push([row]);
|
2683
|
-
currentPanelIndex += 2;
|
2684
|
-
} else {
|
2685
|
-
if (!panels[currentPanelIndex]) {
|
2686
|
-
panels.push([]);
|
2687
|
-
}
|
2688
|
-
panels[currentPanelIndex].push(row);
|
2689
|
-
}
|
2690
|
-
return panels;
|
2691
|
-
}, []);
|
2692
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2693
|
-
(acc, [uid, configuration]) => {
|
2694
|
-
acc[uid] = {
|
2695
|
-
layout: convertEditLayoutToFieldLayouts(
|
2696
|
-
configuration.layouts.edit,
|
2697
|
-
components[uid].attributes,
|
2698
|
-
configuration.metadatas
|
2699
|
-
),
|
2700
|
-
settings: {
|
2701
|
-
...configuration.settings,
|
2702
|
-
icon: components[uid].info.icon,
|
2703
|
-
displayName: components[uid].info.displayName
|
2704
|
-
}
|
2705
|
-
};
|
2706
|
-
return acc;
|
2707
|
-
},
|
2708
|
-
{}
|
2709
|
-
);
|
2710
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2711
|
-
(acc, [attribute, metadata]) => {
|
2712
|
-
return {
|
2713
|
-
...acc,
|
2714
|
-
[attribute]: metadata.edit
|
2715
|
-
};
|
2716
|
-
},
|
2717
|
-
{}
|
2718
|
-
);
|
2719
|
-
return {
|
2720
|
-
layout: panelledEditAttributes,
|
2721
|
-
components: componentEditAttributes,
|
2722
|
-
metadatas: editMetadatas,
|
2723
|
-
settings: {
|
2724
|
-
...data.contentType.settings,
|
2725
|
-
displayName: schema?.info.displayName
|
2726
|
-
},
|
2727
|
-
options: {
|
2728
|
-
...schema?.options,
|
2729
|
-
...schema?.pluginOptions,
|
2730
|
-
...data.contentType.options
|
2731
|
-
}
|
2732
|
-
};
|
2733
|
-
};
|
2734
|
-
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
2735
|
-
return rows.map(
|
2736
|
-
(row) => row.map((field) => {
|
2737
|
-
const attribute = attributes[field.name];
|
2738
|
-
if (!attribute) {
|
2739
|
-
return null;
|
2740
|
-
}
|
2741
|
-
const { edit: metadata } = metadatas[field.name];
|
2742
|
-
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2743
|
-
return {
|
2744
|
-
attribute,
|
2745
|
-
disabled: !metadata.editable,
|
2746
|
-
hint: metadata.description,
|
2747
|
-
label: metadata.label ?? "",
|
2748
|
-
name: field.name,
|
2749
|
-
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
2750
|
-
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2751
|
-
schemas,
|
2752
|
-
components: components?.schemas ?? {}
|
2753
|
-
}),
|
2754
|
-
placeholder: metadata.placeholder ?? "",
|
2755
|
-
required: attribute.required ?? false,
|
2756
|
-
size: field.size,
|
2757
|
-
unique: "unique" in attribute ? attribute.unique : false,
|
2758
|
-
visible: metadata.visible ?? true,
|
2759
|
-
type: attribute.type
|
2760
|
-
};
|
2761
|
-
}).filter((field) => field !== null)
|
2762
|
-
);
|
2763
|
-
};
|
2764
|
-
const formatListLayout = (data, {
|
2765
|
-
schemas,
|
2766
|
-
schema,
|
2767
|
-
components
|
2768
|
-
}) => {
|
2769
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2770
|
-
(acc, [attribute, metadata]) => {
|
2771
|
-
return {
|
2772
|
-
...acc,
|
2773
|
-
[attribute]: metadata.list
|
2774
|
-
};
|
2775
|
-
},
|
2776
|
-
{}
|
2777
|
-
);
|
2778
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
2779
|
-
data.contentType.layouts.list,
|
2780
|
-
schema?.attributes,
|
2781
|
-
listMetadatas,
|
2782
|
-
{ configurations: data.components, schemas: components },
|
2783
|
-
schemas
|
2784
|
-
);
|
2785
|
-
return {
|
2786
|
-
layout: listAttributes,
|
2787
|
-
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
2788
|
-
metadatas: listMetadatas,
|
2789
|
-
options: {
|
2790
|
-
...schema?.options,
|
2791
|
-
...schema?.pluginOptions,
|
2792
|
-
...data.contentType.options
|
2793
|
-
}
|
2794
|
-
};
|
2795
|
-
};
|
2796
|
-
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
2797
|
-
return columns.map((name) => {
|
2798
|
-
const attribute = attributes[name];
|
2799
|
-
if (!attribute) {
|
2800
|
-
return null;
|
2801
|
-
}
|
2802
|
-
const metadata = metadatas[name];
|
2803
|
-
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
2804
|
-
return {
|
2805
|
-
attribute,
|
2806
|
-
label: metadata.label ?? "",
|
2807
|
-
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
2808
|
-
schemas,
|
2809
|
-
components: components?.schemas ?? {}
|
2810
|
-
}),
|
2811
|
-
name,
|
2812
|
-
searchable: metadata.searchable ?? true,
|
2813
|
-
sortable: metadata.sortable ?? true
|
2814
|
-
};
|
2815
|
-
}).filter((field) => field !== null);
|
2816
|
-
};
|
3072
|
+
);
|
3073
|
+
});
|
2817
3074
|
const ConfirmBulkActionDialog = ({
|
2818
3075
|
onToggleDialog,
|
2819
3076
|
isOpen = false,
|
@@ -2821,30 +3078,23 @@ const ConfirmBulkActionDialog = ({
|
|
2821
3078
|
endAction
|
2822
3079
|
}) => {
|
2823
3080
|
const { formatMessage } = reactIntl.useIntl();
|
2824
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
2825
|
-
designSystem.Dialog,
|
2826
|
-
|
2827
|
-
|
2828
|
-
|
2829
|
-
|
2830
|
-
|
2831
|
-
|
2832
|
-
|
2833
|
-
|
2834
|
-
|
2835
|
-
|
2836
|
-
|
2837
|
-
|
2838
|
-
|
2839
|
-
|
2840
|
-
|
2841
|
-
}) }),
|
2842
|
-
endAction
|
2843
|
-
}
|
2844
|
-
)
|
2845
|
-
]
|
2846
|
-
}
|
2847
|
-
);
|
3081
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
3082
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
|
3083
|
+
id: "app.components.ConfirmDialog.title",
|
3084
|
+
defaultMessage: "Confirmation"
|
3085
|
+
}) }),
|
3086
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3087
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3088
|
+
dialogBody
|
3089
|
+
] }) }),
|
3090
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
3091
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
|
3092
|
+
id: "app.components.Button.cancel",
|
3093
|
+
defaultMessage: "Cancel"
|
3094
|
+
}) }) }),
|
3095
|
+
endAction
|
3096
|
+
] })
|
3097
|
+
] }) });
|
2848
3098
|
};
|
2849
3099
|
const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
|
2850
3100
|
const ConfirmDialogPublishAll = ({
|
@@ -2859,6 +3109,7 @@ const ConfirmDialogPublishAll = ({
|
|
2859
3109
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
|
2860
3110
|
const { model, schema } = useDoc();
|
2861
3111
|
const [{ query }] = strapiAdmin.useQueryParams();
|
3112
|
+
const enableDraftRelationsCount = false;
|
2862
3113
|
const {
|
2863
3114
|
data: countDraftRelations = 0,
|
2864
3115
|
isLoading,
|
@@ -2870,7 +3121,7 @@ const ConfirmDialogPublishAll = ({
|
|
2870
3121
|
locale: query?.plugins?.i18n?.locale
|
2871
3122
|
},
|
2872
3123
|
{
|
2873
|
-
skip:
|
3124
|
+
skip: !enableDraftRelationsCount
|
2874
3125
|
}
|
2875
3126
|
);
|
2876
3127
|
React__namespace.useEffect(() => {
|
@@ -2949,16 +3200,30 @@ const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
|
2949
3200
|
)
|
2950
3201
|
);
|
2951
3202
|
} else {
|
2952
|
-
messages.push(
|
3203
|
+
messages.push(
|
3204
|
+
...formatErrorMessages(
|
3205
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3206
|
+
value,
|
3207
|
+
currentKey,
|
3208
|
+
formatMessage
|
3209
|
+
)
|
3210
|
+
);
|
2953
3211
|
}
|
3212
|
+
} else {
|
3213
|
+
messages.push(
|
3214
|
+
formatMessage(
|
3215
|
+
{
|
3216
|
+
id: `${value}.withField`,
|
3217
|
+
defaultMessage: value
|
3218
|
+
},
|
3219
|
+
{ field: currentKey }
|
3220
|
+
)
|
3221
|
+
);
|
2954
3222
|
}
|
2955
3223
|
});
|
2956
3224
|
return messages;
|
2957
3225
|
};
|
2958
|
-
const EntryValidationText = ({
|
2959
|
-
validationErrors,
|
2960
|
-
isPublished = false
|
2961
|
-
}) => {
|
3226
|
+
const EntryValidationText = ({ validationErrors, status }) => {
|
2962
3227
|
const { formatMessage } = reactIntl.useIntl();
|
2963
3228
|
if (validationErrors) {
|
2964
3229
|
const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
|
@@ -2969,7 +3234,7 @@ const EntryValidationText = ({
|
|
2969
3234
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
|
2970
3235
|
] });
|
2971
3236
|
}
|
2972
|
-
if (
|
3237
|
+
if (status === "published") {
|
2973
3238
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
2974
3239
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
|
2975
3240
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
|
@@ -2978,6 +3243,15 @@ const EntryValidationText = ({
|
|
2978
3243
|
}) })
|
2979
3244
|
] });
|
2980
3245
|
}
|
3246
|
+
if (status === "modified") {
|
3247
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3248
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.ArrowsCounterClockwise, { fill: "alternative600" }),
|
3249
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3250
|
+
id: "content-manager.bulk-publish.modified",
|
3251
|
+
defaultMessage: "Ready to publish changes"
|
3252
|
+
}) })
|
3253
|
+
] });
|
3254
|
+
}
|
2981
3255
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
2982
3256
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
|
2983
3257
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
@@ -3029,10 +3303,10 @@ const SelectedEntriesTableContent = ({
|
|
3029
3303
|
EntryValidationText,
|
3030
3304
|
{
|
3031
3305
|
validationErrors: validationErrors[row.documentId],
|
3032
|
-
|
3306
|
+
status: row.status
|
3033
3307
|
}
|
3034
3308
|
) }),
|
3035
|
-
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3309
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3036
3310
|
designSystem.IconButton,
|
3037
3311
|
{
|
3038
3312
|
tag: reactRouterDom.Link,
|
@@ -3041,23 +3315,16 @@ const SelectedEntriesTableContent = ({
|
|
3041
3315
|
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3042
3316
|
},
|
3043
3317
|
state: { from: pathname },
|
3044
|
-
label: formatMessage(
|
3045
|
-
|
3046
|
-
|
3047
|
-
|
3048
|
-
{
|
3049
|
-
id: "content-manager.components.ListViewHelperPluginTable.row-line",
|
3050
|
-
defaultMessage: "item line {number}"
|
3051
|
-
},
|
3052
|
-
{ number: index2 + 1 }
|
3053
|
-
)
|
3054
|
-
}
|
3055
|
-
),
|
3318
|
+
label: formatMessage({
|
3319
|
+
id: "content-manager.bulk-publish.edit",
|
3320
|
+
defaultMessage: "Edit"
|
3321
|
+
}),
|
3056
3322
|
target: "_blank",
|
3057
3323
|
marginLeft: "auto",
|
3058
|
-
|
3324
|
+
variant: "ghost",
|
3325
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, { width: "1.6rem", height: "1.6rem" })
|
3059
3326
|
}
|
3060
|
-
) })
|
3327
|
+
) }) })
|
3061
3328
|
] }, row.id)) })
|
3062
3329
|
] });
|
3063
3330
|
};
|
@@ -3094,7 +3361,13 @@ const SelectedEntriesModalContent = ({
|
|
3094
3361
|
);
|
3095
3362
|
const { rows, validationErrors } = React__namespace.useMemo(() => {
|
3096
3363
|
if (data.length > 0 && schema) {
|
3097
|
-
const validate = createYupSchema(
|
3364
|
+
const validate = createYupSchema(
|
3365
|
+
schema.attributes,
|
3366
|
+
components,
|
3367
|
+
// Since this is the "Publish" action, the validation
|
3368
|
+
// schema must enforce the rules for published entities
|
3369
|
+
{ status: "published" }
|
3370
|
+
);
|
3098
3371
|
const validationErrors2 = {};
|
3099
3372
|
const rows2 = data.map((entry) => {
|
3100
3373
|
try {
|
@@ -3170,7 +3443,7 @@ const SelectedEntriesModalContent = ({
|
|
3170
3443
|
);
|
3171
3444
|
};
|
3172
3445
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
3173
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.
|
3446
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
|
3174
3447
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
|
3175
3448
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3176
3449
|
SelectedEntriesTableContent,
|
@@ -3182,27 +3455,24 @@ const SelectedEntriesModalContent = ({
|
|
3182
3455
|
}
|
3183
3456
|
) })
|
3184
3457
|
] }),
|
3185
|
-
/* @__PURE__ */ jsxRuntime.
|
3186
|
-
designSystem.
|
3187
|
-
|
3188
|
-
|
3189
|
-
|
3190
|
-
|
3191
|
-
}) }),
|
3192
|
-
|
3193
|
-
|
3194
|
-
|
3195
|
-
|
3196
|
-
|
3197
|
-
|
3198
|
-
|
3199
|
-
|
3200
|
-
|
3201
|
-
|
3202
|
-
|
3203
|
-
] })
|
3204
|
-
}
|
3205
|
-
),
|
3458
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3459
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
|
3460
|
+
id: "app.components.Button.cancel",
|
3461
|
+
defaultMessage: "Cancel"
|
3462
|
+
}) }),
|
3463
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3464
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
|
3465
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3466
|
+
designSystem.Button,
|
3467
|
+
{
|
3468
|
+
onClick: toggleDialog,
|
3469
|
+
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
|
3470
|
+
loading: isSubmittingForm,
|
3471
|
+
children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
|
3472
|
+
}
|
3473
|
+
)
|
3474
|
+
] })
|
3475
|
+
] }),
|
3206
3476
|
/* @__PURE__ */ jsxRuntime.jsx(
|
3207
3477
|
ConfirmDialogPublishAll,
|
3208
3478
|
{
|
@@ -3222,8 +3492,7 @@ const PublishAction = ({ documents, model }) => {
|
|
3222
3492
|
const refetchList = () => {
|
3223
3493
|
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3224
3494
|
};
|
3225
|
-
if (!showPublishButton)
|
3226
|
-
return null;
|
3495
|
+
if (!showPublishButton) return null;
|
3227
3496
|
return {
|
3228
3497
|
actionType: "publish",
|
3229
3498
|
variant: "tertiary",
|
@@ -3267,143 +3536,10 @@ const BulkActionsRenderer = () => {
|
|
3267
3536
|
documents: selectedRows
|
3268
3537
|
},
|
3269
3538
|
descriptions: plugins["content-manager"].apis.getBulkActions(),
|
3270
|
-
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsxRuntime.jsx(
|
3539
|
+
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActionButton, { ...action }, action.id))
|
3271
3540
|
}
|
3272
3541
|
) });
|
3273
3542
|
};
|
3274
|
-
const BulkActionAction = (action) => {
|
3275
|
-
const [dialogId, setDialogId] = React__namespace.useState(null);
|
3276
|
-
const { toggleNotification } = strapiAdmin.useNotification();
|
3277
|
-
const handleClick = (action2) => (e) => {
|
3278
|
-
const { onClick, dialog, id } = action2;
|
3279
|
-
if (onClick) {
|
3280
|
-
onClick(e);
|
3281
|
-
}
|
3282
|
-
if (dialog) {
|
3283
|
-
switch (dialog.type) {
|
3284
|
-
case "notification":
|
3285
|
-
toggleNotification({
|
3286
|
-
title: dialog.title,
|
3287
|
-
message: dialog.content,
|
3288
|
-
type: dialog.status,
|
3289
|
-
timeout: dialog.timeout,
|
3290
|
-
onClose: dialog.onClose
|
3291
|
-
});
|
3292
|
-
break;
|
3293
|
-
case "dialog":
|
3294
|
-
case "modal": {
|
3295
|
-
e.preventDefault();
|
3296
|
-
setDialogId(id);
|
3297
|
-
}
|
3298
|
-
}
|
3299
|
-
}
|
3300
|
-
};
|
3301
|
-
const handleClose = () => {
|
3302
|
-
setDialogId(null);
|
3303
|
-
if (action.dialog?.type === "modal" && action.dialog?.onClose) {
|
3304
|
-
action.dialog.onClose();
|
3305
|
-
}
|
3306
|
-
};
|
3307
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
3308
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
3309
|
-
designSystem.Button,
|
3310
|
-
{
|
3311
|
-
disabled: action.disabled,
|
3312
|
-
startIcon: action.icon,
|
3313
|
-
variant: action.variant,
|
3314
|
-
onClick: handleClick(action),
|
3315
|
-
children: action.label
|
3316
|
-
}
|
3317
|
-
),
|
3318
|
-
action.dialog?.type === "dialog" ? /* @__PURE__ */ jsxRuntime.jsx(
|
3319
|
-
BulkActionConfirmDialog,
|
3320
|
-
{
|
3321
|
-
...action.dialog,
|
3322
|
-
variant: action.variant,
|
3323
|
-
isOpen: dialogId === action.id,
|
3324
|
-
onClose: handleClose
|
3325
|
-
}
|
3326
|
-
) : null,
|
3327
|
-
action.dialog?.type === "modal" ? /* @__PURE__ */ jsxRuntime.jsx(
|
3328
|
-
BulkActionModal,
|
3329
|
-
{
|
3330
|
-
...action.dialog,
|
3331
|
-
onModalClose: handleClose,
|
3332
|
-
isOpen: dialogId === action.id
|
3333
|
-
}
|
3334
|
-
) : null
|
3335
|
-
] });
|
3336
|
-
};
|
3337
|
-
const BulkActionConfirmDialog = ({
|
3338
|
-
onClose,
|
3339
|
-
onCancel,
|
3340
|
-
onConfirm,
|
3341
|
-
title,
|
3342
|
-
content,
|
3343
|
-
confirmButton,
|
3344
|
-
isOpen,
|
3345
|
-
variant = "secondary"
|
3346
|
-
}) => {
|
3347
|
-
const { formatMessage } = reactIntl.useIntl();
|
3348
|
-
const handleClose = async () => {
|
3349
|
-
if (onCancel) {
|
3350
|
-
await onCancel();
|
3351
|
-
}
|
3352
|
-
onClose();
|
3353
|
-
};
|
3354
|
-
const handleConfirm = async () => {
|
3355
|
-
if (onConfirm) {
|
3356
|
-
await onConfirm();
|
3357
|
-
}
|
3358
|
-
onClose();
|
3359
|
-
};
|
3360
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog, { isOpen, title, onClose: handleClose, children: [
|
3361
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.DialogBody, { icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, {}), children: content }),
|
3362
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
3363
|
-
designSystem.DialogFooter,
|
3364
|
-
{
|
3365
|
-
startAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", children: formatMessage({
|
3366
|
-
id: "app.components.Button.cancel",
|
3367
|
-
defaultMessage: "Cancel"
|
3368
|
-
}) }),
|
3369
|
-
endAction: /* @__PURE__ */ jsxRuntime.jsx(
|
3370
|
-
designSystem.Button,
|
3371
|
-
{
|
3372
|
-
onClick: handleConfirm,
|
3373
|
-
variant: variant === "danger-light" ? variant : "secondary",
|
3374
|
-
startIcon: variant === "danger-light" ? /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}) : /* @__PURE__ */ jsxRuntime.jsx(Icons.Check, {}),
|
3375
|
-
children: confirmButton ? confirmButton : formatMessage({
|
3376
|
-
id: "app.components.Button.confirm",
|
3377
|
-
defaultMessage: "Confirm"
|
3378
|
-
})
|
3379
|
-
}
|
3380
|
-
)
|
3381
|
-
}
|
3382
|
-
)
|
3383
|
-
] });
|
3384
|
-
};
|
3385
|
-
const BulkActionModal = ({
|
3386
|
-
isOpen,
|
3387
|
-
title,
|
3388
|
-
onClose,
|
3389
|
-
content: Content,
|
3390
|
-
onModalClose
|
3391
|
-
}) => {
|
3392
|
-
const id = React__namespace.useId();
|
3393
|
-
if (!isOpen) {
|
3394
|
-
return null;
|
3395
|
-
}
|
3396
|
-
const handleClose = () => {
|
3397
|
-
if (onClose) {
|
3398
|
-
onClose();
|
3399
|
-
}
|
3400
|
-
onModalClose();
|
3401
|
-
};
|
3402
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { borderRadius: "4px", overflow: "hidden", onClose: handleClose, labelledBy: id, children: [
|
3403
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral800", tag: "h2", id, children: title }) }),
|
3404
|
-
/* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose })
|
3405
|
-
] });
|
3406
|
-
};
|
3407
3543
|
const DeleteAction = ({ documents, model }) => {
|
3408
3544
|
const { formatMessage } = reactIntl.useIntl();
|
3409
3545
|
const { schema: contentType } = useDoc();
|
@@ -3424,8 +3560,7 @@ const DeleteAction = ({ documents, model }) => {
|
|
3424
3560
|
selectRow([]);
|
3425
3561
|
}
|
3426
3562
|
};
|
3427
|
-
if (!hasDeletePermission)
|
3428
|
-
return null;
|
3563
|
+
if (!hasDeletePermission) return null;
|
3429
3564
|
return {
|
3430
3565
|
variant: "danger-light",
|
3431
3566
|
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
@@ -3436,6 +3571,7 @@ const DeleteAction = ({ documents, model }) => {
|
|
3436
3571
|
defaultMessage: "Confirmation"
|
3437
3572
|
}),
|
3438
3573
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3574
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3439
3575
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3440
3576
|
id: "popUpWarning.bodyMessage.contentType.delete.all",
|
3441
3577
|
defaultMessage: "Are you sure you want to delete these entries?"
|
@@ -3472,9 +3608,8 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3472
3608
|
selectRow([]);
|
3473
3609
|
}
|
3474
3610
|
};
|
3475
|
-
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published");
|
3476
|
-
if (!showUnpublishButton)
|
3477
|
-
return null;
|
3611
|
+
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3612
|
+
if (!showUnpublishButton) return null;
|
3478
3613
|
return {
|
3479
3614
|
variant: "tertiary",
|
3480
3615
|
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
@@ -3485,6 +3620,7 @@ const UnpublishAction = ({ documents, model }) => {
|
|
3485
3620
|
defaultMessage: "Confirmation"
|
3486
3621
|
}),
|
3487
3622
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3623
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3488
3624
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3489
3625
|
id: "popUpWarning.bodyMessage.contentType.unpublish.all",
|
3490
3626
|
defaultMessage: "Are you sure you want to unpublish these entries?"
|
@@ -3578,7 +3714,7 @@ const TableActions = ({ document }) => {
|
|
3578
3714
|
strapiAdmin.DescriptionComponentRenderer,
|
3579
3715
|
{
|
3580
3716
|
props,
|
3581
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3717
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("table-row").filter((action) => action.name !== "PublishAction"),
|
3582
3718
|
children: (actions2) => {
|
3583
3719
|
const tableRowActions = actions2.filter((action) => {
|
3584
3720
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -3637,6 +3773,7 @@ const EditAction = ({ documentId }) => {
|
|
3637
3773
|
};
|
3638
3774
|
};
|
3639
3775
|
EditAction.type = "edit";
|
3776
|
+
EditAction.position = "table-row";
|
3640
3777
|
const StyledPencil = styledComponents.styled(Icons.Pencil)`
|
3641
3778
|
path {
|
3642
3779
|
fill: currentColor;
|
@@ -3689,7 +3826,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3689
3826
|
}),
|
3690
3827
|
content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
3691
3828
|
footer: ({ onClose }) => {
|
3692
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.
|
3829
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3693
3830
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
3694
3831
|
id: "cancel",
|
3695
3832
|
defaultMessage: "Cancel"
|
@@ -3713,6 +3850,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
3713
3850
|
};
|
3714
3851
|
};
|
3715
3852
|
CloneAction.type = "clone";
|
3853
|
+
CloneAction.position = "table-row";
|
3716
3854
|
const StyledDuplicate = styledComponents.styled(Icons.Duplicate)`
|
3717
3855
|
path {
|
3718
3856
|
fill: currentColor;
|
@@ -3730,8 +3868,7 @@ class ContentManagerPlugin {
|
|
3730
3868
|
documentActions = [
|
3731
3869
|
...DEFAULT_ACTIONS,
|
3732
3870
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
3733
|
-
...DEFAULT_HEADER_ACTIONS
|
3734
|
-
HistoryAction
|
3871
|
+
...DEFAULT_HEADER_ACTIONS
|
3735
3872
|
];
|
3736
3873
|
editViewSidePanels = [ActionsPanel];
|
3737
3874
|
headerActions = [];
|
@@ -3800,7 +3937,14 @@ class ContentManagerPlugin {
|
|
3800
3937
|
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
3801
3938
|
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
3802
3939
|
getBulkActions: () => this.bulkActions,
|
3803
|
-
getDocumentActions: () =>
|
3940
|
+
getDocumentActions: (position) => {
|
3941
|
+
if (position) {
|
3942
|
+
return this.documentActions.filter(
|
3943
|
+
(action) => action.position == void 0 || [action.position].flat().includes(position)
|
3944
|
+
);
|
3945
|
+
}
|
3946
|
+
return this.documentActions;
|
3947
|
+
},
|
3804
3948
|
getEditViewSidePanels: () => this.editViewSidePanels,
|
3805
3949
|
getHeaderActions: () => this.headerActions
|
3806
3950
|
}
|
@@ -3810,16 +3954,71 @@ class ContentManagerPlugin {
|
|
3810
3954
|
const getPrintableType = (value) => {
|
3811
3955
|
const nativeType = typeof value;
|
3812
3956
|
if (nativeType === "object") {
|
3813
|
-
if (value === null)
|
3814
|
-
|
3815
|
-
if (Array.isArray(value))
|
3816
|
-
return "array";
|
3957
|
+
if (value === null) return "null";
|
3958
|
+
if (Array.isArray(value)) return "array";
|
3817
3959
|
if (value instanceof Object && value.constructor.name !== "Object") {
|
3818
3960
|
return value.constructor.name;
|
3819
3961
|
}
|
3820
3962
|
}
|
3821
3963
|
return nativeType;
|
3822
3964
|
};
|
3965
|
+
const HistoryAction = ({ model, document }) => {
|
3966
|
+
const { formatMessage } = reactIntl.useIntl();
|
3967
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3968
|
+
const navigate = reactRouterDom.useNavigate();
|
3969
|
+
const { trackUsage } = strapiAdmin.useTracking();
|
3970
|
+
const { pathname } = reactRouterDom.useLocation();
|
3971
|
+
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
3972
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3973
|
+
return null;
|
3974
|
+
}
|
3975
|
+
const handleOnClick = () => {
|
3976
|
+
const destination = { pathname: "history", search: pluginsQueryParams };
|
3977
|
+
trackUsage("willNavigate", {
|
3978
|
+
from: pathname,
|
3979
|
+
to: `${pathname}/${destination.pathname}`
|
3980
|
+
});
|
3981
|
+
navigate(destination);
|
3982
|
+
};
|
3983
|
+
return {
|
3984
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
3985
|
+
label: formatMessage({
|
3986
|
+
id: "content-manager.history.document-action",
|
3987
|
+
defaultMessage: "Content History"
|
3988
|
+
}),
|
3989
|
+
onClick: handleOnClick,
|
3990
|
+
disabled: (
|
3991
|
+
/**
|
3992
|
+
* The user is creating a new document.
|
3993
|
+
* It hasn't been saved yet, so there's no history to go to
|
3994
|
+
*/
|
3995
|
+
!document || /**
|
3996
|
+
* The document has been created but the current dimension has never been saved.
|
3997
|
+
* For example, the user is creating a new locale in an existing document,
|
3998
|
+
* so there's no history for the document in that locale
|
3999
|
+
*/
|
4000
|
+
!document.id || /**
|
4001
|
+
* History is only available for content types created by the user.
|
4002
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
4003
|
+
* which start with `admin::` or `plugin::`
|
4004
|
+
*/
|
4005
|
+
!model.startsWith("api::")
|
4006
|
+
),
|
4007
|
+
position: "header"
|
4008
|
+
};
|
4009
|
+
};
|
4010
|
+
HistoryAction.type = "history";
|
4011
|
+
HistoryAction.position = "header";
|
4012
|
+
const historyAdmin = {
|
4013
|
+
bootstrap(app) {
|
4014
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
4015
|
+
addDocumentAction((actions2) => {
|
4016
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
4017
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
4018
|
+
return actions2;
|
4019
|
+
});
|
4020
|
+
}
|
4021
|
+
};
|
3823
4022
|
const initialState = {
|
3824
4023
|
collectionTypeLinks: [],
|
3825
4024
|
components: [],
|
@@ -3856,6 +4055,92 @@ const { setInitialData } = actions;
|
|
3856
4055
|
const reducer = toolkit.combineReducers({
|
3857
4056
|
app: reducer$1
|
3858
4057
|
});
|
4058
|
+
const previewApi = contentManagerApi.injectEndpoints({
|
4059
|
+
endpoints: (builder) => ({
|
4060
|
+
getPreviewUrl: builder.query({
|
4061
|
+
query({ query, params }) {
|
4062
|
+
return {
|
4063
|
+
url: `/content-manager/preview/url/${params.contentType}`,
|
4064
|
+
method: "GET",
|
4065
|
+
config: {
|
4066
|
+
params: query
|
4067
|
+
}
|
4068
|
+
};
|
4069
|
+
}
|
4070
|
+
})
|
4071
|
+
})
|
4072
|
+
});
|
4073
|
+
const { useGetPreviewUrlQuery } = previewApi;
|
4074
|
+
const ConditionalTooltip = ({ isShown, label, children }) => {
|
4075
|
+
if (isShown) {
|
4076
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { label, children });
|
4077
|
+
}
|
4078
|
+
return children;
|
4079
|
+
};
|
4080
|
+
const PreviewSidePanel = ({ model, documentId, document }) => {
|
4081
|
+
const { formatMessage } = reactIntl.useIntl();
|
4082
|
+
const { trackUsage } = strapiAdmin.useTracking();
|
4083
|
+
const { pathname } = reactRouterDom.useLocation();
|
4084
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
4085
|
+
const isModified = strapiAdmin.useForm("PreviewSidePanel", (state) => state.modified);
|
4086
|
+
const { data, error } = useGetPreviewUrlQuery({
|
4087
|
+
params: {
|
4088
|
+
contentType: model
|
4089
|
+
},
|
4090
|
+
query: {
|
4091
|
+
documentId,
|
4092
|
+
locale: document?.locale,
|
4093
|
+
status: document?.status
|
4094
|
+
}
|
4095
|
+
});
|
4096
|
+
if (!data?.data?.url || error) {
|
4097
|
+
return null;
|
4098
|
+
}
|
4099
|
+
const trackNavigation = () => {
|
4100
|
+
const destinationPathname = pathname.replace(/\/$/, "") + "/preview";
|
4101
|
+
trackUsage("willNavigate", { from: pathname, to: destinationPathname });
|
4102
|
+
};
|
4103
|
+
return {
|
4104
|
+
title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
|
4105
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(
|
4106
|
+
ConditionalTooltip,
|
4107
|
+
{
|
4108
|
+
label: formatMessage({
|
4109
|
+
id: "content-manager.preview.panel.button-disabled-tooltip",
|
4110
|
+
defaultMessage: "Please save to open the preview"
|
4111
|
+
}),
|
4112
|
+
isShown: isModified,
|
4113
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { cursor: "not-allowed", width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(
|
4114
|
+
designSystem.Button,
|
4115
|
+
{
|
4116
|
+
variant: "tertiary",
|
4117
|
+
tag: reactRouterDom.Link,
|
4118
|
+
to: { pathname: "preview", search: qs.stringify(query, { encode: false }) },
|
4119
|
+
onClick: trackNavigation,
|
4120
|
+
width: "100%",
|
4121
|
+
disabled: isModified,
|
4122
|
+
pointerEvents: isModified ? "none" : void 0,
|
4123
|
+
tabIndex: isModified ? -1 : void 0,
|
4124
|
+
children: formatMessage({
|
4125
|
+
id: "content-manager.preview.panel.button",
|
4126
|
+
defaultMessage: "Open preview"
|
4127
|
+
})
|
4128
|
+
}
|
4129
|
+
) })
|
4130
|
+
}
|
4131
|
+
)
|
4132
|
+
};
|
4133
|
+
};
|
4134
|
+
const FEATURE_ID = "preview";
|
4135
|
+
const previewAdmin = {
|
4136
|
+
bootstrap(app) {
|
4137
|
+
if (!window.strapi.future.isEnabled(FEATURE_ID)) {
|
4138
|
+
return;
|
4139
|
+
}
|
4140
|
+
const contentManagerPluginApis = app.getPlugin("content-manager").apis;
|
4141
|
+
contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
|
4142
|
+
}
|
4143
|
+
};
|
3859
4144
|
const index = {
|
3860
4145
|
register(app) {
|
3861
4146
|
const cm = new ContentManagerPlugin();
|
@@ -3870,15 +4155,32 @@ const index = {
|
|
3870
4155
|
defaultMessage: "Content Manager"
|
3871
4156
|
},
|
3872
4157
|
permissions: [],
|
3873
|
-
Component: () => Promise.resolve().then(() => require("./layout-b91XRlD2.js")).then((mod) => ({ default: mod.Layout })),
|
3874
4158
|
position: 1
|
3875
4159
|
});
|
4160
|
+
app.router.addRoute({
|
4161
|
+
path: "content-manager/*",
|
4162
|
+
lazy: async () => {
|
4163
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-szfTCeYm.js"));
|
4164
|
+
return {
|
4165
|
+
Component: Layout
|
4166
|
+
};
|
4167
|
+
},
|
4168
|
+
children: routes
|
4169
|
+
});
|
3876
4170
|
app.registerPlugin(cm.config);
|
3877
4171
|
},
|
4172
|
+
bootstrap(app) {
|
4173
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
4174
|
+
historyAdmin.bootstrap(app);
|
4175
|
+
}
|
4176
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
4177
|
+
previewAdmin.bootstrap(app);
|
4178
|
+
}
|
4179
|
+
},
|
3878
4180
|
async registerTrads({ locales }) {
|
3879
4181
|
const importedTrads = await Promise.all(
|
3880
4182
|
locales.map((locale) => {
|
3881
|
-
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-
|
4183
|
+
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-BK8Xyl5I.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 }) => {
|
3882
4184
|
return {
|
3883
4185
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3884
4186
|
locale
|
@@ -3896,6 +4198,7 @@ const index = {
|
|
3896
4198
|
};
|
3897
4199
|
exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
|
3898
4200
|
exports.BulkActionsRenderer = BulkActionsRenderer;
|
4201
|
+
exports.CLONE_PATH = CLONE_PATH;
|
3899
4202
|
exports.COLLECTION_TYPES = COLLECTION_TYPES;
|
3900
4203
|
exports.CREATOR_FIELDS = CREATOR_FIELDS;
|
3901
4204
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
@@ -3922,8 +4225,8 @@ exports.getDisplayName = getDisplayName;
|
|
3922
4225
|
exports.getMainField = getMainField;
|
3923
4226
|
exports.getTranslation = getTranslation;
|
3924
4227
|
exports.index = index;
|
3925
|
-
exports.routes = routes;
|
3926
4228
|
exports.setInitialData = setInitialData;
|
4229
|
+
exports.useContentManagerContext = useContentManagerContext;
|
3927
4230
|
exports.useContentTypeSchema = useContentTypeSchema;
|
3928
4231
|
exports.useDoc = useDoc;
|
3929
4232
|
exports.useDocLayout = useDocLayout;
|
@@ -3935,5 +4238,6 @@ exports.useGetAllContentTypeSettingsQuery = useGetAllContentTypeSettingsQuery;
|
|
3935
4238
|
exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
3936
4239
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3937
4240
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
4241
|
+
exports.useGetPreviewUrlQuery = useGetPreviewUrlQuery;
|
3938
4242
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3939
|
-
//# sourceMappingURL=index-
|
4243
|
+
//# sourceMappingURL=index-CptTdHNy.js.map
|