@plone/volto 19.0.0-alpha.2 → 19.0.0-alpha.20
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/.eslintignore +1 -0
- package/.eslintrc +37 -3
- package/CHANGELOG.md +338 -1
- package/README.md +20 -16
- package/babel.js +1 -3
- package/cypress/docker/prefixed-rules.yml +26 -0
- package/cypress/docker/prefixed.yml +24 -0
- package/cypress/support/commands.js +12 -6
- package/cypress/support/guillotina.js +1 -0
- package/cypress.config.js +1 -0
- package/global-test-setup.js +1 -2
- package/locales/af.json +1 -0
- package/locales/ar.json +1 -0
- package/locales/bg.json +1 -0
- package/locales/bn.json +1 -0
- package/locales/ca/LC_MESSAGES/volto.po +124 -17
- package/locales/ca.json +1 -1
- package/locales/cs.json +1 -0
- package/locales/cy.json +1 -0
- package/locales/da.json +1 -0
- package/locales/de/LC_MESSAGES/volto.po +135 -28
- package/locales/de.json +1 -1
- package/locales/el.json +1 -0
- package/locales/en/LC_MESSAGES/volto.po +125 -18
- package/locales/en.json +1 -1
- package/locales/en_AU.json +1 -0
- package/locales/en_GB.json +1 -0
- package/locales/eo.json +1 -0
- package/locales/es/LC_MESSAGES/volto.po +125 -18
- package/locales/es.json +1 -1
- package/locales/et.json +1 -0
- package/locales/eu/LC_MESSAGES/volto.po +124 -17
- package/locales/eu.json +1 -1
- package/locales/fa.json +1 -0
- package/locales/fi/LC_MESSAGES/volto.po +124 -17
- package/locales/fi.json +1 -1
- package/locales/fr/LC_MESSAGES/volto.po +125 -18
- package/locales/fr.json +1 -1
- package/locales/fu.json +1 -0
- package/locales/gl.json +1 -0
- package/locales/he.json +1 -0
- package/locales/hi/LC_MESSAGES/volto.po +128 -21
- package/locales/hi.json +1 -1
- package/locales/hr.json +1 -0
- package/locales/hu.json +1 -0
- package/locales/hy.json +1 -0
- package/locales/id.json +1 -0
- package/locales/it/LC_MESSAGES/volto.po +129 -22
- package/locales/it.json +1 -1
- package/locales/ja/LC_MESSAGES/volto.po +124 -17
- package/locales/ja.json +1 -1
- package/locales/ka.json +1 -0
- package/locales/kn.json +1 -0
- package/locales/ko.json +1 -0
- package/locales/lt.json +1 -0
- package/locales/lv.json +1 -0
- package/locales/mi.json +1 -0
- package/locales/mk.json +1 -0
- package/locales/my.json +1 -0
- package/locales/nb_NO.json +1 -0
- package/locales/nl/LC_MESSAGES/volto.po +128 -21
- package/locales/nl.json +1 -1
- package/locales/nn.json +1 -0
- package/locales/pl.json +1 -0
- package/locales/pt/LC_MESSAGES/volto.po +124 -17
- package/locales/pt.json +1 -1
- package/locales/pt_BR/LC_MESSAGES/volto.po +147 -40
- package/locales/pt_BR.json +1 -1
- package/locales/rm.json +1 -0
- package/locales/ro/LC_MESSAGES/volto.po +128 -21
- package/locales/ro.json +1 -1
- package/locales/ru/LC_MESSAGES/volto.po +128 -21
- package/locales/ru.json +1 -1
- package/locales/sk.json +1 -0
- package/locales/sl.json +1 -0
- package/locales/sm.json +1 -0
- package/locales/sq.json +1 -0
- package/locales/sr.json +1 -0
- package/locales/sr@cyrl.json +1 -0
- package/locales/sr@latn.json +1 -0
- package/locales/sv.json +1 -1
- package/locales/ta.json +1 -0
- package/locales/te.json +1 -0
- package/locales/th.json +1 -0
- package/locales/to.json +1 -0
- package/locales/tr.json +1 -0
- package/locales/uk.json +1 -0
- package/locales/vi.json +1 -0
- package/locales/volto.pot +125 -18
- package/locales/zh_CN/LC_MESSAGES/volto.po +124 -17
- package/locales/zh_CN.json +1 -1
- package/locales/zh_Hant.json +1 -0
- package/locales/zh_Hant_HK.json +1 -0
- package/package.json +43 -100
- package/razzle.config.js +21 -21
- package/src/actions/content/content.js +0 -1
- package/src/actions/controlpanels/controlpanels.js +13 -7
- package/src/actions/controlpanels/controlpanels.test.js +11 -5
- package/src/actions/users/users.js +2 -2
- package/src/components/manage/Actions/Actions.test.jsx +1 -5
- package/src/components/manage/Add/Add.jsx +5 -6
- package/src/components/manage/BlockChooser/BlockChooser.jsx +1 -0
- package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +1 -5
- package/src/components/manage/Blocks/Block/Edit.jsx +1 -0
- package/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +9 -4
- package/src/components/manage/Blocks/Block/Settings.test.jsx +1 -5
- package/src/components/manage/Blocks/HTML/Edit.test.jsx +1 -5
- package/src/components/manage/Blocks/Image/Edit.jsx +5 -1
- package/src/components/manage/Blocks/Image/ImageSidebar.test.jsx +1 -5
- package/src/components/manage/Blocks/LeadImage/Edit.jsx +2 -2
- package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx +1 -1
- package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +1 -5
- package/src/components/manage/Blocks/Listing/ImageGallery.jsx +6 -4
- package/src/components/manage/Blocks/Maps/Edit.jsx +2 -1
- package/src/components/manage/Blocks/Maps/MapsSidebar.test.jsx +1 -5
- package/src/components/manage/Blocks/Search/SearchBlockView.jsx +21 -4
- package/src/components/manage/Blocks/Search/components/DateRangeFacet.test.jsx +1 -6
- package/src/components/manage/Blocks/Search/components/SelectFacet.test.jsx +1 -6
- package/src/components/manage/Blocks/Teaser/Data.jsx +21 -7
- package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +1 -1
- package/src/components/manage/Blocks/Teaser/schema.js +8 -3
- package/src/components/manage/Blocks/Video/Edit.jsx +2 -1
- package/src/components/manage/Blocks/Video/VideoSidebar.test.jsx +1 -5
- package/src/components/manage/Contents/Contents.jsx +689 -654
- package/src/components/manage/Contents/Contents.test.jsx +8 -5
- package/src/components/manage/Contents/ContentsBreadcrumbs.Multilingual.test.jsx +18 -5
- package/src/components/manage/Contents/ContentsBreadcrumbs.jsx +20 -26
- package/src/components/manage/Contents/ContentsBreadcrumbs.test.jsx +14 -0
- package/src/components/manage/Contents/ContentsDeleteModal.jsx +258 -206
- package/src/components/manage/Contents/ContentsDeleteModal.stories.jsx +26 -8
- package/src/components/manage/Contents/ContentsItem.jsx +10 -2
- package/src/components/manage/Contents/ContentsPropertiesModal.test.jsx +1 -5
- package/src/components/manage/Contents/ContentsRenameModal.test.jsx +1 -5
- package/src/components/manage/Contents/ContentsTagsModal.test.jsx +1 -5
- package/src/components/manage/Contents/ContentsUploadModal.test.jsx +13 -22
- package/src/components/manage/Contents/ContentsWorkflowModal.test.jsx +1 -5
- package/src/components/manage/Contents/DropZoneContent.jsx +323 -0
- package/src/components/manage/Contents/__mocks__/index.tsx +2 -18
- package/src/components/manage/Controlpanels/Aliases.test.jsx +1 -5
- package/src/components/manage/Controlpanels/ContentType.jsx +1 -1
- package/src/components/manage/Controlpanels/ContentType.test.jsx +1 -5
- package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.jsx +3 -2
- package/src/components/manage/Controlpanels/Relations/Relations.jsx +1 -1
- package/src/components/manage/Controlpanels/Rules/AddRule.test.jsx +1 -5
- package/src/components/manage/Controlpanels/Rules/EditRule.test.jsx +1 -5
- package/src/components/manage/Controlpanels/UndoControlpanel.test.jsx +1 -5
- package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +156 -175
- package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +575 -630
- package/src/components/manage/Controlpanels/Users/UsersControlpanel.test.jsx +4 -3
- package/src/components/manage/Diff/Diff.test.jsx +1 -6
- package/src/components/manage/Diff/DiffField.test.jsx +1 -6
- package/src/components/manage/Display/Display.test.jsx +2 -11
- package/src/components/manage/Edit/Edit.jsx +2 -3
- package/src/components/manage/Edit/Edit.test.jsx +1 -5
- package/src/components/manage/Form/BlockDataForm.test.jsx +1 -5
- package/src/components/manage/Form/Form.test.jsx +1 -5
- package/src/components/manage/Form/InlineForm.jsx +2 -2
- package/src/components/manage/Form/InlineForm.test.jsx +1 -5
- package/src/components/manage/Form/ModalForm.jsx +12 -10
- package/src/components/manage/Form/ModalForm.test.jsx +27 -5
- package/src/components/manage/Form/__mocks__/index.tsx +9 -27
- package/src/components/manage/Multilingual/CompareLanguages.jsx +2 -5
- package/src/components/manage/Multilingual/CreateTranslation.jsx +8 -8
- package/src/components/manage/Multilingual/ManageTranslations.jsx +4 -2
- package/src/components/manage/Multilingual/ManageTranslations.test.jsx +5 -1
- package/src/components/manage/Multilingual/TranslationObject.jsx +1 -1
- package/src/components/manage/Preferences/ChangePassword.test.jsx +1 -5
- package/src/components/manage/Preferences/PersonalPreferences.test.jsx +1 -17
- package/src/components/manage/Sidebar/ObjectBrowser.jsx +3 -0
- package/src/components/manage/Sidebar/ObjectBrowserBody.jsx +13 -1
- package/src/components/manage/Sidebar/ObjectBrowserNav.jsx +2 -1
- package/src/components/manage/Sidebar/SidebarPortal.test.tsx +42 -0
- package/src/components/manage/Sidebar/SidebarPortal.tsx +48 -0
- package/src/components/manage/TemplateChooser/TemplateChooser.jsx +2 -1
- package/src/components/manage/Toolbar/More.jsx +4 -1
- package/src/components/manage/Toolbar/More.test.jsx +3 -0
- package/src/components/manage/Toolbar/PersonalTools.jsx +2 -1
- package/src/components/manage/Toolbar/Toolbar.jsx +3 -4
- package/src/components/manage/Toolbar/Types.jsx +7 -7
- package/src/components/manage/UniversalLink/UniversalLink.tsx +1 -0
- package/src/components/manage/Widgets/AlignWidget.stories.jsx +9 -0
- package/src/components/manage/Widgets/AlignWidget.test.tsx +95 -0
- package/src/components/manage/Widgets/{AlignWidget.jsx → AlignWidget.tsx} +23 -7
- package/src/components/manage/Widgets/ArrayWidget.test.jsx +1 -6
- package/src/components/manage/Widgets/BlockAlignment.stories.tsx +104 -0
- package/src/components/manage/Widgets/BlockAlignment.test.tsx +104 -0
- package/src/components/manage/Widgets/BlockAlignment.tsx +88 -0
- package/src/components/manage/Widgets/BlockWidth.stories.tsx +69 -0
- package/src/components/manage/Widgets/BlockWidth.test.tsx +62 -0
- package/src/components/manage/Widgets/BlockWidth.tsx +101 -0
- package/src/components/manage/Widgets/ButtonsWidget.stories.jsx +61 -0
- package/src/components/manage/Widgets/ButtonsWidget.test.tsx +138 -0
- package/src/components/manage/Widgets/ButtonsWidget.tsx +176 -0
- package/src/components/manage/Widgets/CheckboxGroupWidget.test.jsx +1 -6
- package/src/components/manage/Widgets/DatetimeWidget.jsx +16 -1
- package/src/components/manage/Widgets/DatetimeWidget.test.jsx +1 -6
- package/src/components/manage/Widgets/FileWidget.jsx +14 -8
- package/src/components/manage/Widgets/FormFieldWrapper.jsx +146 -168
- package/src/components/manage/Widgets/ImageWidget.jsx +171 -38
- package/src/components/manage/Widgets/InternalUrlWidget.jsx +2 -0
- package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +8 -0
- package/src/components/manage/Widgets/ObjectListWidget.test.jsx +2 -11
- package/src/components/manage/Widgets/ObjectWidget.test.jsx +1 -5
- package/src/components/manage/Widgets/QueryWidget.jsx +137 -9
- package/src/components/manage/Widgets/RadioGroupWidget.test.jsx +1 -6
- package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.test.jsx +1 -6
- package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +3 -2
- package/src/components/manage/Widgets/SchemaWidget.test.jsx +1 -6
- package/src/components/manage/Widgets/SchemaWidgetFieldset.test.jsx +1 -6
- package/src/components/manage/Widgets/SelectAutoComplete.jsx +29 -12
- package/src/components/manage/Widgets/SelectAutoComplete.test.jsx +1 -6
- package/src/components/manage/Widgets/SelectWidget.test.jsx +1 -6
- package/src/components/manage/Widgets/Size.stories.tsx +69 -0
- package/src/components/manage/Widgets/Size.test.tsx +59 -0
- package/src/components/manage/Widgets/Size.tsx +78 -0
- package/src/components/manage/Widgets/TimeWidget.test.jsx +1 -6
- package/src/components/manage/Widgets/TokenWidget.test.jsx +1 -6
- package/src/components/manage/Widgets/UrlWidget.jsx +2 -0
- package/src/components/manage/Widgets/VocabularyTermsWidget.test.jsx +2 -11
- package/src/components/manage/Widgets/__mocks__/index.tsx +33 -51
- package/src/components/manage/Widgets/index.tsx +21 -0
- package/src/components/manage/Workflow/Workflow.test.jsx +2 -11
- package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.jsx +1 -3
- package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.test.jsx +0 -4
- package/src/components/theme/App/App.jsx +5 -1
- package/src/components/theme/App/App.test.jsx +1 -0
- package/src/components/theme/Avatar/Avatar.jsx +2 -1
- package/src/components/theme/Comments/CommentEditModal.test.jsx +1 -5
- package/src/components/theme/Comments/Comments.test.jsx +2 -11
- package/src/components/theme/ContactForm/ContactForm.test.jsx +1 -5
- package/src/components/theme/FormattedDate/FormattedDate.stories.jsx +20 -2
- package/src/components/theme/Image/Image.jsx +11 -8
- package/src/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.tsx +7 -0
- package/src/components/theme/LanguageSelector/{LanguageSelector.test.jsx → LanguageSelector.test.tsx} +6 -6
- package/src/components/theme/LanguageSelector/LanguageSelector.tsx +89 -0
- package/src/components/theme/Logo/Logo.Multilingual.test.jsx +0 -5
- package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +10 -14
- package/src/components/theme/MultilingualRedirector/MultilingualRedirector.test.jsx +3 -5
- package/src/components/theme/Navigation/NavItem.jsx +1 -5
- package/src/components/theme/Navigation/Navigation.Multilingual.test.jsx +0 -5
- package/src/components/theme/NotFound/NotFound.jsx +5 -2
- package/src/components/theme/NotFound/NotFound.test.jsx +3 -0
- package/src/components/theme/PasswordReset/RequestPasswordReset.test.jsx +1 -5
- package/src/components/theme/PreviewImage/PreviewImage.jsx +1 -1
- package/src/components/theme/Register/Register.test.jsx +1 -5
- package/src/components/theme/RequestTimeout/RequestTimeout.jsx +1 -1
- package/src/components/theme/Sitemap/Sitemap.jsx +6 -5
- package/src/components/theme/Sitemap/Sitemap.test.jsx +0 -1
- package/src/components/theme/Unauthorized/Unauthorized.jsx +5 -2
- package/src/components/theme/View/EventDatesInfo.test.jsx +1 -6
- package/src/components/theme/View/EventView.test.jsx +1 -6
- package/src/components/theme/View/FileView.jsx +9 -1
- package/src/components/theme/View/View.jsx +8 -1
- package/src/components/theme/Widgets/ImageWidget.jsx +2 -1
- package/src/config/ControlPanels.js +1 -0
- package/src/config/Widgets.jsx +7 -0
- package/src/config/index.js +18 -25
- package/src/config/server.js +0 -2
- package/src/config/slots.js +19 -0
- package/src/express-middleware/devproxy.js +20 -5
- package/src/helpers/Api/APIResourceWithAuth.js +8 -3
- package/src/helpers/Api/Api.js +7 -4
- package/src/helpers/AsyncConnect/ssr.js +4 -1
- package/src/helpers/Content/Content.js +23 -0
- package/src/helpers/Content/Content.test.js +39 -0
- package/src/helpers/Content/withClientSideContent.jsx +35 -0
- package/src/helpers/Extensions/withBlockSchemaEnhancer.jsx +4 -1
- package/src/helpers/Html/Html.jsx +13 -7
- package/src/helpers/LanguageMap/LanguageMap.js +115 -8
- package/src/helpers/Loadable/__mocks__/Loadable.jsx +7 -22
- package/src/helpers/MessageLabels/MessageLabels.js +5 -0
- package/src/helpers/Sitemap/Sitemap.js +4 -4
- package/src/helpers/Url/Url.js +33 -2
- package/src/helpers/Url/Url.test.js +62 -0
- package/src/hooks/user/useUser.js +1 -1
- package/src/internalChecks.test.ts +11 -0
- package/src/middleware/Api.test.js +4 -0
- package/src/middleware/api.js +82 -28
- package/src/middleware/storeProtectLoadUtils.test.js +3 -3
- package/src/reducers/content/content.js +3 -18
- package/src/reducers/diff/diff.js +5 -1
- package/src/reducers/diff/diff.test.js +60 -4
- package/src/reducers/querystring/querystring.js +8 -1
- package/src/routes.js +4 -2
- package/src/server.jsx +45 -14
- package/src/start-client.jsx +9 -6
- package/src/start-server.js +9 -3
- package/test-addons-loader.js +3 -0
- package/test-setup-config.jsx +0 -2
- package/test-setup-globals.js +30 -2
- package/theme/themes/pastanaga/extras/blocks.less +26 -0
- package/theme/themes/pastanaga/extras/contents.less +80 -5
- package/theme/themes/pastanaga/extras/main.less +17 -2
- package/theme/themes/pastanaga/extras/widgets.less +79 -0
- package/tsconfig.declarations.json +1 -1
- package/tsconfig.json +4 -5
- package/types/components/manage/Blocks/Teaser/schema.d.ts +1 -0
- package/types/components/manage/Contents/DropZoneContent.d.ts +2 -0
- package/types/components/manage/Contents/__mocks__/index.d.ts +2 -2
- package/types/components/manage/Controlpanels/Relations/RelationsMatrix.d.ts +1 -1
- package/types/components/manage/Controlpanels/Users/RenderUsers.d.ts +18 -2
- package/types/components/manage/Controlpanels/Users/UsersControlpanel.d.ts +6 -2
- package/types/components/manage/Controlpanels/index.d.ts +2 -2
- package/types/components/manage/Form/__mocks__/index.d.ts +8 -8
- package/types/components/manage/Multilingual/ManageTranslations.d.ts +1 -1
- package/types/components/manage/Sidebar/ObjectBrowser.d.ts +1 -1
- package/types/components/manage/Sidebar/SidebarPortal.d.ts +7 -15
- package/types/components/manage/Widgets/AlignWidget.d.ts +8 -10
- package/types/components/manage/Widgets/AlignWidget.stories.d.ts +1 -0
- package/types/components/manage/Widgets/BlockAlignment.d.ts +7 -0
- package/types/components/manage/Widgets/BlockAlignment.stories.d.ts +8 -0
- package/types/components/manage/Widgets/BlockWidth.d.ts +7 -0
- package/types/components/manage/Widgets/BlockWidth.stories.d.ts +6 -0
- package/types/components/manage/Widgets/ButtonsWidget.d.ts +48 -1
- package/types/components/manage/Widgets/ButtonsWidget.stories.d.ts +3 -0
- package/types/components/manage/Widgets/FormFieldWrapper.d.ts +28 -5
- package/types/components/manage/Widgets/ImageWidget.d.ts +41 -1
- package/types/components/manage/Widgets/InternalUrlWidget.d.ts +1 -1
- package/types/components/manage/Widgets/ObjectBrowserWidget.d.ts +2 -0
- package/types/components/manage/Widgets/QueryWidget.d.ts +5 -2
- package/types/components/manage/Widgets/RecurrenceWidget/Utils.d.ts +12 -18
- package/types/components/manage/Widgets/Size.d.ts +7 -0
- package/types/components/manage/Widgets/Size.stories.d.ts +6 -0
- package/types/components/manage/Widgets/UrlWidget.d.ts +1 -1
- package/types/components/manage/Widgets/__mocks__/index.d.ts +33 -33
- package/types/components/manage/Widgets/index.d.ts +11 -6
- package/types/components/theme/FormattedDate/FormattedDate.stories.d.ts +1 -1
- package/types/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.d.ts +3 -0
- package/types/components/theme/LanguageSelector/LanguageSelector.d.ts +3 -10
- package/types/components/theme/Unauthorized/Unauthorized.d.ts +2 -2
- package/types/config/Widgets.d.ts +6 -0
- package/types/config/slots.d.ts +7 -0
- package/types/helpers/Content/Content.d.ts +7 -0
- package/types/helpers/Content/withClientSideContent.d.ts +1 -0
- package/types/helpers/Extensions/withBlockSchemaEnhancer.d.ts +4 -5
- package/types/helpers/Helmet/Helmet.d.ts +1 -1
- package/types/helpers/LanguageMap/LanguageMap.d.ts +428 -4
- package/types/helpers/Loadable/__mocks__/Loadable.d.ts +2 -2
- package/types/helpers/MessageLabels/MessageLabels.d.ts +68 -62
- package/types/helpers/Url/Url.d.ts +14 -0
- package/types/helpers/Url/bulkFlattenToAppURL.d.ts +5 -0
- package/types/middleware/api.d.ts +6 -9
- package/types/reducers/index.d.ts +1 -0
- package/types/start-client.d.ts +0 -1
- package/vitest.config.mjs +4 -4
- package/webpack-plugins/webpack-scss-plugin.js +172 -0
- package/jest-addons-loader.js +0 -3
- package/jest-extender-plugin.js +0 -39
- package/jest-setup-afterenv.js +0 -2
- package/jest-svgsystem-transform.js +0 -10
- package/package-why.json +0 -34
- package/patches/patchit.sh +0 -2
- package/patches/razzle-jest.patch +0 -10
- package/src/actions/content/content.multilingual.test.js +0 -17
- package/src/components/manage/Contents/__mocks__/index.vitest.tsx +0 -5
- package/src/components/manage/Form/__mocks__/index.vitest.tsx +0 -73
- package/src/components/manage/Sidebar/SidebarPortal.jsx +0 -47
- package/src/components/manage/Sidebar/SidebarPortal.test.jsx +0 -26
- package/src/components/manage/Widgets/AlignWidget.test.jsx +0 -59
- package/src/components/manage/Widgets/ButtonsWidget.jsx +0 -41
- package/src/components/manage/Widgets/ButtonsWidget.test.jsx +0 -70
- package/src/components/manage/Widgets/__mocks__/index.vitest.tsx +0 -41
- package/src/components/theme/LanguageSelector/LanguageSelector.jsx +0 -77
- package/src/helpers/Loadable/__mocks__/Loadable.vitest.jsx +0 -39
- package/test-setup-globals-vitest.js +0 -46
- package/theme/themes/pastanaga/extras/utils.less +0 -63
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import { Button, Dimmer, Loader, Message } from 'semantic-ui-react';
|
|
3
3
|
import { useIntl, defineMessages } from 'react-intl';
|
|
4
|
-
import { useDispatch } from 'react-redux';
|
|
4
|
+
import { useDispatch, useSelector } from 'react-redux';
|
|
5
5
|
import { useLocation } from 'react-router-dom';
|
|
6
6
|
import loadable from '@loadable/component';
|
|
7
7
|
import { connect } from 'react-redux';
|
|
@@ -9,11 +9,15 @@ import { compose } from 'redux';
|
|
|
9
9
|
import { toast } from 'react-toastify';
|
|
10
10
|
import useLinkEditor from '@plone/volto/components/manage/AnchorPlugin/useLinkEditor';
|
|
11
11
|
import withObjectBrowser from '@plone/volto/components/manage/Sidebar/ObjectBrowser';
|
|
12
|
+
import config from '@plone/volto/registry';
|
|
12
13
|
|
|
13
14
|
import {
|
|
14
15
|
flattenToAppURL,
|
|
15
16
|
getBaseUrl,
|
|
17
|
+
getParentUrl,
|
|
16
18
|
isInternalURL,
|
|
19
|
+
normalizeUrl,
|
|
20
|
+
removeProtocol,
|
|
17
21
|
} from '@plone/volto/helpers/Url/Url';
|
|
18
22
|
import { validateFileUploadSize } from '@plone/volto/helpers/FormValidation/FormValidation';
|
|
19
23
|
import { usePrevious } from '@plone/volto/helpers/Utils/usePrevious';
|
|
@@ -28,6 +32,9 @@ import clearSVG from '@plone/volto/icons/clear.svg';
|
|
|
28
32
|
import navTreeSVG from '@plone/volto/icons/nav.svg';
|
|
29
33
|
import linkSVG from '@plone/volto/icons/link.svg';
|
|
30
34
|
import uploadSVG from '@plone/volto/icons/upload.svg';
|
|
35
|
+
import Image from '../../theme/Image/Image';
|
|
36
|
+
import { urlValidator } from '@plone/volto/helpers/FormValidation/validators';
|
|
37
|
+
import { searchContent } from '@plone/volto/actions/search/search';
|
|
31
38
|
|
|
32
39
|
const Dropzone = loadable(() => import('react-dropzone'));
|
|
33
40
|
|
|
@@ -70,6 +77,14 @@ const messages = defineMessages({
|
|
|
70
77
|
id: 'imageUploadErrorMessage',
|
|
71
78
|
defaultMessage: 'Please upload an image instead.',
|
|
72
79
|
},
|
|
80
|
+
externalURLsNotAllowed: {
|
|
81
|
+
id: 'externalURLsNotAllowed',
|
|
82
|
+
defaultMessage: 'External URLs are not allowed in this field.',
|
|
83
|
+
},
|
|
84
|
+
internalImageNotFoundErrorMessage: {
|
|
85
|
+
id: 'internalImageNotFoundErrorMessage',
|
|
86
|
+
defaultMessage: 'No image was found in the internal path you provided.',
|
|
87
|
+
},
|
|
73
88
|
});
|
|
74
89
|
|
|
75
90
|
const UnconnectedImageInput = (props) => {
|
|
@@ -89,12 +104,15 @@ const UnconnectedImageInput = (props) => {
|
|
|
89
104
|
placeholderLinkInput = '',
|
|
90
105
|
onSelectItem,
|
|
91
106
|
} = props;
|
|
92
|
-
const imageValue = value?.[0]?.['@id'] || value;
|
|
107
|
+
const imageValue = value?.[0]?.['@id'] || value?.['@id'] || value;
|
|
93
108
|
|
|
94
109
|
const intl = useIntl();
|
|
95
110
|
const linkEditor = useLinkEditor();
|
|
96
111
|
const location = useLocation();
|
|
97
112
|
const dispatch = useDispatch();
|
|
113
|
+
const isFolderish = useSelector(
|
|
114
|
+
(state) => state?.content?.data?.is_folderish,
|
|
115
|
+
);
|
|
98
116
|
const contextUrl = location.pathname;
|
|
99
117
|
|
|
100
118
|
const [uploading, setUploading] = React.useState(false);
|
|
@@ -109,21 +127,41 @@ const UnconnectedImageInput = (props) => {
|
|
|
109
127
|
const imageId = content?.['@id'];
|
|
110
128
|
const image = content?.image;
|
|
111
129
|
let loading = false;
|
|
130
|
+
const isRelationChoice = props.factory === 'Relation Choice';
|
|
112
131
|
|
|
113
132
|
useEffect(() => {
|
|
114
133
|
if (uploading && loading && loaded) {
|
|
115
134
|
setUploading(false);
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
135
|
+
if (isRelationChoice) {
|
|
136
|
+
onChange(id, content, {
|
|
137
|
+
image_field: 'image',
|
|
138
|
+
image_scales: { image: [image] },
|
|
139
|
+
});
|
|
140
|
+
} else {
|
|
141
|
+
onChange(id, imageId, {
|
|
142
|
+
image_field: 'image',
|
|
143
|
+
image_scales: { image: [image] },
|
|
144
|
+
});
|
|
145
|
+
}
|
|
120
146
|
}
|
|
121
|
-
}, [
|
|
147
|
+
}, [
|
|
148
|
+
loading,
|
|
149
|
+
loaded,
|
|
150
|
+
uploading,
|
|
151
|
+
imageId,
|
|
152
|
+
image,
|
|
153
|
+
id,
|
|
154
|
+
content,
|
|
155
|
+
isRelationChoice,
|
|
156
|
+
onChange,
|
|
157
|
+
]);
|
|
122
158
|
|
|
123
159
|
loading = usePrevious(props.request?.loading);
|
|
124
160
|
|
|
125
161
|
const handleUpload = React.useCallback(
|
|
126
162
|
(eventOrFile) => {
|
|
163
|
+
let uploadUrl = getBaseUrl(contextUrl);
|
|
164
|
+
if (!isFolderish) uploadUrl = getParentUrl(uploadUrl);
|
|
127
165
|
if (restrictFileUpload === true) return;
|
|
128
166
|
eventOrFile.target && eventOrFile.stopPropagation();
|
|
129
167
|
|
|
@@ -139,7 +177,7 @@ const UnconnectedImageInput = (props) => {
|
|
|
139
177
|
const fields = fileData.match(/^data:(.*);(.*),(.*)$/);
|
|
140
178
|
dispatch(
|
|
141
179
|
createContent(
|
|
142
|
-
|
|
180
|
+
uploadUrl,
|
|
143
181
|
{
|
|
144
182
|
'@type': 'Image',
|
|
145
183
|
title: file.name,
|
|
@@ -156,11 +194,12 @@ const UnconnectedImageInput = (props) => {
|
|
|
156
194
|
});
|
|
157
195
|
},
|
|
158
196
|
[
|
|
197
|
+
contextUrl,
|
|
198
|
+
isFolderish,
|
|
159
199
|
restrictFileUpload,
|
|
160
200
|
intl.formatMessage,
|
|
161
201
|
dispatch,
|
|
162
|
-
props,
|
|
163
|
-
contextUrl,
|
|
202
|
+
props.block,
|
|
164
203
|
requestId,
|
|
165
204
|
],
|
|
166
205
|
);
|
|
@@ -170,6 +209,83 @@ const UnconnectedImageInput = (props) => {
|
|
|
170
209
|
}, [restrictFileUpload]);
|
|
171
210
|
const onDragLeave = React.useCallback(() => setDragging(false), []);
|
|
172
211
|
|
|
212
|
+
const validateManualLink = React.useCallback(
|
|
213
|
+
(url) => {
|
|
214
|
+
if (!url.startsWith('/')) {
|
|
215
|
+
const error = urlValidator({
|
|
216
|
+
value: url,
|
|
217
|
+
formatMessage: intl.formatMessage,
|
|
218
|
+
});
|
|
219
|
+
// if (error && url !== '') {
|
|
220
|
+
// this.setState({ errors: [error] });
|
|
221
|
+
// } else {
|
|
222
|
+
// this.setState({ errors: [] });
|
|
223
|
+
// }
|
|
224
|
+
return !Boolean(error);
|
|
225
|
+
} else {
|
|
226
|
+
return isInternalURL(url);
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
[intl.formatMessage],
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
const onSubmitURL = React.useCallback(
|
|
233
|
+
(url) => {
|
|
234
|
+
if (validateManualLink(url)) {
|
|
235
|
+
if (isInternalURL(url)) {
|
|
236
|
+
// convert it into an internal on if possible
|
|
237
|
+
props
|
|
238
|
+
.searchContent(
|
|
239
|
+
'/',
|
|
240
|
+
{
|
|
241
|
+
portal_type: config.settings.imageObjects,
|
|
242
|
+
'path.query': flattenToAppURL(url),
|
|
243
|
+
'path.depth': '0',
|
|
244
|
+
sort_on: 'getObjPositionInParent',
|
|
245
|
+
metadata_fields: '_all',
|
|
246
|
+
b_size: 1000,
|
|
247
|
+
},
|
|
248
|
+
`${props.block}-${props.mode}`,
|
|
249
|
+
)
|
|
250
|
+
.then((resp) => {
|
|
251
|
+
if (resp.items?.length > 0) {
|
|
252
|
+
onChange(props.id, resp.items[0], {});
|
|
253
|
+
} else {
|
|
254
|
+
toast.error(
|
|
255
|
+
<Toast
|
|
256
|
+
error
|
|
257
|
+
title={intl.formatMessage(messages.Error)}
|
|
258
|
+
content={intl.formatMessage(
|
|
259
|
+
messages.internalImageNotFoundErrorMessage,
|
|
260
|
+
)}
|
|
261
|
+
/>,
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
} else {
|
|
266
|
+
if (isRelationChoice) {
|
|
267
|
+
toast.error(
|
|
268
|
+
<Toast
|
|
269
|
+
error
|
|
270
|
+
title={intl.formatMessage(messages.Error)}
|
|
271
|
+
content={intl.formatMessage(messages.imageUploadErrorMessage)}
|
|
272
|
+
/>,
|
|
273
|
+
);
|
|
274
|
+
} else {
|
|
275
|
+
// if it's an external link, we save it as is
|
|
276
|
+
onChange(props.id, [
|
|
277
|
+
{
|
|
278
|
+
'@id': normalizeUrl(url),
|
|
279
|
+
title: removeProtocol(url),
|
|
280
|
+
},
|
|
281
|
+
]);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
[validateManualLink, props, intl, isRelationChoice, onChange],
|
|
287
|
+
);
|
|
288
|
+
|
|
173
289
|
return imageValue ? (
|
|
174
290
|
<div
|
|
175
291
|
className="image-upload-widget-image"
|
|
@@ -178,15 +294,20 @@ const UnconnectedImageInput = (props) => {
|
|
|
178
294
|
role="toolbar"
|
|
179
295
|
>
|
|
180
296
|
{selected && <ImageToolbar {...props} />}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
297
|
+
{/* If it's relation choice (preview_image_link) */}
|
|
298
|
+
{isRelationChoice ? (
|
|
299
|
+
<Image item={value} width="fit-content" height="auto" loading="lazy" />
|
|
300
|
+
) : (
|
|
301
|
+
<Image
|
|
302
|
+
className={props.className}
|
|
303
|
+
src={
|
|
304
|
+
isInternalURL(imageValue)
|
|
305
|
+
? `${flattenToAppURL(imageValue)}/@@images/image/${imageSize}`
|
|
306
|
+
: imageValue
|
|
307
|
+
}
|
|
308
|
+
alt=""
|
|
309
|
+
/>
|
|
310
|
+
)}
|
|
190
311
|
</div>
|
|
191
312
|
) : (
|
|
192
313
|
<div
|
|
@@ -227,7 +348,7 @@ const UnconnectedImageInput = (props) => {
|
|
|
227
348
|
</Loader>
|
|
228
349
|
</Dimmer>
|
|
229
350
|
)}
|
|
230
|
-
<
|
|
351
|
+
<Image src={imageBlockSVG} alt="" className="placeholder" />
|
|
231
352
|
<p>{description || intl.formatMessage(messages.addImage)}</p>
|
|
232
353
|
<div className="toolbar-wrapper">
|
|
233
354
|
<div className="toolbar-inner" ref={linkEditor.anchorNode}>
|
|
@@ -242,15 +363,24 @@ const UnconnectedImageInput = (props) => {
|
|
|
242
363
|
e.preventDefault();
|
|
243
364
|
openObjectBrowser({
|
|
244
365
|
mode: objectBrowserPickerType,
|
|
245
|
-
onSelectItem:
|
|
246
|
-
?
|
|
247
|
-
|
|
248
|
-
onChange(props.id,
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
366
|
+
onSelectItem: isRelationChoice
|
|
367
|
+
? (url, item) => {
|
|
368
|
+
// we save the whole item if it's a relation choice
|
|
369
|
+
onChange(props.id, item);
|
|
370
|
+
}
|
|
371
|
+
: onSelectItem
|
|
372
|
+
? onSelectItem
|
|
373
|
+
: // else we save the url along with the image field and scales
|
|
374
|
+
(
|
|
375
|
+
url,
|
|
376
|
+
{ title, image_field, image_scales },
|
|
377
|
+
) => {
|
|
378
|
+
onChange(props.id, flattenToAppURL(url), {
|
|
379
|
+
title,
|
|
380
|
+
image_field,
|
|
381
|
+
image_scales,
|
|
382
|
+
});
|
|
383
|
+
},
|
|
254
384
|
currentPath: contextUrl,
|
|
255
385
|
});
|
|
256
386
|
}}
|
|
@@ -311,13 +441,14 @@ const UnconnectedImageInput = (props) => {
|
|
|
311
441
|
intl.formatMessage(messages.linkAnImage)
|
|
312
442
|
}
|
|
313
443
|
objectBrowserPickerType={objectBrowserPickerType}
|
|
314
|
-
onChange={(_, e) =>
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
444
|
+
onChange={(_, e) => {
|
|
445
|
+
onSubmitURL(e);
|
|
446
|
+
// onChange(
|
|
447
|
+
// props.id,
|
|
448
|
+
// isInternalURL(e) ? flattenToAppURL(e) : e,
|
|
449
|
+
// {},
|
|
450
|
+
// );
|
|
451
|
+
}}
|
|
321
452
|
id={id}
|
|
322
453
|
/>
|
|
323
454
|
)}
|
|
@@ -331,6 +462,8 @@ const UnconnectedImageInput = (props) => {
|
|
|
331
462
|
};
|
|
332
463
|
|
|
333
464
|
export const ImageInput = compose(
|
|
465
|
+
// This HOC goes first because it injects block in case that it's not present (not a block, but a DX field)
|
|
466
|
+
withObjectBrowser,
|
|
334
467
|
connect(
|
|
335
468
|
(state, ownProps) => {
|
|
336
469
|
const requestId = `image-upload-${ownProps.id}`;
|
|
@@ -339,9 +472,9 @@ export const ImageInput = compose(
|
|
|
339
472
|
content: state.content.subrequests[ownProps.block || requestId]?.data,
|
|
340
473
|
};
|
|
341
474
|
},
|
|
342
|
-
{ createContent },
|
|
475
|
+
{ createContent, searchContent },
|
|
343
476
|
),
|
|
344
|
-
)(
|
|
477
|
+
)(UnconnectedImageInput);
|
|
345
478
|
|
|
346
479
|
const ImageUploadWidget = (props) => {
|
|
347
480
|
const { fieldSet, id, title } = props;
|
|
@@ -100,6 +100,7 @@ export const InternalUrlWidget = (props) => {
|
|
|
100
100
|
{value?.length > 0 ? (
|
|
101
101
|
<Button.Group>
|
|
102
102
|
<Button
|
|
103
|
+
type="button"
|
|
103
104
|
basic
|
|
104
105
|
className="cancel"
|
|
105
106
|
aria-label="clearUrlBrowser"
|
|
@@ -115,6 +116,7 @@ export const InternalUrlWidget = (props) => {
|
|
|
115
116
|
) : (
|
|
116
117
|
<Button.Group>
|
|
117
118
|
<Button
|
|
119
|
+
type="button"
|
|
118
120
|
basic
|
|
119
121
|
icon
|
|
120
122
|
aria-label="openUrlBrowser"
|
|
@@ -82,6 +82,7 @@ export class ObjectBrowserWidgetComponent extends Component {
|
|
|
82
82
|
openObjectBrowser: PropTypes.func.isRequired,
|
|
83
83
|
allowExternals: PropTypes.bool,
|
|
84
84
|
placeholder: PropTypes.string,
|
|
85
|
+
onlyFolderishSelectable: PropTypes.bool,
|
|
85
86
|
};
|
|
86
87
|
|
|
87
88
|
/**
|
|
@@ -98,6 +99,7 @@ export class ObjectBrowserWidgetComponent extends Component {
|
|
|
98
99
|
return: 'multiple',
|
|
99
100
|
initialPath: '',
|
|
100
101
|
allowExternals: false,
|
|
102
|
+
onlyFolderishSelectable: false,
|
|
101
103
|
};
|
|
102
104
|
|
|
103
105
|
state = {
|
|
@@ -315,6 +317,9 @@ export class ObjectBrowserWidgetComponent extends Component {
|
|
|
315
317
|
maximumSelectionSize:
|
|
316
318
|
this.props.widgetOptions?.pattern_options?.maximumSelectionSize ||
|
|
317
319
|
this.props.maximumSelectionSize,
|
|
320
|
+
onlyFolderishSelectable:
|
|
321
|
+
this.props.widgetOptions?.pattern_options?.onlyFolderishSelectable ||
|
|
322
|
+
this.props.onlyFolderishSelectable,
|
|
318
323
|
});
|
|
319
324
|
};
|
|
320
325
|
|
|
@@ -399,6 +404,7 @@ export class ObjectBrowserWidgetComponent extends Component {
|
|
|
399
404
|
{this.state.manualLinkInput && isEmpty(items) && (
|
|
400
405
|
<Button.Group>
|
|
401
406
|
<Button
|
|
407
|
+
type="button"
|
|
402
408
|
basic
|
|
403
409
|
className="cancel"
|
|
404
410
|
onClick={(e) => {
|
|
@@ -409,6 +415,7 @@ export class ObjectBrowserWidgetComponent extends Component {
|
|
|
409
415
|
<Icon name={clearSVG} size="18px" color="#e40166" />
|
|
410
416
|
</Button>
|
|
411
417
|
<Button
|
|
418
|
+
type="button"
|
|
412
419
|
basic
|
|
413
420
|
primary
|
|
414
421
|
disabled={!this.state.validURL}
|
|
@@ -423,6 +430,7 @@ export class ObjectBrowserWidgetComponent extends Component {
|
|
|
423
430
|
)}
|
|
424
431
|
{!this.state.manualLinkInput && (
|
|
425
432
|
<Button
|
|
433
|
+
type="button"
|
|
426
434
|
aria-label={this.props.intl.formatMessage(
|
|
427
435
|
messages.openObjectBrowser,
|
|
428
436
|
)}
|
|
@@ -4,17 +4,8 @@ import { render } from '@testing-library/react';
|
|
|
4
4
|
import configureStore from 'redux-mock-store';
|
|
5
5
|
import ObjectListWidget from './ObjectListWidget';
|
|
6
6
|
|
|
7
|
-
vi.mock('@plone/volto/helpers/Loadable/Loadable'
|
|
8
|
-
|
|
9
|
-
'@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
|
|
10
|
-
);
|
|
11
|
-
});
|
|
12
|
-
vi.mock('@plone/volto/components/manage/Form', async () => {
|
|
13
|
-
return await import(
|
|
14
|
-
'@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
|
|
15
|
-
);
|
|
16
|
-
});
|
|
17
|
-
|
|
7
|
+
vi.mock('@plone/volto/helpers/Loadable/Loadable');
|
|
8
|
+
vi.mock('@plone/volto/components/manage/Form');
|
|
18
9
|
beforeAll(async () => {
|
|
19
10
|
const { __setLoadables } = await import(
|
|
20
11
|
'@plone/volto/helpers/Loadable/Loadable'
|
|
@@ -5,11 +5,7 @@ import { Provider } from 'react-intl-redux';
|
|
|
5
5
|
import { render, fireEvent } from '@testing-library/react';
|
|
6
6
|
import ObjectWidget from './ObjectWidget';
|
|
7
7
|
|
|
8
|
-
vi.mock('@plone/volto/components/manage/Form'
|
|
9
|
-
return await import(
|
|
10
|
-
'@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
|
|
11
|
-
);
|
|
12
|
-
});
|
|
8
|
+
vi.mock('@plone/volto/components/manage/Form');
|
|
13
9
|
|
|
14
10
|
const mockStore = configureStore();
|
|
15
11
|
|
|
@@ -15,8 +15,12 @@ import groupBy from 'lodash/groupBy';
|
|
|
15
15
|
import isEmpty from 'lodash/isEmpty';
|
|
16
16
|
import map from 'lodash/map';
|
|
17
17
|
import { defineMessages, injectIntl } from 'react-intl';
|
|
18
|
+
import { withRouter } from 'react-router';
|
|
18
19
|
import { getQuerystring } from '@plone/volto/actions/querystring/querystring';
|
|
20
|
+
import { getQueryStringResults } from '@plone/volto/actions/querystringsearch/querystringsearch';
|
|
19
21
|
import Icon from '@plone/volto/components/theme/Icon/Icon';
|
|
22
|
+
import ObjectBrowserWidget from '@plone/volto/components/manage/Widgets/ObjectBrowserWidget';
|
|
23
|
+
import NumberWidget from '@plone/volto/components/manage/Widgets/NumberWidget';
|
|
20
24
|
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
21
25
|
import cx from 'classnames';
|
|
22
26
|
import config from '@plone/volto/registry';
|
|
@@ -43,8 +47,27 @@ const messages = defineMessages({
|
|
|
43
47
|
id: 'querystring-widget-select',
|
|
44
48
|
defaultMessage: 'Select…',
|
|
45
49
|
},
|
|
50
|
+
currentPath: {
|
|
51
|
+
id: 'query-widget-currentPath',
|
|
52
|
+
defaultMessage: 'Current path (./)',
|
|
53
|
+
},
|
|
54
|
+
parentPath: {
|
|
55
|
+
id: 'query-widget-parentPath',
|
|
56
|
+
defaultMessage: 'Parent path (../)',
|
|
57
|
+
},
|
|
46
58
|
});
|
|
47
59
|
|
|
60
|
+
const parseUidDepth = (val) => {
|
|
61
|
+
if (typeof val !== 'string') return { uid: '', depth: 1 };
|
|
62
|
+
const lastSep = String(val).lastIndexOf('::');
|
|
63
|
+
if (lastSep !== -1) {
|
|
64
|
+
const uid = val.substring(0, lastSep);
|
|
65
|
+
const parsed = parseInt(val.substring(lastSep + 2), 10);
|
|
66
|
+
return { uid, depth: Number.isNaN(parsed) ? 1 : parsed };
|
|
67
|
+
}
|
|
68
|
+
return { uid: val, depth: 1 };
|
|
69
|
+
};
|
|
70
|
+
|
|
48
71
|
/**
|
|
49
72
|
* Widget for a querystring value, to define a catalog search criteria.
|
|
50
73
|
*/
|
|
@@ -97,6 +120,7 @@ export class QuerystringWidgetComponent extends Component {
|
|
|
97
120
|
};
|
|
98
121
|
this.onChangeValue = this.onChangeValue.bind(this);
|
|
99
122
|
this.getWidget = this.getWidget.bind(this);
|
|
123
|
+
this.loadReferenceWidgetItem = this.loadReferenceWidgetItem.bind(this);
|
|
100
124
|
}
|
|
101
125
|
|
|
102
126
|
/**
|
|
@@ -111,6 +135,27 @@ export class QuerystringWidgetComponent extends Component {
|
|
|
111
135
|
this.props.getQuerystring();
|
|
112
136
|
}
|
|
113
137
|
|
|
138
|
+
loadReferenceWidgetItem(v) {
|
|
139
|
+
const loading =
|
|
140
|
+
this.props.reference[`${v}_query_reference`]?.loading ?? false;
|
|
141
|
+
if (!loading && v?.length > 0) {
|
|
142
|
+
this.props.getQueryStringResults(
|
|
143
|
+
'/',
|
|
144
|
+
{
|
|
145
|
+
b_size: 1,
|
|
146
|
+
query: [
|
|
147
|
+
{
|
|
148
|
+
i: 'path',
|
|
149
|
+
o: 'plone.app.querystring.operation.string.absolutePath',
|
|
150
|
+
v: v + '::0',
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
},
|
|
154
|
+
v + '_query_reference',
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
114
159
|
/**
|
|
115
160
|
* Get correct widget
|
|
116
161
|
* @method getWidget
|
|
@@ -118,15 +163,16 @@ export class QuerystringWidgetComponent extends Component {
|
|
|
118
163
|
* @param {number} index Row index.
|
|
119
164
|
* @returns {Object} Widget.
|
|
120
165
|
*/
|
|
121
|
-
getWidget(row, index, Select) {
|
|
166
|
+
getWidget(row, index, Select, intl) {
|
|
122
167
|
const props = {
|
|
123
168
|
fluid: true,
|
|
124
169
|
value: row.v,
|
|
125
170
|
onChange: (data) => this.onChangeValue(index, data.target.value),
|
|
126
171
|
};
|
|
127
172
|
const values = this.props.indexes[row.i].values;
|
|
173
|
+
const operator = this.props.indexes[row.i].operators[row.o];
|
|
128
174
|
|
|
129
|
-
switch (
|
|
175
|
+
switch (operator.widget) {
|
|
130
176
|
case null:
|
|
131
177
|
return <span />;
|
|
132
178
|
case 'DateWidget':
|
|
@@ -217,13 +263,93 @@ export class QuerystringWidgetComponent extends Component {
|
|
|
217
263
|
</Form.Field>
|
|
218
264
|
);
|
|
219
265
|
case 'ReferenceWidget':
|
|
266
|
+
const { uid: uidValue, depth: depthValue } = parseUidDepth(props.value);
|
|
267
|
+
if (!this.props.reference[`${uidValue}_query_reference`]) {
|
|
268
|
+
this.loadReferenceWidgetItem(uidValue);
|
|
269
|
+
}
|
|
270
|
+
const referenceItem = this.props.reference[
|
|
271
|
+
`${uidValue}_query_reference`
|
|
272
|
+
]
|
|
273
|
+
? this.props.reference[`${uidValue}_query_reference`].items[0]
|
|
274
|
+
: null;
|
|
275
|
+
return (
|
|
276
|
+
<div className="location-object-browser">
|
|
277
|
+
<Form.Field className="object-browser-field">
|
|
278
|
+
<ObjectBrowserWidget
|
|
279
|
+
id={`query-reference-widget-${index}`}
|
|
280
|
+
mode="link"
|
|
281
|
+
onChange={(id, data) => {
|
|
282
|
+
const itemSelected = data.length > 0 ? data[0] : {};
|
|
283
|
+
const uid = itemSelected.UID ?? '';
|
|
284
|
+
this.onChangeValue(index, uid ? `${uid}::${depthValue}` : '');
|
|
285
|
+
this.loadReferenceWidgetItem(uid);
|
|
286
|
+
}}
|
|
287
|
+
value={uidValue && this.props.reference ? [referenceItem] : []}
|
|
288
|
+
wrapped={false}
|
|
289
|
+
onlyFolderishSelectable={true}
|
|
290
|
+
allowExternals={true}
|
|
291
|
+
/>
|
|
292
|
+
</Form.Field>
|
|
293
|
+
|
|
294
|
+
{uidValue && (
|
|
295
|
+
<Form.Field className="reference-widget-depth">
|
|
296
|
+
<NumberWidget
|
|
297
|
+
title={intl.formatMessage({
|
|
298
|
+
id: 'Depth',
|
|
299
|
+
defaultMessage: 'Depth',
|
|
300
|
+
})}
|
|
301
|
+
min={1}
|
|
302
|
+
step={1}
|
|
303
|
+
value={depthValue}
|
|
304
|
+
onChange={(id, value) => {
|
|
305
|
+
const newDepth = parseInt(value, 10) || 1;
|
|
306
|
+
const curUid = uidValue || '';
|
|
307
|
+
this.onChangeValue(index, `${curUid}::${newDepth}`);
|
|
308
|
+
}}
|
|
309
|
+
/>
|
|
310
|
+
</Form.Field>
|
|
311
|
+
)}
|
|
312
|
+
</div>
|
|
313
|
+
);
|
|
314
|
+
case 'RelativePathWidget':
|
|
315
|
+
const relativePathOptions = [
|
|
316
|
+
{
|
|
317
|
+
label: intl.formatMessage(messages.currentPath),
|
|
318
|
+
value: './',
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
label: intl.formatMessage(messages.parentPath),
|
|
322
|
+
value: '../',
|
|
323
|
+
},
|
|
324
|
+
];
|
|
325
|
+
return (
|
|
326
|
+
<Form.Field style={{ flex: '1 0 auto', maxWidth: '92%' }}>
|
|
327
|
+
<Select
|
|
328
|
+
{...props}
|
|
329
|
+
className="react-select-container"
|
|
330
|
+
classNamePrefix="react-select"
|
|
331
|
+
options={relativePathOptions}
|
|
332
|
+
styles={customSelectStyles}
|
|
333
|
+
placeholder={this.props.intl.formatMessage(messages.select)}
|
|
334
|
+
theme={selectTheme}
|
|
335
|
+
components={{ DropdownIndicator, Option }}
|
|
336
|
+
onChange={(data) => {
|
|
337
|
+
this.onChangeValue(index, data.value);
|
|
338
|
+
}}
|
|
339
|
+
isMulti={false}
|
|
340
|
+
value={
|
|
341
|
+
relativePathOptions.filter((p) => p.value === props.value)?.[0]
|
|
342
|
+
}
|
|
343
|
+
/>
|
|
344
|
+
</Form.Field>
|
|
345
|
+
);
|
|
220
346
|
default:
|
|
221
347
|
// if (row.o === 'plone.app.querystring.operation.string.relativePath') {
|
|
222
348
|
// props.onChange = data => this.onChangeValue(index, data.target.value);
|
|
223
349
|
// }
|
|
224
350
|
return (
|
|
225
351
|
<Form.Field style={{ flex: '1 0 auto' }}>
|
|
226
|
-
<Input {...props} />
|
|
352
|
+
<Input {...props} description={operator.description} />
|
|
227
353
|
</Form.Field>
|
|
228
354
|
);
|
|
229
355
|
}
|
|
@@ -334,7 +460,7 @@ export class QuerystringWidgetComponent extends Component {
|
|
|
334
460
|
value: row.i,
|
|
335
461
|
label: indexes[row.i]?.title,
|
|
336
462
|
}}
|
|
337
|
-
onChange={(data) =>
|
|
463
|
+
onChange={(data) => {
|
|
338
464
|
onChange(
|
|
339
465
|
id,
|
|
340
466
|
map(value, (curRow, curIndex) =>
|
|
@@ -346,8 +472,8 @@ export class QuerystringWidgetComponent extends Component {
|
|
|
346
472
|
}
|
|
347
473
|
: curRow,
|
|
348
474
|
),
|
|
349
|
-
)
|
|
350
|
-
}
|
|
475
|
+
);
|
|
476
|
+
}}
|
|
351
477
|
/>
|
|
352
478
|
</Form.Field>
|
|
353
479
|
<Form.Field style={{ flex: '1 0 auto' }}>
|
|
@@ -408,7 +534,7 @@ export class QuerystringWidgetComponent extends Component {
|
|
|
408
534
|
</Button>
|
|
409
535
|
)}
|
|
410
536
|
</div>
|
|
411
|
-
{this.getWidget(row, index, Select)}
|
|
537
|
+
{this.getWidget(row, index, Select, intl)}
|
|
412
538
|
{this.props.indexes[row.i].operators[row.o].widget && (
|
|
413
539
|
<Button
|
|
414
540
|
onClick={(event) => {
|
|
@@ -500,10 +626,12 @@ export class QuerystringWidgetComponent extends Component {
|
|
|
500
626
|
export default compose(
|
|
501
627
|
injectIntl,
|
|
502
628
|
injectLazyLibs(['reactSelect']),
|
|
629
|
+
withRouter,
|
|
503
630
|
connect(
|
|
504
|
-
(state) => ({
|
|
631
|
+
(state, props) => ({
|
|
505
632
|
indexes: state.querystring.indexes,
|
|
633
|
+
reference: state.querystringsearch.subrequests,
|
|
506
634
|
}),
|
|
507
|
-
{ getQuerystring },
|
|
635
|
+
{ getQuerystring, getQueryStringResults },
|
|
508
636
|
),
|
|
509
637
|
)(QuerystringWidgetComponent);
|
|
@@ -7,12 +7,7 @@ import RadioGroupWidget from './RadioGroupWidget';
|
|
|
7
7
|
|
|
8
8
|
const mockStore = configureStore();
|
|
9
9
|
|
|
10
|
-
vi.mock('@plone/volto/helpers/Loadable/Loadable'
|
|
11
|
-
return await import(
|
|
12
|
-
'@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
|
|
13
|
-
);
|
|
14
|
-
});
|
|
15
|
-
|
|
10
|
+
vi.mock('@plone/volto/helpers/Loadable/Loadable');
|
|
16
11
|
beforeAll(async () => {
|
|
17
12
|
const { __setLoadables } = await import(
|
|
18
13
|
'@plone/volto/helpers/Loadable/Loadable'
|