Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 2023.02.xx] #9702: Fix - Background selector in contexts won't retain thumbnail in view mode (#9720) #9744

Merged
merged 1 commit into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 80 additions & 2 deletions web/client/epics/__tests__/config-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import expect from 'expect';
import {head} from 'lodash';
import {loadMapConfigAndConfigureMap, loadMapInfoEpic, storeDetailsInfoEpic} from '../config';
import {loadMapConfigAndConfigureMap, loadMapInfoEpic, storeDetailsInfoEpic, backgroundsListInitEpic} from '../config';
import {LOAD_USER_SESSION} from '../../actions/usersession';
import {
loadMapConfig,
Expand All @@ -18,7 +18,8 @@ import {
MAP_INFO_LOADED,
MAP_INFO_LOAD_START,
loadMapInfo,
mapInfoLoaded
mapInfoLoaded,
configureMap
} from '../../actions/config';

import { TEST_TIMEOUT, addTimeoutEpic, testEpic } from './epicTestUtils';
Expand Down Expand Up @@ -379,5 +380,82 @@ describe('config epics', () => {
}});
});
});
describe("backgroundsListInitEpic", () => {
const base64 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII";
it('test layer update with thumbnail on background init', (done) => {
testEpic(addTimeoutEpic(backgroundsListInitEpic), 3, configureMap({
map: {
backgrounds: [{id: "1", thumbnail: base64}],
layers: [{id: "1", group: "background", name: "layer_1", visibility: true}]
}
}), actions => {
expect(actions.length).toBe(3);
actions.map((action) => {
switch (action.type) {
case "CHANGE_LAYER_PROPERTIES":
expect(action.newProperties.thumbURL).toBeTruthy();
expect(action.layer).toBe("1");
break;
case "BACKGROUND_SELECTOR:CREATE_BACKGROUNDS_LIST":
expect(action.backgrounds.length).toBe(1);
expect(action.backgrounds[0].id).toBe("1");
expect(action.backgrounds[0].thumbnail).toBe(base64);
break;
case "BACKGROUND_SELECTOR:SET_CURRENT_BACKGROUND_LAYER":
expect(action.layerId).toBe("1");
break;
default:
expect(true).toBe(false);
}
});
done();
});
});
it('test layer update with thumbnail with layer not visible', (done) => {
testEpic(addTimeoutEpic(backgroundsListInitEpic), 2, configureMap({
map: {
backgrounds: [{id: "1", thumbnail: base64}],
layers: [{id: "1", group: "background", name: "layer_1", visibility: false}]
}
}), actions => {
expect(actions.length).toBe(2);
actions.map((action) => {
switch (action.type) {
case "CHANGE_LAYER_PROPERTIES":
expect(action.newProperties.thumbURL).toBeTruthy();
expect(action.layer).toBe("1");
break;
case "BACKGROUND_SELECTOR:CREATE_BACKGROUNDS_LIST":
expect(action.backgrounds.length).toBe(1);
expect(action.backgrounds[0].id).toBe("1");
expect(action.backgrounds[0].thumbnail).toBe(base64);
break;
default:
expect(true).toBe(false);
}
});
done();
}, {});
});
it('test backgroundsListInitEpic with no background layer', (done) => {
testEpic(addTimeoutEpic(backgroundsListInitEpic), 1, configureMap({
map: {
layers: [{id: "1", name: "layer_1", visibility: false}]
}
}), actions => {
expect(actions.length).toBe(1);
actions.map((action) => {
switch (action.type) {
case "BACKGROUND_SELECTOR:CREATE_BACKGROUNDS_LIST":
expect(action.backgrounds.length).toBe(0);
break;
default:
expect(true).toBe(false);
}
});
done();
}, {});
});
});
});

26 changes: 0 additions & 26 deletions web/client/epics/backgroundselector.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
BACKGROUND_EDITED,
REMOVE_BACKGROUND,
SYNC_CURRENT_BACKGROUND_LAYER,
createBackgroundsList,
clearModalParameters,
setBackgroundModalParams,
setCurrentBackgroundLayer,
Expand All @@ -27,7 +26,6 @@ import {
} from '../actions/backgroundselector';

import { setControlProperty } from '../actions/controls';
import { MAP_CONFIG_LOADED } from '../actions/config';
import { changeSelectedService } from '../actions/catalog';
import {ADD_LAYER, changeLayerProperties, removeNode} from '../actions/layers';
import { getLayerFromId, currentBackgroundSelector } from '../selectors/layers';
Expand Down Expand Up @@ -58,29 +56,6 @@ const addBackgroundPropertiesEpic = (action$) =>
: defaultAction;
});

