UNPKG

@plone/volto

Version:
180 lines (169 loc) 5.39 kB
import { useEffect, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory, useLocation, useParams } from 'react-router-dom'; import Helmet from '@plone/volto/helpers/Helmet/Helmet'; import { useClient } from '@plone/volto/hooks/client/useClient'; import { tryParseJSON, extractInvariantErrors, } from '@plone/volto/helpers/FormValidation/FormValidation'; import { createPortal } from 'react-dom'; import { Button, Container } from 'semantic-ui-react'; import { defineMessages, useIntl } from 'react-intl'; import { toast } from 'react-toastify'; import Icon from '@plone/volto/components/theme/Icon/Icon'; import Toolbar from '@plone/volto/components/manage/Toolbar/Toolbar'; import Toast from '@plone/volto/components/manage/Toast/Toast'; import { Form } from '@plone/volto/components/manage/Form'; import { updateControlpanel, getControlpanel, } from '@plone/volto/actions/controlpanels/controlpanels'; import { getSite } from '@plone/volto/actions/site/site'; import config from '@plone/volto/registry'; import saveSVG from '@plone/volto/icons/save.svg'; import clearSVG from '@plone/volto/icons/clear.svg'; const messages = defineMessages({ changesSaved: { id: 'Changes saved.', defaultMessage: 'Changes saved.', }, back: { id: 'Back', defaultMessage: 'Back', }, save: { id: 'Save', defaultMessage: 'Save', }, cancel: { id: 'Cancel', defaultMessage: 'Cancel', }, info: { id: 'Info', defaultMessage: 'Info', }, error: { id: 'Error', defaultMessage: 'Error', }, }); const Controlpanel = () => { const { filterControlPanelsSchema } = config.settings; const intl = useIntl(); const id = useParams().id; const pathname = useLocation().pathname; const history = useHistory(); const isClient = useClient(); const dispatch = useDispatch(); const controlpanel = useSelector((state) => state.controlpanels.controlpanel); const updateRequest = useSelector((state) => state.controlpanels.update); const [error, setError] = useState(null); const formRef = useRef(); const onCancel = () => { history.goBack(); }; const onSubmit = (data) => { dispatch(updateControlpanel(controlpanel['@id'], data)) .then(() => { dispatch(getSite()); toast.info( <Toast info title={intl.formatMessage(messages.info)} content={intl.formatMessage(messages.changesSaved)} />, ); }) .catch((err) => { const message = err?.response?.body?.error?.message || err?.response?.body?.message || err?.response?.text || ''; const error = new DOMParser().parseFromString(message, 'text/html')?.all?.[0] ?.textContent || message; const errorsList = tryParseJSON(error); let invariantErrors = []; if (Array.isArray(errorsList)) { invariantErrors = extractInvariantErrors(errorsList); } setError(error); if (invariantErrors.length > 0) { toast.error( <Toast error title={intl.formatMessage(messages.error)} content={invariantErrors.join(' - ')} />, ); } }); }; useEffect(() => { dispatch(getControlpanel(id)).catch((error) => setError(error)); }, [dispatch, id]); if (controlpanel) { return ( <div id="page-controlpanel"> <Helmet title={controlpanel.title} /> <Container> <Form ref={formRef} title={controlpanel.title} schema={filterControlPanelsSchema(controlpanel)} formData={controlpanel.data} requestError={error} onSubmit={onSubmit} onCancel={onCancel} hideActions loading={updateRequest.loading} /> </Container> {isClient && createPortal( <Toolbar pathname={pathname} hideDefaultViewButtons inner={ <> <Button id="toolbar-save" className="save" aria-label={intl.formatMessage(messages.save)} onClick={() => formRef.current.onSubmit()} disabled={updateRequest.loading} loading={updateRequest.loading} > <Icon name={saveSVG} className="circled" size="30px" title={intl.formatMessage(messages.save)} /> </Button> <Button className="cancel" aria-label={intl.formatMessage(messages.cancel)} onClick={onCancel} > <Icon name={clearSVG} className="circled" size="30px" title={intl.formatMessage(messages.cancel)} /> </Button> </> } />, document.getElementById('toolbar'), )} </div> ); } return <div />; }; export default Controlpanel;