UNPKG

@plone/volto

Version:
204 lines (193 loc) 6.18 kB
import React, { useState, useCallback, useMemo } from 'react'; import PropTypes from 'prop-types'; import { Button, Input, Message } from 'semantic-ui-react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import cx from 'classnames'; import { withBlockExtensions } from '@plone/volto/helpers/Extensions'; import { compose } from 'redux'; import Icon from '@plone/volto/components/theme/Icon/Icon'; import SidebarPortal from '@plone/volto/components/manage/Sidebar/SidebarPortal'; import MapsSidebar from '@plone/volto/components/manage/Blocks/Maps/MapsSidebar'; import clearSVG from '@plone/volto/icons/clear.svg'; import aheadSVG from '@plone/volto/icons/ahead.svg'; import mapsBlockSVG from '@plone/volto/components/manage/Blocks/Maps/block-maps.svg'; import Image from '@plone/volto/components/theme/Image/Image'; const messages = defineMessages({ MapsBlockInputPlaceholder: { id: 'Enter map Embed Code', defaultMessage: 'Enter map Embed Code', }, left: { id: 'Left', defaultMessage: 'Left', }, right: { id: 'Right', defaultMessage: 'Right', }, center: { id: 'Center', defaultMessage: 'Center', }, full: { id: 'Full', defaultMessage: 'Full', }, GoogleMapsEmbeddedBlock: { id: 'Google Maps Embedded Block', defaultMessage: 'Google Maps Embedded Block', }, }); const Edit = React.memo((props) => { const intl = useIntl(); const [url, setUrl] = useState(''); const [error, setError] = useState(null); const { onChangeBlock, data, block, selected } = props; const onChangeUrl = ({ target }) => { setUrl(target.value); }; const onSubmitUrl = useCallback(() => { onChangeBlock(block, { ...data, url: getSrc(url), }); }, [onChangeBlock, block, data, url]); const onKeyDownVariantMenuForm = useCallback( (e) => { if (e.key === 'Enter') { e.preventDefault(); e.stopPropagation(); onSubmitUrl(); } else if (e.key === 'Escape') { e.preventDefault(); e.stopPropagation(); // TODO: Do something on ESC key } }, [onSubmitUrl], ); const getSrc = (embed) => { const parser = new DOMParser(); const doc = parser.parseFromString(embed, 'text/html'); const iframe = doc.getElementsByTagName('iframe'); if (iframe.length === 0) { setError(true); return ''; } setError(false); return iframe[0].src; }; const resetSubmitUrl = () => { setUrl(''); }; const placeholder = useMemo( () => data.placeholder || intl.formatMessage(messages.MapsBlockInputPlaceholder), [data, intl], ); return ( <div className={cx( 'block maps align', { center: !Boolean(data.align), }, data.align, )} > {data.url ? ( <div className={cx('maps-inner', { 'full-width': data.align === 'full', })} > <iframe title={intl.formatMessage(messages.GoogleMapsEmbeddedBlock)} src={data.url} className="google-map" frameBorder="0" allowFullScreen /> </div> ) : ( <Message> <center> <Image src={mapsBlockSVG} alt="" /> <div className="toolbar-inner"> <Input onKeyDown={onKeyDownVariantMenuForm} onChange={onChangeUrl} placeholder={placeholder} value={url} // Prevents propagation to the Dropzone and the opening // of the upload browser dialog onClick={(e) => e.stopPropagation()} /> {url && ( <Button.Group> <Button type="button" basic className="cancel" onClick={(e) => { e.stopPropagation(); setUrl(''); }} > <Icon name={clearSVG} size="30px" /> </Button> </Button.Group> )} <Button.Group> <Button type="button" basic primary onClick={(e) => { e.stopPropagation(); onSubmitUrl(); }} > <Icon name={aheadSVG} size="30px" /> </Button> </Button.Group> </div> <div className="message-text"> <FormattedMessage id="Please enter the Embed Code provided by Google Maps -> Share -> Embed map. It should contain the <iframe> code on it." defaultMessage="Please enter the Embed Code provided by Google Maps -> Share -> Embed map. It should contain the <iframe> code on it." /> {error && ( <div style={{ color: 'red' }}> <FormattedMessage id="Embed code error, please follow the instructions and try again." defaultMessage="Embed code error, please follow the instructions and try again." /> </div> )} </div> </center> </Message> )} {!selected && <div className="map-overlay" />} <SidebarPortal selected={selected}> <MapsSidebar {...props} resetSubmitUrl={resetSubmitUrl} /> </SidebarPortal> </div> ); }); Edit.propTypes = { selected: PropTypes.bool.isRequired, block: PropTypes.string.isRequired, index: PropTypes.number.isRequired, data: PropTypes.objectOf(PropTypes.any).isRequired, pathname: PropTypes.string.isRequired, onChangeBlock: PropTypes.func.isRequired, onSelectBlock: PropTypes.func.isRequired, onDeleteBlock: PropTypes.func.isRequired, onFocusPreviousBlock: PropTypes.func.isRequired, onFocusNextBlock: PropTypes.func.isRequired, handleKeyDown: PropTypes.func.isRequired, }; export default compose(withBlockExtensions)(Edit);