Skip to content
Snippets Groups Projects
Commit c3e8b48e authored by mateusz-winiarczyk's avatar mateusz-winiarczyk
Browse files

feat(plugins): data overlays (MIN-222)

parent b61872e4
No related branches found
No related tags found
2 merge requests!223reset the pin numbers before search results are fetch (so the results will be...,!152feat(plugins): data overlays (MIN-222)
Showing
with 366 additions and 1 deletion
import { isOverlayActiveSelector } from '@/redux/overlayBioEntity/overlayBioEntity.selector';
import { removeOverlayBioEntityForGivenOverlay } from '@/redux/overlayBioEntity/overlayBioEntity.slice';
import { overlaySelector, userOverlaySelector } from '@/redux/overlays/overlays.selectors';
import { store } from '@/redux/store';
import { PluginsEventBus } from '../../pluginsEventBus';
import { ERROR_OVERLAY_ID_NOT_ACTIVE, ERROR_OVERLAY_ID_NOT_FOUND } from '../../errorMessages';
export const hideDataOverlay = (overlayId: number): void => {
const { dispatch, getState } = store;
const state = getState();
const isOverlayActive = isOverlayActiveSelector(state, overlayId);
const overlay = overlaySelector(state, overlayId);
const userOverlay = userOverlaySelector(state, overlayId);
const matchingOverlay = overlay || userOverlay;
if (!matchingOverlay) throw new Error(ERROR_OVERLAY_ID_NOT_FOUND);
if (!isOverlayActive) {
throw new Error(ERROR_OVERLAY_ID_NOT_ACTIVE);
}
dispatch(removeOverlayBioEntityForGivenOverlay({ overlayId }));
PluginsEventBus.dispatchEvent('onHideOverlay', matchingOverlay);
};
/* eslint-disable no-magic-numbers */
import { RootState, store } from '@/redux/store';
import { OVERLAYS_INITIAL_STATE_MOCK } from '@/redux/overlays/overlays.mock';
import { overlaysFixture } from '@/models/fixtures/overlaysFixture';
import { DEFAULT_ERROR } from '@/constants/errors';
import { removeOverlay } from '@/redux/overlays/overlays.thunks';
import { removeDataOverlay } from './removeDataOverlay';
import { ERROR_OVERLAY_ID_NOT_FOUND } from '../../errorMessages';
jest.mock('../../../../redux/store');
jest.mock('../../../../redux/overlays/overlays.thunks');
const MOCK_STATE = {
overlays: {
...OVERLAYS_INITIAL_STATE_MOCK,
userOverlays: {
data: overlaysFixture,
loading: 'idle',
error: DEFAULT_ERROR,
},
},
};
describe('removeDataOverlay', () => {
afterEach(() => {
jest.clearAllMocks();
});
const getStateSpy = jest.spyOn(store, 'getState');
it('should throw error if matching overlay not found', () => {
const overlayId = 991;
getStateSpy.mockImplementation(() => MOCK_STATE as RootState);
expect(() => removeDataOverlay(overlayId)).toThrow(ERROR_OVERLAY_ID_NOT_FOUND);
});
it('should dispatch removeOverlay with correct overlayId if matching overlay is found', () => {
getStateSpy.mockImplementation(() => MOCK_STATE as RootState);
const overlayId = overlaysFixture[0].idObject;
removeDataOverlay(overlayId);
expect(removeOverlay).toHaveBeenCalledWith({ overlayId });
});
});
import { overlaySelector, userOverlaySelector } from '@/redux/overlays/overlays.selectors';
import { removeOverlay } from '@/redux/overlays/overlays.thunks';
import { store } from '@/redux/store';
import { ERROR_OVERLAY_ID_NOT_FOUND } from '../../errorMessages';
export const removeDataOverlay = (overlayId: number): void => {
const { dispatch, getState } = store;
const state = getState();
const overlay = overlaySelector(state, overlayId);
const userOverlay = userOverlaySelector(state, overlayId);
const matchingOverlayId = overlay || userOverlay;
if (!matchingOverlayId) throw new Error(ERROR_OVERLAY_ID_NOT_FOUND);
dispatch(removeOverlay({ overlayId }));
};
export { showDataOverlay } from './showDataOverlay';
import {
BACKGROUNDS_MOCK,
BACKGROUND_INITIAL_STATE_MOCK,
} from '@/redux/backgrounds/background.mock';
import { initialMapStateFixture } from '@/redux/map/map.fixtures';
import { RootState, store } from '@/redux/store';
import { setBackgroundtoEmptyIfAvailable } from './setBackgroundtoEmptyIfAvailable';
const DEFAULT_BACKGROUND_ID = 0;
const EMPTY_BACKGROUND_ID = 15;
describe('setEmptyBackground', () => {
beforeEach(() => {
jest.clearAllMocks();
});
const getStateSpy = jest.spyOn(store, 'getState');
const dispatchSpy = jest.spyOn(store, 'dispatch');
it('should not set background to empty if its not available', () => {
getStateSpy.mockImplementation(
() =>
({
map: initialMapStateFixture,
backgrounds: BACKGROUND_INITIAL_STATE_MOCK,
}) as RootState,
);
expect(store.getState().map.data.backgroundId).toBe(DEFAULT_BACKGROUND_ID);
setBackgroundtoEmptyIfAvailable();
expect(dispatchSpy).not.toHaveBeenCalled();
});
it('should set background to empty if its available', () => {
getStateSpy.mockImplementation(
() =>
({
map: initialMapStateFixture,
backgrounds: { ...BACKGROUND_INITIAL_STATE_MOCK, data: BACKGROUNDS_MOCK },
}) as RootState,
);
expect(store.getState().map.data.backgroundId).toBe(DEFAULT_BACKGROUND_ID);
setBackgroundtoEmptyIfAvailable();
expect(dispatchSpy).toHaveBeenCalledWith({
payload: EMPTY_BACKGROUND_ID,
type: 'map/setMapBackground',
});
});
});
import { emptyBackgroundIdSelector } from '@/redux/backgrounds/background.selectors';
import { setMapBackground } from '@/redux/map/map.slice';
import { store } from '@/redux/store';
export const setBackgroundtoEmptyIfAvailable = (): void => {
const { dispatch, getState } = store;
const emptyBackgroundId = emptyBackgroundIdSelector(getState());
if (emptyBackgroundId) {
dispatch(setMapBackground(emptyBackgroundId));
}
};
/* eslint-disable no-magic-numbers */
import { RootState, store } from '@/redux/store';
import { overlaysFixture } from '@/models/fixtures/overlaysFixture';
import { DEFAULT_ERROR } from '@/constants/errors';
import { OVERLAYS_INITIAL_STATE_MOCK } from '@/redux/overlays/overlays.mock';
import { OVERLAY_BIO_ENTITY_INITIAL_STATE_MOCK } from '@/redux/overlayBioEntity/overlayBioEntity.mock';
import {
ERROR_OVERLAY_ID_ALREADY_ACTIVE,
ERROR_OVERLAY_ID_NOT_FOUND,
} from '@/services/pluginsManager/errorMessages';
import { getOverlayBioEntityForAllModels } from '@/redux/overlayBioEntity/overlayBioEntity.thunk';
import { PluginsEventBus } from '@/services/pluginsManager/pluginsEventBus';
import { showDataOverlay } from './showDataOverlay';
import { setBackgroundtoEmptyIfAvailable } from './setBackgroundtoEmptyIfAvailable';
jest.mock('../../../../../redux/overlayBioEntity/overlayBioEntity.thunk');
jest.mock('../../../../../redux/store');
jest.mock('./setBackgroundtoEmptyIfAvailable');
const OVERLAY_ID = overlaysFixture[0].idObject;
describe('showDataOverlay function', () => {
afterEach(() => {
jest.clearAllMocks(); // Clear mocks after each test
});
const getStateSpy = jest.spyOn(store, 'getState');
it('should throw error if overlay is already active', () => {
getStateSpy.mockImplementation(
() =>
({
overlays: {
...OVERLAYS_INITIAL_STATE_MOCK,
userOverlays: {
data: overlaysFixture,
loading: 'idle',
error: DEFAULT_ERROR,
},
},
overlayBioEntity: { ...OVERLAY_BIO_ENTITY_INITIAL_STATE_MOCK, overlaysId: [OVERLAY_ID] },
}) as RootState,
);
expect(() => showDataOverlay(OVERLAY_ID)).toThrow(ERROR_OVERLAY_ID_ALREADY_ACTIVE);
});
it('should throw error if matching overlay is not found', () => {
getStateSpy.mockImplementation(
() =>
({
overlays: {
...OVERLAYS_INITIAL_STATE_MOCK,
userOverlays: {
data: overlaysFixture,
loading: 'idle',
error: DEFAULT_ERROR,
},
},
overlayBioEntity: { ...OVERLAY_BIO_ENTITY_INITIAL_STATE_MOCK, overlaysId: [OVERLAY_ID] },
}) as RootState,
);
expect(() => showDataOverlay(991)).toThrow(ERROR_OVERLAY_ID_NOT_FOUND);
});
it('should dispatch overlay id to show', () => {
getStateSpy.mockImplementation(
() =>
({
overlays: {
...OVERLAYS_INITIAL_STATE_MOCK,
userOverlays: {
data: overlaysFixture,
loading: 'idle',
error: DEFAULT_ERROR,
},
},
overlayBioEntity: { ...OVERLAY_BIO_ENTITY_INITIAL_STATE_MOCK },
}) as RootState,
);
showDataOverlay(OVERLAY_ID);
expect(getOverlayBioEntityForAllModels).toHaveBeenCalledWith({ overlayId: OVERLAY_ID });
});
it('should dispatch plugin event with overlay to show', () => {
const pluginDispatchEvent = jest.spyOn(PluginsEventBus, 'dispatchEvent');
getStateSpy.mockImplementation(
() =>
({
overlays: {
...OVERLAYS_INITIAL_STATE_MOCK,
userOverlays: {
data: overlaysFixture,
loading: 'idle',
error: DEFAULT_ERROR,
},
},
overlayBioEntity: { ...OVERLAY_BIO_ENTITY_INITIAL_STATE_MOCK },
}) as RootState,
);
showDataOverlay(OVERLAY_ID);
expect(pluginDispatchEvent).toHaveBeenCalledWith('onShowOverlay', overlaysFixture[0]);
});
it('should not set empty background when it show overlay', () => {
getStateSpy.mockImplementation(
() =>
({
overlays: {
...OVERLAYS_INITIAL_STATE_MOCK,
userOverlays: {
data: overlaysFixture,
loading: 'idle',
error: DEFAULT_ERROR,
},
},
overlayBioEntity: { ...OVERLAY_BIO_ENTITY_INITIAL_STATE_MOCK },
}) as RootState,
);
showDataOverlay(OVERLAY_ID);
expect(setBackgroundtoEmptyIfAvailable).not.toHaveBeenCalled();
});
it('should set empty background when it show overlay if setBackgroundEmpty is true', () => {
getStateSpy.mockImplementation(
() =>
({
overlays: {
...OVERLAYS_INITIAL_STATE_MOCK,
userOverlays: {
data: overlaysFixture,
loading: 'idle',
error: DEFAULT_ERROR,
},
},
overlayBioEntity: { ...OVERLAY_BIO_ENTITY_INITIAL_STATE_MOCK },
}) as RootState,
);
showDataOverlay(OVERLAY_ID, true);
expect(setBackgroundtoEmptyIfAvailable).toHaveBeenCalled();
});
});
import { store } from '@/redux/store';
import { getOverlayBioEntityForAllModels } from '@/redux/overlayBioEntity/overlayBioEntity.thunk';
import { isOverlayActiveSelector } from '@/redux/overlayBioEntity/overlayBioEntity.selector';
import { overlaySelector, userOverlaySelector } from '@/redux/overlays/overlays.selectors';
import { PluginsEventBus } from '@/services/pluginsManager/pluginsEventBus';
import {
ERROR_OVERLAY_ID_ALREADY_ACTIVE,
ERROR_OVERLAY_ID_NOT_FOUND,
} from '@/services/pluginsManager/errorMessages';
import { setBackgroundtoEmptyIfAvailable } from './setBackgroundtoEmptyIfAvailable';
export const showDataOverlay = (overlayId: number, setBackgroundEmpty?: boolean): void => {
const { dispatch, getState } = store;
const state = getState();
const isOverlayActive = isOverlayActiveSelector(state, overlayId);
const overlay = overlaySelector(state, overlayId);
const userOverlay = userOverlaySelector(state, overlayId);
const matchingOverlay = overlay || userOverlay;
if (!matchingOverlay) throw new Error(ERROR_OVERLAY_ID_NOT_FOUND);
if (isOverlayActive) {
throw new Error(ERROR_OVERLAY_ID_ALREADY_ACTIVE);
}
if (setBackgroundEmpty) {
setBackgroundtoEmptyIfAvailable();
}
dispatch(getOverlayBioEntityForAllModels({ overlayId }));
PluginsEventBus.dispatchEvent('onShowOverlay', matchingOverlay);
};
......@@ -18,12 +18,18 @@ import { showOverviewImageModal } from './overviewImage/showOverviewImageModal';
import { PluginsEventBus } from './pluginsEventBus';
import type { PluginsManagerType } from './pluginsManager.types';
import { configurationMapper } from './pluginsManager.utils';
import { getDataOverlays } from './map/overlays/getDataOverlays';
import { getVisibleDataOverlays } from './map/overlays/getVisibleDataOverlays';
import { showDataOverlay } from './map/overlays/showDataOverlay';
import { hideDataOverlay } from './map/overlays/hideDataOverlay';
import { removeDataOverlay } from './map/overlays/removeDataOverlay';
import { addDataOverlay } from './map/overlays/addDataOverlay';
import { getApiUrls } from './project/data/getApiUrls';
import { getDisease } from './project/data/getDisease';
import { getName } from './project/data/getName';
import { getOrganism } from './project/data/getOrganism';
import { getProjectId } from './project/data/getProjectId';
import { getVersion } from './project/data/getVersion';
import { getBounds } from './map/data/getBounds';
import { fitBounds } from './map/fitBounds';
import { getOpenMapId } from './map/getOpenMapId';
......@@ -66,6 +72,16 @@ export const PluginsManager: PluginsManagerType = {
selectOverviewImage,
showOverviewImageModal,
},
overlays: {
data: {
getDataOverlays,
getVisibleDataOverlays,
},
showDataOverlay,
hideDataOverlay,
removeDataOverlay,
addDataOverlay,
},
project: {
data: {
getProjectId,
......@@ -73,6 +89,7 @@ export const PluginsManager: PluginsManagerType = {
getVersion,
getDisease,
getOrganism,
getApiUrls,
},
},
};
......
import { BASE_API_URL, BASE_NEW_API_URL } from '@/constants';
type ApiUrls = {
baseApiUrl: string;
baseNewApiUrl: string;
};
export const getApiUrls = (): ApiUrls => ({
baseApiUrl: BASE_API_URL,
baseNewApiUrl: BASE_NEW_API_URL,
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment