diff --git a/src/components/AnnotationManifestsAccordion.js b/src/components/AnnotationManifestsAccordion.js index 749330b99e8777f0c74b35af0653534569c4f834..5851ed129bfc460500bd0b7f456a19276c2f0395 100644 --- a/src/components/AnnotationManifestsAccordion.js +++ b/src/components/AnnotationManifestsAccordion.js @@ -10,6 +10,7 @@ import { } from '@material-ui/core'; import Button from '@material-ui/core/Button'; import Tooltip from '@material-ui/core/Tooltip'; +import { AnnotationManifestsItem } from './AnnotationManifestsItem'; /** * AnnotationManifestsAccordion @@ -20,9 +21,9 @@ export class AnnotationManifestsAccordion extends Component { */ constructor(props) { super(props); - this.handleOpenManifestSideToSide = this.handleOpenManifestSideToSide.bind(this); this.handleOpenAccordion = this.handleOpenAccordion.bind(this); + /** Search if the annotation is a manifest. URL must be resolvable for the annotation. So the manifest url is added at the end of the id */ function searchManifestInID(id) { const match = id.match( @@ -44,37 +45,9 @@ export class AnnotationManifestsAccordion extends Component { this.state = { annotation }; } - - /** */ - handleOpenManifestSideToSide(e, manifestId) { - const { addResource, addWindow } = this.props; - addResource(manifestId); - addWindow({ manifestId }); - } - /** */ // eslint-disable-next-line class-methods-use-this,require-jsdoc handleOpenAccordion(e) { - const { annotation } = this.state; - /** */ - async function load(manifests) { - return Promise.all(manifests.map((manifest) => fetch(manifest.id) - .then((response) => response.json()) - .then((data) => { - if (data.type === 'Manifest') { - return data; - } - return null; - }))); - } - - load(annotation.manifests) - .then((values) => { - if (values) { - annotation.manifests = values; - this.setState({ annotation }); - } - }); e.stopPropagation(); } @@ -84,8 +57,6 @@ export class AnnotationManifestsAccordion extends Component { classes, t, i18n, } = this.props; - const language = i18n.language; - const { annotation } = this.state; if (annotation.manifests === null || annotation.manifests.length === 0) { @@ -103,30 +74,11 @@ export class AnnotationManifestsAccordion extends Component { </AccordionSummary> <AccordionDetails className={classes.manifestContainer}> {annotation.manifests.map(manifest => ( - <Typography > - <Card className={classes.root}> - <CardActionArea> - <CardContent> - <Typography> - { manifest.label ? manifest.label[language] : manifest.id } - </Typography> - </CardContent> - </CardActionArea> - <CardActions> - <Tooltip title={t('openManifestInOtherWindow', { manifest: manifest.id })}> - <Button - size="small" - color="primary" - onClick={(e) => { - this.handleOpenManifestSideToSide(e, manifest.id); - }} - > - {t('open')} - </Button> - </Tooltip> - </CardActions> - </Card> - </Typography> + <AnnotationManifestsItem + manifestId={manifest.id} + language={i18n.language} + key={manifest} + /> ))} </AccordionDetails> </Accordion> @@ -136,8 +88,7 @@ export class AnnotationManifestsAccordion extends Component { } AnnotationManifestsAccordion.propsTypes = { - addResource: PropTypes.func.isRequired, - addWindow: PropTypes.func.isRequired, + annotation: PropTypes.shape( { content: PropTypes.string, @@ -146,6 +97,7 @@ AnnotationManifestsAccordion.propsTypes = { }, ), classes: PropTypes.objectOf(PropTypes.string), + fetchManifest: PropTypes.func.isRequired, t: PropTypes.func.isRequired, }; diff --git a/src/components/AnnotationManifestsItem.js b/src/components/AnnotationManifestsItem.js new file mode 100644 index 0000000000000000000000000000000000000000..260f55796b665305ec0ecd7ba09e99ce69bdbe45 --- /dev/null +++ b/src/components/AnnotationManifestsItem.js @@ -0,0 +1,84 @@ +import React, { Component } from 'react'; +import Typography from '@material-ui/core/Typography'; +import PropTypes from 'prop-types'; +import { + Card, CardActionArea, CardActions, CardContent, CardMedia, Fab, +} from '@material-ui/core'; +import Button from '@material-ui/core/Button'; +import Tooltip from '@material-ui/core/Tooltip'; + +/** + * AnnotationManifestsItem + */ +export class AnnotationManifestsItem extends Component { + /** + * constructor + */ + constructor(props) { + super(props); + this.handleOpenManifestSideToSide = this.handleOpenManifestSideToSide.bind(this); + } + + /** */ + handleOpenManifestSideToSide(e, manifestId) { + const { addResource, addWindow } = this.props; + addResource(manifestId); + addWindow({ manifestId }); + } + + /** */ + componentDidMount() { + const { + fetchManifest, manifestId, ready, isFetching, error, provider, + } = this.props; + + if (!ready && !error && !isFetching && provider !== 'file') fetchManifest(manifestId); + } + + /** */ + render() { + const { + classes, t, language, manifest, + } = this.props; + + return ( + <Typography> + <Card className={classes.root}> + <CardActionArea> + <CardContent> + <Typography> + { manifest.label ? manifest.label[language] : manifest.id } + </Typography> + </CardContent> + </CardActionArea> + <CardActions> + <Tooltip title={t('openManifestInOtherWindow', { manifest: manifest.id })}> + <Button + size="small" + color="primary" + onClick={(e) => { + this.handleOpenManifestSideToSide(e, manifest.id); + }} + > + {t('open')} + </Button> + </Tooltip> + </CardActions> + </Card> + </Typography> + ); + } +} + +AnnotationManifestsItem.propsTypes = { + addResource: PropTypes.func.isRequired, + addWindow: PropTypes.func.isRequired, + classes: PropTypes.objectOf(PropTypes.string), + fetchManifest: PropTypes.func.isRequired, + manifests: PropTypes.arrayOf(PropTypes.string), + t: PropTypes.func.isRequired, +}; + +AnnotationManifestsItem.defaultProps = { + classes: {}, +}; diff --git a/src/containers/AnnotationManifestsAccordion.js b/src/containers/AnnotationManifestsAccordion.js index 257810aa2f135d70a8d90550bc757d21e095d57e..e9229f8ddde9d2ab58816528cb33410f679cc709 100644 --- a/src/containers/AnnotationManifestsAccordion.js +++ b/src/containers/AnnotationManifestsAccordion.js @@ -4,7 +4,6 @@ import { withTranslation } from 'react-i18next'; import { withStyles } from '@material-ui/core/styles'; import { withPlugins } from '../extend/withPlugins'; import { AnnotationManifestsAccordion } from '../components/AnnotationManifestsAccordion'; -import * as actions from '../state/actions'; import { getConfig } from '../state/selectors'; /** For connect */ @@ -18,8 +17,7 @@ const mapStateToProps = (state, { canvasId, windowId }) => ({ * @private */ const mapDispatchToProps = { - addResource: actions.addResource, - addWindow: actions.addWindow, + }; /** For withStyles */ diff --git a/src/containers/AnnotationManifestsItem.js b/src/containers/AnnotationManifestsItem.js new file mode 100644 index 0000000000000000000000000000000000000000..985132cb6e36d192e01041621637814cc21cb219 --- /dev/null +++ b/src/containers/AnnotationManifestsItem.js @@ -0,0 +1,64 @@ +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { withTranslation } from 'react-i18next'; +import { withStyles } from '@material-ui/core/styles'; +import { withPlugins } from '../extend/withPlugins'; +import * as actions from '../state/actions'; +import { AnnotationManifestsItem } from '../components/AnnotationManifestsItem'; +import { + getCanvases, + getManifest, getManifestLogo, + getManifestoInstance, getManifestProvider, getManifestThumbnail, getManifestTitle, + getSequenceBehaviors, + getWindowManifests +} from '../state/selectors'; + +/** For connect */ +const mapStateToProps = (state, { manifestId }) => { + const manifest = getManifest(state, { manifestId }) || {}; + + return { + active: getWindowManifests(state).includes(manifestId), + error: manifest.error, + isFetching: manifest.isFetching, + manifestLogo: getManifestLogo(state, { manifestId }), + provider: getManifestProvider(state, { manifestId }), + ready: !!manifest.json, + thumbnail: getManifestThumbnail(state, { manifestId }), + title: getManifestTitle(state, { manifestId }), + }; +}; + +/** + * mapDispatchToProps - to hook up connect + * @memberof WindowSideBarAnnotationsPanel + * @private + */ +const mapDispatchToProps = { + addResource: actions.addResource, + addWindow: actions.addWindow, + fetchManifest: actions.fetchManifest, +}; + +/** For withStyles */ +const styles = theme => ({ + logo: { + height: '2.5rem', + maxWidth: '100%', + objectFit: 'contain', + paddingRight: 8, + }, + thumbnail: { + maxWidth: '100%', + objectFit: 'contain', + }, +}); + +const enhance = compose( + withTranslation(), + withStyles(styles), + connect(mapStateToProps, mapDispatchToProps), + withPlugins('AnnotationManifestsItem'), +); + +export default enhance(AnnotationManifestsItem);