diff --git a/src/components/FunctionalArea/FunctionalArea.component.tsx b/src/components/FunctionalArea/FunctionalArea.component.tsx index 784d7fdeb3f64fa5ee1e14e942fb3a556f558054..d38bcd195aa44fcd1c7f18c3dd0c2f43dc912797 100644 --- a/src/components/FunctionalArea/FunctionalArea.component.tsx +++ b/src/components/FunctionalArea/FunctionalArea.component.tsx @@ -1,6 +1,6 @@ -import { TopBar } from '@/components/FunctionalArea/TopBar'; -import { NavBar } from '@/components/FunctionalArea/NavBar'; import { MapNavigation } from '@/components/FunctionalArea/MapNavigation'; +import { NavBar } from '@/components/FunctionalArea/NavBar'; +import { TopBar } from '@/components/FunctionalArea/TopBar'; export const FunctionalArea = (): JSX.Element => ( <> diff --git a/src/components/Map/MapViewer/utils/config/getMapTileUrl.test.ts b/src/components/Map/MapViewer/utils/config/getMapTileUrl.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..91d8919adcef11d7f6b19d9291487a7eac13315d --- /dev/null +++ b/src/components/Map/MapViewer/utils/config/getMapTileUrl.test.ts @@ -0,0 +1,34 @@ +import { BASE_MAP_IMAGES_URL } from '@/constants'; +import { getMapTileUrl } from './getMapTileUrl'; + +describe('getMapTileUrl - util', () => { + describe('when projectDirectory is empty', () => { + it('should return empty value', () => { + const projectDirectory = undefined; + const currentBackgroundImagePath = 'currentBackgroundImagePath'; + const result = ''; + + expect( + getMapTileUrl({ + projectDirectory, + currentBackgroundImagePath, + }), + ).toBe(result); + }); + }); + + describe('when all args are valid', () => { + it('should return correct value', () => { + const projectDirectory = 'directory'; + const currentBackgroundImagePath = 'currentBackgroundImagePath'; + const result = `${BASE_MAP_IMAGES_URL}/map_images/${projectDirectory}/${currentBackgroundImagePath}/{z}/{x}/{y}.PNG`; + + expect( + getMapTileUrl({ + projectDirectory, + currentBackgroundImagePath, + }), + ).toBe(result); + }); + }); +}); diff --git a/src/components/Map/MapViewer/utils/useOlMapInit.test.ts b/src/components/Map/MapViewer/utils/useOlMapInit.test.ts deleted file mode 100644 index 100eaaee71d7afc9ab80ffdd5f711ac10d306e38..0000000000000000000000000000000000000000 --- a/src/components/Map/MapViewer/utils/useOlMapInit.test.ts +++ /dev/null @@ -1,9 +0,0 @@ -describe.skip('useOlMapConfig - util', () => { - // TODO: tests - // everything is mocked in the file, so we need to firstly wait for module API connection - - it('noop', () => { - // eslint-disable-next-line no-magic-numbers - expect(1).toEqual(1); - }); -}); diff --git a/src/components/SPA/MinervaSPA.component.tsx b/src/components/SPA/MinervaSPA.component.tsx index 6703ea8ca8f905c08c1bfe80ee9097bbf1cead97..856e3487b746b504123995ebdf46329736f81787 100644 --- a/src/components/SPA/MinervaSPA.component.tsx +++ b/src/components/SPA/MinervaSPA.component.tsx @@ -1,15 +1,8 @@ import { FunctionalArea } from '@/components/FunctionalArea'; import { Map } from '@/components/Map'; -import { PROJECT_ID } from '@/constants'; -import { useAppDispatch } from '@/redux/hooks/useAppDispatch'; -import { initMapData } from '@/redux/map/map.thunks'; -import { getProjectById } from '@/redux/project/project.thunks'; -import { initDataLoadingInitialized } from '@/redux/root/init.selectors'; -import { AppDispatch } from '@/redux/store'; import { Manrope } from '@next/font/google'; -import { useEffect } from 'react'; -import { useSelector } from 'react-redux'; import { twMerge } from 'tailwind-merge'; +import { useInitializeStore } from './utils/useInitializeStore'; const manrope = Manrope({ variable: '--font-manrope', @@ -18,25 +11,8 @@ const manrope = Manrope({ subsets: ['latin'], }); -/* prettier-ignore */ -const getInitStoreData = - () => - (dispatch: AppDispatch): void => { - dispatch(getProjectById(PROJECT_ID)); - dispatch(initMapData()); - }; - export const MinervaSPA = (): JSX.Element => { - const dispatch = useAppDispatch(); - const storeInitialized = useSelector(initDataLoadingInitialized); - - useEffect(() => { - if (storeInitialized) { - return; - } - - dispatch(getInitStoreData()); - }, [dispatch, storeInitialized]); + useInitializeStore(); return ( <div className={twMerge('relative', manrope.variable)}> diff --git a/src/components/SPA/utils/useInitializeStore.test.ts b/src/components/SPA/utils/useInitializeStore.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..d1b7da08d0e98f26cc0fc4403efc1c333dfa877b --- /dev/null +++ b/src/components/SPA/utils/useInitializeStore.test.ts @@ -0,0 +1,85 @@ +import { PROJECT_ID } from '@/constants'; +import { backgroundsFixture } from '@/models/fixtures/backgroundsFixture'; +import { modelsFixture } from '@/models/fixtures/modelsFixture'; +import { overlaysFixture } from '@/models/fixtures/overlaysFixture'; +import { projectFixture } from '@/models/fixtures/projectFixture'; +import { apiPath } from '@/redux/apiPath'; +import { backgroundsDataSelector } from '@/redux/backgrounds/background.selectors'; +import { modelsDataSelector } from '@/redux/models/models.selectors'; +import { overlaysDataSelector } from '@/redux/overlays/overlays.selectors'; +import { projectDataSelector } from '@/redux/project/project.selectors'; +import { initDataLoadingInitialized } from '@/redux/root/init.selectors'; +import { mockNetworkResponse } from '@/utils/mockNetworkResponse'; +import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore'; +import { renderHook, waitFor } from '@testing-library/react'; +import { HttpStatusCode } from 'axios'; +import * as hook from './useInitializeStore'; + +const mockedAxiosClient = mockNetworkResponse(); + +describe('useInitializeStore - hook', () => { + describe('when fired', () => { + beforeAll(() => { + mockedAxiosClient.onGet(apiPath.getModelsString()).reply(HttpStatusCode.Ok, modelsFixture); + mockedAxiosClient + .onGet(apiPath.getAllOverlaysByProjectIdQuery(PROJECT_ID, { publicOverlay: true })) + .reply(HttpStatusCode.Ok, overlaysFixture); + mockedAxiosClient + .onGet(apiPath.getProjectById(PROJECT_ID)) + .reply(HttpStatusCode.Ok, projectFixture); + mockedAxiosClient + .onGet(apiPath.getAllBackgroundsByProjectIdQuery(PROJECT_ID)) + .reply(HttpStatusCode.Ok, backgroundsFixture); + }); + + it('should fetch project data in store', async () => { + const { Wrapper, store } = getReduxWrapperWithStore(); + renderHook(() => hook.useInitializeStore(), { wrapper: Wrapper }); + + await waitFor(() => { + const data = projectDataSelector(store.getState()); + expect(data).toEqual(projectFixture); + }); + }); + + it('should fetch backgrounds data in store', async () => { + const { Wrapper, store } = getReduxWrapperWithStore(); + renderHook(() => hook.useInitializeStore(), { wrapper: Wrapper }); + + await waitFor(() => { + const data = backgroundsDataSelector(store.getState()); + expect(data).toEqual(backgroundsFixture); + }); + }); + + it('should fetch overlays data in store', async () => { + const { Wrapper, store } = getReduxWrapperWithStore(); + renderHook(() => hook.useInitializeStore(), { wrapper: Wrapper }); + + await waitFor(() => { + const data = overlaysDataSelector(store.getState()); + expect(data).toEqual(overlaysFixture); + }); + }); + + it('should fetch models data in store', async () => { + const { Wrapper, store } = getReduxWrapperWithStore(); + renderHook(() => hook.useInitializeStore(), { wrapper: Wrapper }); + + await waitFor(() => { + const data = modelsDataSelector(store.getState()); + expect(data).toEqual(modelsFixture); + }); + }); + + it('should use valid initialize value', () => { + const { Wrapper, store } = getReduxWrapperWithStore(); + const initializedeBefore = initDataLoadingInitialized(store.getState()); + renderHook(() => hook.useInitializeStore(), { wrapper: Wrapper }); + const initializedAfter = initDataLoadingInitialized(store.getState()); + + expect(initializedeBefore).toBe(false); + expect(initializedAfter).toBe(true); + }); + }); +}); diff --git a/src/components/SPA/utils/useInitializeStore.ts b/src/components/SPA/utils/useInitializeStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..7e2fb0af61681ddf2f73cefa1571580fd8b36022 --- /dev/null +++ b/src/components/SPA/utils/useInitializeStore.ts @@ -0,0 +1,29 @@ +import { PROJECT_ID } from '@/constants'; +import { useAppDispatch } from '@/redux/hooks/useAppDispatch'; +import { initMapData } from '@/redux/map/map.thunks'; +import { getProjectById } from '@/redux/project/project.thunks'; +import { initDataLoadingInitialized } from '@/redux/root/init.selectors'; +import { AppDispatch } from '@/redux/store'; +import { useEffect } from 'react'; +import { useSelector } from 'react-redux'; + +/* prettier-ignore */ +export const getInitStoreData = + () => + (dispatch: AppDispatch): void => { + dispatch(getProjectById(PROJECT_ID)); + dispatch(initMapData()); + }; + +export const useInitializeStore = (): void => { + const dispatch = useAppDispatch(); + const isInitialized = useSelector(initDataLoadingInitialized); + + useEffect(() => { + if (isInitialized) { + return; + } + + dispatch(getInitStoreData()); + }, [dispatch, isInitialized]); +}; diff --git a/src/models/fixtures/modelsFixture.ts b/src/models/fixtures/modelsFixture.ts index 2eb9109dbac56042aafff5dd0a25a49f61be2c64..91bc15d71cd0b9d631fe2ceb68aa3f09ee9e557d 100644 --- a/src/models/fixtures/modelsFixture.ts +++ b/src/models/fixtures/modelsFixture.ts @@ -8,3 +8,8 @@ export const modelsFixture = createFixture(z.array(mapModelSchema), { seed: ZOD_SEED, array: { min: 3, max: 3 }, }); + +export const singleModelFixture = createFixture(mapModelSchema, { + seed: ZOD_SEED, + array: { min: 3, max: 3 }, +}); diff --git a/src/redux/map/map.constants.ts b/src/redux/map/map.constants.ts index a6307772f6c81239b02d58d839c0e050112fa761..ba88a03811be7e0e0d08fe58bb13ceaff6f51d65 100644 --- a/src/redux/map/map.constants.ts +++ b/src/redux/map/map.constants.ts @@ -26,3 +26,5 @@ export const MAP_DATA_INITIAL_STATE: MapData = { maxZoom: DEFAULT_MAX_ZOOM, }, }; + +export const MIDDLEWARE_ALLOWED_ACTIONS: string[] = ['map/setMapData', 'map/initMapData']; diff --git a/src/redux/map/map.middleware.ts b/src/redux/map/map.middleware.ts deleted file mode 100644 index dc1e99e775bee72d6b753c185b152a02e9d4ec8c..0000000000000000000000000000000000000000 --- a/src/redux/map/map.middleware.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { MapModel } from '@/types/models'; -import { getUpdatedMapData } from '@/utils/getUpdatedMapData'; -import { Middleware, MiddlewareAPI, PayloadAction } from '@reduxjs/toolkit'; -import { modelsDataSelector } from '../models/models.selectors'; -import type { AppDispatch, RootState } from '../store'; -import { setMapData } from './map.slice'; -import { InitMapDataActionPayload, SetMapDataActionPayload } from './map.types'; - -type AllowedAction = PayloadAction<SetMapDataActionPayload | InitMapDataActionPayload>; - -const ALLOWED_ACTIONS = ['map/setMapData', 'map/initMapData']; - -const checkIfIsActionValid = (action: AllowedAction, state: RootState): boolean => { - const isAllowedAction = ALLOWED_ACTIONS.some(allowedAction => - action.type.includes(allowedAction), - ); - const isModelIdTheSame = state.map.data.modelId === action.payload?.modelId; - - return isAllowedAction && !isModelIdTheSame; -}; - -const getUpdatedModel = (action: AllowedAction, state: RootState): MapModel | undefined => { - const models = modelsDataSelector(state); - return models.find(model => model.idObject === action?.payload?.modelId); -}; - -/* prettier-ignore */ -export const mapMiddleware: Middleware = - ({ getState, dispatch }: MiddlewareAPI<AppDispatch, RootState>) => - (next: AppDispatch) => - // eslint-disable-next-line consistent-return - (action: AllowedAction) => { - const state = getState(); - const isActionValid = checkIfIsActionValid(action, state); - const updatedModel = getUpdatedModel(action, state); - const returnValue = next(action); - - if (!isActionValid || !updatedModel) { - return returnValue; - } - - const updatedMapData = getUpdatedMapData({ model: updatedModel }); - dispatch(setMapData(updatedMapData)); - - return returnValue; - }; diff --git a/src/redux/map/map.reducers.ts b/src/redux/map/map.reducers.ts index 51f7faabc3987ba50a3e2c60ccb762fcf5ce9c07..962704b36070701d2e763147d57f2f99c8751ae8 100644 --- a/src/redux/map/map.reducers.ts +++ b/src/redux/map/map.reducers.ts @@ -11,7 +11,8 @@ export const getMapReducers = (builder: ActionReducerMapBuilder<MapState>): void state.loading = 'pending'; }); builder.addCase(initMapData.fulfilled, (state, action) => { - state.data = { ...state.data, ...action.payload }; + const payload = action.payload || {}; + state.data = { ...state.data, ...payload }; state.loading = 'succeeded'; }); builder.addCase(initMapData.rejected, state => { diff --git a/src/redux/map/map.thunks.test.ts b/src/redux/map/map.thunks.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..e6eb15231ef49d9d0d3145ca7ff3be4d82f3b2ec --- /dev/null +++ b/src/redux/map/map.thunks.test.ts @@ -0,0 +1,85 @@ +import { PROJECT_ID } from '@/constants'; +import { backgroundsFixture } from '@/models/fixtures/backgroundsFixture'; +import { modelsFixture } from '@/models/fixtures/modelsFixture'; +import { overlaysFixture } from '@/models/fixtures/overlaysFixture'; +import { mockNetworkResponse } from '@/utils/mockNetworkResponse'; +import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore'; +import { HttpStatusCode } from 'axios'; +import { apiPath } from '../apiPath'; +import { backgroundsDataSelector } from '../backgrounds/background.selectors'; +import { modelsDataSelector } from '../models/models.selectors'; +import { overlaysDataSelector } from '../overlays/overlays.selectors'; +import { StoreType } from '../store'; +import { initMapData } from './map.thunks'; +import { InitMapDataActionPayload } from './map.types'; + +const mockedAxiosClient = mockNetworkResponse(); + +describe('map thunks', () => { + describe('initMapData - thunk', () => { + describe('when API is returning valid data', () => { + let store = {} as StoreType; + let payload = {} as InitMapDataActionPayload; + + beforeAll(async () => { + mockedAxiosClient.resetHandlers(); + mockedAxiosClient.onGet(apiPath.getModelsString()).reply(HttpStatusCode.Ok, modelsFixture); + mockedAxiosClient + .onGet(apiPath.getAllOverlaysByProjectIdQuery(PROJECT_ID, { publicOverlay: true })) + .reply(HttpStatusCode.Ok, overlaysFixture); + mockedAxiosClient + .onGet(apiPath.getAllBackgroundsByProjectIdQuery(PROJECT_ID)) + .reply(HttpStatusCode.Ok, backgroundsFixture); + + store = getReduxWrapperWithStore().store; + payload = (await store.dispatch(initMapData())).payload as InitMapDataActionPayload; + }); + + it('should fetch backgrounds data in store', async () => { + const data = backgroundsDataSelector(store.getState()); + expect(data).toEqual(backgroundsFixture); + }); + + it('should fetch overlays data in store', async () => { + const data = overlaysDataSelector(store.getState()); + expect(data).toEqual(overlaysFixture); + }); + + it('should fetch models data in store', async () => { + const data = modelsDataSelector(store.getState()); + expect(data).toEqual(modelsFixture); + }); + + it('should return valid payload', () => { + const FIRST = 0; + + expect(payload).toMatchObject({ + modelId: modelsFixture[FIRST].idObject, + backgroundId: backgroundsFixture[FIRST].id, + }); + }); + }); + + describe('when API is returning empty array', () => { + let store = {} as StoreType; + let payload = {} as InitMapDataActionPayload; + + beforeEach(async () => { + mockedAxiosClient.onGet(apiPath.getModelsString()).reply(HttpStatusCode.Ok, []); + mockedAxiosClient + .onGet(apiPath.getAllOverlaysByProjectIdQuery(PROJECT_ID, { publicOverlay: true })) + .reply(HttpStatusCode.Ok, []); + mockedAxiosClient + .onGet(apiPath.getAllBackgroundsByProjectIdQuery(PROJECT_ID)) + .reply(HttpStatusCode.Ok, []); + + store = getReduxWrapperWithStore().store; + payload = (await store.dispatch(initMapData())).payload as InitMapDataActionPayload; + }); + + it('should return empty payload', () => { + expect(payload).toStrictEqual({}); + }); + }); + }); +}); diff --git a/src/redux/map/map.thunks.ts b/src/redux/map/map.thunks.ts index 481d5cfbd6c6235d24da3414082b3e2a4762ba0b..e6d8fef456ef2f0bda91c46d99cd7c45347c192e 100644 --- a/src/redux/map/map.thunks.ts +++ b/src/redux/map/map.thunks.ts @@ -8,7 +8,22 @@ import { getAllPublicOverlaysByProjectId } from '../overlays/overlays.thunks'; import type { AppDispatch, RootState } from '../store'; import { InitMapDataActionPayload } from './map.types'; -const FIRST = 0; +const getPayloadFromState = (state: RootState): InitMapDataActionPayload => { + const FIRST = 0; + const models = modelsDataSelector(state); + const backgrounds = backgroundsDataSelector(state); + const modelId = models?.[FIRST]?.idObject; + const backgroundId = backgrounds?.[FIRST]?.id; + + if (!modelId || !backgroundId) { + return {}; + } + + return { + modelId, + backgroundId, + }; +}; export const initMapData = createAsyncThunk< InitMapDataActionPayload, @@ -22,10 +37,5 @@ export const initMapData = createAsyncThunk< ]); const state = getState(); - const models = modelsDataSelector(state); - const backgrounds = backgroundsDataSelector(state); - const modelId = models[FIRST].idObject; - const backgroundId = backgrounds[FIRST].id; - - return { modelId, backgroundId }; + return getPayloadFromState(state); }); diff --git a/src/redux/map/map.types.ts b/src/redux/map/map.types.ts index 108648dcbe5a8a5eca06e9294328e41b904fb07b..7051691ed57d56fe19e934c18e8fa020a9f9246e 100644 --- a/src/redux/map/map.types.ts +++ b/src/redux/map/map.types.ts @@ -30,6 +30,10 @@ export type SetMapDataActionPayload = Partial<MapData> | undefined; export type SetMapDataAction = PayloadAction<SetMapDataActionPayload>; -export type InitMapDataActionPayload = { modelId: number; backgroundId: number }; +export type InitMapDataActionPayload = { modelId: number; backgroundId: number } | object; export type InitMapDataAction = PayloadAction<SetMapDataAction>; + +export type MiddlewareAllowedAction = PayloadAction< + SetMapDataActionPayload | InitMapDataActionPayload +>; diff --git a/src/redux/models/models.selectors.ts b/src/redux/models/models.selectors.ts index 1ae57c7e2e962dc33485300be74d02a61e888d91..8a9478b171d44dfc00afb4a23f34517b14ab6d33 100644 --- a/src/redux/models/models.selectors.ts +++ b/src/redux/models/models.selectors.ts @@ -4,7 +4,7 @@ import { mapDataSelector } from '../map/map.selectors'; export const modelsSelector = createSelector(rootSelector, state => state.models); -export const modelsDataSelector = createSelector(modelsSelector, models => models.data || []); +export const modelsDataSelector = createSelector(modelsSelector, models => models?.data || []); export const currentModelSelector = createSelector( modelsDataSelector, diff --git a/src/redux/overlays/overlays.selectors.ts b/src/redux/overlays/overlays.selectors.ts index 80b0439bc90d4f04f09ac02c9b5a64803dff2fd4..f9d36cad0a63c93ae55565e795b897c6bbd4db3e 100644 --- a/src/redux/overlays/overlays.selectors.ts +++ b/src/redux/overlays/overlays.selectors.ts @@ -5,5 +5,5 @@ export const overlaysSelector = createSelector(rootSelector, state => state.over export const overlaysDataSelector = createSelector( overlaysSelector, - overlays => overlays.data || [], + overlays => overlays?.data || [], ); diff --git a/src/redux/store.ts b/src/redux/store.ts index e1ecab618c63430b288ef907de5f2b1e66ca163c..aaecc167f6dc28fd7d4dab19cae41db8655b9812 100644 --- a/src/redux/store.ts +++ b/src/redux/store.ts @@ -10,7 +10,7 @@ import overlaysReducer from '@/redux/overlays/overlays.slice'; import projectReducer from '@/redux/project/project.slice'; import searchReducer from '@/redux/search/search.slice'; import { applyMiddleware, configureStore } from '@reduxjs/toolkit'; -import { mapMiddleware } from './map/map.middleware'; +import { mapMiddleware } from './map/middleware/map.middleware'; export const reducers = { search: searchReducer, diff --git a/src/utils/map/getUpdatedMapData.test.ts b/src/utils/map/getUpdatedMapData.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..5afdbc3c00a37776b425577324036ae739553b07 --- /dev/null +++ b/src/utils/map/getUpdatedMapData.test.ts @@ -0,0 +1,94 @@ +import { DEFAULT_ZOOM } from '@/constants/map'; +import { singleModelFixture } from '@/models/fixtures/modelsFixture'; +import { getUpdatedMapData } from './getUpdatedMapData'; + +const HALF = 2; + +describe('getUpdatedMapData - util', () => { + describe('when model does not have default values', () => { + const model = { + ...singleModelFixture, + defaultCenterX: null, + defaultCenterY: null, + defaultZoomLevel: null, + }; + + it('should return correct value', () => { + const result = { + modelId: model.idObject, + size: { + width: model.width, + height: model.height, + tileSize: model.tileSize, + minZoom: model.minZoom, + maxZoom: model.maxZoom, + }, + position: { + x: model.width / HALF, + y: model.height / HALF, + z: DEFAULT_ZOOM, + }, + }; + + expect(getUpdatedMapData({ model })).toMatchObject(result); + }); + }); + + describe('when model has default falsy values', () => { + const model = { + ...singleModelFixture, + defaultCenterX: 0, + defaultCenterY: 0, + defaultZoomLevel: null, + }; + + it('should return correct value', () => { + const result = { + modelId: model.idObject, + size: { + width: model.width, + height: model.height, + tileSize: model.tileSize, + minZoom: model.minZoom, + maxZoom: model.maxZoom, + }, + position: { + x: 0, + y: 0, + z: DEFAULT_ZOOM, + }, + }; + + expect(getUpdatedMapData({ model })).toMatchObject(result); + }); + }); + + describe('when model has default truthy values', () => { + const model = { + ...singleModelFixture, + defaultCenterX: 10, + defaultCenterY: 10, + defaultZoomLevel: 1, + }; + + it('should return correct value', () => { + const result = { + modelId: model.idObject, + size: { + width: model.width, + height: model.height, + tileSize: model.tileSize, + minZoom: model.minZoom, + maxZoom: model.maxZoom, + }, + position: { + x: 10, + y: 10, + z: 1, + }, + }; + + expect(getUpdatedMapData({ model })).toMatchObject(result); + }); + }); +}); diff --git a/src/utils/getUpdatedMapData.ts b/src/utils/map/getUpdatedMapData.ts similarity index 74% rename from src/utils/getUpdatedMapData.ts rename to src/utils/map/getUpdatedMapData.ts index 7bbc132984cc9a5b87670f241c64b9247bc8b29d..552e29a64b20d955929f5e99a2233c915aebe9f0 100644 --- a/src/utils/getUpdatedMapData.ts +++ b/src/utils/map/getUpdatedMapData.ts @@ -6,9 +6,7 @@ interface GetUpdatedMapDataArgs { model: MapModel; } -type GetUpdatedMapDataResult = Pick<MapData, 'modelId' | 'size' | 'position'> & { - backgroundId?: number; -}; +type GetUpdatedMapDataResult = Pick<MapData, 'modelId' | 'size' | 'position'>; const HALF = 2; @@ -22,8 +20,8 @@ export const getUpdatedMapData = ({ model }: GetUpdatedMapDataArgs): GetUpdatedM maxZoom: model.maxZoom, }, position: { - x: model.defaultCenterX || model.width / HALF, - y: model.defaultCenterY || model.height / HALF, - z: model.defaultZoomLevel || DEFAULT_ZOOM, + x: model.defaultCenterX ?? model.width / HALF, + y: model.defaultCenterY ?? model.height / HALF, + z: model.defaultZoomLevel ?? DEFAULT_ZOOM, }, });