Skip to content
Snippets Groups Projects
Commit 0909054b authored by Jack Reed's avatar Jack Reed
Browse files

Setup the ability to select single vs bookview

parent f8e06ee8
No related branches found
No related tags found
No related merge requests found
......@@ -20,6 +20,7 @@ describe('window actions', () => {
thumbnailNavigationPosition: 'bottom',
xywh: [0, 0, 400, 400],
rotation: null,
view: 'single',
},
};
expect(actions.addWindow(options)).toEqual(expectedAction);
......@@ -59,6 +60,18 @@ describe('window actions', () => {
});
});
describe('setWindowViewType', () => {
it('returns the appropriate action type', () => {
const id = 'abc123';
const expectedAction = {
type: ActionTypes.SET_WINDOW_VIEW_TYPE,
windowId: id,
viewType: 'book',
};
expect(actions.setWindowViewType(id, 'book')).toEqual(expectedAction);
});
});
describe('toggleWindowSideBarPanel', () => {
it('returns the appropriate action type', () => {
const windowId = 'abc123';
......
......@@ -4,6 +4,7 @@ import ListItem from '@material-ui/core/ListItem';
import Menu from '@material-ui/core/Menu';
import Divider from '@material-ui/core/Divider';
import WindowThumbnailSettings from '../../../src/containers/WindowThumbnailSettings';
import WindowViewSettings from '../../../src/containers/WindowViewSettings';
import WindowTopMenu from '../../../src/components/WindowTopMenu';
/** create wrapper */
......@@ -22,9 +23,10 @@ describe('WindowTopMenu', () => {
it('renders all needed elements', () => {
const wrapper = createWrapper();
expect(wrapper.find(Menu).length).toBe(1);
expect(wrapper.find(ListItem).length).toBe(1);
expect(wrapper.find(ListItem).length).toBe(2);
expect(wrapper.find(WindowThumbnailSettings).length).toBe(1);
expect(wrapper.find(Divider).length).toBe(1);
expect(wrapper.find(WindowViewSettings).length).toBe(1);
expect(wrapper.find(Divider).length).toBe(2);
});
it('passes windowId to <WindowThumbnailSettings/>', () => {
......
import React from 'react';
import { shallow } from 'enzyme';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import RadioGroup from '@material-ui/core/RadioGroup';
import Typography from '@material-ui/core/Typography';
import WindowViewSettings from '../../../src/components/WindowViewSettings';
/** create wrapper */
function createWrapper(props) {
return shallow(
<WindowViewSettings
windowId="xyz"
setWindowViewType={() => {}}
windowViewType="single"
{...props}
/>,
);
}
describe('WindowViewSettings', () => {
it('renders all elements correctly', () => {
const wrapper = createWrapper();
expect(wrapper.find(Typography).length).toBe(1);
expect(wrapper.find(RadioGroup).length).toBe(1);
const labels = wrapper.find(FormControlLabel);
expect(labels.length).toBe(2);
expect(labels.at(0).props().value).toBe('single');
expect(labels.at(1).props().value).toBe('book');
});
it('should set the correct label active', () => {
let wrapper = createWrapper({ windowViewType: 'single' });
expect(wrapper.find(RadioGroup).props().value).toBe('single');
wrapper = createWrapper({ windowViewType: 'book' });
expect(wrapper.find(RadioGroup).props().value).toBe('book');
});
it('updates state when the view config selection changes', () => {
const setWindowViewType = jest.fn();
const wrapper = createWrapper({ setWindowViewType });
wrapper.find(RadioGroup).first().simulate('change', { target: { value: 'book' } });
expect(setWindowViewType).toHaveBeenCalledWith('xyz', 'book');
wrapper.find(RadioGroup).first().simulate('change', { target: { value: 'single' } });
expect(setWindowViewType).toHaveBeenCalledWith('xyz', 'single');
});
});
......@@ -65,6 +65,24 @@ describe('windows reducer', () => {
expect(reducer(before, action)).toEqual(after);
});
it('should handle SET_WINDOW_VIEW_TYPE by changing the view attribute', () => {
const action = {
type: ActionTypes.SET_WINDOW_VIEW_TYPE,
windowId: 'abc123',
viewType: 'book',
};
const before = {
abc123: { view: 'single' },
abc321: { view: 'book' },
};
const after = {
abc123: { view: 'book' },
abc321: { view: 'book' },
};
expect(reducer(before, action)).toEqual(after);
});
describe('TOGGLE_WINDOW_SIDE_BAR_PANEL', () => {
it('sets the sideBarPanel value to the given value when it was changed', () => {
const action = {
......
......@@ -6,6 +6,7 @@ import {
getManifestCanvases,
getThumbnailNavigationPosition,
getManifestTitle,
getWindowViewType,
} from '../../../src/state/selectors';
......@@ -114,3 +115,27 @@ describe('getManifestTitle', () => {
expect(received).toBeUndefined();
});
});
describe('getWindowViewType', () => {
const state = {
windows: {
a: { id: 'a', view: 'single' },
b: { id: 'b' },
},
};
it('should return view type if window exists', () => {
const received = getWindowViewType(state, 'a');
expect(received).toBe('single');
});
it('should return undefined if view type does not exist in window', () => {
const received = getWindowViewType(state, 'b');
expect(received).toBeUndefined();
});
it('should return undefined if window does not exists', () => {
const received = getWindowViewType(state, 'c');
expect(received).toBeUndefined();
});
});
......@@ -2,6 +2,7 @@
"translation": {
"aboutThisItem": "About this item",
"add": "Add",
"book": "Book",
"bottom": "Bottom",
"closeInfoCompanionWindow": "Close information companion window",
"closeMenu": "Close Menu",
......@@ -19,11 +20,13 @@
"openWindows": "Open windows",
"position": "Position",
"right": "Right",
"single": "Single",
"settings": "Settings",
"theme": "Theme",
"thumbnails": "Thumbnails",
"toggleWindowSideBar": "Toggle window sidebar",
"untitled": "[Untitled]",
"view": "View",
"zoomIn": "Zoom in",
"zoomOut": "Zoom out",
"zoomReset": "Reset zoom"
......
......@@ -4,6 +4,7 @@ import Menu from '@material-ui/core/Menu';
import Divider from '@material-ui/core/Divider';
import PropTypes from 'prop-types';
import WindowThumbnailSettings from '../containers/WindowThumbnailSettings';
import WindowViewSettings from '../containers/WindowViewSettings';
/**
*/
......@@ -19,6 +20,10 @@ class WindowTopMenu extends Component {
return (
<>
<Menu id={`window-menu_${windowId}`} anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleClose}>
<ListItem>
<WindowViewSettings windowId={windowId} />
</ListItem>
<Divider />
<ListItem>
<WindowThumbnailSettings windowId={windowId} />
</ListItem>
......
import React, { Component } from 'react';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Radio from '@material-ui/core/Radio';
import RadioGroup from '@material-ui/core/RadioGroup';
import Typography from '@material-ui/core/Typography';
import PhotoIcon from '@material-ui/icons/Photo';
import ViewAgendaIcon from '@material-ui/icons/ViewAgenda';
import PropTypes from 'prop-types';
/**
*
*/
export default class WindowViewSettings extends Component {
/**
* constructor -
*/
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
/**
* @private
*/
handleChange(event) {
const { windowId, setWindowViewType } = this.props;
setWindowViewType(windowId, event.target.value);
}
/**
* render
*
* @return {type} description
*/
render() {
const { windowViewType, t } = this.props;
return (
<>
<Typography>{t('view')}</Typography>
<RadioGroup aria-label={t('position')} name="position" value={windowViewType} onChange={this.handleChange} row>
<FormControlLabel
value="single"
control={<Radio color="primary" icon={<PhotoIcon />} checkedIcon={<PhotoIcon />} />}
label={t('single')}
labelPlacement="bottom"
/>
<FormControlLabel
value="book"
control={<Radio color="primary" icon={<ViewAgendaIconRotated />} checkedIcon={<ViewAgendaIconRotated />} />}
label={t('book')}
labelPlacement="bottom"
/>
</RadioGroup>
</>
);
}
}
/**
* @private
*/
function ViewAgendaIconRotated(props) {
return (
<ViewAgendaIcon style={{ transform: 'rotate(-90deg)' }} />
);
}
WindowViewSettings.propTypes = {
windowId: PropTypes.string.isRequired,
setWindowViewType: PropTypes.func.isRequired,
windowViewType: PropTypes.string.isRequired,
t: PropTypes.func,
};
WindowViewSettings.defaultProps = {
t: key => key,
};
import { compose } from 'redux';
import { connect } from 'react-redux';
import { withNamespaces } from 'react-i18next';
import miradorWithPlugins from '../lib/miradorWithPlugins';
import * as actions from '../state/actions';
import { getWindowViewType } from '../state/selectors';
import WindowViewSettings from '../components/WindowViewSettings';
/**
* mapDispatchToProps - used to hook up connect to action creators
* @memberof ManifestListItem
* @private
*/
const mapDispatchToProps = { setWindowViewType: actions.setWindowViewType };
/**
* mapStateToProps - to hook up connect
* @memberof WindowViewer
* @private
*/
const mapStateToProps = (state, props) => (
{
windowViewType: getWindowViewType(state, props.windowId),
}
);
const enhance = compose(
connect(mapStateToProps, mapDispatchToProps),
withNamespaces(),
miradorWithPlugins,
// further HOC go here
);
export default enhance(WindowViewSettings);
......@@ -13,6 +13,7 @@ const ActionTypes = {
RECEIVE_MANIFEST_FAILURE: 'RECEIVE_MANIFEST_FAILURE',
SET_CONFIG: 'SET_CONFIG',
SET_WINDOW_THUMBNAIL_POSITION: 'SET_WINDOW_THUMBNAIL_POSITION',
SET_WINDOW_VIEW_TYPE: 'SET_WINDOW_VIEW_TYPE',
TOGGLE_WINDOW_SIDE_BAR: 'TOGGLE_WINDOW_SIDE_BAR',
TOGGLE_WINDOW_SIDE_BAR_PANEL: 'TOGGLE_WINDOW_SIDE_BAR_PANEL',
TOGGLE_ZOOM_CONTROLS: 'TOGGLE_ZOOM_CONTROLS',
......
......@@ -27,6 +27,7 @@ export function addWindow(options) {
thumbnailNavigationPosition: 'bottom', // bottom by default in settings.js
xywh: [0, 0, 400, 400],
rotation: null,
view: 'single',
};
return { type: ActionTypes.ADD_WINDOW, window: { ...defaultOptions, ...options } };
}
......@@ -72,3 +73,14 @@ export function toggleWindowSideBarPanel(windowId, panelType) {
export function setWindowThumbnailPosition(windowId, position) {
return { type: ActionTypes.SET_WINDOW_THUMBNAIL_POSITION, windowId, position };
}
/**
* setWindowViewType - action creator
*
* @param {String} windowId
* @param {String} viewType
* @memberof ActionCreators
*/
export function setWindowViewType(windowId, viewType) {
return { type: ActionTypes.SET_WINDOW_VIEW_TYPE, windowId, viewType };
}
......@@ -22,7 +22,14 @@ const windowsReducer = (state = {}, action) => {
sideBarOpen: !state[action.windowId].sideBarOpen,
},
};
case ActionTypes.SET_WINDOW_VIEW_TYPE:
return {
...state,
[action.windowId]: {
...state[action.windowId],
view: action.viewType,
},
};
case ActionTypes.SET_WINDOW_THUMBNAIL_POSITION:
return {
...state,
......
......@@ -54,3 +54,12 @@ export function getManifestTitle(manifest) {
&& manifest.manifestation
&& manifest.manifestation.getLabel().map(label => label.value)[0];
}
/** Return type of view in a certain window.
* @param {object} state
* @param {String} windowId
* @param {String}
*/
export function getWindowViewType(state, windowId) {
return state.windows[windowId] && state.windows[windowId].view;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment