diff --git a/__tests__/src/actions/workspace.test.js b/__tests__/src/actions/workspace.test.js index bee998d415e8f99c6053e41a98191b214662d8a7..4eec7ef21699c1ba4770369fe9e3c91a72411ef2 100644 --- a/__tests__/src/actions/workspace.test.js +++ b/__tests__/src/actions/workspace.test.js @@ -91,4 +91,12 @@ describe('workspace actions', () => { expect(actions.toggleWorkspaceExposeMode()).toEqual(expectedAction); }); }); + describe('toggleDraggingEnabled', () => { + it('should set the draggingEnabled to false', () => { + const expectedAction = { + type: ActionTypes.TOGGLE_DRAGGING, + }; + expect(actions.toggleDraggingEnabled()).toEqual(expectedAction); + }); + }); }); diff --git a/__tests__/src/components/WindowTopMenu.test.js b/__tests__/src/components/WindowTopMenu.test.js index 1f8dce45749a34fa07388ef67eb7e6713a8f7edc..637aa4ffd92a0caba47b139dd5206163642d9d92 100644 --- a/__tests__/src/components/WindowTopMenu.test.js +++ b/__tests__/src/components/WindowTopMenu.test.js @@ -13,6 +13,7 @@ function createWrapper(props) { windowId="xyz" handleClose={() => {}} anchorEl={null} + toggleDraggingEnabled={() => {}} {...props} />, ); @@ -35,18 +36,24 @@ describe('WindowTopMenu', () => { it('passses correct props to <Menu/> when no achor element given', () => { const handleClose = jest.fn(); - const wrapper = createWrapper({ handleClose }); + const toggleDraggingEnabled = jest.fn(); + const wrapper = createWrapper({ handleClose, toggleDraggingEnabled }); expect(wrapper.find(Menu).first().props().anchorEl).toBe(null); expect(wrapper.find(Menu).first().props().open).toBe(false); expect(wrapper.find(Menu).first().props().onClose).toBe(handleClose); + expect(wrapper.find(Menu).first().props().onEntering).toBe(toggleDraggingEnabled); + expect(wrapper.find(Menu).first().props().onExit).toBe(toggleDraggingEnabled); }); - it('passses correct props to <Menu/> when no achor element given', () => { + it('passses correct props to <Menu/> when achor element given', () => { const handleClose = jest.fn(); + const toggleDraggingEnabled = jest.fn(); const anchorEl = {}; - const wrapper = createWrapper({ anchorEl, handleClose }); + const wrapper = createWrapper({ anchorEl, handleClose, toggleDraggingEnabled }); expect(wrapper.find(Menu).first().props().anchorEl).toBe(anchorEl); expect(wrapper.find(Menu).first().props().open).toBe(true); expect(wrapper.find(Menu).first().props().onClose).toBe(handleClose); + expect(wrapper.find(Menu).first().props().onEntering).toBe(toggleDraggingEnabled); + expect(wrapper.find(Menu).first().props().onExit).toBe(toggleDraggingEnabled); }); }); diff --git a/__tests__/src/reducers/workspace.test.js b/__tests__/src/reducers/workspace.test.js index e55e462697af093a23f957d2a27822f1009c91ac..fee4a988b8729ace1708996d72f9a174babadf10 100644 --- a/__tests__/src/reducers/workspace.test.js +++ b/__tests__/src/reducers/workspace.test.js @@ -112,4 +112,9 @@ describe('workspace reducer', () => { type: ActionTypes.IMPORT_MIRADOR_STATE, })).toEqual({ new: 'stuff' }); }); + it('should handle ActionTypes.TOGGLE_DRAGGING', () => { + expect(workspaceReducer({ draggingEnabled: true }, { + type: ActionTypes.TOGGLE_DRAGGING, + })).toEqual({ draggingEnabled: false }); + }); }); diff --git a/src/components/WindowSideBarCanvasPanel.js b/src/components/WindowSideBarCanvasPanel.js index 959e92a6f1558d63d52d3b05e1af70293c1eb53e..d951ff3b4295a4103eb5641a090322eda3bbc222 100644 --- a/src/components/WindowSideBarCanvasPanel.js +++ b/src/components/WindowSideBarCanvasPanel.js @@ -18,8 +18,11 @@ export class WindowSideBarCanvasPanel extends Component { /** */ constructor(props) { super(props); - this.handleVariantChange = this.handleVariantChange.bind(this); + + this.state = { + variantSelectionOpened: false, + }; } /** @private */ @@ -37,6 +40,7 @@ export class WindowSideBarCanvasPanel extends Component { const { updateVariant } = this.props; updateVariant(event.target.value); + this.setState({ variantSelectionOpened: false }); } /** */ @@ -92,10 +96,18 @@ export class WindowSideBarCanvasPanel extends Component { */ render() { const { - canvases, selectedCanvases, setCanvas, classes, t, variant, windowId, id, + canvases, + classes, + id, + selectedCanvases, + setCanvas, + t, + toggleDraggingEnabled, + variant, + windowId, } = this.props; - + const { variantSelectionOpened } = this.state; const canvasesIdAndLabel = this.getIdAndLabelOfCanvases(canvases); return ( <CompanionWindow @@ -116,6 +128,15 @@ export class WindowSideBarCanvasPanel extends Component { value={variant} onChange={this.handleVariantChange} name="variant" + open={variantSelectionOpened} + onOpen={(e) => { + toggleDraggingEnabled(); + this.setState({ variantSelectionOpened: true }); + }} + onClose={(e) => { + toggleDraggingEnabled(); + this.setState({ variantSelectionOpened: false }); + }} classes={{ select: classes.select }} className={classes.selectEmpty} > @@ -123,7 +144,7 @@ export class WindowSideBarCanvasPanel extends Component { <MenuItem value="thumbnail"><Typography variant="body2">{ t('thumbnailList') }</Typography></MenuItem> </Select> </FormControl> - )} + )} > <List> { @@ -160,6 +181,7 @@ WindowSideBarCanvasPanel.propTypes = { selectedCanvases: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.string })), setCanvas: PropTypes.func.isRequired, t: PropTypes.func.isRequired, + toggleDraggingEnabled: PropTypes.func.isRequired, updateVariant: PropTypes.func.isRequired, variant: PropTypes.oneOf(['compact', 'thumbnail']), windowId: PropTypes.string.isRequired, diff --git a/src/components/WindowTopMenu.js b/src/components/WindowTopMenu.js index 458085b447659cae1aa886de0439881416a1eb97..2e2af8a0a2c35ac2076de33a0901be32b6c62d94 100644 --- a/src/components/WindowTopMenu.js +++ b/src/components/WindowTopMenu.js @@ -30,7 +30,7 @@ export class WindowTopMenu extends Component { */ render() { const { - containerId, handleClose, anchorEl, windowId, + containerId, handleClose, anchorEl, toggleDraggingEnabled, windowId, } = this.props; // const {} = this.state; @@ -51,6 +51,8 @@ export class WindowTopMenu extends Component { getContentAnchorEl={null} open={Boolean(anchorEl)} onClose={handleClose} + onEntering={toggleDraggingEnabled} + onExit={toggleDraggingEnabled} disableAutoFocusItem > <WindowViewSettings windowId={windowId} handleClose={handleClose} /> @@ -66,6 +68,7 @@ WindowTopMenu.propTypes = { anchorEl: PropTypes.object, // eslint-disable-line react/forbid-prop-types containerId: PropTypes.string.isRequired, handleClose: PropTypes.func.isRequired, + toggleDraggingEnabled: PropTypes.func.isRequired, windowId: PropTypes.string.isRequired, }; diff --git a/src/components/WorkspaceElastic.js b/src/components/WorkspaceElastic.js index f2d4ec95d68a27ab9328031ff821f5738e776c4e..f830fb93ef355c5f588d91b5e315a10a88093c6b 100644 --- a/src/components/WorkspaceElastic.js +++ b/src/components/WorkspaceElastic.js @@ -54,6 +54,7 @@ class WorkspaceElastic extends React.Component { }} cancel={`.${ns('window')}`} className={ns('workspace')} + disableDragging={!workspace.draggingEnabled} > { Object.keys(elasticLayout).map(windowId => ( diff --git a/src/containers/WindowSideBarCanvasPanel.js b/src/containers/WindowSideBarCanvasPanel.js index f3318dc59c3515e72b7e1fbf473263a6bde1ded0..32fb2f0e72314d3c06031f1642eb09cb508d7955 100644 --- a/src/containers/WindowSideBarCanvasPanel.js +++ b/src/containers/WindowSideBarCanvasPanel.js @@ -25,9 +25,14 @@ const mapStateToProps = (state, { id, windowId }) => { }; }; -/** */ +/** + * mapStateToProps - used to hook up connect to state + * @memberof WindowSideBarCanvasPanel + * @private + */ const mapDispatchToProps = (dispatch, { id, windowId }) => ({ setCanvas: (...args) => dispatch(actions.setCanvas(...args)), + toggleDraggingEnabled: () => dispatch(actions.toggleDraggingEnabled()), updateVariant: variant => dispatch( actions.updateCompanionWindow(windowId, id, { variant }), ), diff --git a/src/containers/WindowTopMenu.js b/src/containers/WindowTopMenu.js index a422c18f00b3024b3942c80dab7247b0b25375f9..95bdc612c648a7cd82ab458be95c0fd02c1256eb 100644 --- a/src/containers/WindowTopMenu.js +++ b/src/containers/WindowTopMenu.js @@ -2,6 +2,7 @@ import { compose } from 'redux'; import { connect } from 'react-redux'; import { withTranslation } from 'react-i18next'; import { withPlugins } from '../extend/withPlugins'; +import * as actions from '../state/actions'; import { WindowTopMenu } from '../components/WindowTopMenu'; import { getContainerId } from '../state/selectors'; @@ -14,9 +15,18 @@ const mapStateToProps = state => ({ containerId: getContainerId(state), }); +/** + * mapStateToProps - used to hook up connect to state + * @memberof WindowTopMenu + * @private + */ +const mapDispatchToProps = (dispatch, {}) => ({ + toggleDraggingEnabled: () => dispatch(actions.toggleDraggingEnabled()), +}); + const enhance = compose( withTranslation(), - connect(mapStateToProps, null), + connect(mapStateToProps, mapDispatchToProps), withPlugins('WindowTopMenu'), ); diff --git a/src/state/actions/action-types.js b/src/state/actions/action-types.js index 4f4de04963c24511f153bad0282893413c401116..9e4016521b650954294a56175ace65c88489aeb0 100644 --- a/src/state/actions/action-types.js +++ b/src/state/actions/action-types.js @@ -38,6 +38,7 @@ const ActionTypes = { SET_WINDOW_VIEW_TYPE: 'SET_WINDOW_VIEW_TYPE', SET_WORKSPACE_ADD_VISIBILITY: 'SET_WORKSPACE_ADD_VISIBILITY', TOGGLE_WINDOW_SIDE_BAR: 'TOGGLE_WINDOW_SIDE_BAR', + TOGGLE_DRAGGING: 'TOGGLE_DRAGGING', SET_WINDOW_SIDE_BAR_PANEL: 'SET_WINDOW_SIDE_BAR_PANEL', TOGGLE_ZOOM_CONTROLS: 'TOGGLE_ZOOM_CONTROLS', UPDATE_CONFIG: 'UPDATE_CONFIG', diff --git a/src/state/actions/window.js b/src/state/actions/window.js index ecbb0c0718bc97172ffeb4688e1eab242a913317..1fed95f5c7f2c193f385fda5418fee1fb9bdbc00 100644 --- a/src/state/actions/window.js +++ b/src/state/actions/window.js @@ -50,6 +50,7 @@ export function addWindow(options) { companionAreaOpen: true, companionWindowIds: [cwDefault, cwThumbs], displayAllAnnotations: config.displayAllAnnotations || false, + draggingEnabled: true, id: `window-${uuid()}`, layoutOrder: numWindows + 1, manifestId: null, diff --git a/src/state/actions/workspace.js b/src/state/actions/workspace.js index 783ab5bdb14f680e85b20fd7d75bcdb436e2dd3b..ff0f64b6d57c17cf4f1a11c728c6025f28663e4e 100644 --- a/src/state/actions/workspace.js +++ b/src/state/actions/workspace.js @@ -85,3 +85,12 @@ export function toggleWorkspaceExposeMode() { type: ActionTypes.TOGGLE_WORKSPACE_EXPOSE_MODE, }; } + +/** + * toggleDraggingEnabled - action creator + */ +export function toggleDraggingEnabled() { + return { + type: ActionTypes.TOGGLE_DRAGGING, + }; +} diff --git a/src/state/reducers/workspace.js b/src/state/reducers/workspace.js index 2cd43499c2a0984edb9e3089b600ab067de7725a..9951b1c45f5f25d1ced21de00465ae9fa44758f3 100644 --- a/src/state/reducers/workspace.js +++ b/src/state/reducers/workspace.js @@ -6,6 +6,7 @@ import ActionTypes from '../actions/action-types'; */ export const workspaceReducer = ( state = { // we'll need to abstract this more, methinks. + draggingEnabled: true, exposeModeOn: false, height: 5000, id: uuid(), @@ -58,6 +59,8 @@ export const workspaceReducer = ( return { ...state, exposeModeOn: !state.exposeModeOn }; case ActionTypes.IMPORT_MIRADOR_STATE: return action.state.workspace; + case ActionTypes.TOGGLE_DRAGGING: + return { ...state, draggingEnabled: !state.draggingEnabled }; default: return state; }