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

Add a toggle to show/hide the left companion window area

parent 701581c1
No related branches found
No related tags found
No related merge requests found
...@@ -144,6 +144,12 @@ describe('companionWindow actions', () => { ...@@ -144,6 +144,12 @@ describe('companionWindow actions', () => {
windowId: 'abc123', windowId: 'abc123',
panelType: 'info', panelType: 'info',
}); });
expect(mockDispatch).toHaveBeenNthCalledWith(2, {
type: ActionTypes.UPDATE_WINDOW,
id: 'abc123',
payload: { companionAreaOpen: true },
});
}); });
}); });
}); });
...@@ -66,6 +66,19 @@ describe('window actions', () => { ...@@ -66,6 +66,19 @@ describe('window actions', () => {
}); });
}); });
describe('setCompanionAreaOpen', () => {
it('returns the appropriate action type', () => {
const id = 'abc123';
const expectedAction = {
type: ActionTypes.UPDATE_WINDOW,
id,
payload: { companionAreaOpen: true },
};
expect(actions.setCompanionAreaOpen(id, true)).toEqual(expectedAction);
});
});
describe('setWindowThumbnailPosition', () => { describe('setWindowThumbnailPosition', () => {
it('returns the appropriate action type', () => { it('returns the appropriate action type', () => {
const id = 'abc123'; const id = 'abc123';
......
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import IconButton from '@material-ui/core/IconButton';
import ArrowLeftSharpIcon from '@material-ui/icons/ArrowLeftSharp';
import ArrowRightSharpIcon from '@material-ui/icons/ArrowRightSharp';
import { CompanionArea } from '../../../src/components/CompanionArea'; import { CompanionArea } from '../../../src/components/CompanionArea';
import CompanionWindowFactory from '../../../src/containers/CompanionWindowFactory'; import CompanionWindowFactory from '../../../src/containers/CompanionWindowFactory';
...@@ -8,6 +11,7 @@ function createWrapper(props) { ...@@ -8,6 +11,7 @@ function createWrapper(props) {
return shallow( return shallow(
<CompanionArea <CompanionArea
windowId="abc123" windowId="abc123"
position="right"
companionWindows={[ companionWindows={[
{ position: 'right', id: 'foo' }, { position: 'right', id: 'foo' },
{ position: 'right', id: 'baz' }, { position: 'right', id: 'baz' },
...@@ -29,4 +33,64 @@ describe('CompanionArea', () => { ...@@ -29,4 +33,64 @@ describe('CompanionArea', () => {
expect(props.id).toBe('foo'); expect(props.id).toBe('foo');
expect(props.windowId).toBe('abc123'); expect(props.windowId).toBe('abc123');
}); });
it('has a toggle to show the companion area window in the left position', () => {
const setCompanionAreaOpen = jest.fn();
const wrapper = createWrapper({
position: 'left', sideBarOpen: true, setCompanionAreaOpen, companionAreaOpen: false,
});
expect(wrapper.find('WithStyles(IconButton)').length).toBe(1);
expect(wrapper.find('WithStyles(IconButton)').matchesElement(
<IconButton>
<ArrowRightSharpIcon />
</IconButton>,
)).toBe(true);
expect(wrapper.find('div.mirador-companion-windows').length).toBe(1);
expect(wrapper.find('div.mirador-companion-windows').props().style.display).toBe('none');
wrapper.find('WithStyles(IconButton)').simulate('click');
expect(setCompanionAreaOpen).toHaveBeenCalledWith('abc123', true);
});
it('has a toggle to hide the companion area window in the left position', () => {
const setCompanionAreaOpen = jest.fn();
const wrapper = createWrapper({
position: 'left', sideBarOpen: true, setCompanionAreaOpen, companionAreaOpen: true,
});
expect(wrapper.find('WithStyles(IconButton)').length).toBe(1);
expect(wrapper.find('WithStyles(IconButton)').matchesElement(
<IconButton>
<ArrowLeftSharpIcon />
</IconButton>,
)).toBe(true);
expect(wrapper.find('div.mirador-companion-windows').length).toBe(1);
expect(wrapper.find('div.mirador-companion-windows').props().style.display).toBe('flex');
wrapper.find('WithStyles(IconButton)').simulate('click');
expect(setCompanionAreaOpen).toHaveBeenCalledWith('abc123', false);
});
it('does not show a toggle if the sidebar is collapsed', () => {
const wrapper = createWrapper({
position: 'left', sideBarOpen: false, setCompanionAreaOpen: () => {}, companionAreaOpen: true,
});
expect(wrapper.find('WithStyles(IconButton)').length).toBe(0);
});
it('does not show a toggle in other positions', () => {
const wrapper = createWrapper({
position: 'whatever', sideBarOpen: true, setCompanionAreaOpen: () => {}, companionAreaOpen: true,
});
expect(wrapper.find('WithStyles(IconButton)').length).toBe(0);
});
}); });
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import IconButton from '@material-ui/core/IconButton';
import ArrowLeftIcon from '@material-ui/icons/ArrowLeftSharp';
import ArrowRightIcon from '@material-ui/icons/ArrowRightSharp';
import CompanionWindowFactory from '../containers/CompanionWindowFactory'; import CompanionWindowFactory from '../containers/CompanionWindowFactory';
import ns from '../config/css-ns';
/** */ /** */
export class CompanionArea extends Component { export class CompanionArea extends Component {
/** */ /** */
render() { render() {
const { companionWindows, windowId } = this.props; const {
classes, companionWindows, companionAreaOpen, setCompanionAreaOpen,
position, sideBarOpen, windowId,
} = this.props;
return ( return (
<> <div className={classes.root} style={{ minHeight: 0, display: 'flex' }}>
{
setCompanionAreaOpen && position === 'left' && sideBarOpen && companionWindows.length > 0
&& (
<IconButton
className={classes.toggle}
onClick={() => { setCompanionAreaOpen(windowId, !companionAreaOpen); }}
>
{ companionAreaOpen ? <ArrowLeftIcon /> : <ArrowRightIcon /> }
</IconButton>
)
}
<div className={ns('companion-windows')} style={{ display: companionAreaOpen && (position !== 'left' || sideBarOpen) ? 'flex' : 'none' }}>
{ {
companionWindows.map(cw => ( companionWindows.map(cw => (
<CompanionWindowFactory id={cw.id} key={cw.id} windowId={windowId} /> <CompanionWindowFactory id={cw.id} key={cw.id} windowId={windowId} />
)) ))
} }
</> </div>
</div>
); );
} }
} }
CompanionArea.propTypes = { CompanionArea.propTypes = {
classes: PropTypes.object, // eslint-disable-line react/forbid-prop-types
position: PropTypes.string.isRequired,
windowId: PropTypes.string.isRequired, windowId: PropTypes.string.isRequired,
companionWindows: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types companionWindows: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types
sideBarOpen: PropTypes.bool,
companionAreaOpen: PropTypes.bool,
setCompanionAreaOpen: PropTypes.func,
};
CompanionArea.defaultProps = {
sideBarOpen: false,
companionAreaOpen: true,
setCompanionAreaOpen: () => {},
classes: {},
}; };
...@@ -41,12 +41,14 @@ export class CompanionWindow extends Component { ...@@ -41,12 +41,14 @@ export class CompanionWindow extends Component {
position === 'left' position === 'left'
? updateCompanionWindow ? updateCompanionWindow
&& ( && (
<>
<IconButton <IconButton
aria-label={t('openInCompanionWindow')} aria-label={t('openInCompanionWindow')}
onClick={() => { updateCompanionWindow(windowId, id, { position: 'right' }); }} onClick={() => { updateCompanionWindow(windowId, id, { position: 'right' }); }}
> >
<OpenInNewIcon /> <OpenInNewIcon />
</IconButton> </IconButton>
</>
) )
: ( : (
<IconButton <IconButton
......
import { compose } from 'redux'; import { compose } from 'redux';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withStyles } from '@material-ui/core';
import { getCompanionWindowsOfWindow } from '../state/selectors'; import { getCompanionWindowsOfWindow } from '../state/selectors';
import * as actions from '../state/actions';
import { CompanionArea } from '../components/CompanionArea'; import { CompanionArea } from '../components/CompanionArea';
/** */ /** */
const mapStateToProps = (state, { windowId, position }) => ({ const mapStateToProps = (state, { windowId, position }) => ({
sideBarOpen: state.windows[windowId].sideBarOpen,
companionWindows: getCompanionWindowsOfWindow(state, windowId) companionWindows: getCompanionWindowsOfWindow(state, windowId)
.filter(cw => cw.position === position), .filter(cw => cw.position === position),
companionAreaOpen: position !== 'left' || state.windows[windowId].companionAreaOpen,
});
const mapDispatchToProps = ({
setCompanionAreaOpen: actions.setCompanionAreaOpen,
});
/** */
const styles = theme => ({
root: {
position: 'relative',
},
toggle: {
position: 'absolute',
left: '100%',
width: '1rem',
zIndex: theme.zIndex.drawer,
backgroundColor: theme.palette.background.paper,
border: `1px solid ${theme.palette.primary.dark}`,
borderRadius: 0,
padding: 2,
marginTop: '1rem',
},
}); });
const enhance = compose( const enhance = compose(
connect(mapStateToProps), withStyles(styles),
connect(mapStateToProps, mapDispatchToProps),
); );
export default enhance(CompanionArea); export default enhance(CompanionArea);
...@@ -18,7 +18,7 @@ const mapStateToProps = (state, { id, windowId }) => { ...@@ -18,7 +18,7 @@ const mapStateToProps = (state, { id, windowId }) => {
...companionWindow, ...companionWindow,
isDisplayed: (companionWindow isDisplayed: (companionWindow
&& companionWindow.content && companionWindow.content
&& companionWindow.content.length > 0) && (companionWindow.position !== 'left' || state.windows[windowId].sideBarOpen), && companionWindow.content.length > 0),
}; };
}; };
......
import uuid from 'uuid/v4'; import uuid from 'uuid/v4';
import ActionTypes from './action-types'; import ActionTypes from './action-types';
import { updateWindow, setWindowSideBarPanel } from './window'; import { updateWindow, setCompanionAreaOpen, setWindowSideBarPanel } from './window';
const defaultProps = { const defaultProps = {
content: null, content: null,
...@@ -72,6 +72,8 @@ export function popOutCompanionWindow(windowId, panelType, position) { ...@@ -72,6 +72,8 @@ export function popOutCompanionWindow(windowId, panelType, position) {
if (position === 'left') { if (position === 'left') {
dispatch(setWindowSideBarPanel(windowId, panelType)); dispatch(setWindowSideBarPanel(windowId, panelType));
dispatch(setCompanionAreaOpen(windowId, true));
} }
const action = dispatch(addCompanionWindow({ content: panelType, position })); const action = dispatch(addCompanionWindow({ content: panelType, position }));
......
...@@ -42,6 +42,11 @@ export function updateWindow(id, payload) { ...@@ -42,6 +42,11 @@ export function updateWindow(id, payload) {
return { type: ActionTypes.UPDATE_WINDOW, id, payload }; return { type: ActionTypes.UPDATE_WINDOW, id, payload };
} }
/** */
export function setCompanionAreaOpen(id, companionAreaOpen) {
return { type: ActionTypes.UPDATE_WINDOW, id, payload: { companionAreaOpen } };
}
/** /**
* removeWindow - action creator * removeWindow - action creator
* *
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment