From c3b9e2fad3d31c1e50e39ffd198c10af11f58196 Mon Sep 17 00:00:00 2001 From: mateusz-winiarczyk <mateusz.winiarczyk@appunite.com> Date: Fri, 8 Mar 2024 11:37:29 +0100 Subject: [PATCH] feat(pluginevents): add dispatching event onsearch on map click (MIN-296) --- .../handleSearchResultForRightClickAction.ts | 2 +- .../mapSingleClick/handleAliasResults.test.ts | 5 +- .../mapSingleClick/handleAliasResults.ts | 12 ++++- .../handleReactionResults.test.ts | 5 +- .../mapSingleClick/handleReactionResults.ts | 11 ++++- .../handleSearchResultAction.ts | 2 +- src/redux/bioEntity/bioEntity.thunks.test.ts | 49 ++++++++++++++++++- src/redux/bioEntity/bioEntity.thunks.ts | 15 ++++-- .../pluginsEventBus/pluginsEventBus.types.ts | 11 ++++- 9 files changed, 98 insertions(+), 14 deletions(-) diff --git a/src/components/Map/MapViewer/utils/listeners/mapRightClick/handleSearchResultForRightClickAction.ts b/src/components/Map/MapViewer/utils/listeners/mapRightClick/handleSearchResultForRightClickAction.ts index 858b57fb..29056a8f 100644 --- a/src/components/Map/MapViewer/utils/listeners/mapRightClick/handleSearchResultForRightClickAction.ts +++ b/src/components/Map/MapViewer/utils/listeners/mapRightClick/handleSearchResultForRightClickAction.ts @@ -20,5 +20,5 @@ export const handleSearchResultForRightClickAction = async ({ REACTION: handleReactionResults, }[type]; - await action(dispatch)(closestSearchResult); + await action(dispatch, closestSearchResult)(closestSearchResult); }; diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.test.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.test.ts index 44ac11c9..1d8a0df8 100644 --- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.test.ts +++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.test.ts @@ -24,7 +24,10 @@ describe('handleAliasResults - util', () => { .reply(HttpStatusCode.Ok, bioEntityResponseFixture); beforeAll(async () => { - handleAliasResults(dispatch)(ELEMENT_SEARCH_RESULT_MOCK_ALIAS); + handleAliasResults( + dispatch, + ELEMENT_SEARCH_RESULT_MOCK_ALIAS, + )(ELEMENT_SEARCH_RESULT_MOCK_ALIAS); }); it('should run openBioEntityDrawerById as first action', async () => { diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.ts index cd7aefe9..cd386b1c 100644 --- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.ts +++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.ts @@ -3,10 +3,11 @@ import { openBioEntityDrawerById } from '@/redux/drawer/drawer.slice'; import { AppDispatch } from '@/redux/store'; import { searchFitBounds } from '@/services/pluginsManager/map/triggerSearch/searchFitBounds'; import { ElementSearchResult } from '@/types/models'; +import { PluginsEventBus } from '@/services/pluginsManager/pluginsEventBus'; /* prettier-ignore */ export const handleAliasResults = - (dispatch: AppDispatch, hasFitBounds?: boolean, fitBoundsZoom?: number) => + (dispatch: AppDispatch, closestSearchResult: ElementSearchResult, hasFitBounds?: boolean, fitBoundsZoom?: number) => async ({ id }: ElementSearchResult): Promise<void> => { dispatch(openBioEntityDrawerById(id)); @@ -16,7 +17,14 @@ export const handleAliasResults = isPerfectMatch: true }), ) - .unwrap().then(() => { + .unwrap().then((bioEntityContents) => { + + PluginsEventBus.dispatchEvent('onSearch', { + type: 'bioEntity', + searchValues: [closestSearchResult], + results: [bioEntityContents], + }); + if (hasFitBounds) { searchFitBounds(fitBoundsZoom); } diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts index b514095b..020f0c64 100644 --- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts +++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts @@ -33,7 +33,10 @@ describe('handleReactionResults - util', () => { .reply(HttpStatusCode.Ok, reactionsFixture); beforeAll(async () => { - handleReactionResults(dispatch)(ELEMENT_SEARCH_RESULT_MOCK_REACTION); + handleReactionResults( + dispatch, + ELEMENT_SEARCH_RESULT_MOCK_REACTION, + )(ELEMENT_SEARCH_RESULT_MOCK_REACTION); }); it('should run getReactionsByIds as first action', () => { diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts index d8282817..24332182 100644 --- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts +++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts @@ -6,10 +6,11 @@ import { AppDispatch } from '@/redux/store'; import { searchFitBounds } from '@/services/pluginsManager/map/triggerSearch/searchFitBounds'; import { ElementSearchResult, Reaction } from '@/types/models'; import { PayloadAction } from '@reduxjs/toolkit'; +import { PluginsEventBus } from '@/services/pluginsManager/pluginsEventBus'; /* prettier-ignore */ export const handleReactionResults = - (dispatch: AppDispatch, hasFitBounds?: boolean, fitBoundsZoom?: number) => + (dispatch: AppDispatch, closestSearchResult: ElementSearchResult, hasFitBounds?: boolean, fitBoundsZoom?: number) => async ({ id }: ElementSearchResult): Promise<void> => { const data = await dispatch(getReactionsByIds([id])) as PayloadAction<Reaction[] | undefined>; const payload = data?.payload; @@ -30,7 +31,13 @@ export const handleReactionResults = searchQueries: bioEntitiesIds, isPerfectMatch: true }, ) - ).unwrap().then(() => { + ).unwrap().then((bioEntityContents) => { + PluginsEventBus.dispatchEvent('onSearch', { + type: 'bioEntity', + searchValues: [closestSearchResult], + results: [bioEntityContents], + }); + if (hasFitBounds) { searchFitBounds(fitBoundsZoom); } diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleSearchResultAction.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleSearchResultAction.ts index c3663e41..39dea100 100644 --- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleSearchResultAction.ts +++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleSearchResultAction.ts @@ -25,7 +25,7 @@ export const handleSearchResultAction = async ({ REACTION: handleReactionResults, }[type]; - await action(dispatch, hasFitBounds, fitBoundsZoom)(closestSearchResult); + await action(dispatch, closestSearchResult, hasFitBounds, fitBoundsZoom)(closestSearchResult); if (type === 'ALIAS') { PluginsEventBus.dispatchEvent('onBioEntityClick', closestSearchResult); diff --git a/src/redux/bioEntity/bioEntity.thunks.test.ts b/src/redux/bioEntity/bioEntity.thunks.test.ts index b45d1941..9757ab4b 100644 --- a/src/redux/bioEntity/bioEntity.thunks.test.ts +++ b/src/redux/bioEntity/bioEntity.thunks.test.ts @@ -7,7 +7,7 @@ import { import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse'; import { HttpStatusCode } from 'axios'; import contentsReducer from './bioEntity.slice'; -import { getBioEntity } from './bioEntity.thunks'; +import { getBioEntity, getMultiBioEntity } from './bioEntity.thunks'; import { BioEntityContentsState } from './bioEntity.types'; const mockedAxiosClient = mockNetworkNewAPIResponse(); @@ -56,4 +56,51 @@ describe('bioEntityContents thunks', () => { expect(payload).toEqual(undefined); }); }); + describe('getMultiBioEntity', () => { + it('should return transformed bioEntityContent array', async () => { + mockedAxiosClient + .onGet( + apiPath.getBioEntityContentsStringWithQuery({ + searchQuery: SEARCH_QUERY, + isPerfectMatch: false, + }), + ) + .reply(HttpStatusCode.Ok, bioEntityResponseFixture); + + const data = await store + .dispatch( + getMultiBioEntity({ + searchQueries: [SEARCH_QUERY], + isPerfectMatch: false, + }), + ) + .unwrap(); + + expect(data).toEqual(bioEntityResponseFixture.content); + }); + it('should combine all returned bioEntityContent arrays and return array with all provided bioEntityContent elements', async () => { + mockedAxiosClient + .onGet( + apiPath.getBioEntityContentsStringWithQuery({ + searchQuery: SEARCH_QUERY, + isPerfectMatch: false, + }), + ) + .reply(HttpStatusCode.Ok, bioEntityResponseFixture); + + const data = await store + .dispatch( + getMultiBioEntity({ + searchQueries: [SEARCH_QUERY, SEARCH_QUERY], + isPerfectMatch: false, + }), + ) + .unwrap(); + + expect(data).toEqual([ + ...bioEntityResponseFixture.content, + ...bioEntityResponseFixture.content, + ]); + }); + }); }); diff --git a/src/redux/bioEntity/bioEntity.thunks.ts b/src/redux/bioEntity/bioEntity.thunks.ts index e1b59d1e..32185755 100644 --- a/src/redux/bioEntity/bioEntity.thunks.ts +++ b/src/redux/bioEntity/bioEntity.thunks.ts @@ -1,5 +1,5 @@ import { PerfectMultiSearchParams, PerfectSearchParams } from '@/types/search'; -import { createAsyncThunk } from '@reduxjs/toolkit'; +import { PayloadAction, createAsyncThunk } from '@reduxjs/toolkit'; import { bioEntityResponseSchema } from '@/models/bioEntityResponseSchema'; import { apiPath } from '@/redux/apiPath'; import { axiosInstanceNewAPI } from '@/services/api/utils/axiosInstance'; @@ -25,17 +25,26 @@ export const getBioEntity = createAsyncThunk( ); type GetMultiBioEntityProps = PerfectMultiSearchParams; +type GetMultiBioEntityActions = PayloadAction<BioEntityContent[] | undefined>[]; export const getMultiBioEntity = createAsyncThunk( 'project/getMultiBioEntity', async ( { searchQueries, isPerfectMatch }: GetMultiBioEntityProps, { dispatch }, - ): Promise<void> => { + ): Promise<BioEntityContent[]> => { const asyncGetBioEntityFunctions = searchQueries.map(searchQuery => dispatch(getBioEntity({ searchQuery, isPerfectMatch })), ); - await Promise.all(asyncGetBioEntityFunctions); + const bioEntityContentsActions = (await Promise.all( + asyncGetBioEntityFunctions, + )) as GetMultiBioEntityActions; + + const bioEntityContents = bioEntityContentsActions + .map(bioEntityContentsAction => bioEntityContentsAction.payload || []) + .flat(); + + return bioEntityContents; }, ); diff --git a/src/services/pluginsManager/pluginsEventBus/pluginsEventBus.types.ts b/src/services/pluginsManager/pluginsEventBus/pluginsEventBus.types.ts index 7679bb0a..2122a199 100644 --- a/src/services/pluginsManager/pluginsEventBus/pluginsEventBus.types.ts +++ b/src/services/pluginsManager/pluginsEventBus/pluginsEventBus.types.ts @@ -1,4 +1,11 @@ -import { BioEntityContent, Chemical, CreatedOverlay, Drug, MapOverlay } from '@/types/models'; +import { + BioEntityContent, + Chemical, + CreatedOverlay, + Drug, + ElementSearchResult, + MapOverlay, +} from '@/types/models'; import { dispatchEvent } from './pluginsEventBus'; export type BackgroundEvents = 'onBackgroundOverlayChange'; @@ -36,7 +43,7 @@ export type ClickedBioEntity = { export type SearchDataBioEntity = { type: 'bioEntity'; - searchValues: string[]; + searchValues: string[] | ElementSearchResult[]; results: BioEntityContent[][]; }; -- GitLab