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

Add toggle between compact + thumbnail canvas navigation

parent c22472c6
No related branches found
No related tags found
No related merge requests found
......@@ -72,4 +72,9 @@ describe('CompanionWindow', () => {
expect(updateCompanionWindow).toHaveBeenCalledTimes(1);
expect(updateCompanionWindow).toHaveBeenCalledWith('x', 'abc123', { position: 'right' });
});
it('renders title controls', () => {
companionWindow = createWrapper({ position: 'bottom', titleControls: <div className="xyz" /> });
expect(companionWindow.find('div.xyz').length).toBe(1);
});
});
......@@ -5,40 +5,70 @@ import ListItem from '@material-ui/core/ListItem';
import Typography from '@material-ui/core/Typography';
import manifesto from 'manifesto.js';
import { WindowSideBarCanvasPanel } from '../../../src/components/WindowSideBarCanvasPanel';
import { CanvasThumbnail } from '../../../src/components/CanvasThumbnail';
import manifestJson from '../../fixtures/version-2/019.json';
import { getIdAndLabelOfCanvases } from '../../../src/state/selectors';
describe('WindowSideBarCanvasPanel', () => {
let wrapper;
let setCanvas;
let canvases;
beforeEach(() => {
setCanvas = jest.fn();
canvases = manifesto.create(manifestJson).getSequences()[0].getCanvases();
/**
* Helper function to create a shallow wrapper around WindowSideBarCanvasPanel
*/
function createWrapper(props) {
const canvases = manifesto.create(manifestJson).getSequences()[0].getCanvases();
wrapper = shallow(
return shallow(
<WindowSideBarCanvasPanel
id="asdf"
canvases={canvases}
classes={{}}
t={key => key}
windowId="xyz"
setCanvas={setCanvas}
setCanvas={() => {}}
config={{ canvasNavigation: { height: 100 } }}
{...props}
/>,
);
}
describe('WindowSideBarCanvasPanel', () => {
let setCanvas;
beforeEach(() => {
setCanvas = jest.fn();
});
it('renders all needed elements', () => {
it('renders all needed elements for the thumbnail view', () => {
const wrapper = createWrapper();
expect(wrapper.props().title).toBe('canvasIndex');
expect(wrapper.find(List).length).toBe(1);
expect(wrapper.find(ListItem).length).toBe(3);
expect(wrapper.find(ListItem).first().props().component).toEqual('li');
expect(wrapper.find(List).find(Typography).length).toBe(3);
expect(wrapper.find(CanvasThumbnail).length).toBe(3);
});
describe('handleVariantChange', () => {
it('toggles state', () => {
const wrapper = createWrapper();
wrapper.instance().handleVariantChange({ target: { value: 'compact' } });
expect(wrapper.state().variant).toBe('compact');
});
});
it('renders all needed elements for the compact view', () => {
const wrapper = createWrapper();
wrapper.setState({ variant: 'compact' });
expect(wrapper.props().title).toBe('canvasIndex');
expect(wrapper.find(List).length).toBe(1);
expect(wrapper.find(ListItem).length).toBe(3);
expect(wrapper.find(ListItem).first().props().component).toEqual('li');
expect(wrapper.find(List).find(Typography).length).toBe(3);
expect(wrapper.find(CanvasThumbnail).length).toBe(0);
});
it('should set the correct labels', () => {
const wrapper = createWrapper();
const canvases = manifesto.create(manifestJson).getSequences()[0].getCanvases();
const idsAndLabels = getIdAndLabelOfCanvases(canvases);
expect(wrapper
.find(List)
......@@ -56,6 +86,7 @@ describe('WindowSideBarCanvasPanel', () => {
});
it('should call the onClick handler of a list item', () => {
const wrapper = createWrapper({ setCanvas });
wrapper.find(ListItem).at(1).simulate('click');
expect(setCanvas).toHaveBeenCalledTimes(1);
});
......
......@@ -21,7 +21,7 @@ export class CompanionWindow extends Component {
render() {
const {
classes, paperClassName, id, onCloseClick, updateCompanionWindow, isDisplayed,
position, t, windowId, title, children,
position, t, windowId, title, children, titleControls,
} = this.props;
return (
......@@ -35,10 +35,13 @@ export class CompanionWindow extends Component {
component="aside"
aria-label={title}
>
<Toolbar variant="dense" className={[position === 'left' ? classes.leftPadding : undefined, ns('companion-window-header')].join(' ')} disableGutters>
<Toolbar className={[classes.toolbar, position === 'left' ? classes.leftPadding : undefined, ns('companion-window-header')].join(' ')} disableGutters>
<Typography variant="h3" className={classes.windowSideBarTitle}>
{title}
</Typography>
<div className={ns('companion-window-title-controls')}>
{titleControls}
</div>
{
position === 'left'
? updateCompanionWindow
......@@ -94,6 +97,7 @@ CompanionWindow.propTypes = {
isDisplayed: PropTypes.bool,
t: PropTypes.func,
title: PropTypes.string,
titleControls: PropTypes.node,
windowId: PropTypes.string.isRequired,
children: PropTypes.node,
};
......@@ -107,4 +111,5 @@ CompanionWindow.defaultProps = {
title: null,
t: key => key,
children: undefined,
titleControls: null,
};
......@@ -4,6 +4,10 @@ import classNames from 'classnames';
import Typography from '@material-ui/core/Typography';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import FilledInput from '@material-ui/core/FilledInput';
import MenuItem from '@material-ui/core/MenuItem';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';
import { CanvasThumbnail } from './CanvasThumbnail';
import ManifestoCanvas from '../lib/ManifestoCanvas';
import CompanionWindow from '../containers/CompanionWindow';
......@@ -13,37 +17,51 @@ import { getIdAndLabelOfCanvases } from '../state/selectors';
* a panel showing the canvases for a given manifest
*/
export class WindowSideBarCanvasPanel extends Component {
/**
* render
*/
render() {
/** */
constructor(props) {
super(props);
this.state = { variant: 'thumbnail' };
this.handleVariantChange = this.handleVariantChange.bind(this);
}
/** */
handleVariantChange(event) {
this.setState({ variant: event.target.value });
}
/** */
renderCompact(canvas, otherCanvas) {
const {
canvases, classes, config, setCanvas, t, windowId, id,
classes,
} = this.props;
const canvasesIdAndLabel = getIdAndLabelOfCanvases(canvases);
return (
<CompanionWindow title={t('canvasIndex')} id={id} windowId={windowId}>
<List>
{
canvasesIdAndLabel.map((canvas, canvasIndex) => {
<>
<Typography
className={classNames(classes.label)}
variant="body2"
>
{canvas.label}
</Typography>
</>
);
}
/** */
renderThumbnail(canvas, otherCanvas) {
const {
classes, config,
} = this.props;
const { width, height } = config.canvasNavigation;
const manifestoCanvas = new ManifestoCanvas(canvases[canvasIndex]);
const isValid = manifestoCanvas.hasValidDimensions;
const onClick = () => { setCanvas(windowId, canvasIndex); }; // eslint-disable-line require-jsdoc, max-len
const manifestoCanvas = new ManifestoCanvas(otherCanvas);
return (
<ListItem
key={canvas.id}
alignItems="flex-start"
onClick={onClick}
button
component="li"
>
<>
<div style={{ minWidth: 50 }}>
<CanvasThumbnail
className={classNames(classes.clickable)}
isValid={isValid}
isValid={manifestoCanvas.hasValidDimensions}
imageUrl={manifestoCanvas.thumbnail(width, height)}
maxHeight={config.canvasNavigation.height}
maxWidth={config.canvasNavigation.width}
......@@ -56,6 +74,58 @@ export class WindowSideBarCanvasPanel extends Component {
>
{canvas.label}
</Typography>
</>
);
}
/**
* render
*/
render() {
const {
canvases, setCanvas, t, windowId, id,
} = this.props;
const { variant } = this.state;
const canvasesIdAndLabel = getIdAndLabelOfCanvases(canvases);
return (
<CompanionWindow
title={t('canvasIndex')}
id={id}
windowId={windowId}
titleControls={(
<FormControl variant="filled">
<Select
value={variant}
onChange={this.handleVariantChange}
name="variant"
autoWidth
variant="filled"
input={<FilledInput name="variant" />}
>
<MenuItem value="compact">Compact List</MenuItem>
<MenuItem value="thumbnail">Thumbnail List</MenuItem>
</Select>
</FormControl>
)}
>
<List>
{
canvasesIdAndLabel.map((canvas, canvasIndex) => {
const onClick = () => { setCanvas(windowId, canvasIndex); }; // eslint-disable-line require-jsdoc, max-len
return (
<ListItem
key={canvas.id}
alignItems="flex-start"
onClick={onClick}
button
component="li"
>
{variant === 'compact' && this.renderCompact(canvas, canvases[canvasIndex])}
{variant === 'thumbnail' && this.renderThumbnail(canvas, canvases[canvasIndex])}
</ListItem>
);
})
......
......@@ -59,6 +59,9 @@ const styles = theme => ({
positionButton: {
order: -100,
},
toolbar: {
minHeight: 'max-content',
},
leftPadding: {
...theme.mixins.gutters(),
paddingRight: 0,
......
......@@ -20,6 +20,21 @@
}
}
&-companion-window-header {
flex-wrap: wrap;
}
&-companion-window-title-controls {
order: 1000;
flex-grow: 1;
}
&-companion-window-bottom {
.mirador-companion-window-title-controls {
order: unset;
}
}
&-companion-window-header {
background: $surface-dark;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment