Skip to content

Commit

Permalink
#4675: Add dynamic import of map libraries in base map component (#6245)
Browse files Browse the repository at this point in the history
  • Loading branch information
allyoucanmap committed Nov 26, 2020
1 parent ac91678 commit f4b08c4
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 58 deletions.
4 changes: 3 additions & 1 deletion web/client/components/geostory/media/Map.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ export default compose(
size,
showCaption,
caption: contentCaption,
mapType = "leaflet" // default for when map MediaViewer is not connected to redux
mapType = "leaflet", // default for when map MediaViewer is not connected to redux
onMapTypeLoaded
}) => {

const { layers = [], mapOptions = {}, description, ...m} = (map.data ? map.data : map);
Expand Down Expand Up @@ -107,6 +108,7 @@ export default compose(
tools={isMapInfoControlActive ? ["popup"] : []}
options={applyDefaults(updatedMapOptions)}
mapType={mapType}
onMapTypeLoaded={onMapTypeLoaded}
/>
{expandable && !editMap &&
<Button
Expand Down
55 changes: 32 additions & 23 deletions web/client/components/geostory/media/__tests__/Map-test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,30 @@ describe('Map component', () => {
ReactDOM.render(<Provider store={mockStore}><Map /></Provider>, document.getElementById("container"));
const container = document.getElementById('container');
const mediaMapNode = container.querySelector('.ms-media-map');
expect(mediaMapNode).toExist();
expect(mediaMapNode).toBeTruthy();
});
it('should show buttons to expand map', () => {
it('should show buttons to expand map', (done) => {
const mockStore = { subscribe: () => {}, getState: () => ({}) };
ReactDOM.render(<Provider store={mockStore}><Map expandable /></Provider>, document.getElementById("container"));
const container = document.getElementById('container');
const mediaMapNode = container.querySelector('.ms-media-map');
expect(mediaMapNode).toExist();
expect(mediaMapNode.children.length).toBe(2);
expect(document.body.children.length).toBe(1);
const expandMediaButtonNode = mediaMapNode.querySelector('.ms-expand-media-button');
expect(expandMediaButtonNode).toExist();
ReactTestUtils.Simulate.click(expandMediaButtonNode);
expect(mediaMapNode.children.length).toBe(0);
expect(document.body.children.length).toBe(2);
expect(document.body.children[1].getAttribute('class')).toBe('ms-expanded-media-container');
ReactDOM.render(<Provider store={mockStore}>
<Map expandable
onMapTypeLoaded={() => {
const container = document.getElementById('container');
const mediaMapNode = container.querySelector('.ms-media-map');
expect(mediaMapNode).toBeTruthy();
expect(mediaMapNode.children.length).toBe(2);
expect(document.body.children.length).toBe(1);
const expandMediaButtonNode = mediaMapNode.querySelector('.ms-expand-media-button');
expect(expandMediaButtonNode).toBeTruthy();
ReactTestUtils.Simulate.click(expandMediaButtonNode);
expect(mediaMapNode.children.length).toBe(0);
expect(document.body.children.length).toBe(2);
expect(document.body.children[1].getAttribute('class')).toBe('ms-expanded-media-container');
done();
}}
/>
</Provider>, document.getElementById("container"));
});
it('should use cursor pointer with active map info control', () => {
it('should use cursor pointer with active map info control', (done) => {
const MAP = {
layers: [],
mapInfoControl: true
Expand All @@ -55,14 +61,17 @@ describe('Map component', () => {
<Map
id="map"
mapType="openlayers"
map={MAP} />,
map={MAP}
onMapTypeLoaded={() => {
const container = document.getElementById('container');
const mediaMapNode = container.querySelector('.ms-media-map');
expect(mediaMapNode).toBeTruthy();
const mapContainer = container.querySelector('#media-map');
expect(mapContainer).toBeTruthy();
expect(mapContainer.style.cursor).toBe('pointer');
done();
}}
/>,
document.getElementById("container"));

const container = document.getElementById('container');
const mediaMapNode = container.querySelector('.ms-media-map');
expect(mediaMapNode).toExist();
const mapContainer = container.querySelector('#media-map');
expect(mapContainer).toExist();
expect(mapContainer.style.cursor).toBe('pointer');
});
});
3 changes: 2 additions & 1 deletion web/client/components/map/BaseMap.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class BaseMap extends React.Component {
const {plugins} = this.props;
const {Map} = plugins;
const projection = this.props.map && this.props.map.projection || "EPSG:3857";
if (this.props.map) {
if (this.props.map && Map) {
return (
<Map
projectionDefs={this.props.projectionDefs}
Expand All @@ -151,6 +151,7 @@ class BaseMap extends React.Component {
>
{this.renderLayers()}
{this.renderTools()}
{this.props.children}
</Map>
);
}
Expand Down
22 changes: 14 additions & 8 deletions web/client/components/map/__tests__/BaseMap-test-chrome.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,20 @@ describe('BaseMap', () => {
document.body.innerHTML = '';
setTimeout(done);
});
it('test cesium map', () => {
const map = ReactDOM.render(<TestMap mapType="cesium" id="myMap" layers={SAMPLE_LAYERS_1} />, document.getElementById("container"));
expect(map).toExist();
const el = ReactDOM.findDOMNode(map);
expect(el).toExist();
expect(el.id).toBe("myMap");
expect(el.querySelector('canvas')).toExist();

it('test cesium map', (done) => {
const map = ReactDOM.render(<TestMap
mapType="cesium"
id="myMap"
layers={SAMPLE_LAYERS_1}
onMapTypeLoaded={() => {
expect(map).toBeTruthy();
const el = ReactDOM.findDOMNode(map);
expect(el).toBeTruthy();
expect(el.id).toBe("myMap");
expect(el.querySelector('canvas')).toBeTruthy();
done();
}}
/>, document.getElementById("container"));
});

});
60 changes: 45 additions & 15 deletions web/client/components/map/__tests__/BaseMap-test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,21 +132,51 @@ describe('BaseMap', () => {
document.body.innerHTML = '';
setTimeout(done);
});
it('test openlayers map', () => {
const map = ReactDOM.render(<TestMap mapType="openlayers" id="myMap" layers={SAMPLE_LAYERS_1} />, document.getElementById("container"));
expect(map).toExist();
const el = ReactDOM.findDOMNode(map);
expect(el).toExist();
expect(el.id).toBe("myMap");
expect(el.querySelector('canvas')).toExist();

it('test openlayers map', (done) => {
const map = ReactDOM.render(<TestMap
mapType="openlayers"
id="myMap" layers={SAMPLE_LAYERS_1}
onMapTypeLoaded={() => {
expect(map).toBeTruthy();
const el = ReactDOM.findDOMNode(map);
expect(el).toBeTruthy();
expect(el.id).toBe("myMap");
expect(el.querySelector('canvas')).toBeTruthy();
done();
}}
/>, document.getElementById("container"));
});
it('test leaflet map', (done) => {
const map = ReactDOM.render(<TestMap
mapType="leaflet"
id="myMap"
layers={SAMPLE_LAYERS_1}
onMapTypeLoaded={() => {
expect(map).toBeTruthy();
const el = ReactDOM.findDOMNode(map);
expect(el).toBeTruthy();
expect(el.id).toBe("myMap");
expect(el.querySelector('div')).toBeTruthy();
done();
}}
/>, document.getElementById("container"));
});
it('test leaflet map', () => {
const map = ReactDOM.render(<TestMap mapType="leaflet" id="myMap" layers={SAMPLE_LAYERS_1} />, document.getElementById("container"));
expect(map).toExist();
const el = ReactDOM.findDOMNode(map);
expect(el).toExist();
expect(el.id).toBe("myMap");
expect(el.querySelector('div')).toExist();
it('should allow children as tools', (done) => {
function MapTool({ map }) {
return map ? <div id="map-tool"></div> : null;
}
ReactDOM.render(
<TestMap
mapType="leaflet"
id="myMap"
layers={SAMPLE_LAYERS_1}
onMapTypeLoaded={() => {
const mapToolNode = document.querySelector('#map-tool');
expect(mapToolNode).toBeTruthy();
done();
}}
>
<MapTool />
</TestMap>, document.getElementById("container"));
});
});
66 changes: 59 additions & 7 deletions web/client/components/map/enhancers/mapType.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { withPropsOnChange } from 'recompose';

/*
* Copyright 2018, GeoSolutions Sas.
Expand All @@ -8,10 +7,63 @@ import { withPropsOnChange } from 'recompose';
* LICENSE file in the root directory of this source tree.
*/

import React from 'react';
import PropTypes from 'prop-types';

export default withPropsOnChange(
['mapType', 'plugins'],
({mapType, plugins} = {}) => ({
plugins: {...require('../plugins/' + mapType + '.js').default(), ...plugins}
})
);
function mapType(Component) {
class WithMapType extends React.Component {

static propTypes = {
mapType: PropTypes.string,
onMapTypeLoaded: PropTypes.func
};

static defaultProps = {
onMapTypeLoaded: () => {}
};

state = {
plugins: {}
};

componentDidMount() {
this.setPlugins(this.props);
this._isMounted = true;
}

componentWillUpdate(newProps) {
if (newProps.mapType !== this.props.mapType) {
this.setPlugins(newProps);
}
}

componentWillUnmount() {
this._isMounted = false;
}

render() {
const { plugins } = this.state;
return <Component {...this.props} plugins={plugins}/>;
}

setPlugins(props) {
if (props.mapType) {
import(/* webpackChunkName: 'map-library-[request]' */ '../plugins/' + props.mapType + '.js')
.then((mod) => {
if (this._isMounted) {
this.setState({
plugins: mod.default()
});
this.props.onMapTypeLoaded();
}
});
}
}
}

WithMapType.displayName = `${Component.displayName}WithMapType`;

return WithMapType;
}

export default mapType;
5 changes: 2 additions & 3 deletions web/client/components/widgets/widget/MapView.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import { compose } from 'recompose';

import BaseMap from '../../map/BaseMap';
/*
* Copyright 2018, GeoSolutions Sas.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
import { compose } from 'recompose';
import autoMapType from '../../map/enhancers/autoMapType';
import autoResize from '../../map/enhancers/autoResize';
import getProjectionDefs from '../../map/enhancers/getProjectionDefs';
import { handlingUnsupportedProjection } from '../../map/enhancers/handlingUnsupportedProjection';
import mapType from '../../map/enhancers/mapType';
import onMapViewChanges from '../../map/enhancers/onMapViewChanges';
import BaseMap from '../../map/BaseMap';

export default compose(
onMapViewChanges,
Expand Down

0 comments on commit f4b08c4

Please sign in to comment.