@plone/volto 19.0.0-alpha.0 → 19.0.0-alpha.10
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 -0
- package/CHANGELOG.md +274 -2
- package/README.md +3 -6
- 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/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 +96 -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 +104 -25
- package/locales/de.json +1 -1
- package/locales/el.json +1 -0
- package/locales/en/LC_MESSAGES/volto.po +97 -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 +97 -18
- package/locales/es.json +1 -1
- package/locales/et.json +1 -0
- package/locales/eu/LC_MESSAGES/volto.po +96 -17
- package/locales/eu.json +1 -1
- package/locales/fa.json +1 -0
- package/locales/fi/LC_MESSAGES/volto.po +96 -17
- package/locales/fi.json +1 -1
- package/locales/fr/LC_MESSAGES/volto.po +97 -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 +100 -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 +101 -22
- package/locales/it.json +1 -1
- package/locales/ja/LC_MESSAGES/volto.po +96 -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 +100 -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 +96 -17
- package/locales/pt.json +1 -1
- package/locales/pt_BR/LC_MESSAGES/volto.po +116 -37
- package/locales/pt_BR.json +1 -1
- package/locales/rm.json +1 -0
- package/locales/ro/LC_MESSAGES/volto.po +100 -21
- package/locales/ro.json +1 -1
- package/locales/ru/LC_MESSAGES/volto.po +100 -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 +97 -18
- package/locales/zh_CN/LC_MESSAGES/volto.po +96 -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 +36 -27
- package/razzle.config.js +16 -0
- package/src/actions/actions/actions.test.js +3 -3
- package/src/actions/addons/addons.test.js +15 -12
- package/src/actions/aliases/aliases.test.js +1 -1
- 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/querystring/querystring.test.js +2 -2
- package/src/actions/types/types.test.js +1 -1
- package/src/actions/users/users.js +2 -2
- package/src/components/manage/Actions/Actions.test.jsx +5 -1
- package/src/components/manage/Add/Add.jsx +27 -26
- package/src/components/manage/Add/Add.test.jsx +6 -3
- package/src/components/manage/Aliases/Aliases.test.jsx +7 -7
- package/src/components/manage/Blocks/Block/BlocksForm.jsx +1 -0
- package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +48 -16
- package/src/components/manage/Blocks/Block/Edit.jsx +3 -1
- package/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +9 -4
- package/src/components/manage/Blocks/Block/Settings.test.jsx +5 -1
- package/src/components/manage/Blocks/Block/StyleWrapper.jsx +11 -3
- package/src/components/manage/Blocks/Description/View.test.jsx +1 -1
- package/src/components/manage/Blocks/HTML/Edit.test.jsx +12 -5
- package/src/components/manage/Blocks/HTML/View.test.jsx +1 -1
- package/src/components/manage/Blocks/Image/Edit.jsx +5 -1
- package/src/components/manage/Blocks/Image/ImageSidebar.test.jsx +6 -2
- 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 +8 -1
- package/src/components/manage/Blocks/Listing/ImageGallery.jsx +6 -4
- package/src/components/manage/Blocks/Listing/View.test.jsx +3 -1
- package/src/components/manage/Blocks/Maps/Edit.jsx +2 -1
- package/src/components/manage/Blocks/Maps/MapsSidebar.test.jsx +5 -1
- package/src/components/manage/Blocks/Search/SearchBlockView.jsx +21 -4
- package/src/components/manage/Blocks/Search/components/DateRangeFacet.test.jsx +13 -7
- package/src/components/manage/Blocks/Search/components/SelectFacet.test.jsx +12 -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/Title/Edit.jsx +8 -2
- package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.test.jsx +11 -1
- package/src/components/manage/Blocks/Video/Edit.jsx +2 -1
- package/src/components/manage/Blocks/Video/VideoSidebar.test.jsx +5 -1
- package/src/components/manage/ConditionalLink/ConditionalLink.test.tsx +109 -0
- package/src/components/manage/ConditionalLink/ConditionalLink.tsx +36 -0
- package/src/components/manage/Contents/Contents.jsx +23 -2
- package/src/components/manage/Contents/Contents.test.jsx +36 -13
- 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 +5 -1
- package/src/components/manage/Contents/ContentsRenameModal.test.jsx +5 -1
- package/src/components/manage/Contents/ContentsTagsModal.test.jsx +5 -1
- package/src/components/manage/Contents/ContentsUploadModal.test.jsx +13 -22
- package/src/components/manage/Contents/ContentsWorkflowModal.test.jsx +5 -1
- package/src/components/manage/Contents/__mocks__/index.tsx +16 -0
- package/src/components/manage/Contents/__mocks__/index.vitest.tsx +5 -0
- package/src/components/manage/Controlpanels/AddonsControlpanel.test.jsx +28 -3
- package/src/components/manage/Controlpanels/Aliases.test.jsx +35 -3
- package/src/components/manage/Controlpanels/ContentType.jsx +1 -1
- package/src/components/manage/Controlpanels/ContentType.test.jsx +29 -3
- package/src/components/manage/Controlpanels/ContentTypeLayout.test.jsx +4 -2
- package/src/components/manage/Controlpanels/ContentTypes.test.jsx +25 -2
- package/src/components/manage/Controlpanels/Controlpanel.test.jsx +37 -6
- package/src/components/manage/Controlpanels/Controlpanels.test.jsx +47 -3
- package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.jsx +3 -2
- package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.test.jsx +15 -9
- package/src/components/manage/Controlpanels/ModerateComments.test.jsx +31 -5
- package/src/components/manage/Controlpanels/Rules/AddRule.test.jsx +13 -4
- package/src/components/manage/Controlpanels/Rules/ConfigureRule.test.jsx +9 -5
- package/src/components/manage/Controlpanels/Rules/EditRule.test.jsx +12 -4
- package/src/components/manage/Controlpanels/Rules/Rules.test.jsx +7 -3
- package/src/components/manage/Controlpanels/UndoControlpanel.test.jsx +33 -4
- package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +156 -175
- package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.test.jsx +3 -1
- package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +575 -630
- package/src/components/manage/Controlpanels/Users/UsersControlpanel.test.jsx +16 -9
- package/src/components/manage/Delete/Delete.test.jsx +45 -4
- package/src/components/manage/Diff/Diff.test.jsx +15 -6
- package/src/components/manage/Diff/DiffField.test.jsx +12 -6
- package/src/components/manage/Display/Display.test.jsx +17 -6
- package/src/components/manage/Edit/Edit.jsx +2 -3
- package/src/components/manage/Edit/Edit.test.jsx +11 -3
- package/src/components/manage/Form/BlockDataForm.test.jsx +5 -1
- package/src/components/manage/Form/Form.jsx +32 -0
- package/src/components/manage/Form/Form.test.jsx +27 -19
- package/src/components/manage/Form/InlineForm.jsx +2 -2
- package/src/components/manage/Form/InlineForm.test.jsx +5 -1
- package/src/components/manage/Form/ModalForm.test.jsx +5 -1
- package/src/components/manage/Form/__mocks__/index.tsx +17 -0
- package/src/components/manage/Form/__mocks__/index.vitest.tsx +73 -0
- package/src/components/manage/History/History.test.jsx +3 -1
- package/src/components/manage/LinksToItem/LinksToItem.test.jsx +6 -4
- package/src/components/manage/MaybeWrap/MaybeWrap.tsx +15 -0
- 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 +8 -3
- package/src/components/manage/Multilingual/TranslationObject.jsx +1 -1
- package/src/components/manage/Preferences/ChangePassword.test.jsx +9 -2
- package/src/components/manage/Preferences/PersonalInformation.test.jsx +3 -1
- package/src/components/manage/Preferences/PersonalPreferences.test.jsx +20 -7
- package/src/components/manage/Rules/Rules.test.jsx +6 -3
- package/src/components/manage/Sharing/Sharing.test.jsx +3 -1
- package/src/components/manage/Sidebar/ObjectBrowserNav.jsx +2 -1
- package/src/components/manage/Sidebar/ObjectBrowserNav.test.jsx +3 -3
- 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 +9 -7
- 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.test.jsx +196 -14
- package/src/components/manage/UniversalLink/UniversalLink.tsx +215 -0
- package/src/components/manage/Widgets/ArrayWidget.test.jsx +22 -5
- package/src/components/manage/Widgets/CheckboxGroupWidget.test.jsx +12 -5
- package/src/components/manage/Widgets/DatetimeWidget.jsx +5 -0
- package/src/components/manage/Widgets/DatetimeWidget.test.jsx +21 -6
- package/src/components/manage/Widgets/FileWidget.jsx +14 -8
- package/src/components/manage/Widgets/ImageWidget.jsx +176 -40
- package/src/components/manage/Widgets/InternalUrlWidget.jsx +2 -0
- package/src/components/manage/Widgets/NumberWidget.test.jsx +8 -7
- package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +3 -0
- package/src/components/manage/Widgets/ObjectListWidget.jsx +11 -1
- package/src/components/manage/Widgets/ObjectListWidget.test.jsx +18 -8
- package/src/components/manage/Widgets/ObjectWidget.test.jsx +5 -1
- package/src/components/manage/Widgets/RadioGroupWidget.test.jsx +12 -5
- package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.test.jsx +12 -6
- package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +44 -41
- package/src/components/manage/Widgets/SchemaWidget.test.jsx +12 -5
- package/src/components/manage/Widgets/SchemaWidgetFieldset.test.jsx +12 -5
- package/src/components/manage/Widgets/SelectAutoComplete.jsx +29 -12
- package/src/components/manage/Widgets/SelectAutoComplete.test.jsx +12 -6
- package/src/components/manage/Widgets/SelectWidget.jsx +3 -1
- package/src/components/manage/Widgets/SelectWidget.test.jsx +12 -6
- package/src/components/manage/Widgets/TimeWidget.test.jsx +13 -5
- package/src/components/manage/Widgets/TokenWidget.test.jsx +12 -6
- package/src/components/manage/Widgets/UrlWidget.jsx +2 -0
- package/src/components/manage/Widgets/VocabularyTermsWidget.test.jsx +18 -9
- package/src/components/manage/Widgets/__mocks__/index.tsx +16 -0
- package/src/components/manage/Widgets/__mocks__/index.vitest.tsx +41 -0
- package/src/components/manage/Workflow/Workflow.test.jsx +17 -7
- 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 +3 -1
- package/src/components/theme/App/App.test.jsx +22 -17
- package/src/components/theme/AppExtras/AppExtras.test.jsx +6 -6
- package/src/components/theme/Avatar/Avatar.jsx +2 -1
- package/src/components/theme/Comments/CommentEditModal.test.jsx +5 -1
- package/src/components/theme/Comments/Comments.test.jsx +29 -12
- package/src/components/theme/ContactForm/ContactForm.test.jsx +8 -4
- package/src/components/theme/FormattedDate/FormattedDate.stories.jsx +20 -2
- package/src/components/theme/Header/Header.test.jsx +19 -13
- package/src/components/theme/Image/Image.jsx +11 -8
- 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/Logout/Logout.test.jsx +1 -1
- package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +8 -12
- 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/PasswordReset.test.jsx +10 -1
- package/src/components/theme/PasswordReset/RequestPasswordReset.test.jsx +5 -1
- package/src/components/theme/PreviewImage/PreviewImage.jsx +1 -1
- package/src/components/theme/Register/Register.test.jsx +5 -1
- package/src/components/theme/RequestTimeout/RequestTimeout.jsx +1 -1
- package/src/components/theme/Search/Search.test.jsx +6 -4
- package/src/components/theme/Sitemap/Sitemap.jsx +6 -5
- package/src/components/theme/Sitemap/Sitemap.test.jsx +0 -1
- package/src/components/theme/TsTest/TsTest.test.tsx +0 -1
- package/src/components/theme/View/EventDatesInfo.test.jsx +12 -5
- package/src/components/theme/View/EventView.test.jsx +12 -5
- package/src/components/theme/View/FileView.jsx +9 -1
- package/src/components/theme/View/ListingView.test.jsx +2 -0
- package/src/components/theme/View/SummaryView.test.jsx +10 -0
- package/src/components/theme/View/TabularView.test.jsx +1 -0
- package/src/components/theme/View/View.jsx +1 -1
- package/src/components/theme/View/View.test.jsx +42 -23
- package/src/components/theme/Widgets/ImageWidget.jsx +2 -1
- package/src/config/ControlPanels.js +1 -0
- package/src/config/index.js +18 -25
- package/src/config/server.js +0 -2
- 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/Api/Api.plone.rest.test.js +11 -9
- package/src/helpers/Api/Api.test.js +11 -14
- package/src/helpers/AsyncConnect/AsyncConnect.test.jsx +145 -189
- package/src/helpers/AsyncConnect/ssr.js +4 -1
- package/src/helpers/AuthToken/AuthToken.test.js +60 -22
- package/src/helpers/Blocks/Blocks.test.js +1 -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/Html/Html.test.jsx +32 -28
- package/src/helpers/LanguageMap/LanguageMap.js +115 -8
- package/src/helpers/Loadable/__mocks__/Loadable.jsx +16 -1
- package/src/helpers/Loadable/__mocks__/Loadable.vitest.jsx +39 -0
- package/src/helpers/MessageLabels/MessageLabels.js +5 -0
- package/src/helpers/Sitemap/Sitemap.js +4 -4
- package/src/helpers/Url/Url.js +32 -2
- package/src/helpers/Url/Url.test.js +62 -0
- package/src/helpers/Utils/withSaveAsDraft.jsx +241 -0
- package/src/hooks/user/useUser.js +1 -1
- package/src/middleware/Api.test.js +51 -0
- package/src/middleware/api.js +78 -29
- package/src/middleware/storeProtectLoadUtils.test.js +93 -81
- 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/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-setup-config.jsx +0 -2
- package/test-setup-globals-vitest.js +46 -0
- package/theme/themes/pastanaga/collections/table.overrides +9 -0
- package/theme/themes/pastanaga/extras/blocks.less +26 -0
- package/theme/themes/pastanaga/extras/contents.less +17 -5
- package/theme/themes/pastanaga/extras/main.less +32 -2
- package/tsconfig.declarations.json +12 -1
- package/tsconfig.json +5 -5
- package/types/components/manage/Blocks/Teaser/schema.d.ts +1 -0
- package/types/components/manage/ConditionalLink/ConditionalLink.d.ts +11 -15
- package/types/components/manage/Contents/__mocks__/index.vitest.d.ts +2 -0
- 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.vitest.d.ts +8 -0
- package/types/components/manage/MaybeWrap/MaybeWrap.d.ts +7 -5
- package/types/components/manage/Sidebar/SidebarPortal.d.ts +7 -15
- package/types/components/manage/UniversalLink/UniversalLink.d.ts +54 -20
- package/types/components/manage/Widgets/ImageWidget.d.ts +41 -1
- package/types/components/manage/Widgets/RecurrenceWidget/Utils.d.ts +12 -18
- package/types/components/manage/Widgets/__mocks__/index.vitest.d.ts +33 -0
- package/types/components/theme/FormattedDate/FormattedDate.stories.d.ts +1 -1
- package/types/components/theme/LanguageSelector/LanguageSelector.d.ts +3 -10
- 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.vitest.d.ts +3 -0
- 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/helpers/Utils/withSaveAsDraft.d.ts +1 -0
- package/types/middleware/api.d.ts +6 -9
- package/types/react-router-hash-link.d.ts +12 -0
- package/types/reducers/index.d.ts +1 -0
- package/types/routes.d.ts +4 -0
- package/types/server.d.ts +1 -1
- package/types/start-client.d.ts +0 -1
- package/vite-plugins/svg.mjs +81 -0
- package/vitest.config.mjs +77 -0
- package/package-why.json +0 -34
- package/src/actions/content/content.multilingual.test.js +0 -17
- package/src/components/manage/ConditionalLink/ConditionalLink.jsx +0 -27
- package/src/components/manage/ConditionalLink/ConditionalLink.test.jsx +0 -30
- package/src/components/manage/MaybeWrap/MaybeWrap.jsx +0 -9
- package/src/components/manage/Sidebar/SidebarPortal.jsx +0 -47
- package/src/components/manage/Sidebar/SidebarPortal.test.jsx +0 -26
- package/src/components/manage/UniversalLink/UniversalLink.jsx +0 -154
- package/src/components/manage/Widgets/FileWidget.test.jsx +0 -91
- package/src/components/theme/LanguageSelector/LanguageSelector.jsx +0 -77
- package/theme/themes/pastanaga/extras/utils.less +0 -63
|
@@ -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
|
});
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import hoistNonReactStatics from 'hoist-non-react-statics';
|
|
3
|
+
import isEqual from 'react-fast-compare';
|
|
4
|
+
import { toast } from 'react-toastify';
|
|
5
|
+
import Icon from '@plone/volto/components/theme/Icon/Icon';
|
|
6
|
+
import Toast from '@plone/volto/components/manage/Toast/Toast';
|
|
7
|
+
import { Button } from 'semantic-ui-react';
|
|
8
|
+
import checkSVG from '@plone/volto/icons/check.svg';
|
|
9
|
+
import clearSVG from '@plone/volto/icons/clear.svg';
|
|
10
|
+
import { useIntl, defineMessages } from 'react-intl';
|
|
11
|
+
import { useLocation } from 'react-router-dom';
|
|
12
|
+
|
|
13
|
+
const messages = defineMessages({
|
|
14
|
+
autoSaveFound: {
|
|
15
|
+
id: 'Autosaved content found',
|
|
16
|
+
defaultMessage: 'Autosaved content found',
|
|
17
|
+
},
|
|
18
|
+
loadData: {
|
|
19
|
+
id: 'Do you want to restore your autosaved content?',
|
|
20
|
+
defaultMessage: 'Do you want to restore your autosaved content?',
|
|
21
|
+
},
|
|
22
|
+
loadExpiredData: {
|
|
23
|
+
id: "Another person edited this content, and it's currently displayed. Do you want to replace it with your autosaved content?",
|
|
24
|
+
defaultMessage:
|
|
25
|
+
"Another person edited this content, and it's currently displayed. Do you want to replace it with your autosaved content?",
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
function getDisplayName(WrappedComponent) {
|
|
30
|
+
return WrappedComponent.displayName || WrappedComponent.name || 'Component';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const mapSchemaToData = (schema, data) => {
|
|
34
|
+
if (!data) return {};
|
|
35
|
+
const dataKeys = Object.keys(data);
|
|
36
|
+
return Object.assign(
|
|
37
|
+
{},
|
|
38
|
+
...Object.keys(schema.properties)
|
|
39
|
+
.filter((k) => dataKeys.includes(k))
|
|
40
|
+
.map((k) => ({ [k]: data[k] })),
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// will be used to avoid using the first mount call if there is a second call
|
|
45
|
+
let mountTime;
|
|
46
|
+
|
|
47
|
+
const getFormId = (props, location) => {
|
|
48
|
+
const { type, pathname = location.pathname, isEditForm, schema } = props;
|
|
49
|
+
const id = isEditForm
|
|
50
|
+
? ['form', type, pathname].join('-')
|
|
51
|
+
: type
|
|
52
|
+
? ['form', pathname, type].join('-')
|
|
53
|
+
: schema?.properties?.comment
|
|
54
|
+
? ['form', pathname, 'comment'].join('-')
|
|
55
|
+
: ['form', pathname].join('-');
|
|
56
|
+
|
|
57
|
+
return id;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Toast content that has OK and Cancel buttons
|
|
62
|
+
* @param {function} onUpdate
|
|
63
|
+
* @param {function} onClose
|
|
64
|
+
* @param {string} userMessage
|
|
65
|
+
* @returns
|
|
66
|
+
*/
|
|
67
|
+
const ConfirmAutoSave = ({ onUpdate, onClose, userMessage }) => {
|
|
68
|
+
const handleClickOK = () => onUpdate();
|
|
69
|
+
const handleClickCancel = () => onClose();
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<div className="toast-box-center">
|
|
73
|
+
<div>{userMessage}</div>
|
|
74
|
+
<Button
|
|
75
|
+
icon
|
|
76
|
+
aria-label="Unchecked"
|
|
77
|
+
className="save toast-box"
|
|
78
|
+
onClick={handleClickOK}
|
|
79
|
+
>
|
|
80
|
+
<Icon
|
|
81
|
+
name={checkSVG}
|
|
82
|
+
size="24px"
|
|
83
|
+
className="circled toast-box-blue-icon"
|
|
84
|
+
/>
|
|
85
|
+
</Button>
|
|
86
|
+
<Button
|
|
87
|
+
icon
|
|
88
|
+
aria-label="Unchecked"
|
|
89
|
+
className="save toast-box"
|
|
90
|
+
onClick={handleClickCancel}
|
|
91
|
+
>
|
|
92
|
+
<Icon
|
|
93
|
+
name={clearSVG}
|
|
94
|
+
size="24px"
|
|
95
|
+
className="circled toast-box-blue-icon"
|
|
96
|
+
/>
|
|
97
|
+
</Button>
|
|
98
|
+
</div>
|
|
99
|
+
);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Will remove localStorage item using debounce
|
|
104
|
+
* @param {string} id
|
|
105
|
+
* @param {number} timerForDeletion
|
|
106
|
+
*/
|
|
107
|
+
const clearStorage = (id, timerForDeletion) => {
|
|
108
|
+
timerForDeletion.current && clearTimeout(timerForDeletion.current);
|
|
109
|
+
timerForDeletion.current = setTimeout(() => {
|
|
110
|
+
localStorage.removeItem(id);
|
|
111
|
+
}, 500);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Stale if server date is more recent
|
|
116
|
+
* @param {string} serverModifiedDate
|
|
117
|
+
* @param {string} autoSaveDate
|
|
118
|
+
* @returns {Boolean}
|
|
119
|
+
*/
|
|
120
|
+
const autoSaveFoundIsStale = (serverModifiedDate, autoSaveDate) => {
|
|
121
|
+
const result = !serverModifiedDate
|
|
122
|
+
? false
|
|
123
|
+
: new Date(serverModifiedDate) > new Date(autoSaveDate);
|
|
124
|
+
return result;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const draftApi = (id, schema, timer, timerForDeletion, intl) => ({
|
|
128
|
+
// - since Add Content Type will call componentDidMount twice, we will
|
|
129
|
+
// use the second call (using debounce)- the first will ignore any setState comands;
|
|
130
|
+
// - Delete local data only if user confirms Cancel
|
|
131
|
+
// - Will tell user that it has local stored data, even if its less recent than the server data
|
|
132
|
+
checkSavedDraft(state, updateCallback) {
|
|
133
|
+
if (!schema) return;
|
|
134
|
+
const saved = localStorage.getItem(id);
|
|
135
|
+
|
|
136
|
+
if (saved && Object.keys(JSON.parse(saved)).length > 1) {
|
|
137
|
+
const formData = mapSchemaToData(schema, state);
|
|
138
|
+
// includes autoSaveDate
|
|
139
|
+
const foundSavedData = JSON.parse(saved);
|
|
140
|
+
// includes only form data found in schema (no autoSaveDate)
|
|
141
|
+
const foundSavedSchemaData = mapSchemaToData(schema, foundSavedData);
|
|
142
|
+
|
|
143
|
+
if (!isEqual(formData, foundSavedSchemaData)) {
|
|
144
|
+
// eslint-disable-next-line no-alert
|
|
145
|
+
// cancel existing setTimeout to avoid using first call if
|
|
146
|
+
// successive calls are made
|
|
147
|
+
mountTime && clearTimeout(mountTime);
|
|
148
|
+
mountTime = setTimeout(() => {
|
|
149
|
+
toast.info(
|
|
150
|
+
<Toast
|
|
151
|
+
position="top-right"
|
|
152
|
+
info
|
|
153
|
+
autoClose={false}
|
|
154
|
+
title={intl.formatMessage(messages.autoSaveFound)}
|
|
155
|
+
content={
|
|
156
|
+
<ConfirmAutoSave
|
|
157
|
+
onUpdate={() => updateCallback(foundSavedSchemaData)}
|
|
158
|
+
onClose={() => clearStorage(id, timerForDeletion)}
|
|
159
|
+
userMessage={
|
|
160
|
+
autoSaveFoundIsStale(
|
|
161
|
+
state.modified,
|
|
162
|
+
foundSavedData.autoSaveDate,
|
|
163
|
+
)
|
|
164
|
+
? intl.formatMessage(messages.loadExpiredData)
|
|
165
|
+
: intl.formatMessage(messages.loadData)
|
|
166
|
+
}
|
|
167
|
+
/>
|
|
168
|
+
}
|
|
169
|
+
/>,
|
|
170
|
+
);
|
|
171
|
+
}, 300);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
// use debounce mode
|
|
176
|
+
onSaveDraft(state) {
|
|
177
|
+
if (!schema) return;
|
|
178
|
+
timer.current && clearTimeout(timer.current);
|
|
179
|
+
timer.current = setTimeout(() => {
|
|
180
|
+
const formData = mapSchemaToData(schema, state);
|
|
181
|
+
const saved = localStorage.getItem(id);
|
|
182
|
+
const newData = JSON.parse(saved);
|
|
183
|
+
|
|
184
|
+
localStorage.setItem(
|
|
185
|
+
id,
|
|
186
|
+
JSON.stringify({
|
|
187
|
+
...newData,
|
|
188
|
+
...formData,
|
|
189
|
+
autoSaveDate: new Date(),
|
|
190
|
+
}),
|
|
191
|
+
);
|
|
192
|
+
}, 300);
|
|
193
|
+
},
|
|
194
|
+
|
|
195
|
+
onCancelDraft() {
|
|
196
|
+
if (!schema) return;
|
|
197
|
+
clearStorage(id, timerForDeletion);
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
export default function withSaveAsDraft(options) {
|
|
202
|
+
const { forwardRef } = options;
|
|
203
|
+
|
|
204
|
+
return (WrappedComponent) => {
|
|
205
|
+
function WithSaveAsDraft(props) {
|
|
206
|
+
const { schema } = props;
|
|
207
|
+
const intl = useIntl();
|
|
208
|
+
const location = useLocation();
|
|
209
|
+
const id = getFormId(props, location);
|
|
210
|
+
const timmeRef = React.useRef();
|
|
211
|
+
const timmerForDeletionRef = React.useRef();
|
|
212
|
+
const api = React.useMemo(
|
|
213
|
+
() => draftApi(id, schema, timmeRef, timmerForDeletionRef, intl),
|
|
214
|
+
[id, schema, timmeRef, timmerForDeletionRef, intl],
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
return (
|
|
218
|
+
<WrappedComponent
|
|
219
|
+
{...props}
|
|
220
|
+
{...api}
|
|
221
|
+
ref={forwardRef ? props.forwardedRef : null}
|
|
222
|
+
/>
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
WithSaveAsDraft.displayName = `WithSaveAsDraft(${getDisplayName(
|
|
227
|
+
WrappedComponent,
|
|
228
|
+
)})`;
|
|
229
|
+
|
|
230
|
+
if (forwardRef) {
|
|
231
|
+
return hoistNonReactStatics(
|
|
232
|
+
React.forwardRef((props, ref) => (
|
|
233
|
+
<WithSaveAsDraft {...props} forwardedRef={ref} />
|
|
234
|
+
)),
|
|
235
|
+
WrappedComponent,
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return hoistNonReactStatics(WithSaveAsDraft, WrappedComponent);
|
|
240
|
+
};
|
|
241
|
+
}
|
|
@@ -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]);
|
|
@@ -25,6 +25,8 @@ describe('api middleware helpers', () => {
|
|
|
25
25
|
const result = addExpandersToPath(
|
|
26
26
|
'/de/mypage?expand=translations',
|
|
27
27
|
GET_CONTENT,
|
|
28
|
+
false,
|
|
29
|
+
true,
|
|
28
30
|
);
|
|
29
31
|
expect(result).toEqual('/de/mypage?expand=translations,mycustomexpander');
|
|
30
32
|
});
|
|
@@ -183,6 +185,8 @@ describe('api middleware helpers', () => {
|
|
|
183
185
|
const result = addExpandersToPath(
|
|
184
186
|
'/de/mypage/@navigation?expand=translations&expand.navigation.depth=3&someotherquery=1&someotherquery=2',
|
|
185
187
|
GET_CONTENT,
|
|
188
|
+
false,
|
|
189
|
+
true,
|
|
186
190
|
);
|
|
187
191
|
// No need to stringify
|
|
188
192
|
expect(result).toEqual(
|
|
@@ -282,4 +286,51 @@ describe('api middleware helpers', () => {
|
|
|
282
286
|
'/de/mypage?expand=navigation&expand.navigation.coolness=1&expand.navigation.depth=3&someotherquery=1&someotherquery=2',
|
|
283
287
|
);
|
|
284
288
|
});
|
|
289
|
+
|
|
290
|
+
it('addExpandersToPath - inherit expander merged using querystring as a function', () => {
|
|
291
|
+
config.settings.apiExpanders = [
|
|
292
|
+
{
|
|
293
|
+
match: '/',
|
|
294
|
+
GET_CONTENT: ['navigation'],
|
|
295
|
+
querystring: {
|
|
296
|
+
'expand.navigation.depth': 3,
|
|
297
|
+
'expand.navigation.coolness': 1,
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
match: '/',
|
|
302
|
+
GET_CONTENT: ['inherit'],
|
|
303
|
+
querystring: {
|
|
304
|
+
'expand.inherit.behaviors':
|
|
305
|
+
'voltolighttheme.header,voltolighttheme.theme,voltolighttheme.footer',
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
match: '/',
|
|
310
|
+
GET_CONTENT: ['inherit'],
|
|
311
|
+
querystring: (config, querystring) => {
|
|
312
|
+
if (querystring['expand.inherit.behaviors']) {
|
|
313
|
+
return {
|
|
314
|
+
'expand.inherit.behaviors': querystring[
|
|
315
|
+
'expand.inherit.behaviors'
|
|
316
|
+
].concat(',', 'plonegovbr.socialmedia.settings'),
|
|
317
|
+
};
|
|
318
|
+
} else {
|
|
319
|
+
return {
|
|
320
|
+
'expand.inherit.behaviors': 'plonegovbr.socialmedia.settings',
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
];
|
|
326
|
+
|
|
327
|
+
const result = addExpandersToPath(
|
|
328
|
+
'/de/mypage?someotherquery=1&someotherquery=2',
|
|
329
|
+
GET_CONTENT,
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
expect(result).toEqual(
|
|
333
|
+
'/de/mypage?expand=navigation,inherit&expand.inherit.behaviors=voltolighttheme.header,voltolighttheme.theme,voltolighttheme.footer,plonegovbr.socialmedia.settings&expand.navigation.coolness=1&expand.navigation.depth=3&someotherquery=1&someotherquery=2',
|
|
334
|
+
);
|
|
335
|
+
});
|
|
285
336
|
});
|
package/src/middleware/api.js
CHANGED
|
@@ -35,7 +35,7 @@ let socket = null;
|
|
|
35
35
|
*
|
|
36
36
|
* - It should add the expanders set in the config settings
|
|
37
37
|
* - It should preserve any query if present
|
|
38
|
-
* - It should preserve (and add) any expand parameter (if present)
|
|
38
|
+
* - It should preserve (and add) any expand parameter (if present)
|
|
39
39
|
* - It should take use the correct codification for arrays in querystring (repeated parameter for each member of the array)
|
|
40
40
|
*
|
|
41
41
|
* @function addExpandersToPath
|
|
@@ -43,7 +43,7 @@ let socket = null;
|
|
|
43
43
|
* @param {*} type The action type
|
|
44
44
|
* @returns {string} The url/path with the configured expanders added to the query string
|
|
45
45
|
*/
|
|
46
|
-
export function addExpandersToPath(path, type, isAnonymous) {
|
|
46
|
+
export function addExpandersToPath(path, type, isAnonymous, isMultilingual) {
|
|
47
47
|
const { settings } = config;
|
|
48
48
|
const { apiExpanders = [] } = settings;
|
|
49
49
|
|
|
@@ -58,7 +58,14 @@ export function addExpandersToPath(path, type, isAnonymous) {
|
|
|
58
58
|
|
|
59
59
|
const expandMerge = compact(
|
|
60
60
|
union([expand, ...flatten(expandersFromConfig)]),
|
|
61
|
-
).filter(
|
|
61
|
+
).filter(
|
|
62
|
+
// Remove types for anonymous, translations unless multilingual
|
|
63
|
+
(item) =>
|
|
64
|
+
!(
|
|
65
|
+
(item === 'types' && isAnonymous) ||
|
|
66
|
+
(item === 'translations' && !isMultilingual)
|
|
67
|
+
),
|
|
68
|
+
);
|
|
62
69
|
|
|
63
70
|
const stringifiedExpand = qs.stringify(
|
|
64
71
|
{ expand: expandMerge },
|
|
@@ -75,7 +82,7 @@ export function addExpandersToPath(path, type, isAnonymous) {
|
|
|
75
82
|
// The querystring accepts being a function to be able to take other
|
|
76
83
|
// config parameters
|
|
77
84
|
if (typeof querystring === 'function') {
|
|
78
|
-
querystring = querystring(config);
|
|
85
|
+
querystring = querystring(config, acc);
|
|
79
86
|
}
|
|
80
87
|
return { ...acc, ...querystring };
|
|
81
88
|
}, {});
|
|
@@ -128,6 +135,8 @@ function sendOnSocket(request) {
|
|
|
128
135
|
* @param {Object} api Api object.
|
|
129
136
|
* @returns {Promise} Action promise.
|
|
130
137
|
*/
|
|
138
|
+
let isHydrating = __CLIENT__ ? true : false;
|
|
139
|
+
|
|
131
140
|
const apiMiddlewareFactory =
|
|
132
141
|
(api) =>
|
|
133
142
|
({ dispatch, getState }) =>
|
|
@@ -135,14 +144,17 @@ const apiMiddlewareFactory =
|
|
|
135
144
|
(action) => {
|
|
136
145
|
const { settings } = config;
|
|
137
146
|
|
|
138
|
-
const
|
|
139
|
-
|
|
147
|
+
const state = getState();
|
|
148
|
+
const token = state.userSession.token;
|
|
149
|
+
let uploadedFiles = state.content.uploadedFiles;
|
|
150
|
+
const isMultilingual = state.site.data.features?.multilingual;
|
|
140
151
|
let isAnonymous = true;
|
|
141
152
|
if (token) {
|
|
142
153
|
const tokenExpiration = jwtDecode(token).exp;
|
|
143
154
|
const currentTime = new Date().getTime() / 1000;
|
|
144
155
|
isAnonymous = !token || currentTime > tokenExpiration;
|
|
145
156
|
}
|
|
157
|
+
const hasExistingError = state.content.get?.error;
|
|
146
158
|
|
|
147
159
|
if (typeof action === 'function') {
|
|
148
160
|
return action(dispatch, getState);
|
|
@@ -164,14 +176,24 @@ const apiMiddlewareFactory =
|
|
|
164
176
|
request.map((item) =>
|
|
165
177
|
sendOnSocket({
|
|
166
178
|
...item,
|
|
167
|
-
path: addExpandersToPath(
|
|
179
|
+
path: addExpandersToPath(
|
|
180
|
+
item.path,
|
|
181
|
+
type,
|
|
182
|
+
isAnonymous,
|
|
183
|
+
isMultilingual,
|
|
184
|
+
),
|
|
168
185
|
id: type,
|
|
169
186
|
}),
|
|
170
187
|
),
|
|
171
188
|
)
|
|
172
189
|
: sendOnSocket({
|
|
173
190
|
...request,
|
|
174
|
-
path: addExpandersToPath(
|
|
191
|
+
path: addExpandersToPath(
|
|
192
|
+
request.path,
|
|
193
|
+
type,
|
|
194
|
+
isAnonymous,
|
|
195
|
+
isMultilingual,
|
|
196
|
+
),
|
|
175
197
|
id: type,
|
|
176
198
|
});
|
|
177
199
|
} else {
|
|
@@ -180,7 +202,12 @@ const apiMiddlewareFactory =
|
|
|
180
202
|
? request.reduce((prevPromise, item) => {
|
|
181
203
|
return prevPromise.then((acc) => {
|
|
182
204
|
return api[item.op](
|
|
183
|
-
addExpandersToPath(
|
|
205
|
+
addExpandersToPath(
|
|
206
|
+
item.path,
|
|
207
|
+
type,
|
|
208
|
+
isAnonymous,
|
|
209
|
+
isMultilingual,
|
|
210
|
+
),
|
|
184
211
|
{
|
|
185
212
|
data: item.data,
|
|
186
213
|
type: item.type,
|
|
@@ -201,28 +228,42 @@ const apiMiddlewareFactory =
|
|
|
201
228
|
}, Promise.resolve([]))
|
|
202
229
|
: Promise.all(
|
|
203
230
|
request.map((item) =>
|
|
204
|
-
api[item.op](
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
action.type,
|
|
231
|
+
api[item.op](
|
|
232
|
+
addExpandersToPath(
|
|
233
|
+
item.path,
|
|
234
|
+
type,
|
|
235
|
+
isAnonymous,
|
|
236
|
+
isMultilingual,
|
|
211
237
|
),
|
|
212
|
-
|
|
213
|
-
|
|
238
|
+
{
|
|
239
|
+
data: item.data,
|
|
240
|
+
type: item.type,
|
|
241
|
+
headers: item.headers,
|
|
242
|
+
params: request.params,
|
|
243
|
+
checkUrl: settings.actions_raising_api_errors.includes(
|
|
244
|
+
action.type,
|
|
245
|
+
),
|
|
246
|
+
attach: item.attach,
|
|
247
|
+
},
|
|
248
|
+
),
|
|
214
249
|
),
|
|
215
250
|
)
|
|
216
|
-
: api[request.op](
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
251
|
+
: api[request.op](
|
|
252
|
+
addExpandersToPath(request.path, type, isAnonymous, isMultilingual),
|
|
253
|
+
{
|
|
254
|
+
data: request.data,
|
|
255
|
+
type: request.type,
|
|
256
|
+
headers: request.headers,
|
|
257
|
+
params: request.params,
|
|
258
|
+
checkUrl: settings.actions_raising_api_errors.includes(
|
|
259
|
+
action.type,
|
|
260
|
+
),
|
|
261
|
+
attach: request.attach,
|
|
262
|
+
},
|
|
263
|
+
);
|
|
224
264
|
actionPromise.then(
|
|
225
265
|
(result) => {
|
|
266
|
+
isHydrating = false;
|
|
226
267
|
if (uploadedFiles !== 0) {
|
|
227
268
|
dispatch(updateUploadedFiles(0));
|
|
228
269
|
}
|
|
@@ -298,8 +339,16 @@ const apiMiddlewareFactory =
|
|
|
298
339
|
}
|
|
299
340
|
},
|
|
300
341
|
(error) => {
|
|
342
|
+
// Make sure an error during hydration
|
|
343
|
+
// (for example when serving an archived page)
|
|
344
|
+
// doesn't hide the SSR content.
|
|
345
|
+
if (isHydrating && !hasExistingError) {
|
|
346
|
+
isHydrating = false;
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
301
350
|
// Only SSR can set ECONNREFUSED
|
|
302
|
-
if (error
|
|
351
|
+
if (error?.code === 'ECONNREFUSED') {
|
|
303
352
|
next({
|
|
304
353
|
...rest,
|
|
305
354
|
error,
|
|
@@ -310,7 +359,7 @@ const apiMiddlewareFactory =
|
|
|
310
359
|
}
|
|
311
360
|
|
|
312
361
|
// Response error is marked crossDomain if CORS error happen
|
|
313
|
-
else if (error
|
|
362
|
+
else if (error?.crossDomain) {
|
|
314
363
|
next({
|
|
315
364
|
...rest,
|
|
316
365
|
error,
|
|
@@ -361,7 +410,7 @@ const apiMiddlewareFactory =
|
|
|
361
410
|
...rest,
|
|
362
411
|
error,
|
|
363
412
|
statusCode: error.response,
|
|
364
|
-
message: error.response
|
|
413
|
+
message: error.response?.body?.message,
|
|
365
414
|
connectionRefused: false,
|
|
366
415
|
type: SET_APIERROR,
|
|
367
416
|
});
|