Skip to content
Snippets Groups Projects
Commit 5dd569d0 authored by Chris Beer's avatar Chris Beer
Browse files

Extract configuration for view types

parent 051f4c2c
Branches
Tags
No related merge requests found
......@@ -7,11 +7,12 @@ import { WindowViewSettings } from '../../../src/components/WindowViewSettings';
/** create wrapper */
function createWrapper(props) {
return shallow(
return mount(
<WindowViewSettings
classes={{}}
windowId="xyz"
setWindowViewType={() => {}}
viewTypes={['single', 'book', 'scroll', 'gallery']}
windowViewType="single"
{...props}
/>,
......@@ -64,6 +65,7 @@ describe('WindowViewSettings', () => {
classes={{}}
windowId="xyz"
setWindowViewType={() => {}}
viewTypes={['single', 'book', 'scroll', 'gallery']}
windowViewType="single"
/>,
);
......
......@@ -11,6 +11,7 @@ import {
getWindowManifests,
getWindows,
getMaximizedWindowsIds,
getAllowedWindowViewTypes,
} from '../../../src/state/selectors/windows';
describe('getWindows', () => {
......@@ -104,6 +105,12 @@ describe('getWindowViewType', () => {
config: {
window: {
defaultView: 'default',
views: [
{ behaviors: ['individuals'], key: 'single' },
{ behaviors: ['paged'], key: 'book' },
{ behaviors: ['continuous'], key: 'scroll' },
{ key: 'gallery' },
],
},
},
manifests: {
......@@ -150,6 +157,36 @@ describe('getWindowViewType', () => {
});
});
describe('getAllowedWindowViewTypes', () => {
const state = {
config: {
window: {
defaultView: 'single',
views: [
{ behaviors: ['individuals'], key: 'single' },
{ behaviors: ['paged'], key: 'book' },
{ behaviors: ['continuous'], key: 'scroll' },
{ key: 'gallery' },
],
},
},
manifests: {
x: { json: { ...manifestFixture001 } },
y: { json: { ...manifestFixture015 } },
},
};
it('should return unrestricted view types', () => {
const received = getAllowedWindowViewTypes(state, { manifestId: 'x' });
expect(received).toEqual(['single', 'gallery']);
});
it('should return view types where behaviors match', () => {
const received = getAllowedWindowViewTypes(state, { manifestId: 'y' });
expect(received).toEqual(['single', 'book', 'gallery']);
});
});
describe('getViewer', () => {
const state = {
viewers: {
......
......@@ -4,6 +4,7 @@ import FormControlLabel from '@material-ui/core/FormControlLabel';
import MenuItem from '@material-ui/core/MenuItem';
import ListSubheader from '@material-ui/core/ListSubheader';
import SingleIcon from '@material-ui/icons/CropOriginalSharp';
import ScrollViewIcon from '@material-ui/icons/ViewColumn';
import PropTypes from 'prop-types';
import BookViewIcon from './icons/BookViewIcon';
import GalleryViewIcon from './icons/GalleryViewIcon';
......@@ -55,53 +56,41 @@ export class WindowViewSettings extends Component {
*/
render() {
const {
classes, handleClose, t, windowViewType,
classes, handleClose, t, windowViewType, viewTypes,
} = this.props;
return (
<>
<ListSubheader role="presentation" disableSticky tabIndex="-1">{t('view')}</ListSubheader>
if (viewTypes.length === 0) return null;
const iconMap = {
book: BookViewIcon,
gallery: GalleryViewIcon,
scroll: ScrollViewIcon,
single: SingleIcon,
};
/** */
const ViewItem = ({ Icon, value }) => (
<MenuItem
className={classes.MenuItem}
ref={ref => this.handleSelectedRef(ref)}
onClick={() => { this.handleChange('single'); handleClose(); }}
onClick={() => { this.handleChange(value); handleClose(); }}
>
<FormControlLabel
value="single"
classes={{ label: windowViewType === 'single' ? classes.selectedLabel : classes.label }}
control={<SingleIcon color={windowViewType === 'single' ? 'secondary' : undefined} />}
label={t('single')}
labelPlacement="bottom"
/>
</MenuItem>
<MenuItem className={classes.MenuItem} onClick={() => { this.handleChange('book'); handleClose(); }}>
<FormControlLabel
value="book"
classes={{ label: windowViewType === 'book' ? classes.selectedLabel : classes.label }}
control={<BookViewIcon color={windowViewType === 'book' ? 'secondary' : undefined} />}
label={t('book')}
labelPlacement="bottom"
/>
</MenuItem>
<MenuItem className={classes.MenuItem} onClick={() => { this.handleChange('scroll'); handleClose(); }}>
<FormControlLabel
value="scroll"
classes={{ label: windowViewType === 'scroll' ? classes.selectedLabel : classes.label }}
control={<BookViewIcon color={windowViewType === 'scroll' ? 'secondary' : undefined} />}
label={t('scroll')}
labelPlacement="bottom"
/>
</MenuItem>
<MenuItem className={classes.MenuItem} onClick={() => { this.handleChange('gallery'); handleClose(); }}>
<FormControlLabel
value="gallery"
classes={{ label: windowViewType === 'gallery' ? classes.selectedLabel : classes.label }}
control={<GalleryViewIcon color={windowViewType === 'gallery' ? 'secondary' : undefined} />}
label={t('gallery')}
value={value}
classes={{ label: windowViewType === value ? classes.selectedLabel : classes.label }}
control={Icon && <Icon color={windowViewType === value ? 'secondary' : undefined} />}
label={t(value)}
labelPlacement="bottom"
/>
</MenuItem>
);
return (
<>
<ListSubheader role="presentation" disableSticky tabIndex="-1">{t('view')}</ListSubheader>
{viewTypes.map(value => (
<ViewItem Icon={iconMap[value]} key={value} value={value} />
))}
</>
);
}
......@@ -112,10 +101,12 @@ WindowViewSettings.propTypes = {
handleClose: PropTypes.func,
setWindowViewType: PropTypes.func.isRequired,
t: PropTypes.func,
viewTypes: PropTypes.arrayOf(PropTypes.string),
windowId: PropTypes.string.isRequired,
windowViewType: PropTypes.string.isRequired,
};
WindowViewSettings.defaultProps = {
handleClose: () => {},
t: key => key,
viewTypes: [],
};
......@@ -242,7 +242,13 @@ export default {
canvas: true,
annotations: true,
search: true,
}
},
views: [
{ key: 'single', behaviors: ['individuals'] },
{ key: 'book', behaviors: ['paged'] },
{ key: 'scroll', behaviors: ['continuous'] },
{ key: 'gallery' },
],
},
windows: [ // Array of windows to be open when mirador initializes (each object should at least provide a manifestId key with the value of the IIIF presentation manifest to load)
/**
......
......@@ -4,7 +4,7 @@ import { withTranslation } from 'react-i18next';
import { withStyles } from '@material-ui/core/styles';
import { withPlugins } from '../extend/withPlugins';
import * as actions from '../state/actions';
import { getWindowViewType } from '../state/selectors';
import { getAllowedWindowViewTypes, getWindowViewType } from '../state/selectors';
import { WindowViewSettings } from '../components/WindowViewSettings';
/**
......@@ -21,6 +21,7 @@ const mapDispatchToProps = { setWindowViewType: actions.setWindowViewType };
*/
const mapStateToProps = (state, { windowId }) => (
{
viewTypes: getAllowedWindowViewTypes(state, { windowId }),
windowViewType: getWindowViewType(state, { windowId }),
}
);
......
......@@ -52,6 +52,11 @@ export const getDefaultView = createSelector(
({ window }) => window && window.defaultView,
);
export const getViewConfigs = createSelector(
[getConfig],
({ window }) => (window && window.views) || [],
);
export const getThemeDirection = createSelector(
[getConfig],
({ theme }) => theme.direction || 'ltr',
......
......@@ -5,7 +5,7 @@ import {
getManifestViewingHint,
getManifestoInstance,
} from './manifests';
import { getDefaultView } from './config';
import { getDefaultView, getViewConfigs } from './config';
import { getWorkspaceType } from './workspace';
/**
......@@ -85,19 +85,41 @@ export const getWindowViewType = createSelector(
getManifestViewingHint,
getManifestBehaviors,
getDefaultView,
getViewConfigs,
],
(window, manifestViewingHint, manifestBehaviors, defaultView) => {
const lookup = {
continuous: 'scroll',
individuals: 'single',
paged: 'book',
};
return (window && window.view)
|| lookup[manifestBehaviors.find(b => lookup[b]) || manifestViewingHint]
|| defaultView;
(window, manifestViewingHint, manifestBehaviors, defaultView, viewConfig) => {
if (window && window.view) return window.view;
const config = viewConfig.find(view => (
view.behaviors
&& view.behaviors.some(b => manifestViewingHint === b || manifestBehaviors.includes(b))
));
return (config && config.key) || defaultView;
},
);
/** */
export const getAllowedWindowViewTypes = createSelector(
[
getManifestViewingHint,
getManifestBehaviors,
getDefaultView,
getViewConfigs,
],
(manifestViewingHint, manifestBehaviors, defaultView, viewConfig) => (
viewConfig.reduce((allowedViews, view) => {
if (
view.key === defaultView
|| !view.behaviors
|| view.behaviors.some(b => (
manifestViewingHint === b || manifestBehaviors.includes(b)
))) allowedViews.push(view.key);
return allowedViews;
}, [])
),
);
export const getViewer = createSelector(
[
state => state.viewers,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment