diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsList.types.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsList.types.tsx index f9707cb23f573f4e7f5ed6466b60509a844c1a78..74d6fe343e329624a3cd16fe827787a090acd756 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsList.types.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsList.types.tsx @@ -8,3 +8,9 @@ export type PinItem = { }; export type PinTypeWithNone = PinType | 'none'; + +export type AvailableSubmaps = { + id: number; + modelId: number; + name: string; +}; diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.test.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.test.tsx index edf080098c2c65d28d96338ba5370ed11ffa7e1d..fdc457a0a2a6b776dcf6fb1381e79468c8624c4f 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.test.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.test.tsx @@ -9,6 +9,7 @@ import { getReduxWrapperWithStore, } from '@/utils/testing/getReduxWrapperWithStore'; import { render, screen } from '@testing-library/react'; +// import { MODELS_MOCK_SHORT } from '@/models/mocks/modelsMock'; import { PinTypeWithNone } from '../PinsList.types'; import { PinsListItem } from './PinsListItem.component'; @@ -77,7 +78,7 @@ describe('PinsListItem - component ', () => { expect(screen.getByText(secondPinReferenceResource, { exact: false })).toBeInTheDocument(); }); it('should display list of elements for pin for chemicals', () => { - renderComponent(CHEMICALS_PIN.name, CHEMICALS_PIN.pin, 'drugs'); + renderComponent(CHEMICALS_PIN.name, CHEMICALS_PIN.pin, 'chemicals'); const firstPinElementType = chemicalsFixture[0].targets[0].targetParticipants[0].type; const firstPinElementResource = chemicalsFixture[0].targets[0].targetParticipants[0].resource; @@ -100,4 +101,14 @@ describe('PinsListItem - component ', () => { expect(screen.queryByText(bioEntityName, { exact: false })).not.toBeInTheDocument(); }); + it("should not display list of available submaps for pin when there aren't any submaps", () => { + const chemicalWithoutSubmaps = { + ...CHEMICALS_PIN.pin, + targetElements: [], + }; + + renderComponent(CHEMICALS_PIN.name, chemicalWithoutSubmaps, 'chemicals'); + + expect(screen.queryByText('Available in submaps:')).toBeNull(); + }); }); diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.tsx index 88bdb4bda775221cb2dc0ad3fbe4a5cb0d0da651..d87156efe2be89368063d16df26f41b49ced4d48 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.tsx @@ -1,8 +1,14 @@ import { Icon } from '@/shared/Icon'; import { PinDetailsItem } from '@/types/models'; import { twMerge } from 'tailwind-merge'; -import { PinTypeWithNone } from '../PinsList.types'; -import { getPinColor } from './PinsListItem.component.utils'; +import { useAppSelector } from '@/redux/hooks/useAppSelector'; +import { modelsDataSelector } from '@/redux/models/models.selectors'; +import { SIZE_OF_EMPTY_ARRAY } from '@/constants/common'; +import { useAppDispatch } from '@/redux/hooks/useAppDispatch'; +import { openMapAndSetActive, setActiveMap } from '@/redux/map/map.slice'; +import { mapOpenedMapsSelector } from '@/redux/map/map.selectors'; +import { getListOfAvailableSubmaps, getPinColor } from './PinsListItem.component.utils'; +import { AvailableSubmaps, PinTypeWithNone } from '../PinsList.types'; interface PinsListItemProps { name: string; @@ -11,6 +17,22 @@ interface PinsListItemProps { } export const PinsListItem = ({ name, type, pin }: PinsListItemProps): JSX.Element => { + const dispatch = useAppDispatch(); + const openedMaps = useAppSelector(mapOpenedMapsSelector); + const models = useAppSelector(modelsDataSelector); + const availableSubmaps = getListOfAvailableSubmaps(pin, models); + + const isMapAlreadyOpened = (modelId: number): boolean => + openedMaps.some(map => map.modelId === modelId); + + const onSubmapClick = (map: AvailableSubmaps): void => { + if (isMapAlreadyOpened(map.modelId)) { + dispatch(setActiveMap({ modelId: map.modelId })); + } else { + dispatch(openMapAndSetActive({ modelId: map.modelId, modelName: map.name })); + } + }; + return ( <div className="mb-4 flex w-full flex-col gap-3 rounded-lg border-[1px] border-solid border-greyscale-500 p-4"> <div className="flex w-full flex-row items-center gap-2"> @@ -52,6 +74,23 @@ export const PinsListItem = ({ name, type, pin }: PinsListItemProps): JSX.Elemen ); })} </ul> + {availableSubmaps.length > SIZE_OF_EMPTY_ARRAY && ( + <ul className="leading-6"> + <div className="mb-2 font-bold">Available in submaps:</div> + {availableSubmaps.map(submap => { + return ( + <button + onClick={(): void => onSubmapClick(submap)} + className="mb-2 mr-2 rounded border border-solid border-greyscale-500 p-2 font-normal text-[#6A6977] hover:border-[#6A6977]" + type="button" + key={submap.id} + > + {submap.name} + </button> + ); + })} + </ul> + )} </div> ); }; diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.utils.ts b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.utils.ts index 49c0547a9302b1b64f28e8822a5ade3e8a6a6654..f0775c25e6de370a0e0ace771cf6729bff5f4658 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.utils.ts +++ b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.utils.ts @@ -1,4 +1,7 @@ -import { PinTypeWithNone } from '../PinsList.types'; +import { MapModel, PinDetailsItem } from '@/types/models'; +import { AvailableSubmaps, PinTypeWithNone } from '../PinsList.types'; + +const MAIN_MAP_ID = 52; export const getPinColor = (type: PinTypeWithNone): string => { const pinColors: Record<PinTypeWithNone, string> = { @@ -10,3 +13,27 @@ export const getPinColor = (type: PinTypeWithNone): string => { return pinColors[type]; }; + +export const getListOfAvailableSubmaps = ( + pin: PinDetailsItem, + models: MapModel[], +): AvailableSubmaps[] => { + const submaps = pin.targetElements.filter((element, index) => { + return ( + index === + pin.targetElements.findIndex(o => element.model === o.model && element.model !== MAIN_MAP_ID) + ); + }); + + const availableSubmaps = submaps.map(submap => { + const data: AvailableSubmaps = { + id: submap.id, + modelId: submap.model, + name: models.find(model => model.idObject === submap.model)?.name || '', + }; + + return data; + }); + + return availableSubmaps; +};