@plone/volto
Version:
Volto
180 lines (169 loc) • 5.39 kB
JSX
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;