From 9e69299f079b247951ed26fe412b8dfa802f7e0e Mon Sep 17 00:00:00 2001 From: Jack Reed <phillipjreed@gmail.com> Date: Wed, 7 Oct 2020 17:01:59 -0600 Subject: [PATCH] Setup collections to open and close the collection selection modal --- .../integration/mirador/collections.html | 22 +++--- .../src/components/PrimaryWindow.test.js | 7 ++ src/components/CollectionDialog.js | 11 ++- src/components/PrimaryWindow.js | 18 ++++- src/components/SelectCollection.js | 67 +++++++++++++++++++ src/containers/CollectionDialog.js | 8 ++- src/containers/PrimaryWindow.js | 11 +++ src/containers/SelectCollection.js | 36 ++++++++++ src/locales/en/translation.json | 1 + src/state/actions/workspace.js | 1 - 10 files changed, 167 insertions(+), 15 deletions(-) create mode 100644 src/components/SelectCollection.js create mode 100644 src/containers/SelectCollection.js diff --git a/__tests__/integration/mirador/collections.html b/__tests__/integration/mirador/collections.html index 71056abeb..c41b9135a 100644 --- a/__tests__/integration/mirador/collections.html +++ b/__tests__/integration/mirador/collections.html @@ -13,16 +13,18 @@ <script type="text/javascript"> var miradorInstance = Mirador.viewer({ id: 'mirador', - windows: [{ - manifestId: 'https://www.e-codices.unifr.ch/metadata/iiif/collection.json' - }], - // windows: [{ - // collectionPath: [ - // "https://www.e-codices.unifr.ch/metadata/iiif/collection.json", - // "https://www.e-codices.unifr.ch/metadata/iiif/collection/stabs.json" - // ], - // manifestId: "https://www.e-codices.unifr.ch/metadata/iiif/stabs-StAlban-DD1-1580/manifest.json" - // }], + windows: [ + { + collectionPath: [ + "https://www.e-codices.unifr.ch/metadata/iiif/collection.json", + "https://www.e-codices.unifr.ch/metadata/iiif/collection/stabs.json" + ], + manifestId: "https://www.e-codices.unifr.ch/metadata/iiif/stabs-StAlban-DD1-1580/manifest.json" + }, + { + manifestId: 'https://www.e-codices.unifr.ch/metadata/iiif/collection.json' + } + ], catalog: [ { manifestId: "https://www.e-codices.unifr.ch/metadata/iiif/collection.json" }, ] diff --git a/__tests__/src/components/PrimaryWindow.test.js b/__tests__/src/components/PrimaryWindow.test.js index da8de5fbb..5cdcccfe6 100644 --- a/__tests__/src/components/PrimaryWindow.test.js +++ b/__tests__/src/components/PrimaryWindow.test.js @@ -4,6 +4,7 @@ import { PrimaryWindow } from '../../../src/components/PrimaryWindow'; import WindowSideBar from '../../../src/containers/WindowSideBar'; import WindowViewer from '../../../src/containers/WindowViewer'; import GalleryView from '../../../src/containers/GalleryView'; +import CollectionDialog from '../../../src/containers/CollectionDialog'; /** create wrapper */ function createWrapper(props) { @@ -37,4 +38,10 @@ describe('PrimaryWindow', () => { const wrapper = createWrapper({ isFetching: false, view: 'gallery', windowId: 'window-2' }); expect(wrapper.find(GalleryView)).toHaveLength(1); }); + it('should render <CollectionDialog> and <SelectCollection> if manifest is collection and isCollectionDialogVisible', () => { + const wrapper = createWrapper({ isCollection: true, isCollectionDialogVisible: true }); + const lazyComponent = wrapper.find('lazy'); + expect(lazyComponent.type().displayName).toBe('SelectCollection'); + expect(wrapper.find(CollectionDialog)).toHaveLength(1); + }); }); diff --git a/src/components/CollectionDialog.js b/src/components/CollectionDialog.js index 59730884c..9930997f3 100644 --- a/src/components/CollectionDialog.js +++ b/src/components/CollectionDialog.js @@ -102,12 +102,15 @@ export class CollectionDialog extends Component { /** */ placeholder() { - const { classes, hideCollectionDialog } = this.props; + const { classes, containerId, hideCollectionDialog, windowId } = this.props; return ( <Dialog + className={classes.dialog} onClose={hideCollectionDialog} open + container={document.querySelector(`#${containerId} #${windowId}`)} + BackdropProps={{ classes: classes.dialog }} > <DialogTitle id="select-collection" disableTypography> <Skeleton className={classes.placeholder} variant="text" /> @@ -125,12 +128,14 @@ export class CollectionDialog extends Component { const { classes, collection, + containerId, error, hideCollectionDialog, isMultipart, manifest, ready, t, + windowId, } = this.props; const { filter } = this.state; @@ -152,7 +157,10 @@ export class CollectionDialog extends Component { return ( <Dialog + className={classes.dialog} onClose={hideCollectionDialog} + container={document.querySelector(`#${containerId} #${windowId}`)} + BackdropProps={{ classes: { root: classes.dialog }}} open > <DialogTitle id="select-collection" disableTypography> @@ -260,6 +268,7 @@ CollectionDialog.propTypes = { CollectionDialog.defaultProps = { collection: null, collectionPath: [], + containerId: null, error: null, isMultipart: false, ready: false, diff --git a/src/components/PrimaryWindow.js b/src/components/PrimaryWindow.js index e96811e9b..d440b9759 100644 --- a/src/components/PrimaryWindow.js +++ b/src/components/PrimaryWindow.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { Component, lazy } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import WindowSideBar from '../containers/WindowSideBar'; @@ -7,6 +7,9 @@ import GalleryView from '../containers/GalleryView'; import CompanionArea from '../containers/CompanionArea'; import ns from '../config/css-ns'; +const SelectCollection = lazy(() => import('../containers/SelectCollection')); +SelectCollection.displayName = 'SelectCollection'; + /** * WindowMiddleContent - component that renders the "middle" area of the * Mirador Window @@ -18,7 +21,16 @@ export class PrimaryWindow extends Component { * @return {(String|null)} */ renderViewer() { - const { isFetching, view, windowId } = this.props; + const { + isCollection, isFetching, view, windowId, + } = this.props; + if (isCollection) { + return ( + <SelectCollection + windowId={windowId} + /> + ); + } if (isFetching === false) { if (view === 'gallery') { return ( @@ -53,12 +65,14 @@ export class PrimaryWindow extends Component { PrimaryWindow.propTypes = { classes: PropTypes.objectOf(PropTypes.string).isRequired, + isCollection: PropTypes.bool, isFetching: PropTypes.bool, view: PropTypes.string, windowId: PropTypes.string.isRequired, }; PrimaryWindow.defaultProps = { + isCollection: false, isFetching: false, view: undefined, }; diff --git a/src/components/SelectCollection.js b/src/components/SelectCollection.js new file mode 100644 index 000000000..decfdf6de --- /dev/null +++ b/src/components/SelectCollection.js @@ -0,0 +1,67 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import Button from '@material-ui/core/Button'; +import Grid from '@material-ui/core/Grid'; +import Typography from '@material-ui/core/Typography'; +import ListSharpIcon from '@material-ui/icons/ListSharp'; + +/** + * + */ +export class SelectCollection extends Component { + /** */ + constructor(props) { + super(props); + + this.openCollectionDialog = this.openCollectionDialog.bind(this); + } + + /** */ + openCollectionDialog() { + const { + collectionPath, manifestId, showCollectionDialog, windowId, + } = this.props; + showCollectionDialog(manifestId, collectionPath.slice(0, -1), windowId); + } + + /** */ + render() { + const { + t, + } = this.props; + return ( + <Grid container justify="center" alignItems="center"> + <Grid container direction="column" alignItems="center"> + <Typography variant="h4" paragraph> + <em> + {t('noItemSelected')} + </em> + </Typography> + <Button + color="primary" + variant="contained" + onClick={this.openCollectionDialog} + startIcon={<ListSharpIcon />} + > + {t('showCollection')} + </Button> + </Grid> + </Grid> + ); + } +} + +SelectCollection.propTypes = { + collectionPath: PropTypes.arrayOf(PropTypes.string), + manifestId: PropTypes.string, + showCollectionDialog: PropTypes.func.isRequired, + t: PropTypes.func, + windowId: PropTypes.string, +}; + +SelectCollection.defaultProps = { + collectionPath: [], + manifestId: null, + t: () => {}, + windowId: null, +}; diff --git a/src/containers/CollectionDialog.js b/src/containers/CollectionDialog.js index 8c1f687ed..325640145 100644 --- a/src/containers/CollectionDialog.js +++ b/src/containers/CollectionDialog.js @@ -4,7 +4,9 @@ import { withStyles } from '@material-ui/core'; import { withTranslation } from 'react-i18next'; import { withPlugins } from '../extend/withPlugins'; import * as actions from '../state/actions'; -import { getManifest, getManifestoInstance, getSequenceBehaviors } from '../state/selectors'; +import { + getContainerId, getManifest, getManifestoInstance, getSequenceBehaviors, +} from '../state/selectors'; import { CollectionDialog } from '../components/CollectionDialog'; /** @@ -35,6 +37,7 @@ const mapStateToProps = (state) => { return { collection: collection && getManifestoInstance(state, { manifestId: collection.id }), collectionPath, + containerId: getContainerId(state), error: manifest && manifest.error, isMultipart: getSequenceBehaviors(state, { manifestId }).includes('multi-part'), manifest: manifest && getManifestoInstance(state, { manifestId }), @@ -57,6 +60,9 @@ const styles = theme => ({ dark: { color: '#000000', }, + dialog: { + position: 'absolute !important', + }, dialogContent: { padding: 0, }, diff --git a/src/containers/PrimaryWindow.js b/src/containers/PrimaryWindow.js index 4c90a1294..50332d7c8 100644 --- a/src/containers/PrimaryWindow.js +++ b/src/containers/PrimaryWindow.js @@ -1,8 +1,18 @@ import { compose } from 'redux'; +import { connect } from 'react-redux'; import { withStyles } from '@material-ui/core/styles'; import { withPlugins } from '../extend/withPlugins'; +import { getManifestoInstance } from '../state/selectors'; import { PrimaryWindow } from '../components/PrimaryWindow'; +/** */ +const mapStateToProps = (state, { windowId }) => { + const manifestoInstance = getManifestoInstance(state, { windowId }); + return { + isCollection: manifestoInstance && manifestoInstance.isCollection(), + }; +}; + const styles = { primaryWindow: { display: 'flex', @@ -13,6 +23,7 @@ const styles = { const enhance = compose( withStyles(styles), + connect(mapStateToProps), withPlugins('PrimaryWindow'), ); diff --git a/src/containers/SelectCollection.js b/src/containers/SelectCollection.js new file mode 100644 index 000000000..446c32711 --- /dev/null +++ b/src/containers/SelectCollection.js @@ -0,0 +1,36 @@ +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { withTranslation } from 'react-i18next'; +import { withStyles } from '@material-ui/core/styles'; +import * as actions from '../state/actions'; +import { withPlugins } from '../extend/withPlugins'; +import { + getWindow, +} from '../state/selectors'; +import { SelectCollection } from '../components/SelectCollection'; + +/** */ +const mapStateToProps = (state, { windowId }) => { + const { collectionPath, manifestId } = (getWindow(state, { windowId }) || {}); + + return { + collectionPath, + manifestId, + }; +}; + +const mapDispatchToProps = { + showCollectionDialog: actions.showCollectionDialog, +}; +/** */ +const styles = (theme) => ({ +}); + +const enhance = compose( + withTranslation(), + withStyles(styles), + connect(mapStateToProps, mapDispatchToProps), + withPlugins('SelectCollection'), +); + +export default enhance(SelectCollection); diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 8c0756f50..c6c0ef9d2 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -90,6 +90,7 @@ "moveCompanionWindowToBottom": "Move to bottom", "moveCompanionWindowToRight": "Move to right", "nextCanvas": "Next item", + "noItemSelected": "No item selected", "numItems": "{{number}} items", "off": "Off", "openCompanionWindow_annotations": "Annotations", diff --git a/src/state/actions/workspace.js b/src/state/actions/workspace.js index 47740062c..29c52e0f1 100644 --- a/src/state/actions/workspace.js +++ b/src/state/actions/workspace.js @@ -95,7 +95,6 @@ export function toggleDraggingEnabled() { /** */ export function showCollectionDialog(manifestId, collectionPath = [], windowId = null) { - console.log(manifestId, collectionPath); return { collectionPath, manifestId, -- GitLab