diff --git a/__tests__/src/actions/workspace.test.js b/__tests__/src/actions/workspace.test.js index 5f430096a1d0c3daf2baad8fa41da608b1a886ce..d20bc614439432f04892cae4ff205992772edc85 100644 --- a/__tests__/src/actions/workspace.test.js +++ b/__tests__/src/actions/workspace.test.js @@ -49,6 +49,23 @@ describe('workspace actions', () => { expect(actions.setWorkspaceAddVisibility(true)).toEqual(expectedAction); }); }); + describe('setWorkspaceViewportDimensions', () => { + it('should set the workspace add visibility', () => { + const expectedAction = { + type: ActionTypes.SET_WORKSPACE_VIEWPORT_POSITION, + payload: { + position: { + width: 20, + height: 25, + }, + }, + }; + expect(actions.setWorkspaceViewportDimensions({ + width: 20, + height: 25, + })).toEqual(expectedAction); + }); + }); describe('setWorkspaceViewportPosition', () => { it('should set the workspace add visibility', () => { const expectedAction = { diff --git a/__tests__/src/components/WorkspaceElastic.test.js b/__tests__/src/components/WorkspaceElastic.test.js index cba74aa1bac583a2c259cbd82686ff3624a35394..fde419fca641deaca49479e14bddc1ff13c47eca 100644 --- a/__tests__/src/components/WorkspaceElastic.test.js +++ b/__tests__/src/components/WorkspaceElastic.test.js @@ -1,6 +1,7 @@ import React from 'react'; import { shallow } from 'enzyme'; import { Rnd } from 'react-rnd'; +import ResizeObserver from 'react-resize-observer'; import WorkspaceElastic from '../../../src/components/WorkspaceElastic'; /** create wrapper */ @@ -17,6 +18,7 @@ function createWrapper(props) { y: 20, }, }} + setWorkspaceViewportDimensions={() => {}} setWorkspaceViewportPosition={() => {}} setWindowSize={() => {}} updateWindowPosition={() => {}} @@ -143,5 +145,26 @@ describe('WorkspaceElastic', () => { y: -2700, }); }); + + it('when workspace itself is resized', () => { + const mockResize = jest.fn(); + wrapper = createWrapper({ + windows, + setWorkspaceViewportDimensions: mockResize, + }); + + wrapper + .find(ResizeObserver) + .at(0) + .props() + .onResize({ + width: 500, + height: 500, + }); + expect(mockResize).toHaveBeenCalledWith({ + width: 500, + height: 500, + }); + }); }); }); diff --git a/__tests__/src/reducers/workspace.test.js b/__tests__/src/reducers/workspace.test.js index e4d40d59434a5b6ff1f413f91f4979a5382ac2b1..14ffd01f524eb2dc67aa9aa3b75c49204c447392 100644 --- a/__tests__/src/reducers/workspace.test.js +++ b/__tests__/src/reducers/workspace.test.js @@ -60,12 +60,16 @@ describe('workspace reducer', () => { position: { x: 50, y: 50, + width: 50, + height: 50, }, }, })).toEqual({ viewportPosition: { x: 50, y: 50, + width: 50, + height: 50, }, }); }); diff --git a/package.json b/package.json index 9d8d741a6dbb7738525566873554ad5b57e5884c..aaee48b36a160973221642dcc61970bd433f5d01 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "react-mosaic-component": "^2.1.0", "react-placeholder": "^3.0.1", "react-redux": "^6.0.0", + "react-resize-observer": "^1.1.1", "react-rnd": "^9.1.1", "react-virtualized": "^9.21.0", "redux": "4.0.1", diff --git a/src/components/WorkspaceElastic.js b/src/components/WorkspaceElastic.js index a151532180745da42f01d7755ef2a0a95e112dc6..412d848d7520c6450f32e49c6ddd89bc4c72855e 100644 --- a/src/components/WorkspaceElastic.js +++ b/src/components/WorkspaceElastic.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Rnd } from 'react-rnd'; +import ResizeObserver from 'react-resize-observer'; import Window from '../containers/Window'; import ns from '../config/css-ns'; @@ -16,6 +17,7 @@ class WorkspaceElastic extends React.Component { const { workspace, windows, + setWorkspaceViewportDimensions, setWorkspaceViewportPosition, updateWindowPosition, setWindowSize, @@ -27,6 +29,10 @@ class WorkspaceElastic extends React.Component { return ( <div style={{ position: 'relative', width: '100%', height: '100%' }}> + <ResizeObserver + onResize={(rect) => { setWorkspaceViewportDimensions(rect); }} + /> + <Rnd default={{ width: workspace.width, @@ -88,6 +94,7 @@ class WorkspaceElastic extends React.Component { WorkspaceElastic.propTypes = { setWorkspaceViewportPosition: PropTypes.func.isRequired, + setWorkspaceViewportDimensions: PropTypes.func.isRequired, windows: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types workspace: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types updateWindowPosition: PropTypes.func.isRequired, diff --git a/src/containers/WorkspaceElastic.js b/src/containers/WorkspaceElastic.js index 8c0b8d714bb1d69c700178fd79aefac3612b1288..78e66ad737f88b6df07b4e2b0ce3c2d1d06c71f3 100644 --- a/src/containers/WorkspaceElastic.js +++ b/src/containers/WorkspaceElastic.js @@ -15,13 +15,17 @@ const mapStateToProps = state => ( } ); - /** * mapDispatchToProps - used to hook up connect to action creators * @memberof Workspace * @private */ const mapDispatchToProps = (dispatch, props) => ({ + setWorkspaceViewportDimensions: (position) => { + dispatch( + actions.setWorkspaceViewportDimensions(position), + ); + }, setWorkspaceViewportPosition: (position) => { dispatch( actions.setWorkspaceViewportPosition(position), diff --git a/src/state/actions/workspace.js b/src/state/actions/workspace.js index 6da0e4898d127da4000cf334164bc1f670a71f1d..a75bfe5b5d38c6f0ff90d783b6edcd4618e29f6b 100644 --- a/src/state/actions/workspace.js +++ b/src/state/actions/workspace.js @@ -45,18 +45,35 @@ export function setWorkspaceAddVisibility(isWorkspaceAddVisible) { * @param {Object} position * @memberof ActionCreators */ -export function setWorkspaceViewportPosition(position) { +export function setWorkspaceViewportPosition({ x, y }) { return { type: ActionTypes.SET_WORKSPACE_VIEWPORT_POSITION, payload: { position: { - x: position.x, - y: position.y, + x, + y, }, }, }; } +/** + * setWorkspaceViewportDimensions - action creator + * + * @param {Object} position + * @memberof ActionCreators + */ +export function setWorkspaceViewportDimensions({ width, height }) { + return { + type: ActionTypes.SET_WORKSPACE_VIEWPORT_POSITION, + payload: { + position: { + width, + height, + }, + }, + }; +} /** * toggleWorkspaceExposeMode - action creator * diff --git a/src/state/reducers/workspace.js b/src/state/reducers/workspace.js index d9606abd8ca7821bd860aac9262b73f0fc0566a8..ae1939f1abec215001ecfcbe108479d04f7f6c10 100644 --- a/src/state/reducers/workspace.js +++ b/src/state/reducers/workspace.js @@ -34,7 +34,13 @@ export const workspaceReducer = ( case ActionTypes.SET_WORKSPACE_ADD_VISIBILITY: return { ...state, isWorkspaceAddVisible: action.isWorkspaceAddVisible }; case ActionTypes.SET_WORKSPACE_VIEWPORT_POSITION: - return { ...state, viewportPosition: action.payload.position }; + return { + ...state, + viewportPosition: { + ...state.viewportPosition, + ...action.payload.position, + }, + }; case ActionTypes.TOGGLE_WORKSPACE_EXPOSE_MODE: return { ...state, exposeModeOn: !state.exposeModeOn }; default: