diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/getPolygonLatitudeCoordinates.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/getPolygonLatitudeCoordinates.ts index 5b3937831210f6b967a8bba559bf2a28ce0b2e10..bd9977393790b6d31539cb97a4f7b7b017c259a2 100644 --- a/src/components/Map/MapViewer/utils/config/overlaysLayer/getPolygonLatitudeCoordinates.ts +++ b/src/components/Map/MapViewer/utils/config/overlaysLayer/getPolygonLatitudeCoordinates.ts @@ -1,4 +1,4 @@ -import { roundToTwoDiggits } from '@/utils/number/roundToTwoDiggits'; +import { roundToTwoDigits } from '@/utils/number/roundToTwoDigits'; type GetLatitudeCoordinatesProps = { width: number; @@ -22,5 +22,5 @@ export const getPolygonLatitudeCoordinates = ({ const polygonWidth = width / nOverlays; const newXMin = xMin + polygonWidth * overlayIndexBasedOnOrder; const xMax = newXMin + polygonWidth; - return { xMin: roundToTwoDiggits(newXMin), xMax: roundToTwoDiggits(xMax) }; + return { xMin: roundToTwoDigits(newXMin), xMax: roundToTwoDigits(xMax) }; }; diff --git a/src/redux/overlayBioEntity/overlayBioEntity.thunk.ts b/src/redux/overlayBioEntity/overlayBioEntity.thunk.ts index 21aecf106db07d5bc44a4701f544dee1e5d490bf..2ba83189feb03c61dd36bb018a9519b485a81772 100644 --- a/src/redux/overlayBioEntity/overlayBioEntity.thunk.ts +++ b/src/redux/overlayBioEntity/overlayBioEntity.thunk.ts @@ -9,6 +9,8 @@ import { parseOverlayBioEntityToOlRenderingFormat } from './overlayBioEntity.uti import { apiPath } from '../apiPath'; import { modelsIdsSelector } from '../models/models.selectors'; import type { RootState } from '../store'; +import { setMapBackground } from '../map/map.slice'; +import { emptyBackgroundIdSelector } from '../backgrounds/background.selectors'; type GetOverlayBioEntityThunkProps = { overlayId: number; @@ -54,3 +56,19 @@ export const getOverlayBioEntityForAllModels = createAsyncThunk< await Promise.all(asyncGetOverlayBioEntityFunctions); }, ); + +type GetInitOverlaysProps = { overlaysId: number[] }; + +export const getInitOverlays = createAsyncThunk<void, GetInitOverlaysProps, { state: RootState }>( + 'appInit/getInitOverlays', + async ({ overlaysId }, { dispatch, getState }): Promise<void> => { + const state = getState(); + + const emptyBackgroundId = emptyBackgroundIdSelector(state); + if (emptyBackgroundId) { + dispatch(setMapBackground(emptyBackgroundId)); + } + + overlaysId.forEach(id => dispatch(getOverlayBioEntityForAllModels({ overlayId: id }))); + }, +); diff --git a/src/redux/overlayBioEntity/overlayBioEntity.utils.ts b/src/redux/overlayBioEntity/overlayBioEntity.utils.ts index ab187513315a37a4c613af29d5e5be40ab7ef72c..e632f31a4fd5cb75b966d33868cddf9f0acf1777 100644 --- a/src/redux/overlayBioEntity/overlayBioEntity.utils.ts +++ b/src/redux/overlayBioEntity/overlayBioEntity.utils.ts @@ -37,6 +37,13 @@ export type OverlayOrder = { index: number; }; +const byOrderOrId = (a: OverlayOrder, b: OverlayOrder): number => { + if (a.order === b.order) { + return a.id - b.id; + } + return a.order - b.order; +}; + /** function calculates order of the function based on "order" property in ovarlay data. */ export const calculateOvarlaysOrder = ( overlaysIdsAndOrder: OverlayIdAndOrder[], @@ -48,13 +55,7 @@ export const calculateOvarlaysOrder = ( index, })); - /** if two overlays have the same order, order is determined by id of the overlay */ - overlaysOrder.sort((a, b) => { - if (a.order === b.order) { - return a.id - b.id; - } - return a.order - b.order; - }); + overlaysOrder.sort(byOrderOrId); overlaysOrder.forEach((overlay, index) => { const updatedOverlay = { ...overlay }; diff --git a/src/redux/root/init.thunks.ts b/src/redux/root/init.thunks.ts index 4591391b0de75ecfe2cfa99bc66b98deec784987..32c086c98ac2b4275277347e8dad8d777921e2b4 100644 --- a/src/redux/root/init.thunks.ts +++ b/src/redux/root/init.thunks.ts @@ -18,6 +18,7 @@ import { getSearchData } from '../search/search.thunks'; import { setPerfectMatch } from '../search/search.slice'; import { getSessionValid } from '../user/user.thunks'; import { getConfigurationOptions } from '../configuration/configuration.thunks'; +import { getInitOverlays } from '../overlayBioEntity/overlayBioEntity.thunk'; interface InitializeAppParams { queryData: QueryData; @@ -28,7 +29,7 @@ export const fetchInitialAppData = createAsyncThunk< InitializeAppParams, { dispatch: AppDispatch } >('appInit/fetchInitialAppData', async ({ queryData }, { dispatch }): Promise<void> => { - /** Fetch all data required for renderin map */ + /** Fetch all data required for rendering map */ await Promise.all([ dispatch(getConfigurationOptions()), dispatch(getProjectById(PROJECT_ID)), @@ -59,4 +60,9 @@ export const fetchInitialAppData = createAsyncThunk< ); dispatch(openSearchDrawerWithSelectedTab(getDefaultSearchTab(queryData.searchValue))); } + + /** fetch overlays */ + if (queryData.overlaysId) { + dispatch(getInitOverlays({ overlaysId: queryData.overlaysId })); + } }); diff --git a/src/redux/root/query.selectors.ts b/src/redux/root/query.selectors.ts index 55929fcae655ffdf2eb0e668bf105286f508b39c..98660410716f25c5e3f663f7f22cd7073667ceee 100644 --- a/src/redux/root/query.selectors.ts +++ b/src/redux/root/query.selectors.ts @@ -1,17 +1,33 @@ import { QueryDataParams } from '@/types/query'; import { createSelector } from '@reduxjs/toolkit'; +import { ZERO } from '@/constants/common'; import { mapDataSelector } from '../map/map.selectors'; import { perfectMatchSelector, searchValueSelector } from '../search/search.selectors'; +import { activeOverlaysIdSelector } from '../overlayBioEntity/overlayBioEntity.selector'; export const queryDataParamsSelector = createSelector( searchValueSelector, perfectMatchSelector, mapDataSelector, - (searchValue, perfectMatch, { modelId, backgroundId, position }): QueryDataParams => ({ - searchValue: searchValue.join(';'), + activeOverlaysIdSelector, + ( + searchValue, perfectMatch, - modelId, - backgroundId, - ...position.last, - }), + { modelId, backgroundId, position }, + activeOverlaysId, + ): QueryDataParams => { + const queryDataParams: QueryDataParams = { + searchValue: searchValue.join(';'), + perfectMatch, + modelId, + backgroundId, + ...position.last, + }; + + if (activeOverlaysId.length > ZERO) { + queryDataParams.overlaysId = activeOverlaysId.join(','); + } + + return queryDataParams; + }, ); diff --git a/src/types/query.ts b/src/types/query.ts index a6696aa9ab6676ade0473673db26b60f8d2e9004..98309123aeea5a80626fca86870beb56c6561ec3 100644 --- a/src/types/query.ts +++ b/src/types/query.ts @@ -6,6 +6,7 @@ export interface QueryData { modelId?: number; backgroundId?: number; initialPosition?: Partial<Point>; + overlaysId?: number[]; } export interface QueryDataParams { @@ -16,6 +17,7 @@ export interface QueryDataParams { x?: number; y?: number; z?: number; + overlaysId?: string; } export interface QueryDataRouterParams { @@ -26,4 +28,5 @@ export interface QueryDataRouterParams { x?: string; y?: string; z?: string; + overlaysId?: string; } diff --git a/src/utils/number/roundToTwoDiggits.test.ts b/src/utils/number/roundToTwoDiggits.test.ts deleted file mode 100644 index e93ab76934dfdb76430e99ffdbaa5b1fbae2f33c..0000000000000000000000000000000000000000 --- a/src/utils/number/roundToTwoDiggits.test.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-disable no-magic-numbers */ -import { roundToTwoDiggits } from './roundToTwoDiggits'; - -describe('roundToTwoDiggits', () => { - it('should round a positive number with more than two decimal places to two decimal places', () => { - expect(roundToTwoDiggits(3.14159265359)).toBe(3.14); - expect(roundToTwoDiggits(2.71828182845)).toBe(2.72); - expect(roundToTwoDiggits(1.23456789)).toBe(1.23); - }); - - it('should round a negative number with more than two decimal places to two decimal places', () => { - expect(roundToTwoDiggits(-3.14159265359)).toBe(-3.14); - expect(roundToTwoDiggits(-2.71828182845)).toBe(-2.72); - expect(roundToTwoDiggits(-1.23456789)).toBe(-1.23); - }); - - it('should round a number with exactly two decimal places to two decimal places', () => { - expect(roundToTwoDiggits(3.14)).toBe(3.14); - expect(roundToTwoDiggits(2.72)).toBe(2.72); - expect(roundToTwoDiggits(1.23)).toBe(1.23); - }); - - it('should round a number with less than two decimal places to two decimal places', () => { - expect(roundToTwoDiggits(3)).toBe(3.0); - expect(roundToTwoDiggits(2.7)).toBe(2.7); - expect(roundToTwoDiggits(1.2)).toBe(1.2); - }); - - it('should round zero to two decimal places', () => { - expect(roundToTwoDiggits(0)).toBe(0); - }); -}); diff --git a/src/utils/number/roundToTwoDiggits.ts b/src/utils/number/roundToTwoDiggits.ts deleted file mode 100644 index c529f3d5c379f283768894ee9e316c67be0e305d..0000000000000000000000000000000000000000 --- a/src/utils/number/roundToTwoDiggits.ts +++ /dev/null @@ -1,2 +0,0 @@ -const TWO_DIGITS = 100; -export const roundToTwoDiggits = (x: number): number => Math.round(x * TWO_DIGITS) / TWO_DIGITS; diff --git a/src/utils/number/roundToTwoDigits.test.ts b/src/utils/number/roundToTwoDigits.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..68fa6ecf4bf54cab52b4ad816f7effa2007d65e3 --- /dev/null +++ b/src/utils/number/roundToTwoDigits.test.ts @@ -0,0 +1,32 @@ +/* eslint-disable no-magic-numbers */ +import { roundToTwoDigits } from './roundToTwoDigits'; + +describe('roundToTwoDiggits', () => { + it('should round a positive number with more than two decimal places to two decimal places', () => { + expect(roundToTwoDigits(3.14159265359)).toBe(3.14); + expect(roundToTwoDigits(2.71828182845)).toBe(2.72); + expect(roundToTwoDigits(1.23456789)).toBe(1.23); + }); + + it('should round a negative number with more than two decimal places to two decimal places', () => { + expect(roundToTwoDigits(-3.14159265359)).toBe(-3.14); + expect(roundToTwoDigits(-2.71828182845)).toBe(-2.72); + expect(roundToTwoDigits(-1.23456789)).toBe(-1.23); + }); + + it('should round a number with exactly two decimal places to two decimal places', () => { + expect(roundToTwoDigits(3.14)).toBe(3.14); + expect(roundToTwoDigits(2.72)).toBe(2.72); + expect(roundToTwoDigits(1.23)).toBe(1.23); + }); + + it('should round a number with less than two decimal places to two decimal places', () => { + expect(roundToTwoDigits(3)).toBe(3.0); + expect(roundToTwoDigits(2.7)).toBe(2.7); + expect(roundToTwoDigits(1.2)).toBe(1.2); + }); + + it('should round zero to two decimal places', () => { + expect(roundToTwoDigits(0)).toBe(0); + }); +}); diff --git a/src/utils/number/roundToTwoDigits.ts b/src/utils/number/roundToTwoDigits.ts new file mode 100644 index 0000000000000000000000000000000000000000..0a3aa52d831800ce44c6efd5746f05b96dfdcca6 --- /dev/null +++ b/src/utils/number/roundToTwoDigits.ts @@ -0,0 +1,2 @@ +const TWO_DIGITS = 100; +export const roundToTwoDigits = (x: number): number => Math.round(x * TWO_DIGITS) / TWO_DIGITS; diff --git a/src/utils/parseQueryToTypes.test.ts b/src/utils/parseQueryToTypes.test.ts index 83d991077b5544c69fac4e36f0f423a6129e0a41..113111d7d64cb750ec6724bbaa1ff477718bc97b 100644 --- a/src/utils/parseQueryToTypes.test.ts +++ b/src/utils/parseQueryToTypes.test.ts @@ -10,6 +10,7 @@ describe('parseQueryToTypes', () => { modelId: undefined, backgroundId: undefined, initialPosition: { x: undefined, y: undefined, z: undefined }, + overlaysId: undefined, }); expect(parseQueryToTypes({ perfectMatch: 'true' })).toEqual({ @@ -18,6 +19,7 @@ describe('parseQueryToTypes', () => { modelId: undefined, backgroundId: undefined, initialPosition: { x: undefined, y: undefined, z: undefined }, + overlaysId: undefined, }); expect(parseQueryToTypes({ perfectMatch: 'false' })).toEqual({ @@ -26,6 +28,7 @@ describe('parseQueryToTypes', () => { modelId: undefined, backgroundId: undefined, initialPosition: { x: undefined, y: undefined, z: undefined }, + overlaysId: undefined, }); expect(parseQueryToTypes({ modelId: '666' })).toEqual({ @@ -34,6 +37,7 @@ describe('parseQueryToTypes', () => { modelId: 666, backgroundId: undefined, initialPosition: { x: undefined, y: undefined, z: undefined }, + overlaysId: undefined, }); expect(parseQueryToTypes({ x: '2137' })).toEqual({ searchValue: undefined, @@ -41,6 +45,7 @@ describe('parseQueryToTypes', () => { modelId: undefined, backgroundId: undefined, initialPosition: { x: 2137, y: undefined, z: undefined }, + overlaysId: undefined, }); expect(parseQueryToTypes({ y: '1372' })).toEqual({ searchValue: undefined, @@ -48,6 +53,7 @@ describe('parseQueryToTypes', () => { modelId: undefined, backgroundId: undefined, initialPosition: { x: undefined, y: 1372, z: undefined }, + overlaysId: undefined, }); expect(parseQueryToTypes({ z: '3721' })).toEqual({ searchValue: undefined, @@ -55,6 +61,16 @@ describe('parseQueryToTypes', () => { modelId: undefined, backgroundId: undefined, initialPosition: { x: undefined, y: undefined, z: 3721 }, + overlaysId: undefined, + }); + expect(parseQueryToTypes({ overlaysId: '1,2,3' })).toEqual({ + searchValue: undefined, + perfectMatch: false, + modelId: undefined, + backgroundId: undefined, + initialPosition: { x: undefined, y: undefined, z: undefined }, + // eslint-disable-next-line no-magic-numbers + overlaysId: [1, 2, 3], }); }); }); diff --git a/src/utils/parseQueryToTypes.ts b/src/utils/parseQueryToTypes.ts index 9dc659c0eaada11d7dae247f577a4a7df87f6d00..ee7440375a4834e13cf217b9af5fd714889ec56b 100644 --- a/src/utils/parseQueryToTypes.ts +++ b/src/utils/parseQueryToTypes.ts @@ -10,4 +10,5 @@ export const parseQueryToTypes = (query: QueryDataRouterParams): QueryData => ({ y: Number(query.y) || undefined, z: Number(query.z) || undefined, }, + overlaysId: query.overlaysId?.split(',').map(Number), });