@bigfishtv/cockpit
Version:
185 lines (166 loc) • 4.95 kB
JavaScript
import React, { Component } from 'react'
import { Fieldset } from '@bigfishtv/react-forms'
import filesize from 'file-size'
import modalFormValueContext from '../../decorators/modalFormValueContext'
import { openImageEditModal } from '../../utils/imageEditUtils'
import { fromNow } from '../../utils/timeUtils'
import Modal from '../modal/Modal'
import Field from '../form/Field'
import Button from '../button/Button'
import Textarea from '../input/TextareaInput'
import ButtonGroup from '../button/ButtonGroup'
import AssetDropzone from '../input/AssetDropzoneInput'
import { getAssetUrl } from '../../utils/fileUtils'
const AssetToolbar = ({ asset, onEdit, onDownload, onDelete }) => (
<ButtonGroup>
{asset && asset.kind == 'image' && (
<Button style="primary" onClick={onEdit}>
Edit
</Button>
)}
<a
className="button button-medium"
href={getAssetUrl(asset)}
download={asset.title}
style={{ userSelect: 'none' }}
onClick={e => {
if (onDownload) {
e.preventDefault()
onDownload()
}
}}
children="Download"
/>
<Button onClick={onDelete} style="error">
Delete
</Button>
</ButtonGroup>
)
/**
* Is the modal component for editing asset details.
* Shows a preview of asset if image, displays toolbar buttons and shows file info.
* Doesn't save details on its own as it's decorated with modalFormValueContext and expects its caller to handle that.
*/
export default class AssetEditModal extends Component {
static defaultProps = {
isNew: false,
AssetToolbar,
onEdit: null,
onDelete: null,
onDownload: null,
onUpdate: () => console.warn('[AssetEditModal] no onUpdate prop'),
}
/**
* Calls onSave prop with latest formValue and isNew prop
*/
handleSave = () => {
this.props.onSave(this.props.formValue, this.props.isNew)
}
/**
* Calls onClose prop with latest formValue, whether or not it was saved, and its isNew prop
* @param {Boolean} didSave
*/
handleClose = (didSave = false) => {
this.props.onClose(this.props.formValue, didSave, this.props.isNew)
}
/**
* Calls onDelete prop with a callback that closes itself after a timeout
*/
handleDelete = () => {
this.props.onDelete(() => {
// I'm using setTimeout because closeModal only closes the top-most modal,
// which happens to be a prompt modal until next render cycle
setTimeout(() => this.props.closeModal())
})
}
/**
* Calls onDownload prop with asset otherwise opens new window directly to asset path
*/
handleDownload = () => {
const asset = this.props.formValue.select('asset').value
this.props.onDownload ? this.props.onDownload(asset) : window.open('/uploads/' + asset.filename)
}
/**
* Calls onEdit prop otherwise opens image editing modal window
*/
handleEdit = () => {
const asset = this.props.formValue.select('asset').value
if (this.props.onEdit) {
this.props.onEdit(asset)
} else {
openImageEditModal(asset, newAsset => {
this.props.formValue.select('asset').update(newAsset)
this.props.onUpdate(newAsset)
})
}
}
render() {
const { formValue, AssetToolbar } = this.props
const asset = formValue.select('asset').value
const size = filesize(asset.bytes).human('si')
const created = fromNow(asset.created)
const modified = fromNow(asset.modified)
return (
<Modal
title="Edit Asset"
size="small"
onClose={this.handleClose}
onSave={this.handleSave}
ModalActions={props => (
<div>
<button className="button button-secondary" onClick={props.onSave}>
Save
</button>
<button className="button" onClick={props.onClose}>
Cancel
</button>
</div>
)}>
<Fieldset formValue={formValue}>
<Field select="asset">
<AssetDropzone
multiple={false}
Toolbar={false}
assetSize="cockpit-large"
cellSize="100%"
mediaRatio="4-3"
onDoubleClick={this.handleEdit}
/>
</Field>
{asset !== null && (
<AssetToolbar
asset={asset}
onEdit={this.handleEdit}
onDelete={this.handleDelete}
onDownload={this.handleDownload}
/>
)}
<br />
<br />
<Fieldset select="asset">
<Field select="title" label="Title" />
<Field select="caption" label="Caption" Input={Textarea} />
<Field select="credit" label="Credit" />
<Field select="origin" label="Origin URL" />
<fieldset>
<legend>Asset Properties</legend>
<dl>
<dt>File Name</dt>
<dd>{asset.filename}</dd>
<dt>File Size</dt>
<dd>{size}</dd>
<dt>Date Created</dt>
<dd>{created}</dd>
<dt>Last Modified</dt>
<dd>{modified}</dd>
{asset.kind == 'image' && <dt>Dimensions</dt>}
{asset.kind == 'image' && <dd>{asset.width + ' x ' + asset.height}</dd>}
</dl>
</fieldset>
</Fieldset>
</Fieldset>
</Modal>
)
}
}