diff --git a/CHANGELOG b/CHANGELOG index 6a39df06153f9c662122a976baa6745e8e3b6e5a..60e6ca7d4077f245988718e38c6e041dcedda39b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,19 @@ minerva-front (19.0.0~alpha.0) stable; urgency=medium -- Piotr Gawron <piotr.gawron@uni.lu> Fri, 18 Oct 2024 13:00:00 +0200 +minerva-front (18.0.5) stable; urgency=medium + * Bug fix: anchor overlays were disappearing after clicking on anchor and + outside of the anchor (#319) + + -- Piotr Gawron <piotr.gawron@uni.lu> Wed, 27 Nov 2024 13:00:00 +0200 + +minerva-front (18.0.4) stable; urgency=medium + * Bug fix: link to search result from overview image caused map not to + load (#318) + * Bug fix: when compartment is missing "default" is added (#314) + + -- Piotr Gawron <piotr.gawron@uni.lu> Mon, 11 Nov 2024 15:00:00 +0200 + minerva-front (18.0.3) stable; urgency=medium * Bug fix: Molart froze after clicking (#313) * Bug fix: missing description and modifications added to element and diff --git a/src/components/FunctionalArea/Modal/OverviewImagesModal/OverviewImageModal.types.ts b/src/components/FunctionalArea/Modal/OverviewImagesModal/OverviewImageModal.types.ts index a09968c65631dad23f8b8df5fca373d2b35e42a2..8575ee97bb8dccc205ba8957dc65d398c010e3ed 100644 --- a/src/components/FunctionalArea/Modal/OverviewImagesModal/OverviewImageModal.types.ts +++ b/src/components/FunctionalArea/Modal/OverviewImagesModal/OverviewImageModal.types.ts @@ -1,4 +1,8 @@ -import { OverviewImageLinkImage, OverviewImageLinkModel } from '@/types/models'; +import { + OverviewImageLinkImage, + OverviewImageLinkModel, + OverviewImageLinkSearch, +} from '@/types/models'; export interface OverviewImageSize { width: number; @@ -26,3 +30,5 @@ export interface OverviewImageLinkConfig { export type OverviewImageLinkImageHandler = (link: OverviewImageLinkImage) => void; export type OverviewImageLinkModelHandler = (link: OverviewImageLinkModel) => void; + +export type OverviewImageLinkSearchHandler = (link: OverviewImageLinkSearch) => void; diff --git a/src/components/FunctionalArea/Modal/OverviewImagesModal/utils/useOverviewImageLinkActions.ts b/src/components/FunctionalArea/Modal/OverviewImagesModal/utils/useOverviewImageLinkActions.ts index d69596ffa24e94187a5d5506c7fc749669ac5057..3b7aee8c0d297b86e612177ac145fa05398187b2 100644 --- a/src/components/FunctionalArea/Modal/OverviewImagesModal/utils/useOverviewImageLinkActions.ts +++ b/src/components/FunctionalArea/Modal/OverviewImagesModal/utils/useOverviewImageLinkActions.ts @@ -1,4 +1,4 @@ -import { NOOP } from '@/constants/common'; +import { NOOP, ZERO } from '@/constants/common'; import { useAppDispatch } from '@/redux/hooks/useAppDispatch'; import { useAppSelector } from '@/redux/hooks/useAppSelector'; import { mapOpenedMapsSelector } from '@/redux/map/map.selectors'; @@ -8,9 +8,12 @@ import { currentModelIdSelector, modelsDataSelector } from '@/redux/models/model import { projectOverviewImagesSelector } from '@/redux/project/project.selectors'; import { PluginsEventBus } from '@/services/pluginsManager/pluginsEventBus'; import { MapModel, OverviewImageLink, OverviewImageLinkModel } from '@/types/models'; +import { getSearchData } from '@/redux/search/search.thunks'; +import { openSearchDrawerWithSelectedTab } from '@/redux/drawer/drawer.slice'; import { OverviewImageLinkImageHandler, OverviewImageLinkModelHandler, + OverviewImageLinkSearchHandler, } from '../OverviewImageModal.types'; interface UseOverviewImageLinkActionsResult { @@ -75,6 +78,16 @@ export const useOverviewImageLinkActions = (): UseOverviewImageLinkActionsResult dispatch(closeModal()); }; + const onSearchClick: OverviewImageLinkSearchHandler = link => { + const { query } = link; + + const searchValues = query.split(','); + dispatch(getSearchData({ searchQueries: searchValues, isPerfectMatch: false })); + dispatch(openSearchDrawerWithSelectedTab(searchValues[ZERO])); + + dispatch(closeModal()); + }; + const onImageClick: OverviewImageLinkImageHandler = link => { const isImageAvailable = checkIfImageIsAvailable(link.linkedOverviewImage); if (!isImageAvailable) { @@ -87,6 +100,7 @@ export const useOverviewImageLinkActions = (): UseOverviewImageLinkActionsResult const handleLinkClick: UseOverviewImageLinkActionsResult['handleLinkClick'] = link => { const isImageLink = 'linkedOverviewImage' in link; const isModelLink = 'linkedModel' in link; + const isSearchLink = 'query' in link; if (isImageLink) { return onImageClick(link); @@ -96,6 +110,10 @@ export const useOverviewImageLinkActions = (): UseOverviewImageLinkActionsResult return onSubmapClick(link); } + if (isSearchLink) { + return onSearchClick(link); + } + return NOOP(); }; diff --git a/src/components/FunctionalArea/TopBar/ClearAnchorsButton/ClearAnchorsButton.component.test.tsx b/src/components/FunctionalArea/TopBar/ClearAnchorsButton/ClearAnchorsButton.component.test.tsx index 0180c8a68058e01002993b279d338b03ff0b027b..b8bc885aedc1f6e0382d6355baf871510edc85cd 100644 --- a/src/components/FunctionalArea/TopBar/ClearAnchorsButton/ClearAnchorsButton.component.test.tsx +++ b/src/components/FunctionalArea/TopBar/ClearAnchorsButton/ClearAnchorsButton.component.test.tsx @@ -49,7 +49,7 @@ describe('ClearAnchorsButton - component', () => { { payload: undefined, type: 'contextMenu/closeContextMenu' }, { payload: undefined, type: 'reactions/resetReactionsData' }, { payload: undefined, type: 'search/clearSearchData' }, - { payload: undefined, type: 'bioEntityContents/clearBioEntitiesData' }, + { payload: undefined, type: 'bioEntityContents/clearBioEntities' }, { payload: undefined, type: 'drugs/clearDrugsData' }, { payload: undefined, type: 'chemicals/clearChemicalsData' }, ]); @@ -75,7 +75,7 @@ describe('ClearAnchorsButton - component', () => { { payload: undefined, type: 'contextMenu/closeContextMenu' }, { payload: undefined, type: 'reactions/resetReactionsData' }, { payload: undefined, type: 'search/clearSearchData' }, - { payload: undefined, type: 'bioEntityContents/clearBioEntitiesData' }, + { payload: undefined, type: 'bioEntityContents/clearBioEntities' }, { payload: undefined, type: 'drugs/clearDrugsData' }, { payload: undefined, type: 'chemicals/clearChemicalsData' }, ]); diff --git a/src/components/FunctionalArea/TopBar/ClearAnchorsButton/ClearAnchorsButton.component.tsx b/src/components/FunctionalArea/TopBar/ClearAnchorsButton/ClearAnchorsButton.component.tsx index 3be4a77026bbe811877e473dbf4bee1ff76b86d7..0cb3417872af8ff8ebd0541c3f04d2e838c8fef1 100644 --- a/src/components/FunctionalArea/TopBar/ClearAnchorsButton/ClearAnchorsButton.component.tsx +++ b/src/components/FunctionalArea/TopBar/ClearAnchorsButton/ClearAnchorsButton.component.tsx @@ -1,4 +1,4 @@ -import { clearBioEntitiesData } from '@/redux/bioEntity/bioEntity.slice'; +import { clearBioEntities } from '@/redux/bioEntity/bioEntity.slice'; import { clearChemicalsData } from '@/redux/chemicals/chemicals.slice'; import { closeContextMenu } from '@/redux/contextMenu/contextMenu.slice'; import { resultDrawerOpen } from '@/redux/drawer/drawer.selectors'; @@ -31,7 +31,7 @@ export const ClearAnchorsButton = (): React.ReactNode => { dispatch(clearSearchData()); // Reset old pins data - dispatch(clearBioEntitiesData()); + dispatch(clearBioEntities()); dispatch(clearDrugsData()); dispatch(clearChemicalsData()); }; diff --git a/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx b/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx index 853c8e22a178ad7489022c3a49640ca3c68384b0..44344acaf633d4fa064c47239bf3c0f69978e707 100644 --- a/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx +++ b/src/components/Map/Drawer/BioEntityDrawer/BioEntityDrawer.component.tsx @@ -62,14 +62,22 @@ export const BioEntityDrawer = (): React.ReactNode => { /> <div className="flex max-h-full flex-col gap-6 overflow-y-auto p-6"> <div className="text-sm font-normal"> - Compartment: <b className="font-semibold">{bioEntityData.compartmentName}</b> + Compartment:{' '} + <b className="font-semibold"> + {bioEntityData.compartmentName ? bioEntityData.compartmentName : 'default'} + </b> </div> {bioEntityData.fullName && ( <div className="text-sm font-normal"> Full name: <b className="font-semibold">{bioEntityData.fullName}</b> </div> )} - {bioEntityData.notes && <div className="text-sm font-normal">{bioEntityData.notes}</div>} + {bioEntityData.notes && ( + <span> + <hr className="border-b border-b-divide" /> + <div className="text-sm font-normal">{bioEntityData.notes}</div> + </span> + )} {isModificationAvailable && ( <h3 className="font-semibold">Post-translational modifications:</h3> )} 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 bd25417f10ee1dd4c71662c9e84b96c86a971d75..b867378fc4c08464afe2900276e5a9280dbc4727 100644 --- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.test.ts +++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.test.ts @@ -80,7 +80,7 @@ describe('handleAliasResults - util', () => { 'project/getBioEntityById/fulfilled', 'entityNumber/addNumbersToEntityNumberData', 'project/getMultiBioEntity/fulfilled', - 'bioEntityContents/clearBioEntitiesData', + 'bioEntityContents/clearBioEntities', ]); }); }); @@ -121,7 +121,7 @@ describe('handleAliasResults - util', () => { 'entityNumber/addNumbersToEntityNumberData', 'project/getMultiBioEntity/fulfilled', 'drawer/closeDrawer', - 'bioEntityContents/clearBioEntitiesData', + 'bioEntityContents/clearBioEntities', ]); }); }); diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.ts index 02c8312ec556e43e4399fdc51860c17b18475610..c3d05abac90d5ed78f58e8dc986bf6adcb0316f8 100644 --- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.ts +++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.ts @@ -3,7 +3,7 @@ import { AppDispatch } from '@/redux/store'; import { searchFitBounds } from '@/services/pluginsManager/map/triggerSearch/searchFitBounds'; import { ElementSearchResult } from '@/types/models'; import { PluginsEventBus } from '@/services/pluginsManager/pluginsEventBus'; -import { clearBioEntitiesData } from '@/redux/bioEntity/bioEntity.slice'; +import { clearBioEntities } from '@/redux/bioEntity/bioEntity.slice'; import { Point } from '@/types/map'; import { getMultiBioEntityByIds } from '@/redux/bioEntity/thunks/getMultiBioEntity'; import { findClosestBioEntityPoint } from './findClosestBioEntityPoint'; @@ -37,7 +37,7 @@ export const handleAliasResults = dispatch(closeDrawer()); } - dispatch(clearBioEntitiesData()); + dispatch(clearBioEntities()); return; } } 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 f44aa7c86cfd4fc74609b1540a14c261fbc5bfcc..b39bdca0a40440f8c5220156ce4690cb9f618f0a 100644 --- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts +++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts @@ -206,7 +206,7 @@ describe('handleReactionResults - util', () => { 'reactions/getByIds/fulfilled', 'drawer/closeDrawer', 'reactions/resetReactionsData', - 'bioEntityContents/clearBioEntitiesData', + 'bioEntityContents/clearBioEntities', ]); }); @@ -229,7 +229,7 @@ describe('handleReactionResults - util', () => { expect(dispatchSpy).toHaveBeenCalledWith({ payload: undefined, - type: 'bioEntityContents/clearBioEntitiesData', + type: 'bioEntityContents/clearBioEntities', }); }); }); diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionSearchClickFailure.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionSearchClickFailure.ts index 7368bb185bb1bf9020c5000c3f3fa193c04110c9..30c6178fd8257aa687962e7a54c7db33a8c8fbd0 100644 --- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionSearchClickFailure.ts +++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionSearchClickFailure.ts @@ -1,7 +1,7 @@ import { AppDispatch } from '@/redux/store'; import { closeDrawer } from '@/redux/drawer/drawer.slice'; import { resetReactionsData } from '@/redux/reactions/reactions.slice'; -import { clearBioEntitiesData } from '@/redux/bioEntity/bioEntity.slice'; +import { clearBioEntities } from '@/redux/bioEntity/bioEntity.slice'; export const handleReactionSearchClickFailure = ( dispatch: AppDispatch, @@ -11,5 +11,5 @@ export const handleReactionSearchClickFailure = ( dispatch(closeDrawer()); } dispatch(resetReactionsData()); - dispatch(clearBioEntitiesData()); + dispatch(clearBioEntities()); }; diff --git a/src/models/overviewImageLink.ts b/src/models/overviewImageLink.ts index 6a57bdb0f0ff6b1d0070302d5ca82ac1ba1a9d8b..69d168ad080616ee87b4be76835049b7d2167232 100644 --- a/src/models/overviewImageLink.ts +++ b/src/models/overviewImageLink.ts @@ -18,4 +18,15 @@ export const overviewImageLinkModel = z.object({ // type: z.string(), }); -export const overviewImageLink = z.union([overviewImageLinkImage, overviewImageLinkModel]); +export const overviewImageLinkSearch = z.object({ + idObject: z.number(), + polygon: z.array(positionSchema), + query: z.string(), + type: z.string(), +}); + +export const overviewImageLink = z.union([ + overviewImageLinkImage, + overviewImageLinkModel, + overviewImageLinkSearch, +]); diff --git a/src/redux/bioEntity/bioEntity.reducers.ts b/src/redux/bioEntity/bioEntity.reducers.ts index 517792916872a630a10d4c953bf4415fedff6b59..b24046b9538468ee7577f23bf48a19b8dfe4629d 100644 --- a/src/redux/bioEntity/bioEntity.reducers.ts +++ b/src/redux/bioEntity/bioEntity.reducers.ts @@ -108,11 +108,9 @@ export const getSubmapConnectionsBioEntityReducer = ( }); }; -export const clearBioEntitiesDataReducer = (state: BioEntityContentsState): void => { +export const clearBioEntitiesReducer = (state: BioEntityContentsState): void => { state.data = []; state.loading = 'idle'; - - state.submapConnections = BIOENTITY_SUBMAP_CONNECTIONS_INITIAL_STATE; }; export const clearBioEntitiesReducer = (state: BioEntityContentsState): void => { diff --git a/src/redux/bioEntity/bioEntity.slice.ts b/src/redux/bioEntity/bioEntity.slice.ts index 2a9f849dda0ecee6d73d1cc2d8737af1f12ad633..74dcffaa384d92e0c2f6d20586e1e11c386d4e61 100644 --- a/src/redux/bioEntity/bioEntity.slice.ts +++ b/src/redux/bioEntity/bioEntity.slice.ts @@ -1,7 +1,6 @@ import { createSlice } from '@reduxjs/toolkit'; import { BIOENTITY_INITIAL_STATE } from './bioEntity.constants'; import { - clearBioEntitiesDataReducer, clearBioEntitiesReducer, getBioEntityContentsReducer, getMultiBioEntityContentsReducer, @@ -15,7 +14,6 @@ export const bioEntityContentsSlice = createSlice({ name: 'bioEntityContents', initialState: BIOENTITY_INITIAL_STATE, reducers: { - clearBioEntitiesData: clearBioEntitiesDataReducer, clearBioEntities: clearBioEntitiesReducer, toggleIsContentTabOpened: toggleIsContentTabOpenedReducer, setBioEntityContents: setBioEntityContentsReducer, @@ -29,7 +27,6 @@ export const bioEntityContentsSlice = createSlice({ }); export const { - clearBioEntitiesData, clearBioEntities, toggleIsContentTabOpened, setBioEntityContents, diff --git a/src/redux/search/search.thunks.ts b/src/redux/search/search.thunks.ts index 5d1e36e8b7c5c7a818be6981636a9935c0ee1680..b95730d28ef1660c6dca265e31f746822d7f4948 100644 --- a/src/redux/search/search.thunks.ts +++ b/src/redux/search/search.thunks.ts @@ -9,7 +9,6 @@ import { resetReactionsData } from '../reactions/reactions.slice'; import type { RootState } from '../store'; import { DATA_SEARCHING_ERROR_PREFIX } from './search.constants'; import { dispatchPluginsEvents } from './search.thunks.utils'; -import { getSubmapConnectionsBioEntity } from '../bioEntity/thunks/getSubmapConnectionsBioEntity'; type GetSearchDataProps = PerfectMultiSearchParams; @@ -34,13 +33,11 @@ export const getSearchData = createAsyncThunk< dispatch(getMultiBioEntity({ searchQueries, isPerfectMatch })), dispatch(getMultiDrugs(searchQueries)), dispatch(getMultiChemicals(searchQueries)), - dispatch(getSubmapConnectionsBioEntity()), ]); } else { await Promise.all([ dispatch(getMultiBioEntity({ searchQueries, isPerfectMatch })), dispatch(getMultiDrugs(searchQueries)), - dispatch(getSubmapConnectionsBioEntity()), ]); } diff --git a/src/services/pluginsManager/bioEntities/clearAllElements.ts b/src/services/pluginsManager/bioEntities/clearAllElements.ts index 9177d501b7078497512f2650bc677f3ca15b7fbe..ce8a4ee72e3f6d781d7dca40cffadffa729c51fc 100644 --- a/src/services/pluginsManager/bioEntities/clearAllElements.ts +++ b/src/services/pluginsManager/bioEntities/clearAllElements.ts @@ -1,4 +1,4 @@ -import { clearBioEntitiesData } from '@/redux/bioEntity/bioEntity.slice'; +import { clearBioEntities } from '@/redux/bioEntity/bioEntity.slice'; import { clearChemicalsData } from '@/redux/chemicals/chemicals.slice'; import { clearDrugsData } from '@/redux/drugs/drugs.slice'; import { setMarkersData } from '@/redux/markers/markers.slice'; @@ -10,7 +10,7 @@ export const clearAllElements = (elements: ElementName[]): void => { const { dispatch } = store; if (elements.includes('content')) { - dispatch(clearBioEntitiesData()); + dispatch(clearBioEntities()); } if (elements.includes('chemicals')) { diff --git a/src/types/models.ts b/src/types/models.ts index 4821833d59a22bbbf9941454cd5830deaf618735..a7f9735a40a82fc12d4c72e5c82a3771976efb7f 100644 --- a/src/types/models.ts +++ b/src/types/models.ts @@ -44,6 +44,7 @@ import { overviewImageLink, overviewImageLinkImage, overviewImageLinkModel, + overviewImageLinkSearch, } from '@/models/overviewImageLink'; import { overviewImageView } from '@/models/overviewImageView'; import { pluginSchema } from '@/models/pluginSchema'; @@ -89,6 +90,7 @@ export type OverviewImageView = z.infer<typeof overviewImageView>; export type OverviewImageLink = z.infer<typeof overviewImageLink>; export type OverviewImageLinkImage = z.infer<typeof overviewImageLinkImage>; export type OverviewImageLinkModel = z.infer<typeof overviewImageLinkModel>; +export type OverviewImageLinkSearch = z.infer<typeof overviewImageLinkSearch>; export type MapModel = z.infer<typeof mapModelSchema>; export type BioShape = z.infer<typeof bioShapeSchema>; export type LineType = z.infer<typeof lineTypeSchema>;