diff --git a/web/client/components/geostory/common/enhancers/__tests__/map-test.jsx b/web/client/components/geostory/common/enhancers/__tests__/map-test.jsx index 58d39e69ef..39f574cb03 100644 --- a/web/client/components/geostory/common/enhancers/__tests__/map-test.jsx +++ b/web/client/components/geostory/common/enhancers/__tests__/map-test.jsx @@ -62,6 +62,39 @@ describe("geostory media map component enhancers", () => { })); ReactDOM.render(, document.getElementById("container")); }); + it('withMapEnhancer generate correct props for geostory with layers array includes empty items', (done) => { + const resources = [{id: "1", type: "map", data: {id: "2", layers: [ + { + name: "layer01", center: {x: 1, y: 1, crs: 'EPSG:4326'}, zoom: 1 + }, { + name: "layer02", center: {x: 2, y: 2, crs: 'EPSG:4326'}, zoom: 2 + }, { + name: "layer03", center: {x: 3, y: 3, crs: 'EPSG:4326'}, zoom: 3 + }, { name: "layer04", center: {x: 4, y: 4, crs: 'EPSG:4326'}, zoom: 4, "visibility": true}], groups: [], context: "1"}}]; + const store = { + subscribe: () => {}, getState: () => ({geostory: {currentStory: {resources}}}) + }; + const resourceId = "1"; + const Sink = withMapEnhancer(createSink( props => { + expect(props).toBeTruthy(); + expect(props.map).toBeTruthy(); + expect(props.map).toEqual({id: "2", layers: [ { + name: "layer01", center: {x: 1, y: 1, crs: 'EPSG:4326'}, zoom: 1 + }, { + name: "layer02", center: {x: 2, y: 2, crs: 'EPSG:4326'}, zoom: 2 + }, { + name: "layer03", center: {x: 3, y: 3, crs: 'EPSG:4326'}, zoom: 3 + }, { name: "layer04", center: {x: 4, y: 4, crs: 'EPSG:4326'}, zoom: 4, "visibility": false + }], groups: [], context: "1"}); + done(); + })); + let layersWithEmptyItems = []; + layersWithEmptyItems.length = 3; + layersWithEmptyItems.push({visibility: false}); + ReactDOM.render(, document.getElementById("container")); + }); it('withLocalMapState generate correct props', (done) => { const Sink = withLocalMapState(createSink( props => { expect(props).toExist(); diff --git a/web/client/components/geostory/common/enhancers/map.jsx b/web/client/components/geostory/common/enhancers/map.jsx index 4b332d0dd0..ebab6f7984 100644 --- a/web/client/components/geostory/common/enhancers/map.jsx +++ b/web/client/components/geostory/common/enhancers/map.jsx @@ -40,8 +40,11 @@ export default compose( const resource = find(resources, { id: resourceId }) || {}; const baseMap = omit(resource.data, ['context']); const isLegacyGeostory = (map?.layers || [])?.indexOf(null) !== -1 || (map?.groups || [])?.indexOf(null) !== -1; + // 'layersGroupsHasEmptyItems' is a flag that indicates if the geostory 'map' object in section includes empty layers/groups + // the layers/groups array may include empty items in case change layer properties e.g: opacity,title ...etc + const layersGroupsHasEmptyItems = (map?.layers || []).includes(undefined) || (map?.groups || []).includes(undefined); const cleanedMap = {...map, layers: (map.layers || baseMap?.layers || []).map(lay => lay ? lay : undefined), groups: (map.groups || baseMap?.groups || []).map(gr => gr ? gr : undefined)}; // for better initiating cleanedMap layers in case 'map.layers = undefined' -> baseMap.layers check is added in fallBack - return { map: createMapObject(baseMap, cleanedMap, isLegacyGeostory)}; + return { map: createMapObject(baseMap, cleanedMap, isLegacyGeostory, layersGroupsHasEmptyItems)}; } )); /** diff --git a/web/client/utils/GeoStoryUtils.js b/web/client/utils/GeoStoryUtils.js index 01a0f3b999..a29dde4e7f 100644 --- a/web/client/utils/GeoStoryUtils.js +++ b/web/client/utils/GeoStoryUtils.js @@ -172,11 +172,12 @@ export const applyDefaults = (options = {}) => merge({}, DEFAULT_MAP_OPTIONS, op * @param {object} baseMap initial map object * @param {object} overrides object to override with * @param {bool} isLegacyGeostory boolean that indicates if the geostory is legacy one or new + * @param {bool} layersGroupsHasEmptyItems boolean that indicates if the geostory map object in section includes empty layers/groups * @return {object} options merged with defaults */ -export const createMapObject = (baseMap = {}, overrides = {}, isLegacyGeostory = false) => { +export const createMapObject = (baseMap = {}, overrides = {}, isLegacyGeostory = false, layersGroupsHasEmptyItems = false) => { const mergedMap = merge({}, baseMap, overrides); - if (isLegacyGeostory) { + if (isLegacyGeostory || layersGroupsHasEmptyItems) { return mergedMap; } return { diff --git a/web/client/utils/__tests__/GeoStoryUtils-test.js b/web/client/utils/__tests__/GeoStoryUtils-test.js index c1c3fcf569..1c950f7a6c 100644 --- a/web/client/utils/__tests__/GeoStoryUtils-test.js +++ b/web/client/utils/__tests__/GeoStoryUtils-test.js @@ -364,7 +364,7 @@ describe("GeoStory Utils", () => { }); expect(res).toEqual(merged); }); - it('test override layers in createMapObject', () => { + it('test override layers in createMapObject with empty layers array', () => { // initial baseMap layer is empty array const merged1 = { zoomControl: true, @@ -398,8 +398,9 @@ describe("GeoStory Utils", () => { }] }); expect(res1).toEqual(merged1); - // initial baseMap layer not empty array - const merged2 = { + }); + it('test override layers in createMapObject with normal layers array', () => { + const merged = { zoomControl: true, mapInfoControl: false, mapOptions: { @@ -417,7 +418,7 @@ describe("GeoStory Utils", () => { }], groups: [] }; - const res2 = createMapObject({...DEFAULT_MAP_OPTIONS, layers: [{ + const res = createMapObject({...DEFAULT_MAP_OPTIONS, layers: [{ name: "layer01", center: {x: 1, y: 1, crs: 'EPSG:4326'}, zoom: 1 }]}, { mapOptions: { @@ -432,9 +433,11 @@ describe("GeoStory Utils", () => { name: "layer02", center: {x: 2, y: 2, crs: 'EPSG:4326'}, zoom: 2 }] }); - expect(res2).toEqual(merged2); + expect(res).toEqual(merged); + }); + it('test override layers in createMapObject for legacy geostory', () => { // legacy geostory - const merged3 = { + const merged = { zoomControl: true, mapInfoControl: false, mapOptions: { @@ -456,7 +459,7 @@ describe("GeoStory Utils", () => { expanded: true }] }; - const res3 = createMapObject({...DEFAULT_MAP_OPTIONS, layers: [{ + const res = createMapObject({...DEFAULT_MAP_OPTIONS, layers: [{ "visibility": true }, { "visibility": false @@ -482,7 +485,53 @@ describe("GeoStory Utils", () => { expanded: true }] }, true); - expect(res3).toEqual(merged3); + expect(res).toEqual(merged); + }); + it('test override layers in createMapObject with layers array includes empty items ', () => { + let layersWithEmptyItems = []; + layersWithEmptyItems.length = 3; + layersWithEmptyItems.push({visibility: false}); + const merged = { + zoomControl: true, + mapInfoControl: false, + mapOptions: { + scrollWheelZoom: false, + interactions: { + mouseWheelZoom: false, + mouseClick: false, + dragPan: true + } + }, + layers: [{ + name: "layer01", center: {x: 1, y: 1, crs: 'EPSG:4326'}, zoom: 1 + }, { + name: "layer02", center: {x: 2, y: 2, crs: 'EPSG:4326'}, zoom: 2 + }, { + name: "layer03", center: {x: 3, y: 3, crs: 'EPSG:4326'}, zoom: 3 + }, { + name: "layer04", center: {x: 4, y: 4, crs: 'EPSG:4326'}, zoom: 4, visibility: false + }], + groups: [] + }; + const res = createMapObject({...DEFAULT_MAP_OPTIONS, layers: [{ + name: "layer01", center: {x: 1, y: 1, crs: 'EPSG:4326'}, zoom: 1 + }, { + name: "layer02", center: {x: 2, y: 2, crs: 'EPSG:4326'}, zoom: 2 + }, { + name: "layer03", center: {x: 3, y: 3, crs: 'EPSG:4326'}, zoom: 3 + }, { + name: "layer04", center: {x: 4, y: 4, crs: 'EPSG:4326'}, zoom: 4, visibility: true + }], groups: []}, { + mapOptions: { + scrollWheelZoom: false, + interactions: { + mouseClick: false + } + }, + layers: layersWithEmptyItems, + groups: [] + }, false, true); + expect(res).toEqual(merged); }); it('test testRegex', () => { const title = "title";