public/js/components/FormFields/FormFieldImageSelect.js (117 lines of code) (raw):

import React from 'react'; import {PropTypes} from 'prop-types'; import filesize from 'filesize'; import Modal from '../Utilities/Modal'; import ShowErrors from '../Utilities/ShowErrors'; import { errorPropType } from '../../constants/errorPropType'; import {parseImageFromGridCrop, findSmallestAssetAboveWidth, gridUrlFromApiUrl} from '../../util/imageHelpers'; import {logInfo} from '../../util/logger'; const assetPropType = PropTypes.shape({ mimeType: PropTypes.string.isRequired, file: PropTypes.string.isRequired, dimensions: PropTypes.shape({ height: PropTypes.number.isRequired, width: PropTypes.number.isRequired }).isRequired, size: PropTypes.number.isRequired, credit: PropTypes.string, copyright: PropTypes.string, source: PropTypes.string, photographer: PropTypes.string, suppliersReference: PropTypes.string }); const gridImagePropType = PropTypes.shape({ mediaId: PropTypes.string.isRequired, assets: PropTypes.arrayOf(assetPropType).isRequired, master: assetPropType.isRequired }); class FormFieldImageSelect extends React.Component { static propTypes = { onUpdateField: PropTypes.func, fieldValue: gridImagePropType, fieldName: PropTypes.string, fieldLabel: PropTypes.string, fieldErrors: PropTypes.arrayOf(errorPropType), formRowClass: PropTypes.string, gridUrl: PropTypes.string.isRequired }; state = { modalOpen: false }; closeModal = () => { this.setState({ modalOpen: false }); window.removeEventListener('message', this.onMessage, false); }; openModal = () => { this.setState({ modalOpen: true }); window.addEventListener('message', this.onMessage, false); }; removeImage = () => { this.props.onUpdateField(null); }; validMessage(data) { return data && data.crop && data.crop.data && data.image && data.image.data; } onMessage = (event) => { if (event.origin !== this.props.gridUrl) { logInfo("didn't come from the grid"); return; } const data = event.data; if (!data) { logInfo("got no data..."); return; } if (!this.validMessage(data)) { logInfo("not a valid message..."); return; } this.closeModal(); this.props.onUpdateField(parseImageFromGridCrop(data)); }; renderWithoutImage() { return ( <button className="image-select__button" type="button" onClick={this.openModal}> + Add Image from Grid </button> ); } renderWithImage() { const thumbnail = findSmallestAssetAboveWidth(this.props.fieldValue.assets, 200); return ( <div className="image-select__image-display"> <div className="image-select__image"> <img src={thumbnail.file} /> </div> <div className="image-select__image-details"> <div className="image-select__image-details__detail"> <a target="_blank" rel="noreferrer" href={gridUrlFromApiUrl(this.props.fieldValue.mediaId)}>View image in the Grid</a> </div> <div className="image-select__image-details__detail"> Size: {filesize(this.props.fieldValue.master.size)} </div> <div className="image-select__image-details__detail"> Dimensions: {this.props.fieldValue.master.dimensions.width} x {this.props.fieldValue.master.dimensions.height} </div> <button className="image-select__button image-select__replace-button" type="button" onClick={this.openModal}> Replace Image </button> <button className="image-select__remove-button btn--red" type="button" onClick={this.removeImage}> Remove Image </button> </div> </div> ); } render () { return ( <div className={this.props.formRowClass || "form__row"}> {this.props.fieldLabel ? <label htmlFor={this.props.fieldName} className="form__label">{this.props.fieldLabel}</label> : false} <div className="image-select"> {this.props.fieldValue ? this.renderWithImage() : this.renderWithoutImage()} <Modal isOpen={this.state.modalOpen} dismiss={this.closeModal}> <iframe className="image-select__modal" src={this.props.gridUrl}></iframe> </Modal> </div> <ShowErrors errors={this.props.fieldErrors}/> </div> ); } } export default FormFieldImageSelect;