@plone/volto 19.0.0-alpha.3 → 19.0.0-alpha.30
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 +2 -0
- package/.eslintrc +37 -6
- package/CHANGELOG.md +534 -2
- package/README.md +23 -21
- package/babel.js +1 -9
- 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/LC_MESSAGES/volto.po +5500 -0
- package/locales/af.json +1 -1
- package/locales/ar/LC_MESSAGES/volto.po +5500 -0
- package/locales/ar.json +1 -1
- package/locales/bg/LC_MESSAGES/volto.po +5500 -0
- package/locales/bg.json +1 -1
- package/locales/bn/LC_MESSAGES/volto.po +5500 -0
- package/locales/bn.json +1 -1
- package/locales/ca/LC_MESSAGES/volto.po +559 -349
- package/locales/ca.json +1 -1
- package/locales/cs/LC_MESSAGES/volto.po +5500 -0
- package/locales/cs.json +1 -1
- package/locales/cy/LC_MESSAGES/volto.po +5500 -0
- package/locales/cy.json +1 -1
- package/locales/da/LC_MESSAGES/volto.po +5500 -0
- package/locales/da.json +1 -1
- package/locales/de/LC_MESSAGES/volto.po +232 -21
- package/locales/de.json +1 -1
- package/locales/el/LC_MESSAGES/volto.po +5500 -0
- package/locales/el.json +1 -1
- package/locales/en/LC_MESSAGES/volto.po +226 -11
- package/locales/en.json +1 -1
- package/locales/en_AU/LC_MESSAGES/volto.po +5500 -0
- package/locales/en_AU.json +1 -1
- package/locales/en_GB/LC_MESSAGES/volto.po +5500 -0
- package/locales/en_GB.json +1 -1
- package/locales/eo/LC_MESSAGES/volto.po +5500 -0
- package/locales/eo.json +1 -1
- package/locales/es/LC_MESSAGES/volto.po +321 -111
- package/locales/es.json +1 -1
- package/locales/et/LC_MESSAGES/volto.po +5500 -0
- package/locales/et.json +1 -1
- package/locales/eu/LC_MESSAGES/volto.po +404 -194
- package/locales/eu.json +1 -1
- package/locales/fa/LC_MESSAGES/volto.po +5500 -0
- package/locales/fa.json +1 -1
- package/locales/fi/LC_MESSAGES/volto.po +221 -11
- package/locales/fi.json +1 -1
- package/locales/fr/LC_MESSAGES/volto.po +220 -10
- package/locales/fr.json +1 -1
- package/locales/fu/LC_MESSAGES/volto.po +5500 -0
- package/locales/fu.json +1 -1
- package/locales/gl/LC_MESSAGES/volto.po +5501 -0
- package/locales/gl.json +1 -1
- package/locales/he/LC_MESSAGES/volto.po +5500 -0
- package/locales/he.json +1 -1
- package/locales/hi/LC_MESSAGES/volto.po +225 -10
- package/locales/hi.json +1 -1
- package/locales/hr/LC_MESSAGES/volto.po +5500 -0
- package/locales/hr.json +1 -1
- package/locales/hu/LC_MESSAGES/volto.po +5500 -0
- package/locales/hu.json +1 -1
- package/locales/hy/LC_MESSAGES/volto.po +5500 -0
- package/locales/hy.json +1 -1
- package/locales/id/LC_MESSAGES/volto.po +5500 -0
- package/locales/id.json +1 -1
- package/locales/it/LC_MESSAGES/volto.po +239 -24
- package/locales/it.json +1 -1
- package/locales/ja/LC_MESSAGES/volto.po +264 -53
- package/locales/ja.json +1 -1
- package/locales/ka/LC_MESSAGES/volto.po +5500 -0
- package/locales/ka.json +1 -1
- package/locales/kn/LC_MESSAGES/volto.po +5500 -0
- package/locales/kn.json +1 -1
- package/locales/ko/LC_MESSAGES/volto.po +5500 -0
- package/locales/ko.json +1 -1
- package/locales/lt/LC_MESSAGES/volto.po +5500 -0
- package/locales/lt.json +1 -1
- package/locales/lv/LC_MESSAGES/volto.po +5500 -0
- package/locales/lv.json +1 -1
- package/locales/mi/LC_MESSAGES/volto.po +5500 -0
- package/locales/mi.json +1 -1
- package/locales/mk/LC_MESSAGES/volto.po +5500 -0
- package/locales/mk.json +1 -1
- package/locales/my/LC_MESSAGES/volto.po +5500 -0
- package/locales/my.json +1 -1
- package/locales/nb_NO/LC_MESSAGES/volto.po +5500 -0
- package/locales/nb_NO.json +1 -1
- package/locales/nl/LC_MESSAGES/volto.po +243 -32
- package/locales/nl.json +1 -1
- package/locales/nn/LC_MESSAGES/volto.po +5500 -0
- package/locales/nn.json +1 -1
- package/locales/pl/LC_MESSAGES/volto.po +5500 -0
- package/locales/pl.json +1 -1
- package/locales/pt/LC_MESSAGES/volto.po +869 -659
- package/locales/pt.json +1 -1
- package/locales/pt_BR/LC_MESSAGES/volto.po +229 -19
- package/locales/pt_BR.json +1 -1
- package/locales/rm/LC_MESSAGES/volto.po +5500 -0
- package/locales/rm.json +1 -1
- package/locales/ro/LC_MESSAGES/volto.po +252 -42
- package/locales/ro.json +1 -1
- package/locales/ru/LC_MESSAGES/volto.po +220 -10
- package/locales/ru.json +1 -1
- package/locales/sk/LC_MESSAGES/volto.po +5500 -0
- package/locales/sk.json +1 -1
- package/locales/sl/LC_MESSAGES/volto.po +5500 -0
- package/locales/sl.json +1 -1
- package/locales/sm/LC_MESSAGES/volto.po +5500 -0
- package/locales/sm.json +1 -1
- package/locales/sq/LC_MESSAGES/volto.po +5500 -0
- package/locales/sq.json +1 -1
- package/locales/sr/LC_MESSAGES/volto.po +5500 -0
- package/locales/sr.json +1 -1
- package/locales/sr@cyrl/LC_MESSAGES/volto.po +5500 -0
- package/locales/sr@cyrl.json +1 -1
- package/locales/sr@latn/LC_MESSAGES/volto.po +5500 -0
- package/locales/sr@latn.json +1 -1
- package/locales/sv/LC_MESSAGES/volto.po +5500 -0
- package/locales/sv.json +1 -1
- package/locales/ta/LC_MESSAGES/volto.po +5501 -0
- package/locales/ta.json +1 -1
- package/locales/te/LC_MESSAGES/volto.po +5500 -0
- package/locales/te.json +1 -1
- package/locales/th/LC_MESSAGES/volto.po +5500 -0
- package/locales/th.json +1 -1
- package/locales/to/LC_MESSAGES/volto.po +5500 -0
- package/locales/to.json +1 -1
- package/locales/tr/LC_MESSAGES/volto.po +5501 -0
- package/locales/tr.json +1 -1
- package/locales/uk/LC_MESSAGES/volto.po +5500 -0
- package/locales/uk.json +1 -1
- package/locales/vi/LC_MESSAGES/volto.po +5500 -0
- package/locales/vi.json +1 -1
- package/locales/volto.pot +220 -10
- package/locales/zh_CN/LC_MESSAGES/volto.po +221 -10
- package/locales/zh_CN.json +1 -1
- package/locales/zh_Hant/LC_MESSAGES/volto.po +5500 -0
- package/locales/zh_Hant.json +1 -1
- package/locales/zh_Hant_HK/LC_MESSAGES/volto.po +5500 -0
- package/locales/zh_Hant_HK.json +1 -1
- package/package.json +72 -146
- package/razzle.config.js +32 -25
- package/src/actions/blockTypes/blockTypes.ts +24 -0
- package/src/components/manage/Actions/Actions.test.jsx +1 -5
- package/src/components/manage/Add/Add.jsx +15 -10
- package/src/components/manage/BlockChooser/BlockChooser.jsx +1 -0
- package/src/components/manage/Blocks/Block/BlocksForm.jsx +10 -7
- package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +3 -14
- package/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +9 -4
- package/src/components/manage/Blocks/Block/Order/Item.jsx +27 -13
- package/src/components/manage/Blocks/Block/Order/Item.test.jsx +90 -0
- package/src/components/manage/Blocks/Block/Order/Order.jsx +116 -67
- package/src/components/manage/Blocks/Block/Order/utilities.js +28 -11
- package/src/components/manage/Blocks/Block/Settings.test.jsx +1 -5
- package/src/components/manage/Blocks/Grid/View.jsx +14 -11
- package/src/components/manage/Blocks/Grid/context.js +3 -0
- 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 +2 -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 +2 -5
- package/src/components/manage/Blocks/Listing/Edit.jsx +1 -0
- package/src/components/manage/Blocks/Listing/ImageGallery.jsx +6 -4
- package/src/components/manage/Blocks/Listing/ListingBody.jsx +4 -0
- 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.jsx +22 -1
- package/src/components/manage/Blocks/Search/components/SelectFacet.test.jsx +1 -6
- package/src/components/manage/Blocks/Search/components/SortOn.jsx +8 -2
- package/src/components/manage/Blocks/Search/components/ToggleFacet.jsx +14 -0
- package/src/components/manage/Blocks/Teaser/Data.jsx +21 -7
- package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +11 -3
- package/src/components/manage/Blocks/Teaser/View.jsx +0 -1
- package/src/components/manage/Blocks/Teaser/utils.js +13 -0
- package/src/components/manage/Blocks/Teaser/utils.test.js +34 -0
- package/src/components/manage/Blocks/Title/Edit.jsx +5 -0
- package/src/components/manage/Blocks/Video/Body.jsx +69 -43
- package/src/components/manage/Blocks/Video/Body.test.jsx +122 -5
- package/src/components/manage/Blocks/Video/Edit.jsx +22 -3
- package/src/components/manage/Blocks/Video/Edit.test.jsx +6 -0
- package/src/components/manage/Blocks/Video/VideoSidebar.test.jsx +1 -5
- package/src/components/manage/Blocks/Video/View.jsx +1 -0
- package/src/components/manage/Blocks/Video/View.test.jsx +29 -15
- package/src/components/manage/Blocks/Video/schema.js +14 -1
- package/src/components/manage/Contents/Contents.jsx +697 -659
- package/src/components/manage/Contents/Contents.test.jsx +1 -5
- package/src/components/manage/Contents/ContentsBreadcrumbs.jsx +6 -5
- package/src/components/manage/Contents/ContentsItem.jsx +1 -1
- 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/ContentsWorkflowModal.test.jsx +1 -5
- package/src/components/manage/Contents/DropZoneContent.jsx +338 -0
- package/src/components/manage/Contents/__mocks__/index.tsx +2 -18
- package/src/components/manage/Controlpanels/AddonsControlpanel.jsx +7 -0
- package/src/components/manage/Controlpanels/Aliases.test.jsx +1 -5
- package/src/components/manage/Controlpanels/BlockType.tsx +166 -0
- package/src/components/manage/Controlpanels/BlockTypes.tsx +145 -0
- package/src/components/manage/Controlpanels/ContentType.jsx +1 -1
- package/src/components/manage/Controlpanels/ContentType.test.jsx +1 -5
- package/src/components/manage/Controlpanels/ContentTypeSchema.jsx +1 -1
- package/src/components/manage/Controlpanels/Controlpanels.jsx +28 -5
- package/src/components/manage/Controlpanels/Controlpanels.test.jsx +10 -0
- package/src/components/manage/Controlpanels/DatabaseInformation.jsx +9 -0
- package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.jsx +3 -2
- package/src/components/manage/Controlpanels/ModerateComments.jsx +8 -0
- 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/UserGroupMembershipControlPanel.test.jsx +3 -0
- package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +575 -631
- package/src/components/manage/Controlpanels/Users/UsersControlpanel.test.jsx +58 -11
- package/src/components/manage/Diff/Diff.jsx +201 -298
- 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.test.jsx +1 -5
- package/src/components/manage/Form/BlockDataForm.test.jsx +1 -5
- package/src/components/manage/Form/Form.jsx +3 -3
- 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 +6 -6
- package/src/components/manage/Multilingual/CreateTranslation.jsx +16 -13
- package/src/components/manage/Multilingual/ManageTranslations.jsx +5 -5
- package/src/components/manage/Multilingual/TranslationObject.jsx +11 -8
- package/src/components/manage/Preferences/ChangePassword.test.jsx +1 -5
- package/src/components/manage/Preferences/PersonalPreferences.jsx +8 -5
- package/src/components/manage/Preferences/PersonalPreferences.test.jsx +1 -17
- package/src/components/manage/Sharing/Sharing.jsx +21 -15
- package/src/components/manage/Sidebar/ObjectBrowser.jsx +3 -0
- package/src/components/manage/Sidebar/ObjectBrowserBody.jsx +18 -2
- 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/TemplateChooser/TemplateChooser.test.jsx +1 -0
- package/src/components/manage/Toast/Toast.jsx +32 -0
- package/src/components/manage/Toast/Toast.test.jsx +9 -5
- package/src/components/manage/Toolbar/PersonalTools.jsx +2 -1
- package/src/components/manage/Toolbar/PersonalTools.test.jsx +15 -0
- package/src/components/manage/Toolbar/Toolbar.jsx +14 -4
- package/src/components/manage/Toolbar/Types.crash.test.jsx +48 -0
- package/src/components/manage/Toolbar/Types.jsx +6 -4
- package/src/components/manage/UniversalLink/UniversalLink.test.jsx +16 -0
- package/src/components/manage/UniversalLink/UniversalLink.tsx +2 -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 +195 -0
- package/src/components/manage/Widgets/CheckboxGroupWidget.test.jsx +1 -6
- package/src/components/manage/Widgets/DatetimeWidget.jsx +102 -53
- package/src/components/manage/Widgets/DatetimeWidget.test.jsx +56 -6
- package/src/components/manage/Widgets/FileWidget.jsx +21 -8
- package/src/components/manage/Widgets/FormFieldWrapper.jsx +146 -168
- package/src/components/manage/Widgets/ImageWidget.jsx +177 -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.jsx +1 -1
- package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +4 -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 +49 -18
- 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 -0
- package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.test.jsx +30 -0
- package/src/components/theme/App/App.jsx +5 -1
- 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/ConnectionRefused/ConnectionRefused.jsx +3 -2
- package/src/components/theme/ContactForm/ContactForm.test.jsx +1 -5
- package/src/components/theme/Image/Image.jsx +25 -13
- package/src/components/theme/Image/Image.test.jsx +247 -146
- package/src/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.tsx +7 -0
- package/src/components/theme/LanguageSelector/LanguageSelector.tsx +89 -0
- package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +42 -12
- package/src/components/theme/PasswordReset/PasswordReset.jsx +108 -191
- 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.stories.jsx +82 -0
- package/src/components/theme/SlotRenderer/SlotRenderer.tsx +12 -6
- package/src/components/theme/Unauthorized/Unauthorized.jsx +35 -25
- package/src/components/theme/Unauthorized/Unauthorized.test.jsx +28 -1
- package/src/components/theme/VideoEmbed/VideoEmbed.jsx +100 -0
- package/src/components/theme/View/EventDatesInfo.test.jsx +1 -6
- package/src/components/theme/View/EventView.stories.jsx +89 -0
- package/src/components/theme/View/EventView.test.jsx +1 -6
- package/src/components/theme/View/FileView.stories.jsx +50 -0
- package/src/components/theme/View/ImageView.jsx +2 -1
- package/src/components/theme/View/ImageView.test.jsx +3 -0
- package/src/components/theme/View/LinkView.stories.jsx +57 -0
- package/src/components/theme/View/ListingView.stories.jsx +70 -0
- package/src/components/theme/View/NewsItemView.stories.jsx +58 -0
- package/src/components/theme/View/RenderBlocks.jsx +8 -10
- package/src/components/theme/View/RenderBlocks.stories.jsx +112 -0
- package/src/components/theme/View/RenderBlocks.test.jsx +14 -4
- package/src/components/theme/View/SummaryView.stories.jsx +71 -0
- package/src/components/theme/View/TabularView.stories.jsx +66 -0
- package/src/components/theme/View/View.jsx +8 -1
- package/src/components/theme/Widgets/ImageWidget.jsx +2 -1
- package/src/components/theme/Widgets/ImageWidget.test.jsx +31 -11
- package/src/config/Blocks.jsx +3 -0
- package/src/config/ControlPanels.js +3 -0
- package/src/config/Widgets.jsx +7 -0
- package/src/config/index.js +19 -12
- package/src/config/server.js +0 -2
- package/src/config/slots.js +19 -0
- package/src/config/validation.ts +8 -0
- package/src/constants/ActionTypes.js +1 -0
- package/src/express-middleware/devproxy.js +22 -5
- package/src/express-middleware/files.js +1 -0
- package/src/express-middleware/files.test.js +59 -0
- package/src/express-middleware/images.js +1 -0
- package/src/express-middleware/images.test.js +50 -0
- 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/AuthToken/AuthToken.js +1 -6
- package/src/helpers/Blocks/Blocks.js +113 -28
- package/src/helpers/Blocks/Blocks.test.js +100 -0
- 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/FormValidation/FormValidation.test.js +31 -0
- package/src/helpers/FormValidation/validators.ts +52 -6
- package/src/helpers/Html/Html.jsx +13 -4
- package/src/helpers/Loadable/__mocks__/Loadable.jsx +7 -22
- package/src/helpers/MessageLabels/MessageLabels.js +10 -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/helpers/Utils/Utils.jsx +17 -0
- package/src/helpers/Utils/Utils.test.jsx +39 -0
- package/src/hooks/user/useUser.js +1 -1
- package/src/internalChecks.test.ts +11 -0
- package/src/middleware/api.js +17 -8
- package/src/middleware/storeProtectLoadUtils.test.js +3 -3
- package/src/reducers/blockTypes/blockTypes.js +38 -0
- 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/index.js +2 -0
- package/src/reducers/querystring/querystring.js +8 -1
- package/src/reducers/users/users.js +1 -1
- package/src/routes.js +13 -1
- package/src/server.jsx +47 -13
- package/src/start-client.jsx +9 -2
- package/src/start-server.js +9 -3
- package/test-addons-loader.js +3 -0
- package/test-setup-globals.js +56 -2
- package/theme/themes/default/elements/segment.variables +9 -16
- package/theme/themes/pastanaga/collections/form.overrides +1 -1
- package/theme/themes/pastanaga/elements/segment.variables +1 -4
- package/theme/themes/pastanaga/extras/block-types.less +17 -0
- package/theme/themes/pastanaga/extras/blocks.less +19 -0
- package/theme/themes/pastanaga/extras/contents.less +75 -0
- package/theme/themes/pastanaga/extras/main.less +20 -4
- package/theme/themes/pastanaga/extras/toolbar.less +10 -5
- package/theme/themes/pastanaga/extras/videoembed.less +22 -0
- package/theme/themes/pastanaga/extras/widgets.less +79 -0
- package/tsconfig.declarations.json +1 -1
- package/tsconfig.json +4 -5
- package/types/actions/blockTypes/blockTypes.d.ts +7 -0
- package/types/components/index.d.ts +1 -1
- package/types/components/manage/Blocks/Block/Order/Item.test.d.ts +1 -0
- package/types/components/manage/Blocks/Block/Order/utilities.d.ts +2 -1
- package/types/components/manage/Blocks/Grid/context.d.ts +1 -0
- package/types/components/manage/Blocks/Teaser/utils.d.ts +5 -0
- package/types/components/manage/Blocks/Video/Body.d.ts +4 -2
- package/types/components/manage/Blocks/Video/schema.d.ts +4 -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/BlockType.d.ts +7 -0
- package/types/components/manage/Controlpanels/BlockTypes.d.ts +7 -0
- 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/Diff/Diff.d.ts +7 -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/Toolbar/Types.crash.test.d.ts +1 -0
- 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/ConnectionRefused/ConnectionRefused.d.ts +2 -2
- package/types/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.d.ts +3 -0
- package/types/components/theme/LanguageSelector/LanguageSelector.d.ts +3 -10
- package/types/components/theme/PasswordReset/PasswordReset.d.ts +6 -2
- package/types/components/theme/Sitemap/Sitemap.stories.d.ts +13 -0
- package/types/components/theme/SlotRenderer/SlotRenderer.d.ts +4 -5
- package/types/components/theme/Unauthorized/Unauthorized.d.ts +2 -2
- package/types/components/theme/VideoEmbed/VideoEmbed.d.ts +2 -0
- package/types/components/theme/View/EventView.stories.d.ts +19 -0
- package/types/components/theme/View/FileView.stories.d.ts +18 -0
- package/types/components/theme/View/LinkView.stories.d.ts +18 -0
- package/types/components/theme/View/ListingView.stories.d.ts +24 -0
- package/types/components/theme/View/NewsItemView.stories.d.ts +23 -0
- package/types/components/theme/View/RenderBlocks.stories.d.ts +23 -0
- package/types/components/theme/View/SummaryView.stories.d.ts +23 -0
- package/types/components/theme/View/TabularView.stories.d.ts +23 -0
- package/types/config/ControlPanels.d.ts +1 -0
- package/types/config/Views.d.ts +1 -1
- package/types/config/Widgets.d.ts +6 -0
- package/types/config/slots.d.ts +7 -0
- package/types/constants/ActionTypes.d.ts +1 -0
- package/types/helpers/Blocks/Blocks.d.ts +4 -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/FormValidation/validators.d.ts +18 -1
- package/types/helpers/Helmet/Helmet.d.ts +1 -1
- package/types/helpers/Loadable/__mocks__/Loadable.d.ts +2 -2
- package/types/helpers/MessageLabels/MessageLabels.d.ts +105 -93
- package/types/helpers/Url/Url.d.ts +14 -0
- package/types/helpers/Url/bulkFlattenToAppURL.d.ts +5 -0
- package/types/helpers/Utils/Utils.d.ts +1 -0
- package/types/reducers/blockTypes/blockTypes.d.ts +16 -0
- package/types/reducers/index.d.ts +3 -0
- package/types/routes.d.ts +7 -5
- package/types/start-client.d.ts +0 -1
- package/vitest.config.mjs +84 -42
- package/webpack-plugins/webpack-less-plugin.js +1 -1
- package/webpack-plugins/webpack-scss-plugin.js +172 -0
- package/cypress/downloads/downloads.html +0 -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/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 -79
- 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
- /package/src/components/theme/LanguageSelector/{LanguageSelector.test.jsx → LanguageSelector.test.tsx} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { validationMessage } from '@plone/volto/helpers/FormValidation/FormValidation';
|
|
2
2
|
import { messages } from '@plone/volto/helpers/MessageLabels/MessageLabels';
|
|
3
|
+
import config from '@plone/volto/registry';
|
|
3
4
|
|
|
4
5
|
type MinMaxValidator = {
|
|
5
6
|
value: string | number;
|
|
@@ -15,6 +16,24 @@ type Validator = {
|
|
|
15
16
|
formatMessage: Function;
|
|
16
17
|
};
|
|
17
18
|
|
|
19
|
+
type Choice = {
|
|
20
|
+
token: string;
|
|
21
|
+
label: string;
|
|
22
|
+
};
|
|
23
|
+
type ChoiceValidator = {
|
|
24
|
+
value: string | Choice;
|
|
25
|
+
field: Record<string, any>;
|
|
26
|
+
formData: any;
|
|
27
|
+
formatMessage: Function;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
type FileValidator = {
|
|
31
|
+
value: Record<string, any>;
|
|
32
|
+
field: Record<string, any>;
|
|
33
|
+
formData: any;
|
|
34
|
+
formatMessage: Function;
|
|
35
|
+
};
|
|
36
|
+
|
|
18
37
|
export const isMaxPropertyValid = ({
|
|
19
38
|
value,
|
|
20
39
|
fieldSpec,
|
|
@@ -134,6 +153,15 @@ export const hasUniqueItemsValidator = ({
|
|
|
134
153
|
return !isValid ? formatMessage(messages.uniqueItems) : null;
|
|
135
154
|
};
|
|
136
155
|
|
|
156
|
+
const formatDateValue = (isoString: string) => {
|
|
157
|
+
const date = new Date(isoString);
|
|
158
|
+
if (isNaN(date.getTime())) return isoString;
|
|
159
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
160
|
+
dateStyle: 'medium',
|
|
161
|
+
timeStyle: 'short',
|
|
162
|
+
}).format(date);
|
|
163
|
+
};
|
|
164
|
+
|
|
137
165
|
export const startEventDateRangeValidator = ({
|
|
138
166
|
value,
|
|
139
167
|
field,
|
|
@@ -144,7 +172,9 @@ export const startEventDateRangeValidator = ({
|
|
|
144
172
|
value && formData.end && new Date(value) < new Date(formData.end);
|
|
145
173
|
return !isValid
|
|
146
174
|
? formatMessage(messages.startEventRange, {
|
|
147
|
-
endDateValueOrEndFieldName: formData.end
|
|
175
|
+
endDateValueOrEndFieldName: formData.end
|
|
176
|
+
? formatDateValue(formData.end)
|
|
177
|
+
: 'end',
|
|
148
178
|
})
|
|
149
179
|
: null;
|
|
150
180
|
};
|
|
@@ -159,7 +189,9 @@ export const endEventDateRangeValidator = ({
|
|
|
159
189
|
value && formData.start && new Date(value) > new Date(formData.start);
|
|
160
190
|
return !isValid
|
|
161
191
|
? formatMessage(messages.endEventRange, {
|
|
162
|
-
startDateValueOrStartFieldName: formData.start
|
|
192
|
+
startDateValueOrStartFieldName: formData.start
|
|
193
|
+
? formatDateValue(formData.start)
|
|
194
|
+
: 'start',
|
|
163
195
|
})
|
|
164
196
|
: null;
|
|
165
197
|
};
|
|
@@ -211,12 +243,26 @@ export const defaultLanguageControlPanelValidator = ({
|
|
|
211
243
|
value,
|
|
212
244
|
formData,
|
|
213
245
|
formatMessage,
|
|
214
|
-
}:
|
|
246
|
+
}: ChoiceValidator) => {
|
|
247
|
+
const token = typeof value === 'object' ? value.token : value;
|
|
215
248
|
const isValid =
|
|
216
|
-
|
|
249
|
+
token &&
|
|
217
250
|
(formData.available_languages.find(
|
|
218
|
-
(lang: { token: string }) => lang.token ===
|
|
251
|
+
(lang: { token: string }) => lang.token === token,
|
|
219
252
|
) ||
|
|
220
|
-
formData.available_languages.includes(
|
|
253
|
+
formData.available_languages.includes(token));
|
|
221
254
|
return !isValid ? formatMessage(messages.defaultLanguage) : null;
|
|
222
255
|
};
|
|
256
|
+
|
|
257
|
+
export const sizeValidator = ({
|
|
258
|
+
value,
|
|
259
|
+
field,
|
|
260
|
+
formatMessage,
|
|
261
|
+
}: FileValidator) => {
|
|
262
|
+
const maxSize = field.size
|
|
263
|
+
? parseInt(field.size, 10)
|
|
264
|
+
: config.settings.maxFileUploadSize;
|
|
265
|
+
return maxSize && value.size > maxSize
|
|
266
|
+
? formatMessage(messages.maxSize, { maxSize, size: value.size })
|
|
267
|
+
: null;
|
|
268
|
+
};
|
|
@@ -9,6 +9,7 @@ import Helmet from '@plone/volto/helpers/Helmet/Helmet';
|
|
|
9
9
|
import serialize from 'serialize-javascript';
|
|
10
10
|
import join from 'lodash/join';
|
|
11
11
|
import BodyClass from '@plone/volto/helpers/BodyClass/BodyClass';
|
|
12
|
+
import { addSubpathPrefix } from '@plone/volto/helpers/Url/Url';
|
|
12
13
|
import { runtimeConfig } from '@plone/volto/runtime_config';
|
|
13
14
|
import config from '@plone/volto/registry';
|
|
14
15
|
|
|
@@ -126,14 +127,22 @@ class Html extends Component {
|
|
|
126
127
|
}}
|
|
127
128
|
/>
|
|
128
129
|
|
|
129
|
-
<link
|
|
130
|
-
|
|
130
|
+
<link
|
|
131
|
+
rel="icon"
|
|
132
|
+
href={addSubpathPrefix('/favicon.ico')}
|
|
133
|
+
sizes="any"
|
|
134
|
+
/>
|
|
135
|
+
<link
|
|
136
|
+
rel="icon"
|
|
137
|
+
href={addSubpathPrefix('/icon.svg')}
|
|
138
|
+
type="image/svg+xml"
|
|
139
|
+
/>
|
|
131
140
|
<link
|
|
132
141
|
rel="apple-touch-icon"
|
|
133
142
|
sizes="180x180"
|
|
134
|
-
href=
|
|
143
|
+
href={addSubpathPrefix('/apple-touch-icon.png')}
|
|
135
144
|
/>
|
|
136
|
-
<link rel="manifest" href=
|
|
145
|
+
<link rel="manifest" href={addSubpathPrefix('/site.webmanifest')} />
|
|
137
146
|
<meta name="generator" content="Plone 6 - https://plone.org" />
|
|
138
147
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
139
148
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Then, in the tests, we need to replace:
|
|
3
|
-
|
|
4
|
-
vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
|
|
5
|
-
return await import(
|
|
6
|
-
'@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
|
|
7
|
-
);
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
with the following:
|
|
11
|
-
|
|
12
|
-
vi.mock('@plone/volto/helpers/Loadable/Loadable');
|
|
13
|
-
|
|
14
|
-
Finally, remove this comment.
|
|
15
|
-
*/
|
|
16
|
-
|
|
1
|
+
import React from 'react';
|
|
17
2
|
import config from '@plone/volto/registry';
|
|
18
3
|
const loadables = config.settings.loadables;
|
|
19
4
|
|
|
@@ -33,21 +18,21 @@ export const __setLoadables = async () => {
|
|
|
33
18
|
};
|
|
34
19
|
|
|
35
20
|
// TODO: filter mockAllLoadables
|
|
36
|
-
export const injectLazyLibs =
|
|
21
|
+
export const injectLazyLibs = vi.fn().mockImplementation(function ([
|
|
37
22
|
libraries,
|
|
38
23
|
]) {
|
|
39
|
-
return
|
|
40
|
-
|
|
24
|
+
return vi.fn((WrappedComponent) =>
|
|
25
|
+
vi.fn((props) => {
|
|
41
26
|
return <WrappedComponent {...props} {...mockAllLoadables} />;
|
|
42
27
|
}),
|
|
43
28
|
);
|
|
44
29
|
});
|
|
45
30
|
|
|
46
|
-
export const preloadLazyLibs =
|
|
31
|
+
export const preloadLazyLibs = vi.fn().mockImplementation(function ([
|
|
47
32
|
libraries,
|
|
48
33
|
]) {
|
|
49
|
-
return
|
|
50
|
-
|
|
34
|
+
return vi.fn((WrappedComponent) =>
|
|
35
|
+
vi.fn((props) => {
|
|
51
36
|
return <WrappedComponent {...props} />;
|
|
52
37
|
}),
|
|
53
38
|
);
|
|
@@ -25,6 +25,11 @@ export const messages = defineMessages({
|
|
|
25
25
|
id: 'Maximum value is {len}.',
|
|
26
26
|
defaultMessage: 'Maximum value is {len}.',
|
|
27
27
|
},
|
|
28
|
+
maxSize: {
|
|
29
|
+
id: 'Maximum file size is {maxSize} bytes, but the uploaded file is {size} bytes.',
|
|
30
|
+
defaultMessage:
|
|
31
|
+
'Maximum file size is {maxSize} bytes, but the uploaded file is {size} bytes.',
|
|
32
|
+
},
|
|
28
33
|
uniqueItems: {
|
|
29
34
|
id: 'Items must be unique.',
|
|
30
35
|
defaultMessage: 'Items must be unique.',
|
|
@@ -152,6 +157,11 @@ export const messages = defineMessages({
|
|
|
152
157
|
id: 'Groupname',
|
|
153
158
|
defaultMessage: 'Groupname',
|
|
154
159
|
},
|
|
160
|
+
addGroupsFormGroupNameDescription: {
|
|
161
|
+
id: 'A unique identifier for the group. Cannot be changed after creation. No spaces allowed.',
|
|
162
|
+
defaultMessage:
|
|
163
|
+
'A unique identifier for the group. Cannot be changed after creation. No spaces allowed.',
|
|
164
|
+
},
|
|
155
165
|
addGroupsFormDescriptionTitle: {
|
|
156
166
|
id: 'Description',
|
|
157
167
|
defaultMessage: 'Description',
|
|
@@ -22,10 +22,10 @@ export const SITEMAP_BATCH_SIZE = 5000;
|
|
|
22
22
|
export const generateSitemap = (_req, start = 0, size = undefined) =>
|
|
23
23
|
new Promise((resolve) => {
|
|
24
24
|
const { settings } = config;
|
|
25
|
-
const
|
|
25
|
+
const apiSuffix = settings.legacyTraverse ? '' : '/++api++';
|
|
26
26
|
const apiPath = settings.internalApiPath ?? settings.apiPath;
|
|
27
27
|
const request = superagent.get(
|
|
28
|
-
`${apiPath}${
|
|
28
|
+
`${apiPath}${apiSuffix}/@search?metadata_fields=modified&b_start=${start}&b_size=${
|
|
29
29
|
size !== undefined ? size : 100000000
|
|
30
30
|
}&use_site_search_settings=1`,
|
|
31
31
|
);
|
|
@@ -64,10 +64,10 @@ export const generateSitemap = (_req, start = 0, size = undefined) =>
|
|
|
64
64
|
export const generateSitemapIndex = (_req, gzip = false) =>
|
|
65
65
|
new Promise((resolve) => {
|
|
66
66
|
const { settings } = config;
|
|
67
|
-
const
|
|
67
|
+
const apiSuffix = settings.legacyTraverse ? '' : '/++api++';
|
|
68
68
|
const apiPath = settings.internalApiPath ?? settings.apiPath;
|
|
69
69
|
const request = superagent.get(
|
|
70
|
-
`${apiPath}${
|
|
70
|
+
`${apiPath}${apiSuffix}/@search?metadata_fields=modified&b_size=0&use_site_search_settings=1`,
|
|
71
71
|
);
|
|
72
72
|
request.set('Accept', 'application/json');
|
|
73
73
|
const authToken = _req.universalCookies.get('auth_token');
|
package/src/helpers/Url/Url.js
CHANGED
|
@@ -193,7 +193,7 @@ export function addAppURL(url) {
|
|
|
193
193
|
*/
|
|
194
194
|
export function expandToBackendURL(path) {
|
|
195
195
|
const { settings } = config;
|
|
196
|
-
const
|
|
196
|
+
const apiSuffix = settings.legacyTraverse ? '' : '/++api++';
|
|
197
197
|
let adjustedPath;
|
|
198
198
|
if (path.startsWith('http://') || path.startsWith('https://')) {
|
|
199
199
|
// flattenToAppURL first if we get a full URL
|
|
@@ -210,7 +210,7 @@ export function expandToBackendURL(path) {
|
|
|
210
210
|
apiPath = settings.apiPath;
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
return `${apiPath}${
|
|
213
|
+
return `${apiPath}${apiSuffix}${adjustedPath}`;
|
|
214
214
|
}
|
|
215
215
|
|
|
216
216
|
/**
|
|
@@ -258,6 +258,36 @@ export function isUrl(url) {
|
|
|
258
258
|
return urlRegex().test(url);
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Add subpath path if set in settings
|
|
263
|
+
* @method addSubpathPrefix
|
|
264
|
+
* @param {string} src pathname
|
|
265
|
+
* @returns {string} prefixed subpath pathname
|
|
266
|
+
*/
|
|
267
|
+
export function addSubpathPrefix(src) {
|
|
268
|
+
let url = src;
|
|
269
|
+
const { subpathPrefix } = config.settings;
|
|
270
|
+
if (isInternalURL(src) && subpathPrefix && !src.startsWith(subpathPrefix)) {
|
|
271
|
+
url = subpathPrefix + src; //add subpathPrefix to src if it's an internal url and not a static resource.
|
|
272
|
+
}
|
|
273
|
+
return url;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* strip subpath path particulary from api calls
|
|
278
|
+
* @method stripSubpathPrefix
|
|
279
|
+
* @param {string} src pathname
|
|
280
|
+
* @returns {string} pathname
|
|
281
|
+
*/
|
|
282
|
+
export function stripSubpathPrefix(src) {
|
|
283
|
+
let url = src;
|
|
284
|
+
const { subpathPrefix } = config.settings;
|
|
285
|
+
if (subpathPrefix && src.match(new RegExp(`^${subpathPrefix}(/|$)`))) {
|
|
286
|
+
url = src.slice(subpathPrefix.length);
|
|
287
|
+
}
|
|
288
|
+
return url;
|
|
289
|
+
}
|
|
290
|
+
|
|
261
291
|
/**
|
|
262
292
|
* Get field url
|
|
263
293
|
* @method getFieldURL
|
|
@@ -381,6 +411,7 @@ export function flattenScales(path, image) {
|
|
|
381
411
|
const basePath = image.base_path || path;
|
|
382
412
|
const imageInfo = {
|
|
383
413
|
...image,
|
|
414
|
+
scales: image.scales || {},
|
|
384
415
|
download: flattenToAppURL(removeObjectIdFromURL(basePath, image.download)),
|
|
385
416
|
};
|
|
386
417
|
|
|
@@ -19,6 +19,8 @@ import {
|
|
|
19
19
|
normaliseMail,
|
|
20
20
|
normalizeTelephone,
|
|
21
21
|
flattenScales,
|
|
22
|
+
addSubpathPrefix,
|
|
23
|
+
stripSubpathPrefix,
|
|
22
24
|
} from './Url';
|
|
23
25
|
|
|
24
26
|
beforeEach(() => {
|
|
@@ -533,4 +535,64 @@ describe('Url', () => {
|
|
|
533
535
|
});
|
|
534
536
|
});
|
|
535
537
|
});
|
|
538
|
+
|
|
539
|
+
describe('Subpath tests', () => {
|
|
540
|
+
beforeEach(() => {
|
|
541
|
+
settings.subpathPrefix = '/site';
|
|
542
|
+
});
|
|
543
|
+
describe('addSubpathPrefix', () => {
|
|
544
|
+
it('adds subpath prefix to internal URLs', () => {
|
|
545
|
+
expect(addSubpathPrefix('/some-page')).toBe('/site/some-page');
|
|
546
|
+
expect(addSubpathPrefix('/news/article')).toBe('/site/news/article');
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
it('does not add subpath prefix to URLs that already have it', () => {
|
|
550
|
+
expect(addSubpathPrefix('/site/some-page')).toBe('/site/some-page');
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
it('does not add subpath prefix to external URLs', () => {
|
|
554
|
+
expect(addSubpathPrefix('https://example.com/page')).toBe(
|
|
555
|
+
'https://example.com/page',
|
|
556
|
+
);
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
it('handles empty subpath prefix', () => {
|
|
560
|
+
settings.subpathPrefix = '';
|
|
561
|
+
expect(addSubpathPrefix('/some-page')).toBe('/some-page');
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
it('handles undefined subpath prefix', () => {
|
|
565
|
+
settings.subpathPrefix = undefined;
|
|
566
|
+
expect(addSubpathPrefix('/some-page')).toBe('/some-page');
|
|
567
|
+
});
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
describe('stripSubpathPrefix', () => {
|
|
571
|
+
beforeEach(() => {
|
|
572
|
+
settings.subpathPrefix = '/site';
|
|
573
|
+
});
|
|
574
|
+
it('removes subpath prefix from URLs that have it', () => {
|
|
575
|
+
expect(stripSubpathPrefix('/site/some-page')).toBe('/some-page');
|
|
576
|
+
expect(stripSubpathPrefix('/site/news/article')).toBe('/news/article');
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
it('leaves URLs unchanged if they do not have the prefix', () => {
|
|
580
|
+
expect(stripSubpathPrefix('/other/some-page')).toBe('/other/some-page');
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
it('handles the case where URL is exactly the subpath prefix', () => {
|
|
584
|
+
expect(stripSubpathPrefix('/site')).toBe('');
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
it('handles empty subpath prefix', () => {
|
|
588
|
+
settings.subpathPrefix = '';
|
|
589
|
+
expect(stripSubpathPrefix('/some-page')).toBe('/some-page');
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
it('handles undefined subpath prefix', () => {
|
|
593
|
+
settings.subpathPrefix = undefined;
|
|
594
|
+
expect(stripSubpathPrefix('/some-page')).toBe('/some-page');
|
|
595
|
+
});
|
|
596
|
+
});
|
|
597
|
+
});
|
|
536
598
|
});
|
|
@@ -37,6 +37,23 @@ export const safeWrapper = (func) => (config) => {
|
|
|
37
37
|
return res;
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Extract a readable error message from several possible error shapes
|
|
42
|
+
* @param {object} error
|
|
43
|
+
* @returns {string} message
|
|
44
|
+
*/
|
|
45
|
+
export const getErrorMessage = (error) => {
|
|
46
|
+
const respBody = error?.response?.body;
|
|
47
|
+
if (respBody?.error?.message) return respBody.error.message;
|
|
48
|
+
if (respBody?.message) return respBody.message;
|
|
49
|
+
if (error?.message) return error.message;
|
|
50
|
+
try {
|
|
51
|
+
return JSON.stringify(error);
|
|
52
|
+
} catch (e) {
|
|
53
|
+
return String(error);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
40
57
|
/**
|
|
41
58
|
* A helper to pipe a configuration object through configuration loaders
|
|
42
59
|
*
|
|
@@ -3,6 +3,7 @@ import config from '@plone/volto/registry';
|
|
|
3
3
|
import {
|
|
4
4
|
applyConfig,
|
|
5
5
|
difference,
|
|
6
|
+
getErrorMessage,
|
|
6
7
|
getColor,
|
|
7
8
|
getInitials,
|
|
8
9
|
hasApiExpander,
|
|
@@ -246,6 +247,44 @@ describe('Utils tests', () => {
|
|
|
246
247
|
});
|
|
247
248
|
});
|
|
248
249
|
|
|
250
|
+
describe('getErrorMessage', () => {
|
|
251
|
+
it('returns nested backend error message', () => {
|
|
252
|
+
const error = {
|
|
253
|
+
response: {
|
|
254
|
+
body: {
|
|
255
|
+
error: {
|
|
256
|
+
message: 'Backend nested message',
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
expect(getErrorMessage(error)).toEqual('Backend nested message');
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
it('returns body message when present', () => {
|
|
266
|
+
const error = {
|
|
267
|
+
response: {
|
|
268
|
+
body: {
|
|
269
|
+
message: 'Backend body message',
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
expect(getErrorMessage(error)).toEqual('Backend body message');
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('returns generic error.message fallback', () => {
|
|
278
|
+
expect(getErrorMessage(new Error('Generic message'))).toEqual(
|
|
279
|
+
'Generic message',
|
|
280
|
+
);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it('returns stringified object as final fallback', () => {
|
|
284
|
+
expect(getErrorMessage({ foo: 'bar' })).toEqual('{"foo":"bar"}');
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
|
|
249
288
|
describe('safeWrapper', () => {
|
|
250
289
|
it('calls the function with config', () => {
|
|
251
290
|
expect(
|
|
@@ -12,7 +12,7 @@ const useUser = () => {
|
|
|
12
12
|
const dispatch = useDispatch();
|
|
13
13
|
|
|
14
14
|
useEffect(() => {
|
|
15
|
-
if (!user?.id && users?.get.loading === false) {
|
|
15
|
+
if (userId && !user?.id && users?.get.loading === false) {
|
|
16
16
|
dispatch(getUser(userId));
|
|
17
17
|
}
|
|
18
18
|
}, [dispatch, userId, user, users?.get.loading]);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import packageJson from '../package.json';
|
|
3
|
+
|
|
4
|
+
describe('internal checks', () => {
|
|
5
|
+
it('keeps prettier listed as a runtime dependency', () => {
|
|
6
|
+
const dependencies = packageJson.dependencies ?? {};
|
|
7
|
+
|
|
8
|
+
expect(dependencies).toHaveProperty('prettier');
|
|
9
|
+
expect(typeof dependencies.prettier).toBe('string');
|
|
10
|
+
});
|
|
11
|
+
});
|
package/src/middleware/api.js
CHANGED
|
@@ -287,9 +287,13 @@ const apiMiddlewareFactory =
|
|
|
287
287
|
const langFileName = toGettextLang(lang);
|
|
288
288
|
import(
|
|
289
289
|
/* @vite-ignore */ '@root/../locales/' + langFileName + '.json'
|
|
290
|
-
)
|
|
291
|
-
|
|
292
|
-
|
|
290
|
+
)
|
|
291
|
+
.then((locale) => {
|
|
292
|
+
dispatch(changeLanguage(lang, locale.default));
|
|
293
|
+
})
|
|
294
|
+
.catch(() => {
|
|
295
|
+
dispatch(changeLanguage(lang, {}));
|
|
296
|
+
});
|
|
293
297
|
}
|
|
294
298
|
}
|
|
295
299
|
|
|
@@ -341,14 +345,19 @@ const apiMiddlewareFactory =
|
|
|
341
345
|
(error) => {
|
|
342
346
|
// Make sure an error during hydration
|
|
343
347
|
// (for example when serving an archived page)
|
|
344
|
-
// doesn't hide the SSR content.
|
|
345
|
-
|
|
348
|
+
// doesn't hide the SSR content. Only suppress GET_CONTENT failures;
|
|
349
|
+
// user-initiated actions (LOGIN, etc.) must always dispatch _FAIL so
|
|
350
|
+
// loaders stop and errors surface.
|
|
351
|
+
const shouldIgnoreHydrationError =
|
|
352
|
+
isHydrating && !hasExistingError && type === GET_CONTENT;
|
|
353
|
+
|
|
354
|
+
if (shouldIgnoreHydrationError) {
|
|
346
355
|
isHydrating = false;
|
|
347
356
|
return;
|
|
348
357
|
}
|
|
349
358
|
|
|
350
359
|
// Only SSR can set ECONNREFUSED
|
|
351
|
-
if (error
|
|
360
|
+
if (error?.code === 'ECONNREFUSED') {
|
|
352
361
|
next({
|
|
353
362
|
...rest,
|
|
354
363
|
error,
|
|
@@ -359,7 +368,7 @@ const apiMiddlewareFactory =
|
|
|
359
368
|
}
|
|
360
369
|
|
|
361
370
|
// Response error is marked crossDomain if CORS error happen
|
|
362
|
-
else if (error
|
|
371
|
+
else if (error?.crossDomain) {
|
|
363
372
|
next({
|
|
364
373
|
...rest,
|
|
365
374
|
error,
|
|
@@ -410,7 +419,7 @@ const apiMiddlewareFactory =
|
|
|
410
419
|
...rest,
|
|
411
420
|
error,
|
|
412
421
|
statusCode: error.response,
|
|
413
|
-
message: error.response
|
|
422
|
+
message: error.response?.body?.message,
|
|
414
423
|
connectionRefused: false,
|
|
415
424
|
type: SET_APIERROR,
|
|
416
425
|
});
|
|
@@ -445,9 +445,9 @@ describe('storeProtectLoadUtils', () => {
|
|
|
445
445
|
isCounting: false,
|
|
446
446
|
});
|
|
447
447
|
};
|
|
448
|
-
test('pending', expectPass({ type: 'ANY_PENDING' }
|
|
449
|
-
test('success', expectPass({ type: 'ANY_SUCCESS' }
|
|
450
|
-
test('failure', expectPass({ type: 'ANY_FAIL' }
|
|
448
|
+
test('pending', expectPass({ type: 'ANY_PENDING' }, 2));
|
|
449
|
+
test('success', expectPass({ type: 'ANY_SUCCESS' }, 2));
|
|
450
|
+
test('failure', expectPass({ type: 'ANY_FAIL' }, 2));
|
|
451
451
|
});
|
|
452
452
|
describe('counting', () => {
|
|
453
453
|
const expectCount = (action, from, to) => () => {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { GET_BLOCKTYPES_INDEX } from '@plone/volto/constants/ActionTypes';
|
|
2
|
+
|
|
3
|
+
const initialState = {
|
|
4
|
+
error: null,
|
|
5
|
+
items: {},
|
|
6
|
+
loaded: false,
|
|
7
|
+
loading: false,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default function blockTypes(state = initialState, action = {}) {
|
|
11
|
+
switch (action.type) {
|
|
12
|
+
case `${GET_BLOCKTYPES_INDEX}_PENDING`:
|
|
13
|
+
return {
|
|
14
|
+
...state,
|
|
15
|
+
error: null,
|
|
16
|
+
loaded: false,
|
|
17
|
+
loading: true,
|
|
18
|
+
};
|
|
19
|
+
case `${GET_BLOCKTYPES_INDEX}_SUCCESS`:
|
|
20
|
+
return {
|
|
21
|
+
...state,
|
|
22
|
+
error: null,
|
|
23
|
+
items: action.result,
|
|
24
|
+
loaded: true,
|
|
25
|
+
loading: false,
|
|
26
|
+
};
|
|
27
|
+
case `${GET_BLOCKTYPES_INDEX}_FAIL`:
|
|
28
|
+
return {
|
|
29
|
+
...state,
|
|
30
|
+
error: action.error,
|
|
31
|
+
items: {},
|
|
32
|
+
loaded: false,
|
|
33
|
+
loading: false,
|
|
34
|
+
};
|
|
35
|
+
default:
|
|
36
|
+
return state;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
* @module reducers/content/content
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import map from 'lodash/map';
|
|
7
|
-
import mapKeys from 'lodash/mapKeys';
|
|
8
6
|
import omit from 'lodash/omit';
|
|
9
7
|
|
|
10
8
|
import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
|
|
9
|
+
import { flattenStaticBehaviors } from '@plone/volto/helpers/Content/Content';
|
|
11
10
|
|
|
12
11
|
import {
|
|
13
12
|
CREATE_CONTENT,
|
|
@@ -131,14 +130,7 @@ export default function content(state = initialState, action = {}) {
|
|
|
131
130
|
},
|
|
132
131
|
};
|
|
133
132
|
case `${CREATE_CONTENT}_SUCCESS`:
|
|
134
|
-
|
|
135
|
-
map(result['@static_behaviors'], (behavior) => {
|
|
136
|
-
result = {
|
|
137
|
-
...omit(result, behavior),
|
|
138
|
-
...mapKeys(result[behavior], (value, key) => `${behavior}.${key}`),
|
|
139
|
-
};
|
|
140
|
-
});
|
|
141
|
-
}
|
|
133
|
+
result = flattenStaticBehaviors(result);
|
|
142
134
|
const data = action.subrequest
|
|
143
135
|
? Array.isArray(result)
|
|
144
136
|
? result.map((item) => ({
|
|
@@ -188,14 +180,7 @@ export default function content(state = initialState, action = {}) {
|
|
|
188
180
|
},
|
|
189
181
|
};
|
|
190
182
|
case `${GET_CONTENT}_SUCCESS`:
|
|
191
|
-
|
|
192
|
-
map(result['@static_behaviors'], (behavior) => {
|
|
193
|
-
result = {
|
|
194
|
-
...omit(result, behavior),
|
|
195
|
-
...mapKeys(result[behavior], (value, key) => `${behavior}.${key}`),
|
|
196
|
-
};
|
|
197
|
-
});
|
|
198
|
-
}
|
|
183
|
+
result = flattenStaticBehaviors(result);
|
|
199
184
|
|
|
200
185
|
const transforms = config.getUtilities({
|
|
201
186
|
type: 'transform',
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { GET_DIFF } from '@plone/volto/constants/ActionTypes';
|
|
7
|
+
import { flattenStaticBehaviors } from '@plone/volto/helpers/Content/Content';
|
|
7
8
|
|
|
8
9
|
const initialState = {
|
|
9
10
|
error: null,
|
|
@@ -29,10 +30,13 @@ export default function diff(state = initialState, action = {}) {
|
|
|
29
30
|
loading: true,
|
|
30
31
|
};
|
|
31
32
|
case `${GET_DIFF}_SUCCESS`:
|
|
33
|
+
const first_result = flattenStaticBehaviors(action.result[0]);
|
|
34
|
+
const second_result = flattenStaticBehaviors(action.result[1]);
|
|
35
|
+
|
|
32
36
|
return {
|
|
33
37
|
...state,
|
|
34
38
|
error: null,
|
|
35
|
-
data:
|
|
39
|
+
data: [first_result, second_result],
|
|
36
40
|
loaded: true,
|
|
37
41
|
loading: false,
|
|
38
42
|
};
|