diff --git a/docs/source/contributing/bundle-size-optimization.md b/docs/source/contributing/bundle-size-optimization.md new file mode 100644 index 0000000000..3c0c5c5348 --- /dev/null +++ b/docs/source/contributing/bundle-size-optimization.md @@ -0,0 +1,42 @@ +--- +myst: + html_meta: + "description": "Bundle size optimization in Volto" + "property=og:description": "Bundle size optimization in Volto" + "property=og:title": "Bundle size optimization" + "keywords": "Volto, Plone, frontend, React, Performance, guidelines" +--- + +(bundle-size-optimization-label)= + +# Bundle size optimization + +This document describes how to optimize the bundle size of components through {term}`lazy loading` to improve page load times. +Contributors to Volto core should follow the guidelines in this document. + + +## Lazy loading in core + +Since Volto 18, several core components use lazy loading to keep the final build size under control. + +For example, the `Form` components are lazy loaded, which means that the code for the form components is only loaded when the user navigates to a page that contains a form. +A new index file has been created at `packages/volto/src/components/manage/Form/index.tsx` that exports the form components with lazy loading. +The `export`s in the main components index (`packages/volto/src/components/index.js`) have been updated to export components from the new specific index. +The same goes for other components that have been lazy loaded, such as the control panels and widgets. + +Several `import` statements have been updated to use the new lazy loaded components. +For example, the `Form` component is now imported from `@plone/volto/components/manage/Form` instead of `@plone/volto/components/manage/Form/Form`. +You should keep this in mind, and always import components from the specific component index files when available, while avoiding importing components from the main components index file, if possible. +This should also help to reduce circular dependencies, and help the overall build performance in the long run. + + +### Unit test components that use lazy loaded components + +If you import a component from a lazy loaded index, you can have issues with rendering these in unit tests. +Mocks are provided for lazy loaded components and are available for you to use. +This can be done by using the `jest.mock` function to mock the specific component index. +For example, to mock the `Form` component and all other components in the `Form`-specific index, you can use the following code in your test file: + +```javascript +jest.mock('@plone/volto/components/manage/Form'); +``` diff --git a/docs/source/contributing/index.md b/docs/source/contributing/index.md index 1e914a43a4..cc6b8d03b2 100644 --- a/docs/source/contributing/index.md +++ b/docs/source/contributing/index.md @@ -47,12 +47,14 @@ The Volto Team reviews pull requests only from people with a GitHub account who ```{include} ./branch-policy.md ``` + (contributing-install-volto-for-development-label)= ## Install Volto for development For developing Volto, follow {doc}`developing-core`. + (contributing-translations-label)= ## Translations @@ -125,6 +127,7 @@ redux routing icons accessibility-guidelines +bundle-size-optimization typescript volto-core-addons version-policy diff --git a/packages/coresandbox/src/components/Blocks/TestBlock/Data.tsx b/packages/coresandbox/src/components/Blocks/TestBlock/Data.tsx index 814cac8004..104ea631ee 100644 --- a/packages/coresandbox/src/components/Blocks/TestBlock/Data.tsx +++ b/packages/coresandbox/src/components/Blocks/TestBlock/Data.tsx @@ -1,5 +1,5 @@ import { useIntl } from 'react-intl'; -import { BlockDataForm } from '@plone/volto/components'; +import { BlockDataForm } from '@plone/volto/components/manage/Form'; import type { BlockEditProps } from '@plone/types'; const TestBlockData = (props: BlockEditProps) => { diff --git a/packages/volto-slate/news/5295.internal b/packages/volto-slate/news/5295.internal new file mode 100644 index 0000000000..146a3378a2 --- /dev/null +++ b/packages/volto-slate/news/5295.internal @@ -0,0 +1 @@ +Update imports to work with the new code split components in Volto. @pnicolli diff --git a/packages/volto-slate/src/blocks/Table/TableBlockEdit.jsx b/packages/volto-slate/src/blocks/Table/TableBlockEdit.jsx index 397bff13fd..96a493e9aa 100644 --- a/packages/volto-slate/src/blocks/Table/TableBlockEdit.jsx +++ b/packages/volto-slate/src/blocks/Table/TableBlockEdit.jsx @@ -11,7 +11,8 @@ import cx from 'classnames'; import { defineMessages, injectIntl } from 'react-intl'; import Cell from './Cell'; -import { BlockDataForm, Icon, SidebarPortal } from '@plone/volto/components'; +import { Icon, SidebarPortal } from '@plone/volto/components'; +import { BlockDataForm } from '@plone/volto/components/manage/Form'; import TableSchema from './schema'; import rowBeforeSVG from '@plone/volto/icons/row-before.svg'; diff --git a/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx b/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx index a94357f794..eeb1450dd9 100644 --- a/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx +++ b/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx @@ -12,11 +12,8 @@ import { validateFileUploadSize, } from '@plone/volto/helpers'; import config from '@plone/volto/registry'; -import { - BlockDataForm, - SidebarPortal, - BlockChooserButton, -} from '@plone/volto/components'; +import { SidebarPortal, BlockChooserButton } from '@plone/volto/components'; +import { BlockDataForm } from '@plone/volto/components/manage/Form'; import { SlateEditor } from '@plone/volto-slate/editor'; import { serializeNodesToText } from '@plone/volto-slate/editor/render'; diff --git a/packages/volto-slate/src/elementEditor/PluginEditor.jsx b/packages/volto-slate/src/elementEditor/PluginEditor.jsx index b7f866e7b7..e33b87ec27 100644 --- a/packages/volto-slate/src/elementEditor/PluginEditor.jsx +++ b/packages/volto-slate/src/elementEditor/PluginEditor.jsx @@ -3,7 +3,8 @@ import { isEqual } from 'lodash'; import React from 'react'; import { useDispatch } from 'react-redux'; import { ReactEditor } from 'slate-react'; -import { Icon as VoltoIcon, BlockDataForm } from '@plone/volto/components'; +import { Icon as VoltoIcon } from '@plone/volto/components'; +import { BlockDataForm } from '@plone/volto/components/manage/Form'; import { setPluginOptions } from '@plone/volto-slate/actions'; import BaseSchemaProvider from './SchemaProvider'; diff --git a/packages/volto-slate/src/widgets/HtmlSlateWidget.jsx b/packages/volto-slate/src/widgets/HtmlSlateWidget.jsx index 97385733a4..ba7367ccd9 100644 --- a/packages/volto-slate/src/widgets/HtmlSlateWidget.jsx +++ b/packages/volto-slate/src/widgets/HtmlSlateWidget.jsx @@ -9,7 +9,7 @@ import { MemoryRouter } from 'react-router-dom'; import { Provider, useSelector } from 'react-redux'; import { defineMessages, injectIntl } from 'react-intl'; -import { FormFieldWrapper } from '@plone/volto/components'; +import { FormFieldWrapper } from '@plone/volto/components/manage/Widgets'; import SlateEditor from '@plone/volto-slate/editor/SlateEditor'; import { serializeNodes } from '@plone/volto-slate/editor/render'; import { makeEditor } from '@plone/volto-slate/utils'; diff --git a/packages/volto-slate/src/widgets/ObjectByTypeWidget.jsx b/packages/volto-slate/src/widgets/ObjectByTypeWidget.jsx index 7730ddf557..a97f3c28de 100644 --- a/packages/volto-slate/src/widgets/ObjectByTypeWidget.jsx +++ b/packages/volto-slate/src/widgets/ObjectByTypeWidget.jsx @@ -1,6 +1,7 @@ import React from 'react'; import { Menu, Tab } from 'semantic-ui-react'; -import { Icon, ObjectWidget } from '@plone/volto/components'; +import { Icon } from '@plone/volto/components'; +import { ObjectWidget } from '@plone/volto/components/manage/Widgets'; export const ObjectByTypeWidget = (props) => { const { schemas, value = {}, onChange, errors = {}, id } = props; diff --git a/packages/volto-slate/src/widgets/RichTextWidget.jsx b/packages/volto-slate/src/widgets/RichTextWidget.jsx index 0428440681..6cc151ebc6 100644 --- a/packages/volto-slate/src/widgets/RichTextWidget.jsx +++ b/packages/volto-slate/src/widgets/RichTextWidget.jsx @@ -6,7 +6,7 @@ import React from 'react'; import isUndefined from 'lodash/isUndefined'; import isString from 'lodash/isString'; -import { FormFieldWrapper } from '@plone/volto/components'; +import { FormFieldWrapper } from '@plone/volto/components/manage/Widgets'; import SlateEditor from '@plone/volto-slate/editor/SlateEditor'; import { createEmptyParagraph, createParagraph } from '../utils/blocks'; diff --git a/packages/volto/cypress/support/commands.js b/packages/volto/cypress/support/commands.js index 0410029d94..6ae8849820 100644 --- a/packages/volto/cypress/support/commands.js +++ b/packages/volto/cypress/support/commands.js @@ -702,10 +702,7 @@ Cypress.Commands.add( 'pasteClipboard', { prevSubject: true }, (query, htmlContent) => { - return cy - .wrap(query) - .type(' {backspace}') - .trigger('paste', createHtmlPasteEvent(htmlContent)); + return cy.wrap(query).trigger('paste', createHtmlPasteEvent(htmlContent)); }, ); diff --git a/packages/volto/cypress/support/e2e.js b/packages/volto/cypress/support/e2e.js index 4698c07b09..a103bdc2c4 100644 --- a/packages/volto/cypress/support/e2e.js +++ b/packages/volto/cypress/support/e2e.js @@ -5,6 +5,15 @@ import './commands'; import { setupGuillotina, tearDownGuillotina } from './guillotina'; import { setup, teardown } from './reset-fixture'; +Cypress.on('uncaught:exception', (err) => { + // We are getting this error in Cypress tests but we don't use ResizeObserver ourselves + if (/ResizeObserver loop/.test(err.message)) { + // returning false here prevents Cypress from + // failing the test + return false; + } +}); + before(function () { if (Cypress.env('API') === 'guillotina') { tearDownGuillotina({ allowFail: true }); diff --git a/packages/volto/cypress/tests/core/controlpanels/upgrade.js b/packages/volto/cypress/tests/core/controlpanels/upgrade.js index 20dd2fbbb9..8b30cf6d5e 100644 --- a/packages/volto/cypress/tests/core/controlpanels/upgrade.js +++ b/packages/volto/cypress/tests/core/controlpanels/upgrade.js @@ -39,11 +39,12 @@ describe('Upgrade Site Tests', () => { body: { ...getUpgradeNeedsUpgrade, }, - }).as('getSystemNeedsUpdate'); + }).as('getUpgradeNeedsUpgrade'); cy.navigate('controlpanel'); cy.wait('@getSystemNeedsUpdate'); cy.findByText('Please continue with the upgrade.').click(); + cy.wait('@getUpgradeNeedsUpgrade'); cy.get('.content-area').contains( 'The site configuration is outdated and needs to be upgraded.', ); diff --git a/packages/volto/cypress/tests/core/volto-slate/06-block-slate-format-link.js b/packages/volto/cypress/tests/core/volto-slate/06-block-slate-format-link.js index b34867f541..8e7519ee61 100644 --- a/packages/volto/cypress/tests/core/volto-slate/06-block-slate-format-link.js +++ b/packages/volto/cypress/tests/core/volto-slate/06-block-slate-format-link.js @@ -100,7 +100,7 @@ describe('Block Tests: Links', () => { it('As editor I can add a link and pressing enter does not add another link in the next block', function () { // https://github.com/plone/volto/pull/5186 cy.get('#toolbar').click(); - cy.getSlate().type('Colorless green ideas sleep furiously'); + cy.getSlateEditorAndType('Colorless green ideas sleep furiously'); cy.log('Create a Link'); @@ -111,8 +111,8 @@ describe('Block Tests: Links', () => { 'https://google.com{enter}', ); cy.getSlate().should('have.descendants', 'a.slate-editor-link'); - cy.getSlate().type('{rightarrow}').type('{enter}'); - cy.getSlate().type('Hello').type('{enter}'); + cy.getSlateEditorAndType('{rightarrow}').type('{enter}'); + cy.getSlateEditorAndType('Hello').type('{enter}'); cy.toolbarSave(); diff --git a/packages/volto/news/5295.internal b/packages/volto/news/5295.internal new file mode 100644 index 0000000000..c6a8273fb7 --- /dev/null +++ b/packages/volto/news/5295.internal @@ -0,0 +1 @@ +Reduced JavaScript bundle size of the production build. Code split several internal modules: Controlpanels, Form, Widgets among other small ones. @pnicolli @deodorhunter diff --git a/packages/volto/package.json b/packages/volto/package.json index eafd481366..b1cdeae2fc 100644 --- a/packages/volto/package.json +++ b/packages/volto/package.json @@ -301,6 +301,7 @@ "@testing-library/react": "14.2.0", "@testing-library/react-hooks": "8.0.1", "@types/jest": "^29.5.8", + "@types/loadable__component": "^5.13.9", "@types/lodash": "^4.14.201", "@types/react": "^18", "@types/react-dom": "^18", diff --git a/packages/volto/src/components/index.js b/packages/volto/src/components/index.js index 22bff3e1d7..bcd0f9a8f8 100644 --- a/packages/volto/src/components/index.js +++ b/packages/volto/src/components/index.js @@ -75,39 +75,54 @@ export { default as AlbumView } from '@plone/volto/components/theme/View/AlbumVi export { default as Actions } from '@plone/volto/components/manage/Actions/Actions'; export { default as Add } from '@plone/volto/components/manage/Add/Add'; -export { default as AddonsControlpanel } from '@plone/volto/components/manage/Controlpanels/AddonsControlpanel'; -export { default as UndoControlpanel } from '@plone/volto/components/manage/Controlpanels/UndoControlpanel'; -export { default as Contents } from '@plone/volto/components/manage/Contents/Contents'; +export { + Controlpanels, + Controlpanel, + RulesControlpanel, + AddRuleControlpanel, + EditRuleControlpanel, + ConfigureRuleControlpanel, + UsersControlpanel, + RenderUsers, + UserGroupMembershipControlPanel, + GroupsControlpanel, + RenderGroups, + RelationsControlpanel, + AliasesControlpanel, + UndoControlpanel, + AddonsControlpanel, + ContentType, + ContentTypeLayout, + ContentTypeSchema, + ContentTypes, + VersionOverview, + UpgradeControlPanel, + ModerateComments, + DatabaseInformation, +} from '@plone/volto/components/manage/Controlpanels'; + export { default as Circle } from '@plone/volto/components/manage/Contents/circle'; -export { default as DatabaseInformation } from '@plone/volto/components/manage/Controlpanels/DatabaseInformation'; -export { default as Controlpanel } from '@plone/volto/components/manage/Controlpanels/Controlpanel'; -export { default as Controlpanels } from '@plone/volto/components/manage/Controlpanels/Controlpanels'; -export { default as AliasesControlpanel } from '@plone/volto/components/manage/Controlpanels/Aliases'; -export { default as ContentTypes } from '@plone/volto/components/manage/Controlpanels/ContentTypes'; -export { default as ContentType } from '@plone/volto/components/manage/Controlpanels/ContentType'; -export { default as ContentTypeLayout } from '@plone/volto/components/manage/Controlpanels/ContentTypeLayout'; -export { default as ContentTypeSchema } from '@plone/volto/components/manage/Controlpanels/ContentTypeSchema'; -export { default as ContentTypesActions } from '@plone/volto/components/manage/Controlpanels/ContentTypesActions'; -export { default as UsersControlpanel } from '@plone/volto/components/manage/Controlpanels/Users/UsersControlpanel'; -export { default as UserGroupMembershipControlPanel } from '@plone/volto/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel'; -export { default as Relations } from '@plone/volto/components/manage/Controlpanels/Relations/Relations'; -export { default as GroupsControlpanel } from '@plone/volto/components/manage/Controlpanels/Groups/GroupsControlpanel'; -export { default as RulesControlpanel } from '@plone/volto/components/manage/Controlpanels/Rules/Rules'; -export { default as AddRuleControlpanel } from '@plone/volto/components/manage/Controlpanels/Rules/AddRule'; -export { default as EditRuleControlpanel } from '@plone/volto/components/manage/Controlpanels/Rules/EditRule'; -export { default as ConfigureRuleControlpanel } from '@plone/volto/components/manage/Controlpanels/Rules/ConfigureRule'; -export { default as UpgradeControlPanel } from '@plone/volto/components/manage/Controlpanels/UpgradeControlPanel'; - -export { default as ModerateComments } from '@plone/volto/components/manage/Controlpanels/ModerateComments'; -export { default as VersionOverview } from '@plone/volto/components/manage/Controlpanels/VersionOverview'; + export { default as Delete } from '@plone/volto/components/manage/Delete/Delete'; -export { default as Diff } from '@plone/volto/components/manage/Diff/Diff'; +export const Diff = loadable( + () => + import( + /* webpackChunkName: "HistoryView" */ '@plone/volto/components/manage/Diff/Diff' + ), +); +export const DiffField = loadable( + () => + import( + /* webpackChunkName: "HistoryView" */ '@plone/volto/components/manage/Diff/DiffField' + ), +); export { default as Display } from '@plone/volto/components/manage/Display/Display'; export { default as Edit } from '@plone/volto/components/manage/Edit/Edit'; -export { default as ModalForm } from '@plone/volto/components/manage/Form/ModalForm'; export { default as History } from '@plone/volto/components/manage/History/History'; export { default as Sharing } from '@plone/volto/components/manage/Sharing/Sharing'; -export { default as Rules } from '@plone/volto/components/manage/Rules/Rules'; +export const Rules = loadable( + () => import('@plone/volto/components/manage/Rules/Rules'), +); export { default as Aliases } from '@plone/volto/components/manage/Aliases/Aliases'; export { default as LinksToItem } from '@plone/volto/components/manage/LinksToItem/LinksToItem'; export { default as Workflow } from '@plone/volto/components/manage/Workflow/Workflow'; @@ -124,58 +139,74 @@ export { default as Types } from '@plone/volto/components/manage/Toolbar/Types'; export { default as Toast } from '@plone/volto/components/manage/Toast/Toast'; export { default as ManageTranslations } from '@plone/volto/components/manage/Multilingual/ManageTranslations'; -// Potentially could ve removed from index, since they are internal components and -// we don't want them to end up in the main chunk -export { default as Form } from '@plone/volto/components/manage/Form/Form'; -export { default as BlocksToolbar } from '@plone/volto/components/manage/Form/BlocksToolbar'; -export { default as UndoToolbar } from '@plone/volto/components/manage/Form/UndoToolbar'; -export { default as Field } from '@plone/volto/components/manage/Form/Field'; +export { + Field, + InlineForm, + ModalForm, + UndoToolbar, + BlocksToolbar, + BlockDataForm, + BlocksForm, + Form, +} from '@plone/volto/components/manage/Form'; export { default as SearchTags } from '@plone/volto/components/theme/Search/SearchTags'; -export { default as CommentEditModal } from '@plone/volto/components/theme/Comments/CommentEditModal'; -export { default as ContentsBreadcrumbs } from '@plone/volto/components/manage/Contents/ContentsBreadcrumbs'; -export { default as ContentsIndexHeader } from '@plone/volto/components/manage/Contents/ContentsIndexHeader'; -export { default as ContentsItem } from '@plone/volto/components/manage/Contents/ContentsItem'; -export { default as ContentsUploadModal } from '@plone/volto/components/manage/Contents/ContentsUploadModal'; -export { default as ContentsPropertiesModal } from '@plone/volto/components/manage/Contents/ContentsPropertiesModal'; -export { default as ContentsRenameModal } from '@plone/volto/components/manage/Contents/ContentsRenameModal'; -export { default as ContentsWorkflowModal } from '@plone/volto/components/manage/Contents/ContentsWorkflowModal'; -export { default as ContentsTagsModal } from '@plone/volto/components/manage/Contents/ContentsTagsModal'; -export { default as RenderUsers } from '@plone/volto/components/manage/Controlpanels/Users/RenderUsers'; -export { default as RenderGroups } from '@plone/volto/components/manage/Controlpanels/Groups/RenderGroups'; -export { default as DiffField } from '@plone/volto/components/manage/Diff/DiffField'; +export { CommentEditModal } from '@plone/volto/components/theme/Comments'; +export { + Contents, + ContentsBreadcrumbs, + ContentsIndexHeader, + ContentsItem, + ContentsUploadModal, + ContentsPropertiesModal, + ContentsRenameModal, + ContentsWorkflowModal, + ContentsTagsModal, +} from '@plone/volto/components/manage/Contents'; export { default as DragDropList } from '@plone/volto/components/manage/DragDropList/DragDropList'; -export { default as InlineForm } from '@plone/volto/components/manage/Form/InlineForm'; -export { default as BlocksForm } from '@plone/volto/components/manage/Blocks/Block/BlocksForm'; -export { default as BlockDataForm } from '@plone/volto/components/manage/Form/BlockDataForm'; - -export { default as FormFieldWrapper } from '@plone/volto/components/manage/Widgets/FormFieldWrapper'; -export { default as ArrayWidget } from '@plone/volto/components/manage/Widgets/ArrayWidget'; -export { default as CheckboxWidget } from '@plone/volto/components/manage/Widgets/CheckboxWidget'; -export const DatetimeWidget = loadable( - () => import('@plone/volto/components/manage/Widgets/DatetimeWidget'), +export { + AlignWidget, + ButtonsWidget, + ArrayWidget, + CheckboxWidget, + FileWidget, + IdWidget, + PasswordWidget, + QueryWidget, + QuerySortOnWidget, + QuerystringWidget, + SchemaWidget, + SelectWidget, + TextareaWidget, + TextWidget, + TokenWidget, + WysiwygWidget, + UrlWidget, + InternalUrlWidget, + EmailWidget, + NumberWidget, + ImageSizeWidget, + RegistryImageWidget, + ReferenceWidget, + ObjectBrowserWidget, + ObjectWidget, + ObjectListWidget, + VocabularyTermsWidget, + SelectMetadataWidget, + SelectAutoComplete, + ColorPickerWidget, + DatetimeWidget, + RecurrenceWidget, + FormFieldWrapper, +} from '@plone/volto/components/manage/Widgets'; + +export const SchemaWidgetFieldset = loadable( + () => import('@plone/volto/components/manage/Widgets/SchemaWidgetFieldset'), ); -export const RecurrenceWidget = loadable( - () => - import( - '@plone/volto/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget' - ), +export const ObjectBrowserWidgetMode = loadable( + () => import('@plone/volto/components/manage/Widgets/ObjectBrowserWidget'), ); -export { default as FileWidget } from '@plone/volto/components/manage/Widgets/FileWidget'; -export { default as IdWidget } from '@plone/volto/components/manage/Widgets/IdWidget'; -export { default as PasswordWidget } from '@plone/volto/components/manage/Widgets/PasswordWidget'; -export { default as ReferenceWidget } from '@plone/volto/components/manage/Widgets/ReferenceWidget'; -export { default as SchemaWidget } from '@plone/volto/components/manage/Widgets/SchemaWidget'; -export { default as SchemaWidgetFieldset } from '@plone/volto/components/manage/Widgets/SchemaWidgetFieldset'; -export { default as SelectWidget } from '@plone/volto/components/manage/Widgets/SelectWidget'; -export { default as TextareaWidget } from '@plone/volto/components/manage/Widgets/TextareaWidget'; -export { default as TextWidget } from '@plone/volto/components/manage/Widgets/TextWidget'; -export { default as ObjectBrowserWidget } from '@plone/volto/components/manage/Widgets/ObjectBrowserWidget'; -export { default as ObjectBrowserWidgetMode } from '@plone/volto/components/manage/Widgets/ObjectBrowserWidget'; -export { default as ObjectWidget } from '@plone/volto/components/manage/Widgets/ObjectWidget'; -export { default as ObjectListWidget } from '@plone/volto/components/manage/Widgets/ObjectListWidget'; - export { default as EditDefaultBlock } from '@plone/volto/components/manage/Blocks/Block/DefaultEdit'; export { default as EditDescriptionBlock } from '@plone/volto/components/manage/Blocks/Description/Edit'; export { default as EditTitleBlock } from '@plone/volto/components/manage/Blocks/Title/Edit'; diff --git a/packages/volto/src/components/manage/Actions/Actions.jsx b/packages/volto/src/components/manage/Actions/Actions.jsx index 765ba01c20..9d063146c6 100644 --- a/packages/volto/src/components/manage/Actions/Actions.jsx +++ b/packages/volto/src/components/manage/Actions/Actions.jsx @@ -8,7 +8,8 @@ import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; import { cut, copy, copyContent, moveContent } from '@plone/volto/actions'; import { getBaseUrl } from '@plone/volto/helpers'; -import { ContentsRenameModal, Toast } from '@plone/volto/components'; +import { Toast } from '@plone/volto/components'; +import { ContentsRenameModal } from '@plone/volto/components/manage/Contents'; const messages = defineMessages({ cut: { diff --git a/packages/volto/src/components/manage/Actions/Actions.test.jsx b/packages/volto/src/components/manage/Actions/Actions.test.jsx index ba2032f6a1..d66f98dabb 100644 --- a/packages/volto/src/components/manage/Actions/Actions.test.jsx +++ b/packages/volto/src/components/manage/Actions/Actions.test.jsx @@ -8,9 +8,7 @@ import Actions from './Actions'; const mockStore = configureStore(); -jest.mock('../Contents/ContentsRenameModal', () => - jest.fn(() =>
), -); +jest.mock('@plone/volto/components/manage/Contents'); describe('Actions', () => { it('renders an actions component', () => { diff --git a/packages/volto/src/components/manage/Actions/__snapshots__/Actions.test.jsx.snap b/packages/volto/src/components/manage/Actions/__snapshots__/Actions.test.jsx.snap index 51c4c11017..db5940cde3 100644 --- a/packages/volto/src/components/manage/Actions/__snapshots__/Actions.test.jsx.snap +++ b/packages/volto/src/components/manage/Actions/__snapshots__/Actions.test.jsx.snap @@ -92,7 +92,7 @@ exports[`Actions renders an actions component 1`] = `
diff --git a/packages/volto/src/components/manage/Add/Add.jsx b/packages/volto/src/components/manage/Add/Add.jsx index cf5057267b..0510b43f5a 100644 --- a/packages/volto/src/components/manage/Add/Add.jsx +++ b/packages/volto/src/components/manage/Add/Add.jsx @@ -23,13 +23,13 @@ import { setFormData, } from '@plone/volto/actions'; import { - Form, Icon, Toolbar, Sidebar, Toast, TranslationObject, } from '@plone/volto/components'; +import { Form } from '@plone/volto/components/manage/Form'; import { getBaseUrl, hasBlocksData, diff --git a/packages/volto/src/components/manage/Blocks/Block/DefaultEdit.jsx b/packages/volto/src/components/manage/Blocks/Block/DefaultEdit.jsx index f15953cba0..f8fab927af 100644 --- a/packages/volto/src/components/manage/Blocks/Block/DefaultEdit.jsx +++ b/packages/volto/src/components/manage/Blocks/Block/DefaultEdit.jsx @@ -2,7 +2,7 @@ import React from 'react'; import config from '@plone/volto/registry'; import { useIntl } from 'react-intl'; import { SidebarPortal } from '@plone/volto/components'; -import { BlockDataForm } from '@plone/volto/components'; +import { BlockDataForm } from '@plone/volto/components/manage/Form'; import DefaultBlockView from './DefaultView'; const DefaultBlockEdit = (props) => { diff --git a/packages/volto/src/components/manage/Blocks/Block/Settings.jsx b/packages/volto/src/components/manage/Blocks/Block/Settings.jsx index 9c72d5a084..0501f324fd 100644 --- a/packages/volto/src/components/manage/Blocks/Block/Settings.jsx +++ b/packages/volto/src/components/manage/Blocks/Block/Settings.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { injectIntl } from 'react-intl'; -import BlockDataForm from '@plone/volto/components/manage/Form/BlockDataForm'; +import { BlockDataForm } from '@plone/volto/components/manage/Form'; const Settings = ({ data, diff --git a/packages/volto/src/components/manage/Blocks/Block/Settings.test.jsx b/packages/volto/src/components/manage/Blocks/Block/Settings.test.jsx index 8cc2a7f301..237b53d556 100644 --- a/packages/volto/src/components/manage/Blocks/Block/Settings.test.jsx +++ b/packages/volto/src/components/manage/Blocks/Block/Settings.test.jsx @@ -5,6 +5,8 @@ import configureStore from 'redux-mock-store'; import config from '@plone/volto/registry'; import { Provider } from 'react-intl-redux'; +jest.mock('@plone/volto/components/manage/Form'); + const mockStore = configureStore(); const withStateManagement = diff --git a/packages/volto/src/components/manage/Blocks/Block/__snapshots__/Settings.test.jsx.snap b/packages/volto/src/components/manage/Blocks/Block/__snapshots__/Settings.test.jsx.snap index d60a35d1da..a629ca9637 100644 --- a/packages/volto/src/components/manage/Blocks/Block/__snapshots__/Settings.test.jsx.snap +++ b/packages/volto/src/components/manage/Blocks/Block/__snapshots__/Settings.test.jsx.snap @@ -3,15 +3,18 @@ exports[`Settings renders block settings form without schema enhancers 1`] = `
-
-
-
-
+ data-schema="{ + \\"fieldsets\\": [ + { + \\"title\\": \\"Default\\", + \\"id\\": \\"default\\", + \\"fields\\": [] + } + ], + \\"properties\\": {}, + \\"required\\": [] +}" + id="BlockDataForm" + />
`; diff --git a/packages/volto/src/components/manage/Blocks/Container/Data.jsx b/packages/volto/src/components/manage/Blocks/Container/Data.jsx index 76c18b5c72..d9b24bf6e0 100644 --- a/packages/volto/src/components/manage/Blocks/Container/Data.jsx +++ b/packages/volto/src/components/manage/Blocks/Container/Data.jsx @@ -1,5 +1,5 @@ import { useIntl } from 'react-intl'; -import { BlockDataForm } from '@plone/volto/components'; +import { BlockDataForm } from '@plone/volto/components/manage/Form'; const ContainerData = (props) => { const { block, blocksConfig, data, onChangeBlock, navRoot, contentType } = diff --git a/packages/volto/src/components/manage/Blocks/Container/Edit.jsx b/packages/volto/src/components/manage/Blocks/Container/Edit.jsx index df72ef7228..6c7fa892cb 100644 --- a/packages/volto/src/components/manage/Blocks/Container/Edit.jsx +++ b/packages/volto/src/components/manage/Blocks/Container/Edit.jsx @@ -1,7 +1,8 @@ import { useState } from 'react'; import { useIntl } from 'react-intl'; import { pickBy } from 'lodash'; -import { BlocksForm, SidebarPortal } from '@plone/volto/components'; +import { SidebarPortal } from '@plone/volto/components'; +import { BlocksForm } from '@plone/volto/components/manage/Form'; import PropTypes from 'prop-types'; import ContainerData from './Data'; import DefaultEditBlockWrapper from './EditBlockWrapper'; diff --git a/packages/volto/src/components/manage/Blocks/Image/ImageSidebar.jsx b/packages/volto/src/components/manage/Blocks/Image/ImageSidebar.jsx index 2df5c64190..94a43e1d3c 100644 --- a/packages/volto/src/components/manage/Blocks/Image/ImageSidebar.jsx +++ b/packages/volto/src/components/manage/Blocks/Image/ImageSidebar.jsx @@ -3,7 +3,8 @@ import PropTypes from 'prop-types'; import { Segment, Button } from 'semantic-ui-react'; import { useIntl, FormattedMessage, defineMessages } from 'react-intl'; import { flattenToAppURL, isInternalURL } from '@plone/volto/helpers'; -import { BlockDataForm, Icon, Image } from '@plone/volto/components'; +import { Icon, Image } from '@plone/volto/components'; +import { BlockDataForm } from '@plone/volto/components/manage/Form'; import { ImageSchema } from './schema'; import imageSVG from '@plone/volto/icons/image.svg'; import trashSVG from '@plone/volto/icons/delete.svg'; diff --git a/packages/volto/src/components/manage/Blocks/Image/ImageSidebar.test.jsx b/packages/volto/src/components/manage/Blocks/Image/ImageSidebar.test.jsx index bc070b1d89..725237aff8 100644 --- a/packages/volto/src/components/manage/Blocks/Image/ImageSidebar.test.jsx +++ b/packages/volto/src/components/manage/Blocks/Image/ImageSidebar.test.jsx @@ -5,6 +5,8 @@ import { Provider } from 'react-intl-redux'; import ImageSidebar from './ImageSidebar'; +jest.mock('@plone/volto/components/manage/Form'); + const mockStore = configureStore(); test('renders an Image Block Sidebar component', () => { diff --git a/packages/volto/src/components/manage/Blocks/Image/__snapshots__/ImageSidebar.test.jsx.snap b/packages/volto/src/components/manage/Blocks/Image/__snapshots__/ImageSidebar.test.jsx.snap index e4e4544a01..ebfafbc06e 100644 --- a/packages/volto/src/components/manage/Blocks/Image/__snapshots__/ImageSidebar.test.jsx.snap +++ b/packages/volto/src/components/manage/Blocks/Image/__snapshots__/ImageSidebar.test.jsx.snap @@ -58,125 +58,57 @@ Array [ />
,
-
-
-
- Alt text - - - - Describe the purpose of the image. - - - Leave empty if the image is purely decorative. -
-
- Alignment - - - No description -
-
- Image size - - - No description -
-
-
-
- -
-
, + data-schema="{ + \\"fieldsets\\": [ + { + \\"id\\": \\"default\\", + \\"title\\": \\"Default\\", + \\"fields\\": [ + \\"alt\\", + \\"align\\", + \\"size\\" + ] + }, + { + \\"id\\": \\"link_settings\\", + \\"title\\": \\"Link settings\\", + \\"fields\\": [ + \\"href\\", + \\"openLinkInNewTab\\" + ] + } + ], + \\"properties\\": { + \\"alt\\": { + \\"title\\": \\"Alt text\\" + }, + \\"align\\": { + \\"title\\": \\"Alignment\\", + \\"widget\\": \\"align\\" + }, + \\"size\\": { + \\"title\\": \\"Image size\\", + \\"widget\\": \\"image_size\\" + }, + \\"href\\": { + \\"title\\": \\"Link to\\", + \\"widget\\": \\"object_browser\\", + \\"mode\\": \\"link\\", + \\"selectedItemAttrs\\": [ + \\"Title\\", + \\"Description\\", + \\"hasPreviewImage\\" + ], + \\"allowExternals\\": true + }, + \\"openLinkInNewTab\\": { + \\"title\\": \\"Open in a new tab\\", + \\"type\\": \\"boolean\\" + } + }, + \\"required\\": [] +}" + id="BlockDataForm" + />, ] `; diff --git a/packages/volto/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx b/packages/volto/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx index 8998fc1be1..5a126ec2cc 100644 --- a/packages/volto/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx +++ b/packages/volto/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx @@ -3,12 +3,11 @@ import PropTypes from 'prop-types'; import { Form } from 'semantic-ui-react'; import { Accordion, Grid, Segment } from 'semantic-ui-react'; import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; +import { Icon, Image } from '@plone/volto/components'; import { CheckboxWidget, - Icon, - Image, TextWidget, -} from '@plone/volto/components'; +} from '@plone/volto/components/manage/Widgets'; import { flattenToAppURL } from '@plone/volto/helpers'; import AlignBlock from '@plone/volto/components/manage/Sidebar/AlignBlock'; diff --git a/packages/volto/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx b/packages/volto/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx index a606afff4e..6eb8e5e98e 100644 --- a/packages/volto/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +++ b/packages/volto/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx @@ -5,6 +5,8 @@ import { Provider } from 'react-intl-redux'; import LeadImageSidebar from './LeadImageSidebar'; +jest.mock('@plone/volto/components/manage/Widgets'); + const mockStore = configureStore(); test('renders a Lead Image block Sidebar component', () => { diff --git a/packages/volto/src/components/manage/Blocks/LeadImage/__snapshots__/LeadImageSidebar.test.jsx.snap b/packages/volto/src/components/manage/Blocks/LeadImage/__snapshots__/LeadImageSidebar.test.jsx.snap index 92ec28dabf..07e5ee1607 100644 --- a/packages/volto/src/components/manage/Blocks/LeadImage/__snapshots__/LeadImageSidebar.test.jsx.snap +++ b/packages/volto/src/components/manage/Blocks/LeadImage/__snapshots__/LeadImageSidebar.test.jsx.snap @@ -29,84 +29,8 @@ exports[`renders a Lead Image block Sidebar component 1`] = ` className="ui segment form sidebar-image-data" >
-
-
-
-
- -
-
-
-
- -