@strapi/content-manager 0.0.0-experimental.d1602f22dc638a4c3c5084965fd6126fff5e9d4f → 0.0.0-experimental.d2a56e52af31fcf0f0c582a5a2e58e310966e96b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/chunks/{CardDragPreview-DwuraT0K.js → CardDragPreview-DwuraT0K.mjs} +1 -1
- package/dist/admin/chunks/CardDragPreview-DwuraT0K.mjs.map +1 -0
- package/dist/admin/chunks/{ComponentConfigurationPage-DXwOtpq1.js → ComponentConfigurationPage-CGn9IYeg.js} +6 -6
- package/dist/admin/chunks/{ComponentConfigurationPage-DXwOtpq1.js.map → ComponentConfigurationPage-CGn9IYeg.js.map} +1 -1
- package/dist/admin/chunks/{ComponentConfigurationPage-DhYZp4nN.js → ComponentConfigurationPage-DgYK4xW6.mjs} +9 -9
- package/dist/admin/chunks/ComponentConfigurationPage-DgYK4xW6.mjs.map +1 -0
- package/dist/admin/chunks/{ComponentIcon-BZcTc4rj.js → ComponentIcon-BZcTc4rj.mjs} +1 -1
- package/dist/admin/chunks/ComponentIcon-BZcTc4rj.mjs.map +1 -0
- package/dist/admin/chunks/{EditConfigurationPage-D0Ng758X.js → EditConfigurationPage-7w_-4jF4.js} +6 -6
- package/dist/admin/chunks/{EditConfigurationPage-D0Ng758X.js.map → EditConfigurationPage-7w_-4jF4.js.map} +1 -1
- package/dist/admin/chunks/{EditConfigurationPage-DDuPch5d.js → EditConfigurationPage-C05SwwH-.mjs} +9 -9
- package/dist/admin/chunks/EditConfigurationPage-C05SwwH-.mjs.map +1 -0
- package/dist/admin/chunks/EditViewPage-CVRJBOEv.mjs +318 -0
- package/dist/admin/chunks/EditViewPage-CVRJBOEv.mjs.map +1 -0
- package/dist/admin/chunks/EditViewPage-CuQfZJDf.js +341 -0
- package/dist/admin/chunks/EditViewPage-CuQfZJDf.js.map +1 -0
- package/dist/admin/chunks/{FieldTypeIcon-BY6MrVF4.js → FieldTypeIcon-BY6MrVF4.mjs} +1 -1
- package/dist/admin/chunks/FieldTypeIcon-BY6MrVF4.mjs.map +1 -0
- package/dist/admin/chunks/{Form-BEqiuSvQ.js → Form-BqNYRsCb.js} +5 -5
- package/dist/admin/chunks/{Form-BEqiuSvQ.js.map → Form-BqNYRsCb.js.map} +1 -1
- package/dist/admin/chunks/{Form-CZmB6JIg.js → Form-DaEnqAeV.mjs} +5 -5
- package/dist/admin/chunks/Form-DaEnqAeV.mjs.map +1 -0
- package/dist/admin/chunks/{History-CPYXgxkS.js → History-B7dGNfmx.mjs} +68 -15
- package/dist/admin/chunks/History-B7dGNfmx.mjs.map +1 -0
- package/dist/admin/chunks/{History-BlLKDZSw.js → History-CEoOna4w.js} +67 -14
- package/dist/admin/chunks/History-CEoOna4w.js.map +1 -0
- package/dist/admin/chunks/{Input-CLX3C5DI.js → Input-B3QUS9rv.mjs} +2273 -511
- package/dist/admin/chunks/Input-B3QUS9rv.mjs.map +1 -0
- package/dist/admin/chunks/{Input-DiR2Xfa7.js → Input-B8I0b9aD.js} +2284 -519
- package/dist/admin/chunks/Input-B8I0b9aD.js.map +1 -0
- package/dist/admin/chunks/{ListConfigurationPage-DdTp-HxB.js → ListConfigurationPage-BbjJweN-.js} +7 -7
- package/dist/admin/chunks/{ListConfigurationPage-DdTp-HxB.js.map → ListConfigurationPage-BbjJweN-.js.map} +1 -1
- package/dist/admin/chunks/{ListConfigurationPage-CNvotSqe.js → ListConfigurationPage-VtFQ5mOK.mjs} +8 -8
- package/dist/admin/chunks/ListConfigurationPage-VtFQ5mOK.mjs.map +1 -0
- package/dist/admin/chunks/{ListViewPage-MJNfQTp-.js → ListViewPage-Cg3zbT7Y.mjs} +5 -5
- package/dist/admin/chunks/ListViewPage-Cg3zbT7Y.mjs.map +1 -0
- package/dist/admin/chunks/{ListViewPage-BtXYjEYz.js → ListViewPage-CzUm2VJN.js} +8 -8
- package/dist/admin/chunks/{ListViewPage-BtXYjEYz.js.map → ListViewPage-CzUm2VJN.js.map} +1 -1
- package/dist/admin/chunks/{NoContentTypePage-CVvVpwj4.js → NoContentTypePage-FcLLn2Wt.js} +3 -2
- package/dist/admin/chunks/{NoContentTypePage-BJrZvYPY.js.map → NoContentTypePage-FcLLn2Wt.js.map} +1 -1
- package/dist/admin/chunks/{NoContentTypePage-BJrZvYPY.js → NoContentTypePage-NOf7Aq_E.mjs} +3 -2
- package/dist/admin/chunks/NoContentTypePage-NOf7Aq_E.mjs.map +1 -0
- package/dist/admin/chunks/{NoPermissionsPage-C5yWg70d.js → NoPermissionsPage-DmeyXtCk.js} +3 -2
- package/dist/admin/chunks/{NoPermissionsPage-BulvG4hB.js.map → NoPermissionsPage-DmeyXtCk.js.map} +1 -1
- package/dist/admin/chunks/{NoPermissionsPage-BulvG4hB.js → NoPermissionsPage-OVr9KG6L.mjs} +3 -2
- package/dist/admin/chunks/NoPermissionsPage-OVr9KG6L.mjs.map +1 -0
- package/dist/admin/chunks/Preview-BH9l1QXk.mjs +593 -0
- package/dist/admin/chunks/Preview-BH9l1QXk.mjs.map +1 -0
- package/dist/admin/chunks/Preview-BYKkpc11.js +615 -0
- package/dist/admin/chunks/Preview-BYKkpc11.js.map +1 -0
- package/dist/admin/chunks/{ar-DckYq_WK.js → ar-DckYq_WK.mjs} +1 -1
- package/dist/admin/chunks/ar-DckYq_WK.mjs.map +1 -0
- package/dist/admin/chunks/{ca-DviY7mRj.js → ca-DviY7mRj.mjs} +1 -1
- package/dist/admin/chunks/ca-DviY7mRj.mjs.map +1 -0
- package/dist/admin/chunks/{cs-C7OSYFQ7.js → cs-C7OSYFQ7.mjs} +1 -1
- package/dist/admin/chunks/cs-C7OSYFQ7.mjs.map +1 -0
- package/dist/admin/chunks/{de-5QRlDHyR.js → de-5QRlDHyR.mjs} +1 -1
- package/dist/admin/chunks/de-5QRlDHyR.mjs.map +1 -0
- package/dist/admin/chunks/{en-LfhocNG2.js → en-C2zEwS3-.mjs} +6 -1
- package/dist/admin/chunks/en-C2zEwS3-.mjs.map +1 -0
- package/dist/admin/chunks/{en-C1CjdAtC.js → en-G976DLsg.js} +6 -1
- package/dist/admin/chunks/{en-LfhocNG2.js.map → en-G976DLsg.js.map} +1 -1
- package/dist/admin/chunks/{es-DkoWSExG.js → es-DkoWSExG.mjs} +1 -1
- package/dist/admin/chunks/es-DkoWSExG.mjs.map +1 -0
- package/dist/admin/chunks/{eu-BG1xX7HK.js → eu-BG1xX7HK.mjs} +1 -1
- package/dist/admin/chunks/eu-BG1xX7HK.mjs.map +1 -0
- package/dist/admin/chunks/{fr-CFdRaRVj.js → fr-CFdRaRVj.mjs} +1 -1
- package/dist/admin/chunks/fr-CFdRaRVj.mjs.map +1 -0
- package/dist/admin/chunks/{gu-D5MMMXRs.js → gu-D5MMMXRs.mjs} +1 -1
- package/dist/admin/chunks/gu-D5MMMXRs.mjs.map +1 -0
- package/dist/admin/chunks/{hi-lp17SCjr.js → hi-lp17SCjr.mjs} +1 -1
- package/dist/admin/chunks/hi-lp17SCjr.mjs.map +1 -0
- package/dist/admin/chunks/{hooks-DMvik5y_.js → hooks-DMvik5y_.mjs} +1 -1
- package/dist/admin/chunks/hooks-DMvik5y_.mjs.map +1 -0
- package/dist/admin/chunks/{hu-CLka1U2C.js → hu-CLka1U2C.mjs} +1 -1
- package/dist/admin/chunks/hu-CLka1U2C.mjs.map +1 -0
- package/dist/admin/chunks/{id-USfY9m1g.js → id-USfY9m1g.mjs} +1 -1
- package/dist/admin/chunks/id-USfY9m1g.mjs.map +1 -0
- package/dist/admin/chunks/{index-BRlRBRLb.js → index-BE7PI9Wp.mjs} +273 -173
- package/dist/admin/chunks/index-BE7PI9Wp.mjs.map +1 -0
- package/dist/admin/chunks/{index-ZIwOPk6p.js → index-BwIhYBsG.js} +246 -142
- package/dist/admin/chunks/index-BwIhYBsG.js.map +1 -0
- package/dist/admin/chunks/{it-BAHrwmYS.js → it-BAHrwmYS.mjs} +1 -1
- package/dist/admin/chunks/it-BAHrwmYS.mjs.map +1 -0
- package/dist/admin/chunks/{ja-BWKmBJFT.js → ja-BWKmBJFT.mjs} +1 -1
- package/dist/admin/chunks/ja-BWKmBJFT.mjs.map +1 -0
- package/dist/admin/chunks/{ko-CgADGBNt.js → ko-CgADGBNt.mjs} +1 -1
- package/dist/admin/chunks/ko-CgADGBNt.mjs.map +1 -0
- package/dist/admin/chunks/{layout-B3-guCPG.js → layout-9zlUM9V3.mjs} +81 -7
- package/dist/admin/chunks/layout-9zlUM9V3.mjs.map +1 -0
- package/dist/admin/chunks/{layout-ameRNiAM.js → layout-Cr0HaJVS.js} +87 -13
- package/dist/admin/chunks/layout-Cr0HaJVS.js.map +1 -0
- package/dist/admin/chunks/{ml-CnhCfOn_.js → ml-CnhCfOn_.mjs} +1 -1
- package/dist/admin/chunks/ml-CnhCfOn_.mjs.map +1 -0
- package/dist/admin/chunks/{ms-Bh09NFff.js → ms-Bh09NFff.mjs} +1 -1
- package/dist/admin/chunks/ms-Bh09NFff.mjs.map +1 -0
- package/dist/admin/chunks/{nl-C8HYflTc.js → nl-C8HYflTc.mjs} +1 -1
- package/dist/admin/chunks/nl-C8HYflTc.mjs.map +1 -0
- package/dist/admin/chunks/{useDragAndDrop-gcqEJMnO.js → objects-BJTP843m.js} +73 -1
- package/dist/admin/chunks/objects-BJTP843m.js.map +1 -0
- package/dist/admin/chunks/{useDragAndDrop-HYwNDExe.js → objects-D2z-IJgu.mjs} +72 -2
- package/dist/admin/chunks/objects-D2z-IJgu.mjs.map +1 -0
- package/dist/admin/chunks/{pl-MFCZJZuZ.js → pl-MFCZJZuZ.mjs} +1 -1
- package/dist/admin/chunks/pl-MFCZJZuZ.mjs.map +1 -0
- package/dist/admin/chunks/{pt-BR-CcotyBGJ.js → pt-BR-CcotyBGJ.mjs} +1 -1
- package/dist/admin/chunks/pt-BR-CcotyBGJ.mjs.map +1 -0
- package/dist/admin/chunks/{pt-HbmgeiYO.js → pt-HbmgeiYO.mjs} +1 -1
- package/dist/admin/chunks/pt-HbmgeiYO.mjs.map +1 -0
- package/dist/admin/chunks/{ru-CB4BUyQp.js → ru-CB4BUyQp.mjs} +1 -1
- package/dist/admin/chunks/{ru-CB4BUyQp.js.map → ru-CB4BUyQp.mjs.map} +1 -1
- package/dist/admin/chunks/{sa-n_aPA-pU.js → sa-n_aPA-pU.mjs} +1 -1
- package/dist/admin/chunks/sa-n_aPA-pU.mjs.map +1 -0
- package/dist/admin/chunks/{sk-tn_BDjE2.js → sk-tn_BDjE2.mjs} +1 -1
- package/dist/admin/chunks/sk-tn_BDjE2.mjs.map +1 -0
- package/dist/admin/chunks/{sv-cq4ZrQRd.js → sv-cq4ZrQRd.mjs} +1 -1
- package/dist/admin/chunks/sv-cq4ZrQRd.mjs.map +1 -0
- package/dist/admin/chunks/{th-mUH7hEtc.js → th-mUH7hEtc.mjs} +1 -1
- package/dist/admin/chunks/th-mUH7hEtc.mjs.map +1 -0
- package/dist/admin/chunks/{tr-Yt38daxh.js → tr-Yt38daxh.mjs} +1 -1
- package/dist/admin/chunks/tr-Yt38daxh.mjs.map +1 -0
- package/dist/admin/chunks/uk-BtM6WnaE.mjs +313 -0
- package/dist/admin/chunks/uk-BtM6WnaE.mjs.map +1 -0
- package/dist/admin/chunks/uk-DB6OgySY.js +318 -0
- package/dist/admin/chunks/{en-C1CjdAtC.js.map → uk-DB6OgySY.js.map} +1 -1
- package/dist/admin/chunks/{relations-CmoFVrKj.js → usePrev-DgZBp9Oo.js} +18 -2
- package/dist/admin/chunks/usePrev-DgZBp9Oo.js.map +1 -0
- package/dist/admin/chunks/{relations-DYQAaXwZ.js → usePrev-PisKKvhT.mjs} +18 -4
- package/dist/admin/chunks/usePrev-PisKKvhT.mjs.map +1 -0
- package/dist/admin/chunks/{vi-CvBGlTjr.js → vi-CvBGlTjr.mjs} +1 -1
- package/dist/admin/chunks/vi-CvBGlTjr.mjs.map +1 -0
- package/dist/admin/chunks/{zh-BmF-sHaT.js → zh-BmF-sHaT.mjs} +1 -1
- package/dist/admin/chunks/zh-BmF-sHaT.mjs.map +1 -0
- package/dist/admin/chunks/{zh-Hans-CI0HKio3.js → zh-Hans-CI0HKio3.mjs} +1 -1
- package/dist/admin/chunks/{zh-Hans-CI0HKio3.js.map → zh-Hans-CI0HKio3.mjs.map} +1 -1
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +2 -1
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/src/components/InjectionZone.d.ts +7 -1
- package/dist/admin/src/content-manager.d.ts +4 -0
- package/dist/admin/src/features/DocumentContext.d.ts +53 -0
- package/dist/admin/src/features/DocumentRBAC.d.ts +3 -2
- package/dist/admin/src/hooks/useDocument.d.ts +2 -0
- package/dist/admin/src/hooks/useDocumentActions.d.ts +1 -0
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +2 -1
- package/dist/admin/src/pages/EditView/components/EditorToolbarObserver.d.ts +11 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +49 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations/RelationModal.d.ts +8 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/{Relations.d.ts → Relations/Relations.d.ts} +8 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygNav.d.ts +1 -2
- package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +9 -3
- package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +7 -4
- package/dist/admin/src/preview/components/PreviewHeader.d.ts +1 -2
- package/dist/admin/src/preview/pages/Preview.d.ts +2 -0
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +1 -1
- package/dist/server/index.mjs.map +1 -1
- package/package.json +8 -8
- package/dist/admin/chunks/CardDragPreview-DwuraT0K.js.map +0 -1
- package/dist/admin/chunks/ComponentConfigurationPage-DhYZp4nN.js.map +0 -1
- package/dist/admin/chunks/ComponentIcon-BZcTc4rj.js.map +0 -1
- package/dist/admin/chunks/EditConfigurationPage-DDuPch5d.js.map +0 -1
- package/dist/admin/chunks/EditViewPage-jCZnUuCR.js +0 -265
- package/dist/admin/chunks/EditViewPage-jCZnUuCR.js.map +0 -1
- package/dist/admin/chunks/EditViewPage-zSnDwLz3.js +0 -288
- package/dist/admin/chunks/EditViewPage-zSnDwLz3.js.map +0 -1
- package/dist/admin/chunks/FieldTypeIcon-BY6MrVF4.js.map +0 -1
- package/dist/admin/chunks/Form-CZmB6JIg.js.map +0 -1
- package/dist/admin/chunks/History-BlLKDZSw.js.map +0 -1
- package/dist/admin/chunks/History-CPYXgxkS.js.map +0 -1
- package/dist/admin/chunks/Input-CLX3C5DI.js.map +0 -1
- package/dist/admin/chunks/Input-DiR2Xfa7.js.map +0 -1
- package/dist/admin/chunks/ListConfigurationPage-CNvotSqe.js.map +0 -1
- package/dist/admin/chunks/ListViewPage-MJNfQTp-.js.map +0 -1
- package/dist/admin/chunks/NoContentTypePage-CVvVpwj4.js.map +0 -1
- package/dist/admin/chunks/NoPermissionsPage-C5yWg70d.js.map +0 -1
- package/dist/admin/chunks/Preview-DEuQgQg2.js +0 -482
- package/dist/admin/chunks/Preview-DEuQgQg2.js.map +0 -1
- package/dist/admin/chunks/Preview-H74FQ9Cq.js +0 -504
- package/dist/admin/chunks/Preview-H74FQ9Cq.js.map +0 -1
- package/dist/admin/chunks/Relations-C8jbZPVK.js +0 -827
- package/dist/admin/chunks/Relations-C8jbZPVK.js.map +0 -1
- package/dist/admin/chunks/Relations-mxOUS7TJ.js +0 -853
- package/dist/admin/chunks/Relations-mxOUS7TJ.js.map +0 -1
- package/dist/admin/chunks/ar-DckYq_WK.js.map +0 -1
- package/dist/admin/chunks/ca-DviY7mRj.js.map +0 -1
- package/dist/admin/chunks/cs-C7OSYFQ7.js.map +0 -1
- package/dist/admin/chunks/de-5QRlDHyR.js.map +0 -1
- package/dist/admin/chunks/es-DkoWSExG.js.map +0 -1
- package/dist/admin/chunks/eu-BG1xX7HK.js.map +0 -1
- package/dist/admin/chunks/fr-CFdRaRVj.js.map +0 -1
- package/dist/admin/chunks/gu-D5MMMXRs.js.map +0 -1
- package/dist/admin/chunks/hi-lp17SCjr.js.map +0 -1
- package/dist/admin/chunks/hooks-DMvik5y_.js.map +0 -1
- package/dist/admin/chunks/hu-CLka1U2C.js.map +0 -1
- package/dist/admin/chunks/id-USfY9m1g.js.map +0 -1
- package/dist/admin/chunks/index-BRlRBRLb.js.map +0 -1
- package/dist/admin/chunks/index-ZIwOPk6p.js.map +0 -1
- package/dist/admin/chunks/it-BAHrwmYS.js.map +0 -1
- package/dist/admin/chunks/ja-BWKmBJFT.js.map +0 -1
- package/dist/admin/chunks/ko-CgADGBNt.js.map +0 -1
- package/dist/admin/chunks/layout-B3-guCPG.js.map +0 -1
- package/dist/admin/chunks/layout-ameRNiAM.js.map +0 -1
- package/dist/admin/chunks/ml-CnhCfOn_.js.map +0 -1
- package/dist/admin/chunks/ms-Bh09NFff.js.map +0 -1
- package/dist/admin/chunks/nl-C8HYflTc.js.map +0 -1
- package/dist/admin/chunks/objects-C3EebVVe.js +0 -76
- package/dist/admin/chunks/objects-C3EebVVe.js.map +0 -1
- package/dist/admin/chunks/objects-wl73iEma.js +0 -73
- package/dist/admin/chunks/objects-wl73iEma.js.map +0 -1
- package/dist/admin/chunks/pl-MFCZJZuZ.js.map +0 -1
- package/dist/admin/chunks/pt-BR-CcotyBGJ.js.map +0 -1
- package/dist/admin/chunks/pt-HbmgeiYO.js.map +0 -1
- package/dist/admin/chunks/relations-CmoFVrKj.js.map +0 -1
- package/dist/admin/chunks/relations-DYQAaXwZ.js.map +0 -1
- package/dist/admin/chunks/sa-n_aPA-pU.js.map +0 -1
- package/dist/admin/chunks/sk-tn_BDjE2.js.map +0 -1
- package/dist/admin/chunks/sv-cq4ZrQRd.js.map +0 -1
- package/dist/admin/chunks/th-mUH7hEtc.js.map +0 -1
- package/dist/admin/chunks/tr-Yt38daxh.js.map +0 -1
- package/dist/admin/chunks/uk-B24MoTVg.js +0 -145
- package/dist/admin/chunks/uk-B24MoTVg.js.map +0 -1
- package/dist/admin/chunks/uk-Cpgmm7gE.js +0 -140
- package/dist/admin/chunks/uk-Cpgmm7gE.js.map +0 -1
- package/dist/admin/chunks/useDragAndDrop-HYwNDExe.js.map +0 -1
- package/dist/admin/chunks/useDragAndDrop-gcqEJMnO.js.map +0 -1
- package/dist/admin/chunks/usePrev-Bjw2dhmq.js +0 -18
- package/dist/admin/chunks/usePrev-Bjw2dhmq.js.map +0 -1
- package/dist/admin/chunks/usePrev-DIYl-IAL.js +0 -21
- package/dist/admin/chunks/usePrev-DIYl-IAL.js.map +0 -1
- package/dist/admin/chunks/vi-CvBGlTjr.js.map +0 -1
- package/dist/admin/chunks/zh-BmF-sHaT.js.map +0 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +0 -0
- package/dist/admin/src/preview/components/PreviewContent.d.ts +0 -3
@@ -1,27 +1,75 @@
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
2
2
|
import * as React from 'react';
|
3
|
-
import { useState, useEffect, useCallback
|
4
|
-
import { useStrapiApp, createContext, useField, useForm, useNotification,
|
5
|
-
import { Box, SingleSelect, SingleSelectOption, Typography, Flex,
|
6
|
-
import { CodeBlock as CodeBlock$1, HeadingOne, HeadingTwo, HeadingThree, HeadingFour, HeadingFive, HeadingSix, Image as Image$1, NumberList, BulletList, Paragraph, Quotes, Link as Link$1, Drag, Collapse, Bold, Italic, Underline, StrikeThrough, Code, Expand, PlusCircle, Trash,
|
3
|
+
import { useState, useEffect, useCallback } from 'react';
|
4
|
+
import { useStrapiApp, useElementOnScreen, createContext, useField, useForm, useNotification, Form, ConfirmDialog, useRBAC, DescriptionComponentRenderer, useQueryParams, useFocusInputField, useAPIErrorHandler, InputRenderer as InputRenderer$1 } from '@strapi/admin/strapi-admin';
|
5
|
+
import { Box, SingleSelect, SingleSelectOption, Typography, Flex, Button, Popover, Field, Menu, IconButton, Tooltip, useComposedRefs, Portal, FocusTrap, Divider, VisuallyHidden, Accordion, MenuItem, Grid as Grid$1, TextInput, Modal, TextButton, Dialog, Loader, EmptyStateLayout, Link as Link$2, Combobox, ComboboxOption, IconButtonGroup } from '@strapi/design-system';
|
6
|
+
import { CodeBlock as CodeBlock$1, HeadingOne, HeadingTwo, HeadingThree, HeadingFour, HeadingFive, HeadingSix, Image as Image$1, NumberList, BulletList, Paragraph, Quotes, More, Link as Link$1, Drag, Collapse, Bold, Italic, Underline, StrikeThrough, Code, Expand, PlusCircle, Trash, EyeStriked, ArrowLeft, ArrowsOut, WarningCircle, ArrowClockwise, Cross, CheckCircle, Loader as Loader$1, Plus } from '@strapi/icons';
|
7
7
|
import { useIntl } from 'react-intl';
|
8
|
-
import { g as getTranslation,
|
8
|
+
import { g as getTranslation, c as useDocumentContext, d as useDocumentLayout, e as createDefaultForm, t as transformDocument, f as useLazyGetDocumentQuery, h as createYupSchema, P as PERMISSIONS, i as DocumentRBAC, j as DocumentActionButton, D as DocumentStatus, C as COLLECTION_TYPES, S as SINGLE_TYPES, k as buildValidParams, l as contentManagerApi, m as useDoc, n as CLONE_PATH, o as useDocumentRBAC } from './index-BE7PI9Wp.mjs';
|
9
9
|
import { styled, css, keyframes } from 'styled-components';
|
10
10
|
import { Editor as Editor$1, Transforms, Node, Element, Range, Path, Point, createEditor } from 'slate';
|
11
11
|
import { withHistory } from 'slate-history';
|
12
12
|
import { useFocused, useSelected, ReactEditor, Editable, Slate, useSlate, withReact } from 'slate-react';
|
13
13
|
import * as Prism from 'prismjs';
|
14
14
|
import 'prismjs/themes/prism-solarizedlight.css';
|
15
|
-
import
|
16
|
-
import
|
15
|
+
import 'prismjs/components/prism-asmatmel';
|
16
|
+
import 'prismjs/components/prism-bash';
|
17
|
+
import 'prismjs/components/prism-basic';
|
18
|
+
import 'prismjs/components/prism-c';
|
19
|
+
import 'prismjs/components/prism-clojure';
|
20
|
+
import 'prismjs/components/prism-cobol';
|
21
|
+
import 'prismjs/components/prism-cpp';
|
22
|
+
import 'prismjs/components/prism-csharp';
|
23
|
+
import 'prismjs/components/prism-dart';
|
24
|
+
import 'prismjs/components/prism-docker';
|
25
|
+
import 'prismjs/components/prism-elixir';
|
26
|
+
import 'prismjs/components/prism-erlang';
|
27
|
+
import 'prismjs/components/prism-fortran';
|
28
|
+
import 'prismjs/components/prism-fsharp';
|
29
|
+
import 'prismjs/components/prism-go';
|
30
|
+
import 'prismjs/components/prism-graphql';
|
31
|
+
import 'prismjs/components/prism-groovy';
|
32
|
+
import 'prismjs/components/prism-haskell';
|
33
|
+
import 'prismjs/components/prism-haxe';
|
34
|
+
import 'prismjs/components/prism-ini';
|
35
|
+
import 'prismjs/components/prism-java';
|
36
|
+
import 'prismjs/components/prism-javascript';
|
37
|
+
import 'prismjs/components/prism-jsx';
|
38
|
+
import 'prismjs/components/prism-json';
|
39
|
+
import 'prismjs/components/prism-julia';
|
40
|
+
import 'prismjs/components/prism-kotlin';
|
41
|
+
import 'prismjs/components/prism-latex';
|
42
|
+
import 'prismjs/components/prism-lua';
|
43
|
+
import 'prismjs/components/prism-markdown';
|
44
|
+
import 'prismjs/components/prism-matlab';
|
45
|
+
import 'prismjs/components/prism-makefile';
|
46
|
+
import 'prismjs/components/prism-objectivec';
|
47
|
+
import 'prismjs/components/prism-perl';
|
48
|
+
import 'prismjs/components/prism-php';
|
49
|
+
import 'prismjs/components/prism-powershell';
|
50
|
+
import 'prismjs/components/prism-python';
|
51
|
+
import 'prismjs/components/prism-r';
|
52
|
+
import 'prismjs/components/prism-ruby';
|
53
|
+
import 'prismjs/components/prism-rust';
|
54
|
+
import 'prismjs/components/prism-sas';
|
55
|
+
import 'prismjs/components/prism-scala';
|
56
|
+
import 'prismjs/components/prism-scheme';
|
57
|
+
import 'prismjs/components/prism-sql';
|
58
|
+
import 'prismjs/components/prism-stata';
|
59
|
+
import 'prismjs/components/prism-swift';
|
60
|
+
import 'prismjs/components/prism-typescript';
|
61
|
+
import 'prismjs/components/prism-tsx';
|
62
|
+
import 'prismjs/components/prism-vbnet';
|
63
|
+
import 'prismjs/components/prism-yaml';
|
64
|
+
import { p as prefixFileUrlWithBackendUrl, u as useGetRelationsQuery, g as getRelationLabel, a as useDebounce, b as useLazySearchRelationsQuery, c as usePrev } from './usePrev-PisKKvhT.mjs';
|
65
|
+
import { D as DIRECTIONS, u as useDragAndDrop, I as ItemTypes, g as getIn, a as DROP_SENSITIVITY } from './objects-D2z-IJgu.mjs';
|
17
66
|
import * as Toolbar from '@radix-ui/react-toolbar';
|
18
67
|
import { getEmptyImage } from 'react-dnd-html5-backend';
|
19
|
-
import {
|
20
|
-
import { g as getIn } from './objects-wl73iEma.js';
|
21
|
-
import { u as useComponent, C as ComponentProvider, M as MemoizedRelationsField } from './Relations-C8jbZPVK.js';
|
68
|
+
import { useNavigate, useLocation, useMatch } from 'react-router-dom';
|
22
69
|
import pipe$1 from 'lodash/fp/pipe';
|
23
|
-
import { C as ComponentIcon, a as COMPONENT_ICONS } from './ComponentIcon-BZcTc4rj.
|
24
|
-
import {
|
70
|
+
import { C as ComponentIcon, a as COMPONENT_ICONS } from './ComponentIcon-BZcTc4rj.mjs';
|
71
|
+
import { generateNKeysBetween } from 'fractional-indexing';
|
72
|
+
import { FixedSizeList } from 'react-window';
|
25
73
|
import CodeMirror from 'codemirror5';
|
26
74
|
import sanitizeHtml from 'sanitize-html';
|
27
75
|
import { getLanguage, highlight, highlightAuto } from 'highlight.js';
|
@@ -410,11 +458,6 @@ const isText$2 = (node)=>{
|
|
410
458
|
}
|
411
459
|
};
|
412
460
|
|
413
|
-
if (typeof window !== 'undefined' && !window.Prism) {
|
414
|
-
window.Prism = Prism;
|
415
|
-
}
|
416
|
-
// NOTE: use dynamic requires to ensure they are run after Prism is set globally
|
417
|
-
require('./utils/prismLanguages');
|
418
461
|
const decorateCode = ([node, path])=>{
|
419
462
|
const ranges = [];
|
420
463
|
// make sure it is an Slate Element
|
@@ -987,7 +1030,7 @@ const isListNode$1 = (element)=>{
|
|
987
1030
|
return element.type === 'list';
|
988
1031
|
};
|
989
1032
|
|
990
|
-
const
|
1033
|
+
const StyledLink = styled(Box)`
|
991
1034
|
text-decoration: none;
|
992
1035
|
`;
|
993
1036
|
const RemoveButton = styled(Button)`
|
@@ -1047,9 +1090,10 @@ const LinkContent = /*#__PURE__*/ React.forwardRef(({ link, children, attributes
|
|
1047
1090
|
open: popoverOpen,
|
1048
1091
|
children: [
|
1049
1092
|
/*#__PURE__*/ jsx(Popover.Trigger, {
|
1050
|
-
children: /*#__PURE__*/ jsx(
|
1093
|
+
children: /*#__PURE__*/ jsx(StyledLink, {
|
1051
1094
|
...attributes,
|
1052
1095
|
ref: forwardedRef,
|
1096
|
+
tag: "a",
|
1053
1097
|
href: link.url,
|
1054
1098
|
onClick: ()=>setPopoverOpen(true),
|
1055
1099
|
color: "primary600",
|
@@ -1653,13 +1697,103 @@ const quoteBlocks = {
|
|
1653
1697
|
}
|
1654
1698
|
};
|
1655
1699
|
|
1700
|
+
const ObservedToolbarComponent = ({ index, lastVisibleIndex, setLastVisibleIndex, rootRef, children })=>{
|
1701
|
+
const isVisible = index <= lastVisibleIndex;
|
1702
|
+
const containerRef = useElementOnScreen((isVisible)=>{
|
1703
|
+
/**
|
1704
|
+
* It's the MoreMenu's job to make an item not visible when there's not room for it.
|
1705
|
+
* But we need to react here to the element becoming visible again.
|
1706
|
+
*/ if (isVisible) {
|
1707
|
+
setLastVisibleIndex((prev)=>Math.max(prev, index));
|
1708
|
+
}
|
1709
|
+
}, {
|
1710
|
+
threshold: 1,
|
1711
|
+
root: rootRef.current
|
1712
|
+
});
|
1713
|
+
return /*#__PURE__*/ jsx("div", {
|
1714
|
+
ref: containerRef,
|
1715
|
+
style: {
|
1716
|
+
/**
|
1717
|
+
* Use visibility so that the element occupies the space if requires even when there's not
|
1718
|
+
* enough room for it to be visible. The empty reserved space will be clipped by the
|
1719
|
+
* overflow:hidden rule on the parent, so it doesn't affect the UI.
|
1720
|
+
* This way we can keep observing its visiblity and react to browser resize events.
|
1721
|
+
*/ visibility: isVisible ? 'visible' : 'hidden'
|
1722
|
+
},
|
1723
|
+
children: children
|
1724
|
+
});
|
1725
|
+
};
|
1726
|
+
const EditorToolbarObserver = ({ observedComponents, menuTriggerVariant = 'ghost' })=>{
|
1727
|
+
const { formatMessage } = useIntl();
|
1728
|
+
const toolbarRef = React.useRef(null);
|
1729
|
+
const [lastVisibleIndex, setLastVisibleIndex] = React.useState(observedComponents.length - 1);
|
1730
|
+
const hasHiddenItems = lastVisibleIndex < observedComponents.length - 1;
|
1731
|
+
const menuIndex = lastVisibleIndex + 1;
|
1732
|
+
const [open, setOpen] = React.useState(false);
|
1733
|
+
const isMenuOpenWithContent = open && hasHiddenItems;
|
1734
|
+
const menuTriggerRef = useElementOnScreen((isVisible)=>{
|
1735
|
+
// We only react to the menu becoming invisible. When that happens, we hide the last item.
|
1736
|
+
if (!isVisible) {
|
1737
|
+
/**
|
1738
|
+
* If there's no room for any item, the index can be -1.
|
1739
|
+
* This is intentional, in that case only the more menu will be visible.
|
1740
|
+
**/ setLastVisibleIndex((prev)=>prev - 1);
|
1741
|
+
// Maintain the menu state if it has content
|
1742
|
+
setOpen(isMenuOpenWithContent);
|
1743
|
+
}
|
1744
|
+
}, {
|
1745
|
+
threshold: 1,
|
1746
|
+
root: toolbarRef.current
|
1747
|
+
});
|
1748
|
+
return observedComponents.map((component, index)=>{
|
1749
|
+
return /*#__PURE__*/ jsx(ObservedToolbarComponent, {
|
1750
|
+
index: index,
|
1751
|
+
lastVisibleIndex: lastVisibleIndex,
|
1752
|
+
setLastVisibleIndex: setLastVisibleIndex,
|
1753
|
+
rootRef: toolbarRef,
|
1754
|
+
children: component.toolbar
|
1755
|
+
}, component.key);
|
1756
|
+
}).toSpliced(menuIndex, 0, /*#__PURE__*/ jsxs(Menu.Root, {
|
1757
|
+
defaultOpen: false,
|
1758
|
+
open: isMenuOpenWithContent,
|
1759
|
+
onOpenChange: setOpen,
|
1760
|
+
children: [
|
1761
|
+
/*#__PURE__*/ jsx(Menu.Trigger, {
|
1762
|
+
paddingLeft: 0,
|
1763
|
+
paddingRight: 0,
|
1764
|
+
ref: menuTriggerRef,
|
1765
|
+
variant: menuTriggerVariant,
|
1766
|
+
style: {
|
1767
|
+
visibility: hasHiddenItems ? 'visible' : 'hidden'
|
1768
|
+
},
|
1769
|
+
label: formatMessage({
|
1770
|
+
id: 'global.more',
|
1771
|
+
defaultMessage: 'More'
|
1772
|
+
}),
|
1773
|
+
tag: IconButton,
|
1774
|
+
icon: /*#__PURE__*/ jsx(More, {})
|
1775
|
+
}),
|
1776
|
+
/*#__PURE__*/ jsx(Menu.Content, {
|
1777
|
+
onCloseAutoFocus: (e)=>e.preventDefault(),
|
1778
|
+
maxHeight: "100%",
|
1779
|
+
minWidth: "256px",
|
1780
|
+
popoverPlacement: "bottom-end",
|
1781
|
+
zIndex: 2,
|
1782
|
+
children: observedComponents.slice(menuIndex).map((component)=>/*#__PURE__*/ jsx(React.Fragment, {
|
1783
|
+
children: component.menu
|
1784
|
+
}, component.key))
|
1785
|
+
})
|
1786
|
+
]
|
1787
|
+
}, "more-menu"));
|
1788
|
+
};
|
1789
|
+
|
1656
1790
|
const ToolbarWrapper = styled(Flex)`
|
1657
1791
|
&[aria-disabled='true'] {
|
1658
1792
|
cursor: not-allowed;
|
1659
1793
|
background: ${({ theme })=>theme.colors.neutral150};
|
1660
1794
|
}
|
1661
1795
|
`;
|
1662
|
-
const
|
1796
|
+
const ToolbarSeparator = styled(Toolbar.Separator)`
|
1663
1797
|
background: ${({ theme })=>theme.colors.neutral150};
|
1664
1798
|
width: 1px;
|
1665
1799
|
height: 2.4rem;
|
@@ -1729,7 +1863,7 @@ const ToolbarButton = ({ icon: Icon, name, label, isActive, disabled, handleClic
|
|
1729
1863
|
const labelMessage = formatMessage(label);
|
1730
1864
|
const enabledColor = isActive ? 'primary600' : 'neutral600';
|
1731
1865
|
return /*#__PURE__*/ jsx(Tooltip, {
|
1732
|
-
|
1866
|
+
label: labelMessage,
|
1733
1867
|
children: /*#__PURE__*/ jsx(Toolbar.ToggleItem, {
|
1734
1868
|
value: name,
|
1735
1869
|
"data-state": isActive ? 'on' : 'off',
|
@@ -1921,8 +2055,9 @@ const BlockOption = ({ value, icon: Icon, label, blockSelected })=>{
|
|
1921
2055
|
const isListNode = (node)=>{
|
1922
2056
|
return Node.isNode(node) && !Editor$1.isEditor(node) && node.type === 'list';
|
1923
2057
|
};
|
1924
|
-
const ListButton = ({ block, format })=>{
|
2058
|
+
const ListButton = ({ block, format, location = 'toolbar' })=>{
|
1925
2059
|
const { editor, disabled, blocks } = useBlocksEditorContext('ListButton');
|
2060
|
+
const { formatMessage } = useIntl();
|
1926
2061
|
const isListActive = ()=>{
|
1927
2062
|
if (!editor.selection) return false;
|
1928
2063
|
// Get the parent list at selection anchor node
|
@@ -1998,6 +2133,18 @@ const ListButton = ({ block, format })=>{
|
|
1998
2133
|
}
|
1999
2134
|
}
|
2000
2135
|
};
|
2136
|
+
if (location === 'menu') {
|
2137
|
+
const Icon = block.icon;
|
2138
|
+
return /*#__PURE__*/ jsxs(StyledMenuItem, {
|
2139
|
+
onSelect: ()=>toggleList(format),
|
2140
|
+
isActive: isListActive(),
|
2141
|
+
disabled: isListDisabled(),
|
2142
|
+
children: [
|
2143
|
+
/*#__PURE__*/ jsx(Icon, {}),
|
2144
|
+
formatMessage(block.label)
|
2145
|
+
]
|
2146
|
+
});
|
2147
|
+
}
|
2001
2148
|
return /*#__PURE__*/ jsx(ToolbarButton, {
|
2002
2149
|
icon: block.icon,
|
2003
2150
|
name: format,
|
@@ -2007,8 +2154,9 @@ const ListButton = ({ block, format })=>{
|
|
2007
2154
|
handleClick: ()=>toggleList(format)
|
2008
2155
|
});
|
2009
2156
|
};
|
2010
|
-
const LinkButton = ({ disabled })=>{
|
2157
|
+
const LinkButton = ({ disabled, location = 'toolbar' })=>{
|
2011
2158
|
const { editor } = useBlocksEditorContext('LinkButton');
|
2159
|
+
const { formatMessage } = useIntl();
|
2012
2160
|
const isLinkActive = ()=>{
|
2013
2161
|
const { selection } = editor;
|
2014
2162
|
if (!selection) return false;
|
@@ -2049,20 +2197,55 @@ const LinkButton = ({ disabled })=>{
|
|
2049
2197
|
url: ''
|
2050
2198
|
});
|
2051
2199
|
};
|
2200
|
+
const label = {
|
2201
|
+
id: 'components.Blocks.link',
|
2202
|
+
defaultMessage: 'Link'
|
2203
|
+
};
|
2204
|
+
if (location === 'menu') {
|
2205
|
+
return /*#__PURE__*/ jsxs(StyledMenuItem, {
|
2206
|
+
onSelect: addLink,
|
2207
|
+
isActive: isLinkActive(),
|
2208
|
+
disabled: isLinkDisabled(),
|
2209
|
+
children: [
|
2210
|
+
/*#__PURE__*/ jsx(Link$1, {}),
|
2211
|
+
formatMessage(label)
|
2212
|
+
]
|
2213
|
+
});
|
2214
|
+
}
|
2052
2215
|
return /*#__PURE__*/ jsx(ToolbarButton, {
|
2053
2216
|
icon: Link$1,
|
2054
2217
|
name: "link",
|
2055
|
-
label:
|
2056
|
-
id: 'components.Blocks.link',
|
2057
|
-
defaultMessage: 'Link'
|
2058
|
-
},
|
2218
|
+
label: label,
|
2059
2219
|
isActive: isLinkActive(),
|
2060
2220
|
handleClick: addLink,
|
2061
2221
|
disabled: isLinkDisabled()
|
2062
2222
|
});
|
2063
2223
|
};
|
2224
|
+
const StyledMenuItem = styled(Menu.Item)`
|
2225
|
+
&:hover {
|
2226
|
+
background-color: ${({ theme })=>theme.colors.primary100};
|
2227
|
+
}
|
2228
|
+
|
2229
|
+
${(props)=>props.isActive && css`
|
2230
|
+
font-weight: bold;
|
2231
|
+
background-color: ${({ theme })=>theme.colors.primary100};
|
2232
|
+
color: ${({ theme })=>theme.colors.primary600};
|
2233
|
+
font-weight: bold;
|
2234
|
+
`}
|
2235
|
+
|
2236
|
+
> span {
|
2237
|
+
display: inline-flex;
|
2238
|
+
gap: ${({ theme })=>theme.spaces[2]};
|
2239
|
+
align-items: center;
|
2240
|
+
}
|
2241
|
+
|
2242
|
+
svg {
|
2243
|
+
fill: ${({ theme, isActive })=>isActive ? theme.colors.primary600 : theme.colors.neutral600};
|
2244
|
+
}
|
2245
|
+
`;
|
2064
2246
|
const BlocksToolbar = ()=>{
|
2065
2247
|
const { editor, blocks, modifiers, disabled } = useBlocksEditorContext('BlocksToolbar');
|
2248
|
+
const { formatMessage } = useIntl();
|
2066
2249
|
/**
|
2067
2250
|
* The modifier buttons are disabled when an image is selected.
|
2068
2251
|
*/ const checkButtonDisabled = ()=>{
|
@@ -2083,6 +2266,94 @@ const BlocksToolbar = ()=>{
|
|
2083
2266
|
return false;
|
2084
2267
|
};
|
2085
2268
|
const isButtonDisabled = checkButtonDisabled();
|
2269
|
+
/**
|
2270
|
+
* Observed components are ones that may or may not be visible in the toolbar, depending on the
|
2271
|
+
* available space. They provide two render props:
|
2272
|
+
* - renderInToolbar: for when we try to render the component in the toolbar (may be hidden)
|
2273
|
+
* - renderInMenu: for when the component didn't fit in the toolbar and is relegated
|
2274
|
+
* to the "more" menu
|
2275
|
+
*/ const observedComponents = [
|
2276
|
+
...Object.entries(modifiers).map(([name, modifier])=>{
|
2277
|
+
const Icon = modifier.icon;
|
2278
|
+
const isActive = modifier.checkIsActive(editor);
|
2279
|
+
const handleSelect = ()=>modifier.handleToggle(editor);
|
2280
|
+
return {
|
2281
|
+
toolbar: /*#__PURE__*/ jsx(ToolbarButton, {
|
2282
|
+
name: name,
|
2283
|
+
icon: modifier.icon,
|
2284
|
+
label: modifier.label,
|
2285
|
+
isActive: modifier.checkIsActive(editor),
|
2286
|
+
handleClick: handleSelect,
|
2287
|
+
disabled: isButtonDisabled
|
2288
|
+
}, name),
|
2289
|
+
menu: /*#__PURE__*/ jsxs(StyledMenuItem, {
|
2290
|
+
onSelect: handleSelect,
|
2291
|
+
isActive: isActive,
|
2292
|
+
children: [
|
2293
|
+
/*#__PURE__*/ jsx(Icon, {}),
|
2294
|
+
formatMessage(modifier.label)
|
2295
|
+
]
|
2296
|
+
}),
|
2297
|
+
key: `modifier.${name}`
|
2298
|
+
};
|
2299
|
+
}),
|
2300
|
+
{
|
2301
|
+
toolbar: /*#__PURE__*/ jsx(LinkButton, {
|
2302
|
+
disabled: isButtonDisabled,
|
2303
|
+
location: "toolbar"
|
2304
|
+
}),
|
2305
|
+
menu: /*#__PURE__*/ jsx(LinkButton, {
|
2306
|
+
disabled: isButtonDisabled,
|
2307
|
+
location: "menu"
|
2308
|
+
}),
|
2309
|
+
key: 'block.link'
|
2310
|
+
},
|
2311
|
+
{
|
2312
|
+
// List buttons can only be rendered together when in the toolbar
|
2313
|
+
toolbar: /*#__PURE__*/ jsxs(Flex, {
|
2314
|
+
direction: "row",
|
2315
|
+
gap: 1,
|
2316
|
+
children: [
|
2317
|
+
/*#__PURE__*/ jsx(ToolbarSeparator, {}),
|
2318
|
+
/*#__PURE__*/ jsx(Toolbar.ToggleGroup, {
|
2319
|
+
type: "single",
|
2320
|
+
asChild: true,
|
2321
|
+
children: /*#__PURE__*/ jsxs(Flex, {
|
2322
|
+
gap: 1,
|
2323
|
+
children: [
|
2324
|
+
/*#__PURE__*/ jsx(ListButton, {
|
2325
|
+
block: blocks['list-unordered'],
|
2326
|
+
format: "unordered",
|
2327
|
+
location: "toolbar"
|
2328
|
+
}),
|
2329
|
+
/*#__PURE__*/ jsx(ListButton, {
|
2330
|
+
block: blocks['list-ordered'],
|
2331
|
+
format: "ordered",
|
2332
|
+
location: "toolbar"
|
2333
|
+
})
|
2334
|
+
]
|
2335
|
+
})
|
2336
|
+
})
|
2337
|
+
]
|
2338
|
+
}),
|
2339
|
+
menu: /*#__PURE__*/ jsxs(Fragment, {
|
2340
|
+
children: [
|
2341
|
+
/*#__PURE__*/ jsx(Menu.Separator, {}),
|
2342
|
+
/*#__PURE__*/ jsx(ListButton, {
|
2343
|
+
block: blocks['list-unordered'],
|
2344
|
+
format: "unordered",
|
2345
|
+
location: "menu"
|
2346
|
+
}),
|
2347
|
+
/*#__PURE__*/ jsx(ListButton, {
|
2348
|
+
block: blocks['list-ordered'],
|
2349
|
+
format: "ordered",
|
2350
|
+
location: "menu"
|
2351
|
+
})
|
2352
|
+
]
|
2353
|
+
}),
|
2354
|
+
key: 'block.list'
|
2355
|
+
}
|
2356
|
+
];
|
2086
2357
|
return /*#__PURE__*/ jsx(Toolbar.Root, {
|
2087
2358
|
"aria-disabled": disabled,
|
2088
2359
|
asChild: true,
|
@@ -2092,43 +2363,18 @@ const BlocksToolbar = ()=>{
|
|
2092
2363
|
width: "100%",
|
2093
2364
|
children: [
|
2094
2365
|
/*#__PURE__*/ jsx(BlocksDropdown, {}),
|
2095
|
-
/*#__PURE__*/ jsx(
|
2366
|
+
/*#__PURE__*/ jsx(ToolbarSeparator, {}),
|
2096
2367
|
/*#__PURE__*/ jsx(Toolbar.ToggleGroup, {
|
2097
2368
|
type: "multiple",
|
2098
2369
|
asChild: true,
|
2099
|
-
children: /*#__PURE__*/
|
2100
|
-
|
2101
|
-
children: [
|
2102
|
-
Object.entries(modifiers).map(([name, modifier])=>/*#__PURE__*/ jsx(ToolbarButton, {
|
2103
|
-
name: name,
|
2104
|
-
icon: modifier.icon,
|
2105
|
-
label: modifier.label,
|
2106
|
-
isActive: modifier.checkIsActive(editor),
|
2107
|
-
handleClick: ()=>modifier.handleToggle(editor),
|
2108
|
-
disabled: isButtonDisabled
|
2109
|
-
}, name)),
|
2110
|
-
/*#__PURE__*/ jsx(LinkButton, {
|
2111
|
-
disabled: isButtonDisabled
|
2112
|
-
})
|
2113
|
-
]
|
2114
|
-
})
|
2115
|
-
}),
|
2116
|
-
/*#__PURE__*/ jsx(Separator, {}),
|
2117
|
-
/*#__PURE__*/ jsx(Toolbar.ToggleGroup, {
|
2118
|
-
type: "single",
|
2119
|
-
asChild: true,
|
2120
|
-
children: /*#__PURE__*/ jsxs(Flex, {
|
2370
|
+
children: /*#__PURE__*/ jsx(Flex, {
|
2371
|
+
direction: "row",
|
2121
2372
|
gap: 1,
|
2122
|
-
|
2123
|
-
|
2124
|
-
|
2125
|
-
|
2126
|
-
|
2127
|
-
/*#__PURE__*/ jsx(ListButton, {
|
2128
|
-
block: blocks['list-ordered'],
|
2129
|
-
format: "ordered"
|
2130
|
-
})
|
2131
|
-
]
|
2373
|
+
grow: 1,
|
2374
|
+
overflow: "hidden",
|
2375
|
+
children: /*#__PURE__*/ jsx(EditorToolbarObserver, {
|
2376
|
+
observedComponents: observedComponents
|
2377
|
+
})
|
2132
2378
|
})
|
2133
2379
|
})
|
2134
2380
|
]
|
@@ -3217,6 +3463,20 @@ const Initializer = ({ disabled, name, onClick })=>{
|
|
3217
3463
|
});
|
3218
3464
|
};
|
3219
3465
|
|
3466
|
+
/**
|
3467
|
+
* We use this component to wrap any individual component field in the Edit View,
|
3468
|
+
* this could be a component field in a dynamic zone, a component within a repeatable space,
|
3469
|
+
* or even nested components.
|
3470
|
+
*
|
3471
|
+
* We primarily need this to provide the component id to the components so that they can
|
3472
|
+
* correctly fetch their relations.
|
3473
|
+
*/ const [ComponentProvider, useComponent] = createContext('ComponentContext', {
|
3474
|
+
id: undefined,
|
3475
|
+
level: -1,
|
3476
|
+
uid: undefined,
|
3477
|
+
type: undefined
|
3478
|
+
});
|
3479
|
+
|
3220
3480
|
const AddComponentButton = ({ hasError, isDisabled, isOpen, children, onClick })=>{
|
3221
3481
|
return /*#__PURE__*/ jsx(StyledButton, {
|
3222
3482
|
type: "button",
|
@@ -3322,15 +3582,24 @@ const ComponentCategory = ({ category, components = [], variant = 'primary', onA
|
|
3322
3582
|
const ResponsiveAccordionContent = styled(Accordion.Content)`
|
3323
3583
|
container-type: inline-size;
|
3324
3584
|
`;
|
3325
|
-
|
3326
|
-
|
3327
|
-
|
3328
|
-
|
3329
|
-
|
3330
|
-
|
3331
|
-
|
3332
|
-
|
3333
|
-
|
3585
|
+
/**
|
3586
|
+
* TODO:
|
3587
|
+
* JSDOM cannot handle container queries.
|
3588
|
+
* This is a temporary workaround so that tests do not fail in the CI when jestdom throws an error
|
3589
|
+
* for failing to parse the stylesheet.
|
3590
|
+
*/ const Grid = process.env.NODE_ENV !== 'test' ? styled(Box)`
|
3591
|
+
display: grid;
|
3592
|
+
grid-template-columns: repeat(auto-fill, 100%);
|
3593
|
+
grid-gap: 4px;
|
3594
|
+
|
3595
|
+
@container (min-width: ${()=>RESPONSIVE_CONTAINER_BREAKPOINTS.sm}) {
|
3596
|
+
grid-template-columns: repeat(auto-fill, 14rem);
|
3597
|
+
}
|
3598
|
+
` : styled(Box)`
|
3599
|
+
display: grid;
|
3600
|
+
grid-template-columns: repeat(auto-fill, 100%);
|
3601
|
+
grid-gap: 4px;
|
3602
|
+
`;
|
3334
3603
|
const ComponentBox = styled(Flex)`
|
3335
3604
|
color: ${({ theme })=>theme.colors.neutral600};
|
3336
3605
|
cursor: pointer;
|
@@ -3395,7 +3664,19 @@ const ComponentPicker = ({ dynamicComponentsByCategory = {}, isOpen, onClickAddC
|
|
3395
3664
|
const DynamicComponent = ({ componentUid, disabled, index, name, onRemoveComponentClick, onMoveComponent, onGrabItem, onDropItem, onCancel, dynamicComponentsByCategory = {}, onAddComponent, children })=>{
|
3396
3665
|
const { formatMessage } = useIntl();
|
3397
3666
|
const formValues = useForm('DynamicComponent', (state)=>state.values);
|
3398
|
-
const
|
3667
|
+
const documentMeta = useDocumentContext('DynamicComponent', (state)=>state.meta);
|
3668
|
+
const rootDocumentMeta = useDocumentContext('DynamicComponent', (state)=>state.rootDocumentMeta);
|
3669
|
+
const { edit: { components: rootComponents } } = useDocumentLayout(rootDocumentMeta.model);
|
3670
|
+
const { edit: { components: relatedComponents } } = useDocumentLayout(documentMeta.model);
|
3671
|
+
// Merge the root level components and related components
|
3672
|
+
const components = React.useMemo(()=>({
|
3673
|
+
...rootComponents,
|
3674
|
+
...relatedComponents
|
3675
|
+
}), [
|
3676
|
+
rootComponents,
|
3677
|
+
relatedComponents
|
3678
|
+
]);
|
3679
|
+
const document = useDocumentContext('DynamicComponent', (state)=>state.document);
|
3399
3680
|
const title = React.useMemo(()=>{
|
3400
3681
|
const { mainField } = components[componentUid]?.settings ?? {
|
3401
3682
|
mainField: 'id'
|
@@ -3627,9 +3908,11 @@ const DynamicComponent = ({ componentUid, disabled, index, name, onRemoveCompone
|
|
3627
3908
|
alignItems: "stretch",
|
3628
3909
|
children: children ? children({
|
3629
3910
|
...fieldWithTranslatedLabel,
|
3911
|
+
document,
|
3630
3912
|
name: fieldName
|
3631
3913
|
}) : /*#__PURE__*/ jsx(MemoizedInputRenderer, {
|
3632
3914
|
...fieldWithTranslatedLabel,
|
3915
|
+
document: document,
|
3633
3916
|
name: fieldName
|
3634
3917
|
})
|
3635
3918
|
}, fieldName);
|
@@ -3747,7 +4030,8 @@ const DynamicZone = ({ attribute, disabled: disabledProp, hint, label, labelActi
|
|
3747
4030
|
const { max = Infinity, min = -Infinity } = attribute ?? {};
|
3748
4031
|
const [addComponentIsOpen, setAddComponentIsOpen] = React.useState(false);
|
3749
4032
|
const [liveText, setLiveText] = React.useState('');
|
3750
|
-
const
|
4033
|
+
const document = useDocumentContext('DynamicZone', (state)=>state.document);
|
4034
|
+
const { components, isLoading } = document;
|
3751
4035
|
const disabled = disabledProp || isLoading;
|
3752
4036
|
const { addFieldRow, removeFieldRow, moveFieldRow } = useForm('DynamicZone', ({ addFieldRow, removeFieldRow, moveFieldRow })=>({
|
3753
4037
|
addFieldRow,
|
@@ -3980,153 +4264,1386 @@ const NotAllowedInput = ({ hint, label, required, name })=>{
|
|
3980
4264
|
});
|
3981
4265
|
};
|
3982
4266
|
|
3983
|
-
|
3984
|
-
|
3985
|
-
|
3986
|
-
|
3987
|
-
|
3988
|
-
|
3989
|
-
|
3990
|
-
|
3991
|
-
|
3992
|
-
|
3993
|
-
|
3994
|
-
|
3995
|
-
|
3996
|
-
|
3997
|
-
}),
|
3998
|
-
generateUID: builder.mutation({
|
3999
|
-
query: ({ params, ...data })=>({
|
4000
|
-
url: '/content-manager/uid/generate',
|
4001
|
-
method: 'POST',
|
4002
|
-
data,
|
4003
|
-
config: {
|
4004
|
-
params
|
4005
|
-
}
|
4006
|
-
}),
|
4007
|
-
transformResponse: (response)=>response.data
|
4008
|
-
}),
|
4009
|
-
getAvailability: builder.query({
|
4010
|
-
query: ({ params, ...data })=>({
|
4011
|
-
url: '/content-manager/uid/check-availability',
|
4012
|
-
method: 'POST',
|
4013
|
-
data,
|
4014
|
-
config: {
|
4015
|
-
params
|
4016
|
-
}
|
4017
|
-
}),
|
4018
|
-
providesTags: (_res, _error, params)=>[
|
4019
|
-
{
|
4020
|
-
type: 'UidAvailability',
|
4021
|
-
id: params.contentTypeUID
|
4022
|
-
}
|
4023
|
-
]
|
4024
|
-
})
|
4025
|
-
})
|
4267
|
+
function getCollectionType(url) {
|
4268
|
+
const regex = new RegExp(`(${COLLECTION_TYPES}|${SINGLE_TYPES})`);
|
4269
|
+
const match = url.match(regex);
|
4270
|
+
return match ? match[1] : undefined;
|
4271
|
+
}
|
4272
|
+
const CustomModalContent = styled(Modal.Content)`
|
4273
|
+
width: 90%;
|
4274
|
+
max-width: 100%;
|
4275
|
+
height: 90%;
|
4276
|
+
max-height: 100%;
|
4277
|
+
`;
|
4278
|
+
const [RelationModalProvider, useRelationModal] = createContext('RelationModal', {
|
4279
|
+
parentModified: false,
|
4280
|
+
depth: 0
|
4026
4281
|
});
|
4027
|
-
const {
|
4028
|
-
|
4029
|
-
|
4030
|
-
* InputUID
|
4031
|
-
* -----------------------------------------------------------------------------------------------*/ const UID_REGEX = /^[A-Za-z0-9-_.~]*$/;
|
4032
|
-
const UIDInput = /*#__PURE__*/ React.forwardRef(({ hint, label, labelAction, name, required, ...props }, ref)=>{
|
4033
|
-
const { model, id } = useDoc();
|
4034
|
-
const allFormValues = useForm('InputUID', (form)=>form.values);
|
4035
|
-
const [availability, setAvailability] = React.useState();
|
4036
|
-
const [showRegenerate, setShowRegenerate] = React.useState(false);
|
4037
|
-
const isCloning = useMatch(CLONE_PATH) !== null;
|
4038
|
-
const field = useField(name);
|
4039
|
-
const debouncedValue = useDebounce(field.value, 300);
|
4040
|
-
const hasChanged = debouncedValue !== field.initialValue;
|
4041
|
-
const { toggleNotification } = useNotification();
|
4042
|
-
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
4282
|
+
const RelationModalForm = ({ relation, triggerButtonLabel })=>{
|
4283
|
+
const navigate = useNavigate();
|
4284
|
+
const { pathname, search } = useLocation();
|
4043
4285
|
const { formatMessage } = useIntl();
|
4044
|
-
const [
|
4045
|
-
const
|
4046
|
-
|
4047
|
-
|
4048
|
-
const
|
4049
|
-
|
4050
|
-
|
4051
|
-
|
4052
|
-
|
4053
|
-
|
4054
|
-
|
4055
|
-
|
4056
|
-
|
4057
|
-
|
4058
|
-
|
4059
|
-
|
4060
|
-
|
4061
|
-
|
4062
|
-
|
4063
|
-
|
4064
|
-
|
4286
|
+
const [triggerRefetchDocument] = useLazyGetDocumentQuery();
|
4287
|
+
const currentDocument = useDocumentContext('RelationModalForm', (state)=>state.document);
|
4288
|
+
const rootDocumentMeta = useDocumentContext('RelationModalForm', (state)=>state.rootDocumentMeta);
|
4289
|
+
const currentDocumentMeta = useDocumentContext('RelationModalForm', (state)=>state.meta);
|
4290
|
+
const changeDocument = useDocumentContext('RelationModalForm', (state)=>state.changeDocument);
|
4291
|
+
const documentHistory = useDocumentContext('RelationModalForm', (state)=>state.documentHistory);
|
4292
|
+
const setDocumentHistory = useDocumentContext('RelationModalForm', (state)=>state.setDocumentHistory);
|
4293
|
+
const [isConfirmationOpen, setIsConfirmationOpen] = React.useState(false);
|
4294
|
+
const [actionPosition, setActionPosition] = React.useState('cancel');
|
4295
|
+
const [isModalOpen, setIsModalOpen] = React.useState(false);
|
4296
|
+
// NOTE: Not sure about this relation modal context, maybe we should move this to DocumentContext?
|
4297
|
+
// Get parent modal context if it exists
|
4298
|
+
const parentContext = useRelationModal('RelationModalForm', (state)=>state);
|
4299
|
+
// Get depth of nested modals
|
4300
|
+
const depth = parentContext ? parentContext.depth + 1 : 0;
|
4301
|
+
// Check if this is a nested modal
|
4302
|
+
const isNested = depth > 0;
|
4303
|
+
const addDocumentToHistory = (document)=>setDocumentHistory((prev)=>[
|
4304
|
+
...prev,
|
4305
|
+
document
|
4306
|
+
]);
|
4307
|
+
const getPreviousDocument = ()=>{
|
4308
|
+
if (documentHistory.length === 0) return undefined;
|
4309
|
+
const lastDocument = documentHistory[documentHistory.length - 1];
|
4310
|
+
return lastDocument;
|
4311
|
+
};
|
4312
|
+
const removeLastDocumentFromHistory = ()=>{
|
4313
|
+
setDocumentHistory((prev)=>[
|
4314
|
+
...prev
|
4315
|
+
].slice(0, prev.length - 1));
|
4316
|
+
};
|
4317
|
+
const handleToggleModal = ()=>{
|
4318
|
+
if (isModalOpen) {
|
4319
|
+
setIsModalOpen(false);
|
4320
|
+
const document = {
|
4321
|
+
collectionType: rootDocumentMeta.collectionType,
|
4322
|
+
model: rootDocumentMeta.model,
|
4323
|
+
documentId: rootDocumentMeta.documentId
|
4324
|
+
};
|
4325
|
+
// Change back to the root document
|
4326
|
+
changeDocument(document);
|
4327
|
+
// Reset the document history
|
4328
|
+
setDocumentHistory([]);
|
4329
|
+
// Reset action position
|
4330
|
+
setActionPosition('cancel');
|
4331
|
+
// Read from cache or refetch root document
|
4332
|
+
triggerRefetchDocument(document, // Favor the cache
|
4333
|
+
true);
|
4334
|
+
} else {
|
4335
|
+
changeDocument(relation);
|
4336
|
+
setIsModalOpen(true);
|
4065
4337
|
}
|
4066
|
-
}
|
4067
|
-
|
4068
|
-
|
4069
|
-
|
4070
|
-
|
4071
|
-
|
4072
|
-
|
4073
|
-
|
4074
|
-
|
4075
|
-
if (
|
4076
|
-
|
4338
|
+
};
|
4339
|
+
const getFullPageLink = ()=>{
|
4340
|
+
const isSingleType = currentDocumentMeta.collectionType === SINGLE_TYPES;
|
4341
|
+
const queryParams = currentDocumentMeta.params?.locale ? `?plugins[i18n][locale]=${currentDocumentMeta.params.locale}` : '';
|
4342
|
+
return `/content-manager/${currentDocumentMeta.collectionType}/${currentDocumentMeta.model}${isSingleType ? '' : '/' + currentDocumentMeta.documentId}${queryParams}`;
|
4343
|
+
};
|
4344
|
+
const handleRedirection = ()=>{
|
4345
|
+
const editViewUrl = `${pathname}${search}`;
|
4346
|
+
const isRootDocumentUrl = editViewUrl.includes(getFullPageLink());
|
4347
|
+
if (isRootDocumentUrl) {
|
4348
|
+
handleToggleModal();
|
4349
|
+
} else {
|
4350
|
+
navigate(getFullPageLink());
|
4077
4351
|
}
|
4078
|
-
}
|
4079
|
-
|
4080
|
-
|
4081
|
-
|
4082
|
-
|
4083
|
-
|
4084
|
-
|
4085
|
-
|
4086
|
-
|
4087
|
-
contentTypeUID: model,
|
4088
|
-
field: name,
|
4089
|
-
data: {
|
4090
|
-
id: id ?? '',
|
4091
|
-
...allFormValues
|
4092
|
-
},
|
4093
|
-
params
|
4094
|
-
});
|
4095
|
-
if ('data' in res) {
|
4096
|
-
field.onChange(name, res.data);
|
4097
|
-
} else {
|
4098
|
-
toggleNotification({
|
4099
|
-
type: 'danger',
|
4100
|
-
message: formatAPIError(res.error)
|
4101
|
-
});
|
4352
|
+
};
|
4353
|
+
const handleConfirm = ()=>{
|
4354
|
+
if (actionPosition === 'navigate') {
|
4355
|
+
handleRedirection();
|
4356
|
+
} else if (actionPosition === 'back') {
|
4357
|
+
const previousRelation = getPreviousDocument();
|
4358
|
+
if (previousRelation) {
|
4359
|
+
removeLastDocumentFromHistory();
|
4360
|
+
changeDocument(previousRelation);
|
4102
4361
|
}
|
4103
|
-
}
|
4104
|
-
|
4105
|
-
|
4106
|
-
|
4107
|
-
|
4108
|
-
|
4109
|
-
})
|
4110
|
-
});
|
4362
|
+
} else {
|
4363
|
+
// Add current relation to history before opening a new one in case we are opening a new one
|
4364
|
+
if (currentDocumentMeta && Object.keys(currentDocumentMeta).length > 0) {
|
4365
|
+
addDocumentToHistory(currentDocumentMeta);
|
4366
|
+
}
|
4367
|
+
handleToggleModal();
|
4111
4368
|
}
|
4112
4369
|
};
|
4113
|
-
|
4114
|
-
|
4115
|
-
|
4116
|
-
|
4117
|
-
|
4118
|
-
|
4119
|
-
|
4120
|
-
skip: !Boolean((hasChanged || isCloning) && debouncedValue && UID_REGEX.test(debouncedValue.trim()))
|
4121
|
-
});
|
4122
|
-
React.useEffect(()=>{
|
4123
|
-
if (availabilityError) {
|
4124
|
-
toggleNotification({
|
4125
|
-
type: 'warning',
|
4126
|
-
message: formatAPIError(availabilityError)
|
4370
|
+
return /*#__PURE__*/ jsx(Form, {
|
4371
|
+
method: "PUT",
|
4372
|
+
initialValues: currentDocument.getInitialFormValues(),
|
4373
|
+
validate: (values, options)=>{
|
4374
|
+
const yupSchema = createYupSchema(currentDocument.schema?.attributes, currentDocument.components, {
|
4375
|
+
status: currentDocument.document?.status,
|
4376
|
+
...options
|
4127
4377
|
});
|
4128
|
-
|
4129
|
-
|
4378
|
+
return yupSchema.validate(values, {
|
4379
|
+
abortEarly: false
|
4380
|
+
});
|
4381
|
+
},
|
4382
|
+
children: ({ modified, isSubmitting, resetForm })=>{
|
4383
|
+
// We don't count the root document, so history starts after 1
|
4384
|
+
const hasHistory = documentHistory.length > 1;
|
4385
|
+
return /*#__PURE__*/ jsxs(RelationModalProvider, {
|
4386
|
+
parentModified: modified,
|
4387
|
+
depth: depth,
|
4388
|
+
children: [
|
4389
|
+
/*#__PURE__*/ jsxs(Modal.Root, {
|
4390
|
+
open: isModalOpen,
|
4391
|
+
onOpenChange: ()=>{
|
4392
|
+
if (isModalOpen) {
|
4393
|
+
if (modified && !isSubmitting) {
|
4394
|
+
setIsConfirmationOpen(true);
|
4395
|
+
} else {
|
4396
|
+
handleToggleModal();
|
4397
|
+
}
|
4398
|
+
}
|
4399
|
+
},
|
4400
|
+
children: [
|
4401
|
+
/*#__PURE__*/ jsx(Modal.Trigger, {
|
4402
|
+
children: /*#__PURE__*/ jsx(Tooltip, {
|
4403
|
+
description: triggerButtonLabel,
|
4404
|
+
children: /*#__PURE__*/ jsx(CustomTextButton, {
|
4405
|
+
onClick: ()=>{
|
4406
|
+
// Check if parent modal has unsaved changes
|
4407
|
+
if (isNested && parentContext.parentModified) {
|
4408
|
+
setIsConfirmationOpen(true);
|
4409
|
+
// Return early to avoid opening the modal
|
4410
|
+
return;
|
4411
|
+
} else {
|
4412
|
+
if (modified && !isSubmitting) {
|
4413
|
+
setIsConfirmationOpen(true);
|
4414
|
+
} else {
|
4415
|
+
// Add current relation to history before opening a new one
|
4416
|
+
if (currentDocumentMeta && Object.keys(currentDocumentMeta).length > 0) {
|
4417
|
+
addDocumentToHistory(currentDocumentMeta);
|
4418
|
+
}
|
4419
|
+
handleToggleModal();
|
4420
|
+
}
|
4421
|
+
if (!isModalOpen) {
|
4422
|
+
setIsModalOpen(true);
|
4423
|
+
}
|
4424
|
+
}
|
4425
|
+
},
|
4426
|
+
width: "100%",
|
4427
|
+
children: triggerButtonLabel
|
4428
|
+
})
|
4429
|
+
})
|
4430
|
+
}),
|
4431
|
+
/*#__PURE__*/ jsxs(CustomModalContent, {
|
4432
|
+
children: [
|
4433
|
+
/*#__PURE__*/ jsx(Modal.Header, {
|
4434
|
+
gap: 2,
|
4435
|
+
children: /*#__PURE__*/ jsx(Flex, {
|
4436
|
+
justifyContent: "space-between",
|
4437
|
+
alignItems: "center",
|
4438
|
+
width: "100%",
|
4439
|
+
children: /*#__PURE__*/ jsxs(Flex, {
|
4440
|
+
gap: 2,
|
4441
|
+
children: [
|
4442
|
+
/*#__PURE__*/ jsx(IconButton, {
|
4443
|
+
withTooltip: false,
|
4444
|
+
label: "Back",
|
4445
|
+
variant: "ghost",
|
4446
|
+
disabled: !hasHistory,
|
4447
|
+
onClick: ()=>{
|
4448
|
+
setActionPosition('back');
|
4449
|
+
if (modified && !isSubmitting) {
|
4450
|
+
setIsConfirmationOpen(true);
|
4451
|
+
} else {
|
4452
|
+
const previousRelation = getPreviousDocument();
|
4453
|
+
if (previousRelation) {
|
4454
|
+
removeLastDocumentFromHistory();
|
4455
|
+
changeDocument(previousRelation);
|
4456
|
+
}
|
4457
|
+
}
|
4458
|
+
},
|
4459
|
+
marginRight: 1,
|
4460
|
+
children: /*#__PURE__*/ jsx(ArrowLeft, {})
|
4461
|
+
}),
|
4462
|
+
/*#__PURE__*/ jsx(Typography, {
|
4463
|
+
tag: "span",
|
4464
|
+
fontWeight: 600,
|
4465
|
+
children: formatMessage({
|
4466
|
+
id: 'content-manager.components.RelationInputModal.modal-title',
|
4467
|
+
defaultMessage: 'Edit a relation'
|
4468
|
+
})
|
4469
|
+
})
|
4470
|
+
]
|
4471
|
+
})
|
4472
|
+
})
|
4473
|
+
}),
|
4474
|
+
/*#__PURE__*/ jsx(RelationModalBody, {
|
4475
|
+
children: /*#__PURE__*/ jsx(IconButton, {
|
4476
|
+
onClick: ()=>{
|
4477
|
+
setActionPosition('navigate');
|
4478
|
+
if (modified && !isSubmitting) {
|
4479
|
+
setIsConfirmationOpen(true);
|
4480
|
+
} else {
|
4481
|
+
navigate(getFullPageLink());
|
4482
|
+
}
|
4483
|
+
},
|
4484
|
+
variant: "tertiary",
|
4485
|
+
label: formatMessage({
|
4486
|
+
id: 'content-manager.components.RelationInputModal.button-fullpage',
|
4487
|
+
defaultMessage: 'Go to entry'
|
4488
|
+
}),
|
4489
|
+
children: /*#__PURE__*/ jsx(ArrowsOut, {})
|
4490
|
+
})
|
4491
|
+
}),
|
4492
|
+
/*#__PURE__*/ jsx(Modal.Footer, {
|
4493
|
+
children: /*#__PURE__*/ jsx(Button, {
|
4494
|
+
onClick: ()=>{
|
4495
|
+
if (modified && !isSubmitting) {
|
4496
|
+
setIsConfirmationOpen(true);
|
4497
|
+
} else {
|
4498
|
+
handleToggleModal();
|
4499
|
+
}
|
4500
|
+
},
|
4501
|
+
variant: "tertiary",
|
4502
|
+
children: formatMessage({
|
4503
|
+
id: 'app.components.Button.cancel',
|
4504
|
+
defaultMessage: 'Cancel'
|
4505
|
+
})
|
4506
|
+
})
|
4507
|
+
})
|
4508
|
+
]
|
4509
|
+
})
|
4510
|
+
]
|
4511
|
+
}),
|
4512
|
+
/*#__PURE__*/ jsx(Dialog.Root, {
|
4513
|
+
open: isConfirmationOpen,
|
4514
|
+
onOpenChange: setIsConfirmationOpen,
|
4515
|
+
children: /*#__PURE__*/ jsx(ConfirmDialog, {
|
4516
|
+
onConfirm: ()=>{
|
4517
|
+
handleConfirm();
|
4518
|
+
setIsConfirmationOpen(false);
|
4519
|
+
resetForm();
|
4520
|
+
},
|
4521
|
+
onCancel: ()=>{
|
4522
|
+
setIsConfirmationOpen(false);
|
4523
|
+
},
|
4524
|
+
variant: "danger",
|
4525
|
+
children: formatMessage({
|
4526
|
+
id: 'content-manager.components.RelationInputModal.confirmation-message',
|
4527
|
+
defaultMessage: 'Some changes were not saved. Are you sure you want to close this relation? All changes that were not saved will be lost.'
|
4528
|
+
})
|
4529
|
+
})
|
4530
|
+
})
|
4531
|
+
]
|
4532
|
+
});
|
4533
|
+
}
|
4534
|
+
});
|
4535
|
+
};
|
4536
|
+
const CustomTextButton = styled(TextButton)`
|
4537
|
+
& > span {
|
4538
|
+
font-size: ${({ theme })=>theme.fontSizes[2]};
|
4539
|
+
width: inherit;
|
4540
|
+
overflow: hidden;
|
4541
|
+
white-space: nowrap;
|
4542
|
+
text-overflow: ellipsis;
|
4543
|
+
}
|
4544
|
+
`;
|
4545
|
+
const RelationModalBody = ({ children })=>{
|
4546
|
+
const { formatMessage } = useIntl();
|
4547
|
+
const documentMeta = useDocumentContext('RelationModalBody', (state)=>state.meta);
|
4548
|
+
const documentResponse = useDocumentContext('RelationModalBody', (state)=>state.document);
|
4549
|
+
const onPreview = useDocumentContext('RelationModalBody', (state)=>state.onPreview);
|
4550
|
+
const documentLayoutResponse = useDocumentLayout(documentMeta.model);
|
4551
|
+
const plugins = useStrapiApp('RelationModalBody', (state)=>state.plugins);
|
4552
|
+
const initialValues = documentResponse.getInitialFormValues();
|
4553
|
+
const { permissions = [], isLoading: isLoadingPermissions, error } = useRBAC(PERMISSIONS.map((action)=>({
|
4554
|
+
action,
|
4555
|
+
subject: documentMeta.model
|
4556
|
+
})));
|
4557
|
+
const isLoading = isLoadingPermissions || documentLayoutResponse.isLoading || documentResponse.isLoading;
|
4558
|
+
if (isLoading && !documentResponse.document?.documentId) {
|
4559
|
+
return /*#__PURE__*/ jsx(Loader, {
|
4560
|
+
small: true,
|
4561
|
+
children: formatMessage({
|
4562
|
+
id: 'content-manager.ListViewTable.relation-loading',
|
4563
|
+
defaultMessage: 'Relations are loading'
|
4564
|
+
})
|
4565
|
+
});
|
4566
|
+
}
|
4567
|
+
if (error || !documentMeta.model || documentLayoutResponse.error || !documentResponse.document || !documentResponse.meta || !documentResponse.schema || !initialValues) {
|
4568
|
+
return /*#__PURE__*/ jsx(Flex, {
|
4569
|
+
alignItems: "center",
|
4570
|
+
height: "100%",
|
4571
|
+
justifyContent: "center",
|
4572
|
+
children: /*#__PURE__*/ jsx(EmptyStateLayout, {
|
4573
|
+
icon: /*#__PURE__*/ jsx(WarningCircle, {
|
4574
|
+
width: "16rem"
|
4575
|
+
}),
|
4576
|
+
content: formatMessage({
|
4577
|
+
id: 'anErrorOccurred',
|
4578
|
+
defaultMessage: 'Whoops! Something went wrong. Please, try again.'
|
4579
|
+
})
|
4580
|
+
})
|
4581
|
+
});
|
4582
|
+
}
|
4583
|
+
const documentTitle = documentResponse.getTitle(documentLayoutResponse.edit.settings.mainField);
|
4584
|
+
const hasDraftAndPublished = documentResponse.schema?.options?.draftAndPublish ?? false;
|
4585
|
+
const props = {
|
4586
|
+
activeTab: 'draft',
|
4587
|
+
collectionType: documentMeta.collectionType,
|
4588
|
+
model: documentMeta.model,
|
4589
|
+
documentId: documentMeta.documentId,
|
4590
|
+
document: documentResponse.document,
|
4591
|
+
meta: documentResponse.meta,
|
4592
|
+
onPreview
|
4593
|
+
};
|
4594
|
+
return /*#__PURE__*/ jsx(Modal.Body, {
|
4595
|
+
children: /*#__PURE__*/ jsxs(DocumentRBAC, {
|
4596
|
+
permissions: permissions,
|
4597
|
+
model: documentMeta.model,
|
4598
|
+
children: [
|
4599
|
+
/*#__PURE__*/ jsxs(Flex, {
|
4600
|
+
alignItems: "flex-start",
|
4601
|
+
direction: "column",
|
4602
|
+
gap: 2,
|
4603
|
+
children: [
|
4604
|
+
/*#__PURE__*/ jsxs(Flex, {
|
4605
|
+
width: "100%",
|
4606
|
+
justifyContent: "space-between",
|
4607
|
+
gap: 2,
|
4608
|
+
children: [
|
4609
|
+
/*#__PURE__*/ jsx(Typography, {
|
4610
|
+
tag: "h2",
|
4611
|
+
variant: "alpha",
|
4612
|
+
children: documentTitle
|
4613
|
+
}),
|
4614
|
+
/*#__PURE__*/ jsxs(Flex, {
|
4615
|
+
gap: 2,
|
4616
|
+
children: [
|
4617
|
+
children,
|
4618
|
+
/*#__PURE__*/ jsx(DescriptionComponentRenderer, {
|
4619
|
+
props: props,
|
4620
|
+
descriptions: plugins['content-manager'].apis.getDocumentActions('relation-modal'),
|
4621
|
+
children: (actions)=>{
|
4622
|
+
const filteredActions = actions.filter((action)=>{
|
4623
|
+
return [
|
4624
|
+
action.position
|
4625
|
+
].flat().includes('relation-modal');
|
4626
|
+
});
|
4627
|
+
const [primaryAction, secondaryAction] = filteredActions;
|
4628
|
+
if (!primaryAction && !secondaryAction) return null;
|
4629
|
+
// Both actions are available when draft and publish enabled
|
4630
|
+
if (primaryAction && secondaryAction) {
|
4631
|
+
return /*#__PURE__*/ jsxs(Fragment, {
|
4632
|
+
children: [
|
4633
|
+
/*#__PURE__*/ jsx(DocumentActionButton, {
|
4634
|
+
...secondaryAction,
|
4635
|
+
variant: secondaryAction.variant || 'secondary'
|
4636
|
+
}),
|
4637
|
+
/*#__PURE__*/ jsx(DocumentActionButton, {
|
4638
|
+
...primaryAction,
|
4639
|
+
variant: primaryAction.variant || 'default'
|
4640
|
+
})
|
4641
|
+
]
|
4642
|
+
});
|
4643
|
+
}
|
4644
|
+
// Otherwise we just have the save action
|
4645
|
+
return /*#__PURE__*/ jsx(DocumentActionButton, {
|
4646
|
+
...primaryAction,
|
4647
|
+
variant: primaryAction.variant || 'secondary'
|
4648
|
+
});
|
4649
|
+
}
|
4650
|
+
})
|
4651
|
+
]
|
4652
|
+
})
|
4653
|
+
]
|
4654
|
+
}),
|
4655
|
+
hasDraftAndPublished ? /*#__PURE__*/ jsx(Box, {
|
4656
|
+
children: /*#__PURE__*/ jsx(DocumentStatus, {
|
4657
|
+
status: documentResponse.document?.status
|
4658
|
+
})
|
4659
|
+
}) : null
|
4660
|
+
]
|
4661
|
+
}),
|
4662
|
+
/*#__PURE__*/ jsx(Flex, {
|
4663
|
+
flex: 1,
|
4664
|
+
overflow: "auto",
|
4665
|
+
alignItems: "stretch",
|
4666
|
+
paddingTop: 7,
|
4667
|
+
children: /*#__PURE__*/ jsx(Box, {
|
4668
|
+
overflow: "auto",
|
4669
|
+
flex: 1,
|
4670
|
+
children: /*#__PURE__*/ jsx(FormLayout, {
|
4671
|
+
layout: documentLayoutResponse.edit.layout,
|
4672
|
+
document: documentResponse,
|
4673
|
+
hasBackground: false
|
4674
|
+
})
|
4675
|
+
})
|
4676
|
+
})
|
4677
|
+
]
|
4678
|
+
})
|
4679
|
+
});
|
4680
|
+
};
|
4681
|
+
|
4682
|
+
/**
|
4683
|
+
* Remove a relation, whether it's been already saved or not.
|
4684
|
+
* It's used both in RelationsList, where the "remove relation" button is, and in the input,
|
4685
|
+
* because we sometimes need to remove a previous relation when selecting a new one.
|
4686
|
+
*/ function useHandleDisconnect(fieldName, consumerName) {
|
4687
|
+
const field = useField(fieldName);
|
4688
|
+
const removeFieldRow = useForm(consumerName, (state)=>state.removeFieldRow);
|
4689
|
+
const addFieldRow = useForm(consumerName, (state)=>state.addFieldRow);
|
4690
|
+
const handleDisconnect = (relation)=>{
|
4691
|
+
if (field.value && field.value.connect) {
|
4692
|
+
/**
|
4693
|
+
* A relation will exist in the `connect` array _if_ it has
|
4694
|
+
* been added without saving. In this case, we just remove it
|
4695
|
+
* from the connect array
|
4696
|
+
*/ const indexOfRelationInConnectArray = field.value.connect.findIndex((rel)=>rel.id === relation.id);
|
4697
|
+
if (indexOfRelationInConnectArray >= 0) {
|
4698
|
+
removeFieldRow(`${fieldName}.connect`, indexOfRelationInConnectArray);
|
4699
|
+
return;
|
4700
|
+
}
|
4701
|
+
}
|
4702
|
+
addFieldRow(`${fieldName}.disconnect`, {
|
4703
|
+
id: relation.id,
|
4704
|
+
apiData: {
|
4705
|
+
id: relation.id,
|
4706
|
+
documentId: relation.documentId,
|
4707
|
+
locale: relation.locale
|
4708
|
+
}
|
4709
|
+
});
|
4710
|
+
};
|
4711
|
+
return handleDisconnect;
|
4712
|
+
}
|
4713
|
+
/* -------------------------------------------------------------------------------------------------
|
4714
|
+
* RelationsField
|
4715
|
+
* -----------------------------------------------------------------------------------------------*/ const RELATIONS_TO_DISPLAY = 5;
|
4716
|
+
const ONE_WAY_RELATIONS = [
|
4717
|
+
'oneWay',
|
4718
|
+
'oneToOne',
|
4719
|
+
'manyToOne',
|
4720
|
+
'oneToManyMorph',
|
4721
|
+
'oneToOneMorph'
|
4722
|
+
];
|
4723
|
+
/**
|
4724
|
+
* TODO: we get a rather ugly flash when we remove a single relation from the list leaving
|
4725
|
+
* no other relations when we press save. The initial relation re-renders, probably because
|
4726
|
+
* of the lag in the Form cleaning it's "disconnect" array, whilst our data has not been invalidated.
|
4727
|
+
*
|
4728
|
+
* Could we invalidate relation data on the document actions? Should we?
|
4729
|
+
*/ /**
|
4730
|
+
* @internal
|
4731
|
+
* @description The relations field holds a lot of domain logic for handling relations which is rather complicated
|
4732
|
+
* At present we do not expose this to plugin developers, however, they are able to overwrite it themselves should
|
4733
|
+
* they wish to do so.
|
4734
|
+
*/ const RelationsField = /*#__PURE__*/ React.forwardRef(({ disabled, label, ...props }, ref)=>{
|
4735
|
+
const currentDocumentMeta = useDocumentContext('RelationsField', (state)=>state.meta);
|
4736
|
+
const currentDocument = useDocumentContext('RelationsField', (state)=>state.document);
|
4737
|
+
const rootDocumentMeta = useDocumentContext('RelationsField', (state)=>state.rootDocumentMeta);
|
4738
|
+
const [currentPage, setCurrentPage] = React.useState(1);
|
4739
|
+
const isRootDocument = rootDocumentMeta.documentId === currentDocumentMeta.documentId;
|
4740
|
+
const documentMeta = isRootDocument ? rootDocumentMeta : currentDocumentMeta;
|
4741
|
+
// Use the documentId from the actual document, not the params (meta)
|
4742
|
+
const documentId = currentDocument.document?.documentId;
|
4743
|
+
const { formatMessage } = useIntl();
|
4744
|
+
const [{ query }] = useQueryParams();
|
4745
|
+
const params = documentMeta.params ?? buildValidParams(query);
|
4746
|
+
const isMorph = props.attribute.relation.toLowerCase().includes('morph');
|
4747
|
+
const isDisabled = isMorph || disabled;
|
4748
|
+
const { componentId, componentUID } = useComponent('RelationsField', ({ uid, id })=>({
|
4749
|
+
componentId: id,
|
4750
|
+
componentUID: uid
|
4751
|
+
}));
|
4752
|
+
const isSubmitting = useForm('RelationsList', (state)=>state.isSubmitting);
|
4753
|
+
React.useEffect(()=>{
|
4754
|
+
setCurrentPage(1);
|
4755
|
+
}, [
|
4756
|
+
isSubmitting
|
4757
|
+
]);
|
4758
|
+
const component = componentUID && currentDocument.components[componentUID];
|
4759
|
+
/**
|
4760
|
+
* We'll always have a documentId in a created entry, so we look for a componentId first.
|
4761
|
+
* Same with `uid` and `documentModel`.
|
4762
|
+
*/ const model = component ? component.uid : documentMeta.model;
|
4763
|
+
const id = component && componentId ? componentId.toString() : documentId;
|
4764
|
+
/**
|
4765
|
+
* The `name` prop is a complete path to the field, e.g. `field1.field2.field3`.
|
4766
|
+
* Where the above example would a nested field within two components, however
|
4767
|
+
* we only require the field on the component not the complete path since we query
|
4768
|
+
* individual components. Therefore we split the string and take the last item.
|
4769
|
+
*/ const [targetField] = props.name.split('.').slice(-1);
|
4770
|
+
const schemaAttributes = component ? component.attributes ?? {} : currentDocument.schema?.attributes ?? {};
|
4771
|
+
/**
|
4772
|
+
* Confirm the target field is related to the current document.
|
4773
|
+
* Since relations can exist in a modal on top of the root document,
|
4774
|
+
* we need to ensure we are fetching relations for the correct document (root document vs related document),
|
4775
|
+
*/ const isRelatedToCurrentDocument = Object.values(schemaAttributes).filter((attribute)=>attribute.type === 'relation' && 'target' in attribute && 'target' in props.attribute && attribute.target === props.attribute.target).length > 0;
|
4776
|
+
const { data, isLoading, isFetching } = useGetRelationsQuery({
|
4777
|
+
model,
|
4778
|
+
targetField,
|
4779
|
+
// below we don't run the query if there is no id.
|
4780
|
+
id,
|
4781
|
+
params: {
|
4782
|
+
...params,
|
4783
|
+
pageSize: RELATIONS_TO_DISPLAY,
|
4784
|
+
page: currentPage
|
4785
|
+
}
|
4786
|
+
}, {
|
4787
|
+
refetchOnMountOrArgChange: true,
|
4788
|
+
skip: !id || !isRelatedToCurrentDocument,
|
4789
|
+
selectFromResult: (result)=>{
|
4790
|
+
return {
|
4791
|
+
...result,
|
4792
|
+
data: {
|
4793
|
+
...result.data,
|
4794
|
+
results: result.data?.results ? result.data.results : []
|
4795
|
+
}
|
4796
|
+
};
|
4797
|
+
}
|
4798
|
+
});
|
4799
|
+
const handleLoadMore = ()=>{
|
4800
|
+
setCurrentPage((prev)=>prev + 1);
|
4801
|
+
};
|
4802
|
+
const field = useField(props.name);
|
4803
|
+
const isFetchingMoreRelations = isLoading || isFetching;
|
4804
|
+
const realServerRelationsCount = 'pagination' in data && data.pagination ? data.pagination.total : 0;
|
4805
|
+
/**
|
4806
|
+
* Items that are already connected, but reordered would be in
|
4807
|
+
* this list, so to get an accurate figure, we remove them.
|
4808
|
+
*/ const relationsConnected = (field.value?.connect ?? []).filter((rel)=>data.results.findIndex((relation)=>relation.id === rel.id) === -1).length ?? 0;
|
4809
|
+
const relationsDisconnected = field.value?.disconnect?.length ?? 0;
|
4810
|
+
const relationsCount = realServerRelationsCount + relationsConnected - relationsDisconnected;
|
4811
|
+
/**
|
4812
|
+
* This is it, the source of truth for reordering in conjunction with partial loading & updating
|
4813
|
+
* of relations. Relations on load are given __temp_key__ when fetched, because we don't want to
|
4814
|
+
* create brand new keys everytime the data updates, just keep adding them onto the newly loaded ones.
|
4815
|
+
*/ const relations = React.useMemo(()=>{
|
4816
|
+
const ctx = {
|
4817
|
+
field: field.value,
|
4818
|
+
// @ts-expect-error – targetModel does exist on the attribute. But it's not typed.
|
4819
|
+
href: `../${COLLECTION_TYPES}/${props.attribute.targetModel}`,
|
4820
|
+
mainField: props.mainField
|
4821
|
+
};
|
4822
|
+
/**
|
4823
|
+
* Tidy up our data.
|
4824
|
+
*/ const transformations = pipe$1(removeConnected(ctx), removeDisconnected(ctx), addLabelAndHref(ctx));
|
4825
|
+
const transformedRels = transformations([
|
4826
|
+
...data.results
|
4827
|
+
]);
|
4828
|
+
/**
|
4829
|
+
* THIS IS CRUCIAL. If you don't sort by the __temp_key__ which comes from fractional indexing
|
4830
|
+
* then the list will be in the wrong order.
|
4831
|
+
*/ return [
|
4832
|
+
...transformedRels,
|
4833
|
+
...field.value?.connect ?? []
|
4834
|
+
].sort((a, b)=>{
|
4835
|
+
if (a.__temp_key__ < b.__temp_key__) return -1;
|
4836
|
+
if (a.__temp_key__ > b.__temp_key__) return 1;
|
4837
|
+
return 0;
|
4838
|
+
});
|
4839
|
+
}, [
|
4840
|
+
data.results,
|
4841
|
+
field.value,
|
4842
|
+
// @ts-expect-error – targetModel does exist on the attribute. But it's not typed.
|
4843
|
+
props.attribute.targetModel,
|
4844
|
+
props.mainField
|
4845
|
+
]);
|
4846
|
+
const handleDisconnect = useHandleDisconnect(props.name, 'RelationsField');
|
4847
|
+
const handleConnect = (relation)=>{
|
4848
|
+
const [lastItemInList] = relations.slice(-1);
|
4849
|
+
const item = {
|
4850
|
+
id: relation.id,
|
4851
|
+
apiData: {
|
4852
|
+
id: relation.id,
|
4853
|
+
documentId: relation.documentId,
|
4854
|
+
locale: relation.locale
|
4855
|
+
},
|
4856
|
+
status: relation.status,
|
4857
|
+
/**
|
4858
|
+
* If there's a last item, that's the first key we use to generate out next one.
|
4859
|
+
*/ __temp_key__: generateNKeysBetween(lastItemInList?.__temp_key__ ?? null, null, 1)[0],
|
4860
|
+
// Fallback to `id` if there is no `mainField` value, which will overwrite the above `id` property with the exact same data.
|
4861
|
+
[props.mainField?.name ?? 'documentId']: relation[props.mainField?.name ?? 'documentId'],
|
4862
|
+
label: getRelationLabel(relation, props.mainField),
|
4863
|
+
// @ts-expect-error – targetModel does exist on the attribute, but it's not typed.
|
4864
|
+
href: `../${COLLECTION_TYPES}/${props.attribute.targetModel}/${relation.documentId}?${relation.locale ? `plugins[i18n][locale]=${relation.locale}` : ''}`
|
4865
|
+
};
|
4866
|
+
if (ONE_WAY_RELATIONS.includes(props.attribute.relation)) {
|
4867
|
+
// Remove any existing relation so they can be replaced with the new one
|
4868
|
+
field.value?.connect?.forEach(handleDisconnect);
|
4869
|
+
relations.forEach(handleDisconnect);
|
4870
|
+
field.onChange(`${props.name}.connect`, [
|
4871
|
+
item
|
4872
|
+
]);
|
4873
|
+
} else {
|
4874
|
+
field.onChange(`${props.name}.connect`, [
|
4875
|
+
...field.value?.connect ?? [],
|
4876
|
+
item
|
4877
|
+
]);
|
4878
|
+
}
|
4879
|
+
};
|
4880
|
+
return /*#__PURE__*/ jsxs(Flex, {
|
4881
|
+
ref: ref,
|
4882
|
+
direction: "column",
|
4883
|
+
gap: 3,
|
4884
|
+
justifyContent: "space-between",
|
4885
|
+
alignItems: "stretch",
|
4886
|
+
wrap: "wrap",
|
4887
|
+
children: [
|
4888
|
+
/*#__PURE__*/ jsxs(StyledFlex, {
|
4889
|
+
direction: "column",
|
4890
|
+
alignItems: "start",
|
4891
|
+
gap: 2,
|
4892
|
+
width: "100%",
|
4893
|
+
children: [
|
4894
|
+
/*#__PURE__*/ jsx(RelationsInput, {
|
4895
|
+
disabled: isDisabled,
|
4896
|
+
// NOTE: we should not default to using the documentId if the component is being created (componentUID is undefined)
|
4897
|
+
id: componentUID && component ? componentId ? `${componentId}` : '' : documentId,
|
4898
|
+
label: `${label} ${relationsCount > 0 ? `(${relationsCount})` : ''}`,
|
4899
|
+
model: model,
|
4900
|
+
onChange: handleConnect,
|
4901
|
+
isRelatedToCurrentDocument: isRelatedToCurrentDocument,
|
4902
|
+
...props
|
4903
|
+
}),
|
4904
|
+
'pagination' in data && data.pagination && data.pagination.pageCount > data.pagination.page ? /*#__PURE__*/ jsx(TextButton, {
|
4905
|
+
disabled: isFetchingMoreRelations,
|
4906
|
+
onClick: handleLoadMore,
|
4907
|
+
loading: isFetchingMoreRelations,
|
4908
|
+
startIcon: /*#__PURE__*/ jsx(ArrowClockwise, {}),
|
4909
|
+
// prevent the label from line-wrapping
|
4910
|
+
shrink: 0,
|
4911
|
+
children: formatMessage({
|
4912
|
+
id: getTranslation('relation.loadMore'),
|
4913
|
+
defaultMessage: 'Load More'
|
4914
|
+
})
|
4915
|
+
}) : null
|
4916
|
+
]
|
4917
|
+
}),
|
4918
|
+
/*#__PURE__*/ jsx(RelationsList, {
|
4919
|
+
data: relations,
|
4920
|
+
serverData: data.results,
|
4921
|
+
disabled: isDisabled,
|
4922
|
+
name: props.name,
|
4923
|
+
isLoading: isFetchingMoreRelations,
|
4924
|
+
relationType: props.attribute.relation,
|
4925
|
+
// @ts-expect-error – targetModel does exist on the attribute. But it's not typed.
|
4926
|
+
targetModel: props.attribute.targetModel
|
4927
|
+
})
|
4928
|
+
]
|
4929
|
+
});
|
4930
|
+
});
|
4931
|
+
/**
|
4932
|
+
* TODO: this can be removed once we stop shipping Inputs with
|
4933
|
+
* labels wrapped round in DS@2.
|
4934
|
+
*/ const StyledFlex = styled(Flex)`
|
4935
|
+
& > div {
|
4936
|
+
width: 100%;
|
4937
|
+
}
|
4938
|
+
`;
|
4939
|
+
/**
|
4940
|
+
* If it's in the connected array, it can get out of our data array,
|
4941
|
+
* we'll be putting it back in later and sorting it anyway.
|
4942
|
+
*/ const removeConnected = ({ field })=>(relations)=>{
|
4943
|
+
return relations.filter((relation)=>{
|
4944
|
+
const connectedRelations = field?.connect ?? [];
|
4945
|
+
return connectedRelations.findIndex((rel)=>rel.id === relation.id) === -1;
|
4946
|
+
});
|
4947
|
+
};
|
4948
|
+
/**
|
4949
|
+
* @description Removes relations that are in the `disconnect` array of the field
|
4950
|
+
*/ const removeDisconnected = ({ field })=>(relations)=>relations.filter((relation)=>{
|
4951
|
+
const disconnectedRelations = field?.disconnect ?? [];
|
4952
|
+
return disconnectedRelations.findIndex((rel)=>rel.id === relation.id) === -1;
|
4953
|
+
});
|
4954
|
+
/**
|
4955
|
+
* @description Adds a label and href to the relation object we use this to render
|
4956
|
+
* a better UI where we can link to the relation and display a human-readable label.
|
4957
|
+
*/ const addLabelAndHref = ({ mainField, href })=>(relations)=>relations.map((relation)=>{
|
4958
|
+
return {
|
4959
|
+
...relation,
|
4960
|
+
// Fallback to `id` if there is no `mainField` value, which will overwrite the above `documentId` property with the exact same data.
|
4961
|
+
[mainField?.name ?? 'documentId']: relation[mainField?.name ?? 'documentId'],
|
4962
|
+
label: getRelationLabel(relation, mainField),
|
4963
|
+
href: `${href}/${relation.documentId}?${relation.locale ? `plugins[i18n][locale]=${relation.locale}` : ''}`
|
4964
|
+
};
|
4965
|
+
});
|
4966
|
+
/**
|
4967
|
+
* @description Contains all the logic for the combobox that can search
|
4968
|
+
* for relations and then add them to the field's connect array.
|
4969
|
+
*/ const RelationsInput = ({ hint, id, model, label, labelAction, name, mainField, placeholder, required, unique: _unique, 'aria-label': _ariaLabel, onChange, isRelatedToCurrentDocument, ...props })=>{
|
4970
|
+
const [textValue, setTextValue] = React.useState('');
|
4971
|
+
const [searchParams, setSearchParams] = React.useState({
|
4972
|
+
_q: '',
|
4973
|
+
page: 1
|
4974
|
+
});
|
4975
|
+
const { toggleNotification } = useNotification();
|
4976
|
+
const [{ query }] = useQueryParams();
|
4977
|
+
const currentDocumentMeta = useDocumentContext('RelationsInput', (state)=>state.meta);
|
4978
|
+
const rootDocumentMeta = useDocumentContext('RelationsInput', (state)=>state.rootDocumentMeta);
|
4979
|
+
const isRootDocument = rootDocumentMeta.documentId === currentDocumentMeta.documentId;
|
4980
|
+
const documentMeta = isRootDocument ? rootDocumentMeta : currentDocumentMeta;
|
4981
|
+
const { formatMessage } = useIntl();
|
4982
|
+
const fieldRef = useFocusInputField(name);
|
4983
|
+
const field = useField(name);
|
4984
|
+
const searchParamsDebounced = useDebounce(searchParams, 300);
|
4985
|
+
const [searchForTrigger, { data, isLoading }] = useLazySearchRelationsQuery();
|
4986
|
+
/**
|
4987
|
+
* Because we're using a lazy query, we need to trigger the search
|
4988
|
+
* when the component mounts and when the search params change.
|
4989
|
+
* We also need to trigger the search when the field value changes
|
4990
|
+
* so that we can filter out the relations that are already connected.
|
4991
|
+
*/ React.useEffect(()=>{
|
4992
|
+
/**
|
4993
|
+
* The `name` prop is a complete path to the field, e.g. `field1.field2.field3`.
|
4994
|
+
* Where the above example would a nested field within two components, however
|
4995
|
+
* we only require the field on the component not the complete path since we query
|
4996
|
+
* individual components. Therefore we split the string and take the last item.
|
4997
|
+
*/ const [targetField] = name.split('.').slice(-1);
|
4998
|
+
// Return early if there is no relation to the document
|
4999
|
+
if (!isRelatedToCurrentDocument) return;
|
5000
|
+
const params = documentMeta.params ?? buildValidParams(query);
|
5001
|
+
searchForTrigger({
|
5002
|
+
model,
|
5003
|
+
targetField,
|
5004
|
+
params: {
|
5005
|
+
...params,
|
5006
|
+
id: id ?? '',
|
5007
|
+
pageSize: 10,
|
5008
|
+
idsToInclude: field.value?.disconnect?.map((rel)=>rel.id.toString()) ?? [],
|
5009
|
+
idsToOmit: field.value?.connect?.map((rel)=>rel.id.toString()) ?? [],
|
5010
|
+
...searchParamsDebounced
|
5011
|
+
}
|
5012
|
+
});
|
5013
|
+
}, [
|
5014
|
+
field.value?.connect,
|
5015
|
+
field.value?.disconnect,
|
5016
|
+
id,
|
5017
|
+
model,
|
5018
|
+
name,
|
5019
|
+
query,
|
5020
|
+
searchForTrigger,
|
5021
|
+
searchParamsDebounced,
|
5022
|
+
isRelatedToCurrentDocument,
|
5023
|
+
documentMeta
|
5024
|
+
]);
|
5025
|
+
const handleSearch = async (search)=>{
|
5026
|
+
setSearchParams((s)=>({
|
5027
|
+
...s,
|
5028
|
+
_q: search,
|
5029
|
+
page: 1
|
5030
|
+
}));
|
5031
|
+
};
|
5032
|
+
const hasNextPage = data?.pagination ? data.pagination.page < data.pagination.pageCount : false;
|
5033
|
+
const options = data?.results ?? [];
|
5034
|
+
const handleChange = (relationId)=>{
|
5035
|
+
if (!relationId) {
|
5036
|
+
return;
|
5037
|
+
}
|
5038
|
+
const relation = options.find((opt)=>opt.id.toString() === relationId);
|
5039
|
+
if (!relation) {
|
5040
|
+
// This is very unlikely to happen, but it ensures we don't have any data for.
|
5041
|
+
console.error("You've tried to add a relation with an id that does not exist in the options you can see, this is likely a bug with Strapi. Please open an issue.");
|
5042
|
+
toggleNotification({
|
5043
|
+
message: formatMessage({
|
5044
|
+
id: getTranslation('relation.error-adding-relation'),
|
5045
|
+
defaultMessage: 'An error occurred while trying to add the relation.'
|
5046
|
+
}),
|
5047
|
+
type: 'danger'
|
5048
|
+
});
|
5049
|
+
return;
|
5050
|
+
}
|
5051
|
+
/**
|
5052
|
+
* You need to give this relation a correct _temp_key_ but
|
5053
|
+
* this component doesn't know about those ones, you can't rely
|
5054
|
+
* on the connect array because that doesn't hold items that haven't
|
5055
|
+
* moved. So use a callback to fill in the gaps when connecting.
|
5056
|
+
*
|
5057
|
+
*/ onChange(relation);
|
5058
|
+
};
|
5059
|
+
const handleLoadMore = ()=>{
|
5060
|
+
if (!data || !data.pagination) {
|
5061
|
+
return;
|
5062
|
+
} else if (data.pagination.page < data.pagination.pageCount) {
|
5063
|
+
setSearchParams((s)=>({
|
5064
|
+
...s,
|
5065
|
+
page: s.page + 1
|
5066
|
+
}));
|
5067
|
+
}
|
5068
|
+
};
|
5069
|
+
React.useLayoutEffect(()=>{
|
5070
|
+
setTextValue('');
|
5071
|
+
}, [
|
5072
|
+
field.value
|
5073
|
+
]);
|
5074
|
+
return /*#__PURE__*/ jsxs(Field.Root, {
|
5075
|
+
error: field.error,
|
5076
|
+
hint: hint,
|
5077
|
+
name: name,
|
5078
|
+
required: required,
|
5079
|
+
children: [
|
5080
|
+
/*#__PURE__*/ jsx(Field.Label, {
|
5081
|
+
action: labelAction,
|
5082
|
+
children: label
|
5083
|
+
}),
|
5084
|
+
/*#__PURE__*/ jsx(Combobox, {
|
5085
|
+
ref: fieldRef,
|
5086
|
+
name: name,
|
5087
|
+
autocomplete: "list",
|
5088
|
+
placeholder: placeholder || formatMessage({
|
5089
|
+
id: getTranslation('relation.add'),
|
5090
|
+
defaultMessage: 'Add relation'
|
5091
|
+
}),
|
5092
|
+
hasMoreItems: hasNextPage,
|
5093
|
+
loading: isLoading,
|
5094
|
+
onOpenChange: ()=>{
|
5095
|
+
handleSearch(textValue ?? '');
|
5096
|
+
},
|
5097
|
+
noOptionsMessage: ()=>formatMessage({
|
5098
|
+
id: getTranslation('relation.notAvailable'),
|
5099
|
+
defaultMessage: 'No relations available'
|
5100
|
+
}),
|
5101
|
+
loadingMessage: formatMessage({
|
5102
|
+
id: getTranslation('relation.isLoading'),
|
5103
|
+
defaultMessage: 'Relations are loading'
|
5104
|
+
}),
|
5105
|
+
onLoadMore: handleLoadMore,
|
5106
|
+
textValue: textValue,
|
5107
|
+
onChange: handleChange,
|
5108
|
+
onTextValueChange: (text)=>{
|
5109
|
+
setTextValue(text);
|
5110
|
+
},
|
5111
|
+
onInputChange: (event)=>{
|
5112
|
+
handleSearch(event.currentTarget.value);
|
5113
|
+
},
|
5114
|
+
...props,
|
5115
|
+
children: options.map((opt)=>{
|
5116
|
+
const textValue = getRelationLabel(opt, mainField);
|
5117
|
+
return /*#__PURE__*/ jsx(ComboboxOption, {
|
5118
|
+
value: opt.id.toString(),
|
5119
|
+
textValue: textValue,
|
5120
|
+
children: /*#__PURE__*/ jsxs(Flex, {
|
5121
|
+
gap: 2,
|
5122
|
+
justifyContent: "space-between",
|
5123
|
+
children: [
|
5124
|
+
/*#__PURE__*/ jsx(Typography, {
|
5125
|
+
ellipsis: true,
|
5126
|
+
children: textValue
|
5127
|
+
}),
|
5128
|
+
opt.status ? /*#__PURE__*/ jsx(DocumentStatus, {
|
5129
|
+
status: opt.status
|
5130
|
+
}) : null
|
5131
|
+
]
|
5132
|
+
})
|
5133
|
+
}, opt.id);
|
5134
|
+
})
|
5135
|
+
}),
|
5136
|
+
/*#__PURE__*/ jsx(Field.Error, {}),
|
5137
|
+
/*#__PURE__*/ jsx(Field.Hint, {})
|
5138
|
+
]
|
5139
|
+
});
|
5140
|
+
};
|
5141
|
+
/* -------------------------------------------------------------------------------------------------
|
5142
|
+
* RelationsList
|
5143
|
+
* -----------------------------------------------------------------------------------------------*/ const RELATION_ITEM_HEIGHT = 50;
|
5144
|
+
const RELATION_GUTTER = 4;
|
5145
|
+
const RelationsList = ({ data, serverData, disabled, name, isLoading, relationType, targetModel })=>{
|
5146
|
+
const ariaDescriptionId = React.useId();
|
5147
|
+
const { formatMessage } = useIntl();
|
5148
|
+
const listRef = React.useRef(null);
|
5149
|
+
const outerListRef = React.useRef(null);
|
5150
|
+
const [overflow, setOverflow] = React.useState();
|
5151
|
+
const [liveText, setLiveText] = React.useState('');
|
5152
|
+
const field = useField(name);
|
5153
|
+
React.useEffect(()=>{
|
5154
|
+
if (data.length <= RELATIONS_TO_DISPLAY) {
|
5155
|
+
return setOverflow(undefined);
|
5156
|
+
}
|
5157
|
+
const handleNativeScroll = (e)=>{
|
5158
|
+
const el = e.target;
|
5159
|
+
const parentScrollContainerHeight = el.parentNode.scrollHeight;
|
5160
|
+
const maxScrollBottom = el.scrollHeight - el.scrollTop;
|
5161
|
+
if (el.scrollTop === 0) {
|
5162
|
+
return setOverflow('bottom');
|
5163
|
+
}
|
5164
|
+
if (maxScrollBottom === parentScrollContainerHeight) {
|
5165
|
+
return setOverflow('top');
|
5166
|
+
}
|
5167
|
+
return setOverflow('top-bottom');
|
5168
|
+
};
|
5169
|
+
const outerListRefCurrent = outerListRef?.current;
|
5170
|
+
if (!isLoading && data.length > 0 && outerListRefCurrent) {
|
5171
|
+
outerListRef.current.addEventListener('scroll', handleNativeScroll);
|
5172
|
+
}
|
5173
|
+
return ()=>{
|
5174
|
+
if (outerListRefCurrent) {
|
5175
|
+
outerListRefCurrent.removeEventListener('scroll', handleNativeScroll);
|
5176
|
+
}
|
5177
|
+
};
|
5178
|
+
}, [
|
5179
|
+
isLoading,
|
5180
|
+
data.length
|
5181
|
+
]);
|
5182
|
+
const getItemPos = (index)=>`${index + 1} of ${data.length}`;
|
5183
|
+
const handleMoveItem = (newIndex, oldIndex)=>{
|
5184
|
+
const item = data[oldIndex];
|
5185
|
+
setLiveText(formatMessage({
|
5186
|
+
id: getTranslation('dnd.reorder'),
|
5187
|
+
defaultMessage: '{item}, moved. New position in list: {position}.'
|
5188
|
+
}, {
|
5189
|
+
item: item.label ?? item.documentId,
|
5190
|
+
position: getItemPos(newIndex)
|
5191
|
+
}));
|
5192
|
+
/**
|
5193
|
+
* Splicing mutates the array, so we need to create a new array
|
5194
|
+
*/ const newData = [
|
5195
|
+
...data
|
5196
|
+
];
|
5197
|
+
const currentRow = data[oldIndex];
|
5198
|
+
const startKey = oldIndex > newIndex ? newData[newIndex - 1]?.__temp_key__ : newData[newIndex]?.__temp_key__;
|
5199
|
+
const endKey = oldIndex > newIndex ? newData[newIndex]?.__temp_key__ : newData[newIndex + 1]?.__temp_key__;
|
5200
|
+
/**
|
5201
|
+
* We're moving the relation between two other relations, so
|
5202
|
+
* we need to generate a new key that keeps the order
|
5203
|
+
*/ const [newKey] = generateNKeysBetween(startKey, endKey, 1);
|
5204
|
+
newData.splice(oldIndex, 1);
|
5205
|
+
newData.splice(newIndex, 0, {
|
5206
|
+
...currentRow,
|
5207
|
+
__temp_key__: newKey
|
5208
|
+
});
|
5209
|
+
/**
|
5210
|
+
* Now we diff against the server to understand what's different so we
|
5211
|
+
* can keep the connect array nice and tidy. It also needs reversing because
|
5212
|
+
* we reverse the relations from the server in the first place.
|
5213
|
+
*/ const connectedRelations = newData.reduce((acc, relation, currentIndex, array)=>{
|
5214
|
+
const relationOnServer = serverData.find((oldRelation)=>oldRelation.id === relation.id);
|
5215
|
+
const relationInFront = array[currentIndex + 1];
|
5216
|
+
if (!relationOnServer || relationOnServer.__temp_key__ !== relation.__temp_key__) {
|
5217
|
+
const position = relationInFront ? {
|
5218
|
+
before: relationInFront.documentId,
|
5219
|
+
locale: relationInFront.locale,
|
5220
|
+
status: 'publishedAt' in relationInFront && relationInFront.publishedAt ? 'published' : 'draft'
|
5221
|
+
} : {
|
5222
|
+
end: true
|
5223
|
+
};
|
5224
|
+
const relationWithPosition = {
|
5225
|
+
...relation,
|
5226
|
+
...{
|
5227
|
+
apiData: {
|
5228
|
+
id: relation.id,
|
5229
|
+
documentId: relation.documentId ?? relation.apiData?.documentId ?? '',
|
5230
|
+
locale: relation.locale || relation.apiData?.locale,
|
5231
|
+
position
|
5232
|
+
}
|
5233
|
+
}
|
5234
|
+
};
|
5235
|
+
return [
|
5236
|
+
...acc,
|
5237
|
+
relationWithPosition
|
5238
|
+
];
|
5239
|
+
}
|
5240
|
+
return acc;
|
5241
|
+
}, []).toReversed();
|
5242
|
+
field.onChange(`${name}.connect`, connectedRelations);
|
5243
|
+
};
|
5244
|
+
const handleGrabItem = (index)=>{
|
5245
|
+
const item = data[index];
|
5246
|
+
setLiveText(formatMessage({
|
5247
|
+
id: getTranslation('dnd.grab-item'),
|
5248
|
+
defaultMessage: `{item}, grabbed. Current position in list: {position}. Press up and down arrow to change position, Spacebar to drop, Escape to cancel.`
|
5249
|
+
}, {
|
5250
|
+
item: item.label ?? item.documentId,
|
5251
|
+
position: getItemPos(index)
|
5252
|
+
}));
|
5253
|
+
};
|
5254
|
+
const handleDropItem = (index)=>{
|
5255
|
+
const { href: _href, label, ...item } = data[index];
|
5256
|
+
setLiveText(formatMessage({
|
5257
|
+
id: getTranslation('dnd.drop-item'),
|
5258
|
+
defaultMessage: `{item}, dropped. Final position in list: {position}.`
|
5259
|
+
}, {
|
5260
|
+
item: label ?? item.documentId,
|
5261
|
+
position: getItemPos(index)
|
5262
|
+
}));
|
5263
|
+
};
|
5264
|
+
const handleCancel = (index)=>{
|
5265
|
+
const item = data[index];
|
5266
|
+
setLiveText(formatMessage({
|
5267
|
+
id: getTranslation('dnd.cancel-item'),
|
5268
|
+
defaultMessage: '{item}, dropped. Re-order cancelled.'
|
5269
|
+
}, {
|
5270
|
+
item: item.label ?? item.documentId
|
5271
|
+
}));
|
5272
|
+
};
|
5273
|
+
const handleDisconnect = useHandleDisconnect(name, 'RelationsList');
|
5274
|
+
/**
|
5275
|
+
* These relation types will only ever have one item
|
5276
|
+
* in their list, so you can't reorder a single item!
|
5277
|
+
*/ const canReorder = !ONE_WAY_RELATIONS.includes(relationType);
|
5278
|
+
const dynamicListHeight = data.length > RELATIONS_TO_DISPLAY ? Math.min(data.length, RELATIONS_TO_DISPLAY) * (RELATION_ITEM_HEIGHT + RELATION_GUTTER) + RELATION_ITEM_HEIGHT / 2 : Math.min(data.length, RELATIONS_TO_DISPLAY) * (RELATION_ITEM_HEIGHT + RELATION_GUTTER);
|
5279
|
+
return /*#__PURE__*/ jsxs(ShadowBox, {
|
5280
|
+
$overflowDirection: overflow,
|
5281
|
+
children: [
|
5282
|
+
/*#__PURE__*/ jsx(VisuallyHidden, {
|
5283
|
+
id: ariaDescriptionId,
|
5284
|
+
children: formatMessage({
|
5285
|
+
id: getTranslation('dnd.instructions'),
|
5286
|
+
defaultMessage: `Press spacebar to grab and re-order`
|
5287
|
+
})
|
5288
|
+
}),
|
5289
|
+
/*#__PURE__*/ jsx(VisuallyHidden, {
|
5290
|
+
"aria-live": "assertive",
|
5291
|
+
children: liveText
|
5292
|
+
}),
|
5293
|
+
/*#__PURE__*/ jsx(FixedSizeList, {
|
5294
|
+
height: dynamicListHeight,
|
5295
|
+
ref: listRef,
|
5296
|
+
outerRef: outerListRef,
|
5297
|
+
itemCount: data.length,
|
5298
|
+
itemSize: RELATION_ITEM_HEIGHT + RELATION_GUTTER,
|
5299
|
+
itemData: {
|
5300
|
+
ariaDescribedBy: ariaDescriptionId,
|
5301
|
+
canDrag: canReorder,
|
5302
|
+
disabled,
|
5303
|
+
handleCancel,
|
5304
|
+
handleDropItem,
|
5305
|
+
handleGrabItem,
|
5306
|
+
handleMoveItem,
|
5307
|
+
name,
|
5308
|
+
handleDisconnect,
|
5309
|
+
relations: data,
|
5310
|
+
targetModel
|
5311
|
+
},
|
5312
|
+
itemKey: (index)=>data[index].id,
|
5313
|
+
innerElementType: "ol",
|
5314
|
+
children: ListItem
|
5315
|
+
})
|
5316
|
+
]
|
5317
|
+
});
|
5318
|
+
};
|
5319
|
+
const ShadowBox = styled(Box)`
|
5320
|
+
position: relative;
|
5321
|
+
overflow: hidden;
|
5322
|
+
flex: 1;
|
5323
|
+
|
5324
|
+
&:before,
|
5325
|
+
&:after {
|
5326
|
+
position: absolute;
|
5327
|
+
width: 100%;
|
5328
|
+
height: 4px;
|
5329
|
+
z-index: 1;
|
5330
|
+
}
|
5331
|
+
|
5332
|
+
&:before {
|
5333
|
+
/* TODO: as for DS Table component we would need this to be handled by the DS theme */
|
5334
|
+
content: '';
|
5335
|
+
background: linear-gradient(rgba(3, 3, 5, 0.2) 0%, rgba(0, 0, 0, 0) 100%);
|
5336
|
+
top: 0;
|
5337
|
+
opacity: ${({ $overflowDirection })=>$overflowDirection === 'top-bottom' || $overflowDirection === 'top' ? 1 : 0};
|
5338
|
+
transition: opacity 0.2s ease-in-out;
|
5339
|
+
}
|
5340
|
+
|
5341
|
+
&:after {
|
5342
|
+
/* TODO: as for DS Table component we would need this to be handled by the DS theme */
|
5343
|
+
content: '';
|
5344
|
+
background: linear-gradient(0deg, rgba(3, 3, 5, 0.2) 0%, rgba(0, 0, 0, 0) 100%);
|
5345
|
+
bottom: 0;
|
5346
|
+
opacity: ${({ $overflowDirection })=>$overflowDirection === 'top-bottom' || $overflowDirection === 'bottom' ? 1 : 0};
|
5347
|
+
transition: opacity 0.2s ease-in-out;
|
5348
|
+
}
|
5349
|
+
`;
|
5350
|
+
const ListItem = ({ data, index, style })=>{
|
5351
|
+
const { ariaDescribedBy, canDrag = false, disabled = false, handleCancel, handleDisconnect, handleDropItem, handleGrabItem, handleMoveItem, name, relations, targetModel } = data;
|
5352
|
+
const { formatMessage } = useIntl();
|
5353
|
+
const { href, id, label, status, documentId, apiData, locale } = relations[index];
|
5354
|
+
const [{ handlerId, isDragging, handleKeyDown }, relationRef, dropRef, dragRef, dragPreviewRef] = useDragAndDrop(canDrag && !disabled, {
|
5355
|
+
type: `${ItemTypes.RELATION}_${name}`,
|
5356
|
+
index,
|
5357
|
+
item: {
|
5358
|
+
displayedValue: label,
|
5359
|
+
status,
|
5360
|
+
id: id,
|
5361
|
+
index
|
5362
|
+
},
|
5363
|
+
onMoveItem: handleMoveItem,
|
5364
|
+
onDropItem: handleDropItem,
|
5365
|
+
onGrabItem: handleGrabItem,
|
5366
|
+
onCancel: handleCancel,
|
5367
|
+
dropSensitivity: DROP_SENSITIVITY.REGULAR
|
5368
|
+
});
|
5369
|
+
const composedRefs = useComposedRefs(relationRef, dragRef);
|
5370
|
+
React.useEffect(()=>{
|
5371
|
+
dragPreviewRef(getEmptyImage());
|
5372
|
+
}, [
|
5373
|
+
dragPreviewRef
|
5374
|
+
]);
|
5375
|
+
return /*#__PURE__*/ jsx(Box, {
|
5376
|
+
style: style,
|
5377
|
+
tag: "li",
|
5378
|
+
ref: dropRef,
|
5379
|
+
"aria-describedby": ariaDescribedBy,
|
5380
|
+
cursor: canDrag ? 'all-scroll' : 'default',
|
5381
|
+
children: isDragging ? /*#__PURE__*/ jsx(RelationItemPlaceholder, {}) : /*#__PURE__*/ jsxs(Flex, {
|
5382
|
+
paddingTop: 2,
|
5383
|
+
paddingBottom: 2,
|
5384
|
+
paddingLeft: canDrag ? 2 : 4,
|
5385
|
+
paddingRight: 4,
|
5386
|
+
hasRadius: true,
|
5387
|
+
borderColor: "neutral200",
|
5388
|
+
background: disabled ? 'neutral150' : 'neutral0',
|
5389
|
+
justifyContent: "space-between",
|
5390
|
+
ref: composedRefs,
|
5391
|
+
"data-handler-id": handlerId,
|
5392
|
+
children: [
|
5393
|
+
/*#__PURE__*/ jsxs(FlexWrapper, {
|
5394
|
+
gap: 1,
|
5395
|
+
children: [
|
5396
|
+
canDrag ? /*#__PURE__*/ jsx(IconButton, {
|
5397
|
+
tag: "div",
|
5398
|
+
role: "button",
|
5399
|
+
tabIndex: 0,
|
5400
|
+
withTooltip: false,
|
5401
|
+
label: formatMessage({
|
5402
|
+
id: getTranslation('components.RelationInput.icon-button-aria-label'),
|
5403
|
+
defaultMessage: 'Drag'
|
5404
|
+
}),
|
5405
|
+
variant: "ghost",
|
5406
|
+
onKeyDown: handleKeyDown,
|
5407
|
+
disabled: disabled,
|
5408
|
+
children: /*#__PURE__*/ jsx(Drag, {})
|
5409
|
+
}) : null,
|
5410
|
+
/*#__PURE__*/ jsxs(Flex, {
|
5411
|
+
width: "100%",
|
5412
|
+
minWidth: 0,
|
5413
|
+
justifyContent: "space-between",
|
5414
|
+
children: [
|
5415
|
+
/*#__PURE__*/ jsx(Box, {
|
5416
|
+
minWidth: 0,
|
5417
|
+
paddingTop: 1,
|
5418
|
+
paddingBottom: 1,
|
5419
|
+
paddingRight: 4,
|
5420
|
+
children: /*#__PURE__*/ jsx(RelationModalForm, {
|
5421
|
+
triggerButtonLabel: label,
|
5422
|
+
relation: {
|
5423
|
+
documentId: documentId ?? apiData?.documentId,
|
5424
|
+
model: targetModel,
|
5425
|
+
collectionType: getCollectionType(href),
|
5426
|
+
params: {
|
5427
|
+
locale: locale || apiData?.locale || null
|
5428
|
+
}
|
5429
|
+
}
|
5430
|
+
})
|
5431
|
+
}),
|
5432
|
+
status ? /*#__PURE__*/ jsx(DocumentStatus, {
|
5433
|
+
status: status
|
5434
|
+
}) : null
|
5435
|
+
]
|
5436
|
+
})
|
5437
|
+
]
|
5438
|
+
}),
|
5439
|
+
/*#__PURE__*/ jsx(Box, {
|
5440
|
+
paddingLeft: 4,
|
5441
|
+
children: /*#__PURE__*/ jsx(IconButton, {
|
5442
|
+
onClick: ()=>handleDisconnect(relations[index]),
|
5443
|
+
disabled: disabled,
|
5444
|
+
label: formatMessage({
|
5445
|
+
id: getTranslation('relation.disconnect'),
|
5446
|
+
defaultMessage: 'Remove'
|
5447
|
+
}),
|
5448
|
+
variant: "ghost",
|
5449
|
+
size: "S",
|
5450
|
+
children: /*#__PURE__*/ jsx(Cross, {})
|
5451
|
+
})
|
5452
|
+
})
|
5453
|
+
]
|
5454
|
+
})
|
5455
|
+
});
|
5456
|
+
};
|
5457
|
+
const FlexWrapper = styled(Flex)`
|
5458
|
+
width: 100%;
|
5459
|
+
/* Used to prevent endAction to be pushed out of container */
|
5460
|
+
min-width: 0;
|
5461
|
+
|
5462
|
+
& > div[role='button'] {
|
5463
|
+
cursor: all-scroll;
|
5464
|
+
}
|
5465
|
+
`;
|
5466
|
+
const DisconnectButton = styled.button`
|
5467
|
+
svg path {
|
5468
|
+
fill: ${({ theme, disabled })=>disabled ? theme.colors.neutral600 : theme.colors.neutral500};
|
5469
|
+
}
|
5470
|
+
|
5471
|
+
&:hover svg path,
|
5472
|
+
&:focus svg path {
|
5473
|
+
fill: ${({ theme, disabled })=>!disabled && theme.colors.neutral600};
|
5474
|
+
}
|
5475
|
+
`;
|
5476
|
+
const LinkEllipsis = styled(Link$2)`
|
5477
|
+
display: block;
|
5478
|
+
|
5479
|
+
& > span {
|
5480
|
+
white-space: nowrap;
|
5481
|
+
overflow: hidden;
|
5482
|
+
text-overflow: ellipsis;
|
5483
|
+
display: block;
|
5484
|
+
}
|
5485
|
+
`;
|
5486
|
+
const RelationItemPlaceholder = ()=>/*#__PURE__*/ jsx(Box, {
|
5487
|
+
paddingTop: 2,
|
5488
|
+
paddingBottom: 2,
|
5489
|
+
paddingLeft: 4,
|
5490
|
+
paddingRight: 4,
|
5491
|
+
hasRadius: true,
|
5492
|
+
borderStyle: "dashed",
|
5493
|
+
borderColor: "primary600",
|
5494
|
+
borderWidth: "1px",
|
5495
|
+
background: "primary100",
|
5496
|
+
height: `calc(100% - ${RELATION_GUTTER}px)`
|
5497
|
+
});
|
5498
|
+
const MemoizedRelationsField = /*#__PURE__*/ React.memo(RelationsField);
|
5499
|
+
|
5500
|
+
const uidApi = contentManagerApi.injectEndpoints({
|
5501
|
+
endpoints: (builder)=>({
|
5502
|
+
getDefaultUID: builder.query({
|
5503
|
+
query: ({ params, ...data })=>{
|
5504
|
+
return {
|
5505
|
+
url: '/content-manager/uid/generate',
|
5506
|
+
method: 'POST',
|
5507
|
+
data,
|
5508
|
+
config: {
|
5509
|
+
params
|
5510
|
+
}
|
5511
|
+
};
|
5512
|
+
},
|
5513
|
+
transformResponse: (response)=>response.data
|
5514
|
+
}),
|
5515
|
+
generateUID: builder.mutation({
|
5516
|
+
query: ({ params, ...data })=>({
|
5517
|
+
url: '/content-manager/uid/generate',
|
5518
|
+
method: 'POST',
|
5519
|
+
data,
|
5520
|
+
config: {
|
5521
|
+
params
|
5522
|
+
}
|
5523
|
+
}),
|
5524
|
+
transformResponse: (response)=>response.data
|
5525
|
+
}),
|
5526
|
+
getAvailability: builder.query({
|
5527
|
+
query: ({ params, ...data })=>({
|
5528
|
+
url: '/content-manager/uid/check-availability',
|
5529
|
+
method: 'POST',
|
5530
|
+
data,
|
5531
|
+
config: {
|
5532
|
+
params
|
5533
|
+
}
|
5534
|
+
}),
|
5535
|
+
providesTags: (_res, _error, params)=>[
|
5536
|
+
{
|
5537
|
+
type: 'UidAvailability',
|
5538
|
+
id: params.contentTypeUID
|
5539
|
+
}
|
5540
|
+
]
|
5541
|
+
})
|
5542
|
+
})
|
5543
|
+
});
|
5544
|
+
const { useGenerateUIDMutation, useGetDefaultUIDQuery, useGetAvailabilityQuery } = uidApi;
|
5545
|
+
|
5546
|
+
/* -------------------------------------------------------------------------------------------------
|
5547
|
+
* InputUID
|
5548
|
+
* -----------------------------------------------------------------------------------------------*/ const UID_REGEX = /^[A-Za-z0-9-_.~]*$/;
|
5549
|
+
const UIDInput = /*#__PURE__*/ React.forwardRef(({ hint, label, labelAction, name, required, ...props }, ref)=>{
|
5550
|
+
const { model, id } = useDoc();
|
5551
|
+
const allFormValues = useForm('InputUID', (form)=>form.values);
|
5552
|
+
const [availability, setAvailability] = React.useState();
|
5553
|
+
const [showRegenerate, setShowRegenerate] = React.useState(false);
|
5554
|
+
const isCloning = useMatch(CLONE_PATH) !== null;
|
5555
|
+
const field = useField(name);
|
5556
|
+
const debouncedValue = useDebounce(field.value, 300);
|
5557
|
+
const hasChanged = debouncedValue !== field.initialValue;
|
5558
|
+
const { toggleNotification } = useNotification();
|
5559
|
+
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
5560
|
+
const { formatMessage } = useIntl();
|
5561
|
+
const [{ query }] = useQueryParams();
|
5562
|
+
const params = React.useMemo(()=>buildValidParams(query), [
|
5563
|
+
query
|
5564
|
+
]);
|
5565
|
+
const { data: defaultGeneratedUID, isLoading: isGeneratingDefaultUID, error: apiError } = useGetDefaultUIDQuery({
|
5566
|
+
contentTypeUID: model,
|
5567
|
+
field: name,
|
5568
|
+
data: {
|
5569
|
+
id: id ?? '',
|
5570
|
+
...allFormValues
|
5571
|
+
},
|
5572
|
+
params
|
5573
|
+
}, {
|
5574
|
+
skip: field.value || !required
|
5575
|
+
});
|
5576
|
+
React.useEffect(()=>{
|
5577
|
+
if (apiError) {
|
5578
|
+
toggleNotification({
|
5579
|
+
type: 'warning',
|
5580
|
+
message: formatAPIError(apiError)
|
5581
|
+
});
|
5582
|
+
}
|
5583
|
+
}, [
|
5584
|
+
apiError,
|
5585
|
+
formatAPIError,
|
5586
|
+
toggleNotification
|
5587
|
+
]);
|
5588
|
+
/**
|
5589
|
+
* If the defaultGeneratedUID is available, then we set it as the value,
|
5590
|
+
* but we also want to set it as the initialValue too.
|
5591
|
+
*/ React.useEffect(()=>{
|
5592
|
+
if (defaultGeneratedUID && field.value === undefined) {
|
5593
|
+
field.onChange(name, defaultGeneratedUID);
|
5594
|
+
}
|
5595
|
+
}, [
|
5596
|
+
defaultGeneratedUID,
|
5597
|
+
field,
|
5598
|
+
name
|
5599
|
+
]);
|
5600
|
+
const [generateUID, { isLoading: isGeneratingUID }] = useGenerateUIDMutation();
|
5601
|
+
const handleRegenerateClick = async ()=>{
|
5602
|
+
try {
|
5603
|
+
const res = await generateUID({
|
5604
|
+
contentTypeUID: model,
|
5605
|
+
field: name,
|
5606
|
+
data: {
|
5607
|
+
id: id ?? '',
|
5608
|
+
...allFormValues
|
5609
|
+
},
|
5610
|
+
params
|
5611
|
+
});
|
5612
|
+
if ('data' in res) {
|
5613
|
+
field.onChange(name, res.data);
|
5614
|
+
} else {
|
5615
|
+
toggleNotification({
|
5616
|
+
type: 'danger',
|
5617
|
+
message: formatAPIError(res.error)
|
5618
|
+
});
|
5619
|
+
}
|
5620
|
+
} catch (err) {
|
5621
|
+
toggleNotification({
|
5622
|
+
type: 'danger',
|
5623
|
+
message: formatMessage({
|
5624
|
+
id: 'notification.error',
|
5625
|
+
defaultMessage: 'An error occurred.'
|
5626
|
+
})
|
5627
|
+
});
|
5628
|
+
}
|
5629
|
+
};
|
5630
|
+
const { data: availabilityData, isLoading: isCheckingAvailability, error: availabilityError } = useGetAvailabilityQuery({
|
5631
|
+
contentTypeUID: model,
|
5632
|
+
field: name,
|
5633
|
+
value: debouncedValue ? debouncedValue.trim() : '',
|
5634
|
+
params
|
5635
|
+
}, {
|
5636
|
+
// Don't check availability if the value is empty or wasn't changed
|
5637
|
+
skip: !Boolean((hasChanged || isCloning) && debouncedValue && UID_REGEX.test(debouncedValue.trim()))
|
5638
|
+
});
|
5639
|
+
React.useEffect(()=>{
|
5640
|
+
if (availabilityError) {
|
5641
|
+
toggleNotification({
|
5642
|
+
type: 'warning',
|
5643
|
+
message: formatAPIError(availabilityError)
|
5644
|
+
});
|
5645
|
+
}
|
5646
|
+
}, [
|
4130
5647
|
availabilityError,
|
4131
5648
|
formatAPIError,
|
4132
5649
|
toggleNotification
|
@@ -4221,7 +5738,7 @@ const UIDInput = /*#__PURE__*/ React.forwardRef(({ hint, label, labelAction, nam
|
|
4221
5738
|
onMouseLeave: ()=>setShowRegenerate(false),
|
4222
5739
|
children: isLoading ? /*#__PURE__*/ jsx(LoadingWrapper, {
|
4223
5740
|
"data-testid": "loading-wrapper",
|
4224
|
-
children: /*#__PURE__*/ jsx(Loader, {})
|
5741
|
+
children: /*#__PURE__*/ jsx(Loader$1, {})
|
4225
5742
|
}) : /*#__PURE__*/ jsx(ArrowClockwise, {})
|
4226
5743
|
})
|
4227
5744
|
]
|
@@ -5484,14 +7001,14 @@ const quoteAndCodeHandler = (editor, markdownType)=>{
|
|
5484
7001
|
};
|
5485
7002
|
|
5486
7003
|
// NAV BUTTONS
|
5487
|
-
|
7004
|
+
styled(IconButtonGroup)`
|
5488
7005
|
margin-left: ${({ theme })=>theme.spaces[4]};
|
5489
7006
|
`;
|
5490
|
-
|
7007
|
+
styled(IconButton)`
|
5491
7008
|
margin: ${({ theme })=>`0 ${theme.spaces[2]}`};
|
5492
7009
|
`;
|
5493
7010
|
// NAV
|
5494
|
-
|
7011
|
+
styled(IconButtonGroup)`
|
5495
7012
|
margin-right: ${({ theme })=>`${theme.spaces[2]}`};
|
5496
7013
|
`;
|
5497
7014
|
// FOOTER
|
@@ -5540,254 +7057,524 @@ const WysiwygFooter = ({ onToggleExpand })=>{
|
|
5540
7057
|
defaultMessage: 'Expand'
|
5541
7058
|
})
|
5542
7059
|
}),
|
5543
|
-
/*#__PURE__*/ jsx(Expand, {})
|
7060
|
+
/*#__PURE__*/ jsx(Expand, {})
|
7061
|
+
]
|
7062
|
+
})
|
7063
|
+
})
|
7064
|
+
});
|
7065
|
+
};
|
7066
|
+
|
7067
|
+
/**
|
7068
|
+
* TODO: refactor this mess.
|
7069
|
+
*/ const WysiwygNav = ({ disabled, editorRef, isPreviewMode, onToggleMediaLib, onTogglePreviewMode })=>{
|
7070
|
+
const { formatMessage } = useIntl();
|
7071
|
+
const isDisabled = disabled || isPreviewMode;
|
7072
|
+
const handleActionClick = (value, currentEditorRef)=>{
|
7073
|
+
switch(value){
|
7074
|
+
case 'Link':
|
7075
|
+
{
|
7076
|
+
markdownHandler(currentEditorRef, value);
|
7077
|
+
break;
|
7078
|
+
}
|
7079
|
+
case 'Code':
|
7080
|
+
case 'Quote':
|
7081
|
+
{
|
7082
|
+
quoteAndCodeHandler(currentEditorRef, value);
|
7083
|
+
break;
|
7084
|
+
}
|
7085
|
+
case 'Bold':
|
7086
|
+
case 'Italic':
|
7087
|
+
case 'Underline':
|
7088
|
+
case 'Strikethrough':
|
7089
|
+
{
|
7090
|
+
markdownHandler(currentEditorRef, value);
|
7091
|
+
break;
|
7092
|
+
}
|
7093
|
+
case 'BulletList':
|
7094
|
+
case 'NumberList':
|
7095
|
+
{
|
7096
|
+
listHandler(currentEditorRef, value);
|
7097
|
+
break;
|
7098
|
+
}
|
7099
|
+
case 'h1':
|
7100
|
+
case 'h2':
|
7101
|
+
case 'h3':
|
7102
|
+
case 'h4':
|
7103
|
+
case 'h5':
|
7104
|
+
case 'h6':
|
7105
|
+
{
|
7106
|
+
titleHandler(currentEditorRef, value);
|
7107
|
+
break;
|
7108
|
+
}
|
7109
|
+
}
|
7110
|
+
};
|
7111
|
+
const observedComponents = [
|
7112
|
+
{
|
7113
|
+
toolbar: /*#__PURE__*/ jsxs(IconButtonGroup, {
|
7114
|
+
children: [
|
7115
|
+
/*#__PURE__*/ jsx(IconButton, {
|
7116
|
+
disabled: isDisabled,
|
7117
|
+
onClick: ()=>handleActionClick('Bold', editorRef),
|
7118
|
+
label: formatMessage({
|
7119
|
+
id: 'components.Blocks.modifiers.bold',
|
7120
|
+
defaultMessage: 'Bold'
|
7121
|
+
}),
|
7122
|
+
name: formatMessage({
|
7123
|
+
id: 'components.Blocks.modifiers.bold',
|
7124
|
+
defaultMessage: 'Bold'
|
7125
|
+
}),
|
7126
|
+
children: /*#__PURE__*/ jsx(Bold, {})
|
7127
|
+
}),
|
7128
|
+
/*#__PURE__*/ jsx(IconButton, {
|
7129
|
+
disabled: isDisabled,
|
7130
|
+
onClick: ()=>handleActionClick('Italic', editorRef),
|
7131
|
+
label: formatMessage({
|
7132
|
+
id: 'components.Blocks.modifiers.italic',
|
7133
|
+
defaultMessage: 'Italic'
|
7134
|
+
}),
|
7135
|
+
name: formatMessage({
|
7136
|
+
id: 'components.Blocks.modifiers.italic',
|
7137
|
+
defaultMessage: 'Italic'
|
7138
|
+
}),
|
7139
|
+
children: /*#__PURE__*/ jsx(Italic, {})
|
7140
|
+
}),
|
7141
|
+
/*#__PURE__*/ jsx(IconButton, {
|
7142
|
+
disabled: isDisabled,
|
7143
|
+
onClick: ()=>handleActionClick('Underline', editorRef),
|
7144
|
+
label: formatMessage({
|
7145
|
+
id: 'components.Blocks.modifiers.underline',
|
7146
|
+
defaultMessage: 'Underline'
|
7147
|
+
}),
|
7148
|
+
name: formatMessage({
|
7149
|
+
id: 'components.Blocks.modifiers.underline',
|
7150
|
+
defaultMessage: 'Underline'
|
7151
|
+
}),
|
7152
|
+
children: /*#__PURE__*/ jsx(Underline, {})
|
7153
|
+
}),
|
7154
|
+
/*#__PURE__*/ jsx(IconButton, {
|
7155
|
+
disabled: isDisabled,
|
7156
|
+
onClick: ()=>handleActionClick('Strikethrough', editorRef),
|
7157
|
+
label: formatMessage({
|
7158
|
+
id: 'components.Blocks.modifiers.strikethrough',
|
7159
|
+
defaultMessage: 'Strikethrough'
|
7160
|
+
}),
|
7161
|
+
name: formatMessage({
|
7162
|
+
id: 'components.Blocks.modifiers.strikethrough',
|
7163
|
+
defaultMessage: 'Strikethrough'
|
7164
|
+
}),
|
7165
|
+
children: /*#__PURE__*/ jsx(StrikeThrough, {})
|
7166
|
+
})
|
7167
|
+
]
|
7168
|
+
}),
|
7169
|
+
menu: /*#__PURE__*/ jsxs(Fragment, {
|
7170
|
+
children: [
|
7171
|
+
/*#__PURE__*/ jsx(Menu.Separator, {}),
|
7172
|
+
/*#__PURE__*/ jsx(Menu.Item, {
|
7173
|
+
onSelect: ()=>handleActionClick('Bold', editorRef),
|
7174
|
+
disabled: isDisabled,
|
7175
|
+
children: /*#__PURE__*/ jsxs(Flex, {
|
7176
|
+
tag: "span",
|
7177
|
+
gap: 2,
|
7178
|
+
children: [
|
7179
|
+
/*#__PURE__*/ jsx(Bold, {
|
7180
|
+
"aria-hidden": true,
|
7181
|
+
fill: "neutral600"
|
7182
|
+
}),
|
7183
|
+
formatMessage({
|
7184
|
+
id: 'components.Blocks.modifiers.bold',
|
7185
|
+
defaultMessage: 'Bold'
|
7186
|
+
})
|
7187
|
+
]
|
7188
|
+
})
|
7189
|
+
}),
|
7190
|
+
/*#__PURE__*/ jsx(Menu.Item, {
|
7191
|
+
onSelect: ()=>handleActionClick('Italic', editorRef),
|
7192
|
+
disabled: isDisabled,
|
7193
|
+
children: /*#__PURE__*/ jsxs(Flex, {
|
7194
|
+
tag: "span",
|
7195
|
+
gap: 2,
|
7196
|
+
children: [
|
7197
|
+
/*#__PURE__*/ jsx(Italic, {
|
7198
|
+
"aria-hidden": true,
|
7199
|
+
fill: "neutral600"
|
7200
|
+
}),
|
7201
|
+
formatMessage({
|
7202
|
+
id: 'components.Blocks.modifiers.italic',
|
7203
|
+
defaultMessage: 'Italic'
|
7204
|
+
})
|
7205
|
+
]
|
7206
|
+
})
|
7207
|
+
}),
|
7208
|
+
/*#__PURE__*/ jsx(Menu.Item, {
|
7209
|
+
onSelect: ()=>handleActionClick('Underline', editorRef),
|
7210
|
+
disabled: isDisabled,
|
7211
|
+
children: /*#__PURE__*/ jsxs(Flex, {
|
7212
|
+
tag: "span",
|
7213
|
+
gap: 2,
|
7214
|
+
children: [
|
7215
|
+
/*#__PURE__*/ jsx(Underline, {
|
7216
|
+
"aria-hidden": true,
|
7217
|
+
fill: "neutral600"
|
7218
|
+
}),
|
7219
|
+
formatMessage({
|
7220
|
+
id: 'components.Blocks.modifiers.underline',
|
7221
|
+
defaultMessage: 'Underline'
|
7222
|
+
})
|
7223
|
+
]
|
7224
|
+
})
|
7225
|
+
}),
|
7226
|
+
/*#__PURE__*/ jsx(Menu.Item, {
|
7227
|
+
onSelect: ()=>handleActionClick('Strikethrough', editorRef),
|
7228
|
+
disabled: isDisabled,
|
7229
|
+
children: /*#__PURE__*/ jsxs(Flex, {
|
7230
|
+
tag: "span",
|
7231
|
+
gap: 2,
|
7232
|
+
children: [
|
7233
|
+
/*#__PURE__*/ jsx(StrikeThrough, {
|
7234
|
+
"aria-hidden": true,
|
7235
|
+
fill: "neutral600"
|
7236
|
+
}),
|
7237
|
+
formatMessage({
|
7238
|
+
id: 'components.Blocks.modifiers.strikethrough',
|
7239
|
+
defaultMessage: 'Strikethrough'
|
7240
|
+
})
|
7241
|
+
]
|
7242
|
+
})
|
7243
|
+
})
|
5544
7244
|
]
|
5545
|
-
})
|
5546
|
-
|
5547
|
-
|
5548
|
-
|
5549
|
-
|
5550
|
-
|
5551
|
-
|
5552
|
-
|
5553
|
-
|
5554
|
-
|
5555
|
-
|
5556
|
-
|
5557
|
-
|
5558
|
-
|
5559
|
-
|
5560
|
-
|
5561
|
-
|
5562
|
-
|
5563
|
-
|
5564
|
-
|
5565
|
-
|
5566
|
-
|
5567
|
-
|
5568
|
-
|
5569
|
-
|
5570
|
-
/*#__PURE__*/ jsxs(Flex, {
|
5571
|
-
children: [
|
5572
|
-
/*#__PURE__*/ jsx(Field.Root, {
|
5573
|
-
children: /*#__PURE__*/ jsxs(SingleSelect, {
|
5574
|
-
disabled: true,
|
5575
|
-
placeholder: selectPlaceholder,
|
5576
|
-
"aria-label": selectPlaceholder,
|
5577
|
-
size: "S",
|
5578
|
-
children: [
|
5579
|
-
/*#__PURE__*/ jsx(SingleSelectOption, {
|
5580
|
-
value: "h1",
|
5581
|
-
children: "h1"
|
5582
|
-
}),
|
5583
|
-
/*#__PURE__*/ jsx(SingleSelectOption, {
|
5584
|
-
value: "h2",
|
5585
|
-
children: "h2"
|
5586
|
-
}),
|
5587
|
-
/*#__PURE__*/ jsx(SingleSelectOption, {
|
5588
|
-
value: "h3",
|
5589
|
-
children: "h3"
|
5590
|
-
}),
|
5591
|
-
/*#__PURE__*/ jsx(SingleSelectOption, {
|
5592
|
-
value: "h4",
|
5593
|
-
children: "h4"
|
5594
|
-
}),
|
5595
|
-
/*#__PURE__*/ jsx(SingleSelectOption, {
|
5596
|
-
value: "h5",
|
5597
|
-
children: "h5"
|
5598
|
-
}),
|
5599
|
-
/*#__PURE__*/ jsx(SingleSelectOption, {
|
5600
|
-
value: "h6",
|
5601
|
-
children: "h6"
|
5602
|
-
})
|
5603
|
-
]
|
5604
|
-
})
|
7245
|
+
}),
|
7246
|
+
key: 'formatting-group-1'
|
7247
|
+
},
|
7248
|
+
{
|
7249
|
+
toolbar: /*#__PURE__*/ jsxs(IconButtonGroup, {
|
7250
|
+
children: [
|
7251
|
+
/*#__PURE__*/ jsx(IconButton, {
|
7252
|
+
disabled: isDisabled,
|
7253
|
+
onClick: ()=>handleActionClick('BulletList', editorRef),
|
7254
|
+
label: formatMessage({
|
7255
|
+
id: 'components.Blocks.blocks.bulletList',
|
7256
|
+
defaultMessage: 'Bulleted list'
|
7257
|
+
}),
|
7258
|
+
name: formatMessage({
|
7259
|
+
id: 'components.Blocks.blocks.bulletList',
|
7260
|
+
defaultMessage: 'Bulleted list'
|
7261
|
+
}),
|
7262
|
+
children: /*#__PURE__*/ jsx(BulletList, {})
|
7263
|
+
}),
|
7264
|
+
/*#__PURE__*/ jsx(IconButton, {
|
7265
|
+
disabled: isDisabled,
|
7266
|
+
onClick: ()=>handleActionClick('NumberList', editorRef),
|
7267
|
+
label: formatMessage({
|
7268
|
+
id: 'components.Blocks.blocks.numberList',
|
7269
|
+
defaultMessage: 'Numbered list'
|
5605
7270
|
}),
|
5606
|
-
|
7271
|
+
name: formatMessage({
|
7272
|
+
id: 'components.Blocks.blocks.numberList',
|
7273
|
+
defaultMessage: 'Numbered list'
|
7274
|
+
}),
|
7275
|
+
children: /*#__PURE__*/ jsx(NumberList, {})
|
7276
|
+
})
|
7277
|
+
]
|
7278
|
+
}),
|
7279
|
+
menu: /*#__PURE__*/ jsxs(Fragment, {
|
7280
|
+
children: [
|
7281
|
+
/*#__PURE__*/ jsx(Menu.Separator, {}),
|
7282
|
+
/*#__PURE__*/ jsx(Menu.Item, {
|
7283
|
+
onSelect: ()=>handleActionClick('BulletList', editorRef),
|
7284
|
+
disabled: isDisabled,
|
7285
|
+
children: /*#__PURE__*/ jsxs(Flex, {
|
7286
|
+
tag: "span",
|
7287
|
+
gap: 2,
|
5607
7288
|
children: [
|
5608
|
-
/*#__PURE__*/ jsx(
|
5609
|
-
|
5610
|
-
|
5611
|
-
name: "Bold",
|
5612
|
-
children: /*#__PURE__*/ jsx(Bold, {})
|
7289
|
+
/*#__PURE__*/ jsx(BulletList, {
|
7290
|
+
"aria-hidden": true,
|
7291
|
+
fill: "neutral600"
|
5613
7292
|
}),
|
5614
|
-
|
5615
|
-
|
5616
|
-
|
5617
|
-
|
5618
|
-
|
7293
|
+
formatMessage({
|
7294
|
+
id: 'components.Blocks.blocks.unorderedList',
|
7295
|
+
defaultMessage: 'Bulleted list'
|
7296
|
+
})
|
7297
|
+
]
|
7298
|
+
})
|
7299
|
+
}),
|
7300
|
+
/*#__PURE__*/ jsx(Menu.Item, {
|
7301
|
+
onSelect: ()=>handleActionClick('NumberList', editorRef),
|
7302
|
+
disabled: isDisabled,
|
7303
|
+
children: /*#__PURE__*/ jsxs(Flex, {
|
7304
|
+
tag: "span",
|
7305
|
+
gap: 2,
|
7306
|
+
children: [
|
7307
|
+
/*#__PURE__*/ jsx(NumberList, {
|
7308
|
+
"aria-hidden": true,
|
7309
|
+
fill: "neutral600"
|
5619
7310
|
}),
|
5620
|
-
|
5621
|
-
|
5622
|
-
|
5623
|
-
name: "Underline",
|
5624
|
-
children: /*#__PURE__*/ jsx(Underline, {})
|
7311
|
+
formatMessage({
|
7312
|
+
id: 'components.Blocks.blocks.orderedList',
|
7313
|
+
defaultMessage: 'Numbered list'
|
5625
7314
|
})
|
5626
7315
|
]
|
5627
|
-
}),
|
5628
|
-
/*#__PURE__*/ jsx(MoreButton, {
|
5629
|
-
disabled: true,
|
5630
|
-
label: "More",
|
5631
|
-
children: /*#__PURE__*/ jsx(More, {})
|
5632
7316
|
})
|
5633
|
-
]
|
5634
|
-
}),
|
5635
|
-
!isExpandMode && /*#__PURE__*/ jsx(Button, {
|
5636
|
-
onClick: onTogglePreviewMode,
|
5637
|
-
variant: "tertiary",
|
5638
|
-
children: formatMessage({
|
5639
|
-
id: 'components.Wysiwyg.ToggleMode.markdown-mode',
|
5640
|
-
defaultMessage: 'Markdown mode'
|
5641
7317
|
})
|
5642
|
-
|
5643
|
-
|
5644
|
-
|
5645
|
-
|
5646
|
-
|
5647
|
-
|
5648
|
-
|
5649
|
-
|
5650
|
-
|
5651
|
-
|
5652
|
-
|
7318
|
+
]
|
7319
|
+
}),
|
7320
|
+
key: 'formatting-group-2'
|
7321
|
+
},
|
7322
|
+
{
|
7323
|
+
toolbar: /*#__PURE__*/ jsxs(IconButtonGroup, {
|
7324
|
+
children: [
|
7325
|
+
/*#__PURE__*/ jsx(IconButton, {
|
7326
|
+
disabled: isDisabled,
|
7327
|
+
onClick: ()=>handleActionClick('Code', editorRef),
|
7328
|
+
label: formatMessage({
|
7329
|
+
id: 'components.Wysiwyg.blocks.code',
|
7330
|
+
defaultMessage: 'Code'
|
7331
|
+
}),
|
7332
|
+
name: formatMessage({
|
7333
|
+
id: 'components.Wysiwyg.blocks.code',
|
7334
|
+
defaultMessage: 'Code'
|
7335
|
+
}),
|
7336
|
+
children: /*#__PURE__*/ jsx(Code, {})
|
7337
|
+
}),
|
7338
|
+
/*#__PURE__*/ jsx(IconButton, {
|
7339
|
+
disabled: isDisabled,
|
7340
|
+
onClick: ()=>{
|
7341
|
+
onToggleMediaLib();
|
7342
|
+
},
|
7343
|
+
label: formatMessage({
|
7344
|
+
id: 'components.Blocks.blocks.image',
|
7345
|
+
defaultMessage: 'Image'
|
7346
|
+
}),
|
7347
|
+
name: formatMessage({
|
7348
|
+
id: 'components.Blocks.blocks.image',
|
7349
|
+
defaultMessage: 'Image'
|
7350
|
+
}),
|
7351
|
+
children: /*#__PURE__*/ jsx(Image$1, {})
|
7352
|
+
}),
|
7353
|
+
/*#__PURE__*/ jsx(IconButton, {
|
7354
|
+
disabled: isDisabled,
|
7355
|
+
onClick: ()=>handleActionClick('Link', editorRef),
|
7356
|
+
label: formatMessage({
|
7357
|
+
id: 'components.Blocks.popover.link',
|
7358
|
+
defaultMessage: 'Link'
|
7359
|
+
}),
|
7360
|
+
name: formatMessage({
|
7361
|
+
id: 'components.Blocks.popover.link',
|
7362
|
+
defaultMessage: 'Link'
|
7363
|
+
}),
|
7364
|
+
children: /*#__PURE__*/ jsx(Link$1, {})
|
7365
|
+
}),
|
7366
|
+
/*#__PURE__*/ jsx(IconButton, {
|
7367
|
+
disabled: isDisabled,
|
7368
|
+
onClick: ()=>handleActionClick('Quote', editorRef),
|
7369
|
+
label: formatMessage({
|
7370
|
+
id: 'components.Blocks.blocks.quote',
|
7371
|
+
defaultMessage: 'Quote'
|
7372
|
+
}),
|
7373
|
+
name: formatMessage({
|
7374
|
+
id: 'components.Blocks.blocks.quote',
|
7375
|
+
defaultMessage: 'Quote'
|
7376
|
+
}),
|
7377
|
+
children: /*#__PURE__*/ jsx(Quotes, {})
|
7378
|
+
})
|
7379
|
+
]
|
7380
|
+
}),
|
7381
|
+
menu: /*#__PURE__*/ jsxs(Fragment, {
|
5653
7382
|
children: [
|
5654
|
-
/*#__PURE__*/ jsx(
|
5655
|
-
|
5656
|
-
|
5657
|
-
|
5658
|
-
|
5659
|
-
|
5660
|
-
|
7383
|
+
/*#__PURE__*/ jsx(Menu.Separator, {}),
|
7384
|
+
/*#__PURE__*/ jsx(Menu.Item, {
|
7385
|
+
onSelect: ()=>handleActionClick('Code', editorRef),
|
7386
|
+
disabled: isDisabled,
|
7387
|
+
children: /*#__PURE__*/ jsxs(Flex, {
|
7388
|
+
tag: "span",
|
7389
|
+
gap: 2,
|
5661
7390
|
children: [
|
5662
|
-
/*#__PURE__*/ jsx(
|
5663
|
-
|
5664
|
-
|
5665
|
-
}),
|
5666
|
-
/*#__PURE__*/ jsx(SingleSelectOption, {
|
5667
|
-
value: "h2",
|
5668
|
-
children: "h2"
|
7391
|
+
/*#__PURE__*/ jsx(Code, {
|
7392
|
+
"aria-hidden": true,
|
7393
|
+
fill: "neutral600"
|
5669
7394
|
}),
|
5670
|
-
|
5671
|
-
|
5672
|
-
|
7395
|
+
formatMessage({
|
7396
|
+
id: 'components.Wysiwyg.blocks.code',
|
7397
|
+
defaultMessage: 'Code'
|
7398
|
+
})
|
7399
|
+
]
|
7400
|
+
})
|
7401
|
+
}),
|
7402
|
+
/*#__PURE__*/ jsx(Menu.Item, {
|
7403
|
+
startIcon: /*#__PURE__*/ jsx(Image$1, {}),
|
7404
|
+
onSelect: ()=>{
|
7405
|
+
onToggleMediaLib();
|
7406
|
+
},
|
7407
|
+
disabled: isDisabled,
|
7408
|
+
children: /*#__PURE__*/ jsxs(Flex, {
|
7409
|
+
tag: "span",
|
7410
|
+
gap: 2,
|
7411
|
+
children: [
|
7412
|
+
/*#__PURE__*/ jsx(Image$1, {
|
7413
|
+
"aria-hidden": true,
|
7414
|
+
fill: "neutral600"
|
5673
7415
|
}),
|
5674
|
-
|
5675
|
-
|
5676
|
-
|
7416
|
+
formatMessage({
|
7417
|
+
id: 'components.Blocks.blocks.image',
|
7418
|
+
defaultMessage: 'Image'
|
7419
|
+
})
|
7420
|
+
]
|
7421
|
+
})
|
7422
|
+
}),
|
7423
|
+
/*#__PURE__*/ jsx(Menu.Item, {
|
7424
|
+
startIcon: /*#__PURE__*/ jsx(Link$1, {}),
|
7425
|
+
onSelect: ()=>handleActionClick('Link', editorRef),
|
7426
|
+
disabled: isDisabled,
|
7427
|
+
children: /*#__PURE__*/ jsxs(Flex, {
|
7428
|
+
tag: "span",
|
7429
|
+
gap: 2,
|
7430
|
+
children: [
|
7431
|
+
/*#__PURE__*/ jsx(Link$1, {
|
7432
|
+
"aria-hidden": true,
|
7433
|
+
fill: "neutral600"
|
5677
7434
|
}),
|
5678
|
-
|
5679
|
-
|
5680
|
-
|
7435
|
+
formatMessage({
|
7436
|
+
id: 'components.Blocks.popover.link',
|
7437
|
+
defaultMessage: 'Link'
|
7438
|
+
})
|
7439
|
+
]
|
7440
|
+
})
|
7441
|
+
}),
|
7442
|
+
/*#__PURE__*/ jsx(Menu.Item, {
|
7443
|
+
onSelect: ()=>handleActionClick('Quote', editorRef),
|
7444
|
+
disabled: isDisabled,
|
7445
|
+
children: /*#__PURE__*/ jsxs(Flex, {
|
7446
|
+
tag: "span",
|
7447
|
+
gap: 2,
|
7448
|
+
children: [
|
7449
|
+
/*#__PURE__*/ jsx(Quotes, {
|
7450
|
+
"aria-hidden": true,
|
7451
|
+
fill: "neutral600"
|
5681
7452
|
}),
|
5682
|
-
|
5683
|
-
|
5684
|
-
|
7453
|
+
formatMessage({
|
7454
|
+
id: 'components.Blocks.blocks.quote',
|
7455
|
+
defaultMessage: 'Quote'
|
5685
7456
|
})
|
5686
7457
|
]
|
5687
7458
|
})
|
7459
|
+
})
|
7460
|
+
]
|
7461
|
+
}),
|
7462
|
+
key: 'formatting-group-3'
|
7463
|
+
}
|
7464
|
+
];
|
7465
|
+
return /*#__PURE__*/ jsxs(Flex, {
|
7466
|
+
padding: 2,
|
7467
|
+
background: "neutral100",
|
7468
|
+
justifyContent: "space-between",
|
7469
|
+
borderRadius: "0.4rem 0.4rem 0 0",
|
7470
|
+
width: "100%",
|
7471
|
+
gap: 4,
|
7472
|
+
children: [
|
7473
|
+
/*#__PURE__*/ jsx(Field.Root, {
|
7474
|
+
children: /*#__PURE__*/ jsxs(SingleSelect, {
|
7475
|
+
disabled: isDisabled,
|
7476
|
+
placeholder: formatMessage({
|
7477
|
+
id: 'components.Wysiwyg.selectOptions.title',
|
7478
|
+
defaultMessage: 'Headings'
|
5688
7479
|
}),
|
5689
|
-
|
5690
|
-
|
5691
|
-
|
5692
|
-
|
5693
|
-
|
5694
|
-
|
5695
|
-
|
7480
|
+
"aria-label": formatMessage({
|
7481
|
+
id: 'components.Wysiwyg.selectOptions.title',
|
7482
|
+
defaultMessage: 'Headings'
|
7483
|
+
}),
|
7484
|
+
// @ts-expect-error – DS v2 will only allow strings.
|
7485
|
+
onChange: (value)=>handleActionClick(value, editorRef),
|
7486
|
+
size: "S",
|
7487
|
+
children: [
|
7488
|
+
/*#__PURE__*/ jsx(SingleSelectOption, {
|
7489
|
+
value: "h1",
|
7490
|
+
startIcon: /*#__PURE__*/ jsx(HeadingOne, {
|
7491
|
+
fill: "neutral600"
|
5696
7492
|
}),
|
5697
|
-
|
5698
|
-
|
5699
|
-
|
5700
|
-
|
5701
|
-
|
7493
|
+
children: formatMessage({
|
7494
|
+
id: 'components.Wysiwyg.selectOptions.H1',
|
7495
|
+
defaultMessage: 'Heading 1'
|
7496
|
+
})
|
7497
|
+
}),
|
7498
|
+
/*#__PURE__*/ jsx(SingleSelectOption, {
|
7499
|
+
value: "h2",
|
7500
|
+
startIcon: /*#__PURE__*/ jsx(HeadingTwo, {
|
7501
|
+
fill: "neutral600"
|
5702
7502
|
}),
|
5703
|
-
|
5704
|
-
|
5705
|
-
|
5706
|
-
name: "Underline",
|
5707
|
-
children: /*#__PURE__*/ jsx(Underline, {})
|
7503
|
+
children: formatMessage({
|
7504
|
+
id: 'components.Wysiwyg.selectOptions.H2',
|
7505
|
+
defaultMessage: 'Heading 2'
|
5708
7506
|
})
|
5709
|
-
|
5710
|
-
|
5711
|
-
|
5712
|
-
|
5713
|
-
|
5714
|
-
children: /*#__PURE__*/ jsx(MoreButton, {
|
5715
|
-
label: "More",
|
5716
|
-
children: /*#__PURE__*/ jsx(More, {})
|
5717
|
-
})
|
7507
|
+
}),
|
7508
|
+
/*#__PURE__*/ jsx(SingleSelectOption, {
|
7509
|
+
value: "h3",
|
7510
|
+
startIcon: /*#__PURE__*/ jsx(HeadingThree, {
|
7511
|
+
fill: "neutral600"
|
5718
7512
|
}),
|
5719
|
-
|
5720
|
-
|
5721
|
-
|
5722
|
-
padding: 2,
|
5723
|
-
children: [
|
5724
|
-
/*#__PURE__*/ jsxs(IconButtonGroupMargin, {
|
5725
|
-
children: [
|
5726
|
-
/*#__PURE__*/ jsx(IconButton, {
|
5727
|
-
onClick: ()=>onActionClick('Strikethrough', editorRef, handleTogglePopover),
|
5728
|
-
label: "Strikethrough",
|
5729
|
-
name: "Strikethrough",
|
5730
|
-
children: /*#__PURE__*/ jsx(StrikeThrough, {})
|
5731
|
-
}),
|
5732
|
-
/*#__PURE__*/ jsx(IconButton, {
|
5733
|
-
onClick: ()=>onActionClick('BulletList', editorRef, handleTogglePopover),
|
5734
|
-
label: "BulletList",
|
5735
|
-
name: "BulletList",
|
5736
|
-
children: /*#__PURE__*/ jsx(BulletList, {})
|
5737
|
-
}),
|
5738
|
-
/*#__PURE__*/ jsx(IconButton, {
|
5739
|
-
onClick: ()=>onActionClick('NumberList', editorRef, handleTogglePopover),
|
5740
|
-
label: "NumberList",
|
5741
|
-
name: "NumberList",
|
5742
|
-
children: /*#__PURE__*/ jsx(NumberList, {})
|
5743
|
-
})
|
5744
|
-
]
|
5745
|
-
}),
|
5746
|
-
/*#__PURE__*/ jsxs(IconButtonGroup, {
|
5747
|
-
children: [
|
5748
|
-
/*#__PURE__*/ jsx(IconButton, {
|
5749
|
-
onClick: ()=>onActionClick('Code', editorRef, handleTogglePopover),
|
5750
|
-
label: "Code",
|
5751
|
-
name: "Code",
|
5752
|
-
children: /*#__PURE__*/ jsx(Code, {})
|
5753
|
-
}),
|
5754
|
-
/*#__PURE__*/ jsx(IconButton, {
|
5755
|
-
onClick: ()=>{
|
5756
|
-
handleTogglePopover();
|
5757
|
-
onToggleMediaLib();
|
5758
|
-
},
|
5759
|
-
label: "Image",
|
5760
|
-
name: "Image",
|
5761
|
-
children: /*#__PURE__*/ jsx(Image$1, {})
|
5762
|
-
}),
|
5763
|
-
/*#__PURE__*/ jsx(IconButton, {
|
5764
|
-
onClick: ()=>onActionClick('Link', editorRef, handleTogglePopover),
|
5765
|
-
label: "Link",
|
5766
|
-
name: "Link",
|
5767
|
-
children: /*#__PURE__*/ jsx(Link$1, {})
|
5768
|
-
}),
|
5769
|
-
/*#__PURE__*/ jsx(IconButton, {
|
5770
|
-
onClick: ()=>onActionClick('Quote', editorRef, handleTogglePopover),
|
5771
|
-
label: "Quote",
|
5772
|
-
name: "Quote",
|
5773
|
-
children: /*#__PURE__*/ jsx(Quotes, {})
|
5774
|
-
})
|
5775
|
-
]
|
5776
|
-
})
|
5777
|
-
]
|
5778
|
-
})
|
7513
|
+
children: formatMessage({
|
7514
|
+
id: 'components.Wysiwyg.selectOptions.H3',
|
7515
|
+
defaultMessage: 'Heading 3'
|
5779
7516
|
})
|
5780
|
-
|
7517
|
+
}),
|
7518
|
+
/*#__PURE__*/ jsx(SingleSelectOption, {
|
7519
|
+
value: "h4",
|
7520
|
+
startIcon: /*#__PURE__*/ jsx(HeadingFour, {
|
7521
|
+
fill: "neutral600"
|
7522
|
+
}),
|
7523
|
+
children: formatMessage({
|
7524
|
+
id: 'components.Wysiwyg.selectOptions.H4',
|
7525
|
+
defaultMessage: 'Heading 4'
|
7526
|
+
})
|
7527
|
+
}),
|
7528
|
+
/*#__PURE__*/ jsx(SingleSelectOption, {
|
7529
|
+
value: "h5",
|
7530
|
+
startIcon: /*#__PURE__*/ jsx(HeadingFive, {
|
7531
|
+
fill: "neutral600"
|
7532
|
+
}),
|
7533
|
+
children: formatMessage({
|
7534
|
+
id: 'components.Wysiwyg.selectOptions.H5',
|
7535
|
+
defaultMessage: 'Heading 5'
|
7536
|
+
})
|
7537
|
+
}),
|
7538
|
+
/*#__PURE__*/ jsx(SingleSelectOption, {
|
7539
|
+
value: "h6",
|
7540
|
+
startIcon: /*#__PURE__*/ jsx(HeadingSix, {
|
7541
|
+
fill: "neutral600"
|
7542
|
+
}),
|
7543
|
+
children: formatMessage({
|
7544
|
+
id: 'components.Wysiwyg.selectOptions.H6',
|
7545
|
+
defaultMessage: 'Heading 6'
|
7546
|
+
})
|
7547
|
+
})
|
7548
|
+
]
|
7549
|
+
})
|
7550
|
+
}),
|
7551
|
+
/*#__PURE__*/ jsxs(Flex, {
|
7552
|
+
width: "100%",
|
7553
|
+
justifyContent: "space-between",
|
7554
|
+
overflow: "hidden",
|
7555
|
+
children: [
|
7556
|
+
/*#__PURE__*/ jsx(Flex, {
|
7557
|
+
gap: 2,
|
7558
|
+
overflow: "hidden",
|
7559
|
+
width: "100%",
|
7560
|
+
children: /*#__PURE__*/ jsx(EditorToolbarObserver, {
|
7561
|
+
menuTriggerVariant: "tertiary",
|
7562
|
+
observedComponents: observedComponents
|
7563
|
+
})
|
7564
|
+
}),
|
7565
|
+
onTogglePreviewMode && /*#__PURE__*/ jsx(Button, {
|
7566
|
+
onClick: onTogglePreviewMode,
|
7567
|
+
variant: "tertiary",
|
7568
|
+
minWidth: "132px",
|
7569
|
+
children: isPreviewMode ? formatMessage({
|
7570
|
+
id: 'components.Wysiwyg.ToggleMode.markdown-mode',
|
7571
|
+
defaultMessage: 'Markdown mode'
|
7572
|
+
}) : formatMessage({
|
7573
|
+
id: 'components.Wysiwyg.ToggleMode.preview-mode',
|
7574
|
+
defaultMessage: 'Preview mode'
|
7575
|
+
})
|
5781
7576
|
})
|
5782
7577
|
]
|
5783
|
-
}),
|
5784
|
-
onTogglePreviewMode && /*#__PURE__*/ jsx(Button, {
|
5785
|
-
onClick: onTogglePreviewMode,
|
5786
|
-
variant: "tertiary",
|
5787
|
-
children: formatMessage({
|
5788
|
-
id: 'components.Wysiwyg.ToggleMode.preview-mode',
|
5789
|
-
defaultMessage: 'Preview mode'
|
5790
|
-
})
|
5791
7578
|
})
|
5792
7579
|
]
|
5793
7580
|
});
|
@@ -5808,48 +7595,6 @@ const Wysiwyg = /*#__PURE__*/ React.forwardRef(({ hint, disabled, label, name, p
|
|
5808
7595
|
setIsPreviewMode(false);
|
5809
7596
|
setIsExpandMode((prev)=>!prev);
|
5810
7597
|
};
|
5811
|
-
const handleActionClick = (value, currentEditorRef, togglePopover)=>{
|
5812
|
-
switch(value){
|
5813
|
-
case 'Link':
|
5814
|
-
case 'Strikethrough':
|
5815
|
-
{
|
5816
|
-
markdownHandler(currentEditorRef, value);
|
5817
|
-
togglePopover?.();
|
5818
|
-
break;
|
5819
|
-
}
|
5820
|
-
case 'Code':
|
5821
|
-
case 'Quote':
|
5822
|
-
{
|
5823
|
-
quoteAndCodeHandler(currentEditorRef, value);
|
5824
|
-
togglePopover?.();
|
5825
|
-
break;
|
5826
|
-
}
|
5827
|
-
case 'Bold':
|
5828
|
-
case 'Italic':
|
5829
|
-
case 'Underline':
|
5830
|
-
{
|
5831
|
-
markdownHandler(currentEditorRef, value);
|
5832
|
-
break;
|
5833
|
-
}
|
5834
|
-
case 'BulletList':
|
5835
|
-
case 'NumberList':
|
5836
|
-
{
|
5837
|
-
listHandler(currentEditorRef, value);
|
5838
|
-
togglePopover?.();
|
5839
|
-
break;
|
5840
|
-
}
|
5841
|
-
case 'h1':
|
5842
|
-
case 'h2':
|
5843
|
-
case 'h3':
|
5844
|
-
case 'h4':
|
5845
|
-
case 'h5':
|
5846
|
-
case 'h6':
|
5847
|
-
{
|
5848
|
-
titleHandler(currentEditorRef, value);
|
5849
|
-
break;
|
5850
|
-
}
|
5851
|
-
}
|
5852
|
-
};
|
5853
7598
|
const handleSelectAssets = (files)=>{
|
5854
7599
|
const formattedFiles = files.map((f)=>({
|
5855
7600
|
alt: f.alternativeText || f.name,
|
@@ -5884,7 +7629,6 @@ const Wysiwyg = /*#__PURE__*/ React.forwardRef(({ hint, disabled, label, name, p
|
|
5884
7629
|
isExpandMode: isExpandMode,
|
5885
7630
|
editorRef: editorRef,
|
5886
7631
|
isPreviewMode: isPreviewMode,
|
5887
|
-
onActionClick: handleActionClick,
|
5888
7632
|
onToggleMediaLib: handleToggleMediaLib,
|
5889
7633
|
onTogglePreviewMode: isExpandMode ? undefined : handleTogglePreviewMode,
|
5890
7634
|
disabled: disabled
|
@@ -5928,17 +7672,25 @@ const MemoizedWysiwyg = /*#__PURE__*/ React.memo(Wysiwyg);
|
|
5928
7672
|
* specifically to be used in the EditView of the content-manager this understands
|
5929
7673
|
* the complete EditFieldLayout and will handle RBAC conditions and rendering CM specific
|
5930
7674
|
* components such as Blocks / Relations.
|
5931
|
-
*/ const InputRenderer = ({ visible, hint: providedHint, ...props })=>{
|
5932
|
-
const {
|
5933
|
-
const
|
7675
|
+
*/ const InputRenderer = ({ visible, hint: providedHint, document, ...props })=>{
|
7676
|
+
const { model: rootModel } = useDoc();
|
7677
|
+
const rootDocumentMeta = useDocumentContext('DynamicComponent', (state)=>state.rootDocumentMeta);
|
7678
|
+
const { edit: { components: rootComponents } } = useDocumentLayout(rootDocumentMeta.model);
|
7679
|
+
const { edit: { components: relatedComponents } } = useDocumentLayout(document.schema?.uid ?? rootModel);
|
7680
|
+
const components = {
|
7681
|
+
...rootComponents,
|
7682
|
+
...relatedComponents
|
7683
|
+
};
|
7684
|
+
const collectionType = document.schema?.kind === 'collectionType' ? 'collection-types' : 'single-types';
|
5934
7685
|
const isInDynamicZone = useDynamicZone('isInDynamicZone', (state)=>state.isInDynamicZone);
|
7686
|
+
const isFormDisabled = useForm('InputRenderer', (state)=>state.disabled);
|
5935
7687
|
const canCreateFields = useDocumentRBAC('InputRenderer', (rbac)=>rbac.canCreateFields);
|
5936
7688
|
const canReadFields = useDocumentRBAC('InputRenderer', (rbac)=>rbac.canReadFields);
|
5937
7689
|
const canUpdateFields = useDocumentRBAC('InputRenderer', (rbac)=>rbac.canUpdateFields);
|
5938
7690
|
const canUserAction = useDocumentRBAC('InputRenderer', (rbac)=>rbac.canUserAction);
|
5939
|
-
let idToCheck =
|
7691
|
+
let idToCheck = document.document?.documentId;
|
5940
7692
|
if (collectionType === SINGLE_TYPES) {
|
5941
|
-
idToCheck = document?.documentId;
|
7693
|
+
idToCheck = document?.document?.documentId;
|
5942
7694
|
}
|
5943
7695
|
const editableFields = idToCheck ? canUpdateFields : canCreateFields;
|
5944
7696
|
const readableFields = idToCheck ? canReadFields : canCreateFields;
|
@@ -5952,7 +7704,6 @@ const MemoizedWysiwyg = /*#__PURE__*/ React.memo(Wysiwyg);
|
|
5952
7704
|
props.attribute.customField
|
5953
7705
|
] : undefined);
|
5954
7706
|
const hint = useFieldHint(providedHint, props.attribute);
|
5955
|
-
const { edit: { components } } = useDocLayout();
|
5956
7707
|
// We pass field in case of Custom Fields to keep backward compatibility
|
5957
7708
|
const field = useField(props.name);
|
5958
7709
|
if (!visible) {
|
@@ -6126,7 +7877,7 @@ const getMinMax = (attribute)=>{
|
|
6126
7877
|
};
|
6127
7878
|
}
|
6128
7879
|
};
|
6129
|
-
const MemoizedInputRenderer = /*#__PURE__*/ memo(InputRenderer);
|
7880
|
+
const MemoizedInputRenderer = /*#__PURE__*/ React.memo(InputRenderer);
|
6130
7881
|
|
6131
7882
|
const RESPONSIVE_CONTAINER_BREAKPOINTS = {
|
6132
7883
|
sm: '27.5rem'
|
@@ -6134,16 +7885,22 @@ const RESPONSIVE_CONTAINER_BREAKPOINTS = {
|
|
6134
7885
|
const ResponsiveGridRoot = styled(Grid$1.Root)`
|
6135
7886
|
container-type: inline-size;
|
6136
7887
|
`;
|
6137
|
-
const ResponsiveGridItem =
|
6138
|
-
|
6139
|
-
|
6140
|
-
|
6141
|
-
|
6142
|
-
|
6143
|
-
|
6144
|
-
|
7888
|
+
const ResponsiveGridItem = /**
|
7889
|
+
* TODO:
|
7890
|
+
* JSDOM cannot handle container queries.
|
7891
|
+
* This is a temporary workaround so that tests do not fail in the CI when jestdom throws an error
|
7892
|
+
* for failing to parse the stylesheet.
|
7893
|
+
*/ process.env.NODE_ENV !== 'test' ? styled(Grid$1.Item)`
|
7894
|
+
grid-column: span 12;
|
7895
|
+
@container (min-width: ${RESPONSIVE_CONTAINER_BREAKPOINTS.sm}) {
|
7896
|
+
${({ col })=>col && `grid-column: span ${col};`}
|
7897
|
+
}
|
7898
|
+
` : styled(Grid$1.Item)`
|
7899
|
+
grid-column: span 12;
|
7900
|
+
`;
|
7901
|
+
const FormLayout = ({ layout, document, hasBackground = true })=>{
|
6145
7902
|
const { formatMessage } = useIntl();
|
6146
|
-
const
|
7903
|
+
const model = document.schema?.modelName;
|
6147
7904
|
return /*#__PURE__*/ jsx(Flex, {
|
6148
7905
|
direction: "column",
|
6149
7906
|
alignItems: "stretch",
|
@@ -6168,20 +7925,20 @@ const FormLayout = ({ layout })=>{
|
|
6168
7925
|
direction: "column",
|
6169
7926
|
alignItems: "stretch",
|
6170
7927
|
children: /*#__PURE__*/ jsx(MemoizedInputRenderer, {
|
6171
|
-
...fieldWithTranslatedLabel
|
7928
|
+
...fieldWithTranslatedLabel,
|
7929
|
+
document: document
|
6172
7930
|
})
|
6173
7931
|
})
|
6174
7932
|
}, field.name);
|
6175
7933
|
}
|
6176
7934
|
return /*#__PURE__*/ jsx(Box, {
|
6177
|
-
|
6178
|
-
|
6179
|
-
|
6180
|
-
|
6181
|
-
|
6182
|
-
|
6183
|
-
|
6184
|
-
borderColor: "neutral150",
|
7935
|
+
...hasBackground && {
|
7936
|
+
padding: 6,
|
7937
|
+
borderColor: 'neutral150',
|
7938
|
+
background: 'neutral0',
|
7939
|
+
hasRadius: true,
|
7940
|
+
shadow: 'tableShadow'
|
7941
|
+
},
|
6185
7942
|
children: /*#__PURE__*/ jsx(Flex, {
|
6186
7943
|
direction: "column",
|
6187
7944
|
alignItems: "stretch",
|
@@ -6203,7 +7960,8 @@ const FormLayout = ({ layout })=>{
|
|
6203
7960
|
direction: "column",
|
6204
7961
|
alignItems: "stretch",
|
6205
7962
|
children: /*#__PURE__*/ jsx(MemoizedInputRenderer, {
|
6206
|
-
...fieldWithTranslatedLabel
|
7963
|
+
...fieldWithTranslatedLabel,
|
7964
|
+
document: document
|
6207
7965
|
})
|
6208
7966
|
}, field.name);
|
6209
7967
|
})
|
@@ -6219,6 +7977,7 @@ const NonRepeatableComponent = ({ attribute, name, children, layout })=>{
|
|
6219
7977
|
const { value } = useField(name);
|
6220
7978
|
const level = useComponent('NonRepeatableComponent', (state)=>state.level);
|
6221
7979
|
const isNested = level > 0;
|
7980
|
+
const currentDocument = useDocumentContext('NonRepeatableComponent', (state)=>state.document);
|
6222
7981
|
return /*#__PURE__*/ jsx(ComponentProvider, {
|
6223
7982
|
id: value?.id,
|
6224
7983
|
uid: attribute.component,
|
@@ -6259,7 +8018,8 @@ const NonRepeatableComponent = ({ attribute, name, children, layout })=>{
|
|
6259
8018
|
children: children({
|
6260
8019
|
...field,
|
6261
8020
|
label: translatedLabel,
|
6262
|
-
name: completeFieldName
|
8021
|
+
name: completeFieldName,
|
8022
|
+
document: currentDocument
|
6263
8023
|
})
|
6264
8024
|
}, completeFieldName);
|
6265
8025
|
})
|
@@ -6277,7 +8037,8 @@ const RepeatableComponent = ({ attribute, disabled, name, mainField, children, l
|
|
6277
8037
|
const search = React.useMemo(()=>new URLSearchParams(searchString), [
|
6278
8038
|
searchString
|
6279
8039
|
]);
|
6280
|
-
const
|
8040
|
+
const currentDocument = useDocumentContext('RepeatableComponent', (state)=>state.document);
|
8041
|
+
const components = currentDocument.components;
|
6281
8042
|
const { value = [], error, rawError } = useField(name);
|
6282
8043
|
const addFieldRow = useForm('RepeatableComponent', (state)=>state.addFieldRow);
|
6283
8044
|
const moveFieldRow = useForm('RepeatableComponent', (state)=>state.moveFieldRow);
|
@@ -6480,7 +8241,8 @@ const RepeatableComponent = ({ attribute, disabled, name, mainField, children, l
|
|
6480
8241
|
children: children({
|
6481
8242
|
...field,
|
6482
8243
|
label: translatedLabel,
|
6483
|
-
name: completeFieldName
|
8244
|
+
name: completeFieldName,
|
8245
|
+
document: currentDocument
|
6484
8246
|
})
|
6485
8247
|
}, completeFieldName);
|
6486
8248
|
})
|
@@ -6642,7 +8404,7 @@ const ComponentInput = ({ label, required, name, attribute, disabled, labelActio
|
|
6642
8404
|
const { formatMessage } = useIntl();
|
6643
8405
|
const field = useField(name);
|
6644
8406
|
const showResetComponent = !attribute.repeatable && field.value && !disabled;
|
6645
|
-
const
|
8407
|
+
const components = useDocumentContext('ComponentInput', (state)=>state.document.components);
|
6646
8408
|
const handleInitialisationClick = ()=>{
|
6647
8409
|
const schema = components[attribute.component];
|
6648
8410
|
const form = createDefaultForm(schema, components);
|
@@ -6707,5 +8469,5 @@ const ComponentInput = ({ label, required, name, attribute, disabled, labelActio
|
|
6707
8469
|
};
|
6708
8470
|
const MemoizedComponentInput = /*#__PURE__*/ React.memo(ComponentInput);
|
6709
8471
|
|
6710
|
-
export {
|
6711
|
-
//# sourceMappingURL=Input-
|
8472
|
+
export { DisconnectButton as D, FlexWrapper as F, LinkEllipsis as L, MemoizedUIDInput as M, NotAllowedInput as N, FormLayout as a, useDynamicZone as b, useFieldHint as c, MemoizedWysiwyg as d, DynamicZone as e, MemoizedComponentInput as f, MemoizedBlocksInput as g, useLazyComponents as u };
|
8473
|
+
//# sourceMappingURL=Input-B3QUS9rv.mjs.map
|