@strapi/content-manager 0.0.0-experimental.e60ec1829240dae21c1e1d29076681c322288813 → 0.0.0-experimental.e8d8fc824d0f6a695b2a9ebaa4680ed21c3645ca
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-DjWJdz6Y.js → ComponentConfigurationPage-BlzvDpbX.js} +5 -6
- package/dist/_chunks/{ComponentConfigurationPage-DjWJdz6Y.js.map → ComponentConfigurationPage-BlzvDpbX.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs → ComponentConfigurationPage-DaPOlQaD.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs.map → ComponentConfigurationPage-DaPOlQaD.mjs.map} +1 -1
- package/dist/_chunks/{ComponentIcon-BBQsYCVn.js → ComponentIcon-CRbtQEUV.js} +9 -4
- package/dist/_chunks/ComponentIcon-CRbtQEUV.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-DacbqQ_f.mjs → EditConfigurationPage-BZPXItXo.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs.map → EditConfigurationPage-BZPXItXo.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js → EditConfigurationPage-uy-v43AR.js} +5 -6
- package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js.map → EditConfigurationPage-uy-v43AR.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-DvNpQkam.js → EditViewPage-DT6A4ayX.js} +102 -54
- package/dist/_chunks/EditViewPage-DT6A4ayX.js.map +1 -0
- package/dist/_chunks/EditViewPage-oOLeTySr.mjs +254 -0
- package/dist/_chunks/EditViewPage-oOLeTySr.mjs.map +1 -0
- package/dist/_chunks/{Field-6gvGdPBV.mjs → Field-D7dv2aUX.mjs} +1192 -896
- package/dist/_chunks/Field-D7dv2aUX.mjs.map +1 -0
- package/dist/_chunks/{Field-DmVKIAOo.js → Field-kYFVIGiP.js} +1238 -943
- package/dist/_chunks/Field-kYFVIGiP.js.map +1 -0
- package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
- package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
- package/dist/_chunks/{Form-DW6K1IH-.mjs → Form-BxR6sc29.mjs} +67 -46
- package/dist/_chunks/Form-BxR6sc29.mjs.map +1 -0
- package/dist/_chunks/{Form-CPZC9vWa.js → Form-CCijSg3V.js} +68 -49
- package/dist/_chunks/Form-CCijSg3V.js.map +1 -0
- package/dist/_chunks/{History-DeAPlvtv.js → History-BMndx49M.js} +182 -147
- package/dist/_chunks/History-BMndx49M.js.map +1 -0
- package/dist/_chunks/{History-Dmr9fmUA.mjs → History-D8F7aYQU.mjs} +181 -144
- package/dist/_chunks/History-D8F7aYQU.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DPCwW5Vr.js → ListConfigurationPage-DouY1EWM.js} +72 -63
- package/dist/_chunks/ListConfigurationPage-DouY1EWM.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DhwvYcNv.mjs → ListConfigurationPage-DqAdSPwC.mjs} +68 -57
- package/dist/_chunks/ListConfigurationPage-DqAdSPwC.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-5ySZ-VUs.js → ListViewPage-BPVmh9pq.js} +179 -164
- package/dist/_chunks/ListViewPage-BPVmh9pq.js.map +1 -0
- package/dist/_chunks/{ListViewPage-BtAwuYLE.mjs → ListViewPage-C73F0jPh.mjs} +175 -159
- package/dist/_chunks/ListViewPage-C73F0jPh.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DSPxnxxp.mjs → NoContentTypePage-B5w7iJOF.mjs} +3 -3
- package/dist/_chunks/NoContentTypePage-B5w7iJOF.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DOC_yWOf.js → NoContentTypePage-BwcL--4H.js} +3 -3
- package/dist/_chunks/NoContentTypePage-BwcL--4H.js.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js → NoPermissionsPage-BMFKVcwJ.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js.map → NoPermissionsPage-BMFKVcwJ.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs → NoPermissionsPage-UnEgMGK4.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs.map → NoPermissionsPage-UnEgMGK4.mjs.map} +1 -1
- package/dist/_chunks/Preview-B7PR3Ok_.js +312 -0
- package/dist/_chunks/Preview-B7PR3Ok_.js.map +1 -0
- package/dist/_chunks/Preview-DECOhK0D.mjs +294 -0
- package/dist/_chunks/Preview-DECOhK0D.mjs.map +1 -0
- package/dist/_chunks/{Relations-J8cscLlR.mjs → Relations-DinMQJ4B.mjs} +138 -94
- package/dist/_chunks/Relations-DinMQJ4B.mjs.map +1 -0
- package/dist/_chunks/{Relations-CgWtgnPe.js → Relations-lndx3aQk.js} +142 -100
- package/dist/_chunks/Relations-lndx3aQk.js.map +1 -0
- package/dist/_chunks/{en-C-V1_90f.js → en-BK8Xyl5I.js} +38 -18
- package/dist/_chunks/{en-C-V1_90f.js.map → en-BK8Xyl5I.js.map} +1 -1
- package/dist/_chunks/{en-MBPul9Su.mjs → en-Dtk_ot79.mjs} +38 -18
- package/dist/_chunks/{en-MBPul9Su.mjs.map → en-Dtk_ot79.mjs.map} +1 -1
- package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
- package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
- package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
- package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
- package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
- package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
- package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
- package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
- package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
- package/dist/_chunks/{index-CwRRo1V9.mjs → index-C2SagWVW.mjs} +2070 -988
- package/dist/_chunks/index-C2SagWVW.mjs.map +1 -0
- package/dist/_chunks/{index-C6AH2hEl.js → index-Cnw4gqee.js} +2047 -966
- package/dist/_chunks/index-Cnw4gqee.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-jIDzX0Fp.mjs → layout-DY_D9MGA.mjs} +46 -28
- package/dist/_chunks/layout-DY_D9MGA.mjs.map +1 -0
- package/dist/_chunks/{layout-B_SXLhqf.js → layout-ivwIVPnV.js} +47 -32
- package/dist/_chunks/layout-ivwIVPnV.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-iBMa_OFG.js → relations-B7C7O_Pv.js} +6 -7
- package/dist/_chunks/relations-B7C7O_Pv.js.map +1 -0
- package/dist/_chunks/{relations-CuvIgCqI.mjs → relations-Boc5Y9kX.mjs} +6 -7
- package/dist/_chunks/relations-Boc5Y9kX.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-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
- package/dist/_chunks/useDragAndDrop-BMtgCYzL.js.map +1 -0
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
- package/dist/_chunks/useDragAndDrop-DJ6jqvZN.mjs.map +1 -0
- 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 +6 -5
- 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 +12 -5
- package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +7 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +3 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +5 -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/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 +886 -480
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +892 -485
- 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 +23 -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.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +4 -4
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +22 -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/controllers/index.d.ts +2 -0
- package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/preview.d.ts +13 -0
- package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
- package/dist/server/src/preview/index.d.ts +4 -0
- package/dist/server/src/preview/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/index.d.ts +8 -0
- package/dist/server/src/preview/routes/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/preview.d.ts +4 -0
- package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
- package/dist/server/src/preview/services/index.d.ts +16 -0
- package/dist/server/src/preview/services/index.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview-config.d.ts +32 -0
- package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview.d.ts +12 -0
- package/dist/server/src/preview/services/preview.d.ts.map +1 -0
- package/dist/server/src/preview/utils.d.ts +19 -0
- package/dist/server/src/preview/utils.d.ts.map +1 -0
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts +13 -12
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +16 -35
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +22 -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/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 +22 -21
- 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-DDS6H9HO.mjs +0 -203
- package/dist/_chunks/EditViewPage-DDS6H9HO.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-DvNpQkam.js.map +0 -1
- package/dist/_chunks/Field-6gvGdPBV.mjs.map +0 -1
- package/dist/_chunks/Field-DmVKIAOo.js.map +0 -1
- package/dist/_chunks/Form-CPZC9vWa.js.map +0 -1
- package/dist/_chunks/Form-DW6K1IH-.mjs.map +0 -1
- package/dist/_chunks/History-DeAPlvtv.js.map +0 -1
- package/dist/_chunks/History-Dmr9fmUA.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DPCwW5Vr.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DhwvYcNv.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-5ySZ-VUs.js.map +0 -1
- package/dist/_chunks/ListViewPage-BtAwuYLE.mjs.map +0 -1
- package/dist/_chunks/NoContentTypePage-DOC_yWOf.js.map +0 -1
- package/dist/_chunks/NoContentTypePage-DSPxnxxp.mjs.map +0 -1
- package/dist/_chunks/Relations-CgWtgnPe.js.map +0 -1
- package/dist/_chunks/Relations-J8cscLlR.mjs.map +0 -1
- package/dist/_chunks/index-C6AH2hEl.js.map +0 -1
- package/dist/_chunks/index-CwRRo1V9.mjs.map +0 -1
- package/dist/_chunks/layout-B_SXLhqf.js.map +0 -1
- package/dist/_chunks/layout-jIDzX0Fp.mjs.map +0 -1
- package/dist/_chunks/relations-CuvIgCqI.mjs.map +0 -1
- package/dist/_chunks/relations-iBMa_OFG.js.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/_chunks/useDragAndDrop-DdHgKsqq.mjs.map +0 -1
- package/dist/_chunks/useDragAndDrop-J0TUUbR6.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
@@ -1,27 +1,33 @@
|
|
1
|
-
import {
|
1
|
+
import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check, CrossCircle, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
|
2
2
|
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
3
|
-
import { useStrapiApp,
|
4
|
-
import { stringify } from "qs";
|
5
|
-
import { useIntl } from "react-intl";
|
6
|
-
import { useNavigate, useParams, Navigate, useMatch, NavLink } from "react-router-dom";
|
3
|
+
import { useStrapiApp, createContext, useQueryParams, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useForm, useTracking, useGuidedTour, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
|
7
4
|
import * as React from "react";
|
8
5
|
import { lazy } from "react";
|
9
|
-
import { Menu, VisuallyHidden, Flex,
|
10
|
-
import
|
6
|
+
import { Menu, Button, VisuallyHidden, Flex, Dialog, Modal, Typography, Radio, Status, Box, SingleSelect, SingleSelectOption, IconButton, Loader, Tooltip, LinkButton } from "@strapi/design-system";
|
7
|
+
import mapValues from "lodash/fp/mapValues";
|
8
|
+
import { useIntl } from "react-intl";
|
9
|
+
import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
|
10
|
+
import { styled } from "styled-components";
|
11
11
|
import * as yup from "yup";
|
12
12
|
import { ValidationError } from "yup";
|
13
|
-
import {
|
14
|
-
import { isAxiosError } from "axios";
|
13
|
+
import { stringify } from "qs";
|
15
14
|
import pipe from "lodash/fp/pipe";
|
16
15
|
import { intervalToDuration, isPast } from "date-fns";
|
17
16
|
import { createSlice, combineReducers } from "@reduxjs/toolkit";
|
18
|
-
const __variableDynamicImportRuntimeHelper = (glob, path) => {
|
17
|
+
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
19
18
|
const v = glob[path];
|
20
19
|
if (v) {
|
21
20
|
return typeof v === "function" ? v() : Promise.resolve(v);
|
22
21
|
}
|
23
22
|
return new Promise((_, reject) => {
|
24
|
-
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
23
|
+
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
24
|
+
reject.bind(
|
25
|
+
null,
|
26
|
+
new Error(
|
27
|
+
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
28
|
+
)
|
29
|
+
)
|
30
|
+
);
|
25
31
|
});
|
26
32
|
};
|
27
33
|
const PLUGIN_ID = "content-manager";
|
@@ -51,42 +57,6 @@ const useInjectionZone = (area) => {
|
|
51
57
|
const [page, position] = area.split(".");
|
52
58
|
return contentManagerPlugin.getInjectedComponents(page, position);
|
53
59
|
};
|
54
|
-
const HistoryAction = ({ model, document }) => {
|
55
|
-
const { formatMessage } = useIntl();
|
56
|
-
const [{ query }] = useQueryParams();
|
57
|
-
const navigate = useNavigate();
|
58
|
-
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
59
|
-
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
60
|
-
return null;
|
61
|
-
}
|
62
|
-
return {
|
63
|
-
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
64
|
-
label: formatMessage({
|
65
|
-
id: "content-manager.history.document-action",
|
66
|
-
defaultMessage: "Content History"
|
67
|
-
}),
|
68
|
-
onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
|
69
|
-
disabled: (
|
70
|
-
/**
|
71
|
-
* The user is creating a new document.
|
72
|
-
* It hasn't been saved yet, so there's no history to go to
|
73
|
-
*/
|
74
|
-
!document || /**
|
75
|
-
* The document has been created but the current dimension has never been saved.
|
76
|
-
* For example, the user is creating a new locale in an existing document,
|
77
|
-
* so there's no history for the document in that locale
|
78
|
-
*/
|
79
|
-
!document.id || /**
|
80
|
-
* History is only available for content types created by the user.
|
81
|
-
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
82
|
-
* which start with `admin::` or `plugin::`
|
83
|
-
*/
|
84
|
-
!model.startsWith("api::")
|
85
|
-
),
|
86
|
-
position: "header"
|
87
|
-
};
|
88
|
-
};
|
89
|
-
HistoryAction.type = "history";
|
90
60
|
const ID = "id";
|
91
61
|
const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
|
92
62
|
const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
|
@@ -138,6 +108,7 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
138
108
|
if (!slug) {
|
139
109
|
throw new Error("Cannot find the slug param in the URL");
|
140
110
|
}
|
111
|
+
const [{ rawQuery }] = useQueryParams();
|
141
112
|
const userPermissions = useAuth("DocumentRBAC", (state) => state.permissions);
|
142
113
|
const contentTypePermissions = React.useMemo(() => {
|
143
114
|
const contentTypePermissions2 = userPermissions.filter(
|
@@ -148,7 +119,14 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
148
119
|
return { ...acc, [action]: [permission] };
|
149
120
|
}, {});
|
150
121
|
}, [slug, userPermissions]);
|
151
|
-
const { isLoading, allowedActions } = useRBAC(
|
122
|
+
const { isLoading, allowedActions } = useRBAC(
|
123
|
+
contentTypePermissions,
|
124
|
+
permissions ?? void 0,
|
125
|
+
// TODO: useRBAC context should be typed and built differently
|
126
|
+
// We are passing raw query as context to the hook so that it can
|
127
|
+
// rely on the locale provided from DocumentRBAC for its permission calculations.
|
128
|
+
rawQuery
|
129
|
+
);
|
152
130
|
const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
|
153
131
|
const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
|
154
132
|
const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
|
@@ -157,9 +135,8 @@ const DocumentRBAC = ({ children, permissions }) => {
|
|
157
135
|
const name = removeNumericalStrings(fieldName.split("."));
|
158
136
|
const componentFieldNames = fieldsUserCanAction.filter((field) => field.split(".").length > 1);
|
159
137
|
if (fieldType === "component") {
|
160
|
-
|
161
|
-
|
162
|
-
return field.includes(fieldName);
|
138
|
+
return componentFieldNames.some((field) => {
|
139
|
+
return field.includes(name.join("."));
|
163
140
|
});
|
164
141
|
}
|
165
142
|
if (name.length > 1) {
|
@@ -189,89 +166,20 @@ const extractAndDedupeFields = (permissions = []) => permissions.flatMap((permis
|
|
189
166
|
(field, index2, arr) => arr.indexOf(field) === index2 && typeof field === "string"
|
190
167
|
);
|
191
168
|
const removeNumericalStrings = (arr) => arr.filter((item) => isNaN(Number(item)));
|
192
|
-
const
|
193
|
-
|
194
|
-
return query;
|
195
|
-
const { plugins: _, ...validQueryParams } = {
|
196
|
-
...query,
|
197
|
-
...Object.values(query?.plugins ?? {}).reduce(
|
198
|
-
(acc, current) => Object.assign(acc, current),
|
199
|
-
{}
|
200
|
-
)
|
201
|
-
};
|
202
|
-
if ("_q" in validQueryParams) {
|
203
|
-
validQueryParams._q = encodeURIComponent(validQueryParams._q);
|
204
|
-
}
|
205
|
-
return validQueryParams;
|
206
|
-
};
|
207
|
-
const axiosBaseQuery = () => async (query, { signal }) => {
|
208
|
-
try {
|
209
|
-
const { get, post, del, put } = getFetchClient();
|
210
|
-
if (typeof query === "string") {
|
211
|
-
const result = await get(query, { signal });
|
212
|
-
return { data: result.data };
|
213
|
-
} else {
|
214
|
-
const { url, method = "GET", data, config } = query;
|
215
|
-
if (method === "POST") {
|
216
|
-
const result2 = await post(url, data, { ...config, signal });
|
217
|
-
return { data: result2.data };
|
218
|
-
}
|
219
|
-
if (method === "DELETE") {
|
220
|
-
const result2 = await del(url, { ...config, signal });
|
221
|
-
return { data: result2.data };
|
222
|
-
}
|
223
|
-
if (method === "PUT") {
|
224
|
-
const result2 = await put(url, data, { ...config, signal });
|
225
|
-
return { data: result2.data };
|
226
|
-
}
|
227
|
-
const result = await get(url, { ...config, signal });
|
228
|
-
return { data: result.data };
|
229
|
-
}
|
230
|
-
} catch (err) {
|
231
|
-
if (isAxiosError(err)) {
|
232
|
-
if (typeof err.response?.data === "object" && err.response?.data !== null && "error" in err.response?.data) {
|
233
|
-
return { data: void 0, error: err.response?.data.error };
|
234
|
-
} else {
|
235
|
-
return {
|
236
|
-
data: void 0,
|
237
|
-
error: {
|
238
|
-
name: "UnknownError",
|
239
|
-
message: "There was an unknown error response from the API",
|
240
|
-
details: err.response?.data,
|
241
|
-
status: err.response?.status
|
242
|
-
}
|
243
|
-
};
|
244
|
-
}
|
245
|
-
}
|
246
|
-
const error = err;
|
247
|
-
return {
|
248
|
-
data: void 0,
|
249
|
-
error: {
|
250
|
-
name: error.name,
|
251
|
-
message: error.message,
|
252
|
-
stack: error.stack
|
253
|
-
}
|
254
|
-
};
|
255
|
-
}
|
256
|
-
};
|
257
|
-
const isBaseQueryError = (error) => {
|
258
|
-
return error.name !== void 0;
|
259
|
-
};
|
260
|
-
const contentManagerApi = createApi({
|
261
|
-
reducerPath: "contentManagerApi",
|
262
|
-
baseQuery: axiosBaseQuery(),
|
263
|
-
tagTypes: [
|
169
|
+
const contentManagerApi = adminApi.enhanceEndpoints({
|
170
|
+
addTagTypes: [
|
264
171
|
"ComponentConfiguration",
|
265
172
|
"ContentTypesConfiguration",
|
266
173
|
"ContentTypeSettings",
|
267
174
|
"Document",
|
268
175
|
"InitialData",
|
269
176
|
"HistoryVersion",
|
270
|
-
"Relations"
|
271
|
-
|
272
|
-
|
177
|
+
"Relations",
|
178
|
+
"UidAvailability"
|
179
|
+
]
|
273
180
|
});
|
274
181
|
const documentApi = contentManagerApi.injectEndpoints({
|
182
|
+
overrideExisting: true,
|
275
183
|
endpoints: (builder) => ({
|
276
184
|
autoCloneDocument: builder.mutation({
|
277
185
|
query: ({ model, sourceId, query }) => ({
|
@@ -281,7 +189,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
281
189
|
params: query
|
282
190
|
}
|
283
191
|
}),
|
284
|
-
invalidatesTags: (_result,
|
192
|
+
invalidatesTags: (_result, error, { model }) => {
|
193
|
+
if (error) {
|
194
|
+
return [];
|
195
|
+
}
|
196
|
+
return [{ type: "Document", id: `${model}_LIST` }];
|
197
|
+
}
|
285
198
|
}),
|
286
199
|
cloneDocument: builder.mutation({
|
287
200
|
query: ({ model, sourceId, data, params }) => ({
|
@@ -292,7 +205,10 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
292
205
|
params
|
293
206
|
}
|
294
207
|
}),
|
295
|
-
invalidatesTags: (_result, _error, { model }) => [
|
208
|
+
invalidatesTags: (_result, _error, { model }) => [
|
209
|
+
{ type: "Document", id: `${model}_LIST` },
|
210
|
+
{ type: "UidAvailability", id: model }
|
211
|
+
]
|
296
212
|
}),
|
297
213
|
/**
|
298
214
|
* Creates a new collection-type document. This should ONLY be used for collection-types.
|
@@ -309,7 +225,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
309
225
|
}),
|
310
226
|
invalidatesTags: (result, _error, { model }) => [
|
311
227
|
{ type: "Document", id: `${model}_LIST` },
|
312
|
-
"Relations"
|
228
|
+
"Relations",
|
229
|
+
{ type: "UidAvailability", id: model }
|
313
230
|
]
|
314
231
|
}),
|
315
232
|
deleteDocument: builder.mutation({
|
@@ -325,12 +242,15 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
325
242
|
]
|
326
243
|
}),
|
327
244
|
deleteManyDocuments: builder.mutation({
|
328
|
-
query: ({ model, ...body }) => ({
|
245
|
+
query: ({ model, params, ...body }) => ({
|
329
246
|
url: `/content-manager/collection-types/${model}/actions/bulkDelete`,
|
330
247
|
method: "POST",
|
331
|
-
data: body
|
248
|
+
data: body,
|
249
|
+
config: {
|
250
|
+
params
|
251
|
+
}
|
332
252
|
}),
|
333
|
-
invalidatesTags: (_res, _error, { model
|
253
|
+
invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
|
334
254
|
}),
|
335
255
|
discardDocument: builder.mutation({
|
336
256
|
query: ({ collectionType, model, documentId, params }) => ({
|
@@ -347,7 +267,8 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
347
267
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
348
268
|
},
|
349
269
|
{ type: "Document", id: `${model}_LIST` },
|
350
|
-
"Relations"
|
270
|
+
"Relations",
|
271
|
+
{ type: "UidAvailability", id: model }
|
351
272
|
];
|
352
273
|
}
|
353
274
|
}),
|
@@ -360,11 +281,12 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
360
281
|
url: `/content-manager/collection-types/${model}`,
|
361
282
|
method: "GET",
|
362
283
|
config: {
|
363
|
-
params
|
284
|
+
params: stringify(params, { encode: true })
|
364
285
|
}
|
365
286
|
}),
|
366
287
|
providesTags: (result, _error, arg) => {
|
367
288
|
return [
|
289
|
+
{ type: "Document", id: `ALL_LIST` },
|
368
290
|
{ type: "Document", id: `${arg.model}_LIST` },
|
369
291
|
...result?.results.map(({ documentId }) => ({
|
370
292
|
type: "Document",
|
@@ -403,6 +325,11 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
403
325
|
{
|
404
326
|
type: "Document",
|
405
327
|
id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
|
328
|
+
},
|
329
|
+
// Make it easy to invalidate all individual documents queries for a model
|
330
|
+
{
|
331
|
+
type: "Document",
|
332
|
+
id: `${model}_ALL_ITEMS`
|
406
333
|
}
|
407
334
|
];
|
408
335
|
}
|
@@ -441,10 +368,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
441
368
|
}
|
442
369
|
}),
|
443
370
|
publishManyDocuments: builder.mutation({
|
444
|
-
query: ({ model, ...body }) => ({
|
371
|
+
query: ({ model, params, ...body }) => ({
|
445
372
|
url: `/content-manager/collection-types/${model}/actions/bulkPublish`,
|
446
373
|
method: "POST",
|
447
|
-
data: body
|
374
|
+
data: body,
|
375
|
+
config: {
|
376
|
+
params
|
377
|
+
}
|
448
378
|
}),
|
449
379
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
450
380
|
}),
|
@@ -463,8 +393,21 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
463
393
|
type: "Document",
|
464
394
|
id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
|
465
395
|
},
|
466
|
-
"Relations"
|
396
|
+
"Relations",
|
397
|
+
{ type: "UidAvailability", id: model }
|
467
398
|
];
|
399
|
+
},
|
400
|
+
async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
|
401
|
+
const patchResult = dispatch(
|
402
|
+
documentApi.util.updateQueryData("getDocument", patch, (draft) => {
|
403
|
+
Object.assign(draft.data, data);
|
404
|
+
})
|
405
|
+
);
|
406
|
+
try {
|
407
|
+
await queryFulfilled;
|
408
|
+
} catch {
|
409
|
+
patchResult.undo();
|
410
|
+
}
|
468
411
|
}
|
469
412
|
}),
|
470
413
|
unpublishDocument: builder.mutation({
|
@@ -486,10 +429,13 @@ const documentApi = contentManagerApi.injectEndpoints({
|
|
486
429
|
}
|
487
430
|
}),
|
488
431
|
unpublishManyDocuments: builder.mutation({
|
489
|
-
query: ({ model, ...body }) => ({
|
432
|
+
query: ({ model, params, ...body }) => ({
|
490
433
|
url: `/content-manager/collection-types/${model}/actions/bulkUnpublish`,
|
491
434
|
method: "POST",
|
492
|
-
data: body
|
435
|
+
data: body,
|
436
|
+
config: {
|
437
|
+
params
|
438
|
+
}
|
493
439
|
}),
|
494
440
|
invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
|
495
441
|
})
|
@@ -513,20 +459,53 @@ const {
|
|
513
459
|
useUnpublishDocumentMutation,
|
514
460
|
useUnpublishManyDocumentsMutation
|
515
461
|
} = documentApi;
|
516
|
-
const
|
462
|
+
const buildValidParams = (query) => {
|
463
|
+
if (!query) return query;
|
464
|
+
const { plugins: _, ...validQueryParams } = {
|
465
|
+
...query,
|
466
|
+
...Object.values(query?.plugins ?? {}).reduce(
|
467
|
+
(acc, current) => Object.assign(acc, current),
|
468
|
+
{}
|
469
|
+
)
|
470
|
+
};
|
471
|
+
return validQueryParams;
|
472
|
+
};
|
473
|
+
const isBaseQueryError = (error) => {
|
474
|
+
return error.name !== void 0;
|
475
|
+
};
|
476
|
+
const arrayValidator = (attribute, options) => ({
|
477
|
+
message: translatedErrors.required,
|
478
|
+
test(value) {
|
479
|
+
if (options.status === "draft") {
|
480
|
+
return true;
|
481
|
+
}
|
482
|
+
if (!attribute.required) {
|
483
|
+
return true;
|
484
|
+
}
|
485
|
+
if (!value) {
|
486
|
+
return false;
|
487
|
+
}
|
488
|
+
if (Array.isArray(value) && value.length === 0) {
|
489
|
+
return false;
|
490
|
+
}
|
491
|
+
return true;
|
492
|
+
}
|
493
|
+
});
|
494
|
+
const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
|
517
495
|
const createModelSchema = (attributes2) => yup.object().shape(
|
518
496
|
Object.entries(attributes2).reduce((acc, [name, attribute]) => {
|
519
497
|
if (DOCUMENT_META_FIELDS.includes(name)) {
|
520
498
|
return acc;
|
521
499
|
}
|
522
500
|
const validations = [
|
501
|
+
addNullableValidation,
|
523
502
|
addRequiredValidation,
|
524
503
|
addMinLengthValidation,
|
525
504
|
addMaxLengthValidation,
|
526
505
|
addMinValidation,
|
527
506
|
addMaxValidation,
|
528
507
|
addRegexValidation
|
529
|
-
].map((fn) => fn(attribute));
|
508
|
+
].map((fn) => fn(attribute, options));
|
530
509
|
const transformSchema = pipe(...validations);
|
531
510
|
switch (attribute.type) {
|
532
511
|
case "component": {
|
@@ -536,12 +515,12 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
536
515
|
...acc,
|
537
516
|
[name]: transformSchema(
|
538
517
|
yup.array().of(createModelSchema(attributes3).nullable(false))
|
539
|
-
)
|
518
|
+
).test(arrayValidator(attribute, options))
|
540
519
|
};
|
541
520
|
} else {
|
542
521
|
return {
|
543
522
|
...acc,
|
544
|
-
[name]: transformSchema(createModelSchema(attributes3))
|
523
|
+
[name]: transformSchema(createModelSchema(attributes3).nullable())
|
545
524
|
};
|
546
525
|
}
|
547
526
|
}
|
@@ -552,24 +531,42 @@ const createYupSchema = (attributes = {}, components = {}) => {
|
|
552
531
|
yup.array().of(
|
553
532
|
yup.lazy(
|
554
533
|
(data) => {
|
555
|
-
const
|
556
|
-
|
534
|
+
const attributes3 = components?.[data?.__component]?.attributes;
|
535
|
+
const validation = yup.object().shape({
|
557
536
|
__component: yup.string().required().oneOf(Object.keys(components))
|
558
|
-
}).nullable(false)
|
537
|
+
}).nullable(false);
|
538
|
+
if (!attributes3) {
|
539
|
+
return validation;
|
540
|
+
}
|
541
|
+
return validation.concat(createModelSchema(attributes3));
|
559
542
|
}
|
560
543
|
)
|
561
544
|
)
|
562
|
-
)
|
545
|
+
).test(arrayValidator(attribute, options))
|
563
546
|
};
|
564
547
|
case "relation":
|
565
548
|
return {
|
566
549
|
...acc,
|
567
550
|
[name]: transformSchema(
|
568
|
-
yup.
|
569
|
-
|
570
|
-
|
571
|
-
})
|
572
|
-
|
551
|
+
yup.lazy((value) => {
|
552
|
+
if (!value) {
|
553
|
+
return yup.mixed().nullable(true);
|
554
|
+
} else if (Array.isArray(value)) {
|
555
|
+
return yup.array().of(
|
556
|
+
yup.object().shape({
|
557
|
+
id: yup.number().required()
|
558
|
+
})
|
559
|
+
);
|
560
|
+
} else if (typeof value === "object") {
|
561
|
+
return yup.object();
|
562
|
+
} else {
|
563
|
+
return yup.mixed().test(
|
564
|
+
"type-error",
|
565
|
+
"Relation values must be either null, an array of objects with {id} or an object.",
|
566
|
+
() => false
|
567
|
+
);
|
568
|
+
}
|
569
|
+
})
|
573
570
|
)
|
574
571
|
};
|
575
572
|
default:
|
@@ -609,6 +606,14 @@ const createAttributeSchema = (attribute) => {
|
|
609
606
|
if (!value || typeof value === "string" && value.length === 0) {
|
610
607
|
return true;
|
611
608
|
}
|
609
|
+
if (typeof value === "object") {
|
610
|
+
try {
|
611
|
+
JSON.stringify(value);
|
612
|
+
return true;
|
613
|
+
} catch (err) {
|
614
|
+
return false;
|
615
|
+
}
|
616
|
+
}
|
612
617
|
try {
|
613
618
|
JSON.parse(value);
|
614
619
|
return true;
|
@@ -627,16 +632,30 @@ const createAttributeSchema = (attribute) => {
|
|
627
632
|
return yup.mixed();
|
628
633
|
}
|
629
634
|
};
|
630
|
-
const
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
635
|
+
const nullableSchema = (schema) => {
|
636
|
+
return schema?.nullable ? schema.nullable() : (
|
637
|
+
// In some cases '.nullable' will not be available on the schema.
|
638
|
+
// e.g. when the schema has been built using yup.lazy (e.g. for relations).
|
639
|
+
// In these cases we should just return the schema as it is.
|
640
|
+
schema
|
641
|
+
);
|
642
|
+
};
|
643
|
+
const addNullableValidation = () => (schema) => {
|
644
|
+
return nullableSchema(schema);
|
645
|
+
};
|
646
|
+
const addRequiredValidation = (attribute, options) => (schema) => {
|
647
|
+
if (options.status === "draft" || !attribute.required) {
|
648
|
+
return schema;
|
636
649
|
}
|
637
|
-
|
650
|
+
if (attribute.required && "required" in schema) {
|
651
|
+
return schema.required(translatedErrors.required);
|
652
|
+
}
|
653
|
+
return schema;
|
638
654
|
};
|
639
|
-
const addMinLengthValidation = (attribute) => (schema) => {
|
655
|
+
const addMinLengthValidation = (attribute, options) => (schema) => {
|
656
|
+
if (options.status === "draft") {
|
657
|
+
return schema;
|
658
|
+
}
|
640
659
|
if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
|
641
660
|
return schema.min(attribute.minLength, {
|
642
661
|
...translatedErrors.minLength,
|
@@ -658,10 +677,13 @@ const addMaxLengthValidation = (attribute) => (schema) => {
|
|
658
677
|
}
|
659
678
|
return schema;
|
660
679
|
};
|
661
|
-
const addMinValidation = (attribute) => (schema) => {
|
662
|
-
if ("
|
680
|
+
const addMinValidation = (attribute, options) => (schema) => {
|
681
|
+
if (options.status === "draft") {
|
682
|
+
return schema;
|
683
|
+
}
|
684
|
+
if ("min" in attribute && "min" in schema) {
|
663
685
|
const min = toInteger(attribute.min);
|
664
|
-
if (
|
686
|
+
if (min) {
|
665
687
|
return schema.min(min, {
|
666
688
|
...translatedErrors.min,
|
667
689
|
values: {
|
@@ -706,24 +728,6 @@ const addRegexValidation = (attribute) => (schema) => {
|
|
706
728
|
}
|
707
729
|
return schema;
|
708
730
|
};
|
709
|
-
const extractValuesFromYupError = (errorType, errorParams) => {
|
710
|
-
if (!errorType || !errorParams) {
|
711
|
-
return {};
|
712
|
-
}
|
713
|
-
return {
|
714
|
-
[errorType]: errorParams[errorType]
|
715
|
-
};
|
716
|
-
};
|
717
|
-
const getInnerErrors = (error) => (error?.inner || []).reduce((acc, currentError) => {
|
718
|
-
if (currentError.path) {
|
719
|
-
acc[currentError.path.split("[").join(".").split("]").join("")] = {
|
720
|
-
id: currentError.message,
|
721
|
-
defaultMessage: currentError.message,
|
722
|
-
values: extractValuesFromYupError(currentError?.type, currentError?.params)
|
723
|
-
};
|
724
|
-
}
|
725
|
-
return acc;
|
726
|
-
}, {});
|
727
731
|
const initApi = contentManagerApi.injectEndpoints({
|
728
732
|
endpoints: (builder) => ({
|
729
733
|
getInitialData: builder.query({
|
@@ -737,27 +741,20 @@ const { useGetInitialDataQuery } = initApi;
|
|
737
741
|
const useContentTypeSchema = (model) => {
|
738
742
|
const { toggleNotification } = useNotification();
|
739
743
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
740
|
-
const {
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
)
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
error: res.error,
|
755
|
-
components: Object.keys(components2).length === 0 ? void 0 : components2,
|
756
|
-
contentType: contentType2,
|
757
|
-
contentTypes: res.data?.contentTypes ?? []
|
758
|
-
};
|
759
|
-
}
|
760
|
-
});
|
744
|
+
const { data, error, isLoading, isFetching } = useGetInitialDataQuery(void 0);
|
745
|
+
const { components, contentType, contentTypes } = React.useMemo(() => {
|
746
|
+
const contentType2 = data?.contentTypes.find((ct) => ct.uid === model);
|
747
|
+
const componentsByKey = data?.components.reduce((acc, component) => {
|
748
|
+
acc[component.uid] = component;
|
749
|
+
return acc;
|
750
|
+
}, {});
|
751
|
+
const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
|
752
|
+
return {
|
753
|
+
components: Object.keys(components2).length === 0 ? void 0 : components2,
|
754
|
+
contentType: contentType2,
|
755
|
+
contentTypes: data?.contentTypes ?? []
|
756
|
+
};
|
757
|
+
}, [model, data]);
|
761
758
|
React.useEffect(() => {
|
762
759
|
if (error) {
|
763
760
|
toggleNotification({
|
@@ -804,17 +801,329 @@ const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
|
|
804
801
|
}, {});
|
805
802
|
return componentsByKey;
|
806
803
|
};
|
807
|
-
const
|
804
|
+
const HOOKS = {
|
805
|
+
/**
|
806
|
+
* Hook that allows to mutate the displayed headers of the list view table
|
807
|
+
* @constant
|
808
|
+
* @type {string}
|
809
|
+
*/
|
810
|
+
INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
|
811
|
+
/**
|
812
|
+
* Hook that allows to mutate the CM's collection types links pre-set filters
|
813
|
+
* @constant
|
814
|
+
* @type {string}
|
815
|
+
*/
|
816
|
+
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
817
|
+
/**
|
818
|
+
* Hook that allows to mutate the CM's edit view layout
|
819
|
+
* @constant
|
820
|
+
* @type {string}
|
821
|
+
*/
|
822
|
+
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
823
|
+
/**
|
824
|
+
* Hook that allows to mutate the CM's single types links pre-set filters
|
825
|
+
* @constant
|
826
|
+
* @type {string}
|
827
|
+
*/
|
828
|
+
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
829
|
+
};
|
830
|
+
const contentTypesApi = contentManagerApi.injectEndpoints({
|
831
|
+
endpoints: (builder) => ({
|
832
|
+
getContentTypeConfiguration: builder.query({
|
833
|
+
query: (uid) => ({
|
834
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
835
|
+
method: "GET"
|
836
|
+
}),
|
837
|
+
transformResponse: (response) => response.data,
|
838
|
+
providesTags: (_result, _error, uid) => [
|
839
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
840
|
+
{ type: "ContentTypeSettings", id: "LIST" }
|
841
|
+
]
|
842
|
+
}),
|
843
|
+
getAllContentTypeSettings: builder.query({
|
844
|
+
query: () => "/content-manager/content-types-settings",
|
845
|
+
transformResponse: (response) => response.data,
|
846
|
+
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
847
|
+
}),
|
848
|
+
updateContentTypeConfiguration: builder.mutation({
|
849
|
+
query: ({ uid, ...body }) => ({
|
850
|
+
url: `/content-manager/content-types/${uid}/configuration`,
|
851
|
+
method: "PUT",
|
852
|
+
data: body
|
853
|
+
}),
|
854
|
+
transformResponse: (response) => response.data,
|
855
|
+
invalidatesTags: (_result, _error, { uid }) => [
|
856
|
+
{ type: "ContentTypesConfiguration", id: uid },
|
857
|
+
{ type: "ContentTypeSettings", id: "LIST" },
|
858
|
+
// Is this necessary?
|
859
|
+
{ type: "InitialData" }
|
860
|
+
]
|
861
|
+
})
|
862
|
+
})
|
863
|
+
});
|
864
|
+
const {
|
865
|
+
useGetContentTypeConfigurationQuery,
|
866
|
+
useGetAllContentTypeSettingsQuery,
|
867
|
+
useUpdateContentTypeConfigurationMutation
|
868
|
+
} = contentTypesApi;
|
869
|
+
const checkIfAttributeIsDisplayable = (attribute) => {
|
870
|
+
const { type } = attribute;
|
871
|
+
if (type === "relation") {
|
872
|
+
return !attribute.relation.toLowerCase().includes("morph");
|
873
|
+
}
|
874
|
+
return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
|
875
|
+
};
|
876
|
+
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
877
|
+
if (!mainFieldName) {
|
878
|
+
return void 0;
|
879
|
+
}
|
880
|
+
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
881
|
+
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
882
|
+
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
883
|
+
);
|
884
|
+
return {
|
885
|
+
name: mainFieldName,
|
886
|
+
type: mainFieldType ?? "string"
|
887
|
+
};
|
888
|
+
};
|
889
|
+
const DEFAULT_SETTINGS = {
|
890
|
+
bulkable: false,
|
891
|
+
filterable: false,
|
892
|
+
searchable: false,
|
893
|
+
pagination: false,
|
894
|
+
defaultSortBy: "",
|
895
|
+
defaultSortOrder: "asc",
|
896
|
+
mainField: "id",
|
897
|
+
pageSize: 10
|
898
|
+
};
|
899
|
+
const useDocumentLayout = (model) => {
|
900
|
+
const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
|
901
|
+
const [{ query }] = useQueryParams();
|
902
|
+
const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
|
808
903
|
const { toggleNotification } = useNotification();
|
809
904
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
905
|
+
const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
|
810
906
|
const {
|
811
|
-
|
812
|
-
isLoading:
|
813
|
-
|
814
|
-
|
815
|
-
} =
|
816
|
-
const
|
817
|
-
React.useEffect(() => {
|
907
|
+
data,
|
908
|
+
isLoading: isLoadingConfigs,
|
909
|
+
error,
|
910
|
+
isFetching: isFetchingConfigs
|
911
|
+
} = useGetContentTypeConfigurationQuery(model);
|
912
|
+
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
913
|
+
React.useEffect(() => {
|
914
|
+
if (error) {
|
915
|
+
toggleNotification({
|
916
|
+
type: "danger",
|
917
|
+
message: formatAPIError(error)
|
918
|
+
});
|
919
|
+
}
|
920
|
+
}, [error, formatAPIError, toggleNotification]);
|
921
|
+
const editLayout = React.useMemo(
|
922
|
+
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
923
|
+
layout: [],
|
924
|
+
components: {},
|
925
|
+
metadatas: {},
|
926
|
+
options: {},
|
927
|
+
settings: DEFAULT_SETTINGS
|
928
|
+
},
|
929
|
+
[data, isLoading, schemas, schema, components]
|
930
|
+
);
|
931
|
+
const listLayout = React.useMemo(() => {
|
932
|
+
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
933
|
+
layout: [],
|
934
|
+
metadatas: {},
|
935
|
+
options: {},
|
936
|
+
settings: DEFAULT_SETTINGS
|
937
|
+
};
|
938
|
+
}, [data, isLoading, schemas, schema, components]);
|
939
|
+
const { layout: edit } = React.useMemo(
|
940
|
+
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
941
|
+
layout: editLayout,
|
942
|
+
query
|
943
|
+
}),
|
944
|
+
[editLayout, query, runHookWaterfall]
|
945
|
+
);
|
946
|
+
return {
|
947
|
+
error,
|
948
|
+
isLoading,
|
949
|
+
edit,
|
950
|
+
list: listLayout
|
951
|
+
};
|
952
|
+
};
|
953
|
+
const useDocLayout = () => {
|
954
|
+
const { model } = useDoc();
|
955
|
+
return useDocumentLayout(model);
|
956
|
+
};
|
957
|
+
const formatEditLayout = (data, {
|
958
|
+
schemas,
|
959
|
+
schema,
|
960
|
+
components
|
961
|
+
}) => {
|
962
|
+
let currentPanelIndex = 0;
|
963
|
+
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
964
|
+
data.contentType.layouts.edit,
|
965
|
+
schema?.attributes,
|
966
|
+
data.contentType.metadatas,
|
967
|
+
{ configurations: data.components, schemas: components },
|
968
|
+
schemas
|
969
|
+
).reduce((panels, row) => {
|
970
|
+
if (row.some((field) => field.type === "dynamiczone")) {
|
971
|
+
panels.push([row]);
|
972
|
+
currentPanelIndex += 2;
|
973
|
+
} else {
|
974
|
+
if (!panels[currentPanelIndex]) {
|
975
|
+
panels.push([row]);
|
976
|
+
} else {
|
977
|
+
panels[currentPanelIndex].push(row);
|
978
|
+
}
|
979
|
+
}
|
980
|
+
return panels;
|
981
|
+
}, []);
|
982
|
+
const componentEditAttributes = Object.entries(data.components).reduce(
|
983
|
+
(acc, [uid, configuration]) => {
|
984
|
+
acc[uid] = {
|
985
|
+
layout: convertEditLayoutToFieldLayouts(
|
986
|
+
configuration.layouts.edit,
|
987
|
+
components[uid].attributes,
|
988
|
+
configuration.metadatas,
|
989
|
+
{ configurations: data.components, schemas: components }
|
990
|
+
),
|
991
|
+
settings: {
|
992
|
+
...configuration.settings,
|
993
|
+
icon: components[uid].info.icon,
|
994
|
+
displayName: components[uid].info.displayName
|
995
|
+
}
|
996
|
+
};
|
997
|
+
return acc;
|
998
|
+
},
|
999
|
+
{}
|
1000
|
+
);
|
1001
|
+
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1002
|
+
(acc, [attribute, metadata]) => {
|
1003
|
+
return {
|
1004
|
+
...acc,
|
1005
|
+
[attribute]: metadata.edit
|
1006
|
+
};
|
1007
|
+
},
|
1008
|
+
{}
|
1009
|
+
);
|
1010
|
+
return {
|
1011
|
+
layout: panelledEditAttributes,
|
1012
|
+
components: componentEditAttributes,
|
1013
|
+
metadatas: editMetadatas,
|
1014
|
+
settings: {
|
1015
|
+
...data.contentType.settings,
|
1016
|
+
displayName: schema?.info.displayName
|
1017
|
+
},
|
1018
|
+
options: {
|
1019
|
+
...schema?.options,
|
1020
|
+
...schema?.pluginOptions,
|
1021
|
+
...data.contentType.options
|
1022
|
+
}
|
1023
|
+
};
|
1024
|
+
};
|
1025
|
+
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
1026
|
+
return rows.map(
|
1027
|
+
(row) => row.map((field) => {
|
1028
|
+
const attribute = attributes[field.name];
|
1029
|
+
if (!attribute) {
|
1030
|
+
return null;
|
1031
|
+
}
|
1032
|
+
const { edit: metadata } = metadatas[field.name];
|
1033
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1034
|
+
return {
|
1035
|
+
attribute,
|
1036
|
+
disabled: !metadata.editable,
|
1037
|
+
hint: metadata.description,
|
1038
|
+
label: metadata.label ?? "",
|
1039
|
+
name: field.name,
|
1040
|
+
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
1041
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1042
|
+
schemas,
|
1043
|
+
components: components?.schemas ?? {}
|
1044
|
+
}),
|
1045
|
+
placeholder: metadata.placeholder ?? "",
|
1046
|
+
required: attribute.required ?? false,
|
1047
|
+
size: field.size,
|
1048
|
+
unique: "unique" in attribute ? attribute.unique : false,
|
1049
|
+
visible: metadata.visible ?? true,
|
1050
|
+
type: attribute.type
|
1051
|
+
};
|
1052
|
+
}).filter((field) => field !== null)
|
1053
|
+
);
|
1054
|
+
};
|
1055
|
+
const formatListLayout = (data, {
|
1056
|
+
schemas,
|
1057
|
+
schema,
|
1058
|
+
components
|
1059
|
+
}) => {
|
1060
|
+
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
1061
|
+
(acc, [attribute, metadata]) => {
|
1062
|
+
return {
|
1063
|
+
...acc,
|
1064
|
+
[attribute]: metadata.list
|
1065
|
+
};
|
1066
|
+
},
|
1067
|
+
{}
|
1068
|
+
);
|
1069
|
+
const listAttributes = convertListLayoutToFieldLayouts(
|
1070
|
+
data.contentType.layouts.list,
|
1071
|
+
schema?.attributes,
|
1072
|
+
listMetadatas,
|
1073
|
+
{ configurations: data.components, schemas: components },
|
1074
|
+
schemas
|
1075
|
+
);
|
1076
|
+
return {
|
1077
|
+
layout: listAttributes,
|
1078
|
+
settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
|
1079
|
+
metadatas: listMetadatas,
|
1080
|
+
options: {
|
1081
|
+
...schema?.options,
|
1082
|
+
...schema?.pluginOptions,
|
1083
|
+
...data.contentType.options
|
1084
|
+
}
|
1085
|
+
};
|
1086
|
+
};
|
1087
|
+
const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
|
1088
|
+
return columns.map((name) => {
|
1089
|
+
const attribute = attributes[name];
|
1090
|
+
if (!attribute) {
|
1091
|
+
return null;
|
1092
|
+
}
|
1093
|
+
const metadata = metadatas[name];
|
1094
|
+
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
1095
|
+
return {
|
1096
|
+
attribute,
|
1097
|
+
label: metadata.label ?? "",
|
1098
|
+
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
1099
|
+
schemas,
|
1100
|
+
components: components?.schemas ?? {}
|
1101
|
+
}),
|
1102
|
+
name,
|
1103
|
+
searchable: metadata.searchable ?? true,
|
1104
|
+
sortable: metadata.sortable ?? true
|
1105
|
+
};
|
1106
|
+
}).filter((field) => field !== null);
|
1107
|
+
};
|
1108
|
+
const useDocument = (args, opts) => {
|
1109
|
+
const { toggleNotification } = useNotification();
|
1110
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1111
|
+
const {
|
1112
|
+
currentData: data,
|
1113
|
+
isLoading: isLoadingDocument,
|
1114
|
+
isFetching: isFetchingDocument,
|
1115
|
+
error
|
1116
|
+
} = useGetDocumentQuery(args, {
|
1117
|
+
...opts,
|
1118
|
+
skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
|
1119
|
+
});
|
1120
|
+
const {
|
1121
|
+
components,
|
1122
|
+
schema,
|
1123
|
+
schemas,
|
1124
|
+
isLoading: isLoadingSchema
|
1125
|
+
} = useContentTypeSchema(args.model);
|
1126
|
+
React.useEffect(() => {
|
818
1127
|
if (error) {
|
819
1128
|
toggleNotification({
|
820
1129
|
type: "danger",
|
@@ -840,7 +1149,7 @@ const useDocument = (args, opts) => {
|
|
840
1149
|
return null;
|
841
1150
|
} catch (error2) {
|
842
1151
|
if (error2 instanceof ValidationError) {
|
843
|
-
return
|
1152
|
+
return getYupValidationErrors(error2);
|
844
1153
|
}
|
845
1154
|
throw error2;
|
846
1155
|
}
|
@@ -848,12 +1157,15 @@ const useDocument = (args, opts) => {
|
|
848
1157
|
[validationSchema]
|
849
1158
|
);
|
850
1159
|
const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
|
1160
|
+
const hasError = !!error;
|
851
1161
|
return {
|
852
1162
|
components,
|
853
1163
|
document: data?.data,
|
854
1164
|
meta: data?.meta,
|
855
1165
|
isLoading,
|
1166
|
+
hasError,
|
856
1167
|
schema,
|
1168
|
+
schemas,
|
857
1169
|
validate
|
858
1170
|
};
|
859
1171
|
};
|
@@ -867,22 +1179,60 @@ const useDoc = () => {
|
|
867
1179
|
if (!slug) {
|
868
1180
|
throw new Error("Could not find model in url params");
|
869
1181
|
}
|
1182
|
+
const document = useDocument(
|
1183
|
+
{ documentId: origin || id, model: slug, collectionType, params },
|
1184
|
+
{
|
1185
|
+
skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
|
1186
|
+
}
|
1187
|
+
);
|
1188
|
+
const returnId = origin || id === "create" ? void 0 : id;
|
870
1189
|
return {
|
871
1190
|
collectionType,
|
872
1191
|
model: slug,
|
873
|
-
id:
|
874
|
-
...
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
1192
|
+
id: returnId,
|
1193
|
+
...document
|
1194
|
+
};
|
1195
|
+
};
|
1196
|
+
const useContentManagerContext = () => {
|
1197
|
+
const {
|
1198
|
+
collectionType,
|
1199
|
+
model,
|
1200
|
+
id,
|
1201
|
+
components,
|
1202
|
+
isLoading: isLoadingDoc,
|
1203
|
+
schema,
|
1204
|
+
schemas
|
1205
|
+
} = useDoc();
|
1206
|
+
const layout = useDocumentLayout(model);
|
1207
|
+
const form = useForm("useContentManagerContext", (state) => state);
|
1208
|
+
const isSingleType = collectionType === SINGLE_TYPES;
|
1209
|
+
const slug = model;
|
1210
|
+
const isCreatingEntry = id === "create";
|
1211
|
+
useContentTypeSchema();
|
1212
|
+
const isLoading = isLoadingDoc || layout.isLoading;
|
1213
|
+
const error = layout.error;
|
1214
|
+
return {
|
1215
|
+
error,
|
1216
|
+
isLoading,
|
1217
|
+
// Base metadata
|
1218
|
+
model,
|
1219
|
+
collectionType,
|
1220
|
+
id,
|
1221
|
+
slug,
|
1222
|
+
isCreatingEntry,
|
1223
|
+
isSingleType,
|
1224
|
+
hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
|
1225
|
+
// All schema infos
|
1226
|
+
components,
|
1227
|
+
contentType: schema,
|
1228
|
+
contentTypes: schemas,
|
1229
|
+
// Form state
|
1230
|
+
form,
|
1231
|
+
// layout infos
|
1232
|
+
layout
|
880
1233
|
};
|
881
1234
|
};
|
882
1235
|
const prefixPluginTranslations = (trad, pluginId) => {
|
883
|
-
if (!pluginId) {
|
884
|
-
throw new TypeError("pluginId can't be empty");
|
885
|
-
}
|
886
1236
|
return Object.keys(trad).reduce((acc, current) => {
|
887
1237
|
acc[`${pluginId}.${current}`] = trad[current];
|
888
1238
|
return acc;
|
@@ -898,6 +1248,8 @@ const useDocumentActions = () => {
|
|
898
1248
|
const { formatMessage } = useIntl();
|
899
1249
|
const { trackUsage } = useTracking();
|
900
1250
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
1251
|
+
const navigate = useNavigate();
|
1252
|
+
const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
|
901
1253
|
const [deleteDocument] = useDeleteDocumentMutation();
|
902
1254
|
const _delete = React.useCallback(
|
903
1255
|
async ({ collectionType, model, documentId, params }, trackerProperty) => {
|
@@ -936,14 +1288,15 @@ const useDocumentActions = () => {
|
|
936
1288
|
},
|
937
1289
|
[trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
|
938
1290
|
);
|
939
|
-
const [
|
940
|
-
const
|
941
|
-
async ({
|
1291
|
+
const [deleteManyDocuments] = useDeleteManyDocumentsMutation();
|
1292
|
+
const deleteMany = React.useCallback(
|
1293
|
+
async ({ model, documentIds, params }) => {
|
942
1294
|
try {
|
943
|
-
|
944
|
-
|
1295
|
+
trackUsage("willBulkDeleteEntries");
|
1296
|
+
const res = await deleteManyDocuments({
|
945
1297
|
model,
|
946
|
-
|
1298
|
+
documentIds,
|
1299
|
+
params
|
947
1300
|
});
|
948
1301
|
if ("error" in res) {
|
949
1302
|
toggleNotification({
|
@@ -954,39 +1307,77 @@ const useDocumentActions = () => {
|
|
954
1307
|
}
|
955
1308
|
toggleNotification({
|
956
1309
|
type: "success",
|
957
|
-
|
958
|
-
id: "
|
959
|
-
defaultMessage: "
|
960
|
-
})
|
1310
|
+
title: formatMessage({
|
1311
|
+
id: getTranslation("success.records.delete"),
|
1312
|
+
defaultMessage: "Successfully deleted."
|
1313
|
+
}),
|
1314
|
+
message: ""
|
961
1315
|
});
|
1316
|
+
trackUsage("didBulkDeleteEntries");
|
962
1317
|
return res.data;
|
963
1318
|
} catch (err) {
|
964
1319
|
toggleNotification({
|
965
1320
|
type: "danger",
|
966
1321
|
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
967
1322
|
});
|
1323
|
+
trackUsage("didNotBulkDeleteEntries");
|
968
1324
|
throw err;
|
969
1325
|
}
|
970
1326
|
},
|
971
|
-
[
|
1327
|
+
[trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
972
1328
|
);
|
973
|
-
const [
|
974
|
-
const
|
975
|
-
async ({ collectionType, model, documentId, params }
|
1329
|
+
const [discardDocument] = useDiscardDocumentMutation();
|
1330
|
+
const discard = React.useCallback(
|
1331
|
+
async ({ collectionType, model, documentId, params }) => {
|
976
1332
|
try {
|
977
|
-
|
978
|
-
const res = await publishDocument({
|
1333
|
+
const res = await discardDocument({
|
979
1334
|
collectionType,
|
980
1335
|
model,
|
981
1336
|
documentId,
|
982
|
-
data,
|
983
1337
|
params
|
984
1338
|
});
|
985
1339
|
if ("error" in res) {
|
986
|
-
toggleNotification({
|
987
|
-
|
988
|
-
|
989
|
-
|
1340
|
+
toggleNotification({
|
1341
|
+
type: "danger",
|
1342
|
+
message: formatAPIError(res.error)
|
1343
|
+
});
|
1344
|
+
return { error: res.error };
|
1345
|
+
}
|
1346
|
+
toggleNotification({
|
1347
|
+
type: "success",
|
1348
|
+
message: formatMessage({
|
1349
|
+
id: "content-manager.success.record.discard",
|
1350
|
+
defaultMessage: "Changes discarded"
|
1351
|
+
})
|
1352
|
+
});
|
1353
|
+
return res.data;
|
1354
|
+
} catch (err) {
|
1355
|
+
toggleNotification({
|
1356
|
+
type: "danger",
|
1357
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1358
|
+
});
|
1359
|
+
throw err;
|
1360
|
+
}
|
1361
|
+
},
|
1362
|
+
[discardDocument, formatAPIError, formatMessage, toggleNotification]
|
1363
|
+
);
|
1364
|
+
const [publishDocument] = usePublishDocumentMutation();
|
1365
|
+
const publish = React.useCallback(
|
1366
|
+
async ({ collectionType, model, documentId, params }, data) => {
|
1367
|
+
try {
|
1368
|
+
trackUsage("willPublishEntry");
|
1369
|
+
const res = await publishDocument({
|
1370
|
+
collectionType,
|
1371
|
+
model,
|
1372
|
+
documentId,
|
1373
|
+
data,
|
1374
|
+
params
|
1375
|
+
});
|
1376
|
+
if ("error" in res) {
|
1377
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1378
|
+
return { error: res.error };
|
1379
|
+
}
|
1380
|
+
trackUsage("didPublishEntry");
|
990
1381
|
toggleNotification({
|
991
1382
|
type: "success",
|
992
1383
|
message: formatMessage({
|
@@ -1005,6 +1396,43 @@ const useDocumentActions = () => {
|
|
1005
1396
|
},
|
1006
1397
|
[trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
|
1007
1398
|
);
|
1399
|
+
const [publishManyDocuments] = usePublishManyDocumentsMutation();
|
1400
|
+
const publishMany = React.useCallback(
|
1401
|
+
async ({ model, documentIds, params }) => {
|
1402
|
+
try {
|
1403
|
+
const res = await publishManyDocuments({
|
1404
|
+
model,
|
1405
|
+
documentIds,
|
1406
|
+
params
|
1407
|
+
});
|
1408
|
+
if ("error" in res) {
|
1409
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1410
|
+
return { error: res.error };
|
1411
|
+
}
|
1412
|
+
toggleNotification({
|
1413
|
+
type: "success",
|
1414
|
+
message: formatMessage({
|
1415
|
+
id: getTranslation("success.record.publish"),
|
1416
|
+
defaultMessage: "Published document"
|
1417
|
+
})
|
1418
|
+
});
|
1419
|
+
return res.data;
|
1420
|
+
} catch (err) {
|
1421
|
+
toggleNotification({
|
1422
|
+
type: "danger",
|
1423
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1424
|
+
});
|
1425
|
+
throw err;
|
1426
|
+
}
|
1427
|
+
},
|
1428
|
+
[
|
1429
|
+
// trackUsage,
|
1430
|
+
publishManyDocuments,
|
1431
|
+
toggleNotification,
|
1432
|
+
formatMessage,
|
1433
|
+
formatAPIError
|
1434
|
+
]
|
1435
|
+
);
|
1008
1436
|
const [updateDocument] = useUpdateDocumentMutation();
|
1009
1437
|
const update = React.useCallback(
|
1010
1438
|
async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
|
@@ -1079,6 +1507,41 @@ const useDocumentActions = () => {
|
|
1079
1507
|
},
|
1080
1508
|
[trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
|
1081
1509
|
);
|
1510
|
+
const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
|
1511
|
+
const unpublishMany = React.useCallback(
|
1512
|
+
async ({ model, documentIds, params }) => {
|
1513
|
+
try {
|
1514
|
+
trackUsage("willBulkUnpublishEntries");
|
1515
|
+
const res = await unpublishManyDocuments({
|
1516
|
+
model,
|
1517
|
+
documentIds,
|
1518
|
+
params
|
1519
|
+
});
|
1520
|
+
if ("error" in res) {
|
1521
|
+
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1522
|
+
return { error: res.error };
|
1523
|
+
}
|
1524
|
+
trackUsage("didBulkUnpublishEntries");
|
1525
|
+
toggleNotification({
|
1526
|
+
type: "success",
|
1527
|
+
title: formatMessage({
|
1528
|
+
id: getTranslation("success.records.unpublish"),
|
1529
|
+
defaultMessage: "Successfully unpublished."
|
1530
|
+
}),
|
1531
|
+
message: ""
|
1532
|
+
});
|
1533
|
+
return res.data;
|
1534
|
+
} catch (err) {
|
1535
|
+
toggleNotification({
|
1536
|
+
type: "danger",
|
1537
|
+
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
|
1538
|
+
});
|
1539
|
+
trackUsage("didNotBulkUnpublishEntries");
|
1540
|
+
throw err;
|
1541
|
+
}
|
1542
|
+
},
|
1543
|
+
[trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
|
1544
|
+
);
|
1082
1545
|
const [createDocument] = useCreateDocumentMutation();
|
1083
1546
|
const create = React.useCallback(
|
1084
1547
|
async ({ model, params }, data, trackerProperty) => {
|
@@ -1101,6 +1564,7 @@ const useDocumentActions = () => {
|
|
1101
1564
|
defaultMessage: "Saved document"
|
1102
1565
|
})
|
1103
1566
|
});
|
1567
|
+
setCurrentStep("contentManager.success");
|
1104
1568
|
return res.data;
|
1105
1569
|
} catch (err) {
|
1106
1570
|
toggleNotification({
|
@@ -1122,7 +1586,6 @@ const useDocumentActions = () => {
|
|
1122
1586
|
sourceId
|
1123
1587
|
});
|
1124
1588
|
if ("error" in res) {
|
1125
|
-
toggleNotification({ type: "danger", message: formatAPIError(res.error) });
|
1126
1589
|
return { error: res.error };
|
1127
1590
|
}
|
1128
1591
|
toggleNotification({
|
@@ -1141,7 +1604,7 @@ const useDocumentActions = () => {
|
|
1141
1604
|
throw err;
|
1142
1605
|
}
|
1143
1606
|
},
|
1144
|
-
[autoCloneDocument,
|
1607
|
+
[autoCloneDocument, formatMessage, toggleNotification]
|
1145
1608
|
);
|
1146
1609
|
const [cloneDocument] = useCloneDocumentMutation();
|
1147
1610
|
const clone = React.useCallback(
|
@@ -1167,6 +1630,7 @@ const useDocumentActions = () => {
|
|
1167
1630
|
defaultMessage: "Cloned document"
|
1168
1631
|
})
|
1169
1632
|
});
|
1633
|
+
navigate(`../../${res.data.data.documentId}`, { relative: "path" });
|
1170
1634
|
return res.data;
|
1171
1635
|
} catch (err) {
|
1172
1636
|
toggleNotification({
|
@@ -1177,7 +1641,7 @@ const useDocumentActions = () => {
|
|
1177
1641
|
throw err;
|
1178
1642
|
}
|
1179
1643
|
},
|
1180
|
-
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError]
|
1644
|
+
[cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
|
1181
1645
|
);
|
1182
1646
|
const [getDoc] = useLazyGetDocumentQuery();
|
1183
1647
|
const getDocument = React.useCallback(
|
@@ -1192,17 +1656,20 @@ const useDocumentActions = () => {
|
|
1192
1656
|
clone,
|
1193
1657
|
create,
|
1194
1658
|
delete: _delete,
|
1659
|
+
deleteMany,
|
1195
1660
|
discard,
|
1196
1661
|
getDocument,
|
1197
1662
|
publish,
|
1663
|
+
publishMany,
|
1198
1664
|
unpublish,
|
1665
|
+
unpublishMany,
|
1199
1666
|
update
|
1200
1667
|
};
|
1201
1668
|
};
|
1202
|
-
const ProtectedHistoryPage = lazy(
|
1203
|
-
() => import("./History-
|
1669
|
+
const ProtectedHistoryPage = React.lazy(
|
1670
|
+
() => import("./History-D8F7aYQU.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
|
1204
1671
|
);
|
1205
|
-
const routes$
|
1672
|
+
const routes$2 = [
|
1206
1673
|
{
|
1207
1674
|
path: ":collectionType/:slug/:id/history",
|
1208
1675
|
Component: ProtectedHistoryPage
|
@@ -1212,32 +1679,45 @@ const routes$1 = [
|
|
1212
1679
|
Component: ProtectedHistoryPage
|
1213
1680
|
}
|
1214
1681
|
];
|
1682
|
+
const ProtectedPreviewPage = React.lazy(
|
1683
|
+
() => import("./Preview-DECOhK0D.mjs").then((mod) => ({ default: mod.ProtectedPreviewPage }))
|
1684
|
+
);
|
1685
|
+
const routes$1 = [
|
1686
|
+
{
|
1687
|
+
path: ":collectionType/:slug/:id/preview",
|
1688
|
+
Component: ProtectedPreviewPage
|
1689
|
+
},
|
1690
|
+
{
|
1691
|
+
path: ":collectionType/:slug/preview",
|
1692
|
+
Component: ProtectedPreviewPage
|
1693
|
+
}
|
1694
|
+
];
|
1215
1695
|
const ProtectedEditViewPage = lazy(
|
1216
|
-
() => import("./EditViewPage-
|
1696
|
+
() => import("./EditViewPage-oOLeTySr.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
|
1217
1697
|
);
|
1218
1698
|
const ProtectedListViewPage = lazy(
|
1219
|
-
() => import("./ListViewPage-
|
1699
|
+
() => import("./ListViewPage-C73F0jPh.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
|
1220
1700
|
);
|
1221
1701
|
const ProtectedListConfiguration = lazy(
|
1222
|
-
() => import("./ListConfigurationPage-
|
1702
|
+
() => import("./ListConfigurationPage-DqAdSPwC.mjs").then((mod) => ({
|
1223
1703
|
default: mod.ProtectedListConfiguration
|
1224
1704
|
}))
|
1225
1705
|
);
|
1226
1706
|
const ProtectedEditConfigurationPage = lazy(
|
1227
|
-
() => import("./EditConfigurationPage-
|
1707
|
+
() => import("./EditConfigurationPage-BZPXItXo.mjs").then((mod) => ({
|
1228
1708
|
default: mod.ProtectedEditConfigurationPage
|
1229
1709
|
}))
|
1230
1710
|
);
|
1231
1711
|
const ProtectedComponentConfigurationPage = lazy(
|
1232
|
-
() => import("./ComponentConfigurationPage-
|
1712
|
+
() => import("./ComponentConfigurationPage-DaPOlQaD.mjs").then((mod) => ({
|
1233
1713
|
default: mod.ProtectedComponentConfigurationPage
|
1234
1714
|
}))
|
1235
1715
|
);
|
1236
1716
|
const NoPermissions = lazy(
|
1237
|
-
() => import("./NoPermissionsPage-
|
1717
|
+
() => import("./NoPermissionsPage-UnEgMGK4.mjs").then((mod) => ({ default: mod.NoPermissions }))
|
1238
1718
|
);
|
1239
1719
|
const NoContentType = lazy(
|
1240
|
-
() => import("./NoContentTypePage-
|
1720
|
+
() => import("./NoContentTypePage-B5w7iJOF.mjs").then((mod) => ({ default: mod.NoContentType }))
|
1241
1721
|
);
|
1242
1722
|
const CollectionTypePages = () => {
|
1243
1723
|
const { collectionType } = useParams();
|
@@ -1249,7 +1729,7 @@ const CollectionTypePages = () => {
|
|
1249
1729
|
const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
|
1250
1730
|
const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
|
1251
1731
|
const LIST_RELATIVE_PATH = ":collectionType/:slug";
|
1252
|
-
const LIST_PATH = `/content-manager
|
1732
|
+
const LIST_PATH = `/content-manager/collection-types/:slug`;
|
1253
1733
|
const routes = [
|
1254
1734
|
{
|
1255
1735
|
path: LIST_RELATIVE_PATH,
|
@@ -1283,6 +1763,7 @@ const routes = [
|
|
1283
1763
|
path: "no-content-types",
|
1284
1764
|
Component: NoContentType
|
1285
1765
|
},
|
1766
|
+
...routes$2,
|
1286
1767
|
...routes$1
|
1287
1768
|
];
|
1288
1769
|
const DocumentActions = ({ actions: actions2 }) => {
|
@@ -1351,12 +1832,14 @@ const DocumentActionButton = (action) => {
|
|
1351
1832
|
/* @__PURE__ */ jsx(
|
1352
1833
|
Button,
|
1353
1834
|
{
|
1354
|
-
flex:
|
1835
|
+
flex: "auto",
|
1355
1836
|
startIcon: action.icon,
|
1356
1837
|
disabled: action.disabled,
|
1357
1838
|
onClick: handleClick(action),
|
1358
1839
|
justifyContent: "center",
|
1359
1840
|
variant: action.variant || "default",
|
1841
|
+
paddingTop: "7px",
|
1842
|
+
paddingBottom: "7px",
|
1360
1843
|
children: action.label
|
1361
1844
|
}
|
1362
1845
|
),
|
@@ -1364,7 +1847,7 @@ const DocumentActionButton = (action) => {
|
|
1364
1847
|
DocumentActionConfirmDialog,
|
1365
1848
|
{
|
1366
1849
|
...action.dialog,
|
1367
|
-
variant: action.variant,
|
1850
|
+
variant: action.dialog?.variant ?? action.variant,
|
1368
1851
|
isOpen: dialogId === action.id,
|
1369
1852
|
onClose: handleClose
|
1370
1853
|
}
|
@@ -1379,6 +1862,11 @@ const DocumentActionButton = (action) => {
|
|
1379
1862
|
) : null
|
1380
1863
|
] });
|
1381
1864
|
};
|
1865
|
+
const MenuItem = styled(Menu.Item)`
|
1866
|
+
&:hover {
|
1867
|
+
background: ${({ theme, isVariantDanger, isDisabled }) => isVariantDanger && !isDisabled ? theme.colors.danger100 : "neutral"};
|
1868
|
+
}
|
1869
|
+
`;
|
1382
1870
|
const DocumentActionsMenu = ({
|
1383
1871
|
actions: actions2,
|
1384
1872
|
children,
|
@@ -1421,49 +1909,48 @@ const DocumentActionsMenu = ({
|
|
1421
1909
|
disabled: isDisabled,
|
1422
1910
|
size: "S",
|
1423
1911
|
endIcon: null,
|
1424
|
-
paddingTop: "
|
1425
|
-
paddingLeft: "
|
1426
|
-
paddingRight: "
|
1912
|
+
paddingTop: "4px",
|
1913
|
+
paddingLeft: "7px",
|
1914
|
+
paddingRight: "7px",
|
1427
1915
|
variant,
|
1428
1916
|
children: [
|
1429
1917
|
/* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
|
1430
|
-
/* @__PURE__ */ jsx(VisuallyHidden, {
|
1918
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: label || formatMessage({
|
1431
1919
|
id: "content-manager.containers.edit.panels.default.more-actions",
|
1432
1920
|
defaultMessage: "More document actions"
|
1433
1921
|
}) })
|
1434
1922
|
]
|
1435
1923
|
}
|
1436
1924
|
),
|
1437
|
-
/* @__PURE__ */ jsxs(Menu.Content, {
|
1925
|
+
/* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
|
1438
1926
|
actions2.map((action) => {
|
1439
1927
|
return /* @__PURE__ */ jsx(
|
1440
|
-
|
1928
|
+
MenuItem,
|
1441
1929
|
{
|
1442
1930
|
disabled: action.disabled,
|
1443
1931
|
onSelect: handleClick(action),
|
1444
1932
|
display: "block",
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
] })
|
1933
|
+
isVariantDanger: action.variant === "danger",
|
1934
|
+
isDisabled: action.disabled,
|
1935
|
+
children: /* @__PURE__ */ jsx(Flex, { justifyContent: "space-between", gap: 4, children: /* @__PURE__ */ jsxs(
|
1936
|
+
Flex,
|
1937
|
+
{
|
1938
|
+
color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
|
1939
|
+
gap: 2,
|
1940
|
+
tag: "span",
|
1941
|
+
children: [
|
1942
|
+
/* @__PURE__ */ jsx(
|
1943
|
+
Flex,
|
1944
|
+
{
|
1945
|
+
tag: "span",
|
1946
|
+
color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
|
1947
|
+
children: action.icon
|
1948
|
+
}
|
1949
|
+
),
|
1950
|
+
action.label
|
1951
|
+
]
|
1952
|
+
}
|
1953
|
+
) })
|
1467
1954
|
},
|
1468
1955
|
action.id
|
1469
1956
|
);
|
@@ -1505,6 +1992,18 @@ const convertActionVariantToColor = (variant = "secondary") => {
|
|
1505
1992
|
return "primary600";
|
1506
1993
|
}
|
1507
1994
|
};
|
1995
|
+
const convertActionVariantToIconColor = (variant = "secondary") => {
|
1996
|
+
switch (variant) {
|
1997
|
+
case "danger":
|
1998
|
+
return "danger600";
|
1999
|
+
case "secondary":
|
2000
|
+
return "neutral500";
|
2001
|
+
case "success":
|
2002
|
+
return "success600";
|
2003
|
+
default:
|
2004
|
+
return "primary600";
|
2005
|
+
}
|
2006
|
+
};
|
1508
2007
|
const DocumentActionConfirmDialog = ({
|
1509
2008
|
onClose,
|
1510
2009
|
onCancel,
|
@@ -1527,61 +2026,54 @@ const DocumentActionConfirmDialog = ({
|
|
1527
2026
|
}
|
1528
2027
|
onClose();
|
1529
2028
|
};
|
1530
|
-
return /* @__PURE__ */
|
1531
|
-
/* @__PURE__ */ jsx(
|
1532
|
-
/* @__PURE__ */ jsx(
|
1533
|
-
|
1534
|
-
{
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
)
|
1545
|
-
] });
|
2029
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2030
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
2031
|
+
/* @__PURE__ */ jsx(Dialog.Body, { children: content }),
|
2032
|
+
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
2033
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
|
2034
|
+
id: "app.components.Button.cancel",
|
2035
|
+
defaultMessage: "Cancel"
|
2036
|
+
}) }) }),
|
2037
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
|
2038
|
+
id: "app.components.Button.confirm",
|
2039
|
+
defaultMessage: "Confirm"
|
2040
|
+
}) })
|
2041
|
+
] })
|
2042
|
+
] }) });
|
1546
2043
|
};
|
1547
2044
|
const DocumentActionModal = ({
|
1548
2045
|
isOpen,
|
1549
2046
|
title,
|
1550
2047
|
onClose,
|
1551
2048
|
footer: Footer,
|
1552
|
-
content,
|
2049
|
+
content: Content,
|
1553
2050
|
onModalClose
|
1554
2051
|
}) => {
|
1555
|
-
const id = React.useId();
|
1556
|
-
if (!isOpen) {
|
1557
|
-
return null;
|
1558
|
-
}
|
1559
2052
|
const handleClose = () => {
|
1560
2053
|
if (onClose) {
|
1561
2054
|
onClose();
|
1562
2055
|
}
|
1563
2056
|
onModalClose();
|
1564
2057
|
};
|
1565
|
-
return /* @__PURE__ */
|
1566
|
-
/* @__PURE__ */ jsx(
|
1567
|
-
/* @__PURE__ */ jsx(
|
1568
|
-
/* @__PURE__ */ jsx(
|
1569
|
-
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
] });
|
2058
|
+
return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
|
2059
|
+
/* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
|
2060
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
|
2061
|
+
typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
|
2062
|
+
] }) });
|
2063
|
+
};
|
2064
|
+
const transformData = (data) => {
|
2065
|
+
if (Array.isArray(data)) {
|
2066
|
+
return data.map(transformData);
|
2067
|
+
}
|
2068
|
+
if (typeof data === "object" && data !== null) {
|
2069
|
+
if ("apiData" in data) {
|
2070
|
+
return data.apiData;
|
2071
|
+
}
|
2072
|
+
return mapValues(transformData)(data);
|
2073
|
+
}
|
2074
|
+
return data;
|
1583
2075
|
};
|
1584
|
-
const PublishAction = ({
|
2076
|
+
const PublishAction$1 = ({
|
1585
2077
|
activeTab,
|
1586
2078
|
documentId,
|
1587
2079
|
model,
|
@@ -1593,13 +2085,18 @@ const PublishAction = ({
|
|
1593
2085
|
const navigate = useNavigate();
|
1594
2086
|
const { toggleNotification } = useNotification();
|
1595
2087
|
const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
|
2088
|
+
const isListView = useMatch(LIST_PATH) !== null;
|
1596
2089
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2090
|
+
const { id } = useParams();
|
1597
2091
|
const { formatMessage } = useIntl();
|
1598
|
-
const { canPublish
|
1599
|
-
"PublishAction",
|
1600
|
-
({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 }) => ({ canPublish: canPublish2, canCreate: canCreate2, canUpdate: canUpdate2 })
|
1601
|
-
);
|
2092
|
+
const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
|
1602
2093
|
const { publish } = useDocumentActions();
|
2094
|
+
const [
|
2095
|
+
countDraftRelations,
|
2096
|
+
{ isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
|
2097
|
+
] = useLazyGetDraftRelationCountQuery();
|
2098
|
+
const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
|
2099
|
+
const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
|
1603
2100
|
const [{ query, rawQuery }] = useQueryParams();
|
1604
2101
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
1605
2102
|
const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
|
@@ -1608,10 +2105,107 @@ const PublishAction = ({
|
|
1608
2105
|
const validate = useForm("PublishAction", (state) => state.validate);
|
1609
2106
|
const setErrors = useForm("PublishAction", (state) => state.setErrors);
|
1610
2107
|
const formValues = useForm("PublishAction", ({ values }) => values);
|
2108
|
+
React.useEffect(() => {
|
2109
|
+
if (isErrorDraftRelations) {
|
2110
|
+
toggleNotification({
|
2111
|
+
type: "danger",
|
2112
|
+
message: formatMessage({
|
2113
|
+
id: getTranslation("error.records.fetch-draft-relatons"),
|
2114
|
+
defaultMessage: "An error occurred while fetching draft relations on this document."
|
2115
|
+
})
|
2116
|
+
});
|
2117
|
+
}
|
2118
|
+
}, [isErrorDraftRelations, toggleNotification, formatMessage]);
|
2119
|
+
React.useEffect(() => {
|
2120
|
+
const localDraftRelations = /* @__PURE__ */ new Set();
|
2121
|
+
const extractDraftRelations = (data) => {
|
2122
|
+
const relations = data.connect || [];
|
2123
|
+
relations.forEach((relation) => {
|
2124
|
+
if (relation.status === "draft") {
|
2125
|
+
localDraftRelations.add(relation.id);
|
2126
|
+
}
|
2127
|
+
});
|
2128
|
+
};
|
2129
|
+
const traverseAndExtract = (data) => {
|
2130
|
+
Object.entries(data).forEach(([key, value]) => {
|
2131
|
+
if (key === "connect" && Array.isArray(value)) {
|
2132
|
+
extractDraftRelations({ connect: value });
|
2133
|
+
} else if (typeof value === "object" && value !== null) {
|
2134
|
+
traverseAndExtract(value);
|
2135
|
+
}
|
2136
|
+
});
|
2137
|
+
};
|
2138
|
+
if (!documentId || modified) {
|
2139
|
+
traverseAndExtract(formValues);
|
2140
|
+
setLocalCountOfDraftRelations(localDraftRelations.size);
|
2141
|
+
}
|
2142
|
+
}, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
|
2143
|
+
React.useEffect(() => {
|
2144
|
+
if (!document || !document.documentId || isListView) {
|
2145
|
+
return;
|
2146
|
+
}
|
2147
|
+
const fetchDraftRelationsCount = async () => {
|
2148
|
+
const { data, error } = await countDraftRelations({
|
2149
|
+
collectionType,
|
2150
|
+
model,
|
2151
|
+
documentId,
|
2152
|
+
params
|
2153
|
+
});
|
2154
|
+
if (error) {
|
2155
|
+
throw error;
|
2156
|
+
}
|
2157
|
+
if (data) {
|
2158
|
+
setServerCountOfDraftRelations(data.data);
|
2159
|
+
}
|
2160
|
+
};
|
2161
|
+
fetchDraftRelationsCount();
|
2162
|
+
}, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
|
1611
2163
|
const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
|
1612
2164
|
if (!schema?.options?.draftAndPublish) {
|
1613
2165
|
return null;
|
1614
2166
|
}
|
2167
|
+
const performPublish = async () => {
|
2168
|
+
setSubmitting(true);
|
2169
|
+
try {
|
2170
|
+
const { errors } = await validate(true, {
|
2171
|
+
status: "published"
|
2172
|
+
});
|
2173
|
+
if (errors) {
|
2174
|
+
toggleNotification({
|
2175
|
+
type: "danger",
|
2176
|
+
message: formatMessage({
|
2177
|
+
id: "content-manager.validation.error",
|
2178
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2179
|
+
})
|
2180
|
+
});
|
2181
|
+
return;
|
2182
|
+
}
|
2183
|
+
const res = await publish(
|
2184
|
+
{
|
2185
|
+
collectionType,
|
2186
|
+
model,
|
2187
|
+
documentId,
|
2188
|
+
params
|
2189
|
+
},
|
2190
|
+
transformData(formValues)
|
2191
|
+
);
|
2192
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2193
|
+
if (id === "create") {
|
2194
|
+
navigate({
|
2195
|
+
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2196
|
+
search: rawQuery
|
2197
|
+
});
|
2198
|
+
}
|
2199
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2200
|
+
setErrors(formatValidationErrors(res.error));
|
2201
|
+
}
|
2202
|
+
} finally {
|
2203
|
+
setSubmitting(false);
|
2204
|
+
}
|
2205
|
+
};
|
2206
|
+
const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
|
2207
|
+
const enableDraftRelationsCount = false;
|
2208
|
+
const hasDraftRelations = enableDraftRelationsCount;
|
1615
2209
|
return {
|
1616
2210
|
/**
|
1617
2211
|
* Disabled when:
|
@@ -1621,52 +2215,40 @@ const PublishAction = ({
|
|
1621
2215
|
* - the document is already published & not modified
|
1622
2216
|
* - the document is being created & not modified
|
1623
2217
|
* - the user doesn't have the permission to publish
|
1624
|
-
* - the user doesn't have the permission to create a new document
|
1625
|
-
* - the user doesn't have the permission to update the document
|
1626
2218
|
*/
|
1627
|
-
disabled: isCloning || isSubmitting || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish
|
2219
|
+
disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
|
1628
2220
|
label: formatMessage({
|
1629
2221
|
id: "app.utils.publish",
|
1630
2222
|
defaultMessage: "Publish"
|
1631
2223
|
}),
|
1632
2224
|
onClick: async () => {
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
documentId,
|
1651
|
-
params
|
1652
|
-
},
|
1653
|
-
formValues
|
1654
|
-
);
|
1655
|
-
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
1656
|
-
navigate({
|
1657
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1658
|
-
search: rawQuery
|
1659
|
-
});
|
1660
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1661
|
-
setErrors(formatValidationErrors(res.error));
|
2225
|
+
await performPublish();
|
2226
|
+
},
|
2227
|
+
dialog: hasDraftRelations ? {
|
2228
|
+
type: "dialog",
|
2229
|
+
variant: "danger",
|
2230
|
+
footer: null,
|
2231
|
+
title: formatMessage({
|
2232
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
|
2233
|
+
defaultMessage: "Confirmation"
|
2234
|
+
}),
|
2235
|
+
content: formatMessage(
|
2236
|
+
{
|
2237
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
2238
|
+
defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
|
2239
|
+
},
|
2240
|
+
{
|
2241
|
+
count: totalDraftRelations
|
1662
2242
|
}
|
1663
|
-
|
1664
|
-
|
2243
|
+
),
|
2244
|
+
onConfirm: async () => {
|
2245
|
+
await performPublish();
|
1665
2246
|
}
|
1666
|
-
}
|
2247
|
+
} : void 0
|
1667
2248
|
};
|
1668
2249
|
};
|
1669
|
-
PublishAction.type = "publish";
|
2250
|
+
PublishAction$1.type = "publish";
|
2251
|
+
PublishAction$1.position = "panel";
|
1670
2252
|
const UpdateAction = ({
|
1671
2253
|
activeTab,
|
1672
2254
|
documentId,
|
@@ -1679,10 +2261,6 @@ const UpdateAction = ({
|
|
1679
2261
|
const cloneMatch = useMatch(CLONE_PATH);
|
1680
2262
|
const isCloning = cloneMatch !== null;
|
1681
2263
|
const { formatMessage } = useIntl();
|
1682
|
-
const { canCreate, canUpdate } = useDocumentRBAC("UpdateAction", ({ canCreate: canCreate2, canUpdate: canUpdate2 }) => ({
|
1683
|
-
canCreate: canCreate2,
|
1684
|
-
canUpdate: canUpdate2
|
1685
|
-
}));
|
1686
2264
|
const { create, update, clone } = useDocumentActions();
|
1687
2265
|
const [{ query, rawQuery }] = useQueryParams();
|
1688
2266
|
const params = React.useMemo(() => buildValidParams(query), [query]);
|
@@ -1693,95 +2271,139 @@ const UpdateAction = ({
|
|
1693
2271
|
const validate = useForm("UpdateAction", (state) => state.validate);
|
1694
2272
|
const setErrors = useForm("UpdateAction", (state) => state.setErrors);
|
1695
2273
|
const resetForm = useForm("PublishAction", ({ resetForm: resetForm2 }) => resetForm2);
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
}
|
1722
|
-
|
1723
|
-
|
1724
|
-
if (
|
1725
|
-
|
2274
|
+
const handleUpdate = React.useCallback(async () => {
|
2275
|
+
setSubmitting(true);
|
2276
|
+
try {
|
2277
|
+
if (!modified) {
|
2278
|
+
return;
|
2279
|
+
}
|
2280
|
+
const { errors } = await validate(true, {
|
2281
|
+
status: "draft"
|
2282
|
+
});
|
2283
|
+
if (errors) {
|
2284
|
+
toggleNotification({
|
2285
|
+
type: "danger",
|
2286
|
+
message: formatMessage({
|
2287
|
+
id: "content-manager.validation.error",
|
2288
|
+
defaultMessage: "There are validation errors in your document. Please fix them before saving."
|
2289
|
+
})
|
2290
|
+
});
|
2291
|
+
return;
|
2292
|
+
}
|
2293
|
+
if (isCloning) {
|
2294
|
+
const res = await clone(
|
2295
|
+
{
|
2296
|
+
model,
|
2297
|
+
documentId: cloneMatch.params.origin,
|
2298
|
+
params
|
2299
|
+
},
|
2300
|
+
transformData(document)
|
2301
|
+
);
|
2302
|
+
if ("data" in res) {
|
2303
|
+
navigate(
|
1726
2304
|
{
|
1727
|
-
|
1728
|
-
documentId: cloneMatch.params.origin,
|
1729
|
-
params
|
1730
|
-
},
|
1731
|
-
document
|
1732
|
-
);
|
1733
|
-
if ("data" in res) {
|
1734
|
-
navigate({
|
1735
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
2305
|
+
pathname: `../${res.data.documentId}`,
|
1736
2306
|
search: rawQuery
|
1737
|
-
});
|
1738
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1739
|
-
setErrors(formatValidationErrors(res.error));
|
1740
|
-
}
|
1741
|
-
} else if (documentId || collectionType === SINGLE_TYPES) {
|
1742
|
-
const res = await update(
|
1743
|
-
{
|
1744
|
-
collectionType,
|
1745
|
-
model,
|
1746
|
-
documentId,
|
1747
|
-
params
|
1748
2307
|
},
|
1749
|
-
|
2308
|
+
{ relative: "path" }
|
1750
2309
|
);
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
1760
|
-
|
2310
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2311
|
+
setErrors(formatValidationErrors(res.error));
|
2312
|
+
}
|
2313
|
+
} else if (documentId || collectionType === SINGLE_TYPES) {
|
2314
|
+
const res = await update(
|
2315
|
+
{
|
2316
|
+
collectionType,
|
2317
|
+
model,
|
2318
|
+
documentId,
|
2319
|
+
params
|
2320
|
+
},
|
2321
|
+
transformData(document)
|
2322
|
+
);
|
2323
|
+
if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2324
|
+
setErrors(formatValidationErrors(res.error));
|
2325
|
+
} else {
|
2326
|
+
resetForm();
|
2327
|
+
}
|
2328
|
+
} else {
|
2329
|
+
const res = await create(
|
2330
|
+
{
|
2331
|
+
model,
|
2332
|
+
params
|
2333
|
+
},
|
2334
|
+
transformData(document)
|
2335
|
+
);
|
2336
|
+
if ("data" in res && collectionType !== SINGLE_TYPES) {
|
2337
|
+
navigate(
|
2338
|
+
{
|
2339
|
+
pathname: `../${res.data.documentId}`,
|
2340
|
+
search: rawQuery
|
1761
2341
|
},
|
1762
|
-
|
2342
|
+
{ replace: true, relative: "path" }
|
1763
2343
|
);
|
1764
|
-
|
1765
|
-
|
1766
|
-
pathname: `../${collectionType}/${model}/${res.data.documentId}`,
|
1767
|
-
search: rawQuery
|
1768
|
-
});
|
1769
|
-
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
1770
|
-
setErrors(formatValidationErrors(res.error));
|
1771
|
-
}
|
2344
|
+
} else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
|
2345
|
+
setErrors(formatValidationErrors(res.error));
|
1772
2346
|
}
|
1773
|
-
} finally {
|
1774
|
-
setSubmitting(false);
|
1775
2347
|
}
|
2348
|
+
} finally {
|
2349
|
+
setSubmitting(false);
|
1776
2350
|
}
|
2351
|
+
}, [
|
2352
|
+
clone,
|
2353
|
+
cloneMatch?.params.origin,
|
2354
|
+
collectionType,
|
2355
|
+
create,
|
2356
|
+
document,
|
2357
|
+
documentId,
|
2358
|
+
formatMessage,
|
2359
|
+
formatValidationErrors,
|
2360
|
+
isCloning,
|
2361
|
+
model,
|
2362
|
+
modified,
|
2363
|
+
navigate,
|
2364
|
+
params,
|
2365
|
+
rawQuery,
|
2366
|
+
resetForm,
|
2367
|
+
setErrors,
|
2368
|
+
setSubmitting,
|
2369
|
+
toggleNotification,
|
2370
|
+
update,
|
2371
|
+
validate
|
2372
|
+
]);
|
2373
|
+
React.useEffect(() => {
|
2374
|
+
const handleKeyDown = (e) => {
|
2375
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
2376
|
+
e.preventDefault();
|
2377
|
+
handleUpdate();
|
2378
|
+
}
|
2379
|
+
};
|
2380
|
+
window.addEventListener("keydown", handleKeyDown);
|
2381
|
+
return () => {
|
2382
|
+
window.removeEventListener("keydown", handleKeyDown);
|
2383
|
+
};
|
2384
|
+
}, [handleUpdate]);
|
2385
|
+
return {
|
2386
|
+
/**
|
2387
|
+
* Disabled when:
|
2388
|
+
* - the form is submitting
|
2389
|
+
* - the document is not modified & we're not cloning (you can save a clone entity straight away)
|
2390
|
+
* - the active tab is the published tab
|
2391
|
+
*/
|
2392
|
+
disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
|
2393
|
+
label: formatMessage({
|
2394
|
+
id: "global.save",
|
2395
|
+
defaultMessage: "Save"
|
2396
|
+
}),
|
2397
|
+
onClick: handleUpdate
|
1777
2398
|
};
|
1778
2399
|
};
|
1779
2400
|
UpdateAction.type = "update";
|
2401
|
+
UpdateAction.position = "panel";
|
1780
2402
|
const UNPUBLISH_DRAFT_OPTIONS = {
|
1781
2403
|
KEEP: "keep",
|
1782
2404
|
DISCARD: "discard"
|
1783
2405
|
};
|
1784
|
-
const UnpublishAction = ({
|
2406
|
+
const UnpublishAction$1 = ({
|
1785
2407
|
activeTab,
|
1786
2408
|
documentId,
|
1787
2409
|
model,
|
@@ -1797,10 +2419,8 @@ const UnpublishAction = ({
|
|
1797
2419
|
const { toggleNotification } = useNotification();
|
1798
2420
|
const [shouldKeepDraft, setShouldKeepDraft] = React.useState(true);
|
1799
2421
|
const isDocumentModified = document?.status === "modified";
|
1800
|
-
const handleChange = (
|
1801
|
-
|
1802
|
-
setShouldKeepDraft(e.target.value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1803
|
-
}
|
2422
|
+
const handleChange = (value) => {
|
2423
|
+
setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
|
1804
2424
|
};
|
1805
2425
|
if (!schema?.options?.draftAndPublish) {
|
1806
2426
|
return null;
|
@@ -1811,7 +2431,7 @@ const UnpublishAction = ({
|
|
1811
2431
|
id: "app.utils.unpublish",
|
1812
2432
|
defaultMessage: "Unpublish"
|
1813
2433
|
}),
|
1814
|
-
icon: /* @__PURE__ */ jsx(
|
2434
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1815
2435
|
onClick: async () => {
|
1816
2436
|
if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
|
1817
2437
|
if (!documentId) {
|
@@ -1844,45 +2464,30 @@ const UnpublishAction = ({
|
|
1844
2464
|
content: /* @__PURE__ */ jsxs(Flex, { alignItems: "flex-start", direction: "column", gap: 6, children: [
|
1845
2465
|
/* @__PURE__ */ jsxs(Flex, { width: "100%", direction: "column", gap: 2, children: [
|
1846
2466
|
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1847
|
-
/* @__PURE__ */ jsx(Typography, {
|
2467
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1848
2468
|
id: "content-manager.actions.unpublish.dialog.body",
|
1849
2469
|
defaultMessage: "Are you sure?"
|
1850
2470
|
}) })
|
1851
2471
|
] }),
|
1852
2472
|
/* @__PURE__ */ jsxs(
|
1853
|
-
|
2473
|
+
Radio.Group,
|
1854
2474
|
{
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
1859
|
-
|
2475
|
+
defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
|
2476
|
+
name: "discard-options",
|
2477
|
+
"aria-label": formatMessage({
|
2478
|
+
id: "content-manager.actions.unpublish.dialog.radio-label",
|
2479
|
+
defaultMessage: "Choose an option to unpublish the document."
|
2480
|
+
}),
|
2481
|
+
onValueChange: handleChange,
|
1860
2482
|
children: [
|
1861
|
-
/* @__PURE__ */ jsx(
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1866
|
-
|
1867
|
-
|
1868
|
-
|
1869
|
-
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
1870
|
-
defaultMessage: "Keep draft"
|
1871
|
-
})
|
1872
|
-
}
|
1873
|
-
),
|
1874
|
-
/* @__PURE__ */ jsx(
|
1875
|
-
Radio,
|
1876
|
-
{
|
1877
|
-
checked: !shouldKeepDraft,
|
1878
|
-
value: UNPUBLISH_DRAFT_OPTIONS.DISCARD,
|
1879
|
-
name: "discard-options",
|
1880
|
-
children: formatMessage({
|
1881
|
-
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
1882
|
-
defaultMessage: "Replace draft"
|
1883
|
-
})
|
1884
|
-
}
|
1885
|
-
)
|
2483
|
+
/* @__PURE__ */ jsx(Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
|
2484
|
+
id: "content-manager.actions.unpublish.dialog.option.keep-draft",
|
2485
|
+
defaultMessage: "Keep draft"
|
2486
|
+
}) }),
|
2487
|
+
/* @__PURE__ */ jsx(Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
|
2488
|
+
id: "content-manager.actions.unpublish.dialog.option.replace-draft",
|
2489
|
+
defaultMessage: "Replace draft"
|
2490
|
+
}) })
|
1886
2491
|
]
|
1887
2492
|
}
|
1888
2493
|
)
|
@@ -1915,7 +2520,8 @@ const UnpublishAction = ({
|
|
1915
2520
|
position: ["panel", "table-row"]
|
1916
2521
|
};
|
1917
2522
|
};
|
1918
|
-
UnpublishAction.type = "unpublish";
|
2523
|
+
UnpublishAction$1.type = "unpublish";
|
2524
|
+
UnpublishAction$1.position = "panel";
|
1919
2525
|
const DiscardAction = ({
|
1920
2526
|
activeTab,
|
1921
2527
|
documentId,
|
@@ -1938,7 +2544,7 @@ const DiscardAction = ({
|
|
1938
2544
|
id: "content-manager.actions.discard.label",
|
1939
2545
|
defaultMessage: "Discard changes"
|
1940
2546
|
}),
|
1941
|
-
icon: /* @__PURE__ */ jsx(
|
2547
|
+
icon: /* @__PURE__ */ jsx(Cross, {}),
|
1942
2548
|
position: ["panel", "table-row"],
|
1943
2549
|
variant: "danger",
|
1944
2550
|
dialog: {
|
@@ -1949,7 +2555,7 @@ const DiscardAction = ({
|
|
1949
2555
|
}),
|
1950
2556
|
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
1951
2557
|
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
1952
|
-
/* @__PURE__ */ jsx(Typography, {
|
2558
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
1953
2559
|
id: "content-manager.actions.discard.dialog.body",
|
1954
2560
|
defaultMessage: "Are you sure?"
|
1955
2561
|
}) })
|
@@ -1966,12 +2572,8 @@ const DiscardAction = ({
|
|
1966
2572
|
};
|
1967
2573
|
};
|
1968
2574
|
DiscardAction.type = "discard";
|
1969
|
-
|
1970
|
-
|
1971
|
-
fill: currentColor;
|
1972
|
-
}
|
1973
|
-
`;
|
1974
|
-
const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction, DiscardAction];
|
2575
|
+
DiscardAction.position = "panel";
|
2576
|
+
const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
|
1975
2577
|
const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
|
1976
2578
|
const RelativeTime = React.forwardRef(
|
1977
2579
|
({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
|
@@ -1983,7 +2585,7 @@ const RelativeTime = React.forwardRef(
|
|
1983
2585
|
});
|
1984
2586
|
const unit = intervals.find((intervalUnit) => {
|
1985
2587
|
return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
|
1986
|
-
});
|
2588
|
+
}) ?? "seconds";
|
1987
2589
|
const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
|
1988
2590
|
const customInterval = customIntervals.find(
|
1989
2591
|
(custom) => interval[custom.unit] < custom.threshold
|
@@ -2017,34 +2619,34 @@ const getDisplayName = ({
|
|
2017
2619
|
return email ?? "";
|
2018
2620
|
};
|
2019
2621
|
const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
2020
|
-
const DocumentStatus = ({ status = "draft", ...restProps }) => {
|
2021
|
-
const statusVariant = status === "draft" ? "
|
2022
|
-
|
2622
|
+
const DocumentStatus = ({ status = "draft", size = "S", ...restProps }) => {
|
2623
|
+
const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
|
2624
|
+
const { formatMessage } = useIntl();
|
2625
|
+
return /* @__PURE__ */ jsx(Status, { ...restProps, size, variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: formatMessage({
|
2626
|
+
id: `content-manager.containers.List.${status}`,
|
2627
|
+
defaultMessage: capitalise(status)
|
2628
|
+
}) }) });
|
2023
2629
|
};
|
2024
2630
|
const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
|
2025
2631
|
const { formatMessage } = useIntl();
|
2026
2632
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2633
|
+
const params = useParams();
|
2027
2634
|
const title = isCreating ? formatMessage({
|
2028
2635
|
id: "content-manager.containers.edit.title.new",
|
2029
2636
|
defaultMessage: "Create an entry"
|
2030
2637
|
}) : documentTitle;
|
2031
|
-
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop:
|
2032
|
-
/* @__PURE__ */ jsx(
|
2033
|
-
|
2034
|
-
Flex,
|
2638
|
+
return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
|
2639
|
+
/* @__PURE__ */ jsx(
|
2640
|
+
BackButton,
|
2035
2641
|
{
|
2036
|
-
|
2037
|
-
justifyContent: "space-between",
|
2038
|
-
paddingTop: 1,
|
2039
|
-
gap: "80px",
|
2040
|
-
alignItems: "flex-start",
|
2041
|
-
children: [
|
2042
|
-
/* @__PURE__ */ jsx(Typography, { variant: "alpha", as: "h1", children: title }),
|
2043
|
-
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2044
|
-
]
|
2642
|
+
fallback: params.collectionType === SINGLE_TYPES ? void 0 : `../${COLLECTION_TYPES}/${params.slug}`
|
2045
2643
|
}
|
2046
2644
|
),
|
2047
|
-
|
2645
|
+
/* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
|
2646
|
+
/* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
|
2647
|
+
/* @__PURE__ */ jsx(HeaderToolbar, {})
|
2648
|
+
] }),
|
2649
|
+
status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
|
2048
2650
|
] });
|
2049
2651
|
};
|
2050
2652
|
const HeaderToolbar = () => {
|
@@ -2090,7 +2692,7 @@ const HeaderToolbar = () => {
|
|
2090
2692
|
meta: isCloning ? void 0 : meta,
|
2091
2693
|
collectionType
|
2092
2694
|
},
|
2093
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
2695
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("header"),
|
2094
2696
|
children: (actions2) => {
|
2095
2697
|
const headerActions = actions2.filter((action) => {
|
2096
2698
|
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
@@ -2127,12 +2729,12 @@ const Information = ({ activeTab }) => {
|
|
2127
2729
|
isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
|
2128
2730
|
label: formatMessage({
|
2129
2731
|
id: "content-manager.containers.edit.information.last-published.label",
|
2130
|
-
defaultMessage: "
|
2732
|
+
defaultMessage: "Published"
|
2131
2733
|
}),
|
2132
2734
|
value: formatMessage(
|
2133
2735
|
{
|
2134
2736
|
id: "content-manager.containers.edit.information.last-published.value",
|
2135
|
-
defaultMessage: `
|
2737
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2136
2738
|
},
|
2137
2739
|
{
|
2138
2740
|
time: /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
|
@@ -2145,12 +2747,12 @@ const Information = ({ activeTab }) => {
|
|
2145
2747
|
isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
|
2146
2748
|
label: formatMessage({
|
2147
2749
|
id: "content-manager.containers.edit.information.last-draft.label",
|
2148
|
-
defaultMessage: "
|
2750
|
+
defaultMessage: "Updated"
|
2149
2751
|
}),
|
2150
2752
|
value: formatMessage(
|
2151
2753
|
{
|
2152
2754
|
id: "content-manager.containers.edit.information.last-draft.value",
|
2153
|
-
defaultMessage: `
|
2755
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2154
2756
|
},
|
2155
2757
|
{
|
2156
2758
|
time: /* @__PURE__ */ jsx(
|
@@ -2168,12 +2770,12 @@ const Information = ({ activeTab }) => {
|
|
2168
2770
|
isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
|
2169
2771
|
label: formatMessage({
|
2170
2772
|
id: "content-manager.containers.edit.information.document.label",
|
2171
|
-
defaultMessage: "
|
2773
|
+
defaultMessage: "Created"
|
2172
2774
|
}),
|
2173
2775
|
value: formatMessage(
|
2174
2776
|
{
|
2175
2777
|
id: "content-manager.containers.edit.information.document.value",
|
2176
|
-
defaultMessage: `
|
2778
|
+
defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
|
2177
2779
|
},
|
2178
2780
|
{
|
2179
2781
|
time: /* @__PURE__ */ jsx(
|
@@ -2196,7 +2798,7 @@ const Information = ({ activeTab }) => {
|
|
2196
2798
|
borderColor: "neutral150",
|
2197
2799
|
direction: "column",
|
2198
2800
|
marginTop: 2,
|
2199
|
-
|
2801
|
+
tag: "dl",
|
2200
2802
|
padding: 5,
|
2201
2803
|
gap: 3,
|
2202
2804
|
alignItems: "flex-start",
|
@@ -2204,32 +2806,84 @@ const Information = ({ activeTab }) => {
|
|
2204
2806
|
marginRight: "-0.4rem",
|
2205
2807
|
width: "calc(100% + 8px)",
|
2206
2808
|
children: information.map((info) => /* @__PURE__ */ jsxs(Flex, { gap: 1, direction: "column", alignItems: "flex-start", children: [
|
2207
|
-
/* @__PURE__ */ jsx(Typography, {
|
2208
|
-
/* @__PURE__ */ jsx(Typography, {
|
2809
|
+
/* @__PURE__ */ jsx(Typography, { tag: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
|
2810
|
+
/* @__PURE__ */ jsx(Typography, { tag: "dd", variant: "pi", textColor: "neutral600", children: info.value })
|
2209
2811
|
] }, info.label))
|
2210
2812
|
}
|
2211
2813
|
);
|
2212
2814
|
};
|
2213
2815
|
const HeaderActions = ({ actions: actions2 }) => {
|
2214
|
-
|
2215
|
-
|
2816
|
+
const [dialogId, setDialogId] = React.useState(null);
|
2817
|
+
const handleClick = (action) => async (e) => {
|
2818
|
+
if (!("options" in action)) {
|
2819
|
+
const { onClick = () => false, dialog, id } = action;
|
2820
|
+
const muteDialog = await onClick(e);
|
2821
|
+
if (dialog && !muteDialog) {
|
2822
|
+
e.preventDefault();
|
2823
|
+
setDialogId(id);
|
2824
|
+
}
|
2825
|
+
}
|
2826
|
+
};
|
2827
|
+
const handleClose = () => {
|
2828
|
+
setDialogId(null);
|
2829
|
+
};
|
2830
|
+
return /* @__PURE__ */ jsx(Flex, { gap: 1, children: actions2.map((action) => {
|
2831
|
+
if (action.options) {
|
2216
2832
|
return /* @__PURE__ */ jsx(
|
2217
2833
|
SingleSelect,
|
2218
2834
|
{
|
2219
2835
|
size: "S",
|
2220
|
-
disabled: action.disabled,
|
2221
|
-
"aria-label": action.label,
|
2222
2836
|
onChange: action.onSelect,
|
2223
|
-
|
2837
|
+
"aria-label": action.label,
|
2838
|
+
...action,
|
2224
2839
|
children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
|
2225
2840
|
},
|
2226
2841
|
action.id
|
2227
2842
|
);
|
2228
2843
|
} else {
|
2229
|
-
|
2844
|
+
if (action.type === "icon") {
|
2845
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
2846
|
+
/* @__PURE__ */ jsx(
|
2847
|
+
IconButton,
|
2848
|
+
{
|
2849
|
+
disabled: action.disabled,
|
2850
|
+
label: action.label,
|
2851
|
+
size: "S",
|
2852
|
+
onClick: handleClick(action),
|
2853
|
+
children: action.icon
|
2854
|
+
}
|
2855
|
+
),
|
2856
|
+
action.dialog ? /* @__PURE__ */ jsx(
|
2857
|
+
HeaderActionDialog,
|
2858
|
+
{
|
2859
|
+
...action.dialog,
|
2860
|
+
isOpen: dialogId === action.id,
|
2861
|
+
onClose: handleClose
|
2862
|
+
}
|
2863
|
+
) : null
|
2864
|
+
] }, action.id);
|
2865
|
+
}
|
2230
2866
|
}
|
2231
2867
|
}) });
|
2232
2868
|
};
|
2869
|
+
const HeaderActionDialog = ({
|
2870
|
+
onClose,
|
2871
|
+
onCancel,
|
2872
|
+
title,
|
2873
|
+
content: Content,
|
2874
|
+
isOpen
|
2875
|
+
}) => {
|
2876
|
+
const handleClose = async () => {
|
2877
|
+
if (onCancel) {
|
2878
|
+
await onCancel();
|
2879
|
+
}
|
2880
|
+
onClose();
|
2881
|
+
};
|
2882
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
2883
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: title }),
|
2884
|
+
typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content
|
2885
|
+
] }) });
|
2886
|
+
};
|
2233
2887
|
const ConfigureTheViewAction = ({ collectionType, model }) => {
|
2234
2888
|
const navigate = useNavigate();
|
2235
2889
|
const { formatMessage } = useIntl();
|
@@ -2238,7 +2892,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2238
2892
|
id: "app.links.configure-view",
|
2239
2893
|
defaultMessage: "Configure the view"
|
2240
2894
|
}),
|
2241
|
-
icon: /* @__PURE__ */ jsx(
|
2895
|
+
icon: /* @__PURE__ */ jsx(ListPlus, {}),
|
2242
2896
|
onClick: () => {
|
2243
2897
|
navigate(`../${collectionType}/${model}/configurations/edit`);
|
2244
2898
|
},
|
@@ -2246,11 +2900,7 @@ const ConfigureTheViewAction = ({ collectionType, model }) => {
|
|
2246
2900
|
};
|
2247
2901
|
};
|
2248
2902
|
ConfigureTheViewAction.type = "configure-the-view";
|
2249
|
-
|
2250
|
-
path {
|
2251
|
-
fill: currentColor;
|
2252
|
-
}
|
2253
|
-
`;
|
2903
|
+
ConfigureTheViewAction.position = "header";
|
2254
2904
|
const EditTheModelAction = ({ model }) => {
|
2255
2905
|
const navigate = useNavigate();
|
2256
2906
|
const { formatMessage } = useIntl();
|
@@ -2259,7 +2909,7 @@ const EditTheModelAction = ({ model }) => {
|
|
2259
2909
|
id: "content-manager.link-to-ctb",
|
2260
2910
|
defaultMessage: "Edit the model"
|
2261
2911
|
}),
|
2262
|
-
icon: /* @__PURE__ */ jsx(
|
2912
|
+
icon: /* @__PURE__ */ jsx(Pencil, {}),
|
2263
2913
|
onClick: () => {
|
2264
2914
|
navigate(`/plugins/content-type-builder/content-types/${model}`);
|
2265
2915
|
},
|
@@ -2267,12 +2917,8 @@ const EditTheModelAction = ({ model }) => {
|
|
2267
2917
|
};
|
2268
2918
|
};
|
2269
2919
|
EditTheModelAction.type = "edit-the-model";
|
2270
|
-
|
2271
|
-
|
2272
|
-
fill: currentColor;
|
2273
|
-
}
|
2274
|
-
`;
|
2275
|
-
const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
2920
|
+
EditTheModelAction.position = "header";
|
2921
|
+
const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
|
2276
2922
|
const navigate = useNavigate();
|
2277
2923
|
const { formatMessage } = useIntl();
|
2278
2924
|
const listViewPathMatch = useMatch(LIST_PATH);
|
@@ -2280,13 +2926,17 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2280
2926
|
const { delete: deleteAction } = useDocumentActions();
|
2281
2927
|
const { toggleNotification } = useNotification();
|
2282
2928
|
const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
|
2929
|
+
const isLocalized = document?.locale != null;
|
2283
2930
|
return {
|
2284
2931
|
disabled: !canDelete || !document,
|
2285
|
-
label: formatMessage(
|
2286
|
-
|
2287
|
-
|
2288
|
-
|
2289
|
-
|
2932
|
+
label: formatMessage(
|
2933
|
+
{
|
2934
|
+
id: "content-manager.actions.delete.label",
|
2935
|
+
defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
|
2936
|
+
},
|
2937
|
+
{ isLocalized }
|
2938
|
+
),
|
2939
|
+
icon: /* @__PURE__ */ jsx(Trash, {}),
|
2290
2940
|
dialog: {
|
2291
2941
|
type: "dialog",
|
2292
2942
|
title: formatMessage({
|
@@ -2295,7 +2945,7 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2295
2945
|
}),
|
2296
2946
|
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
2297
2947
|
/* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
|
2298
|
-
/* @__PURE__ */ jsx(Typography, {
|
2948
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
|
2299
2949
|
id: "content-manager.actions.delete.dialog.body",
|
2300
2950
|
defaultMessage: "Are you sure?"
|
2301
2951
|
}) })
|
@@ -2340,13 +2990,9 @@ const DeleteAction = ({ documentId, model, collectionType, document }) => {
|
|
2340
2990
|
position: ["header", "table-row"]
|
2341
2991
|
};
|
2342
2992
|
};
|
2343
|
-
DeleteAction.type = "delete";
|
2344
|
-
|
2345
|
-
|
2346
|
-
fill: currentColor;
|
2347
|
-
}
|
2348
|
-
`;
|
2349
|
-
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction];
|
2993
|
+
DeleteAction$1.type = "delete";
|
2994
|
+
DeleteAction$1.position = ["header", "table-row"];
|
2995
|
+
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
|
2350
2996
|
const Panels = () => {
|
2351
2997
|
const isCloning = useMatch(CLONE_PATH) !== null;
|
2352
2998
|
const [
|
@@ -2380,7 +3026,7 @@ const ActionsPanel = () => {
|
|
2380
3026
|
return {
|
2381
3027
|
title: formatMessage({
|
2382
3028
|
id: "content-manager.containers.edit.panels.default.title",
|
2383
|
-
defaultMessage: "
|
3029
|
+
defaultMessage: "Entry"
|
2384
3030
|
}),
|
2385
3031
|
content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
|
2386
3032
|
};
|
@@ -2408,7 +3054,7 @@ const ActionsPanelContent = () => {
|
|
2408
3054
|
DescriptionComponentRenderer,
|
2409
3055
|
{
|
2410
3056
|
props,
|
2411
|
-
descriptions: plugins["content-manager"].apis.getDocumentActions(),
|
3057
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("panel"),
|
2412
3058
|
children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
|
2413
3059
|
}
|
2414
3060
|
),
|
@@ -2420,7 +3066,7 @@ const Panel = React.forwardRef(({ children, title }, ref) => {
|
|
2420
3066
|
Flex,
|
2421
3067
|
{
|
2422
3068
|
ref,
|
2423
|
-
|
3069
|
+
tag: "aside",
|
2424
3070
|
"aria-labelledby": "additional-information",
|
2425
3071
|
background: "neutral0",
|
2426
3072
|
borderColor: "neutral150",
|
@@ -2435,133 +3081,707 @@ const Panel = React.forwardRef(({ children, title }, ref) => {
|
|
2435
3081
|
justifyContent: "stretch",
|
2436
3082
|
alignItems: "flex-start",
|
2437
3083
|
children: [
|
2438
|
-
/* @__PURE__ */ jsx(Typography, {
|
3084
|
+
/* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", textColor: "neutral600", children: title }),
|
2439
3085
|
children
|
2440
3086
|
]
|
2441
3087
|
}
|
2442
3088
|
);
|
2443
3089
|
});
|
2444
|
-
const
|
2445
|
-
|
3090
|
+
const ConfirmBulkActionDialog = ({
|
3091
|
+
onToggleDialog,
|
3092
|
+
isOpen = false,
|
3093
|
+
dialogBody,
|
3094
|
+
endAction
|
3095
|
+
}) => {
|
2446
3096
|
const { formatMessage } = useIntl();
|
2447
|
-
|
2448
|
-
|
2449
|
-
|
2450
|
-
|
2451
|
-
case "unique":
|
2452
|
-
return "Identical values in a unique field are not allowed";
|
2453
|
-
default:
|
2454
|
-
return reason;
|
2455
|
-
}
|
2456
|
-
};
|
2457
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
2458
|
-
/* @__PURE__ */ jsx(Typography, { variant: "beta", children: formatMessage({
|
2459
|
-
id: getTranslation("containers.list.autoCloneModal.title"),
|
2460
|
-
defaultMessage: "This entry can't be duplicated directly."
|
3097
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
|
3098
|
+
/* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
|
3099
|
+
id: "app.components.ConfirmDialog.title",
|
3100
|
+
defaultMessage: "Confirmation"
|
2461
3101
|
}) }),
|
2462
|
-
/* @__PURE__ */ jsx(
|
2463
|
-
|
2464
|
-
|
2465
|
-
|
2466
|
-
/* @__PURE__ */
|
2467
|
-
|
2468
|
-
|
2469
|
-
|
2470
|
-
|
2471
|
-
|
2472
|
-
|
2473
|
-
|
2474
|
-
padding: 6,
|
2475
|
-
children: [
|
2476
|
-
/* @__PURE__ */ jsx(Flex, { direction: "row", as: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxs(Typography, { fontWeight: "semiBold", as: "li", children: [
|
2477
|
-
pathSegment,
|
2478
|
-
index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsx(
|
2479
|
-
ChevronRight,
|
2480
|
-
{
|
2481
|
-
fill: "neutral500",
|
2482
|
-
height: "0.8rem",
|
2483
|
-
width: "0.8rem",
|
2484
|
-
style: { margin: "0 0.8rem" }
|
2485
|
-
}
|
2486
|
-
)
|
2487
|
-
] }, index2)) }),
|
2488
|
-
/* @__PURE__ */ jsx(Typography, { as: "p", textColor: "neutral600", children: formatMessage({
|
2489
|
-
id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
|
2490
|
-
defaultMessage: getDefaultErrorMessage(reason)
|
2491
|
-
}) })
|
2492
|
-
]
|
2493
|
-
},
|
2494
|
-
fieldPath.join()
|
2495
|
-
)) })
|
2496
|
-
] });
|
3102
|
+
/* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3103
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3104
|
+
dialogBody
|
3105
|
+
] }) }),
|
3106
|
+
/* @__PURE__ */ jsxs(Dialog.Footer, { children: [
|
3107
|
+
/* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
|
3108
|
+
id: "app.components.Button.cancel",
|
3109
|
+
defaultMessage: "Cancel"
|
3110
|
+
}) }) }),
|
3111
|
+
endAction
|
3112
|
+
] })
|
3113
|
+
] }) });
|
2497
3114
|
};
|
2498
|
-
const
|
3115
|
+
const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
|
3116
|
+
const ConfirmDialogPublishAll = ({
|
3117
|
+
isOpen,
|
3118
|
+
onToggleDialog,
|
3119
|
+
isConfirmButtonLoading = false,
|
3120
|
+
onConfirm
|
3121
|
+
}) => {
|
2499
3122
|
const { formatMessage } = useIntl();
|
2500
|
-
const
|
2501
|
-
const
|
2502
|
-
const
|
2503
|
-
|
2504
|
-
|
2505
|
-
|
2506
|
-
|
2507
|
-
|
2508
|
-
|
3123
|
+
const selectedEntries = useTable("ConfirmDialogPublishAll", (state) => state.selectedRows);
|
3124
|
+
const { toggleNotification } = useNotification();
|
3125
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
|
3126
|
+
const { model, schema } = useDoc();
|
3127
|
+
const [{ query }] = useQueryParams();
|
3128
|
+
const enableDraftRelationsCount = false;
|
3129
|
+
const {
|
3130
|
+
data: countDraftRelations = 0,
|
3131
|
+
isLoading,
|
3132
|
+
error
|
3133
|
+
} = useGetManyDraftRelationCountQuery(
|
3134
|
+
{
|
3135
|
+
model,
|
3136
|
+
documentIds: selectedEntries.map((entry) => entry.documentId),
|
3137
|
+
locale: query?.plugins?.i18n?.locale
|
3138
|
+
},
|
3139
|
+
{
|
3140
|
+
skip: !enableDraftRelationsCount
|
3141
|
+
}
|
3142
|
+
);
|
3143
|
+
React.useEffect(() => {
|
3144
|
+
if (error) {
|
3145
|
+
toggleNotification({ type: "danger", message: formatAPIError(error) });
|
3146
|
+
}
|
3147
|
+
}, [error, formatAPIError, toggleNotification]);
|
3148
|
+
if (error) {
|
3149
|
+
return null;
|
3150
|
+
}
|
2509
3151
|
return /* @__PURE__ */ jsx(
|
2510
|
-
|
3152
|
+
ConfirmBulkActionDialog,
|
2511
3153
|
{
|
2512
|
-
|
2513
|
-
|
2514
|
-
|
2515
|
-
|
2516
|
-
|
2517
|
-
|
2518
|
-
|
2519
|
-
|
2520
|
-
|
3154
|
+
isOpen: isOpen && !isLoading,
|
3155
|
+
onToggleDialog,
|
3156
|
+
dialogBody: /* @__PURE__ */ jsxs(Fragment, { children: [
|
3157
|
+
/* @__PURE__ */ jsxs(Typography, { id: "confirm-description", textAlign: "center", children: [
|
3158
|
+
countDraftRelations > 0 && formatMessage(
|
3159
|
+
{
|
3160
|
+
id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
|
3161
|
+
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. "
|
3162
|
+
},
|
3163
|
+
{
|
3164
|
+
b: BoldChunk$1,
|
3165
|
+
count: countDraftRelations,
|
3166
|
+
entities: selectedEntries.length
|
3167
|
+
}
|
3168
|
+
),
|
3169
|
+
formatMessage({
|
3170
|
+
id: getTranslation("popUpWarning.bodyMessage.contentType.publish.all"),
|
3171
|
+
defaultMessage: "Are you sure you want to publish these entries?"
|
3172
|
+
})
|
3173
|
+
] }),
|
3174
|
+
schema?.pluginOptions && "i18n" in schema.pluginOptions && schema?.pluginOptions.i18n && /* @__PURE__ */ jsx(Typography, { textColor: "danger500", textAlign: "center", children: formatMessage(
|
2521
3175
|
{
|
2522
|
-
|
2523
|
-
|
2524
|
-
|
2525
|
-
|
2526
|
-
|
2527
|
-
variant: "ghost"
|
3176
|
+
id: getTranslation("Settings.list.actions.publishAdditionalInfos"),
|
3177
|
+
defaultMessage: "This will publish the active locale versions <em>(from Internationalization)</em>"
|
3178
|
+
},
|
3179
|
+
{
|
3180
|
+
em: Emphasis
|
2528
3181
|
}
|
2529
|
-
)
|
2530
|
-
}
|
3182
|
+
) })
|
3183
|
+
] }),
|
3184
|
+
endAction: /* @__PURE__ */ jsx(
|
3185
|
+
Button,
|
3186
|
+
{
|
3187
|
+
onClick: onConfirm,
|
3188
|
+
variant: "secondary",
|
3189
|
+
startIcon: /* @__PURE__ */ jsx(Check, {}),
|
3190
|
+
loading: isConfirmButtonLoading,
|
3191
|
+
children: formatMessage({
|
3192
|
+
id: "app.utils.publish",
|
3193
|
+
defaultMessage: "Publish"
|
3194
|
+
})
|
3195
|
+
}
|
3196
|
+
)
|
2531
3197
|
}
|
2532
3198
|
);
|
2533
3199
|
};
|
2534
|
-
const
|
2535
|
-
|
2536
|
-
|
2537
|
-
|
2538
|
-
const
|
2539
|
-
|
2540
|
-
|
2541
|
-
|
2542
|
-
|
2543
|
-
|
2544
|
-
|
2545
|
-
|
2546
|
-
|
2547
|
-
|
2548
|
-
|
2549
|
-
|
2550
|
-
|
2551
|
-
|
3200
|
+
const TypographyMaxWidth = styled(Typography)`
|
3201
|
+
max-width: 300px;
|
3202
|
+
`;
|
3203
|
+
const formatErrorMessages = (errors, parentKey, formatMessage) => {
|
3204
|
+
const messages = [];
|
3205
|
+
Object.entries(errors).forEach(([key, value]) => {
|
3206
|
+
const currentKey = parentKey ? `${parentKey}.${key}` : key;
|
3207
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
3208
|
+
if ("id" in value && "defaultMessage" in value) {
|
3209
|
+
messages.push(
|
3210
|
+
formatMessage(
|
3211
|
+
{
|
3212
|
+
id: `${value.id}.withField`,
|
3213
|
+
defaultMessage: value.defaultMessage
|
3214
|
+
},
|
3215
|
+
{ field: currentKey }
|
3216
|
+
)
|
3217
|
+
);
|
3218
|
+
} else {
|
3219
|
+
messages.push(
|
3220
|
+
...formatErrorMessages(
|
3221
|
+
// @ts-expect-error TODO: check why value is not compatible with FormErrors
|
3222
|
+
value,
|
3223
|
+
currentKey,
|
3224
|
+
formatMessage
|
3225
|
+
)
|
2552
3226
|
);
|
2553
|
-
toggleNotification({
|
2554
|
-
message: formatMessage({
|
2555
|
-
id: "content-manager.actions.edit.error",
|
2556
|
-
defaultMessage: "An error occurred while trying to edit the document."
|
2557
|
-
}),
|
2558
|
-
type: "danger"
|
2559
|
-
});
|
2560
|
-
return;
|
2561
3227
|
}
|
2562
|
-
|
2563
|
-
|
2564
|
-
|
3228
|
+
} else {
|
3229
|
+
messages.push(
|
3230
|
+
formatMessage(
|
3231
|
+
{
|
3232
|
+
id: `${value}.withField`,
|
3233
|
+
defaultMessage: value
|
3234
|
+
},
|
3235
|
+
{ field: currentKey }
|
3236
|
+
)
|
3237
|
+
);
|
3238
|
+
}
|
3239
|
+
});
|
3240
|
+
return messages;
|
3241
|
+
};
|
3242
|
+
const EntryValidationText = ({ validationErrors, status }) => {
|
3243
|
+
const { formatMessage } = useIntl();
|
3244
|
+
if (validationErrors) {
|
3245
|
+
const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
|
3246
|
+
" "
|
3247
|
+
);
|
3248
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3249
|
+
/* @__PURE__ */ jsx(CrossCircle, { fill: "danger600" }),
|
3250
|
+
/* @__PURE__ */ jsx(Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
|
3251
|
+
] });
|
3252
|
+
}
|
3253
|
+
if (status === "published") {
|
3254
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3255
|
+
/* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
3256
|
+
/* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
|
3257
|
+
id: "content-manager.bulk-publish.already-published",
|
3258
|
+
defaultMessage: "Already Published"
|
3259
|
+
}) })
|
3260
|
+
] });
|
3261
|
+
}
|
3262
|
+
if (status === "modified") {
|
3263
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3264
|
+
/* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
|
3265
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
3266
|
+
id: "content-manager.bulk-publish.modified",
|
3267
|
+
defaultMessage: "Ready to publish changes"
|
3268
|
+
}) })
|
3269
|
+
] });
|
3270
|
+
}
|
3271
|
+
return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3272
|
+
/* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
|
3273
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
3274
|
+
id: "app.utils.ready-to-publish",
|
3275
|
+
defaultMessage: "Ready to publish"
|
3276
|
+
}) })
|
3277
|
+
] });
|
3278
|
+
};
|
3279
|
+
const TABLE_HEADERS = [
|
3280
|
+
{ name: "id", label: "id" },
|
3281
|
+
{ name: "name", label: "name" },
|
3282
|
+
{ name: "status", label: "status" },
|
3283
|
+
{ name: "publicationStatus", label: "Publication status" }
|
3284
|
+
];
|
3285
|
+
const SelectedEntriesTableContent = ({
|
3286
|
+
isPublishing,
|
3287
|
+
rowsToDisplay = [],
|
3288
|
+
entriesToPublish = [],
|
3289
|
+
validationErrors = {}
|
3290
|
+
}) => {
|
3291
|
+
const { pathname } = useLocation();
|
3292
|
+
const { formatMessage } = useIntl();
|
3293
|
+
const {
|
3294
|
+
list: {
|
3295
|
+
settings: { mainField }
|
3296
|
+
}
|
3297
|
+
} = useDocLayout();
|
3298
|
+
const shouldDisplayMainField = mainField != null && mainField !== "id";
|
3299
|
+
return /* @__PURE__ */ jsxs(Table.Content, { children: [
|
3300
|
+
/* @__PURE__ */ jsxs(Table.Head, { children: [
|
3301
|
+
/* @__PURE__ */ jsx(Table.HeaderCheckboxCell, {}),
|
3302
|
+
TABLE_HEADERS.filter((head) => head.name !== "name" || shouldDisplayMainField).map(
|
3303
|
+
(head) => /* @__PURE__ */ jsx(Table.HeaderCell, { ...head }, head.name)
|
3304
|
+
)
|
3305
|
+
] }),
|
3306
|
+
/* @__PURE__ */ jsx(Table.Loading, {}),
|
3307
|
+
/* @__PURE__ */ jsx(Table.Body, { children: rowsToDisplay.map((row, index2) => /* @__PURE__ */ jsxs(Table.Row, { children: [
|
3308
|
+
/* @__PURE__ */ jsx(Table.CheckboxCell, { id: row.id }),
|
3309
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row.id }) }),
|
3310
|
+
shouldDisplayMainField && /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row[mainField] }) }),
|
3311
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(DocumentStatus, { status: row.status, maxWidth: "min-content" }) }),
|
3312
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: isPublishing && entriesToPublish.includes(row.documentId) ? /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3313
|
+
/* @__PURE__ */ jsx(Typography, { children: formatMessage({
|
3314
|
+
id: "content-manager.success.record.publishing",
|
3315
|
+
defaultMessage: "Publishing..."
|
3316
|
+
}) }),
|
3317
|
+
/* @__PURE__ */ jsx(Loader, { small: true })
|
3318
|
+
] }) : /* @__PURE__ */ jsx(
|
3319
|
+
EntryValidationText,
|
3320
|
+
{
|
3321
|
+
validationErrors: validationErrors[row.documentId],
|
3322
|
+
status: row.status
|
3323
|
+
}
|
3324
|
+
) }),
|
3325
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
|
3326
|
+
IconButton,
|
3327
|
+
{
|
3328
|
+
tag: Link,
|
3329
|
+
to: {
|
3330
|
+
pathname: `${pathname}/${row.documentId}`,
|
3331
|
+
search: row.locale && `?plugins[i18n][locale]=${row.locale}`
|
3332
|
+
},
|
3333
|
+
state: { from: pathname },
|
3334
|
+
label: formatMessage({
|
3335
|
+
id: "content-manager.bulk-publish.edit",
|
3336
|
+
defaultMessage: "Edit"
|
3337
|
+
}),
|
3338
|
+
target: "_blank",
|
3339
|
+
marginLeft: "auto",
|
3340
|
+
variant: "ghost",
|
3341
|
+
children: /* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" })
|
3342
|
+
}
|
3343
|
+
) }) })
|
3344
|
+
] }, row.id)) })
|
3345
|
+
] });
|
3346
|
+
};
|
3347
|
+
const BoldChunk = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
|
3348
|
+
const SelectedEntriesModalContent = ({
|
3349
|
+
listViewSelectedEntries,
|
3350
|
+
toggleModal,
|
3351
|
+
setListViewSelectedDocuments,
|
3352
|
+
model
|
3353
|
+
}) => {
|
3354
|
+
const { formatMessage } = useIntl();
|
3355
|
+
const { schema, components } = useContentTypeSchema(model);
|
3356
|
+
const documentIds = listViewSelectedEntries.map(({ documentId }) => documentId);
|
3357
|
+
const [{ query }] = useQueryParams();
|
3358
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
3359
|
+
const { data, isLoading, isFetching, refetch } = useGetAllDocumentsQuery(
|
3360
|
+
{
|
3361
|
+
model,
|
3362
|
+
params: {
|
3363
|
+
page: "1",
|
3364
|
+
pageSize: documentIds.length.toString(),
|
3365
|
+
sort: query.sort,
|
3366
|
+
filters: {
|
3367
|
+
documentId: {
|
3368
|
+
$in: documentIds
|
3369
|
+
}
|
3370
|
+
},
|
3371
|
+
locale: query.plugins?.i18n?.locale
|
3372
|
+
}
|
3373
|
+
},
|
3374
|
+
{
|
3375
|
+
selectFromResult: ({ data: data2, ...restRes }) => ({ data: data2?.results ?? [], ...restRes })
|
3376
|
+
}
|
3377
|
+
);
|
3378
|
+
const { rows, validationErrors } = React.useMemo(() => {
|
3379
|
+
if (data.length > 0 && schema) {
|
3380
|
+
const validate = createYupSchema(
|
3381
|
+
schema.attributes,
|
3382
|
+
components,
|
3383
|
+
// Since this is the "Publish" action, the validation
|
3384
|
+
// schema must enforce the rules for published entities
|
3385
|
+
{ status: "published" }
|
3386
|
+
);
|
3387
|
+
const validationErrors2 = {};
|
3388
|
+
const rows2 = data.map((entry) => {
|
3389
|
+
try {
|
3390
|
+
validate.validateSync(entry, { abortEarly: false });
|
3391
|
+
return entry;
|
3392
|
+
} catch (e) {
|
3393
|
+
if (e instanceof ValidationError) {
|
3394
|
+
validationErrors2[entry.documentId] = getYupValidationErrors(e);
|
3395
|
+
}
|
3396
|
+
return entry;
|
3397
|
+
}
|
3398
|
+
});
|
3399
|
+
return { rows: rows2, validationErrors: validationErrors2 };
|
3400
|
+
}
|
3401
|
+
return {
|
3402
|
+
rows: [],
|
3403
|
+
validationErrors: {}
|
3404
|
+
};
|
3405
|
+
}, [components, data, schema]);
|
3406
|
+
const [publishedCount, setPublishedCount] = React.useState(0);
|
3407
|
+
const [isDialogOpen, setIsDialogOpen] = React.useState(false);
|
3408
|
+
const { publishMany: bulkPublishAction } = useDocumentActions();
|
3409
|
+
const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
|
3410
|
+
const selectedRows = useTable("publishAction", (state) => state.selectedRows);
|
3411
|
+
const selectedEntries = rows.filter(
|
3412
|
+
(entry) => selectedRows.some((selectedEntry) => selectedEntry.documentId === entry.documentId)
|
3413
|
+
);
|
3414
|
+
const entriesToPublish = selectedEntries.filter((entry) => !validationErrors[entry.documentId]).map((entry) => entry.documentId);
|
3415
|
+
const selectedEntriesWithErrorsCount = selectedEntries.filter(
|
3416
|
+
({ documentId }) => validationErrors[documentId]
|
3417
|
+
).length;
|
3418
|
+
const selectedEntriesPublished = selectedEntries.filter(
|
3419
|
+
({ status }) => status === "published"
|
3420
|
+
).length;
|
3421
|
+
const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublished;
|
3422
|
+
const toggleDialog = () => setIsDialogOpen((prev) => !prev);
|
3423
|
+
const handleConfirmBulkPublish = async () => {
|
3424
|
+
toggleDialog();
|
3425
|
+
const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
|
3426
|
+
if (!("error" in res)) {
|
3427
|
+
setPublishedCount(res.count);
|
3428
|
+
const unpublishedEntries = rows.filter((row) => {
|
3429
|
+
return !entriesToPublish.includes(row.documentId);
|
3430
|
+
});
|
3431
|
+
setListViewSelectedDocuments(unpublishedEntries);
|
3432
|
+
}
|
3433
|
+
};
|
3434
|
+
const getFormattedCountMessage = () => {
|
3435
|
+
if (publishedCount) {
|
3436
|
+
return formatMessage(
|
3437
|
+
{
|
3438
|
+
id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
|
3439
|
+
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."
|
3440
|
+
},
|
3441
|
+
{
|
3442
|
+
publishedCount,
|
3443
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3444
|
+
b: BoldChunk
|
3445
|
+
}
|
3446
|
+
);
|
3447
|
+
}
|
3448
|
+
return formatMessage(
|
3449
|
+
{
|
3450
|
+
id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
|
3451
|
+
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."
|
3452
|
+
},
|
3453
|
+
{
|
3454
|
+
readyToPublishCount: selectedEntriesWithNoErrorsCount,
|
3455
|
+
withErrorsCount: selectedEntriesWithErrorsCount,
|
3456
|
+
alreadyPublishedCount: selectedEntriesPublished,
|
3457
|
+
b: BoldChunk
|
3458
|
+
}
|
3459
|
+
);
|
3460
|
+
};
|
3461
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
3462
|
+
/* @__PURE__ */ jsxs(Modal.Body, { children: [
|
3463
|
+
/* @__PURE__ */ jsx(Typography, { children: getFormattedCountMessage() }),
|
3464
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 5, children: /* @__PURE__ */ jsx(
|
3465
|
+
SelectedEntriesTableContent,
|
3466
|
+
{
|
3467
|
+
isPublishing: isSubmittingForm,
|
3468
|
+
rowsToDisplay: rows,
|
3469
|
+
entriesToPublish,
|
3470
|
+
validationErrors
|
3471
|
+
}
|
3472
|
+
) })
|
3473
|
+
] }),
|
3474
|
+
/* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
3475
|
+
/* @__PURE__ */ jsx(Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
|
3476
|
+
id: "app.components.Button.cancel",
|
3477
|
+
defaultMessage: "Cancel"
|
3478
|
+
}) }),
|
3479
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
3480
|
+
/* @__PURE__ */ jsx(Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
|
3481
|
+
/* @__PURE__ */ jsx(
|
3482
|
+
Button,
|
3483
|
+
{
|
3484
|
+
onClick: toggleDialog,
|
3485
|
+
disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
|
3486
|
+
loading: isSubmittingForm,
|
3487
|
+
children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
|
3488
|
+
}
|
3489
|
+
)
|
3490
|
+
] })
|
3491
|
+
] }),
|
3492
|
+
/* @__PURE__ */ jsx(
|
3493
|
+
ConfirmDialogPublishAll,
|
3494
|
+
{
|
3495
|
+
isOpen: isDialogOpen,
|
3496
|
+
onToggleDialog: toggleDialog,
|
3497
|
+
isConfirmButtonLoading: isSubmittingForm,
|
3498
|
+
onConfirm: handleConfirmBulkPublish
|
3499
|
+
}
|
3500
|
+
)
|
3501
|
+
] });
|
3502
|
+
};
|
3503
|
+
const PublishAction = ({ documents, model }) => {
|
3504
|
+
const { formatMessage } = useIntl();
|
3505
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3506
|
+
const showPublishButton = hasPublishPermission && documents.some(({ status }) => status !== "published");
|
3507
|
+
const setListViewSelectedDocuments = useTable("publishAction", (state) => state.selectRow);
|
3508
|
+
const refetchList = () => {
|
3509
|
+
contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
|
3510
|
+
};
|
3511
|
+
if (!showPublishButton) return null;
|
3512
|
+
return {
|
3513
|
+
actionType: "publish",
|
3514
|
+
variant: "tertiary",
|
3515
|
+
label: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" }),
|
3516
|
+
dialog: {
|
3517
|
+
type: "modal",
|
3518
|
+
title: formatMessage({
|
3519
|
+
id: getTranslation("containers.ListPage.selectedEntriesModal.title"),
|
3520
|
+
defaultMessage: "Publish entries"
|
3521
|
+
}),
|
3522
|
+
content: ({ onClose }) => {
|
3523
|
+
return /* @__PURE__ */ jsx(Table.Root, { rows: documents, defaultSelectedRows: documents, headers: TABLE_HEADERS, children: /* @__PURE__ */ jsx(
|
3524
|
+
SelectedEntriesModalContent,
|
3525
|
+
{
|
3526
|
+
listViewSelectedEntries: documents,
|
3527
|
+
toggleModal: () => {
|
3528
|
+
onClose();
|
3529
|
+
refetchList();
|
3530
|
+
},
|
3531
|
+
setListViewSelectedDocuments,
|
3532
|
+
model
|
3533
|
+
}
|
3534
|
+
) });
|
3535
|
+
},
|
3536
|
+
onClose: () => {
|
3537
|
+
refetchList();
|
3538
|
+
}
|
3539
|
+
}
|
3540
|
+
};
|
3541
|
+
};
|
3542
|
+
const BulkActionsRenderer = () => {
|
3543
|
+
const plugins = useStrapiApp("BulkActionsRenderer", (state) => state.plugins);
|
3544
|
+
const { model, collectionType } = useDoc();
|
3545
|
+
const { selectedRows } = useTable("BulkActionsRenderer", (state) => state);
|
3546
|
+
return /* @__PURE__ */ jsx(Flex, { gap: 2, children: /* @__PURE__ */ jsx(
|
3547
|
+
DescriptionComponentRenderer,
|
3548
|
+
{
|
3549
|
+
props: {
|
3550
|
+
model,
|
3551
|
+
collectionType,
|
3552
|
+
documents: selectedRows
|
3553
|
+
},
|
3554
|
+
descriptions: plugins["content-manager"].apis.getBulkActions(),
|
3555
|
+
children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(DocumentActionButton, { ...action }, action.id))
|
3556
|
+
}
|
3557
|
+
) });
|
3558
|
+
};
|
3559
|
+
const DeleteAction = ({ documents, model }) => {
|
3560
|
+
const { formatMessage } = useIntl();
|
3561
|
+
const { schema: contentType } = useDoc();
|
3562
|
+
const selectRow = useTable("DeleteAction", (state) => state.selectRow);
|
3563
|
+
const hasI18nEnabled = Boolean(contentType?.pluginOptions?.i18n);
|
3564
|
+
const [{ query }] = useQueryParams();
|
3565
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
3566
|
+
const hasDeletePermission = useDocumentRBAC("deleteAction", (state) => state.canDelete);
|
3567
|
+
const { deleteMany: bulkDeleteAction } = useDocumentActions();
|
3568
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3569
|
+
const handleConfirmBulkDelete = async () => {
|
3570
|
+
const res = await bulkDeleteAction({
|
3571
|
+
documentIds,
|
3572
|
+
model,
|
3573
|
+
params
|
3574
|
+
});
|
3575
|
+
if (!("error" in res)) {
|
3576
|
+
selectRow([]);
|
3577
|
+
}
|
3578
|
+
};
|
3579
|
+
if (!hasDeletePermission) return null;
|
3580
|
+
return {
|
3581
|
+
variant: "danger-light",
|
3582
|
+
label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
|
3583
|
+
dialog: {
|
3584
|
+
type: "dialog",
|
3585
|
+
title: formatMessage({
|
3586
|
+
id: "app.components.ConfirmDialog.title",
|
3587
|
+
defaultMessage: "Confirmation"
|
3588
|
+
}),
|
3589
|
+
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3590
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3591
|
+
/* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3592
|
+
id: "popUpWarning.bodyMessage.contentType.delete.all",
|
3593
|
+
defaultMessage: "Are you sure you want to delete these entries?"
|
3594
|
+
}) }),
|
3595
|
+
hasI18nEnabled && /* @__PURE__ */ jsx(Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsx(Typography, { textColor: "danger500", children: formatMessage(
|
3596
|
+
{
|
3597
|
+
id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
|
3598
|
+
defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
|
3599
|
+
},
|
3600
|
+
{
|
3601
|
+
em: Emphasis
|
3602
|
+
}
|
3603
|
+
) }) })
|
3604
|
+
] }),
|
3605
|
+
onConfirm: handleConfirmBulkDelete
|
3606
|
+
}
|
3607
|
+
};
|
3608
|
+
};
|
3609
|
+
DeleteAction.type = "delete";
|
3610
|
+
const UnpublishAction = ({ documents, model }) => {
|
3611
|
+
const { formatMessage } = useIntl();
|
3612
|
+
const { schema } = useDoc();
|
3613
|
+
const selectRow = useTable("UnpublishAction", (state) => state.selectRow);
|
3614
|
+
const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
|
3615
|
+
const hasI18nEnabled = Boolean(schema?.pluginOptions?.i18n);
|
3616
|
+
const hasDraftAndPublishEnabled = Boolean(schema?.options?.draftAndPublish);
|
3617
|
+
const { unpublishMany: bulkUnpublishAction } = useDocumentActions();
|
3618
|
+
const documentIds = documents.map(({ documentId }) => documentId);
|
3619
|
+
const [{ query }] = useQueryParams();
|
3620
|
+
const params = React.useMemo(() => buildValidParams(query), [query]);
|
3621
|
+
const handleConfirmBulkUnpublish = async () => {
|
3622
|
+
const data = await bulkUnpublishAction({ documentIds, model, params });
|
3623
|
+
if (!("error" in data)) {
|
3624
|
+
selectRow([]);
|
3625
|
+
}
|
3626
|
+
};
|
3627
|
+
const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
|
3628
|
+
if (!showUnpublishButton) return null;
|
3629
|
+
return {
|
3630
|
+
variant: "tertiary",
|
3631
|
+
label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
|
3632
|
+
dialog: {
|
3633
|
+
type: "dialog",
|
3634
|
+
title: formatMessage({
|
3635
|
+
id: "app.components.ConfirmDialog.title",
|
3636
|
+
defaultMessage: "Confirmation"
|
3637
|
+
}),
|
3638
|
+
content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
3639
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
|
3640
|
+
/* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
|
3641
|
+
id: "popUpWarning.bodyMessage.contentType.unpublish.all",
|
3642
|
+
defaultMessage: "Are you sure you want to unpublish these entries?"
|
3643
|
+
}) }),
|
3644
|
+
hasI18nEnabled && /* @__PURE__ */ jsx(Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsx(Typography, { textColor: "danger500", children: formatMessage(
|
3645
|
+
{
|
3646
|
+
id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
|
3647
|
+
defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
|
3648
|
+
},
|
3649
|
+
{
|
3650
|
+
em: Emphasis
|
3651
|
+
}
|
3652
|
+
) }) })
|
3653
|
+
] }),
|
3654
|
+
confirmButton: formatMessage({
|
3655
|
+
id: "app.utils.unpublish",
|
3656
|
+
defaultMessage: "Unpublish"
|
3657
|
+
}),
|
3658
|
+
onConfirm: handleConfirmBulkUnpublish
|
3659
|
+
}
|
3660
|
+
};
|
3661
|
+
};
|
3662
|
+
UnpublishAction.type = "unpublish";
|
3663
|
+
const Emphasis = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
|
3664
|
+
const DEFAULT_BULK_ACTIONS = [PublishAction, UnpublishAction, DeleteAction];
|
3665
|
+
const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
|
3666
|
+
const { formatMessage } = useIntl();
|
3667
|
+
const getDefaultErrorMessage = (reason) => {
|
3668
|
+
switch (reason) {
|
3669
|
+
case "relation":
|
3670
|
+
return "Duplicating the relation could remove it from the original entry.";
|
3671
|
+
case "unique":
|
3672
|
+
return "Identical values in a unique field are not allowed";
|
3673
|
+
default:
|
3674
|
+
return reason;
|
3675
|
+
}
|
3676
|
+
};
|
3677
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
3678
|
+
/* @__PURE__ */ jsx(Typography, { variant: "beta", children: formatMessage({
|
3679
|
+
id: getTranslation("containers.list.autoCloneModal.title"),
|
3680
|
+
defaultMessage: "This entry can't be duplicated directly."
|
3681
|
+
}) }),
|
3682
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 2, children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: formatMessage({
|
3683
|
+
id: getTranslation("containers.list.autoCloneModal.description"),
|
3684
|
+
defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
|
3685
|
+
}) }) }),
|
3686
|
+
/* @__PURE__ */ jsx(Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxs(
|
3687
|
+
Flex,
|
3688
|
+
{
|
3689
|
+
direction: "column",
|
3690
|
+
gap: 2,
|
3691
|
+
alignItems: "flex-start",
|
3692
|
+
borderColor: "neutral200",
|
3693
|
+
hasRadius: true,
|
3694
|
+
padding: 6,
|
3695
|
+
children: [
|
3696
|
+
/* @__PURE__ */ jsx(Flex, { direction: "row", tag: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxs(Typography, { fontWeight: "semiBold", tag: "li", children: [
|
3697
|
+
pathSegment,
|
3698
|
+
index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsx(
|
3699
|
+
ChevronRight,
|
3700
|
+
{
|
3701
|
+
fill: "neutral500",
|
3702
|
+
height: "0.8rem",
|
3703
|
+
width: "0.8rem",
|
3704
|
+
style: { margin: "0 0.8rem" }
|
3705
|
+
}
|
3706
|
+
)
|
3707
|
+
] }, index2)) }),
|
3708
|
+
/* @__PURE__ */ jsx(Typography, { tag: "p", textColor: "neutral600", children: formatMessage({
|
3709
|
+
id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
|
3710
|
+
defaultMessage: getDefaultErrorMessage(reason)
|
3711
|
+
}) })
|
3712
|
+
]
|
3713
|
+
},
|
3714
|
+
fieldPath.join()
|
3715
|
+
)) })
|
3716
|
+
] });
|
3717
|
+
};
|
3718
|
+
const TableActions = ({ document }) => {
|
3719
|
+
const { formatMessage } = useIntl();
|
3720
|
+
const { model, collectionType } = useDoc();
|
3721
|
+
const plugins = useStrapiApp("TableActions", (state) => state.plugins);
|
3722
|
+
const props = {
|
3723
|
+
activeTab: null,
|
3724
|
+
model,
|
3725
|
+
documentId: document.documentId,
|
3726
|
+
collectionType,
|
3727
|
+
document
|
3728
|
+
};
|
3729
|
+
return /* @__PURE__ */ jsx(
|
3730
|
+
DescriptionComponentRenderer,
|
3731
|
+
{
|
3732
|
+
props,
|
3733
|
+
descriptions: plugins["content-manager"].apis.getDocumentActions("table-row").filter((action) => action.name !== "PublishAction"),
|
3734
|
+
children: (actions2) => {
|
3735
|
+
const tableRowActions = actions2.filter((action) => {
|
3736
|
+
const positions = Array.isArray(action.position) ? action.position : [action.position];
|
3737
|
+
return positions.includes("table-row");
|
3738
|
+
});
|
3739
|
+
return /* @__PURE__ */ jsx(
|
3740
|
+
DocumentActionsMenu,
|
3741
|
+
{
|
3742
|
+
actions: tableRowActions,
|
3743
|
+
label: formatMessage({
|
3744
|
+
id: "content-manager.containers.list.table.row-actions",
|
3745
|
+
defaultMessage: "Row action"
|
3746
|
+
}),
|
3747
|
+
variant: "ghost"
|
3748
|
+
}
|
3749
|
+
);
|
3750
|
+
}
|
3751
|
+
}
|
3752
|
+
);
|
3753
|
+
};
|
3754
|
+
const EditAction = ({ documentId }) => {
|
3755
|
+
const navigate = useNavigate();
|
3756
|
+
const { formatMessage } = useIntl();
|
3757
|
+
const { canRead } = useDocumentRBAC("EditAction", ({ canRead: canRead2 }) => ({ canRead: canRead2 }));
|
3758
|
+
const { toggleNotification } = useNotification();
|
3759
|
+
const [{ query }] = useQueryParams();
|
3760
|
+
return {
|
3761
|
+
disabled: !canRead,
|
3762
|
+
icon: /* @__PURE__ */ jsx(StyledPencil, {}),
|
3763
|
+
label: formatMessage({
|
3764
|
+
id: "content-manager.actions.edit.label",
|
3765
|
+
defaultMessage: "Edit"
|
3766
|
+
}),
|
3767
|
+
position: "table-row",
|
3768
|
+
onClick: async () => {
|
3769
|
+
if (!documentId) {
|
3770
|
+
console.error(
|
3771
|
+
"You're trying to edit a document without an id, this is likely a bug with Strapi. Please open an issue."
|
3772
|
+
);
|
3773
|
+
toggleNotification({
|
3774
|
+
message: formatMessage({
|
3775
|
+
id: "content-manager.actions.edit.error",
|
3776
|
+
defaultMessage: "An error occurred while trying to edit the document."
|
3777
|
+
}),
|
3778
|
+
type: "danger"
|
3779
|
+
});
|
3780
|
+
return;
|
3781
|
+
}
|
3782
|
+
navigate({
|
3783
|
+
pathname: documentId,
|
3784
|
+
search: stringify({
|
2565
3785
|
plugins: query.plugins
|
2566
3786
|
})
|
2567
3787
|
});
|
@@ -2569,6 +3789,7 @@ const EditAction = ({ documentId }) => {
|
|
2569
3789
|
};
|
2570
3790
|
};
|
2571
3791
|
EditAction.type = "edit";
|
3792
|
+
EditAction.position = "table-row";
|
2572
3793
|
const StyledPencil = styled(Pencil)`
|
2573
3794
|
path {
|
2574
3795
|
fill: currentColor;
|
@@ -2621,7 +3842,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2621
3842
|
}),
|
2622
3843
|
content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
|
2623
3844
|
footer: ({ onClose }) => {
|
2624
|
-
return /* @__PURE__ */ jsxs(
|
3845
|
+
return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
2625
3846
|
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
|
2626
3847
|
id: "cancel",
|
2627
3848
|
defaultMessage: "Cancel"
|
@@ -2629,7 +3850,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2629
3850
|
/* @__PURE__ */ jsx(
|
2630
3851
|
LinkButton,
|
2631
3852
|
{
|
2632
|
-
|
3853
|
+
tag: NavLink,
|
2633
3854
|
to: {
|
2634
3855
|
pathname: `clone/${documentId}`
|
2635
3856
|
},
|
@@ -2645,6 +3866,7 @@ const CloneAction = ({ model, documentId }) => {
|
|
2645
3866
|
};
|
2646
3867
|
};
|
2647
3868
|
CloneAction.type = "clone";
|
3869
|
+
CloneAction.position = "table-row";
|
2648
3870
|
const StyledDuplicate = styled(Duplicate)`
|
2649
3871
|
path {
|
2650
3872
|
fill: currentColor;
|
@@ -2662,8 +3884,7 @@ class ContentManagerPlugin {
|
|
2662
3884
|
documentActions = [
|
2663
3885
|
...DEFAULT_ACTIONS,
|
2664
3886
|
...DEFAULT_TABLE_ROW_ACTIONS,
|
2665
|
-
...DEFAULT_HEADER_ACTIONS
|
2666
|
-
HistoryAction
|
3887
|
+
...DEFAULT_HEADER_ACTIONS
|
2667
3888
|
];
|
2668
3889
|
editViewSidePanels = [ActionsPanel];
|
2669
3890
|
headerActions = [];
|
@@ -2732,7 +3953,14 @@ class ContentManagerPlugin {
|
|
2732
3953
|
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
|
2733
3954
|
addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
|
2734
3955
|
getBulkActions: () => this.bulkActions,
|
2735
|
-
getDocumentActions: () =>
|
3956
|
+
getDocumentActions: (position) => {
|
3957
|
+
if (position) {
|
3958
|
+
return this.documentActions.filter(
|
3959
|
+
(action) => action.position == void 0 || [action.position].flat().includes(position)
|
3960
|
+
);
|
3961
|
+
}
|
3962
|
+
return this.documentActions;
|
3963
|
+
},
|
2736
3964
|
getEditViewSidePanels: () => this.editViewSidePanels,
|
2737
3965
|
getHeaderActions: () => this.headerActions
|
2738
3966
|
}
|
@@ -2742,16 +3970,71 @@ class ContentManagerPlugin {
|
|
2742
3970
|
const getPrintableType = (value) => {
|
2743
3971
|
const nativeType = typeof value;
|
2744
3972
|
if (nativeType === "object") {
|
2745
|
-
if (value === null)
|
2746
|
-
|
2747
|
-
if (Array.isArray(value))
|
2748
|
-
return "array";
|
3973
|
+
if (value === null) return "null";
|
3974
|
+
if (Array.isArray(value)) return "array";
|
2749
3975
|
if (value instanceof Object && value.constructor.name !== "Object") {
|
2750
3976
|
return value.constructor.name;
|
2751
3977
|
}
|
2752
3978
|
}
|
2753
3979
|
return nativeType;
|
2754
3980
|
};
|
3981
|
+
const HistoryAction = ({ model, document }) => {
|
3982
|
+
const { formatMessage } = useIntl();
|
3983
|
+
const [{ query }] = useQueryParams();
|
3984
|
+
const navigate = useNavigate();
|
3985
|
+
const { trackUsage } = useTracking();
|
3986
|
+
const { pathname } = useLocation();
|
3987
|
+
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
|
3988
|
+
if (!window.strapi.features.isEnabled("cms-content-history")) {
|
3989
|
+
return null;
|
3990
|
+
}
|
3991
|
+
const handleOnClick = () => {
|
3992
|
+
const destination = { pathname: "history", search: pluginsQueryParams };
|
3993
|
+
trackUsage("willNavigate", {
|
3994
|
+
from: pathname,
|
3995
|
+
to: `${pathname}/${destination.pathname}`
|
3996
|
+
});
|
3997
|
+
navigate(destination);
|
3998
|
+
};
|
3999
|
+
return {
|
4000
|
+
icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
|
4001
|
+
label: formatMessage({
|
4002
|
+
id: "content-manager.history.document-action",
|
4003
|
+
defaultMessage: "Content History"
|
4004
|
+
}),
|
4005
|
+
onClick: handleOnClick,
|
4006
|
+
disabled: (
|
4007
|
+
/**
|
4008
|
+
* The user is creating a new document.
|
4009
|
+
* It hasn't been saved yet, so there's no history to go to
|
4010
|
+
*/
|
4011
|
+
!document || /**
|
4012
|
+
* The document has been created but the current dimension has never been saved.
|
4013
|
+
* For example, the user is creating a new locale in an existing document,
|
4014
|
+
* so there's no history for the document in that locale
|
4015
|
+
*/
|
4016
|
+
!document.id || /**
|
4017
|
+
* History is only available for content types created by the user.
|
4018
|
+
* These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
|
4019
|
+
* which start with `admin::` or `plugin::`
|
4020
|
+
*/
|
4021
|
+
!model.startsWith("api::")
|
4022
|
+
),
|
4023
|
+
position: "header"
|
4024
|
+
};
|
4025
|
+
};
|
4026
|
+
HistoryAction.type = "history";
|
4027
|
+
HistoryAction.position = "header";
|
4028
|
+
const historyAdmin = {
|
4029
|
+
bootstrap(app) {
|
4030
|
+
const { addDocumentAction } = app.getPlugin("content-manager").apis;
|
4031
|
+
addDocumentAction((actions2) => {
|
4032
|
+
const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
|
4033
|
+
actions2.splice(indexOfDeleteAction, 0, HistoryAction);
|
4034
|
+
return actions2;
|
4035
|
+
});
|
4036
|
+
}
|
4037
|
+
};
|
2755
4038
|
const initialState = {
|
2756
4039
|
collectionTypeLinks: [],
|
2757
4040
|
components: [],
|
@@ -2788,316 +4071,94 @@ const { setInitialData } = actions;
|
|
2788
4071
|
const reducer = combineReducers({
|
2789
4072
|
app: reducer$1
|
2790
4073
|
});
|
2791
|
-
const
|
2792
|
-
|
2793
|
-
|
2794
|
-
|
2795
|
-
|
2796
|
-
|
2797
|
-
|
2798
|
-
|
2799
|
-
|
2800
|
-
|
2801
|
-
|
2802
|
-
|
2803
|
-
MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
|
2804
|
-
/**
|
2805
|
-
* Hook that allows to mutate the CM's edit view layout
|
2806
|
-
* @constant
|
2807
|
-
* @type {string}
|
2808
|
-
*/
|
2809
|
-
MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
|
2810
|
-
/**
|
2811
|
-
* Hook that allows to mutate the CM's single types links pre-set filters
|
2812
|
-
* @constant
|
2813
|
-
* @type {string}
|
2814
|
-
*/
|
2815
|
-
MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
|
2816
|
-
};
|
2817
|
-
const contentTypesApi = contentManagerApi.injectEndpoints({
|
2818
|
-
endpoints: (builder) => ({
|
2819
|
-
getContentTypeConfiguration: builder.query({
|
2820
|
-
query: (uid) => ({
|
2821
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2822
|
-
method: "GET"
|
2823
|
-
}),
|
2824
|
-
transformResponse: (response) => response.data,
|
2825
|
-
providesTags: (_result, _error, uid) => [
|
2826
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2827
|
-
{ type: "ContentTypeSettings", id: "LIST" }
|
2828
|
-
]
|
2829
|
-
}),
|
2830
|
-
getAllContentTypeSettings: builder.query({
|
2831
|
-
query: () => "/content-manager/content-types-settings",
|
2832
|
-
transformResponse: (response) => response.data,
|
2833
|
-
providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
|
2834
|
-
}),
|
2835
|
-
updateContentTypeConfiguration: builder.mutation({
|
2836
|
-
query: ({ uid, ...body }) => ({
|
2837
|
-
url: `/content-manager/content-types/${uid}/configuration`,
|
2838
|
-
method: "PUT",
|
2839
|
-
data: body
|
2840
|
-
}),
|
2841
|
-
transformResponse: (response) => response.data,
|
2842
|
-
invalidatesTags: (_result, _error, { uid }) => [
|
2843
|
-
{ type: "ContentTypesConfiguration", id: uid },
|
2844
|
-
{ type: "ContentTypeSettings", id: "LIST" },
|
2845
|
-
// Is this necessary?
|
2846
|
-
{ type: "InitialData" }
|
2847
|
-
]
|
4074
|
+
const previewApi = contentManagerApi.injectEndpoints({
|
4075
|
+
endpoints: (builder) => ({
|
4076
|
+
getPreviewUrl: builder.query({
|
4077
|
+
query({ query, params }) {
|
4078
|
+
return {
|
4079
|
+
url: `/content-manager/preview/url/${params.contentType}`,
|
4080
|
+
method: "GET",
|
4081
|
+
config: {
|
4082
|
+
params: query
|
4083
|
+
}
|
4084
|
+
};
|
4085
|
+
}
|
2848
4086
|
})
|
2849
4087
|
})
|
2850
4088
|
});
|
2851
|
-
const {
|
2852
|
-
|
2853
|
-
|
2854
|
-
|
2855
|
-
} = contentTypesApi;
|
2856
|
-
const checkIfAttributeIsDisplayable = (attribute) => {
|
2857
|
-
const { type } = attribute;
|
2858
|
-
if (type === "relation") {
|
2859
|
-
return !attribute.relation.toLowerCase().includes("morph");
|
4089
|
+
const { useGetPreviewUrlQuery } = previewApi;
|
4090
|
+
const ConditionalTooltip = ({ isShown, label, children }) => {
|
4091
|
+
if (isShown) {
|
4092
|
+
return /* @__PURE__ */ jsx(Tooltip, { label, children });
|
2860
4093
|
}
|
2861
|
-
return
|
2862
|
-
};
|
2863
|
-
const getMainField = (attribute, mainFieldName, { schemas, components }) => {
|
2864
|
-
if (!mainFieldName) {
|
2865
|
-
return void 0;
|
2866
|
-
}
|
2867
|
-
const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
|
2868
|
-
// @ts-expect-error – `targetModel` does exist on the attribute for a relation.
|
2869
|
-
schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
|
2870
|
-
);
|
2871
|
-
return {
|
2872
|
-
name: mainFieldName,
|
2873
|
-
type: mainFieldType ?? "string"
|
2874
|
-
};
|
2875
|
-
};
|
2876
|
-
const DEFAULT_SETTINGS = {
|
2877
|
-
bulkable: false,
|
2878
|
-
filterable: false,
|
2879
|
-
searchable: false,
|
2880
|
-
pagination: false,
|
2881
|
-
defaultSortBy: "",
|
2882
|
-
defaultSortOrder: "asc",
|
2883
|
-
mainField: "id",
|
2884
|
-
pageSize: 10
|
4094
|
+
return children;
|
2885
4095
|
};
|
2886
|
-
const
|
2887
|
-
const {
|
4096
|
+
const PreviewSidePanel = ({ model, documentId, document }) => {
|
4097
|
+
const { formatMessage } = useIntl();
|
4098
|
+
const { trackUsage } = useTracking();
|
4099
|
+
const { pathname } = useLocation();
|
2888
4100
|
const [{ query }] = useQueryParams();
|
2889
|
-
const
|
2890
|
-
const {
|
2891
|
-
|
2892
|
-
|
2893
|
-
const {
|
2894
|
-
data,
|
2895
|
-
isLoading: isLoadingConfigs,
|
2896
|
-
error,
|
2897
|
-
isFetching: isFetchingConfigs
|
2898
|
-
} = useGetContentTypeConfigurationQuery(model);
|
2899
|
-
const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
|
2900
|
-
React.useEffect(() => {
|
2901
|
-
if (error) {
|
2902
|
-
toggleNotification({
|
2903
|
-
type: "danger",
|
2904
|
-
message: formatAPIError(error)
|
2905
|
-
});
|
2906
|
-
}
|
2907
|
-
}, [error, formatAPIError, toggleNotification]);
|
2908
|
-
const editLayout = React.useMemo(
|
2909
|
-
() => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
|
2910
|
-
layout: [],
|
2911
|
-
components: {},
|
2912
|
-
metadatas: {},
|
2913
|
-
options: {},
|
2914
|
-
settings: DEFAULT_SETTINGS
|
2915
|
-
},
|
2916
|
-
[data, isLoading, schemas, schema, components]
|
2917
|
-
);
|
2918
|
-
const listLayout = React.useMemo(() => {
|
2919
|
-
return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
|
2920
|
-
layout: [],
|
2921
|
-
metadatas: {},
|
2922
|
-
options: {},
|
2923
|
-
settings: DEFAULT_SETTINGS
|
2924
|
-
};
|
2925
|
-
}, [data, isLoading, schemas, schema, components]);
|
2926
|
-
const { layout: edit } = React.useMemo(
|
2927
|
-
() => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
|
2928
|
-
layout: editLayout,
|
2929
|
-
query
|
2930
|
-
}),
|
2931
|
-
[editLayout, query, runHookWaterfall]
|
2932
|
-
);
|
2933
|
-
return {
|
2934
|
-
error,
|
2935
|
-
isLoading,
|
2936
|
-
edit,
|
2937
|
-
list: listLayout
|
2938
|
-
};
|
2939
|
-
};
|
2940
|
-
const useDocLayout = () => {
|
2941
|
-
const { model } = useDoc();
|
2942
|
-
return useDocumentLayout(model);
|
2943
|
-
};
|
2944
|
-
const formatEditLayout = (data, {
|
2945
|
-
schemas,
|
2946
|
-
schema,
|
2947
|
-
components
|
2948
|
-
}) => {
|
2949
|
-
let currentPanelIndex = 0;
|
2950
|
-
const panelledEditAttributes = convertEditLayoutToFieldLayouts(
|
2951
|
-
data.contentType.layouts.edit,
|
2952
|
-
schema?.attributes,
|
2953
|
-
data.contentType.metadatas,
|
2954
|
-
{ configurations: data.components, schemas: components },
|
2955
|
-
schemas
|
2956
|
-
).reduce((panels, row) => {
|
2957
|
-
if (row.some((field) => field.type === "dynamiczone")) {
|
2958
|
-
panels.push([row]);
|
2959
|
-
currentPanelIndex += 2;
|
2960
|
-
} else {
|
2961
|
-
if (!panels[currentPanelIndex]) {
|
2962
|
-
panels.push([]);
|
2963
|
-
}
|
2964
|
-
panels[currentPanelIndex].push(row);
|
2965
|
-
}
|
2966
|
-
return panels;
|
2967
|
-
}, []);
|
2968
|
-
const componentEditAttributes = Object.entries(data.components).reduce(
|
2969
|
-
(acc, [uid, configuration]) => {
|
2970
|
-
acc[uid] = {
|
2971
|
-
layout: convertEditLayoutToFieldLayouts(
|
2972
|
-
configuration.layouts.edit,
|
2973
|
-
components[uid].attributes,
|
2974
|
-
configuration.metadatas
|
2975
|
-
),
|
2976
|
-
settings: {
|
2977
|
-
...configuration.settings,
|
2978
|
-
icon: components[uid].info.icon,
|
2979
|
-
displayName: components[uid].info.displayName
|
2980
|
-
}
|
2981
|
-
};
|
2982
|
-
return acc;
|
2983
|
-
},
|
2984
|
-
{}
|
2985
|
-
);
|
2986
|
-
const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
2987
|
-
(acc, [attribute, metadata]) => {
|
2988
|
-
return {
|
2989
|
-
...acc,
|
2990
|
-
[attribute]: metadata.edit
|
2991
|
-
};
|
4101
|
+
const isModified = useForm("PreviewSidePanel", (state) => state.modified);
|
4102
|
+
const { data, error } = useGetPreviewUrlQuery({
|
4103
|
+
params: {
|
4104
|
+
contentType: model
|
2992
4105
|
},
|
2993
|
-
{
|
2994
|
-
|
2995
|
-
|
2996
|
-
|
2997
|
-
components: componentEditAttributes,
|
2998
|
-
metadatas: editMetadatas,
|
2999
|
-
settings: {
|
3000
|
-
...data.contentType.settings,
|
3001
|
-
displayName: schema?.info.displayName
|
3002
|
-
},
|
3003
|
-
options: {
|
3004
|
-
...schema?.options,
|
3005
|
-
...schema?.pluginOptions,
|
3006
|
-
...data.contentType.options
|
4106
|
+
query: {
|
4107
|
+
documentId,
|
4108
|
+
locale: document?.locale,
|
4109
|
+
status: document?.status
|
3007
4110
|
}
|
4111
|
+
});
|
4112
|
+
if (!data?.data?.url || error) {
|
4113
|
+
return null;
|
4114
|
+
}
|
4115
|
+
const trackNavigation = () => {
|
4116
|
+
const destinationPathname = pathname.replace(/\/$/, "") + "/preview";
|
4117
|
+
trackUsage("willNavigate", { from: pathname, to: destinationPathname });
|
3008
4118
|
};
|
3009
|
-
};
|
3010
|
-
const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
|
3011
|
-
return rows.map(
|
3012
|
-
(row) => row.map((field) => {
|
3013
|
-
const attribute = attributes[field.name];
|
3014
|
-
if (!attribute) {
|
3015
|
-
return null;
|
3016
|
-
}
|
3017
|
-
const { edit: metadata } = metadatas[field.name];
|
3018
|
-
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
3019
|
-
return {
|
3020
|
-
attribute,
|
3021
|
-
disabled: !metadata.editable,
|
3022
|
-
hint: metadata.description,
|
3023
|
-
label: metadata.label ?? "",
|
3024
|
-
name: field.name,
|
3025
|
-
// @ts-expect-error – mainField does exist on the metadata for a relation.
|
3026
|
-
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
3027
|
-
schemas,
|
3028
|
-
components: components?.schemas ?? {}
|
3029
|
-
}),
|
3030
|
-
placeholder: metadata.placeholder ?? "",
|
3031
|
-
required: attribute.required ?? false,
|
3032
|
-
size: field.size,
|
3033
|
-
unique: "unique" in attribute ? attribute.unique : false,
|
3034
|
-
visible: metadata.visible ?? true,
|
3035
|
-
type: attribute.type
|
3036
|
-
};
|
3037
|
-
}).filter((field) => field !== null)
|
3038
|
-
);
|
3039
|
-
};
|
3040
|
-
const formatListLayout = (data, {
|
3041
|
-
schemas,
|
3042
|
-
schema,
|
3043
|
-
components
|
3044
|
-
}) => {
|
3045
|
-
const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
|
3046
|
-
(acc, [attribute, metadata]) => {
|
3047
|
-
return {
|
3048
|
-
...acc,
|
3049
|
-
[attribute]: metadata.list
|
3050
|
-
};
|
3051
|
-
},
|
3052
|
-
{}
|
3053
|
-
);
|
3054
|
-
const listAttributes = convertListLayoutToFieldLayouts(
|
3055
|
-
data.contentType.layouts.list,
|
3056
|
-
schema?.attributes,
|
3057
|
-
listMetadatas,
|
3058
|
-
{ configurations: data.components, schemas: components },
|
3059
|
-
schemas
|
3060
|
-
);
|
3061
4119
|
return {
|
3062
|
-
|
3063
|
-
|
3064
|
-
|
3065
|
-
|
3066
|
-
|
3067
|
-
|
3068
|
-
|
3069
|
-
|
4120
|
+
title: formatMessage({ id: "content-manager.preview.panel.title", defaultMessage: "Preview" }),
|
4121
|
+
content: /* @__PURE__ */ jsx(
|
4122
|
+
ConditionalTooltip,
|
4123
|
+
{
|
4124
|
+
label: formatMessage({
|
4125
|
+
id: "content-manager.preview.panel.button-disabled-tooltip",
|
4126
|
+
defaultMessage: "Please save to open the preview"
|
4127
|
+
}),
|
4128
|
+
isShown: isModified,
|
4129
|
+
children: /* @__PURE__ */ jsx(Box, { cursor: "not-allowed", width: "100%", children: /* @__PURE__ */ jsx(
|
4130
|
+
Button,
|
4131
|
+
{
|
4132
|
+
variant: "tertiary",
|
4133
|
+
tag: Link,
|
4134
|
+
to: { pathname: "preview", search: stringify(query, { encode: false }) },
|
4135
|
+
onClick: trackNavigation,
|
4136
|
+
width: "100%",
|
4137
|
+
disabled: isModified,
|
4138
|
+
pointerEvents: isModified ? "none" : void 0,
|
4139
|
+
tabIndex: isModified ? -1 : void 0,
|
4140
|
+
children: formatMessage({
|
4141
|
+
id: "content-manager.preview.panel.button",
|
4142
|
+
defaultMessage: "Open preview"
|
4143
|
+
})
|
4144
|
+
}
|
4145
|
+
) })
|
4146
|
+
}
|
4147
|
+
)
|
3070
4148
|
};
|
3071
4149
|
};
|
3072
|
-
const
|
3073
|
-
|
3074
|
-
const
|
3075
|
-
|
3076
|
-
|
3077
|
-
}
|
3078
|
-
const metadata = metadatas[name];
|
3079
|
-
const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
|
3080
|
-
return {
|
3081
|
-
attribute,
|
3082
|
-
label: metadata.label ?? "",
|
3083
|
-
mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
|
3084
|
-
schemas,
|
3085
|
-
components: components?.schemas ?? {}
|
3086
|
-
}),
|
3087
|
-
name,
|
3088
|
-
searchable: metadata.searchable ?? true,
|
3089
|
-
sortable: metadata.sortable ?? true
|
3090
|
-
};
|
3091
|
-
}).filter((field) => field !== null);
|
4150
|
+
const previewAdmin = {
|
4151
|
+
bootstrap(app) {
|
4152
|
+
const contentManagerPluginApis = app.getPlugin("content-manager").apis;
|
4153
|
+
contentManagerPluginApis.addEditViewSidePanel([PreviewSidePanel]);
|
4154
|
+
}
|
3092
4155
|
};
|
3093
4156
|
const index = {
|
3094
4157
|
register(app) {
|
3095
4158
|
const cm = new ContentManagerPlugin();
|
3096
4159
|
app.addReducers({
|
3097
|
-
[contentManagerApi.reducerPath]: contentManagerApi.reducer,
|
3098
4160
|
[PLUGIN_ID]: reducer
|
3099
4161
|
});
|
3100
|
-
app.addMiddlewares([() => contentManagerApi.middleware]);
|
3101
4162
|
app.addMenuLink({
|
3102
4163
|
to: PLUGIN_ID,
|
3103
4164
|
icon: Feather,
|
@@ -3106,14 +4167,32 @@ const index = {
|
|
3106
4167
|
defaultMessage: "Content Manager"
|
3107
4168
|
},
|
3108
4169
|
permissions: [],
|
3109
|
-
|
4170
|
+
position: 1
|
4171
|
+
});
|
4172
|
+
app.router.addRoute({
|
4173
|
+
path: "content-manager/*",
|
4174
|
+
lazy: async () => {
|
4175
|
+
const { Layout } = await import("./layout-DY_D9MGA.mjs");
|
4176
|
+
return {
|
4177
|
+
Component: Layout
|
4178
|
+
};
|
4179
|
+
},
|
4180
|
+
children: routes
|
3110
4181
|
});
|
3111
4182
|
app.registerPlugin(cm.config);
|
3112
4183
|
},
|
4184
|
+
bootstrap(app) {
|
4185
|
+
if (typeof historyAdmin.bootstrap === "function") {
|
4186
|
+
historyAdmin.bootstrap(app);
|
4187
|
+
}
|
4188
|
+
if (typeof previewAdmin.bootstrap === "function") {
|
4189
|
+
previewAdmin.bootstrap(app);
|
4190
|
+
}
|
4191
|
+
},
|
3113
4192
|
async registerTrads({ locales }) {
|
3114
4193
|
const importedTrads = await Promise.all(
|
3115
4194
|
locales.map((locale) => {
|
3116
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-
|
4195
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-Dtk_ot79.mjs"), "./translations/es.json": () => import("./es-D34tqjMw.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr--pg5jUbt.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-BHqhDq4V.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
|
3117
4196
|
return {
|
3118
4197
|
data: prefixPluginTranslations(data, PLUGIN_ID),
|
3119
4198
|
locale
|
@@ -3131,45 +4210,48 @@ const index = {
|
|
3131
4210
|
};
|
3132
4211
|
export {
|
3133
4212
|
ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD as A,
|
3134
|
-
|
4213
|
+
BulkActionsRenderer as B,
|
3135
4214
|
COLLECTION_TYPES as C,
|
3136
4215
|
DocumentStatus as D,
|
3137
|
-
|
3138
|
-
|
3139
|
-
|
4216
|
+
extractContentTypeComponents as E,
|
4217
|
+
DEFAULT_SETTINGS as F,
|
4218
|
+
convertEditLayoutToFieldLayouts as G,
|
3140
4219
|
HOOKS as H,
|
3141
4220
|
InjectionZone as I,
|
3142
|
-
|
3143
|
-
|
4221
|
+
useDocument as J,
|
4222
|
+
useGetPreviewUrlQuery as K,
|
4223
|
+
index as L,
|
4224
|
+
useContentManagerContext as M,
|
4225
|
+
useDocumentActions as N,
|
3144
4226
|
Panels as P,
|
3145
4227
|
RelativeTime as R,
|
3146
4228
|
SINGLE_TYPES as S,
|
3147
4229
|
TableActions as T,
|
3148
|
-
|
3149
|
-
|
3150
|
-
|
3151
|
-
|
3152
|
-
|
3153
|
-
|
4230
|
+
useGetInitialDataQuery as a,
|
4231
|
+
useGetAllContentTypeSettingsQuery as b,
|
4232
|
+
useDoc as c,
|
4233
|
+
buildValidParams as d,
|
4234
|
+
contentManagerApi as e,
|
4235
|
+
useDocumentRBAC as f,
|
3154
4236
|
getTranslation as g,
|
3155
|
-
|
3156
|
-
|
3157
|
-
|
3158
|
-
|
3159
|
-
|
3160
|
-
|
3161
|
-
|
3162
|
-
|
3163
|
-
|
3164
|
-
|
3165
|
-
|
4237
|
+
useDocumentLayout as h,
|
4238
|
+
createYupSchema as i,
|
4239
|
+
Header as j,
|
4240
|
+
PERMISSIONS as k,
|
4241
|
+
DocumentRBAC as l,
|
4242
|
+
DOCUMENT_META_FIELDS as m,
|
4243
|
+
CLONE_PATH as n,
|
4244
|
+
useDocLayout as o,
|
4245
|
+
useGetContentTypeConfigurationQuery as p,
|
4246
|
+
CREATOR_FIELDS as q,
|
4247
|
+
getMainField as r,
|
3166
4248
|
setInitialData as s,
|
3167
4249
|
getDisplayName as t,
|
3168
|
-
|
4250
|
+
useContentTypeSchema as u,
|
3169
4251
|
checkIfAttributeIsDisplayable as v,
|
3170
4252
|
useGetAllDocumentsQuery as w,
|
3171
4253
|
convertListLayoutToFieldLayouts as x,
|
3172
4254
|
capitalise as y,
|
3173
4255
|
useUpdateContentTypeConfigurationMutation as z
|
3174
4256
|
};
|
3175
|
-
//# sourceMappingURL=index-
|
4257
|
+
//# sourceMappingURL=index-C2SagWVW.mjs.map
|