diff --git a/__tests__/miradorAnnotationPlugin.test.js b/__tests__/miradorAnnotationPlugin.test.js index 52b97c99297b837df880e9de6105d5a8ba873e2a..66956369e7dbbb1f000bec3a6b5145a84bf69b97 100644 --- a/__tests__/miradorAnnotationPlugin.test.js +++ b/__tests__/miradorAnnotationPlugin.test.js @@ -7,6 +7,7 @@ import miradorAnnotationPlugin from '../src/plugins/miradorAnnotationPlugin'; function createWrapper(props) { return shallow( <miradorAnnotationPlugin.component + canvases={[]} config={{}} TargetComponent="<div>hello</div>" targetProps={{}} diff --git a/src/AnnotationDownloadDialog.js b/src/AnnotationDownloadDialog.js index dc1241e188c9a14f9360a7f8040684c077ccda02..bcba9564be2f459279be6d3b3db9ece3353b40dc 100644 --- a/src/AnnotationDownloadDialog.js +++ b/src/AnnotationDownloadDialog.js @@ -3,108 +3,118 @@ import Dialog from '@material-ui/core/Dialog'; import DialogContent from '@material-ui/core/DialogContent'; import DialogTitle from '@material-ui/core/DialogTitle'; import GetAppIcon from '@material-ui/icons/GetApp'; -import List from '@material-ui/core/List' -import ListItem from '@material-ui/core/ListItem' -import ListItemIcon from '@material-ui/core/ListItemIcon' -import ListItemText from '@material-ui/core/ListItemText' +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; import Typography from '@material-ui/core/Typography'; import PropTypes, { bool } from 'prop-types'; +/** */ export class AnnotationDownloadDialog extends Component { + /** */ constructor(props) { super(props); this.state = { downloadLinks: [], - } + }; + this.closeDialog = this.closeDialog.bind(this); } + /** */ componentDidUpdate(prevProps) { const { canvases, config, open } = this.props; const { open: prevOpen } = prevProps || {}; if (prevOpen !== open && open) { + /** */ const reducer = async (acc, canvas) => { const store = config.annotation.adapter(canvas.id); - const _acc = await acc; + const resolvedAcc = await acc; const content = await store.all(); - if (content - ) { + if (content) { + // eslint-disable-next-line no-underscore-dangle const label = canvas.__jsonld.label || canvas.id; - const data = new Blob([JSON.stringify(content)], { type: 'application/json' }) + const data = new Blob([JSON.stringify(content)], { type: 'application/json' }); const url = window.URL.createObjectURL(data); - return [..._acc, { - id: content.id || content['@id'], + return [...resolvedAcc, { canvasId: canvas.id, + id: content.id || content['@id'], label, url, - }] + }]; } - return _acc; - } + return resolvedAcc; + }; if (canvases && canvases.length > 0) { - canvases.reduce(reducer, []).then(downloadLinks => { - this.setState({ downloadLinks }) + canvases.reduce(reducer, []).then((downloadLinks) => { + this.setState({ downloadLinks }); }); - } else { - this.setState({ downloadLinks: [] }); } } - if (prevOpen !== open && !open) { - this.setState({ downloadLinks: [] }); - } } + /** */ + closeDialog() { + const { handleClose } = this.props; + this.setState({ downloadLinks: [] }); + handleClose(); + } + + /** */ render() { - const { canvases, config, handleClose, open } = this.props; + const { handleClose, open } = this.props; + const { downloadLinks } = this.state; return ( <Dialog aria-labelledby="annotation-download-dialog-title" id="annotation-download-dialog" onClose={handleClose} - onEscapeKeyDown={handleClose} + onEscapeKeyDown={this.closeDialog} open={open} > <DialogTitle id="annotation-download-dialog-title" disableTypography> <Typography variant="h2">Download Annotations</Typography> </DialogTitle> <DialogContent> - { this.state.downloadLinks === undefined || this.state.downloadLinks.length === 0 ? ( + { downloadLinks === undefined || downloadLinks.length === 0 ? ( <Typography variant="body1">No annotations stored yet.</Typography> ) : ( <List> - {this.state.downloadLinks.map(dl => ( - <ListItem button - component="a" - key={dl.canvasId} - aria-label={`Download annotations for ${dl.label}`} - startIcon={<GetAppIcon/>} - href={dl.url} - download={`annotations-${dl.id}.json`} - > - <ListItemIcon> - <GetAppIcon/> - </ListItemIcon> - <ListItemText> - Download annotations for {dl.label} - </ListItemText> - </ListItem> + { downloadLinks.map((dl) => ( + <ListItem + button + component="a" + key={dl.canvasId} + aria-label={`Download annotations for ${dl.label}`} + startIcon={<GetAppIcon />} + href={dl.url} + download={`annotations-${dl.id}.json`} + > + <ListItemIcon> + <GetAppIcon /> + </ListItemIcon> + <ListItemText> + {`Download annotations for canvas "${dl.label}"`} + </ListItemText> + </ListItem> ))} </List> )} </DialogContent> </Dialog> - ) + ); } } AnnotationDownloadDialog.propTypes = { canvases: PropTypes.arrayOf( PropTypes.shape({ id: PropTypes.string, index: PropTypes.number }), - ), + ).isRequired, config: PropTypes.shape({ annotation: PropTypes.shape({ adapter: PropTypes.func, }), - }), + }).isRequired, handleClose: PropTypes.func.isRequired, open: bool.isRequired, -} +}; diff --git a/src/plugins/miradorAnnotationPlugin.js b/src/plugins/miradorAnnotationPlugin.js index c4a60383aa16cf6b289135e417279f1748b6ab43..4845c8744f6debdc1570d326ddd52d38de73f0b6 100644 --- a/src/plugins/miradorAnnotationPlugin.js +++ b/src/plugins/miradorAnnotationPlugin.js @@ -30,17 +30,22 @@ class MiradorAnnotation extends Component { }); } + /** */ toggleCanvasDownloadDialog(e) { + const { annotationDownloadDialogOpen } = this.state; const newState = { - annotationDownloadDialogOpen: !this.state.annotationDownloadDialogOpen, - } + annotationDownloadDialogOpen: !annotationDownloadDialogOpen, + }; this.setState(newState); } /** */ render() { - const { canvases, config, TargetComponent, targetProps } = this.props; - const showAnnotationDownloadDialog = config.annotation && config.annotation.downloadCanvasAnnotations; + const { + canvases, config, TargetComponent, targetProps, + } = this.props; + const { annotationDownloadDialogOpen } = this.state; + const showDownloadDialog = config.annotation && config.annotation.downloadCanvasAnnotations; return ( <div> <TargetComponent @@ -53,7 +58,7 @@ class MiradorAnnotation extends Component { > <AddBoxIcon /> </MiradorMenuButton> - { showAnnotationDownloadDialog && ( + { showDownloadDialog && ( <MiradorMenuButton aria-label="Download annotation page for canvas" onClick={this.toggleCanvasDownloadDialog} @@ -62,12 +67,12 @@ class MiradorAnnotation extends Component { <GetAppIcon /> </MiradorMenuButton> )} - { showAnnotationDownloadDialog && ( + { showDownloadDialog && ( <AnnotationDownloadDialog canvases={canvases} config={config} handleClose={this.toggleCanvasDownloadDialog} - open={this.state.annotationDownloadDialogOpen} + open={annotationDownloadDialogOpen} /> )} </div> @@ -79,13 +84,13 @@ MiradorAnnotation.propTypes = { addCompanionWindow: PropTypes.func.isRequired, canvases: PropTypes.arrayOf( PropTypes.shape({ id: PropTypes.string, index: PropTypes.number }), - ), + ).isRequired, config: PropTypes.shape({ annotation: PropTypes.shape({ adapter: PropTypes.func, downloadCanvasAnnotations: PropTypes.bool, }), - }), + }).isRequired, TargetComponent: PropTypes.oneOfType([ PropTypes.func, PropTypes.node, @@ -100,12 +105,11 @@ const mapDispatchToProps = (dispatch, props) => ({ ), }); -const mapStateToProps = function mapStateToProps(state, { targetProps: { windowId } }) { - return { - canvases: getVisibleCanvases(state, { windowId }), - config: state.config, - }; -} +/** */ +const mapStateToProps = (state, { targetProps: { windowId } }) => ({ + canvases: getVisibleCanvases(state, { windowId }), + config: state.config, +}); export default { component: MiradorAnnotation,