@strapi/content-manager 0.0.0-experimental.a65a85fdea97faae8679d3ffc5f9d79af61abd26 → 0.0.0-experimental.a687a6977f91492ccfc6771bf398a5236ece3c94
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-DSVYodBX.js → CardDragPreview-C0QyJgRA.js} +10 -14
- package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -0
- package/dist/_chunks/{CardDragPreview-ikSG4M46.mjs → CardDragPreview-DOxamsuj.mjs} +7 -9
- package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -0
- package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js → ComponentConfigurationPage-BebDdCkl.js} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js.map → ComponentConfigurationPage-BebDdCkl.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage--2aLCv-G.mjs → ComponentConfigurationPage-XdGcgtZh.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage--2aLCv-G.mjs.map → ComponentConfigurationPage-XdGcgtZh.mjs.map} +1 -1
- package/dist/_chunks/{ComponentIcon-BBQsYCVn.js → ComponentIcon-BXdiCGQp.js} +8 -2
- package/dist/_chunks/ComponentIcon-BXdiCGQp.js.map +1 -0
- package/dist/_chunks/{ComponentIcon-BOFnK76n.mjs → ComponentIcon-u4bIXTFY.mjs} +9 -3
- package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -0
- package/dist/_chunks/{EditConfigurationPage-CUcGHHvQ.mjs → EditConfigurationPage-DaNf9MoK.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-CUcGHHvQ.mjs.map → EditConfigurationPage-DaNf9MoK.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-BfFzJ4Br.js → EditConfigurationPage-sdGi-bna.js} +4 -4
- package/dist/_chunks/{EditConfigurationPage-BfFzJ4Br.js.map → EditConfigurationPage-sdGi-bna.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-CzOT5Kpj.js → EditViewPage-BRA-JSnw.js} +101 -52
- package/dist/_chunks/EditViewPage-BRA-JSnw.js.map +1 -0
- package/dist/_chunks/EditViewPage-DtbTsNeX.mjs +254 -0
- package/dist/_chunks/EditViewPage-DtbTsNeX.mjs.map +1 -0
- package/dist/_chunks/{Field-Dlh0uGnL.mjs → Field-CDmB9zqh.mjs} +1075 -812
- package/dist/_chunks/Field-CDmB9zqh.mjs.map +1 -0
- package/dist/_chunks/{Field-Caef4JjM.js → Field-DoVRA4co.js} +1120 -858
- package/dist/_chunks/Field-DoVRA4co.js.map +1 -0
- package/dist/_chunks/{Form-BzuAjtRq.js → Form-BEh514bg.js} +69 -49
- package/dist/_chunks/Form-BEh514bg.js.map +1 -0
- package/dist/_chunks/{Form-EnaQL_6L.mjs → Form-Cle2X-4n.mjs} +70 -49
- package/dist/_chunks/Form-Cle2X-4n.mjs.map +1 -0
- package/dist/_chunks/{History-C17LiyRg.js → History-BsPXl1XH.js} +182 -146
- package/dist/_chunks/History-BsPXl1XH.js.map +1 -0
- package/dist/_chunks/{History-D6sbCJvo.mjs → History-ktAPcvHJ.mjs} +182 -145
- package/dist/_chunks/History-ktAPcvHJ.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Ce4qs7qE.mjs → ListConfigurationPage-BNAS_v2s.mjs} +71 -60
- package/dist/_chunks/ListConfigurationPage-BNAS_v2s.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Dks5SX6f.js → ListConfigurationPage-CN1-7Pgi.js} +73 -63
- package/dist/_chunks/ListConfigurationPage-CN1-7Pgi.js.map +1 -0
- package/dist/_chunks/{ListViewPage-Be7S5aKL.mjs → ListViewPage-B15c_0Vt.mjs} +143 -139
- package/dist/_chunks/ListViewPage-B15c_0Vt.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-BwrZrPsh.js → ListViewPage-BUKFOJuS.js} +146 -142
- package/dist/_chunks/ListViewPage-BUKFOJuS.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-CIPmYQMm.mjs → NoContentTypePage-CAgdmhlo.mjs} +7 -7
- package/dist/_chunks/NoContentTypePage-CAgdmhlo.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-Cu5r1-JT.js → NoContentTypePage-Cs7Kk9EW.js} +5 -5
- package/dist/_chunks/NoContentTypePage-Cs7Kk9EW.js.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-C-j6TEUF.js → NoPermissionsPage-DRPnEq9t.js} +4 -5
- package/dist/_chunks/NoPermissionsPage-DRPnEq9t.js.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-DhJ7LYrr.mjs → NoPermissionsPage-JxX4Y4RJ.mjs} +5 -6
- package/dist/_chunks/NoPermissionsPage-JxX4Y4RJ.mjs.map +1 -0
- package/dist/_chunks/Preview-BKuVG1dV.js +286 -0
- package/dist/_chunks/Preview-BKuVG1dV.js.map +1 -0
- package/dist/_chunks/Preview-CQlTtbLc.mjs +267 -0
- package/dist/_chunks/Preview-CQlTtbLc.mjs.map +1 -0
- package/dist/_chunks/{Relations-CY7AtkDA.mjs → Relations-DMQ93R3L.mjs} +135 -89
- package/dist/_chunks/Relations-DMQ93R3L.mjs.map +1 -0
- package/dist/_chunks/{Relations-Czs-uZ-s.js → Relations-DTEGSaM_.js} +138 -93
- package/dist/_chunks/Relations-DTEGSaM_.js.map +1 -0
- package/dist/_chunks/{en-MBPul9Su.mjs → en-CfIXaZf9.mjs} +36 -17
- package/dist/_chunks/{en-MBPul9Su.mjs.map → en-CfIXaZf9.mjs.map} +1 -1
- package/dist/_chunks/{en-C-V1_90f.js → en-DTWPCdTS.js} +36 -17
- package/dist/_chunks/{en-C-V1_90f.js.map → en-DTWPCdTS.js.map} +1 -1
- package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
- package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
- package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
- package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
- package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
- package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
- package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
- package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
- package/dist/_chunks/{index-DNVx8ssZ.mjs → index-BdUq-Dtg.mjs} +1839 -831
- package/dist/_chunks/index-BdUq-Dtg.mjs.map +1 -0
- package/dist/_chunks/{index-X_2tafck.js → index-DjV7tyGu.js} +1826 -818
- package/dist/_chunks/index-DjV7tyGu.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-Dnh0PNp9.mjs → layout-BJ8CpEJu.mjs} +47 -29
- package/dist/_chunks/layout-BJ8CpEJu.mjs.map +1 -0
- package/dist/_chunks/{layout-dBc7wN7L.js → layout-Cx9LHtH5.js} +47 -31
- package/dist/_chunks/layout-Cx9LHtH5.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-4pHtBrHJ.js → relations-5bc76OJz.js} +6 -7
- package/dist/_chunks/relations-5bc76OJz.js.map +1 -0
- package/dist/_chunks/{relations-Dx7tMKJN.mjs → relations-BeezTo41.mjs} +6 -7
- package/dist/_chunks/relations-BeezTo41.mjs.map +1 -0
- package/dist/_chunks/useDebounce-CtcjDB3L.js +28 -0
- 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-DdHgKsqq.mjs.map +1 -1
- package/dist/_chunks/useDragAndDrop-J0TUUbR6.js.map +1 -1
- package/dist/admin/index.js +3 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +9 -7
- package/dist/admin/src/components/ComponentIcon.d.ts +6 -3
- package/dist/admin/src/content-manager.d.ts +3 -3
- package/dist/admin/src/exports.d.ts +2 -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 +37 -9
- package/dist/admin/src/hooks/useDocumentActions.d.ts +24 -3
- package/dist/admin/src/hooks/useDocumentLayout.d.ts +2 -2
- package/dist/admin/src/hooks/useDragAndDrop.d.ts +4 -4
- package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +1 -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 +11 -4
- package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +3 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Component/Input.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.d.ts +3 -5
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +30 -18
- package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +3 -49
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.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 +16 -53
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -10
- 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/pages/ListView/components/BulkActions/PublishAction.d.ts +9 -26
- 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 +2 -3
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +5 -5
- package/dist/admin/src/services/documents.d.ts +31 -20
- package/dist/admin/src/services/init.d.ts +2 -2
- package/dist/admin/src/services/relations.d.ts +3 -3
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/api.d.ts +4 -18
- package/dist/admin/src/utils/validation.d.ts +5 -7
- package/dist/server/index.js +1008 -594
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +1014 -600
- 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/single-types.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 +22 -0
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/dimensions.d.ts +11 -0
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/index.d.ts +1 -1
- package/dist/server/src/history/services/history.d.ts +2 -4
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/index.d.ts +6 -2
- package/dist/server/src/history/services/index.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts +9 -0
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -0
- package/dist/server/src/history/services/utils.d.ts +41 -9
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/history/utils.d.ts +6 -2
- package/dist/server/src/history/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +21 -42
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/preview/constants.d.ts +2 -0
- package/dist/server/src/preview/constants.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/index.d.ts +2 -0
- package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/preview.d.ts +13 -0
- package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
- package/dist/server/src/preview/index.d.ts +4 -0
- package/dist/server/src/preview/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/index.d.ts +8 -0
- package/dist/server/src/preview/routes/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/preview.d.ts +4 -0
- package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
- package/dist/server/src/preview/services/index.d.ts +15 -0
- package/dist/server/src/preview/services/index.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview-config.d.ts +30 -0
- package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview.d.ts +12 -0
- package/dist/server/src/preview/services/preview.d.ts.map +1 -0
- package/dist/server/src/preview/utils.d.ts +18 -0
- package/dist/server/src/preview/utils.d.ts.map +1 -0
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts +13 -12
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +14 -35
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +21 -42
- 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 +8 -1
- 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 +17 -7
- 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/contracts/relations.d.ts +2 -2
- package/dist/shared/contracts/relations.d.ts.map +1 -1
- 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 +19 -20
- package/dist/_chunks/CardDragPreview-DSVYodBX.js.map +0 -1
- package/dist/_chunks/CardDragPreview-ikSG4M46.mjs.map +0 -1
- package/dist/_chunks/ComponentIcon-BBQsYCVn.js.map +0 -1
- package/dist/_chunks/ComponentIcon-BOFnK76n.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-Bm8lgcm6.mjs +0 -203
- package/dist/_chunks/EditViewPage-Bm8lgcm6.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-CzOT5Kpj.js.map +0 -1
- package/dist/_chunks/Field-Caef4JjM.js.map +0 -1
- package/dist/_chunks/Field-Dlh0uGnL.mjs.map +0 -1
- package/dist/_chunks/Form-BzuAjtRq.js.map +0 -1
- package/dist/_chunks/Form-EnaQL_6L.mjs.map +0 -1
- package/dist/_chunks/History-C17LiyRg.js.map +0 -1
- package/dist/_chunks/History-D6sbCJvo.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Ce4qs7qE.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Dks5SX6f.js.map +0 -1
- package/dist/_chunks/ListViewPage-Be7S5aKL.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-BwrZrPsh.js.map +0 -1
- package/dist/_chunks/NoContentTypePage-CIPmYQMm.mjs.map +0 -1
- package/dist/_chunks/NoContentTypePage-Cu5r1-JT.js.map +0 -1
- package/dist/_chunks/NoPermissionsPage-C-j6TEUF.js.map +0 -1
- package/dist/_chunks/NoPermissionsPage-DhJ7LYrr.mjs.map +0 -1
- package/dist/_chunks/Relations-CY7AtkDA.mjs.map +0 -1
- package/dist/_chunks/Relations-Czs-uZ-s.js.map +0 -1
- package/dist/_chunks/index-DNVx8ssZ.mjs.map +0 -1
- package/dist/_chunks/index-X_2tafck.js.map +0 -1
- package/dist/_chunks/layout-Dnh0PNp9.mjs.map +0 -1
- package/dist/_chunks/layout-dBc7wN7L.js.map +0 -1
- package/dist/_chunks/relations-4pHtBrHJ.js.map +0 -1
- package/dist/_chunks/relations-Dx7tMKJN.mjs.map +0 -1
- package/dist/_chunks/urls-CbOsUOoW.mjs +0 -7
- package/dist/_chunks/urls-CbOsUOoW.mjs.map +0 -1
- package/dist/_chunks/urls-DzZya_gm.js +0 -6
- package/dist/_chunks/urls-DzZya_gm.js.map +0 -1
- package/dist/server/src/controllers/utils/dimensions.d.ts +0 -5
- package/dist/server/src/controllers/utils/dimensions.d.ts.map +0 -1
- package/strapi-server.js +0 -3
@@ -2,15 +2,14 @@
|
|
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");
|
10
|
-
const
|
7
|
+
const mapValues = require("lodash/fp/mapValues");
|
8
|
+
const reactIntl = require("react-intl");
|
9
|
+
const reactRouterDom = require("react-router-dom");
|
10
|
+
const styledComponents = require("styled-components");
|
11
11
|
const yup = require("yup");
|
12
|
-
const
|
13
|
-
const axios = require("axios");
|
12
|
+
const qs = require("qs");
|
14
13
|
const pipe = require("lodash/fp/pipe");
|
15
14
|
const dateFns = require("date-fns");
|
16
15
|
const toolkit = require("@reduxjs/toolkit");
|
@@ -34,7 +33,7 @@ function _interopNamespace(e) {
|
|
34
33
|
return Object.freeze(n);
|
35
34
|
}
|
36
35
|
const React__namespace = /* @__PURE__ */ _interopNamespace(React);
|
37
|
-
const
|
36
|
+
const mapValues__default = /* @__PURE__ */ _interopDefault(mapValues);
|
38
37
|
const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
|
39
38
|
const pipe__default = /* @__PURE__ */ _interopDefault(pipe);
|
40
39
|
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
@@ -73,42 +72,6 @@ const useInjectionZone = (area) => {
|
|
73
72
|
const [page, position] = area.split(".");
|
74
73
|
return contentManagerPlugin.getInjectedComponents(page, position);
|
75
74
|
};
|
76
|
-
const HistoryAction = ({ model, document }) => {
|
77
|
-
const { formatMessage } = reactIntl.useIntl();
|
78
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
79
|
-
const navigate = reactRouterDom.useNavigate();
|
80
|
-
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
81
|
-
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
82
|
-
return null;
|
83
|
-
}
|
84
|
-
return {
|
85
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
86
|
-
label: formatMessage({
|
87
|
-
id: "content-manager.history.document-action",
|
88
|
-
defaultMessage: "Content History"
|
89
|
-
}),
|
90
|
-
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
91
|
-
disabled: (
|
92
|
-
/**
|
93
|
-
* The user is creating a new document.
|
94
|
-
* It hasn't been saved yet, so there's no history to go to
|
95
|
-
*/
|
96
|
-
!document || /**
|
97
|
-
* The document has been created but the current dimension has never been saved.
|
98
|
-
* For example, the user is creating a new locale in an existing document,
|
99
|
-
* so there's no history for the document in that locale
|
100
|
-
*/
|
101
|
-
!document.id || /**
|
102
|
-
* History is only available for content types created by the user.
|
103
|
-
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
104
|
-
* which start with `admin::` or `plugin::`
|
105
|
-
*/
|
106
|
-
!model.startsWith("api::")
|
107
|
-
),
|
108
|
-
position: "header"
|
109
|
-
};
|
110
|
-
};
|
111
|
-
HistoryAction.type = "history";
|
112
75
|
const ID = "id";
|
113
76
|
const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
|
114
77
|
const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
|
@@ -160,6 +123,7 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
160
123
|
if (!slug) {
|
161
124
|
throw new Error("Cannot find the slug param in the URL");
|
162
125
|
}
|
126
|
+
const [{ rawQuery }] = strapiAdmin.useQueryParams();
|
163
127
|
const userPermissions = strapiAdmin.useAuth("DocumentRBAC", (state) => state.permissions);
|
164
128
|
const contentTypePermissions = React__namespace.useMemo(() => {
|
165
129
|
const contentTypePermissions2 = userPermissions.filter(
|
@@ -170,7 +134,14 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
170
134
|
return { ...acc, [action]: [permission] };
|
171
135
|
}, {});
|
172
136
|
}, [slug, userPermissions]);
|
173
|
-
const { isLoading, allowedActions } = strapiAdmin.useRBAC(
|
137
|
+
const { isLoading, allowedActions } = strapiAdmin.useRBAC(
|
138
|
+
contentTypePermissions,
|
139
|
+
permissions ?? void 0,
|
140
|
+
// TODO: useRBAC context should be typed and built differently
|
141
|
+
// We are passing raw query as context to the hook so that it can
|
142
|
+
// rely on the locale provided from DocumentRBAC for its permission calculations.
|
143
|
+
rawQuery
|
144
|
+
);
|
174
145
|
const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
|
175
146
|
const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
|
176
147
|
const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
|
@@ -179,9 +150,8 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
179
150
|
const name = removeNumericalStrings(fieldName.split("."));
|
180
151
|
const componentFieldNames = fieldsUserCanAction.filter((field) => field.split(".").length > 1);
|
181
152
|
if (fieldType === "component") {
|
182
|
-
|
183
|
-
|
184
|
-
return field.includes(fieldName);
|
153
|
+
return componentFieldNames.some((field) => {
|
154
|
+
return field.includes(name.join("."));
|
185
155
|
});
|
186
156
|
}
|
187
157
|
if (name.length > 1) {
|
@@ -211,89 +181,20 @@ const extractAndDedupeFields = (permissions = []) => permissions.flatMap((permis
|
|
211
181
|
(field, index2, arr) => arr.indexOf(field) === index2 && typeof field === "string"
|
212
182
|
);
|
213
183
|
const removeNumericalStrings = (arr) => arr.filter((item) => isNaN(Number(item)));
|
214
|
-
const
|
215
|
-
|
216
|
-
return query;
|
217
|
-
const { plugins: _, ...validQueryParams } = {
|
218
|
-
...query,
|
219
|
-
...Object.values(query?.plugins ?? {}).reduce(
|
220
|
-
(acc, current) => Object.assign(acc, current),
|
221
|
-
{}
|
222
|
-
)
|
223
|
-
};
|
224
|
-
if ("_q" in validQueryParams) {
|
225
|
-
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
226
|
-
}
|
227
|
-
return validQueryParams;
|
228
|
-
};
|
229
|
-
const axiosBaseQuery = () => async (query, { signal }) => {
|
230
|
-
try {
|
231
|
-
const { get, post, del, put } = strapiAdmin.getFetchClient();
|
232
|
-
if (typeof query === "string") {
|
233
|
-
const result = await get(query, { signal });
|
234
|
-
return { data: result.data };
|
235
|
-
} else {
|
236
|
-
const { url, method = "GET", data, config } = query;
|
237
|
-
if (method === "POST") {
|
238
|
-
const result2 = await post(url, data, { ...config, signal });
|
239
|
-
return { data: result2.data };
|
240
|
-
}
|
241
|
-
if (method === "DELETE") {
|
242
|
-
const result2 = await del(url, { ...config, signal });
|
243
|
-
return { data: result2.data };
|
244
|
-
}
|
245
|
-
if (method === "PUT") {
|
246
|
-
const result2 = await put(url, data, { ...config, signal });
|
247
|
-
return { data: result2.data };
|
248
|
-
}
|
249
|
-
const result = await get(url, { ...config, signal });
|
250
|
-
return { data: result.data };
|
251
|
-
}
|
252
|
-
} catch (err) {
|
253
|
-
if (axios.isAxiosError(err)) {
|
254
|
-
if (typeof err.response?.data === "object" && err.response?.data !== null && "error" in err.response?.data) {
|
255
|
-
return { data: void 0, error: err.response?.data.error };
|
256
|
-
} else {
|
257
|
-
return {
|
258
|
-
data: void 0,
|
259
|
-
error: {
|
260
|
-
name: "UnknownError",
|
261
|
-
message: "There was an unknown error response from the API",
|
262
|
-
details: err.response?.data,
|
263
|
-
status: err.response?.status
|
264
|
-
}
|
265
|
-
};
|
266
|
-
}
|
267
|
-
}
|
268
|
-
const error = err;
|
269
|
-
return {
|
270
|
-
data: void 0,
|
271
|
-
error: {
|
272
|
-
name: error.name,
|
273
|
-
message: error.message,
|
274
|
-
stack: error.stack
|
275
|
-
}
|
276
|
-
};
|
277
|
-
}
|
278
|
-
};
|
279
|
-
const isBaseQueryError = (error) => {
|
280
|
-
return error.name !== void 0;
|
281
|
-
};
|
282
|
-
const contentManagerApi = react.createApi({
|
283
|
-
reducerPath: "contentManagerApi",
|
284
|
-
baseQuery: axiosBaseQuery(),
|
285
|
-
tagTypes: [
|
184
|
+
const contentManagerApi = strapiAdmin.adminApi.enhanceEndpoints({
|
185
|
+
addTagTypes: [
|
286
186
|
"ComponentConfiguration",
|
287
187
|
"ContentTypesConfiguration",
|
288
188
|
"ContentTypeSettings",
|
289
189
|
"Document",
|
290
190
|
"InitialData",
|
291
191
|
"HistoryVersion",
|
292
|
-
"Relations"
|
293
|
-
|
294
|
-
|
192
|
+
"Relations",
|
193
|
+
"UidAvailability"
|
194
|
+
]
|
295
195
|
});
|
296
196
|
const documentApi = contentManagerApi.injectEndpoints({
|
197
|
+
overrideExisting: true,
|
297
198
|
endpoints: (builder) => ({
|
298
199
|
autoCloneDocument: builder.mutation({
|
299
200
|
query: ({ model, sourceId, query }) => ({
|
@@ -303,7 +204,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
303
204
|
params: query
|
304
205
|
}
|
305
206
|
}),
|
306
|
-
invalidatesTags: (_result,
|
207
|
+
invalidatesTags: (_result, error, { model }) => {
|
208
|
+
if (error) {
|
209
|
+
return [];
|
210
|
+
}
|
211
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
212
|
+
}
|
307
213
|
}),
|
308
214
|
cloneDocument: builder.mutation({
|
309
215
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -314,7 +220,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
314
220
|
params
|
315
221
|
}
|
316
222
|
}),
|
317
|
-
invalidatesTags: (_result, _error, { model }) => [
|
223
|
+
invalidatesTags: (_result, _error, { model }) => [
|
224
|
+
{ type: "Document", id: `${model}_LIST` },
|
225
|
+
{ type: "UidAvailability", id: model }
|
226
|
+
]
|
318
227
|
}),
|
319
228
|
/**
|
320
229
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -331,7 +240,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
331
240
|
}),
|
332
241
|
invalidatesTags: (result, _error, { model }) => [
|
333
242
|
{ type: "Document", id: `${model}_LIST` },
|
334
|
-
"Relations"
|
243
|
+
"Relations",
|
244
|
+
{ type: "UidAvailability", id: model }
|
335
245
|
]
|
336
246
|
}),
|
337
247
|
deleteDocument: builder.mutation({
|
@@ -347,12 +257,15 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
347
257
|
]
|
348
258
|
}),
|
349
259
|
deleteManyDocuments: builder.mutation({
|
350
|
-
query: ({ model, ...body }) => ({
|
260
|
+
query: ({ model, params, ...body }) => ({
|
351
261
|
url: `/content-manager/collection-types/${model}/actions/bulkDelete`,
|
352
262
|
method: "POST",
|
353
|
-
data: body
|
263
|
+
data: body,
|
264
|
+
config: {
|
265
|
+
params
|
266
|
+
}
|
354
267
|
}),
|
355
|
-
invalidatesTags: (_res, _error, { model
|
268
|
+
invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
|
356
269
|
}),
|
357
270
|
discardDocument: builder.mutation({
|
358
271
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -369,7 +282,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
369
282
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
370
283
|
},
|
371
284
|
{ type: "Document", id: `${model}_LIST` },
|
372
|
-
"Relations"
|
285
|
+
"Relations",
|
286
|
+
{ type: "UidAvailability", id: model }
|
373
287
|
];
|
374
288
|
}
|
375
289
|
}),
|
@@ -382,11 +296,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
382
296
|
url: `/content-manager/collection-types/${model}`,
|
383
297
|
method: "GET",
|
384
298
|
config: {
|
385
|
-
params
|
299
|
+
params: qs.stringify(params, { encode: true })
|
386
300
|
}
|
387
301
|
}),
|
388
302
|
providesTags: (result, _error, arg) => {
|
389
303
|
return [
|
304
|
+
{ type: "Document", id: `ALL_LIST` },
|
390
305
|
{ type: "Document", id: `${arg.model}_LIST` },
|
391
306
|
...result?.results.map(({ documentId }) => ({
|
392
307
|
type: "Document",
|
@@ -425,6 +340,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
425
340
|
{
|
426
341
|
type: "Document",
|
427
342
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
343
|
+
},
|
344
|
+
// Make it easy to invalidate all individual documents queries for a model
|
345
|
+
{
|
346
|
+
type: "Document",
|
347
|
+
id: `${model}_ALL_ITEMS`
|
428
348
|
}
|
429
349
|
];
|
430
350
|
}
|
@@ -463,10 +383,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
463
383
|
}
|
464
384
|
}),
|
465
385
|
publishManyDocuments: builder.mutation({
|
466
|
-
query: ({ model, ...body }) => ({
|
386
|
+
query: ({ model, params, ...body }) => ({
|
467
387
|
url: `/content-manager/collection-types/${model}/actions/bulkPublish`,
|
468
388
|
method: "POST",
|
469
|
-
data: body
|
389
|
+
data: body,
|
390
|
+
config: {
|
391
|
+
params
|
392
|
+
}
|
470
393
|
}),
|
471
394
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
472
395
|
}),
|
@@ -485,8 +408,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
485
408
|
type: "Document",
|
486
409
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
487
410
|
},
|
488
|
-
"Relations"
|
411
|
+
"Relations",
|
412
|
+
{ type: "UidAvailability", id: model }
|
489
413
|
];
|
414
|
+
},
|
415
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
416
|
+
const patchResult = dispatch(
|
417
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
418
|
+
Object.assign(draft.data, data);
|
419
|
+
})
|
420
|
+
);
|
421
|
+
try {
|
422
|
+
await queryFulfilled;
|
423
|
+
} catch {
|
424
|
+
patchResult.undo();
|
425
|
+
}
|
490
426
|
}
|
491
427
|
}),
|
492
428
|
unpublishDocument: builder.mutation({
|
@@ -508,10 +444,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
508
444
|
}
|
509
445
|
}),
|
510
446
|
unpublishManyDocuments: builder.mutation({
|
511
|
-
query: ({ model, ...body }) => ({
|
447
|
+
query: ({ model, params, ...body }) => ({
|
512
448
|
url: `/content-manager/collection-types/${model}/actions/bulkUnpublish`,
|
513
449
|
method: "POST",
|
514
|
-
data: body
|
450
|
+
data: body,
|
451
|
+
config: {
|
452
|
+
params
|
453
|
+
}
|
515
454
|
}),
|
516
455
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
517
456
|
})
|
@@ -535,20 +474,54 @@ const {
|
|
535
474
|
useUnpublishDocumentMutation,
|
536
475
|
useUnpublishManyDocumentsMutation
|
537
476
|
} = documentApi;
|
538
|
-
const
|
477
|
+
const buildValidParams = (query) => {
|
478
|
+
if (!query)
|
479
|
+
return query;
|
480
|
+
const { plugins: _, ...validQueryParams } = {
|
481
|
+
...query,
|
482
|
+
...Object.values(query?.plugins ?? {}).reduce(
|
483
|
+
(acc, current) => Object.assign(acc, current),
|
484
|
+
{}
|
485
|
+
)
|
486
|
+
};
|
487
|
+
return validQueryParams;
|
488
|
+
};
|
489
|
+
const isBaseQueryError = (error) => {
|
490
|
+
return error.name !== void 0;
|
491
|
+
};
|
492
|
+
const arrayValidator = (attribute, options) => ({
|
493
|
+
message: strapiAdmin.translatedErrors.required,
|
494
|
+
test(value) {
|
495
|
+
if (options.status === "draft") {
|
496
|
+
return true;
|
497
|
+
}
|
498
|
+
if (!attribute.required) {
|
499
|
+
return true;
|
500
|
+
}
|
501
|
+
if (!value) {
|
502
|
+
return false;
|
503
|
+
}
|
504
|
+
if (Array.isArray(value) && value.length === 0) {
|
505
|
+
return false;
|
506
|
+
}
|
507
|
+
return true;
|
508
|
+
}
|
509
|
+
});
|
510
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
539
511
|
const createModelSchema = (attributes2) => yup__namespace.object().shape(
|
540
512
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
541
513
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
542
514
|
return acc;
|
543
515
|
}
|
544
516
|
const validations = [
|
517
|
+
addNullableValidation,
|
545
518
|
addRequiredValidation,
|
546
519
|
addMinLengthValidation,
|
547
520
|
addMaxLengthValidation,
|
548
521
|
addMinValidation,
|
549
522
|
addMaxValidation,
|
550
523
|
addRegexValidation
|
551
|
-
].map((fn) => fn(attribute));
|
524
|
+
].map((fn) => fn(attribute, options));
|
552
525
|
const transformSchema = pipe__default.default(...validations);
|
553
526
|
switch (attribute.type) {
|
554
527
|
case "component": {
|
@@ -558,12 +531,12 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
558
531
|
...acc,
|
559
532
|
[name]: transformSchema(
|
560
533
|
yup__namespace.array().of(createModelSchema(attributes3).nullable(false))
|
561
|
-
)
|
534
|
+
).test(arrayValidator(attribute, options))
|
562
535
|
};
|
563
536
|
} else {
|
564
537
|
return {
|
565
538
|
...acc,
|
566
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
539
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
567
540
|
};
|
568
541
|
}
|
569
542
|
}
|
@@ -574,24 +547,42 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
574
547
|
yup__namespace.array().of(
|
575
548
|
yup__namespace.lazy(
|
576
549
|
(data) => {
|
577
|
-
const
|
578
|
-
|
550
|
+
const attributes3 = components?.[data?.__component]?.attributes;
|
551
|
+
const validation = yup__namespace.object().shape({
|
579
552
|
__component: yup__namespace.string().required().oneOf(Object.keys(components))
|
580
|
-
}).nullable(false)
|
553
|
+
}).nullable(false);
|
554
|
+
if (!attributes3) {
|
555
|
+
return validation;
|
556
|
+
}
|
557
|
+
return validation.concat(createModelSchema(attributes3));
|
581
558
|
}
|
582
559
|
)
|
583
560
|
)
|
584
|
-
)
|
561
|
+
).test(arrayValidator(attribute, options))
|
585
562
|
};
|
586
563
|
case "relation":
|
587
564
|
return {
|
588
565
|
...acc,
|
589
566
|
[name]: transformSchema(
|
590
|
-
yup__namespace.
|
591
|
-
|
592
|
-
|
593
|
-
})
|
594
|
-
|
567
|
+
yup__namespace.lazy((value) => {
|
568
|
+
if (!value) {
|
569
|
+
return yup__namespace.mixed().nullable(true);
|
570
|
+
} else if (Array.isArray(value)) {
|
571
|
+
return yup__namespace.array().of(
|
572
|
+
yup__namespace.object().shape({
|
573
|
+
id: yup__namespace.number().required()
|
574
|
+
})
|
575
|
+
);
|
576
|
+
} else if (typeof value === "object") {
|
577
|
+
return yup__namespace.object();
|
578
|
+
} else {
|
579
|
+
return yup__namespace.mixed().test(
|
580
|
+
"type-error",
|
581
|
+
"Relation values must be either null, an array of objects with {id} or an object.",
|
582
|
+
() => false
|
583
|
+
);
|
584
|
+
}
|
585
|
+
})
|
595
586
|
)
|
596
587
|
};
|
597
588
|
default:
|
@@ -631,6 +622,14 @@ const createAttributeSchema = (attribute) => {
|
|
631
622
|
if (!value || typeof value === "string" && value.length === 0) {
|
632
623
|
return true;
|
633
624
|
}
|
625
|
+
if (typeof value === "object") {
|
626
|
+
try {
|
627
|
+
JSON.stringify(value);
|
628
|
+
return true;
|
629
|
+
} catch (err) {
|
630
|
+
return false;
|
631
|
+
}
|
632
|
+
}
|
634
633
|
try {
|
635
634
|
JSON.parse(value);
|
636
635
|
return true;
|
@@ -649,16 +648,30 @@ const createAttributeSchema = (attribute) => {
|
|
649
648
|
return yup__namespace.mixed();
|
650
649
|
}
|
651
650
|
};
|
652
|
-
const
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
651
|
+
const nullableSchema = (schema) => {
|
652
|
+
return schema?.nullable ? schema.nullable() : (
|
653
|
+
// In some cases '.nullable' will not be available on the schema.
|
654
|
+
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
655
|
+
// In these cases we should just return the schema as it is.
|
656
|
+
schema
|
657
|
+
);
|
658
|
+
};
|
659
|
+
const addNullableValidation = () => (schema) => {
|
660
|
+
return nullableSchema(schema);
|
661
|
+
};
|
662
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
663
|
+
if (options.status === "draft" || !attribute.required) {
|
664
|
+
return schema;
|
665
|
+
}
|
666
|
+
if (attribute.required && "required" in schema) {
|
667
|
+
return schema.required(strapiAdmin.translatedErrors.required);
|
658
668
|
}
|
659
|
-
return schema
|
669
|
+
return schema;
|
660
670
|
};
|
661
|
-
const addMinLengthValidation = (attribute) => (schema) => {
|
671
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
672
|
+
if (options.status === "draft") {
|
673
|
+
return schema;
|
674
|
+
}
|
662
675
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
663
676
|
return schema.min(attribute.minLength, {
|
664
677
|
...strapiAdmin.translatedErrors.minLength,
|
@@ -680,10 +693,13 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
680
693
|
}
|
681
694
|
return schema;
|
682
695
|
};
|
683
|
-
const addMinValidation = (attribute) => (schema) => {
|
684
|
-
if ("
|
696
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
697
|
+
if (options.status === "draft") {
|
698
|
+
return schema;
|
699
|
+
}
|
700
|
+
if ("min" in attribute && "min" in schema) {
|
685
701
|
const min = toInteger(attribute.min);
|
686
|
-
if (
|
702
|
+
if (min) {
|
687
703
|
return schema.min(min, {
|
688
704
|
...strapiAdmin.translatedErrors.min,
|
689
705
|
values: {
|
@@ -728,24 +744,6 @@ const addRegexValidation = (attribute) => (schema) => {
|
|
728
744
|
}
|
729
745
|
return schema;
|
730
746
|
};
|
731
|
-
const extractValuesFromYupError = (errorType, errorParams) => {
|
732
|
-
if (!errorType || !errorParams) {
|
733
|
-
return {};
|
734
|
-
}
|
735
|
-
return {
|
736
|
-
[errorType]: errorParams[errorType]
|
737
|
-
};
|
738
|
-
};
|
739
|
-
const getInnerErrors = (error) => (error?.inner || []).reduce((acc, currentError) => {
|
740
|
-
if (currentError.path) {
|
741
|
-
acc[currentError.path.split("[").join(".").split("]").join("")] = {
|
742
|
-
id: currentError.message,
|
743
|
-
defaultMessage: currentError.message,
|
744
|
-
values: extractValuesFromYupError(currentError?.type, currentError?.params)
|
745
|
-
};
|
746
|
-
}
|
747
|
-
return acc;
|
748
|
-
}, {});
|
749
747
|
const initApi = contentManagerApi.injectEndpoints({
|
750
748
|
endpoints: (builder) => ({
|
751
749
|
getInitialData: builder.query({
|
@@ -759,27 +757,20 @@ const { useGetInitialDataQuery } = initApi;
|
|
759
757
|
const useContentTypeSchema = (model) => {
|
760
758
|
const { toggleNotification } = strapiAdmin.useNotification();
|
761
759
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
762
|
-
const {
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
)
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
error: res.error,
|
777
|
-
components: Object.keys(components2).length === 0 ? void 0 : components2,
|
778
|
-
contentType: contentType2,
|
779
|
-
contentTypes: res.data?.contentTypes ?? []
|
780
|
-
};
|
781
|
-
}
|
782
|
-
});
|
760
|
+
const { data, error, isLoading, isFetching } = useGetInitialDataQuery(void 0);
|
761
|
+
const { components, contentType, contentTypes } = React__namespace.useMemo(() => {
|
762
|
+
const contentType2 = data?.contentTypes.find((ct) => ct.uid === model);
|
763
|
+
const componentsByKey = data?.components.reduce((acc, component) => {
|
764
|
+
acc[component.uid] = component;
|
765
|
+
return acc;
|
766
|
+
}, {});
|
767
|
+
const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
|
768
|
+
return {
|
769
|
+
components: Object.keys(components2).length === 0 ? void 0 : components2,
|
770
|
+
contentType: contentType2,
|
771
|
+
contentTypes: data?.contentTypes ?? []
|
772
|
+
};
|
773
|
+
}, [model, data]);
|
783
774
|
React__namespace.useEffect(() => {
|
784
775
|
if (error) {
|
785
776
|
toggleNotification({
|
@@ -826,16 +817,328 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
826
817
|
}, {});
|
827
818
|
return componentsByKey;
|
828
819
|
};
|
829
|
-
const
|
820
|
+
const HOOKS = {
|
821
|
+
/**
|
822
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
823
|
+
* @constant
|
824
|
+
* @type {string}
|
825
|
+
*/
|
826
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
827
|
+
/**
|
828
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
829
|
+
* @constant
|
830
|
+
* @type {string}
|
831
|
+
*/
|
832
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
833
|
+
/**
|
834
|
+
* Hook that allows to mutate the CM's edit view layout
|
835
|
+
* @constant
|
836
|
+
* @type {string}
|
837
|
+
*/
|
838
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
839
|
+
/**
|
840
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
841
|
+
* @constant
|
842
|
+
* @type {string}
|
843
|
+
*/
|
844
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
845
|
+
};
|
846
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
847
|
+
endpoints: (builder) => ({
|
848
|
+
getContentTypeConfiguration: builder.query({
|
849
|
+
query: (uid) => ({
|
850
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
851
|
+
method: "GET"
|
852
|
+
}),
|
853
|
+
transformResponse: (response) => response.data,
|
854
|
+
providesTags: (_result, _error, uid) => [
|
855
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
856
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
857
|
+
]
|
858
|
+
}),
|
859
|
+
getAllContentTypeSettings: builder.query({
|
860
|
+
query: () => "/content-manager/content-types-settings",
|
861
|
+
transformResponse: (response) => response.data,
|
862
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
863
|
+
}),
|
864
|
+
updateContentTypeConfiguration: builder.mutation({
|
865
|
+
query: ({ uid, ...body }) => ({
|
866
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
867
|
+
method: "PUT",
|
868
|
+
data: body
|
869
|
+
}),
|
870
|
+
transformResponse: (response) => response.data,
|
871
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
872
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
873
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
874
|
+
// Is this necessary?
|
875
|
+
{ type: "InitialData" }
|
876
|
+
]
|
877
|
+
})
|
878
|
+
})
|
879
|
+
});
|
880
|
+
const {
|
881
|
+
useGetContentTypeConfigurationQuery,
|
882
|
+
useGetAllContentTypeSettingsQuery,
|
883
|
+
useUpdateContentTypeConfigurationMutation
|
884
|
+
} = contentTypesApi;
|
885
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
886
|
+
const { type } = attribute;
|
887
|
+
if (type === "relation") {
|
888
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
889
|
+
}
|
890
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
891
|
+
};
|
892
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
893
|
+
if (!mainFieldName) {
|
894
|
+
return void 0;
|
895
|
+
}
|
896
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
897
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
898
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
899
|
+
);
|
900
|
+
return {
|
901
|
+
name: mainFieldName,
|
902
|
+
type: mainFieldType ?? "string"
|
903
|
+
};
|
904
|
+
};
|
905
|
+
const DEFAULT_SETTINGS = {
|
906
|
+
bulkable: false,
|
907
|
+
filterable: false,
|
908
|
+
searchable: false,
|
909
|
+
pagination: false,
|
910
|
+
defaultSortBy: "",
|
911
|
+
defaultSortOrder: "asc",
|
912
|
+
mainField: "id",
|
913
|
+
pageSize: 10
|
914
|
+
};
|
915
|
+
const useDocumentLayout = (model) => {
|
916
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
917
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
918
|
+
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
830
919
|
const { toggleNotification } = strapiAdmin.useNotification();
|
831
920
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
921
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
832
922
|
const {
|
833
|
-
|
834
|
-
isLoading:
|
923
|
+
data,
|
924
|
+
isLoading: isLoadingConfigs,
|
925
|
+
error,
|
926
|
+
isFetching: isFetchingConfigs
|
927
|
+
} = useGetContentTypeConfigurationQuery(model);
|
928
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
929
|
+
React__namespace.useEffect(() => {
|
930
|
+
if (error) {
|
931
|
+
toggleNotification({
|
932
|
+
type: "danger",
|
933
|
+
message: formatAPIError(error)
|
934
|
+
});
|
935
|
+
}
|
936
|
+
}, [error, formatAPIError, toggleNotification]);
|
937
|
+
const editLayout = React__namespace.useMemo(
|
938
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
939
|
+
layout: [],
|
940
|
+
components: {},
|
941
|
+
metadatas: {},
|
942
|
+
options: {},
|
943
|
+
settings: DEFAULT_SETTINGS
|
944
|
+
},
|
945
|
+
[data, isLoading, schemas, schema, components]
|
946
|
+
);
|
947
|
+
const listLayout = React__namespace.useMemo(() => {
|
948
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
949
|
+
layout: [],
|
950
|
+
metadatas: {},
|
951
|
+
options: {},
|
952
|
+
settings: DEFAULT_SETTINGS
|
953
|
+
};
|
954
|
+
}, [data, isLoading, schemas, schema, components]);
|
955
|
+
const { layout: edit } = React__namespace.useMemo(
|
956
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
957
|
+
layout: editLayout,
|
958
|
+
query
|
959
|
+
}),
|
960
|
+
[editLayout, query, runHookWaterfall]
|
961
|
+
);
|
962
|
+
return {
|
963
|
+
error,
|
964
|
+
isLoading,
|
965
|
+
edit,
|
966
|
+
list: listLayout
|
967
|
+
};
|
968
|
+
};
|
969
|
+
const useDocLayout = () => {
|
970
|
+
const { model } = useDoc();
|
971
|
+
return useDocumentLayout(model);
|
972
|
+
};
|
973
|
+
const formatEditLayout = (data, {
|
974
|
+
schemas,
|
975
|
+
schema,
|
976
|
+
components
|
977
|
+
}) => {
|
978
|
+
let currentPanelIndex = 0;
|
979
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
980
|
+
data.contentType.layouts.edit,
|
981
|
+
schema?.attributes,
|
982
|
+
data.contentType.metadatas,
|
983
|
+
{ configurations: data.components, schemas: components },
|
984
|
+
schemas
|
985
|
+
).reduce((panels, row) => {
|
986
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
987
|
+
panels.push([row]);
|
988
|
+
currentPanelIndex += 2;
|
989
|
+
} else {
|
990
|
+
if (!panels[currentPanelIndex]) {
|
991
|
+
panels.push([row]);
|
992
|
+
} else {
|
993
|
+
panels[currentPanelIndex].push(row);
|
994
|
+
}
|
995
|
+
}
|
996
|
+
return panels;
|
997
|
+
}, []);
|
998
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
999
|
+
(acc, [uid, configuration]) => {
|
1000
|
+
acc[uid] = {
|
1001
|
+
layout: convertEditLayoutToFieldLayouts(
|
1002
|
+
configuration.layouts.edit,
|
1003
|
+
components[uid].attributes,
|
1004
|
+
configuration.metadatas,
|
1005
|
+
{ configurations: data.components, schemas: components }
|
1006
|
+
),
|
1007
|
+
settings: {
|
1008
|
+
...configuration.settings,
|
1009
|
+
icon: components[uid].info.icon,
|
1010
|
+
displayName: components[uid].info.displayName
|
1011
|
+
}
|
1012
|
+
};
|
1013
|
+
return acc;
|
1014
|
+
},
|
1015
|
+
{}
|
1016
|
+
);
|
1017
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1018
|
+
(acc, [attribute, metadata]) => {
|
1019
|
+
return {
|
1020
|
+
...acc,
|
1021
|
+
[attribute]: metadata.edit
|
1022
|
+
};
|
1023
|
+
},
|
1024
|
+
{}
|
1025
|
+
);
|
1026
|
+
return {
|
1027
|
+
layout: panelledEditAttributes,
|
1028
|
+
components: componentEditAttributes,
|
1029
|
+
metadatas: editMetadatas,
|
1030
|
+
settings: {
|
1031
|
+
...data.contentType.settings,
|
1032
|
+
displayName: schema?.info.displayName
|
1033
|
+
},
|
1034
|
+
options: {
|
1035
|
+
...schema?.options,
|
1036
|
+
...schema?.pluginOptions,
|
1037
|
+
...data.contentType.options
|
1038
|
+
}
|
1039
|
+
};
|
1040
|
+
};
|
1041
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1042
|
+
return rows.map(
|
1043
|
+
(row) => row.map((field) => {
|
1044
|
+
const attribute = attributes[field.name];
|
1045
|
+
if (!attribute) {
|
1046
|
+
return null;
|
1047
|
+
}
|
1048
|
+
const { edit: metadata } = metadatas[field.name];
|
1049
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1050
|
+
return {
|
1051
|
+
attribute,
|
1052
|
+
disabled: !metadata.editable,
|
1053
|
+
hint: metadata.description,
|
1054
|
+
label: metadata.label ?? "",
|
1055
|
+
name: field.name,
|
1056
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1057
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1058
|
+
schemas,
|
1059
|
+
components: components?.schemas ?? {}
|
1060
|
+
}),
|
1061
|
+
placeholder: metadata.placeholder ?? "",
|
1062
|
+
required: attribute.required ?? false,
|
1063
|
+
size: field.size,
|
1064
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1065
|
+
visible: metadata.visible ?? true,
|
1066
|
+
type: attribute.type
|
1067
|
+
};
|
1068
|
+
}).filter((field) => field !== null)
|
1069
|
+
);
|
1070
|
+
};
|
1071
|
+
const formatListLayout = (data, {
|
1072
|
+
schemas,
|
1073
|
+
schema,
|
1074
|
+
components
|
1075
|
+
}) => {
|
1076
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1077
|
+
(acc, [attribute, metadata]) => {
|
1078
|
+
return {
|
1079
|
+
...acc,
|
1080
|
+
[attribute]: metadata.list
|
1081
|
+
};
|
1082
|
+
},
|
1083
|
+
{}
|
1084
|
+
);
|
1085
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1086
|
+
data.contentType.layouts.list,
|
1087
|
+
schema?.attributes,
|
1088
|
+
listMetadatas,
|
1089
|
+
{ configurations: data.components, schemas: components },
|
1090
|
+
schemas
|
1091
|
+
);
|
1092
|
+
return {
|
1093
|
+
layout: listAttributes,
|
1094
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1095
|
+
metadatas: listMetadatas,
|
1096
|
+
options: {
|
1097
|
+
...schema?.options,
|
1098
|
+
...schema?.pluginOptions,
|
1099
|
+
...data.contentType.options
|
1100
|
+
}
|
1101
|
+
};
|
1102
|
+
};
|
1103
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1104
|
+
return columns.map((name) => {
|
1105
|
+
const attribute = attributes[name];
|
1106
|
+
if (!attribute) {
|
1107
|
+
return null;
|
1108
|
+
}
|
1109
|
+
const metadata = metadatas[name];
|
1110
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1111
|
+
return {
|
1112
|
+
attribute,
|
1113
|
+
label: metadata.label ?? "",
|
1114
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1115
|
+
schemas,
|
1116
|
+
components: components?.schemas ?? {}
|
1117
|
+
}),
|
1118
|
+
name,
|
1119
|
+
searchable: metadata.searchable ?? true,
|
1120
|
+
sortable: metadata.sortable ?? true
|
1121
|
+
};
|
1122
|
+
}).filter((field) => field !== null);
|
1123
|
+
};
|
1124
|
+
const useDocument = (args, opts) => {
|
1125
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
1126
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1127
|
+
const {
|
1128
|
+
currentData: data,
|
1129
|
+
isLoading: isLoadingDocument,
|
835
1130
|
isFetching: isFetchingDocument,
|
836
1131
|
error
|
837
|
-
} = useGetDocumentQuery(args,
|
838
|
-
|
1132
|
+
} = useGetDocumentQuery(args, {
|
1133
|
+
...opts,
|
1134
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1135
|
+
});
|
1136
|
+
const {
|
1137
|
+
components,
|
1138
|
+
schema,
|
1139
|
+
schemas,
|
1140
|
+
isLoading: isLoadingSchema
|
1141
|
+
} = useContentTypeSchema(args.model);
|
839
1142
|
React__namespace.useEffect(() => {
|
840
1143
|
if (error) {
|
841
1144
|
toggleNotification({
|
@@ -862,7 +1165,7 @@ const useDocument = (args, opts) => {
|
|
862
1165
|
return null;
|
863
1166
|
} catch (error2) {
|
864
1167
|
if (error2 instanceof yup.ValidationError) {
|
865
|
-
return
|
1168
|
+
return strapiAdmin.getYupValidationErrors(error2);
|
866
1169
|
}
|
867
1170
|
throw error2;
|
868
1171
|
}
|
@@ -870,12 +1173,15 @@ const useDocument = (args, opts) => {
|
|
870
1173
|
[validationSchema]
|
871
1174
|
);
|
872
1175
|
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1176
|
+
const hasError = !!error;
|
873
1177
|
return {
|
874
1178
|
components,
|
875
1179
|
document: data?.data,
|
876
1180
|
meta: data?.meta,
|
877
1181
|
isLoading,
|
1182
|
+
hasError,
|
878
1183
|
schema,
|
1184
|
+
schemas,
|
879
1185
|
validate
|
880
1186
|
};
|
881
1187
|
};
|
@@ -889,22 +1195,60 @@ const useDoc = () => {
|
|
889
1195
|
if (!slug) {
|
890
1196
|
throw new Error("Could not find model in url params");
|
891
1197
|
}
|
1198
|
+
const document = useDocument(
|
1199
|
+
{ documentId: origin || id, model: slug, collectionType, params },
|
1200
|
+
{
|
1201
|
+
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
1202
|
+
}
|
1203
|
+
);
|
1204
|
+
const returnId = origin || id === "create" ? void 0 : id;
|
892
1205
|
return {
|
893
1206
|
collectionType,
|
894
1207
|
model: slug,
|
895
|
-
id:
|
896
|
-
...
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
1208
|
+
id: returnId,
|
1209
|
+
...document
|
1210
|
+
};
|
1211
|
+
};
|
1212
|
+
const useContentManagerContext = () => {
|
1213
|
+
const {
|
1214
|
+
collectionType,
|
1215
|
+
model,
|
1216
|
+
id,
|
1217
|
+
components,
|
1218
|
+
isLoading: isLoadingDoc,
|
1219
|
+
schema,
|
1220
|
+
schemas
|
1221
|
+
} = useDoc();
|
1222
|
+
const layout = useDocumentLayout(model);
|
1223
|
+
const form = strapiAdmin.useForm("useContentManagerContext", (state) => state);
|
1224
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1225
|
+
const slug = model;
|
1226
|
+
const isCreatingEntry = id === "create";
|
1227
|
+
useContentTypeSchema();
|
1228
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1229
|
+
const error = layout.error;
|
1230
|
+
return {
|
1231
|
+
error,
|
1232
|
+
isLoading,
|
1233
|
+
// Base metadata
|
1234
|
+
model,
|
1235
|
+
collectionType,
|
1236
|
+
id,
|
1237
|
+
slug,
|
1238
|
+
isCreatingEntry,
|
1239
|
+
isSingleType,
|
1240
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1241
|
+
// All schema infos
|
1242
|
+
components,
|
1243
|
+
contentType: schema,
|
1244
|
+
contentTypes: schemas,
|
1245
|
+
// Form state
|
1246
|
+
form,
|
1247
|
+
// layout infos
|
1248
|
+
layout
|
902
1249
|
};
|
903
1250
|
};
|
904
1251
|
const prefixPluginTranslations = (trad, pluginId) => {
|
905
|
-
if (!pluginId) {
|
906
|
-
throw new TypeError("pluginId can't be empty");
|
907
|
-
}
|
908
1252
|
return Object.keys(trad).reduce((acc, current) => {
|
909
1253
|
acc[`${pluginId}.${current}`] = trad[current];
|
910
1254
|
return acc;
|
@@ -920,6 +1264,8 @@ const useDocumentActions = () => {
|
|
920
1264
|
const { formatMessage } = reactIntl.useIntl();
|
921
1265
|
const { trackUsage } = strapiAdmin.useTracking();
|
922
1266
|
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
1267
|
+
const navigate = reactRouterDom.useNavigate();
|
1268
|
+
const setCurrentStep = strapiAdmin.useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
923
1269
|
const [deleteDocument] = useDeleteDocumentMutation();
|
924
1270
|
const _delete = React__namespace.useCallback(
|
925
1271
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -958,14 +1304,53 @@ const useDocumentActions = () => {
|
|
958
1304
|
},
|
959
1305
|
[trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
|
960
1306
|
);
|
1307
|
+
const [deleteManyDocuments] = useDeleteManyDocumentsMutation();
|
1308
|
+
const deleteMany = React__namespace.useCallback(
|
1309
|
+
async ({ model, documentIds, params }) => {
|
1310
|
+
try {
|
1311
|
+
trackUsage("willBulkDeleteEntries");
|
1312
|
+
const res = await deleteManyDocuments({
|
1313
|
+
model,
|
1314
|
+
documentIds,
|
1315
|
+
params
|
1316
|
+
});
|
1317
|
+
if ("error" in res) {
|
1318
|
+
toggleNotification({
|
1319
|
+
type: "danger",
|
1320
|
+
message: formatAPIError(res.error)
|
1321
|
+
});
|
1322
|
+
return { error: res.error };
|
1323
|
+
}
|
1324
|
+
toggleNotification({
|
1325
|
+
type: "success",
|
1326
|
+
title: formatMessage({
|
1327
|
+
id: getTranslation("success.records.delete"),
|
1328
|
+
defaultMessage: "Successfully deleted."
|
1329
|
+
}),
|
1330
|
+
message: ""
|
1331
|
+
});
|
1332
|
+
trackUsage("didBulkDeleteEntries");
|
1333
|
+
return res.data;
|
1334
|
+
} catch (err) {
|
1335
|
+
toggleNotification({
|
1336
|
+
type: "danger",
|
1337
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1338
|
+
});
|
1339
|
+
trackUsage("didNotBulkDeleteEntries");
|
1340
|
+
throw err;
|
1341
|
+
}
|
1342
|
+
},
|
1343
|
+
[trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
1344
|
+
);
|
961
1345
|
const [discardDocument] = useDiscardDocumentMutation();
|
962
1346
|
const discard = React__namespace.useCallback(
|
963
|
-
async ({ collectionType, model, documentId }) => {
|
1347
|
+
async ({ collectionType, model, documentId, params }) => {
|
964
1348
|
try {
|
965
1349
|
const res = await discardDocument({
|
966
1350
|
collectionType,
|
967
1351
|
model,
|
968
|
-
documentId
|
1352
|
+
documentId,
|
1353
|
+
params
|
969
1354
|
});
|
970
1355
|
if ("error" in res) {
|
971
1356
|
toggleNotification({
|
@@ -1027,6 +1412,43 @@ const useDocumentActions = () => {
|
|
1027
1412
|
},
|
1028
1413
|
[trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
|
1029
1414
|
);
|
1415
|
+
const [publishManyDocuments] = usePublishManyDocumentsMutation();
|
1416
|
+
const publishMany = React__namespace.useCallback(
|
1417
|
+
async ({ model, documentIds, params }) => {
|
1418
|
+
try {
|
1419
|
+
const res = await publishManyDocuments({
|
1420
|
+
model,
|
1421
|
+
documentIds,
|
1422
|
+
params
|
1423
|
+
});
|
1424
|
+
if ("error" in res) {
|
1425
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1426
|
+
return { error: res.error };
|
1427
|
+
}
|
1428
|
+
toggleNotification({
|
1429
|
+
type: "success",
|
1430
|
+
message: formatMessage({
|
1431
|
+
id: getTranslation("success.record.publish"),
|
1432
|
+
defaultMessage: "Published document"
|
1433
|
+
})
|
1434
|
+
});
|
1435
|
+
return res.data;
|
1436
|
+
} catch (err) {
|
1437
|
+
toggleNotification({
|
1438
|
+
type: "danger",
|
1439
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1440
|
+
});
|
1441
|
+
throw err;
|
1442
|
+
}
|
1443
|
+
},
|
1444
|
+
[
|
1445
|
+
// trackUsage,
|
1446
|
+
publishManyDocuments,
|
1447
|
+
toggleNotification,
|
1448
|
+
formatMessage,
|
1449
|
+
formatAPIError
|
1450
|
+
]
|
1451
|
+
);
|
1030
1452
|
const [updateDocument] = useUpdateDocumentMutation();
|
1031
1453
|
const update = React__namespace.useCallback(
|
1032
1454
|
async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
|
@@ -1101,6 +1523,41 @@ const useDocumentActions = () => {
|
|
1101
1523
|
},
|
1102
1524
|
[trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
|
1103
1525
|
);
|
1526
|
+
const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
|
1527
|
+
const unpublishMany = React__namespace.useCallback(
|
1528
|
+
async ({ model, documentIds, params }) => {
|
1529
|
+
try {
|
1530
|
+
trackUsage("willBulkUnpublishEntries");
|
1531
|
+
const res = await unpublishManyDocuments({
|
1532
|
+
model,
|
1533
|
+
documentIds,
|
1534
|
+
params
|
1535
|
+
});
|
1536
|
+
if ("error" in res) {
|
1537
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1538
|
+
return { error: res.error };
|
1539
|
+
}
|
1540
|
+
trackUsage("didBulkUnpublishEntries");
|
1541
|
+
toggleNotification({
|
1542
|
+
type: "success",
|
1543
|
+
title: formatMessage({
|
1544
|
+
id: getTranslation("success.records.unpublish"),
|
1545
|
+
defaultMessage: "Successfully unpublished."
|
1546
|
+
}),
|
1547
|
+
message: ""
|
1548
|
+
});
|
1549
|
+
return res.data;
|
1550
|
+
} catch (err) {
|
1551
|
+
toggleNotification({
|
1552
|
+
type: "danger",
|
1553
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1554
|
+
});
|
1555
|
+
trackUsage("didNotBulkUnpublishEntries");
|
1556
|
+
throw err;
|
1557
|
+
}
|
1558
|
+
},
|
1559
|
+
[trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
1560
|
+
);
|
1104
1561
|
const [createDocument] = useCreateDocumentMutation();
|
1105
1562
|
const create = React__namespace.useCallback(
|
1106
1563
|
async ({ model, params }, data, trackerProperty) => {
|
@@ -1123,6 +1580,7 @@ const useDocumentActions = () => {
|
|
1123
1580
|
defaultMessage: "Saved document"
|
1124
1581
|
})
|
1125
1582
|
});
|
1583
|
+
setCurrentStep("contentManager.success");
|
1126
1584
|
return res.data;
|
1127
1585
|
} catch (err) {
|
1128
1586
|
toggleNotification({
|
@@ -1144,7 +1602,6 @@ const useDocumentActions = () => {
|
|
1144
1602
|
sourceId
|
1145
1603
|
});
|
1146
1604
|
if ("error" in res) {
|
1147
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1148
1605
|
return { error: res.error };
|
1149
1606
|
}
|
1150
1607
|
toggleNotification({
|
@@ -1163,7 +1620,7 @@ const useDocumentActions = () => {
|
|
1163
1620
|
throw err;
|
1164
1621
|
}
|
1165
1622
|
},
|
1166
|
-
[autoCloneDocument,
|
1623
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1167
1624
|
);
|
1168
1625
|
const [cloneDocument] = useCloneDocumentMutation();
|
1169
1626
|
const clone = React__namespace.useCallback(
|
@@ -1189,6 +1646,7 @@ const useDocumentActions = () => {
|
|
1189
1646
|
defaultMessage: "Cloned document"
|
1190
1647
|
})
|
1191
1648
|
});
|
1649
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1192
1650
|
return res.data;
|
1193
1651
|
} catch (err) {
|
1194
1652
|
toggleNotification({
|
@@ -1199,7 +1657,7 @@ const useDocumentActions = () => {
|
|
1199
1657
|
throw err;
|
1200
1658
|
}
|
1201
1659
|
},
|
1202
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1660
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1203
1661
|
);
|
1204
1662
|
const [getDoc] = useLazyGetDocumentQuery();
|
1205
1663
|
const getDocument = React__namespace.useCallback(
|
@@ -1214,17 +1672,20 @@ const useDocumentActions = () => {
|
|
1214
1672
|
clone,
|
1215
1673
|
create,
|
1216
1674
|
delete: _delete,
|
1675
|
+
deleteMany,
|
1217
1676
|
discard,
|
1218
1677
|
getDocument,
|
1219
1678
|
publish,
|
1679
|
+
publishMany,
|
1220
1680
|
unpublish,
|
1681
|
+
unpublishMany,
|
1221
1682
|
update
|
1222
1683
|
};
|
1223
1684
|
};
|
1224
|
-
const ProtectedHistoryPage =
|
1225
|
-
() => Promise.resolve().then(() => require("./History-
|
1685
|
+
const ProtectedHistoryPage = React__namespace.lazy(
|
1686
|
+
() => Promise.resolve().then(() => require("./History-BsPXl1XH.js")).then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1226
1687
|
);
|
1227
|
-
const routes$
|
1688
|
+
const routes$2 = [
|
1228
1689
|
{
|
1229
1690
|
path: ":collectionType/:slug/:id/history",
|
1230
1691
|
Component: ProtectedHistoryPage
|
@@ -1234,32 +1695,45 @@ const routes$1 = [
|
|
1234
1695
|
Component: ProtectedHistoryPage
|
1235
1696
|
}
|
1236
1697
|
];
|
1698
|
+
const ProtectedPreviewPage = React__namespace.lazy(
|
1699
|
+
() => Promise.resolve().then(() => require("./Preview-BKuVG1dV.js")).then((mod) => ({ default: mod.ProtectedPreviewPage }))
|
1700
|
+
);
|
1701
|
+
const routes$1 = [
|
1702
|
+
{
|
1703
|
+
path: ":collectionType/:slug/:id/preview",
|
1704
|
+
Component: ProtectedPreviewPage
|
1705
|
+
},
|
1706
|
+
{
|
1707
|
+
path: ":collectionType/:slug/preview",
|
1708
|
+
Component: ProtectedPreviewPage
|
1709
|
+
}
|
1710
|
+
];
|
1237
1711
|
const ProtectedEditViewPage = React.lazy(
|
1238
|
-
() => Promise.resolve().then(() => require("./EditViewPage-
|
1712
|
+
() => Promise.resolve().then(() => require("./EditViewPage-BRA-JSnw.js")).then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1239
1713
|
);
|
1240
1714
|
const ProtectedListViewPage = React.lazy(
|
1241
|
-
() => Promise.resolve().then(() => require("./ListViewPage-
|
1715
|
+
() => Promise.resolve().then(() => require("./ListViewPage-BUKFOJuS.js")).then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1242
1716
|
);
|
1243
1717
|
const ProtectedListConfiguration = React.lazy(
|
1244
|
-
() => Promise.resolve().then(() => require("./ListConfigurationPage-
|
1718
|
+
() => Promise.resolve().then(() => require("./ListConfigurationPage-CN1-7Pgi.js")).then((mod) => ({
|
1245
1719
|
default: mod.ProtectedListConfiguration
|
1246
1720
|
}))
|
1247
1721
|
);
|
1248
1722
|
const ProtectedEditConfigurationPage = React.lazy(
|
1249
|
-
() => Promise.resolve().then(() => require("./EditConfigurationPage-
|
1723
|
+
() => Promise.resolve().then(() => require("./EditConfigurationPage-sdGi-bna.js")).then((mod) => ({
|
1250
1724
|
default: mod.ProtectedEditConfigurationPage
|
1251
1725
|
}))
|
1252
1726
|
);
|
1253
1727
|
const ProtectedComponentConfigurationPage = React.lazy(
|
1254
|
-
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-
|
1728
|
+
() => Promise.resolve().then(() => require("./ComponentConfigurationPage-BebDdCkl.js")).then((mod) => ({
|
1255
1729
|
default: mod.ProtectedComponentConfigurationPage
|
1256
1730
|
}))
|
1257
1731
|
);
|
1258
1732
|
const NoPermissions = React.lazy(
|
1259
|
-
() => Promise.resolve().then(() => require("./NoPermissionsPage-
|
1733
|
+
() => Promise.resolve().then(() => require("./NoPermissionsPage-DRPnEq9t.js")).then((mod) => ({ default: mod.NoPermissions }))
|
1260
1734
|
);
|
1261
1735
|
const NoContentType = React.lazy(
|
1262
|
-
() => Promise.resolve().then(() => require("./NoContentTypePage-
|
1736
|
+
() => Promise.resolve().then(() => require("./NoContentTypePage-Cs7Kk9EW.js")).then((mod) => ({ default: mod.NoContentType }))
|
1263
1737
|
);
|
1264
1738
|
const CollectionTypePages = () => {
|
1265
1739
|
const { collectionType } = reactRouterDom.useParams();
|
@@ -1271,7 +1745,7 @@ const CollectionTypePages = () => {
|
|
1271
1745
|
const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
|
1272
1746
|
const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
|
1273
1747
|
const LIST_RELATIVE_PATH = ":collectionType/:slug";
|
1274
|
-
const LIST_PATH = `/content-manager
|
1748
|
+
const LIST_PATH = `/content-manager/collection-types/:slug`;
|
1275
1749
|
const routes = [
|
1276
1750
|
{
|
1277
1751
|
path: LIST_RELATIVE_PATH,
|
@@ -1305,6 +1779,7 @@ const routes = [
|
|
1305
1779
|
path: "no-content-types",
|
1306
1780
|
Component: NoContentType
|
1307
1781
|
},
|
1782
|
+
...routes$2,
|
1308
1783
|
...routes$1
|
1309
1784
|
];
|
1310
1785
|
const DocumentActions = ({ actions: actions2 }) => {
|
@@ -1373,12 +1848,14 @@ const DocumentActionButton = (action) => {
|
|
1373
1848
|
/* @__PURE__ */ jsxRuntime.jsx(
|
1374
1849
|
designSystem.Button,
|
1375
1850
|
{
|
1376
|
-
flex:
|
1851
|
+
flex: "auto",
|
1377
1852
|
startIcon: action.icon,
|
1378
1853
|
disabled: action.disabled,
|
1379
1854
|
onClick: handleClick(action),
|
1380
1855
|
justifyContent: "center",
|
1381
1856
|
variant: action.variant || "default",
|
1857
|
+
paddingTop: "7px",
|
1858
|
+
paddingBottom: "7px",
|
1382
1859
|
children: action.label
|
1383
1860
|
}
|
1384
1861
|
),
|
@@ -1386,7 +1863,7 @@ const DocumentActionButton = (action) => {
|
|
1386
1863
|
DocumentActionConfirmDialog,
|
1387
1864
|
{
|
1388
1865
|
...action.dialog,
|
1389
|
-
variant: action.variant,
|
1866
|
+
variant: action.dialog?.variant ?? action.variant,
|
1390
1867
|
isOpen: dialogId === action.id,
|
1391
1868
|
onClose: handleClose
|
1392
1869
|
}
|
@@ -1401,6 +1878,11 @@ const DocumentActionButton = (action) => {
|
|
1401
1878
|
) : null
|
1402
1879
|
] });
|
1403
1880
|
};
|
1881
|
+
const MenuItem = styledComponents.styled(designSystem.Menu.Item)`
|
1882
|
+
&:hover {
|
1883
|
+
background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
|
1884
|
+
}
|
1885
|
+
`;
|
1404
1886
|
const DocumentActionsMenu = ({
|
1405
1887
|
actions: actions2,
|
1406
1888
|
children,
|
@@ -1443,49 +1925,48 @@ const DocumentActionsMenu = ({
|
|
1443
1925
|
disabled: isDisabled,
|
1444
1926
|
size: "S",
|
1445
1927
|
endIcon: null,
|
1446
|
-
paddingTop: "
|
1447
|
-
paddingLeft: "
|
1448
|
-
paddingRight: "
|
1928
|
+
paddingTop: "4px",
|
1929
|
+
paddingLeft: "7px",
|
1930
|
+
paddingRight: "7px",
|
1449
1931
|
variant,
|
1450
1932
|
children: [
|
1451
1933
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.More, { "aria-hidden": true, focusable: false }),
|
1452
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, {
|
1934
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { tag: "span", children: label || formatMessage({
|
1453
1935
|
id: "content-manager.containers.edit.panels.default.more-actions",
|
1454
1936
|
defaultMessage: "More document actions"
|
1455
1937
|
}) })
|
1456
1938
|
]
|
1457
1939
|
}
|
1458
1940
|
),
|
1459
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, {
|
1941
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1460
1942
|
actions2.map((action) => {
|
1461
1943
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
1462
|
-
|
1944
|
+
MenuItem,
|
1463
1945
|
{
|
1464
1946
|
disabled: action.disabled,
|
1465
1947
|
onSelect: handleClick(action),
|
1466
1948
|
display: "block",
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
] })
|
1949
|
+
isVariantDanger: action.variant === "danger",
|
1950
|
+
isDisabled: action.disabled,
|
1951
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "space-between", gap: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
1952
|
+
designSystem.Flex,
|
1953
|
+
{
|
1954
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1955
|
+
gap: 2,
|
1956
|
+
tag: "span",
|
1957
|
+
children: [
|
1958
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
1959
|
+
designSystem.Flex,
|
1960
|
+
{
|
1961
|
+
tag: "span",
|
1962
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1963
|
+
children: action.icon
|
1964
|
+
}
|
1965
|
+
),
|
1966
|
+
action.label
|
1967
|
+
]
|
1968
|
+
}
|
1969
|
+
) })
|
1489
1970
|
},
|
1490
1971
|
action.id
|
1491
1972
|
);
|
@@ -1527,6 +2008,18 @@ const convertActionVariantToColor = (variant = "secondary") => {
|
|
1527
2008
|
return "primary600";
|
1528
2009
|
}
|
1529
2010
|
};
|
2011
|
+
const convertActionVariantToIconColor = (variant = "secondary") => {
|
2012
|
+
switch (variant) {
|
2013
|
+
case "danger":
|
2014
|
+
return "danger600";
|
2015
|
+
case "secondary":
|
2016
|
+
return "neutral500";
|
2017
|
+
case "success":
|
2018
|
+
return "success600";
|
2019
|
+
default:
|
2020
|
+
return "primary600";
|
2021
|
+
}
|
2022
|
+
};
|
1530
2023
|
const DocumentActionConfirmDialog = ({
|
1531
2024
|
onClose,
|
1532
2025
|
onCancel,
|
@@ -1549,61 +2042,54 @@ const DocumentActionConfirmDialog = ({
|
|
1549
2042
|
}
|
1550
2043
|
onClose();
|
1551
2044
|
};
|
1552
|
-
return /* @__PURE__ */ jsxRuntime.
|
1553
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
1554
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
1555
|
-
|
1556
|
-
{
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
)
|
1567
|
-
] });
|
2045
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2046
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
2047
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: content }),
|
2048
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
2049
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
2050
|
+
id: "app.components.Button.cancel",
|
2051
|
+
defaultMessage: "Cancel"
|
2052
|
+
}) }) }),
|
2053
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
2054
|
+
id: "app.components.Button.confirm",
|
2055
|
+
defaultMessage: "Confirm"
|
2056
|
+
}) })
|
2057
|
+
] })
|
2058
|
+
] }) });
|
1568
2059
|
};
|
1569
2060
|
const DocumentActionModal = ({
|
1570
2061
|
isOpen,
|
1571
2062
|
title,
|
1572
2063
|
onClose,
|
1573
2064
|
footer: Footer,
|
1574
|
-
content,
|
2065
|
+
content: Content,
|
1575
2066
|
onModalClose
|
1576
2067
|
}) => {
|
1577
|
-
const id = React__namespace.useId();
|
1578
|
-
if (!isOpen) {
|
1579
|
-
return null;
|
1580
|
-
}
|
1581
2068
|
const handleClose = () => {
|
1582
2069
|
if (onClose) {
|
1583
2070
|
onClose();
|
1584
2071
|
}
|
1585
2072
|
onModalClose();
|
1586
2073
|
};
|
1587
|
-
return /* @__PURE__ */ jsxRuntime.
|
1588
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
1589
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
1590
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1594
|
-
|
1595
|
-
|
1596
|
-
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
] });
|
2074
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
|
2075
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: title }) }),
|
2076
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: Content }),
|
2077
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { onClose: handleClose }) : Footer
|
2078
|
+
] }) });
|
2079
|
+
};
|
2080
|
+
const transformData = (data) => {
|
2081
|
+
if (Array.isArray(data)) {
|
2082
|
+
return data.map(transformData);
|
2083
|
+
}
|
2084
|
+
if (typeof data === "object" && data !== null) {
|
2085
|
+
if ("apiData" in data) {
|
2086
|
+
return data.apiData;
|
2087
|
+
}
|
2088
|
+
return mapValues__default.default(transformData)(data);
|
2089
|
+
}
|
2090
|
+
return data;
|
1605
2091
|
};
|
1606
|
-
const PublishAction = ({
|
2092
|
+
const PublishAction$1 = ({
|
1607
2093
|
activeTab,
|
1608
2094
|
documentId,
|
1609
2095
|
model,
|
@@ -1615,13 +2101,17 @@ const PublishAction = ({
|
|
1615
2101
|
const navigate = reactRouterDom.useNavigate();
|
1616
2102
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1617
2103
|
const { _unstableFormatValidationErrors: formatValidationErrors } = strapiAdmin.useAPIErrorHandler();
|
2104
|
+
const isListView = reactRouterDom.useMatch(LIST_PATH) !== null;
|
1618
2105
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
1619
2106
|
const { formatMessage } = reactIntl.useIntl();
|
1620
|
-
const { canPublish
|
1621
|
-
"PublishAction",
|
1622
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1623
|
-
);
|
2107
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1624
2108
|
const { publish } = useDocumentActions();
|
2109
|
+
const [
|
2110
|
+
countDraftRelations,
|
2111
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
2112
|
+
] = useLazyGetDraftRelationCountQuery();
|
2113
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React__namespace.useState(0);
|
2114
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React__namespace.useState(0);
|
1625
2115
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1626
2116
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
1627
2117
|
const modified = strapiAdmin.useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1630,10 +2120,105 @@ const PublishAction = ({
|
|
1630
2120
|
const validate = strapiAdmin.useForm("PublishAction", (state) => state.validate);
|
1631
2121
|
const setErrors = strapiAdmin.useForm("PublishAction", (state) => state.setErrors);
|
1632
2122
|
const formValues = strapiAdmin.useForm("PublishAction", ({ values }) => values);
|
2123
|
+
React__namespace.useEffect(() => {
|
2124
|
+
if (isErrorDraftRelations) {
|
2125
|
+
toggleNotification({
|
2126
|
+
type: "danger",
|
2127
|
+
message: formatMessage({
|
2128
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
2129
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
2130
|
+
})
|
2131
|
+
});
|
2132
|
+
}
|
2133
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
2134
|
+
React__namespace.useEffect(() => {
|
2135
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
2136
|
+
const extractDraftRelations = (data) => {
|
2137
|
+
const relations = data.connect || [];
|
2138
|
+
relations.forEach((relation) => {
|
2139
|
+
if (relation.status === "draft") {
|
2140
|
+
localDraftRelations.add(relation.id);
|
2141
|
+
}
|
2142
|
+
});
|
2143
|
+
};
|
2144
|
+
const traverseAndExtract = (data) => {
|
2145
|
+
Object.entries(data).forEach(([key, value]) => {
|
2146
|
+
if (key === "connect" && Array.isArray(value)) {
|
2147
|
+
extractDraftRelations({ connect: value });
|
2148
|
+
} else if (typeof value === "object" && value !== null) {
|
2149
|
+
traverseAndExtract(value);
|
2150
|
+
}
|
2151
|
+
});
|
2152
|
+
};
|
2153
|
+
if (!documentId || modified) {
|
2154
|
+
traverseAndExtract(formValues);
|
2155
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
2156
|
+
}
|
2157
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
2158
|
+
React__namespace.useEffect(() => {
|
2159
|
+
if (!document || !document.documentId || isListView) {
|
2160
|
+
return;
|
2161
|
+
}
|
2162
|
+
const fetchDraftRelationsCount = async () => {
|
2163
|
+
const { data, error } = await countDraftRelations({
|
2164
|
+
collectionType,
|
2165
|
+
model,
|
2166
|
+
documentId,
|
2167
|
+
params
|
2168
|
+
});
|
2169
|
+
if (error) {
|
2170
|
+
throw error;
|
2171
|
+
}
|
2172
|
+
if (data) {
|
2173
|
+
setServerCountOfDraftRelations(data.data);
|
2174
|
+
}
|
2175
|
+
};
|
2176
|
+
fetchDraftRelationsCount();
|
2177
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
1633
2178
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1634
2179
|
if (!schema?.options?.draftAndPublish) {
|
1635
2180
|
return null;
|
1636
2181
|
}
|
2182
|
+
const performPublish = async () => {
|
2183
|
+
setSubmitting(true);
|
2184
|
+
try {
|
2185
|
+
const { errors } = await validate(true, {
|
2186
|
+
status: "published"
|
2187
|
+
});
|
2188
|
+
if (errors) {
|
2189
|
+
toggleNotification({
|
2190
|
+
type: "danger",
|
2191
|
+
message: formatMessage({
|
2192
|
+
id: "content-manager.validation.error",
|
2193
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2194
|
+
})
|
2195
|
+
});
|
2196
|
+
return;
|
2197
|
+
}
|
2198
|
+
const res = await publish(
|
2199
|
+
{
|
2200
|
+
collectionType,
|
2201
|
+
model,
|
2202
|
+
documentId,
|
2203
|
+
params
|
2204
|
+
},
|
2205
|
+
transformData(formValues)
|
2206
|
+
);
|
2207
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2208
|
+
navigate({
|
2209
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2210
|
+
search: rawQuery
|
2211
|
+
});
|
2212
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2213
|
+
setErrors(formatValidationErrors(res.error));
|
2214
|
+
}
|
2215
|
+
} finally {
|
2216
|
+
setSubmitting(false);
|
2217
|
+
}
|
2218
|
+
};
|
2219
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
2220
|
+
const enableDraftRelationsCount = false;
|
2221
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1637
2222
|
return {
|
1638
2223
|
/**
|
1639
2224
|
* Disabled when:
|
@@ -1643,52 +2228,39 @@ const PublishAction = ({
|
|
1643
2228
|
* - the document is already published & not modified
|
1644
2229
|
* - the document is being created & not modified
|
1645
2230
|
* - the user doesn't have the permission to publish
|
1646
|
-
* - the user doesn't have the permission to create a new document
|
1647
|
-
* - the user doesn't have the permission to update the document
|
1648
2231
|
*/
|
1649
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
2232
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1650
2233
|
label: formatMessage({
|
1651
2234
|
id: "app.utils.publish",
|
1652
2235
|
defaultMessage: "Publish"
|
1653
2236
|
}),
|
1654
2237
|
onClick: async () => {
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1672
|
-
documentId,
|
1673
|
-
params
|
1674
|
-
},
|
1675
|
-
formValues
|
1676
|
-
);
|
1677
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1678
|
-
navigate({
|
1679
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1680
|
-
search: rawQuery
|
1681
|
-
});
|
1682
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1683
|
-
setErrors(formatValidationErrors(res.error));
|
2238
|
+
await performPublish();
|
2239
|
+
},
|
2240
|
+
dialog: hasDraftRelations ? {
|
2241
|
+
type: "dialog",
|
2242
|
+
variant: "danger",
|
2243
|
+
footer: null,
|
2244
|
+
title: formatMessage({
|
2245
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
2246
|
+
defaultMessage: "Confirmation"
|
2247
|
+
}),
|
2248
|
+
content: formatMessage(
|
2249
|
+
{
|
2250
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
2251
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
2252
|
+
},
|
2253
|
+
{
|
2254
|
+
count: totalDraftRelations
|
1684
2255
|
}
|
1685
|
-
|
1686
|
-
|
2256
|
+
),
|
2257
|
+
onConfirm: async () => {
|
2258
|
+
await performPublish();
|
1687
2259
|
}
|
1688
|
-
}
|
2260
|
+
} : void 0
|
1689
2261
|
};
|
1690
2262
|
};
|
1691
|
-
PublishAction.type = "publish";
|
2263
|
+
PublishAction$1.type = "publish";
|
1692
2264
|
const UpdateAction = ({
|
1693
2265
|
activeTab,
|
1694
2266
|
documentId,
|
@@ -1701,10 +2273,6 @@ const UpdateAction = ({
|
|
1701
2273
|
const cloneMatch = reactRouterDom.useMatch(CLONE_PATH);
|
1702
2274
|
const isCloning = cloneMatch !== null;
|
1703
2275
|
const { formatMessage } = reactIntl.useIntl();
|
1704
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1705
|
-
canCreate: canCreate2,
|
1706
|
-
canUpdate: canUpdate2
|
1707
|
-
}));
|
1708
2276
|
const { create, update, clone } = useDocumentActions();
|
1709
2277
|
const [{ query, rawQuery }] = strapiAdmin.useQueryParams();
|
1710
2278
|
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
@@ -1721,18 +2289,18 @@ const UpdateAction = ({
|
|
1721
2289
|
* - the form is submitting
|
1722
2290
|
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
1723
2291
|
* - the active tab is the published tab
|
1724
|
-
* - the user doesn't have the permission to create a new document
|
1725
|
-
* - the user doesn't have the permission to update the document
|
1726
2292
|
*/
|
1727
|
-
disabled: isSubmitting || !modified && !isCloning || activeTab === "published"
|
2293
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
1728
2294
|
label: formatMessage({
|
1729
|
-
id: "
|
2295
|
+
id: "global.save",
|
1730
2296
|
defaultMessage: "Save"
|
1731
2297
|
}),
|
1732
2298
|
onClick: async () => {
|
1733
2299
|
setSubmitting(true);
|
1734
2300
|
try {
|
1735
|
-
const { errors } = await validate(
|
2301
|
+
const { errors } = await validate(true, {
|
2302
|
+
status: "draft"
|
2303
|
+
});
|
1736
2304
|
if (errors) {
|
1737
2305
|
toggleNotification({
|
1738
2306
|
type: "danger",
|
@@ -1750,13 +2318,16 @@ const UpdateAction = ({
|
|
1750
2318
|
documentId: cloneMatch.params.origin,
|
1751
2319
|
params
|
1752
2320
|
},
|
1753
|
-
document
|
2321
|
+
transformData(document)
|
1754
2322
|
);
|
1755
2323
|
if ("data" in res) {
|
1756
|
-
navigate(
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
2324
|
+
navigate(
|
2325
|
+
{
|
2326
|
+
pathname: `../${res.data.documentId}`,
|
2327
|
+
search: rawQuery
|
2328
|
+
},
|
2329
|
+
{ relative: "path" }
|
2330
|
+
);
|
1760
2331
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1761
2332
|
setErrors(formatValidationErrors(res.error));
|
1762
2333
|
}
|
@@ -1768,7 +2339,7 @@ const UpdateAction = ({
|
|
1768
2339
|
documentId,
|
1769
2340
|
params
|
1770
2341
|
},
|
1771
|
-
document
|
2342
|
+
transformData(document)
|
1772
2343
|
);
|
1773
2344
|
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1774
2345
|
setErrors(formatValidationErrors(res.error));
|
@@ -1781,13 +2352,16 @@ const UpdateAction = ({
|
|
1781
2352
|
model,
|
1782
2353
|
params
|
1783
2354
|
},
|
1784
|
-
document
|
2355
|
+
transformData(document)
|
1785
2356
|
);
|
1786
2357
|
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1787
|
-
navigate(
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
2358
|
+
navigate(
|
2359
|
+
{
|
2360
|
+
pathname: `../${res.data.documentId}`,
|
2361
|
+
search: rawQuery
|
2362
|
+
},
|
2363
|
+
{ replace: true, relative: "path" }
|
2364
|
+
);
|
1791
2365
|
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1792
2366
|
setErrors(formatValidationErrors(res.error));
|
1793
2367
|
}
|
@@ -1803,7 +2377,7 @@ const UNPUBLISH_DRAFT_OPTIONS = {
|
|
1803
2377
|
KEEP: "keep",
|
1804
2378
|
DISCARD: "discard"
|
1805
2379
|
};
|
1806
|
-
const UnpublishAction = ({
|
2380
|
+
const UnpublishAction$1 = ({
|
1807
2381
|
activeTab,
|
1808
2382
|
documentId,
|
1809
2383
|
model,
|
@@ -1819,10 +2393,8 @@ const UnpublishAction = ({
|
|
1819
2393
|
const { toggleNotification } = strapiAdmin.useNotification();
|
1820
2394
|
const [shouldKeepDraft, setShouldKeepDraft] = React__namespace.useState(true);
|
1821
2395
|
const isDocumentModified = document?.status === "modified";
|
1822
|
-
const handleChange = (
|
1823
|
-
|
1824
|
-
setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1825
|
-
}
|
2396
|
+
const handleChange = (value) => {
|
2397
|
+
setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1826
2398
|
};
|
1827
2399
|
if (!schema?.options?.draftAndPublish) {
|
1828
2400
|
return null;
|
@@ -1833,7 +2405,7 @@ const UnpublishAction = ({
|
|
1833
2405
|
id: "app.utils.unpublish",
|
1834
2406
|
defaultMessage: "Unpublish"
|
1835
2407
|
}),
|
1836
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2408
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
1837
2409
|
onClick: async () => {
|
1838
2410
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1839
2411
|
if (!documentId) {
|
@@ -1866,45 +2438,30 @@ const UnpublishAction = ({
|
|
1866
2438
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "flex-start", direction: "column", gap: 6, children: [
|
1867
2439
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", direction: "column", gap: 2, children: [
|
1868
2440
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1869
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2441
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1870
2442
|
id: "content-manager.actions.unpublish.dialog.body",
|
1871
2443
|
defaultMessage: "Are you sure?"
|
1872
2444
|
}) })
|
1873
2445
|
] }),
|
1874
2446
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
1875
|
-
designSystem.
|
2447
|
+
designSystem.Radio.Group,
|
1876
2448
|
{
|
1877
|
-
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1881
|
-
|
2449
|
+
defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
|
2450
|
+
name: "discard-options",
|
2451
|
+
"aria-label": formatMessage({
|
2452
|
+
id: "content-manager.actions.unpublish.dialog.radio-label",
|
2453
|
+
defaultMessage: "Choose an option to unpublish the document."
|
2454
|
+
}),
|
2455
|
+
onValueChange: handleChange,
|
1882
2456
|
children: [
|
1883
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
1884
|
-
|
1885
|
-
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
1890
|
-
|
1891
|
-
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
1892
|
-
defaultMessage: "Keep draft"
|
1893
|
-
})
|
1894
|
-
}
|
1895
|
-
),
|
1896
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
1897
|
-
designSystem.Radio,
|
1898
|
-
{
|
1899
|
-
checked: !shouldKeepDraft,
|
1900
|
-
value: UNPUBLISH_DRAFT_OPTIONS.DISCARD,
|
1901
|
-
name: "discard-options",
|
1902
|
-
children: formatMessage({
|
1903
|
-
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
1904
|
-
defaultMessage: "Replace draft"
|
1905
|
-
})
|
1906
|
-
}
|
1907
|
-
)
|
2457
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
|
2458
|
+
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
2459
|
+
defaultMessage: "Keep draft"
|
2460
|
+
}) }),
|
2461
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
|
2462
|
+
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
2463
|
+
defaultMessage: "Replace draft"
|
2464
|
+
}) })
|
1908
2465
|
]
|
1909
2466
|
}
|
1910
2467
|
)
|
@@ -1937,7 +2494,7 @@ const UnpublishAction = ({
|
|
1937
2494
|
position: ["panel", "table-row"]
|
1938
2495
|
};
|
1939
2496
|
};
|
1940
|
-
UnpublishAction.type = "unpublish";
|
2497
|
+
UnpublishAction$1.type = "unpublish";
|
1941
2498
|
const DiscardAction = ({
|
1942
2499
|
activeTab,
|
1943
2500
|
documentId,
|
@@ -1960,7 +2517,7 @@ const DiscardAction = ({
|
|
1960
2517
|
id: "content-manager.actions.discard.label",
|
1961
2518
|
defaultMessage: "Discard changes"
|
1962
2519
|
}),
|
1963
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2520
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Cross, {}),
|
1964
2521
|
position: ["panel", "table-row"],
|
1965
2522
|
variant: "danger",
|
1966
2523
|
dialog: {
|
@@ -1971,7 +2528,7 @@ const DiscardAction = ({
|
|
1971
2528
|
}),
|
1972
2529
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
|
1973
2530
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1974
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2531
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1975
2532
|
id: "content-manager.actions.discard.dialog.body",
|
1976
2533
|
defaultMessage: "Are you sure?"
|
1977
2534
|
}) })
|
@@ -1988,12 +2545,7 @@ const DiscardAction = ({
|
|
1988
2545
|
};
|
1989
2546
|
};
|
1990
2547
|
DiscardAction.type = "discard";
|
1991
|
-
const
|
1992
|
-
path {
|
1993
|
-
fill: currentColor;
|
1994
|
-
}
|
1995
|
-
`;
|
1996
|
-
const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction, DiscardAction];
|
2548
|
+
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
1997
2549
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
1998
2550
|
const RelativeTime = React__namespace.forwardRef(
|
1999
2551
|
({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
|
@@ -2005,7 +2557,7 @@ const RelativeTime = React__namespace.forwardRef(
|
|
2005
2557
|
});
|
2006
2558
|
const unit = intervals.find((intervalUnit) => {
|
2007
2559
|
return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
|
2008
|
-
});
|
2560
|
+
}) ?? "seconds";
|
2009
2561
|
const relativeTime = dateFns.isPast(timestamp) ? -interval[unit] : interval[unit];
|
2010
2562
|
const customInterval = customIntervals.find(
|
2011
2563
|
(custom) => interval[custom.unit] < custom.threshold
|
@@ -2039,34 +2591,34 @@ const getDisplayName = ({
|
|
2039
2591
|
return email ?? "";
|
2040
2592
|
};
|
2041
2593
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2042
|
-
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2043
|
-
const statusVariant = status === "draft" ? "
|
2044
|
-
|
2594
|
+
const DocumentStatus = ({ status = "draft", size = "S", ...restProps }) => {
|
2595
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2596
|
+
const { formatMessage } = reactIntl.useIntl();
|
2597
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Status, { ...restProps, size, variant: statusVariant, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: formatMessage({
|
2598
|
+
id: `content-manager.containers.List.${status}`,
|
2599
|
+
defaultMessage: capitalise(status)
|
2600
|
+
}) }) });
|
2045
2601
|
};
|
2046
2602
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2047
2603
|
const { formatMessage } = reactIntl.useIntl();
|
2048
2604
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2605
|
+
const params = reactRouterDom.useParams();
|
2049
2606
|
const title = isCreating ? formatMessage({
|
2050
2607
|
id: "content-manager.containers.edit.title.new",
|
2051
2608
|
defaultMessage: "Create an entry"
|
2052
2609
|
}) : documentTitle;
|
2053
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2054
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
2055
|
-
|
2056
|
-
designSystem.Flex,
|
2610
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2611
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2612
|
+
strapiAdmin.BackButton,
|
2057
2613
|
{
|
2058
|
-
|
2059
|
-
justifyContent: "space-between",
|
2060
|
-
paddingTop: 1,
|
2061
|
-
gap: "80px",
|
2062
|
-
alignItems: "flex-start",
|
2063
|
-
children: [
|
2064
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", as: "h1", children: title }),
|
2065
|
-
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2066
|
-
]
|
2614
|
+
fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
|
2067
2615
|
}
|
2068
2616
|
),
|
2069
|
-
|
2617
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2618
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: title }),
|
2619
|
+
/* @__PURE__ */ jsxRuntime.jsx(HeaderToolbar, {})
|
2620
|
+
] }),
|
2621
|
+
status ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2070
2622
|
] });
|
2071
2623
|
};
|
2072
2624
|
const HeaderToolbar = () => {
|
@@ -2149,12 +2701,12 @@ const Information = ({ activeTab }) => {
|
|
2149
2701
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2150
2702
|
label: formatMessage({
|
2151
2703
|
id: "content-manager.containers.edit.information.last-published.label",
|
2152
|
-
defaultMessage: "
|
2704
|
+
defaultMessage: "Published"
|
2153
2705
|
}),
|
2154
2706
|
value: formatMessage(
|
2155
2707
|
{
|
2156
2708
|
id: "content-manager.containers.edit.information.last-published.value",
|
2157
|
-
defaultMessage: `
|
2709
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2158
2710
|
},
|
2159
2711
|
{
|
2160
2712
|
time: /* @__PURE__ */ jsxRuntime.jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2167,12 +2719,12 @@ const Information = ({ activeTab }) => {
|
|
2167
2719
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2168
2720
|
label: formatMessage({
|
2169
2721
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2170
|
-
defaultMessage: "
|
2722
|
+
defaultMessage: "Updated"
|
2171
2723
|
}),
|
2172
2724
|
value: formatMessage(
|
2173
2725
|
{
|
2174
2726
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2175
|
-
defaultMessage: `
|
2727
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2176
2728
|
},
|
2177
2729
|
{
|
2178
2730
|
time: /* @__PURE__ */ jsxRuntime.jsx(
|
@@ -2190,12 +2742,12 @@ const Information = ({ activeTab }) => {
|
|
2190
2742
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2191
2743
|
label: formatMessage({
|
2192
2744
|
id: "content-manager.containers.edit.information.document.label",
|
2193
|
-
defaultMessage: "
|
2745
|
+
defaultMessage: "Created"
|
2194
2746
|
}),
|
2195
2747
|
value: formatMessage(
|
2196
2748
|
{
|
2197
2749
|
id: "content-manager.containers.edit.information.document.value",
|
2198
|
-
defaultMessage: `
|
2750
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2199
2751
|
},
|
2200
2752
|
{
|
2201
2753
|
time: /* @__PURE__ */ jsxRuntime.jsx(
|
@@ -2218,7 +2770,7 @@ const Information = ({ activeTab }) => {
|
|
2218
2770
|
borderColor: "neutral150",
|
2219
2771
|
direction: "column",
|
2220
2772
|
marginTop: 2,
|
2221
|
-
|
2773
|
+
tag: "dl",
|
2222
2774
|
padding: 5,
|
2223
2775
|
gap: 3,
|
2224
2776
|
alignItems: "flex-start",
|
@@ -2226,32 +2778,84 @@ const Information = ({ activeTab }) => {
|
|
2226
2778
|
marginRight: "-0.4rem",
|
2227
2779
|
width: "calc(100% + 8px)",
|
2228
2780
|
children: information.map((info) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, direction: "column", alignItems: "flex-start", children: [
|
2229
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2230
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2781
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
|
2782
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "dd", variant: "pi", textColor: "neutral600", children: info.value })
|
2231
2783
|
] }, info.label))
|
2232
2784
|
}
|
2233
2785
|
);
|
2234
2786
|
};
|
2235
2787
|
const HeaderActions = ({ actions: actions2 }) => {
|
2236
|
-
|
2237
|
-
|
2788
|
+
const [dialogId, setDialogId] = React__namespace.useState(null);
|
2789
|
+
const handleClick = (action) => async (e) => {
|
2790
|
+
if (!("options" in action)) {
|
2791
|
+
const { onClick = () => false, dialog, id } = action;
|
2792
|
+
const muteDialog = await onClick(e);
|
2793
|
+
if (dialog && !muteDialog) {
|
2794
|
+
e.preventDefault();
|
2795
|
+
setDialogId(id);
|
2796
|
+
}
|
2797
|
+
}
|
2798
|
+
};
|
2799
|
+
const handleClose = () => {
|
2800
|
+
setDialogId(null);
|
2801
|
+
};
|
2802
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, children: actions2.map((action) => {
|
2803
|
+
if (action.options) {
|
2238
2804
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
2239
2805
|
designSystem.SingleSelect,
|
2240
2806
|
{
|
2241
2807
|
size: "S",
|
2242
|
-
disabled: action.disabled,
|
2243
|
-
"aria-label": action.label,
|
2244
2808
|
onChange: action.onSelect,
|
2245
|
-
|
2809
|
+
"aria-label": action.label,
|
2810
|
+
...action,
|
2246
2811
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { ...option, children: label }, option.value))
|
2247
2812
|
},
|
2248
2813
|
action.id
|
2249
2814
|
);
|
2250
2815
|
} else {
|
2251
|
-
|
2816
|
+
if (action.type === "icon") {
|
2817
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Fragment, { children: [
|
2818
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
2819
|
+
designSystem.IconButton,
|
2820
|
+
{
|
2821
|
+
disabled: action.disabled,
|
2822
|
+
label: action.label,
|
2823
|
+
size: "S",
|
2824
|
+
onClick: handleClick(action),
|
2825
|
+
children: action.icon
|
2826
|
+
}
|
2827
|
+
),
|
2828
|
+
action.dialog ? /* @__PURE__ */ jsxRuntime.jsx(
|
2829
|
+
HeaderActionDialog,
|
2830
|
+
{
|
2831
|
+
...action.dialog,
|
2832
|
+
isOpen: dialogId === action.id,
|
2833
|
+
onClose: handleClose
|
2834
|
+
}
|
2835
|
+
) : null
|
2836
|
+
] }, action.id);
|
2837
|
+
}
|
2252
2838
|
}
|
2253
2839
|
}) });
|
2254
2840
|
};
|
2841
|
+
const HeaderActionDialog = ({
|
2842
|
+
onClose,
|
2843
|
+
onCancel,
|
2844
|
+
title,
|
2845
|
+
content: Content,
|
2846
|
+
isOpen
|
2847
|
+
}) => {
|
2848
|
+
const handleClose = async () => {
|
2849
|
+
if (onCancel) {
|
2850
|
+
await onCancel();
|
2851
|
+
}
|
2852
|
+
onClose();
|
2853
|
+
};
|
2854
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
2855
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: title }),
|
2856
|
+
typeof Content === "function" ? /* @__PURE__ */ jsxRuntime.jsx(Content, { onClose: handleClose }) : Content
|
2857
|
+
] }) });
|
2858
|
+
};
|
2255
2859
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2256
2860
|
const navigate = reactRouterDom.useNavigate();
|
2257
2861
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2260,7 +2864,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2260
2864
|
id: "app.links.configure-view",
|
2261
2865
|
defaultMessage: "Configure the view"
|
2262
2866
|
}),
|
2263
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2867
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ListPlus, {}),
|
2264
2868
|
onClick: () => {
|
2265
2869
|
navigate(`../${collectionType}/${model}/configurations/edit`);
|
2266
2870
|
},
|
@@ -2268,11 +2872,6 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2268
2872
|
};
|
2269
2873
|
};
|
2270
2874
|
ConfigureTheViewAction.type = "configure-the-view";
|
2271
|
-
const StyledCog = styled__default.default(Icons.Cog)`
|
2272
|
-
path {
|
2273
|
-
fill: currentColor;
|
2274
|
-
}
|
2275
|
-
`;
|
2276
2875
|
const EditTheModelAction = ({ model }) => {
|
2277
2876
|
const navigate = reactRouterDom.useNavigate();
|
2278
2877
|
const { formatMessage } = reactIntl.useIntl();
|
@@ -2281,7 +2880,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2281
2880
|
id: "content-manager.link-to-ctb",
|
2282
2881
|
defaultMessage: "Edit the model"
|
2283
2882
|
}),
|
2284
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
2883
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, {}),
|
2285
2884
|
onClick: () => {
|
2286
2885
|
navigate(`/plugins/content-type-builder/content-types/${model}`);
|
2287
2886
|
},
|
@@ -2289,12 +2888,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2289
2888
|
};
|
2290
2889
|
};
|
2291
2890
|
EditTheModelAction.type = "edit-the-model";
|
2292
|
-
const
|
2293
|
-
path {
|
2294
|
-
fill: currentColor;
|
2295
|
-
}
|
2296
|
-
`;
|
2297
|
-
const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
2891
|
+
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2298
2892
|
const navigate = reactRouterDom.useNavigate();
|
2299
2893
|
const { formatMessage } = reactIntl.useIntl();
|
2300
2894
|
const listViewPathMatch = reactRouterDom.useMatch(LIST_PATH);
|
@@ -2302,13 +2896,17 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2302
2896
|
const { delete: deleteAction } = useDocumentActions();
|
2303
2897
|
const { toggleNotification } = strapiAdmin.useNotification();
|
2304
2898
|
const setSubmitting = strapiAdmin.useForm("DeleteAction", (state) => state.setSubmitting);
|
2899
|
+
const isLocalized = document?.locale != null;
|
2305
2900
|
return {
|
2306
2901
|
disabled: !canDelete || !document,
|
2307
|
-
label: formatMessage(
|
2308
|
-
|
2309
|
-
|
2310
|
-
|
2311
|
-
|
2902
|
+
label: formatMessage(
|
2903
|
+
{
|
2904
|
+
id: "content-manager.actions.delete.label",
|
2905
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2906
|
+
},
|
2907
|
+
{ isLocalized }
|
2908
|
+
),
|
2909
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Trash, {}),
|
2312
2910
|
dialog: {
|
2313
2911
|
type: "dialog",
|
2314
2912
|
title: formatMessage({
|
@@ -2317,7 +2915,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2317
2915
|
}),
|
2318
2916
|
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
|
2319
2917
|
/* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2320
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
2918
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2321
2919
|
id: "content-manager.actions.delete.dialog.body",
|
2322
2920
|
defaultMessage: "Are you sure?"
|
2323
2921
|
}) })
|
@@ -2362,13 +2960,8 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2362
2960
|
position: ["header", "table-row"]
|
2363
2961
|
};
|
2364
2962
|
};
|
2365
|
-
DeleteAction.type = "delete";
|
2366
|
-
const
|
2367
|
-
path {
|
2368
|
-
fill: currentColor;
|
2369
|
-
}
|
2370
|
-
`;
|
2371
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction];
|
2963
|
+
DeleteAction$1.type = "delete";
|
2964
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2372
2965
|
const Panels = () => {
|
2373
2966
|
const isCloning = reactRouterDom.useMatch(CLONE_PATH) !== null;
|
2374
2967
|
const [
|
@@ -2402,7 +2995,7 @@ const ActionsPanel = () => {
|
|
2402
2995
|
return {
|
2403
2996
|
title: formatMessage({
|
2404
2997
|
id: "content-manager.containers.edit.panels.default.title",
|
2405
|
-
defaultMessage: "
|
2998
|
+
defaultMessage: "Entry"
|
2406
2999
|
}),
|
2407
3000
|
content: /* @__PURE__ */ jsxRuntime.jsx(ActionsPanelContent, {})
|
2408
3001
|
};
|
@@ -2442,7 +3035,7 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
|
2442
3035
|
designSystem.Flex,
|
2443
3036
|
{
|
2444
3037
|
ref,
|
2445
|
-
|
3038
|
+
tag: "aside",
|
2446
3039
|
"aria-labelledby": "additional-information",
|
2447
3040
|
background: "neutral0",
|
2448
3041
|
borderColor: "neutral150",
|
@@ -2457,24 +3050,601 @@ const Panel = React__namespace.forwardRef(({ children, title }, ref) => {
|
|
2457
3050
|
justifyContent: "stretch",
|
2458
3051
|
alignItems: "flex-start",
|
2459
3052
|
children: [
|
2460
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
3053
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", textColor: "neutral600", children: title }),
|
2461
3054
|
children
|
2462
3055
|
]
|
2463
3056
|
}
|
2464
3057
|
);
|
2465
3058
|
});
|
2466
|
-
const
|
2467
|
-
|
3059
|
+
const ConfirmBulkActionDialog = ({
|
3060
|
+
onToggleDialog,
|
3061
|
+
isOpen = false,
|
3062
|
+
dialogBody,
|
3063
|
+
endAction
|
3064
|
+
}) => {
|
2468
3065
|
const { formatMessage } = reactIntl.useIntl();
|
2469
|
-
|
2470
|
-
|
2471
|
-
|
2472
|
-
|
2473
|
-
|
2474
|
-
|
2475
|
-
|
2476
|
-
|
2477
|
-
}
|
3066
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
3067
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
|
3068
|
+
id: "app.components.ConfirmDialog.title",
|
3069
|
+
defaultMessage: "Confirmation"
|
3070
|
+
}) }),
|
3071
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3072
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3073
|
+
dialogBody
|
3074
|
+
] }) }),
|
3075
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
3076
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
|
3077
|
+
id: "app.components.Button.cancel",
|
3078
|
+
defaultMessage: "Cancel"
|
3079
|
+
}) }) }),
|
3080
|
+
endAction
|
3081
|
+
] })
|
3082
|
+
] }) });
|
3083
|
+
};
|
3084
|
+
const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
|
3085
|
+
const ConfirmDialogPublishAll = ({
|
3086
|
+
isOpen,
|
3087
|
+
onToggleDialog,
|
3088
|
+
isConfirmButtonLoading = false,
|
3089
|
+
onConfirm
|
3090
|
+
}) => {
|
3091
|
+
const { formatMessage } = reactIntl.useIntl();
|
3092
|
+
const selectedEntries = strapiAdmin.useTable("ConfirmDialogPublishAll", (state) => state.selectedRows);
|
3093
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
3094
|
+
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler(getTranslation);
|
3095
|
+
const { model, schema } = useDoc();
|
3096
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3097
|
+
const enableDraftRelationsCount = false;
|
3098
|
+
const {
|
3099
|
+
data: countDraftRelations = 0,
|
3100
|
+
isLoading,
|
3101
|
+
error
|
3102
|
+
} = useGetManyDraftRelationCountQuery(
|
3103
|
+
{
|
3104
|
+
model,
|
3105
|
+
documentIds: selectedEntries.map((entry) => entry.documentId),
|
3106
|
+
locale: query?.plugins?.i18n?.locale
|
3107
|
+
},
|
3108
|
+
{
|
3109
|
+
skip: !enableDraftRelationsCount
|
3110
|
+
}
|
3111
|
+
);
|
3112
|
+
React__namespace.useEffect(() => {
|
3113
|
+
if (error) {
|
3114
|
+
toggleNotification({ type: "danger", message: formatAPIError(error) });
|
3115
|
+
}
|
3116
|
+
}, [error, formatAPIError, toggleNotification]);
|
3117
|
+
if (error) {
|
3118
|
+
return null;
|
3119
|
+
}
|
3120
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
3121
|
+
ConfirmBulkActionDialog,
|
3122
|
+
{
|
3123
|
+
isOpen: isOpen && !isLoading,
|
3124
|
+
onToggleDialog,
|
3125
|
+
dialogBody: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
3126
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: [
|
3127
|
+
countDraftRelations > 0 && formatMessage(
|
3128
|
+
{
|
3129
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
3130
|
+
defaultMessage: "<b>{count} {count, plural, one { relation } other { relations } } out of {entities} { entities, plural, one { entry } other { entries } } {count, plural, one { is } other { are } }</b> not published yet and might lead to unexpected behavior. "
|
3131
|
+
},
|
3132
|
+
{
|
3133
|
+
b: BoldChunk$1,
|
3134
|
+
count: countDraftRelations,
|
3135
|
+
entities: selectedEntries.length
|
3136
|
+
}
|
3137
|
+
),
|
3138
|
+
formatMessage({
|
3139
|
+
id: getTranslation("popUpWarning.bodyMessage.contentType.publish.all"),
|
3140
|
+
defaultMessage: "Are you sure you want to publish these entries?"
|
3141
|
+
})
|
3142
|
+
] }),
|
3143
|
+
schema?.pluginOptions && "i18n" in schema.pluginOptions && schema?.pluginOptions.i18n && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", textAlign: "center", children: formatMessage(
|
3144
|
+
{
|
3145
|
+
id: getTranslation("Settings.list.actions.publishAdditionalInfos"),
|
3146
|
+
defaultMessage: "This will publish the active locale versions <em>(from Internationalization)</em>"
|
3147
|
+
},
|
3148
|
+
{
|
3149
|
+
em: Emphasis
|
3150
|
+
}
|
3151
|
+
) })
|
3152
|
+
] }),
|
3153
|
+
endAction: /* @__PURE__ */ jsxRuntime.jsx(
|
3154
|
+
designSystem.Button,
|
3155
|
+
{
|
3156
|
+
onClick: onConfirm,
|
3157
|
+
variant: "secondary",
|
3158
|
+
startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Check, {}),
|
3159
|
+
loading: isConfirmButtonLoading,
|
3160
|
+
children: formatMessage({
|
3161
|
+
id: "app.utils.publish",
|
3162
|
+
defaultMessage: "Publish"
|
3163
|
+
})
|
3164
|
+
}
|
3165
|
+
)
|
3166
|
+
}
|
3167
|
+
);
|
3168
|
+
};
|
3169
|
+
const TypographyMaxWidth = styledComponents.styled(designSystem.Typography)`
|
3170
|
+
max-width: 300px;
|
3171
|
+
`;
|
3172
|
+
const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
3173
|
+
const messages = [];
|
3174
|
+
Object.entries(errors).forEach(([key, value]) => {
|
3175
|
+
const currentKey = parentKey ? `${parentKey}.${key}` : key;
|
3176
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
3177
|
+
if ("id" in value && "defaultMessage" in value) {
|
3178
|
+
messages.push(
|
3179
|
+
formatMessage(
|
3180
|
+
{
|
3181
|
+
id: `${value.id}.withField`,
|
3182
|
+
defaultMessage: value.defaultMessage
|
3183
|
+
},
|
3184
|
+
{ field: currentKey }
|
3185
|
+
)
|
3186
|
+
);
|
3187
|
+
} else {
|
3188
|
+
messages.push(
|
3189
|
+
...formatErrorMessages(
|
3190
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3191
|
+
value,
|
3192
|
+
currentKey,
|
3193
|
+
formatMessage
|
3194
|
+
)
|
3195
|
+
);
|
3196
|
+
}
|
3197
|
+
} else {
|
3198
|
+
messages.push(
|
3199
|
+
formatMessage(
|
3200
|
+
{
|
3201
|
+
id: `${value}.withField`,
|
3202
|
+
defaultMessage: value
|
3203
|
+
},
|
3204
|
+
{ field: currentKey }
|
3205
|
+
)
|
3206
|
+
);
|
3207
|
+
}
|
3208
|
+
});
|
3209
|
+
return messages;
|
3210
|
+
};
|
3211
|
+
const EntryValidationText = ({ validationErrors, status }) => {
|
3212
|
+
const { formatMessage } = reactIntl.useIntl();
|
3213
|
+
if (validationErrors) {
|
3214
|
+
const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
|
3215
|
+
" "
|
3216
|
+
);
|
3217
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3218
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.CrossCircle, { fill: "danger600" }),
|
3219
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
|
3220
|
+
] });
|
3221
|
+
}
|
3222
|
+
if (status === "published") {
|
3223
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3224
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
|
3225
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
|
3226
|
+
id: "content-manager.bulk-publish.already-published",
|
3227
|
+
defaultMessage: "Already Published"
|
3228
|
+
}) })
|
3229
|
+
] });
|
3230
|
+
}
|
3231
|
+
if (status === "modified") {
|
3232
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3233
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.ArrowsCounterClockwise, { fill: "alternative600" }),
|
3234
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3235
|
+
id: "content-manager.bulk-publish.modified",
|
3236
|
+
defaultMessage: "Ready to publish changes"
|
3237
|
+
}) })
|
3238
|
+
] });
|
3239
|
+
}
|
3240
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3241
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icons.CheckCircle, { fill: "success600" }),
|
3242
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3243
|
+
id: "app.utils.ready-to-publish",
|
3244
|
+
defaultMessage: "Ready to publish"
|
3245
|
+
}) })
|
3246
|
+
] });
|
3247
|
+
};
|
3248
|
+
const TABLE_HEADERS = [
|
3249
|
+
{ name: "id", label: "id" },
|
3250
|
+
{ name: "name", label: "name" },
|
3251
|
+
{ name: "status", label: "status" },
|
3252
|
+
{ name: "publicationStatus", label: "Publication status" }
|
3253
|
+
];
|
3254
|
+
const SelectedEntriesTableContent = ({
|
3255
|
+
isPublishing,
|
3256
|
+
rowsToDisplay = [],
|
3257
|
+
entriesToPublish = [],
|
3258
|
+
validationErrors = {}
|
3259
|
+
}) => {
|
3260
|
+
const { pathname } = reactRouterDom.useLocation();
|
3261
|
+
const { formatMessage } = reactIntl.useIntl();
|
3262
|
+
const {
|
3263
|
+
list: {
|
3264
|
+
settings: { mainField }
|
3265
|
+
}
|
3266
|
+
} = useDocLayout();
|
3267
|
+
const shouldDisplayMainField = mainField != null && mainField !== "id";
|
3268
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Content, { children: [
|
3269
|
+
/* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Head, { children: [
|
3270
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCheckboxCell, {}),
|
3271
|
+
TABLE_HEADERS.filter((head) => head.name !== "name" || shouldDisplayMainField).map(
|
3272
|
+
(head) => /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.HeaderCell, { ...head }, head.name)
|
3273
|
+
)
|
3274
|
+
] }),
|
3275
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Loading, {}),
|
3276
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Body, { children: rowsToDisplay.map((row, index2) => /* @__PURE__ */ jsxRuntime.jsxs(strapiAdmin.Table.Row, { children: [
|
3277
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.CheckboxCell, { id: row.id }),
|
3278
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row.id }) }),
|
3279
|
+
shouldDisplayMainField && /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: row[mainField] }) }),
|
3280
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(DocumentStatus, { status: row.status, maxWidth: "min-content" }) }),
|
3281
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: isPublishing && entriesToPublish.includes(row.documentId) ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3282
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
|
3283
|
+
id: "content-manager.success.record.publishing",
|
3284
|
+
defaultMessage: "Publishing..."
|
3285
|
+
}) }),
|
3286
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { small: true })
|
3287
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
3288
|
+
EntryValidationText,
|
3289
|
+
{
|
3290
|
+
validationErrors: validationErrors[row.documentId],
|
3291
|
+
status: row.status
|
3292
|
+
}
|
3293
|
+
) }),
|
3294
|
+
/* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
3295
|
+
designSystem.IconButton,
|
3296
|
+
{
|
3297
|
+
tag: reactRouterDom.Link,
|
3298
|
+
to: {
|
3299
|
+
pathname: `${pathname}/${row.documentId}`,
|
3300
|
+
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3301
|
+
},
|
3302
|
+
state: { from: pathname },
|
3303
|
+
label: formatMessage({
|
3304
|
+
id: "content-manager.bulk-publish.edit",
|
3305
|
+
defaultMessage: "Edit"
|
3306
|
+
}),
|
3307
|
+
target: "_blank",
|
3308
|
+
marginLeft: "auto",
|
3309
|
+
variant: "ghost",
|
3310
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icons.Pencil, { width: "1.6rem", height: "1.6rem" })
|
3311
|
+
}
|
3312
|
+
) }) })
|
3313
|
+
] }, row.id)) })
|
3314
|
+
] });
|
3315
|
+
};
|
3316
|
+
const BoldChunk = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: chunks });
|
3317
|
+
const SelectedEntriesModalContent = ({
|
3318
|
+
listViewSelectedEntries,
|
3319
|
+
toggleModal,
|
3320
|
+
setListViewSelectedDocuments,
|
3321
|
+
model
|
3322
|
+
}) => {
|
3323
|
+
const { formatMessage } = reactIntl.useIntl();
|
3324
|
+
const { schema, components } = useContentTypeSchema(model);
|
3325
|
+
const documentIds = listViewSelectedEntries.map(({ documentId }) => documentId);
|
3326
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3327
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
3328
|
+
const { data, isLoading, isFetching, refetch } = useGetAllDocumentsQuery(
|
3329
|
+
{
|
3330
|
+
model,
|
3331
|
+
params: {
|
3332
|
+
page: "1",
|
3333
|
+
pageSize: documentIds.length.toString(),
|
3334
|
+
sort: query.sort,
|
3335
|
+
filters: {
|
3336
|
+
documentId: {
|
3337
|
+
$in: documentIds
|
3338
|
+
}
|
3339
|
+
},
|
3340
|
+
locale: query.plugins?.i18n?.locale
|
3341
|
+
}
|
3342
|
+
},
|
3343
|
+
{
|
3344
|
+
selectFromResult: ({ data: data2, ...restRes }) => ({ data: data2?.results ?? [], ...restRes })
|
3345
|
+
}
|
3346
|
+
);
|
3347
|
+
const { rows, validationErrors } = React__namespace.useMemo(() => {
|
3348
|
+
if (data.length > 0 && schema) {
|
3349
|
+
const validate = createYupSchema(
|
3350
|
+
schema.attributes,
|
3351
|
+
components,
|
3352
|
+
// Since this is the "Publish" action, the validation
|
3353
|
+
// schema must enforce the rules for published entities
|
3354
|
+
{ status: "published" }
|
3355
|
+
);
|
3356
|
+
const validationErrors2 = {};
|
3357
|
+
const rows2 = data.map((entry) => {
|
3358
|
+
try {
|
3359
|
+
validate.validateSync(entry, { abortEarly: false });
|
3360
|
+
return entry;
|
3361
|
+
} catch (e) {
|
3362
|
+
if (e instanceof yup.ValidationError) {
|
3363
|
+
validationErrors2[entry.documentId] = strapiAdmin.getYupValidationErrors(e);
|
3364
|
+
}
|
3365
|
+
return entry;
|
3366
|
+
}
|
3367
|
+
});
|
3368
|
+
return { rows: rows2, validationErrors: validationErrors2 };
|
3369
|
+
}
|
3370
|
+
return {
|
3371
|
+
rows: [],
|
3372
|
+
validationErrors: {}
|
3373
|
+
};
|
3374
|
+
}, [components, data, schema]);
|
3375
|
+
const [publishedCount, setPublishedCount] = React__namespace.useState(0);
|
3376
|
+
const [isDialogOpen, setIsDialogOpen] = React__namespace.useState(false);
|
3377
|
+
const { publishMany: bulkPublishAction } = useDocumentActions();
|
3378
|
+
const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
|
3379
|
+
const selectedRows = strapiAdmin.useTable("publishAction", (state) => state.selectedRows);
|
3380
|
+
const selectedEntries = rows.filter(
|
3381
|
+
(entry) => selectedRows.some((selectedEntry) => selectedEntry.documentId === entry.documentId)
|
3382
|
+
);
|
3383
|
+
const entriesToPublish = selectedEntries.filter((entry) => !validationErrors[entry.documentId]).map((entry) => entry.documentId);
|
3384
|
+
const selectedEntriesWithErrorsCount = selectedEntries.filter(
|
3385
|
+
({ documentId }) => validationErrors[documentId]
|
3386
|
+
).length;
|
3387
|
+
const selectedEntriesPublished = selectedEntries.filter(
|
3388
|
+
({ status }) => status === "published"
|
3389
|
+
).length;
|
3390
|
+
const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublished;
|
3391
|
+
const toggleDialog = () => setIsDialogOpen((prev) => !prev);
|
3392
|
+
const handleConfirmBulkPublish = async () => {
|
3393
|
+
toggleDialog();
|
3394
|
+
const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
|
3395
|
+
if (!("error" in res)) {
|
3396
|
+
setPublishedCount(res.count);
|
3397
|
+
const unpublishedEntries = rows.filter((row) => {
|
3398
|
+
return !entriesToPublish.includes(row.documentId);
|
3399
|
+
});
|
3400
|
+
setListViewSelectedDocuments(unpublishedEntries);
|
3401
|
+
}
|
3402
|
+
};
|
3403
|
+
const getFormattedCountMessage = () => {
|
3404
|
+
if (publishedCount) {
|
3405
|
+
return formatMessage(
|
3406
|
+
{
|
3407
|
+
id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
|
3408
|
+
defaultMessage: "<b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} published. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
|
3409
|
+
},
|
3410
|
+
{
|
3411
|
+
publishedCount,
|
3412
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3413
|
+
b: BoldChunk
|
3414
|
+
}
|
3415
|
+
);
|
3416
|
+
}
|
3417
|
+
return formatMessage(
|
3418
|
+
{
|
3419
|
+
id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
|
3420
|
+
defaultMessage: "<b>{alreadyPublishedCount}</b> {alreadyPublishedCount, plural, =0 {entries} one {entry} other {entries}} already published. <b>{readyToPublishCount}</b> {readyToPublishCount, plural, =0 {entries} one {entry} other {entries}} ready to publish. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
|
3421
|
+
},
|
3422
|
+
{
|
3423
|
+
readyToPublishCount: selectedEntriesWithNoErrorsCount,
|
3424
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3425
|
+
alreadyPublishedCount: selectedEntriesPublished,
|
3426
|
+
b: BoldChunk
|
3427
|
+
}
|
3428
|
+
);
|
3429
|
+
};
|
3430
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
3431
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
|
3432
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: getFormattedCountMessage() }),
|
3433
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 5, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3434
|
+
SelectedEntriesTableContent,
|
3435
|
+
{
|
3436
|
+
isPublishing: isSubmittingForm,
|
3437
|
+
rowsToDisplay: rows,
|
3438
|
+
entriesToPublish,
|
3439
|
+
validationErrors
|
3440
|
+
}
|
3441
|
+
) })
|
3442
|
+
] }),
|
3443
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
3444
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
|
3445
|
+
id: "app.components.Button.cancel",
|
3446
|
+
defaultMessage: "Cancel"
|
3447
|
+
}) }),
|
3448
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
3449
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
|
3450
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3451
|
+
designSystem.Button,
|
3452
|
+
{
|
3453
|
+
onClick: toggleDialog,
|
3454
|
+
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
|
3455
|
+
loading: isSubmittingForm,
|
3456
|
+
children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
|
3457
|
+
}
|
3458
|
+
)
|
3459
|
+
] })
|
3460
|
+
] }),
|
3461
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
3462
|
+
ConfirmDialogPublishAll,
|
3463
|
+
{
|
3464
|
+
isOpen: isDialogOpen,
|
3465
|
+
onToggleDialog: toggleDialog,
|
3466
|
+
isConfirmButtonLoading: isSubmittingForm,
|
3467
|
+
onConfirm: handleConfirmBulkPublish
|
3468
|
+
}
|
3469
|
+
)
|
3470
|
+
] });
|
3471
|
+
};
|
3472
|
+
const PublishAction = ({ documents, model }) => {
|
3473
|
+
const { formatMessage } = reactIntl.useIntl();
|
3474
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3475
|
+
const showPublishButton = hasPublishPermission && documents.some(({ status }) => status !== "published");
|
3476
|
+
const setListViewSelectedDocuments = strapiAdmin.useTable("publishAction", (state) => state.selectRow);
|
3477
|
+
const refetchList = () => {
|
3478
|
+
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3479
|
+
};
|
3480
|
+
if (!showPublishButton)
|
3481
|
+
return null;
|
3482
|
+
return {
|
3483
|
+
actionType: "publish",
|
3484
|
+
variant: "tertiary",
|
3485
|
+
label: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" }),
|
3486
|
+
dialog: {
|
3487
|
+
type: "modal",
|
3488
|
+
title: formatMessage({
|
3489
|
+
id: getTranslation("containers.ListPage.selectedEntriesModal.title"),
|
3490
|
+
defaultMessage: "Publish entries"
|
3491
|
+
}),
|
3492
|
+
content: ({ onClose }) => {
|
3493
|
+
return /* @__PURE__ */ jsxRuntime.jsx(strapiAdmin.Table.Root, { rows: documents, defaultSelectedRows: documents, headers: TABLE_HEADERS, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3494
|
+
SelectedEntriesModalContent,
|
3495
|
+
{
|
3496
|
+
listViewSelectedEntries: documents,
|
3497
|
+
toggleModal: () => {
|
3498
|
+
onClose();
|
3499
|
+
refetchList();
|
3500
|
+
},
|
3501
|
+
setListViewSelectedDocuments,
|
3502
|
+
model
|
3503
|
+
}
|
3504
|
+
) });
|
3505
|
+
},
|
3506
|
+
onClose: () => {
|
3507
|
+
refetchList();
|
3508
|
+
}
|
3509
|
+
}
|
3510
|
+
};
|
3511
|
+
};
|
3512
|
+
const BulkActionsRenderer = () => {
|
3513
|
+
const plugins = strapiAdmin.useStrapiApp("BulkActionsRenderer", (state) => state.plugins);
|
3514
|
+
const { model, collectionType } = useDoc();
|
3515
|
+
const { selectedRows } = strapiAdmin.useTable("BulkActionsRenderer", (state) => state);
|
3516
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
3517
|
+
strapiAdmin.DescriptionComponentRenderer,
|
3518
|
+
{
|
3519
|
+
props: {
|
3520
|
+
model,
|
3521
|
+
collectionType,
|
3522
|
+
documents: selectedRows
|
3523
|
+
},
|
3524
|
+
descriptions: plugins["content-manager"].apis.getBulkActions(),
|
3525
|
+
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsxRuntime.jsx(DocumentActionButton, { ...action }, action.id))
|
3526
|
+
}
|
3527
|
+
) });
|
3528
|
+
};
|
3529
|
+
const DeleteAction = ({ documents, model }) => {
|
3530
|
+
const { formatMessage } = reactIntl.useIntl();
|
3531
|
+
const { schema: contentType } = useDoc();
|
3532
|
+
const selectRow = strapiAdmin.useTable("DeleteAction", (state) => state.selectRow);
|
3533
|
+
const hasI18nEnabled = Boolean(contentType?.pluginOptions?.i18n);
|
3534
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3535
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
3536
|
+
const hasDeletePermission = useDocumentRBAC("deleteAction", (state) => state.canDelete);
|
3537
|
+
const { deleteMany: bulkDeleteAction } = useDocumentActions();
|
3538
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3539
|
+
const handleConfirmBulkDelete = async () => {
|
3540
|
+
const res = await bulkDeleteAction({
|
3541
|
+
documentIds,
|
3542
|
+
model,
|
3543
|
+
params
|
3544
|
+
});
|
3545
|
+
if (!("error" in res)) {
|
3546
|
+
selectRow([]);
|
3547
|
+
}
|
3548
|
+
};
|
3549
|
+
if (!hasDeletePermission)
|
3550
|
+
return null;
|
3551
|
+
return {
|
3552
|
+
variant: "danger-light",
|
3553
|
+
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
3554
|
+
dialog: {
|
3555
|
+
type: "dialog",
|
3556
|
+
title: formatMessage({
|
3557
|
+
id: "app.components.ConfirmDialog.title",
|
3558
|
+
defaultMessage: "Confirmation"
|
3559
|
+
}),
|
3560
|
+
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3561
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3562
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3563
|
+
id: "popUpWarning.bodyMessage.contentType.delete.all",
|
3564
|
+
defaultMessage: "Are you sure you want to delete these entries?"
|
3565
|
+
}) }),
|
3566
|
+
hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
|
3567
|
+
{
|
3568
|
+
id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
|
3569
|
+
defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
|
3570
|
+
},
|
3571
|
+
{
|
3572
|
+
em: Emphasis
|
3573
|
+
}
|
3574
|
+
) }) })
|
3575
|
+
] }),
|
3576
|
+
onConfirm: handleConfirmBulkDelete
|
3577
|
+
}
|
3578
|
+
};
|
3579
|
+
};
|
3580
|
+
DeleteAction.type = "delete";
|
3581
|
+
const UnpublishAction = ({ documents, model }) => {
|
3582
|
+
const { formatMessage } = reactIntl.useIntl();
|
3583
|
+
const { schema } = useDoc();
|
3584
|
+
const selectRow = strapiAdmin.useTable("UnpublishAction", (state) => state.selectRow);
|
3585
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3586
|
+
const hasI18nEnabled = Boolean(schema?.pluginOptions?.i18n);
|
3587
|
+
const hasDraftAndPublishEnabled = Boolean(schema?.options?.draftAndPublish);
|
3588
|
+
const { unpublishMany: bulkUnpublishAction } = useDocumentActions();
|
3589
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3590
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3591
|
+
const params = React__namespace.useMemo(() => buildValidParams(query), [query]);
|
3592
|
+
const handleConfirmBulkUnpublish = async () => {
|
3593
|
+
const data = await bulkUnpublishAction({ documentIds, model, params });
|
3594
|
+
if (!("error" in data)) {
|
3595
|
+
selectRow([]);
|
3596
|
+
}
|
3597
|
+
};
|
3598
|
+
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3599
|
+
if (!showUnpublishButton)
|
3600
|
+
return null;
|
3601
|
+
return {
|
3602
|
+
variant: "tertiary",
|
3603
|
+
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
3604
|
+
dialog: {
|
3605
|
+
type: "dialog",
|
3606
|
+
title: formatMessage({
|
3607
|
+
id: "app.components.ConfirmDialog.title",
|
3608
|
+
defaultMessage: "Confirmation"
|
3609
|
+
}),
|
3610
|
+
content: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3611
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(Icons.WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3612
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3613
|
+
id: "popUpWarning.bodyMessage.contentType.unpublish.all",
|
3614
|
+
defaultMessage: "Are you sure you want to unpublish these entries?"
|
3615
|
+
}) }),
|
3616
|
+
hasI18nEnabled && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger500", children: formatMessage(
|
3617
|
+
{
|
3618
|
+
id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
|
3619
|
+
defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
|
3620
|
+
},
|
3621
|
+
{
|
3622
|
+
em: Emphasis
|
3623
|
+
}
|
3624
|
+
) }) })
|
3625
|
+
] }),
|
3626
|
+
confirmButton: formatMessage({
|
3627
|
+
id: "app.utils.unpublish",
|
3628
|
+
defaultMessage: "Unpublish"
|
3629
|
+
}),
|
3630
|
+
onConfirm: handleConfirmBulkUnpublish
|
3631
|
+
}
|
3632
|
+
};
|
3633
|
+
};
|
3634
|
+
UnpublishAction.type = "unpublish";
|
3635
|
+
const Emphasis = (chunks) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
|
3636
|
+
const DEFAULT_BULK_ACTIONS = [PublishAction, UnpublishAction, DeleteAction];
|
3637
|
+
const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
|
3638
|
+
const { formatMessage } = reactIntl.useIntl();
|
3639
|
+
const getDefaultErrorMessage = (reason) => {
|
3640
|
+
switch (reason) {
|
3641
|
+
case "relation":
|
3642
|
+
return "Duplicating the relation could remove it from the original entry.";
|
3643
|
+
case "unique":
|
3644
|
+
return "Identical values in a unique field are not allowed";
|
3645
|
+
default:
|
3646
|
+
return reason;
|
3647
|
+
}
|
2478
3648
|
};
|
2479
3649
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
2480
3650
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: formatMessage({
|
@@ -2495,7 +3665,7 @@ const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
|
|
2495
3665
|
hasRadius: true,
|
2496
3666
|
padding: 6,
|
2497
3667
|
children: [
|
2498
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "row",
|
3668
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "row", tag: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { fontWeight: "semiBold", tag: "li", children: [
|
2499
3669
|
pathSegment,
|
2500
3670
|
index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
2501
3671
|
Icons.ChevronRight,
|
@@ -2507,7 +3677,7 @@ const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
|
|
2507
3677
|
}
|
2508
3678
|
)
|
2509
3679
|
] }, index2)) }),
|
2510
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, {
|
3680
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", textColor: "neutral600", children: formatMessage({
|
2511
3681
|
id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
|
2512
3682
|
defaultMessage: getDefaultErrorMessage(reason)
|
2513
3683
|
}) })
|
@@ -2532,7 +3702,7 @@ const TableActions = ({ document }) => {
|
|
2532
3702
|
strapiAdmin.DescriptionComponentRenderer,
|
2533
3703
|
{
|
2534
3704
|
props,
|
2535
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3705
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
|
2536
3706
|
children: (actions2) => {
|
2537
3707
|
const tableRowActions = actions2.filter((action) => {
|
2538
3708
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -2591,7 +3761,7 @@ const EditAction = ({ documentId }) => {
|
|
2591
3761
|
};
|
2592
3762
|
};
|
2593
3763
|
EditAction.type = "edit";
|
2594
|
-
const StyledPencil =
|
3764
|
+
const StyledPencil = styledComponents.styled(Icons.Pencil)`
|
2595
3765
|
path {
|
2596
3766
|
fill: currentColor;
|
2597
3767
|
}
|
@@ -2643,7 +3813,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2643
3813
|
}),
|
2644
3814
|
content: /* @__PURE__ */ jsxRuntime.jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
2645
3815
|
footer: ({ onClose }) => {
|
2646
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.
|
3816
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
2647
3817
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
2648
3818
|
id: "cancel",
|
2649
3819
|
defaultMessage: "Cancel"
|
@@ -2651,7 +3821,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2651
3821
|
/* @__PURE__ */ jsxRuntime.jsx(
|
2652
3822
|
designSystem.LinkButton,
|
2653
3823
|
{
|
2654
|
-
|
3824
|
+
tag: reactRouterDom.NavLink,
|
2655
3825
|
to: {
|
2656
3826
|
pathname: `clone/${documentId}`
|
2657
3827
|
},
|
@@ -2667,7 +3837,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2667
3837
|
};
|
2668
3838
|
};
|
2669
3839
|
CloneAction.type = "clone";
|
2670
|
-
const StyledDuplicate =
|
3840
|
+
const StyledDuplicate = styledComponents.styled(Icons.Duplicate)`
|
2671
3841
|
path {
|
2672
3842
|
fill: currentColor;
|
2673
3843
|
}
|
@@ -2684,8 +3854,7 @@ class ContentManagerPlugin {
|
|
2684
3854
|
documentActions = [
|
2685
3855
|
...DEFAULT_ACTIONS,
|
2686
3856
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
2687
|
-
...DEFAULT_HEADER_ACTIONS
|
2688
|
-
HistoryAction
|
3857
|
+
...DEFAULT_HEADER_ACTIONS
|
2689
3858
|
];
|
2690
3859
|
editViewSidePanels = [ActionsPanel];
|
2691
3860
|
headerActions = [];
|
@@ -2774,352 +3943,170 @@ const getPrintableType = (value) => {
|
|
2774
3943
|
}
|
2775
3944
|
return nativeType;
|
2776
3945
|
};
|
2777
|
-
const
|
2778
|
-
|
2779
|
-
|
2780
|
-
|
2781
|
-
|
2782
|
-
|
2783
|
-
|
2784
|
-
|
2785
|
-
|
2786
|
-
name: "app",
|
2787
|
-
initialState,
|
2788
|
-
reducers: {
|
2789
|
-
setInitialData(state, action) {
|
2790
|
-
const {
|
2791
|
-
authorizedCollectionTypeLinks,
|
2792
|
-
authorizedSingleTypeLinks,
|
2793
|
-
components,
|
2794
|
-
contentTypeSchemas,
|
2795
|
-
fieldSizes
|
2796
|
-
} = action.payload;
|
2797
|
-
state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
|
2798
|
-
({ isDisplayed }) => isDisplayed
|
2799
|
-
);
|
2800
|
-
state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
|
2801
|
-
state.components = components;
|
2802
|
-
state.models = contentTypeSchemas;
|
2803
|
-
state.fieldSizes = fieldSizes;
|
2804
|
-
state.isLoading = false;
|
2805
|
-
}
|
2806
|
-
}
|
2807
|
-
});
|
2808
|
-
const { actions, reducer: reducer$1 } = appSlice;
|
2809
|
-
const { setInitialData } = actions;
|
2810
|
-
const reducer = toolkit.combineReducers({
|
2811
|
-
app: reducer$1
|
2812
|
-
});
|
2813
|
-
const HOOKS = {
|
2814
|
-
/**
|
2815
|
-
* Hook that allows to mutate the displayed headers of the list view table
|
2816
|
-
* @constant
|
2817
|
-
* @type {string}
|
2818
|
-
*/
|
2819
|
-
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
2820
|
-
/**
|
2821
|
-
* Hook that allows to mutate the CM's collection types links pre-set filters
|
2822
|
-
* @constant
|
2823
|
-
* @type {string}
|
2824
|
-
*/
|
2825
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2826
|
-
/**
|
2827
|
-
* Hook that allows to mutate the CM's edit view layout
|
2828
|
-
* @constant
|
2829
|
-
* @type {string}
|
2830
|
-
*/
|
2831
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2832
|
-
/**
|
2833
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2834
|
-
* @constant
|
2835
|
-
* @type {string}
|
2836
|
-
*/
|
2837
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2838
|
-
};
|
2839
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2840
|
-
endpoints: (builder) => ({
|
2841
|
-
getContentTypeConfiguration: builder.query({
|
2842
|
-
query: (uid) => ({
|
2843
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2844
|
-
method: "GET"
|
2845
|
-
}),
|
2846
|
-
transformResponse: (response) => response.data,
|
2847
|
-
providesTags: (_result, _error, uid) => [
|
2848
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2849
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2850
|
-
]
|
2851
|
-
}),
|
2852
|
-
getAllContentTypeSettings: builder.query({
|
2853
|
-
query: () => "/content-manager/content-types-settings",
|
2854
|
-
transformResponse: (response) => response.data,
|
2855
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2856
|
-
}),
|
2857
|
-
updateContentTypeConfiguration: builder.mutation({
|
2858
|
-
query: ({ uid, ...body }) => ({
|
2859
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2860
|
-
method: "PUT",
|
2861
|
-
data: body
|
2862
|
-
}),
|
2863
|
-
transformResponse: (response) => response.data,
|
2864
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2865
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2866
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2867
|
-
// Is this necessary?
|
2868
|
-
{ type: "InitialData" }
|
2869
|
-
]
|
2870
|
-
})
|
2871
|
-
})
|
2872
|
-
});
|
2873
|
-
const {
|
2874
|
-
useGetContentTypeConfigurationQuery,
|
2875
|
-
useGetAllContentTypeSettingsQuery,
|
2876
|
-
useUpdateContentTypeConfigurationMutation
|
2877
|
-
} = contentTypesApi;
|
2878
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2879
|
-
const { type } = attribute;
|
2880
|
-
if (type === "relation") {
|
2881
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
2882
|
-
}
|
2883
|
-
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
2884
|
-
};
|
2885
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2886
|
-
if (!mainFieldName) {
|
2887
|
-
return void 0;
|
3946
|
+
const HistoryAction = ({ model, document }) => {
|
3947
|
+
const { formatMessage } = reactIntl.useIntl();
|
3948
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
3949
|
+
const navigate = reactRouterDom.useNavigate();
|
3950
|
+
const { trackUsage } = strapiAdmin.useTracking();
|
3951
|
+
const { pathname } = reactRouterDom.useLocation();
|
3952
|
+
const pluginsQueryParams = qs.stringify({ plugins: query.plugins }, { encode: false });
|
3953
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3954
|
+
return null;
|
2888
3955
|
}
|
2889
|
-
const
|
2890
|
-
|
2891
|
-
|
2892
|
-
|
2893
|
-
|
2894
|
-
|
2895
|
-
|
3956
|
+
const handleOnClick = () => {
|
3957
|
+
const destination = { pathname: "history", search: pluginsQueryParams };
|
3958
|
+
trackUsage("willNavigate", {
|
3959
|
+
from: pathname,
|
3960
|
+
to: `${pathname}/${destination.pathname}`
|
3961
|
+
});
|
3962
|
+
navigate(destination);
|
2896
3963
|
};
|
2897
|
-
};
|
2898
|
-
const DEFAULT_SETTINGS = {
|
2899
|
-
bulkable: false,
|
2900
|
-
filterable: false,
|
2901
|
-
searchable: false,
|
2902
|
-
pagination: false,
|
2903
|
-
defaultSortBy: "",
|
2904
|
-
defaultSortOrder: "asc",
|
2905
|
-
mainField: "id",
|
2906
|
-
pageSize: 10
|
2907
|
-
};
|
2908
|
-
const useDocumentLayout = (model) => {
|
2909
|
-
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
2910
|
-
const [{ query }] = strapiAdmin.useQueryParams();
|
2911
|
-
const runHookWaterfall = strapiAdmin.useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
2912
|
-
const { toggleNotification } = strapiAdmin.useNotification();
|
2913
|
-
const { _unstableFormatAPIError: formatAPIError } = strapiAdmin.useAPIErrorHandler();
|
2914
|
-
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
2915
|
-
const {
|
2916
|
-
data,
|
2917
|
-
isLoading: isLoadingConfigs,
|
2918
|
-
error,
|
2919
|
-
isFetching: isFetchingConfigs
|
2920
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2921
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2922
|
-
React__namespace.useEffect(() => {
|
2923
|
-
if (error) {
|
2924
|
-
toggleNotification({
|
2925
|
-
type: "danger",
|
2926
|
-
message: formatAPIError(error)
|
2927
|
-
});
|
2928
|
-
}
|
2929
|
-
}, [error, formatAPIError, toggleNotification]);
|
2930
|
-
const editLayout = React__namespace.useMemo(
|
2931
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2932
|
-
layout: [],
|
2933
|
-
components: {},
|
2934
|
-
metadatas: {},
|
2935
|
-
options: {},
|
2936
|
-
settings: DEFAULT_SETTINGS
|
2937
|
-
},
|
2938
|
-
[data, isLoading, schemas, schema, components]
|
2939
|
-
);
|
2940
|
-
const listLayout = React__namespace.useMemo(() => {
|
2941
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2942
|
-
layout: [],
|
2943
|
-
metadatas: {},
|
2944
|
-
options: {},
|
2945
|
-
settings: DEFAULT_SETTINGS
|
2946
|
-
};
|
2947
|
-
}, [data, isLoading, schemas, schema, components]);
|
2948
|
-
const { layout: edit } = React__namespace.useMemo(
|
2949
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2950
|
-
layout: editLayout,
|
2951
|
-
query
|
2952
|
-
}),
|
2953
|
-
[editLayout, query, runHookWaterfall]
|
2954
|
-
);
|
2955
3964
|
return {
|
2956
|
-
|
2957
|
-
|
2958
|
-
|
2959
|
-
|
3965
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.ClockCounterClockwise, {}),
|
3966
|
+
label: formatMessage({
|
3967
|
+
id: "content-manager.history.document-action",
|
3968
|
+
defaultMessage: "Content History"
|
3969
|
+
}),
|
3970
|
+
onClick: handleOnClick,
|
3971
|
+
disabled: (
|
3972
|
+
/**
|
3973
|
+
* The user is creating a new document.
|
3974
|
+
* It hasn't been saved yet, so there's no history to go to
|
3975
|
+
*/
|
3976
|
+
!document || /**
|
3977
|
+
* The document has been created but the current dimension has never been saved.
|
3978
|
+
* For example, the user is creating a new locale in an existing document,
|
3979
|
+
* so there's no history for the document in that locale
|
3980
|
+
*/
|
3981
|
+
!document.id || /**
|
3982
|
+
* History is only available for content types created by the user.
|
3983
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
3984
|
+
* which start with `admin::` or `plugin::`
|
3985
|
+
*/
|
3986
|
+
!model.startsWith("api::")
|
3987
|
+
),
|
3988
|
+
position: "header"
|
2960
3989
|
};
|
2961
3990
|
};
|
2962
|
-
|
2963
|
-
|
2964
|
-
|
3991
|
+
HistoryAction.type = "history";
|
3992
|
+
const historyAdmin = {
|
3993
|
+
bootstrap(app) {
|
3994
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
3995
|
+
addDocumentAction((actions2) => {
|
3996
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
3997
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
3998
|
+
return actions2;
|
3999
|
+
});
|
4000
|
+
}
|
2965
4001
|
};
|
2966
|
-
const
|
2967
|
-
|
2968
|
-
|
2969
|
-
|
2970
|
-
|
2971
|
-
|
2972
|
-
|
2973
|
-
|
2974
|
-
|
2975
|
-
|
2976
|
-
|
2977
|
-
|
2978
|
-
|
2979
|
-
|
2980
|
-
|
2981
|
-
|
2982
|
-
|
2983
|
-
|
2984
|
-
|
2985
|
-
}
|
2986
|
-
|
4002
|
+
const initialState = {
|
4003
|
+
collectionTypeLinks: [],
|
4004
|
+
components: [],
|
4005
|
+
fieldSizes: {},
|
4006
|
+
models: [],
|
4007
|
+
singleTypeLinks: [],
|
4008
|
+
isLoading: true
|
4009
|
+
};
|
4010
|
+
const appSlice = toolkit.createSlice({
|
4011
|
+
name: "app",
|
4012
|
+
initialState,
|
4013
|
+
reducers: {
|
4014
|
+
setInitialData(state, action) {
|
4015
|
+
const {
|
4016
|
+
authorizedCollectionTypeLinks,
|
4017
|
+
authorizedSingleTypeLinks,
|
4018
|
+
components,
|
4019
|
+
contentTypeSchemas,
|
4020
|
+
fieldSizes
|
4021
|
+
} = action.payload;
|
4022
|
+
state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
|
4023
|
+
({ isDisplayed }) => isDisplayed
|
4024
|
+
);
|
4025
|
+
state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
|
4026
|
+
state.components = components;
|
4027
|
+
state.models = contentTypeSchemas;
|
4028
|
+
state.fieldSizes = fieldSizes;
|
4029
|
+
state.isLoading = false;
|
2987
4030
|
}
|
2988
|
-
|
2989
|
-
|
2990
|
-
|
2991
|
-
|
2992
|
-
|
2993
|
-
|
2994
|
-
|
2995
|
-
|
2996
|
-
|
2997
|
-
|
2998
|
-
|
2999
|
-
|
3000
|
-
|
3001
|
-
|
3002
|
-
|
3003
|
-
|
3004
|
-
|
3005
|
-
|
3006
|
-
|
3007
|
-
|
3008
|
-
|
3009
|
-
|
3010
|
-
|
3011
|
-
|
3012
|
-
|
3013
|
-
|
3014
|
-
|
3015
|
-
|
3016
|
-
|
3017
|
-
|
3018
|
-
|
3019
|
-
components: componentEditAttributes,
|
3020
|
-
metadatas: editMetadatas,
|
3021
|
-
settings: {
|
3022
|
-
...data.contentType.settings,
|
3023
|
-
displayName: schema?.info.displayName
|
4031
|
+
}
|
4032
|
+
});
|
4033
|
+
const { actions, reducer: reducer$1 } = appSlice;
|
4034
|
+
const { setInitialData } = actions;
|
4035
|
+
const reducer = toolkit.combineReducers({
|
4036
|
+
app: reducer$1
|
4037
|
+
});
|
4038
|
+
const previewApi = contentManagerApi.injectEndpoints({
|
4039
|
+
endpoints: (builder) => ({
|
4040
|
+
getPreviewUrl: builder.query({
|
4041
|
+
query({ query, params }) {
|
4042
|
+
return {
|
4043
|
+
url: `/content-manager/preview/url/${params.contentType}`,
|
4044
|
+
method: "GET",
|
4045
|
+
config: {
|
4046
|
+
params: query
|
4047
|
+
}
|
4048
|
+
};
|
4049
|
+
}
|
4050
|
+
})
|
4051
|
+
})
|
4052
|
+
});
|
4053
|
+
const { useGetPreviewUrlQuery } = previewApi;
|
4054
|
+
const PreviewSidePanel = ({ model, documentId, document }) => {
|
4055
|
+
const { formatMessage } = reactIntl.useIntl();
|
4056
|
+
const { trackUsage } = strapiAdmin.useTracking();
|
4057
|
+
const { pathname } = reactRouterDom.useLocation();
|
4058
|
+
const [{ query }] = strapiAdmin.useQueryParams();
|
4059
|
+
const { data, error } = useGetPreviewUrlQuery({
|
4060
|
+
params: {
|
4061
|
+
contentType: model
|
3024
4062
|
},
|
3025
|
-
|
3026
|
-
|
3027
|
-
|
3028
|
-
|
4063
|
+
query: {
|
4064
|
+
documentId,
|
4065
|
+
locale: document?.locale,
|
4066
|
+
status: document?.status
|
3029
4067
|
}
|
4068
|
+
});
|
4069
|
+
if (!data?.data?.url || error) {
|
4070
|
+
return null;
|
4071
|
+
}
|
4072
|
+
const trackNavigation = () => {
|
4073
|
+
const destinationPathname = pathname.replace(/\/$/, "") + "/preview";
|
4074
|
+
trackUsage("willNavigate", { from: pathname, to: destinationPathname });
|
3030
4075
|
};
|
3031
|
-
};
|
3032
|
-
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
3033
|
-
return rows.map(
|
3034
|
-
(row) => row.map((field) => {
|
3035
|
-
const attribute = attributes[field.name];
|
3036
|
-
if (!attribute) {
|
3037
|
-
return null;
|
3038
|
-
}
|
3039
|
-
const { edit: metadata } = metadatas[field.name];
|
3040
|
-
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
3041
|
-
return {
|
3042
|
-
attribute,
|
3043
|
-
disabled: !metadata.editable,
|
3044
|
-
hint: metadata.description,
|
3045
|
-
label: metadata.label ?? "",
|
3046
|
-
name: field.name,
|
3047
|
-
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
3048
|
-
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
3049
|
-
schemas,
|
3050
|
-
components: components?.schemas ?? {}
|
3051
|
-
}),
|
3052
|
-
placeholder: metadata.placeholder ?? "",
|
3053
|
-
required: attribute.required ?? false,
|
3054
|
-
size: field.size,
|
3055
|
-
unique: "unique" in attribute ? attribute.unique : false,
|
3056
|
-
visible: metadata.visible ?? true,
|
3057
|
-
type: attribute.type
|
3058
|
-
};
|
3059
|
-
}).filter((field) => field !== null)
|
3060
|
-
);
|
3061
|
-
};
|
3062
|
-
const formatListLayout = (data, {
|
3063
|
-
schemas,
|
3064
|
-
schema,
|
3065
|
-
components
|
3066
|
-
}) => {
|
3067
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
3068
|
-
(acc, [attribute, metadata]) => {
|
3069
|
-
return {
|
3070
|
-
...acc,
|
3071
|
-
[attribute]: metadata.list
|
3072
|
-
};
|
3073
|
-
},
|
3074
|
-
{}
|
3075
|
-
);
|
3076
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
3077
|
-
data.contentType.layouts.list,
|
3078
|
-
schema?.attributes,
|
3079
|
-
listMetadatas,
|
3080
|
-
{ configurations: data.components, schemas: components },
|
3081
|
-
schemas
|
3082
|
-
);
|
3083
4076
|
return {
|
3084
|
-
|
3085
|
-
|
3086
|
-
|
3087
|
-
|
3088
|
-
|
3089
|
-
|
3090
|
-
|
3091
|
-
|
4077
|
+
title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
|
4078
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(
|
4079
|
+
designSystem.Button,
|
4080
|
+
{
|
4081
|
+
variant: "tertiary",
|
4082
|
+
tag: reactRouterDom.Link,
|
4083
|
+
to: { pathname: "preview", search: qs.stringify(query, { encode: false }) },
|
4084
|
+
onClick: trackNavigation,
|
4085
|
+
flex: "auto",
|
4086
|
+
children: formatMessage({
|
4087
|
+
id: "content-manager.preview.panel.button",
|
4088
|
+
defaultMessage: "Open preview"
|
4089
|
+
})
|
4090
|
+
}
|
4091
|
+
) })
|
3092
4092
|
};
|
3093
4093
|
};
|
3094
|
-
const
|
3095
|
-
|
3096
|
-
|
3097
|
-
if (!
|
3098
|
-
return
|
4094
|
+
const FEATURE_ID = "preview";
|
4095
|
+
const previewAdmin = {
|
4096
|
+
bootstrap(app) {
|
4097
|
+
if (!window.strapi.future.isEnabled(FEATURE_ID)) {
|
4098
|
+
return;
|
3099
4099
|
}
|
3100
|
-
const
|
3101
|
-
|
3102
|
-
|
3103
|
-
attribute,
|
3104
|
-
label: metadata.label ?? "",
|
3105
|
-
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
3106
|
-
schemas,
|
3107
|
-
components: components?.schemas ?? {}
|
3108
|
-
}),
|
3109
|
-
name,
|
3110
|
-
searchable: metadata.searchable ?? true,
|
3111
|
-
sortable: metadata.sortable ?? true
|
3112
|
-
};
|
3113
|
-
}).filter((field) => field !== null);
|
4100
|
+
const contentManagerPluginApis = app.getPlugin("content-manager").apis;
|
4101
|
+
contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
|
4102
|
+
}
|
3114
4103
|
};
|
3115
4104
|
const index = {
|
3116
4105
|
register(app) {
|
3117
4106
|
const cm = new ContentManagerPlugin();
|
3118
4107
|
app.addReducers({
|
3119
|
-
[contentManagerApi.reducerPath]: contentManagerApi.reducer,
|
3120
4108
|
[PLUGIN_ID]: reducer
|
3121
4109
|
});
|
3122
|
-
app.addMiddlewares([() => contentManagerApi.middleware]);
|
3123
4110
|
app.addMenuLink({
|
3124
4111
|
to: PLUGIN_ID,
|
3125
4112
|
icon: Icons.Feather,
|
@@ -3128,14 +4115,32 @@ const index = {
|
|
3128
4115
|
defaultMessage: "Content Manager"
|
3129
4116
|
},
|
3130
4117
|
permissions: [],
|
3131
|
-
|
4118
|
+
position: 1
|
4119
|
+
});
|
4120
|
+
app.router.addRoute({
|
4121
|
+
path: "content-manager/*",
|
4122
|
+
lazy: async () => {
|
4123
|
+
const { Layout } = await Promise.resolve().then(() => require("./layout-Cx9LHtH5.js"));
|
4124
|
+
return {
|
4125
|
+
Component: Layout
|
4126
|
+
};
|
4127
|
+
},
|
4128
|
+
children: routes
|
3132
4129
|
});
|
3133
4130
|
app.registerPlugin(cm.config);
|
3134
4131
|
},
|
4132
|
+
bootstrap(app) {
|
4133
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
4134
|
+
historyAdmin.bootstrap(app);
|
4135
|
+
}
|
4136
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
4137
|
+
previewAdmin.bootstrap(app);
|
4138
|
+
}
|
4139
|
+
},
|
3135
4140
|
async registerTrads({ locales }) {
|
3136
4141
|
const importedTrads = await Promise.all(
|
3137
4142
|
locales.map((locale) => {
|
3138
|
-
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-
|
4143
|
+
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-DTWPCdTS.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`).then(({ default: data }) => {
|
3139
4144
|
return {
|
3140
4145
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3141
4146
|
locale
|
@@ -3152,6 +4157,8 @@ const index = {
|
|
3152
4157
|
}
|
3153
4158
|
};
|
3154
4159
|
exports.ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD;
|
4160
|
+
exports.BulkActionsRenderer = BulkActionsRenderer;
|
4161
|
+
exports.CLONE_PATH = CLONE_PATH;
|
3155
4162
|
exports.COLLECTION_TYPES = COLLECTION_TYPES;
|
3156
4163
|
exports.CREATOR_FIELDS = CREATOR_FIELDS;
|
3157
4164
|
exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
|
@@ -3178,8 +4185,8 @@ exports.getDisplayName = getDisplayName;
|
|
3178
4185
|
exports.getMainField = getMainField;
|
3179
4186
|
exports.getTranslation = getTranslation;
|
3180
4187
|
exports.index = index;
|
3181
|
-
exports.routes = routes;
|
3182
4188
|
exports.setInitialData = setInitialData;
|
4189
|
+
exports.useContentManagerContext = useContentManagerContext;
|
3183
4190
|
exports.useContentTypeSchema = useContentTypeSchema;
|
3184
4191
|
exports.useDoc = useDoc;
|
3185
4192
|
exports.useDocLayout = useDocLayout;
|
@@ -3191,5 +4198,6 @@ exports.useGetAllContentTypeSettingsQuery = useGetAllContentTypeSettingsQuery;
|
|
3191
4198
|
exports.useGetAllDocumentsQuery = useGetAllDocumentsQuery;
|
3192
4199
|
exports.useGetContentTypeConfigurationQuery = useGetContentTypeConfigurationQuery;
|
3193
4200
|
exports.useGetInitialDataQuery = useGetInitialDataQuery;
|
4201
|
+
exports.useGetPreviewUrlQuery = useGetPreviewUrlQuery;
|
3194
4202
|
exports.useUpdateContentTypeConfigurationMutation = useUpdateContentTypeConfigurationMutation;
|
3195
|
-
//# sourceMappingURL=index-
|
4203
|
+
//# sourceMappingURL=index-DjV7tyGu.js.map
|