From f651bf69cf8e54128a11e808386eeeac8a4ca175 Mon Sep 17 00:00:00 2001 From: Tisha Soumya Date: Tue, 13 Aug 2024 06:08:22 +0530 Subject: [PATCH 1/2] Refactor Register (#4861) Co-authored-by: Nilesh Co-authored-by: Jefferson Bledsoe Co-authored-by: ichim-david --- packages/volto/news/4861.feature | 1 + .../components/theme/Register/Register.jsx | 212 ++++++------------ .../theme/Register/Register.stories.jsx | 49 ++++ 3 files changed, 120 insertions(+), 142 deletions(-) create mode 100644 packages/volto/news/4861.feature create mode 100644 packages/volto/src/components/theme/Register/Register.stories.jsx diff --git a/packages/volto/news/4861.feature b/packages/volto/news/4861.feature new file mode 100644 index 0000000000..c5521a45f1 --- /dev/null +++ b/packages/volto/news/4861.feature @@ -0,0 +1 @@ +Refactor the `Register` component from class-based to functional. @Tishasoumya-02 diff --git a/packages/volto/src/components/theme/Register/Register.jsx b/packages/volto/src/components/theme/Register/Register.jsx index f993e455cf..e8fc522e7d 100644 --- a/packages/volto/src/components/theme/Register/Register.jsx +++ b/packages/volto/src/components/theme/Register/Register.jsx @@ -1,17 +1,10 @@ -/** - * Register container. - * @module components/theme/Register/Register - */ - -import React, { Component } from 'react'; -import { Helmet } from '@plone/volto/helpers'; -import { connect } from 'react-redux'; -import { compose } from 'redux'; -import { defineMessages, injectIntl } from 'react-intl'; -import PropTypes from 'prop-types'; -import { withRouter } from 'react-router-dom'; +import { useEffect, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { defineMessages, useIntl } from 'react-intl'; +import { useHistory } from 'react-router-dom'; import { toast } from 'react-toastify'; +import { Helmet, usePrevious } from '@plone/volto/helpers'; import { Toast } from '@plone/volto/components'; import { Form } from '@plone/volto/components/manage/Form'; import { createUser } from '@plone/volto/actions'; @@ -56,146 +49,81 @@ const messages = defineMessages({ defaultMessage: 'Register', }, }); +const useUsers = () => { + const error = useSelector((state) => state.users.create.error); + const loading = useSelector((state) => state.users.create.loading); + const loaded = useSelector((state) => state.users.create.loaded); -/** - * Register class. - * @class Register - * @extends Component - */ -class Register extends Component { - /** - * Property types. - * @property {Object} propTypes Property types. - * @static - */ - static propTypes = { - createUser: PropTypes.func.isRequired, - loading: PropTypes.bool.isRequired, - loaded: PropTypes.bool.isRequired, - error: PropTypes.shape({ - message: PropTypes.string, - }), - }; + return { error, loaded, loading }; +}; +const Register = () => { + const dispatch = useDispatch(); + const intl = useIntl(); + const history = useHistory(); + const [errors, setError] = useState(null); + const { loaded, loading, error } = useUsers(); - /** - * Default properties. - * @property {Object} defaultProps Default properties. - * @static - */ - static defaultProps = { - error: null, - }; + const prevloading = usePrevious(loading); - /** - * Constructor - * @method constructor - * @param {Object} props Component properties - * @constructs WysiwygEditor - */ - constructor(props) { - super(props); - this.onSubmit = this.onSubmit.bind(this); - this.state = { - error: null, - }; - } - - /** - * Component will receive props - * @method componentWillReceiveProps - * @param {Object} nextProps Next properties - * @returns {undefined} - */ - UNSAFE_componentWillReceiveProps(nextProps) { - if (this.props.loading && nextProps.loaded) { + useEffect(() => { + if (prevloading && loaded) { toast.success( , ); - this.props.history.push('/login'); + history.push('/login'); } - } + }, [intl, history, loaded, prevloading]); - /** - * On submit handler - * @method onSubmit - * @param {object} data Form data. - * @returns {undefined} - */ - onSubmit(data) { - this.props.createUser({ - fullname: data.fullname, - email: data.email, - sendPasswordReset: true, - }); - this.setState({ - error: null, - }); - } + const onSubmit = (data) => { + const { fullname, email } = data; + dispatch( + createUser({ + fullname: fullname, + email: email, + sendPasswordReset: true, + }), + ); + setError(null); + }; - /** - * Render method. - * @method render - * @returns {string} Markup for the component. - */ - render() { - return ( -
- -
+ + -
- ); - } -} + ], + properties: { + fullname: { + type: 'string', + title: intl.formatMessage(messages.fullnameTitle), + description: intl.formatMessage(messages.fullnameDescription), + }, + email: { + type: 'string', + title: intl.formatMessage(messages.emailTitle), + description: intl.formatMessage(messages.emailDescription), + }, + }, + required: ['fullname', 'email'], + }} + /> + + ); +}; -export default compose( - withRouter, - injectIntl, - connect( - (state) => ({ - loading: state.users.create.loading, - loaded: state.users.create.loaded, - error: state.users.create.error, - }), - { createUser }, - ), -)(Register); +export default Register; diff --git a/packages/volto/src/components/theme/Register/Register.stories.jsx b/packages/volto/src/components/theme/Register/Register.stories.jsx new file mode 100644 index 0000000000..a3861a7072 --- /dev/null +++ b/packages/volto/src/components/theme/Register/Register.stories.jsx @@ -0,0 +1,49 @@ +import { injectIntl } from 'react-intl'; +import React from 'react'; +import RegisterComponent from './Register'; +import { RealStoreWrapper as Wrapper } from '@plone/volto/storybook'; + +const IntlRegister = injectIntl(RegisterComponent); + +function StoryComponent(args) { + return ( + +
+ + + ); +} + +export const Default = StoryComponent.bind({}); +Default.args = { + error: false, +}; + +export default { + title: 'Public components/Register', + component: RegisterComponent, + + decorators: [ + (Story) => ( +
+ +
+ ), + ], + + argTypes: {}, +}; From 861554273f4b1679059b8cc59005c21d0a49115f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 12 Aug 2024 17:44:41 -0700 Subject: [PATCH 2/2] Set the `LANGUAGE` environment variable in the Docker backend (#6231) Co-authored-by: David Glick --- docs/source/configuration/multilingual.md | 32 ++++++------- docs/source/contributing/developing-core.md | 51 +++++++++++++++++---- packages/volto/Makefile | 5 +- packages/volto/news/6231.internal | 1 + 4 files changed, 63 insertions(+), 26 deletions(-) create mode 100644 packages/volto/news/6231.internal diff --git a/docs/source/configuration/multilingual.md b/docs/source/configuration/multilingual.md index f9b7888f61..1fd4929a40 100644 --- a/docs/source/configuration/multilingual.md +++ b/docs/source/configuration/multilingual.md @@ -9,13 +9,14 @@ myst: # Multilingual -Volto provide support for Plone's Multilingual feature. You need to install Multiligual -support in Plone (`plone.app.multilingual` add-on), that comes available by default since -Plone 5 and can be installed in Plone's control panel. +Volto provides support for Plone's multilingual feature through the Plone core add-on `plone.app.multilingual`. +It is included with Plone 5 and later. +You can enable it through the {guilabel}`Add-ons` control panel in the administrative interface. + ## Volto configuration -You need to enable multilingual in Volto's configuration object: +You need to enable multilingual in Volto's configuration object. ```js import config from '@plone/volto/registry' @@ -28,22 +29,21 @@ config.settings = { } ``` -Declare the language you want to support in your site in the `supportedLanguages` array, -and which is the default language of your site. +Declare the language you want to support in your site in the `supportedLanguages` array, and which is the default language of your site. ```{warning} -The default language and the supported languages must match the one set in the Plone -side, and those should be set using GenericSetup using your policy package, or -manually via the Languages control panel, i.e. en for English, or pt-br for Portuguese (Brazil) +The default language and the supported languages must match those set in the Plone backend. +Those should be set either using GenericSetup using your policy package or manually via the {guilabel}`Languages` control panel. +Examples include `en` for English, or `pt-br` for Portuguese (Brazil). ``` ## Features -Volto Multilingual features include: +Volto multilingual includes the following features. -- Language detector that detects the language preference (cookie) and redirects to the related language root folder -- Language switcher that allows user to switch between languages -- Add menu entries that allows to create and link a new content with the original one in one of the supported languages set in the site -- When users use the language switcher to change language from a translated content, they are redirected to the linked content (within the same translation group) -- Manual link two objects (Manage translations link in More menu) -- Manual deletion of a link (unlink) between two objects (Manage translations link in More menu) +- language detector that detects the language preference from a cookie, and redirects to the related language root folder +- language switcher that allows the user to switch between languages +- adds menu entries that allows to create and link a new content item with the original one in one of the supported languages set in the site +- when users use the language switcher to change the language from a translated content, they are redirected to the linked content within the same translation group +- manually link two objects via the {guilabel}`Manage translations` link under the {guilabel}`More` menu +- manually delete a link (or unlink) between two objects ({guilabel}`Manage translations` link under the {guilabel}`More` menu) diff --git a/docs/source/contributing/developing-core.md b/docs/source/contributing/developing-core.md index c83a1e11cd..eb79d97c8a 100644 --- a/docs/source/contributing/developing-core.md +++ b/docs/source/contributing/developing-core.md @@ -169,7 +169,19 @@ pnpm install ``` -## Start the backend and Volto +(develop-volto-start-plone-label)= + +## Start Plone + +Every time you want to run Volto for core development, you will need to create two terminal sessions, one for the {ref}`backend ` and one for the {ref}`frontend `. +For both sessions, change your working directory to the root of your Volto clone. + +To stop either the backend or frontend, use {kbd}`ctrl-c`. + + +(develop-volto-start-the-backend-label)= + +### Start the backend `````{versionadded} 18.0.0-alpha.42 Persist backend data across Docker sessions. @@ -184,10 +196,8 @@ It is intended only for development. ```` ````` -Every time you want to run Volto for core development, you will need to create two terminal sessions, one for the backend and one for the frontend. -For both sessions, change your working directory to the root of your Volto clone. - In the first session, start the backend. +You can browse to the backend running at http://localhost:8080. ```shell make backend-docker-start @@ -206,10 +216,35 @@ docker volume rm volto-backend-data Then run `make backend-docker-start` again to start the backend with a clean data volume. ```` - -Browse to the backend running at http://localhost:8080. -In the second session, start the frontend. + +(develop-volto-configure-backend-language-label)= + +#### Configure backend language + +If you use the Docker image [`plone-backend`](https://github.com/plone/plone-backend), you can set its `LANGUAGE` environment variable, overriding the default of `en`, when you start it. + +This variable is applied only when the Plone site is created. +If you persist data through restarts, you only need to do this once. +Conversely, if you create a Plone site in the wrong language, you can delete the data volume, and recreate it with the correct language. + +You can either pass an environment variable into the make command to start the backend, or export an environment variable in your shell session and start the backend. + +```shell +# pass method +LANGUAGE=pt-br make backend-docker-start + +# export method +export LANGUAGE=pt-br +make backend-docker-start +``` + + +(develop-volto-start-the-frontend-label)= + +## Start the frontend + +In the second session, start the frontend, Volto. ```shell pnpm start @@ -217,8 +252,6 @@ pnpm start Browse to the frontend running at http://localhost:3000. -To stop either the backend or frontend, use {kbd}`ctrl-c`. - (developing-core-run-commands-for-pnpm-workspaces-label)= diff --git a/packages/volto/Makefile b/packages/volto/Makefile index 79269d6505..abc6ce0dda 100644 --- a/packages/volto/Makefile +++ b/packages/volto/Makefile @@ -13,6 +13,9 @@ MAKEFLAGS+=--no-builtin-rules # Project settings (read from repo root) include ../../variables.mk +# Allow setting the language for backend-docker-start. Default is `en`. +LANGUAGE ?=en + # Recipe snippets for reuse CHECKOUT_BASENAME="$(shell basename $(shell realpath ./))" @@ -100,7 +103,7 @@ release-notes-copy-to-docs: ## Copy release notes into documentation .PHONY: backend-docker-start backend-docker-start: ## Starts a Docker-based backend for development - docker run -it --rm --name=backend -p 8080:8080 -v volto-backend-data:/data -e SITE=Plone -e ADDONS='$(KGS)' $(DOCKER_IMAGE) + docker run -it --rm --name=backend -p 8080:8080 -v volto-backend-data:/data -e SITE=Plone -e ADDONS='$(KGS)' -e LANGUAGE='$(LANGUAGE)' $(DOCKER_IMAGE) .PHONY: frontend-docker-start frontend-docker-start: ## Starts a Docker-based frontend for development diff --git a/packages/volto/news/6231.internal b/packages/volto/news/6231.internal new file mode 100644 index 0000000000..99beab7a0c --- /dev/null +++ b/packages/volto/news/6231.internal @@ -0,0 +1 @@ +Allow setting the language for `make backend-docker-start`. Default is `en`. Added usage documentation in Contributing > Develop Volto core, and reorganized it. Cleaned up Configuration > Multilingual. @stevepiercy