const backgroundsListInit = (action$) =>
action$.ofType(MAP_CONFIG_LOADED)
.switchMap(({config}) => {
const backgrounds = config.map && config.map.backgrounds || [];
const backgroundLayers = (config.map && config.map.layers || []).filter(layer => layer.group === 'background');
const layerUpdateActions = backgrounds.filter(background => !!background.thumbnail).map(background => {
const toBlob = (data) => {
const bytes = atob(data.split(',')[1]);
const mimeType = data.split(',')[0].split(':')[1].split(';')[0];
let buffer = new ArrayBuffer(bytes.length);
let byteArray = new Uint8Array(buffer);
for (let i = 0; i < bytes.length; ++i) {
byteArray[i] = bytes.charCodeAt(i);
}
return URL.createObjectURL(new Blob([buffer], {type: mimeType}));
};
return changeLayerProperties(background.id, {thumbURL: toBlob(background.thumbnail)});
});
const currentBackground = head(backgroundLayers.filter(layer => layer.visibility));
return Rx.Observable.of(...layerUpdateActions.concat(createBackgroundsList(backgrounds)),
...(currentBackground ? [setCurrentBackgroundLayer(currentBackground.id)] : []));
});

const setCurrentBackgroundLayerEpic = (action$, store) =>
action$.ofType(SET_CURRENT_BACKGROUND_LAYER)
.switchMap(({layerId}) => {
Expand Down Expand Up @@ -151,7 +126,6 @@ const syncSelectedBackgroundEpic = (action$) =>
export default {
accessMetadataExplorer,
addBackgroundPropertiesEpic,
backgroundsListInit,
setCurrentBackgroundLayerEpic,
backgroundAddedEpic,
backgroundEditedEpic,
Expand Down
38 changes: 37 additions & 1 deletion web/client/epics/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/
import { Observable } from 'rxjs';
import axios from '../libs/ajax';
import { get, merge, isNaN, find } from 'lodash';
import { get, merge, isNaN, find, head } from 'lodash';
import {
LOAD_NEW_MAP,
LOAD_MAP_CONFIG,
Expand All @@ -32,6 +32,8 @@ import { detailsLoaded, openDetailsPanel } from '../actions/details';
import {userSessionEnabledSelector, buildSessionName} from "../selectors/usersession";
import {getRequestParameterValue} from "../utils/QueryParamsUtils";
import { EMPTY_RESOURCE_VALUE } from '../utils/MapInfoUtils';
import { changeLayerProperties } from '../actions/layers';
import { createBackgroundsList, setCurrentBackgroundLayer } from '../actions/backgroundselector';

const prepareMapConfiguration = (data, override, state) => {
const queryParamsMap = getRequestParameterValue('map', state);
Expand Down Expand Up @@ -212,3 +214,37 @@ export const storeDetailsInfoEpic = (action$, store) =>
);
});
});
/**
* Intercept MAP_CONFIG_LOADED and update background layers thumbnail
* Epic is placed here to better intercept and update background layers thumbnail info,
* when loading context with map and to avoid race condition
* when loading plugins and map configuration
* @memberof epics.config
* @param {Observable} action$ stream of actions
* @param {object} store redux store
* @return {external:Observable}
*/
export const backgroundsListInitEpic = (action$) =>
action$.ofType(MAP_CONFIG_LOADED)
.switchMap(({config}) => {
const backgrounds = config.map && config.map.backgrounds || [];
const backgroundLayers = (config.map && config.map.layers || []).filter(layer => layer.group === 'background');
const layerUpdateActions = backgrounds.filter(background => !!background.thumbnail).map(background => {
const toBlob = (data) => {
const bytes = atob(data.split(',')[1]);
const mimeType = data.split(',')[0].split(':')[1].split(';')[0];
let buffer = new ArrayBuffer(bytes.length);
let byteArray = new Uint8Array(buffer);
for (let i = 0; i < bytes.length; ++i) {
byteArray[i] = bytes.charCodeAt(i);
}
return URL.createObjectURL(new Blob([buffer], {type: mimeType}));
};
return changeLayerProperties(background.id, {thumbURL: toBlob(background.thumbnail)});
});
const currentBackground = head(backgroundLayers.filter(layer => layer.visibility));
return Observable.of(
...layerUpdateActions.concat(createBackgroundsList(backgrounds)),
...(currentBackground ? [setCurrentBackgroundLayer(currentBackground.id)] : [])
);
});
Loading