diff --git a/__tests__/src/components/WorkspaceMosaic.test.js b/__tests__/src/components/WorkspaceMosaic.test.js index 944d48cd381052fb0c0aa457ec1beaff2750954d..ea11f83901d10ba4db813e654cca6530561cacfd 100644 --- a/__tests__/src/components/WorkspaceMosaic.test.js +++ b/__tests__/src/components/WorkspaceMosaic.test.js @@ -26,6 +26,16 @@ describe('WorkspaceMosaic', () => { <Mosaic initialValue={{ direction: 'row', first: '1', second: '2' }} />, )).toBe(true); }); + describe('componentDidUpdate', () => { + it('updates the workspace layout when windows change', () => { + const updateWorkspaceMosaicLayout = jest.fn(); + wrapper = createWrapper({ windows, updateWorkspaceMosaicLayout }); + + wrapper.setProps({ windows: { ...windows, 3: { id: 3 } } }); + + expect(updateWorkspaceMosaicLayout).toHaveBeenCalled(); + }); + }); describe('determineWorkspaceLayout', () => { it('when window ids do not match workspace layout', () => { wrapper = createWrapper({ windows, workspace: { layout: 'foo' } }); diff --git a/src/components/WorkspaceMosaic.js b/src/components/WorkspaceMosaic.js index 25417adea04374d6a9152fd1eb52f228601ace51..15006a5ee7a9e5fba0dad6250fc1176c9ec63ff8 100644 --- a/src/components/WorkspaceMosaic.js +++ b/src/components/WorkspaceMosaic.js @@ -23,6 +23,44 @@ class WorkspaceMosaic extends React.Component { this.zeroStateView = <div />; } + /** */ + componentDidMount() { + const { updateWorkspaceMosaicLayout } = this.props; + + const newLayout = this.determineWorkspaceLayout(); + if (newLayout) updateWorkspaceMosaicLayout(newLayout); + } + + /** */ + componentDidUpdate(prevProps) { + const { windows, workspace, updateWorkspaceMosaicLayout } = this.props; + if (prevProps.windows !== windows || prevProps.workspace !== workspace) { + const newLayout = this.determineWorkspaceLayout(); + if (newLayout) updateWorkspaceMosaicLayout(newLayout); + } + } + + /** + * Used to determine whether or not a "new" layout should be autogenerated. + * If a Window is added or removed, generate that new layout and use that for + * this render. When the Mosaic changes, that will trigger a new store update. + */ + determineWorkspaceLayout() { + const { windows, workspace } = this.props; + const windowKeys = Object.keys(windows).sort(); + const leaveKeys = getLeaves(workspace.layout); + // Check every window is in the layout, and all layout windows are present + // in store + if (!windowKeys.every(e => leaveKeys.includes(e)) + || !leaveKeys.every(e => windowKeys.includes(e))) { + const newLayout = createBalancedTreeFromLeaves(windowKeys); + + return newLayout; + } + + return null; + } + /** * Render a tile (Window) in the Mosaic. */ @@ -46,35 +84,14 @@ class WorkspaceMosaic extends React.Component { updateWorkspaceMosaicLayout(newLayout); } - /** - * Used to determine whether or not a "new" layout should be autogenerated. - * If a Window is added or removed, generate that new layout and use that for - * this render. When the Mosaic changes, that will trigger a new store update. - */ - determineWorkspaceLayout() { - const { windows, workspace, updateWorkspaceMosaicLayout } = this.props; - const windowKeys = Object.keys(windows).sort(); - const leaveKeys = getLeaves(workspace.layout); - // Check every window is in the layout, and all layout windows are present - // in store - if (!windowKeys.every(e => leaveKeys.includes(e)) - || !leaveKeys.every(e => windowKeys.includes(e))) { - const newLayout = createBalancedTreeFromLeaves(windowKeys); - updateWorkspaceMosaicLayout(newLayout); - return newLayout; - } - return null; - } - /** */ render() { const { workspace } = this.props; - const newLayout = this.determineWorkspaceLayout(); return ( <Mosaic renderTile={this.tileRenderer} - initialValue={newLayout || workspace.layout} + initialValue={workspace.layout || this.determineWorkspaceLayout()} onChange={this.mosaicChange} className="mirador-mosaic" zeroStateView={this.zeroStateView}