diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsList.component.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsList.component.tsx new file mode 100644 index 0000000000000000000000000000000000000000..b563e3f9b9e784e735317cc0ad3eb3f03c40dec0 --- /dev/null +++ b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsList.component.tsx @@ -0,0 +1,21 @@ +import { BioEntityContent } from '@/types/models'; +import { BioEntitiesPinsListItem } from './BioEntitiesPinsListItem'; + +interface BioEntitiesPinsListProps { + bioEnititesPins: BioEntityContent[]; +} + +export const BioEntitiesPinsList = ({ bioEnititesPins }: BioEntitiesPinsListProps): JSX.Element => { + return ( + <ul className="h-[calc(100vh-198px)] overflow-auto px-6 py-2"> + {bioEnititesPins && + bioEnititesPins.map(result => ( + <BioEntitiesPinsListItem + key={result.bioEntity.name} + name={result.bioEntity.name} + pin={result.bioEntity} + /> + ))} + </ul> + ); +}; diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/MirnaPinsListItem.component.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/BioEntitiesPinsListItem.component.tsx similarity index 50% rename from src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/MirnaPinsListItem.component.tsx rename to src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/BioEntitiesPinsListItem.component.tsx index ebd97b20c8f00a7d3b7f28de1cff7af0c6cf53c6..098abeeb3fd35d9161339421a9e6ae7282088353 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/MirnaPinsListItem.component.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/BioEntitiesPinsListItem.component.tsx @@ -1,40 +1,34 @@ import { twMerge } from 'tailwind-merge'; import { Icon } from '@/shared/Icon'; -import { MirnaItems } from '@/types/models'; -import { getPinColor } from './PinsListItem.component.utils'; -import { PinType } from '../PinsList.types'; +import { BioEntity } from '@/types/models'; +import { getPinColor } from '../../../ResultsList/PinsList/PinsListItem/PinsListItem.component.utils'; -interface MirnaPinsListItemProps { +interface BioEntitiesPinsListItemProps { name: string; - type: PinType; - pin: MirnaItems; + pin: BioEntity; } -export const MirnaPinsListItem = ({ name, type, pin }: MirnaPinsListItemProps): JSX.Element => { +export const BioEntitiesPinsListItem = ({ + name, + pin, +}: BioEntitiesPinsListItemProps): JSX.Element => { 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"> - <Icon name="pin" className={twMerge('mr-2 shrink-0', getPinColor(type))} /> + <Icon name="pin" className={twMerge('mr-2 shrink-0', getPinColor('bioEntity'))} /> <p> - Full name: <span className="w-full font-bold">{name}</span> + {pin.stringType}: <span className="w-full font-bold">{name}</span> </p> </div> - <ul className="leading-6"> - <div className="font-bold">Elements:</div> - {pin.targetParticipants.map(element => { - return ( - <li key={element.id} className="my-2 px-2"> - <a - href={element.link} - target="_blank" - className="cursor-pointer text-primary-500 underline" - > - {element.type} ({element.resource}) - </a> - </li> - ); - })} - </ul> + <p className="font-bold leading-6"> + Full name: <span className="w-full font-normal">{pin.fullName}</span> + </p> + <p className="font-bold leading-6"> + Symbol: <span className="w-full font-normal">{pin.symbol}</span> + </p> + <p className="font-bold leading-6"> + Synonyms: <span className="w-full font-normal">{pin.synonyms.join(', ')}</span> + </p> <ul className="leading-6"> <div className="font-bold">References:</div> {pin.references.map(reference => { diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/index.ts b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..ddb7a15384875b7d8c417354a1c35a1132107cda --- /dev/null +++ b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/index.ts @@ -0,0 +1 @@ +export { BioEntitiesPinsListItem } from './BioEntitiesPinsListItem.component'; diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/index.ts b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..fd4bb8c7e0130036cfc409358643811d1238a62d --- /dev/null +++ b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/index.ts @@ -0,0 +1 @@ +export { BioEntitiesPinsList } from './BioEntitiesPinsList.component'; diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesResultsList.component.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesResultsList.component.tsx new file mode 100644 index 0000000000000000000000000000000000000000..6960843cdb860faa0f52381f912d47e8cff5f616 --- /dev/null +++ b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesResultsList.component.tsx @@ -0,0 +1,28 @@ +import { useAppSelector } from '@/redux/hooks/useAppSelector'; +import { bioEnititiesResultListSelector } from '@/redux/drawer/drawer.selectors'; +import { DrawerHeadingBackwardButton } from '@/shared/DrawerHeadingBackwardButton'; +import { useAppDispatch } from '@/redux/hooks/useAppDispatch'; +import { displayGroupedSearchResults } from '@/redux/drawer/drawer.slice'; +import { searchValueSelector } from '@/redux/search/search.selectors'; +import { BioEntitiesPinsList } from './BioEntitiesPinsList'; + +export const BioEntitiesResultsList = (): JSX.Element => { + const dispatch = useAppDispatch(); + const bioEntityData = useAppSelector(bioEnititiesResultListSelector); + const searchValue = useAppSelector(searchValueSelector); + + const navigateToGroupedSearchResults = (): void => { + dispatch(displayGroupedSearchResults()); + }; + + return ( + <div> + <DrawerHeadingBackwardButton + title="BioEntity" + value={searchValue} + backwardFunction={navigateToGroupedSearchResults} + /> + <BioEntitiesPinsList bioEnititesPins={bioEntityData} /> + </div> + ); +}; diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/index.ts b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..4fc0f85b9b58d8e7993b604157362e20f197233a --- /dev/null +++ b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/index.ts @@ -0,0 +1 @@ +export { BioEntitiesResultsList } from './BioEntitiesResultsList.component'; diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/GroupedSearchResults/BioEntitiesAccordion/BioEntitiesAccordion.component.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/GroupedSearchResults/BioEntitiesAccordion/BioEntitiesAccordion.component.tsx index 081247d86a38000347a6de859b5f7b820590542a..6ca6a4423f0a6014173b44b20f1b2fdb4c957d1f 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/GroupedSearchResults/BioEntitiesAccordion/BioEntitiesAccordion.component.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/GroupedSearchResults/BioEntitiesAccordion/BioEntitiesAccordion.component.tsx @@ -9,14 +9,14 @@ import { BioEntitiesSubmapItem } from '@/components/Map/Drawer/SearchDrawerWrapp import { useAppSelector } from '@/redux/hooks/useAppSelector'; import { loadingBioEntityStatusSelector, - numberOfBioEntitiesPerModelSelector, + bioEntitiesPerModelSelector, numberOfBioEntitiesSelector, } from '@/redux/bioEntity/bioEntity.selectors'; export const BioEntitiesAccordion = (): JSX.Element => { const bioEntitiesNumber = useAppSelector(numberOfBioEntitiesSelector); const bioEntitiesState = useAppSelector(loadingBioEntityStatusSelector); - const numberOfBioEntitiesPerModel = useAppSelector(numberOfBioEntitiesPerModelSelector); + const bioEntitiesPerModel = useAppSelector(bioEntitiesPerModelSelector); return ( <AccordionItem> @@ -27,11 +27,12 @@ export const BioEntitiesAccordion = (): JSX.Element => { </AccordionItemButton> </AccordionItemHeading> <AccordionItemPanel> - {numberOfBioEntitiesPerModel.map(model => ( + {bioEntitiesPerModel.map(model => ( <BioEntitiesSubmapItem key={model.modelName} mapName={model.modelName} numberOfEntities={model.numberOfEntities} + bioEntities={model.bioEntities} /> ))} </AccordionItemPanel> diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/GroupedSearchResults/BioEntitiesAccordion/BioEntitiesSubmapItem/BioEntitiesSubmapItem.component.test.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/GroupedSearchResults/BioEntitiesAccordion/BioEntitiesSubmapItem/BioEntitiesSubmapItem.component.test.tsx index 48c8a2ebb887deb97b97aafb3c96b1d84e7c95e8..bd7472d6dc441cf0d4dce7a4913ea5af04a3ebea 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/GroupedSearchResults/BioEntitiesAccordion/BioEntitiesSubmapItem/BioEntitiesSubmapItem.component.test.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/GroupedSearchResults/BioEntitiesAccordion/BioEntitiesSubmapItem/BioEntitiesSubmapItem.component.test.tsx @@ -1,15 +1,34 @@ -import { render, RenderResult, screen } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; +import { StoreType } from '@/redux/store'; +import { bioEntitiesContentFixture } from '@/models/fixtures/bioEntityContentsFixture'; import { - BioEntitiesSubmapItem, - BioEntitiesSubmapItemProps, -} from './BioEntitiesSubmapItem.component'; + InitialStoreState, + getReduxWrapperWithStore, +} from '@/utils/testing/getReduxWrapperWithStore'; +import { BioEntitiesSubmapItem } from './BioEntitiesSubmapItem.component'; -const renderComponent = ({ mapName, numberOfEntities }: BioEntitiesSubmapItemProps): RenderResult => - render(<BioEntitiesSubmapItem mapName={mapName} numberOfEntities={numberOfEntities} />); +const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => { + const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState); + + return ( + render( + <Wrapper> + <BioEntitiesSubmapItem + mapName="main map" + numberOfEntities={21} + bioEntities={bioEntitiesContentFixture} + /> + </Wrapper>, + ), + { + store, + } + ); +}; describe('BioEntitiesSubmapItem - component', () => { it('should display map name,number of elements, icon', () => { - renderComponent({ mapName: 'main map', numberOfEntities: 21 }); + renderComponent(); expect(screen.getByText('main map (21)')).toBeInTheDocument(); }); diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/GroupedSearchResults/BioEntitiesAccordion/BioEntitiesSubmapItem/BioEntitiesSubmapItem.component.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/GroupedSearchResults/BioEntitiesAccordion/BioEntitiesSubmapItem/BioEntitiesSubmapItem.component.tsx index 8ee1caedf79bb47f9972697a170ef38cc0dbcc2d..49d8fc3ba42c9f5ef32e2ef656cc7b4ba0e6a4a2 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/GroupedSearchResults/BioEntitiesAccordion/BioEntitiesSubmapItem/BioEntitiesSubmapItem.component.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/GroupedSearchResults/BioEntitiesAccordion/BioEntitiesSubmapItem/BioEntitiesSubmapItem.component.tsx @@ -1,18 +1,35 @@ import { Icon } from '@/shared/Icon'; +import { displayBioEntitiesList } from '@/redux/drawer/drawer.slice'; +import { useAppDispatch } from '@/redux/hooks/useAppDispatch'; +import { BioEntityContent } from '@/types/models'; export interface BioEntitiesSubmapItemProps { mapName: string; numberOfEntities: string | number; + bioEntities: BioEntityContent[]; } export const BioEntitiesSubmapItem = ({ mapName, numberOfEntities, -}: BioEntitiesSubmapItemProps): JSX.Element => ( - <div className="flex flex-row flex-nowrap justify-between pl-6 [&:not(:last-of-type)]:pb-4"> - <p> - {mapName} ({numberOfEntities}) - </p> - <Icon name="arrow" className="h-6 w-6 fill-font-500" /> - </div> -); + bioEntities, +}: BioEntitiesSubmapItemProps): JSX.Element => { + const dispatch = useAppDispatch(); + + const onSubmapClick = (): void => { + dispatch(displayBioEntitiesList(bioEntities)); + }; + + return ( + <button + onClick={onSubmapClick} + type="button" + className="flex flex-row flex-nowrap items-center justify-between pl-6 [&:not(:last-of-type)]:pb-4" + > + <p className="text-sm font-normal"> + {mapName} ({numberOfEntities}) + </p> + <Icon name="arrow" className="h-6 w-6 fill-font-500" /> + </button> + ); +}; diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsList.component.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsList.component.tsx index 95f53e4fb1abecd24bf6aded02e864041e49b918..b3b3a7c5459476fdd50e1fdd4e1ba59da7000d59 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsList.component.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsList.component.tsx @@ -1,7 +1,7 @@ import { assertNever } from '@/utils/assertNever'; import { AccordionsDetails } from '../AccordionsDetails/AccordionsDetails.component'; import { PinItem, PinType } from './PinsList.types'; -import { MirnaPinsListItem } from './PinsListItem'; +import { PinsListItem } from './PinsListItem'; interface PinsListProps { pinsList: PinItem[]; @@ -17,7 +17,7 @@ export const PinsList = ({ pinsList, type }: PinsListProps): JSX.Element => { <ul className="px-6 py-2"> {pinsList.map(result => { return result.data.targets.map(pin => ( - <MirnaPinsListItem key={pin.name} name={pin.name} type={type} pin={pin} /> + <PinsListItem key={pin.name} name={pin.name} type={type} pin={pin} /> )); })} </ul> @@ -32,7 +32,7 @@ export const PinsList = ({ pinsList, type }: PinsListProps): JSX.Element => { <ul className="px-6 py-2"> {pinsList.map(result => { return result.data.targets.map(pin => ( - <MirnaPinsListItem key={pin.name} name={pin.name} type={type} pin={pin} /> + <PinsListItem key={pin.name} name={pin.name} type={type} pin={pin} /> )); })} </ul> @@ -43,7 +43,7 @@ export const PinsList = ({ pinsList, type }: PinsListProps): JSX.Element => { <ul className="h-[calc(100vh-198px)] overflow-auto px-6 py-2"> {pinsList.map(result => { return result.data.targets.map(pin => ( - <MirnaPinsListItem key={pin.name} name={pin.name} type={type} pin={pin} /> + <PinsListItem key={pin.name} name={pin.name} type={type} pin={pin} /> )); })} </ul> 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 ae58c0eae102094aa29f85a315b97d57fe326dee..6225c84dbc14dd587f243c9b4f65de83a2e7620f 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,22 +1,57 @@ import { twMerge } from 'tailwind-merge'; import { Icon } from '@/shared/Icon'; +import { PinDetailsItem } from '@/types/models'; import { getPinColor } from './PinsListItem.component.utils'; import { PinType } from '../PinsList.types'; -interface PinsListItemProps { +interface MirnaPinsListItemProps { name: string; type: PinType; - onClick: () => void; + pin: PinDetailsItem; } -export const PinsListItem = ({ name, type, onClick }: PinsListItemProps): JSX.Element => ( - <button - className="flex w-full flex-row items-center justify-between pt-4" - onClick={onClick} - type="button" - > - <Icon name="pin" className={twMerge('mr-2 shrink-0', getPinColor(type))} /> - <p className="w-full text-left">{name}</p> - <Icon name="chevron-right" className="h-6 w-6 shrink-0" /> - </button> -); +export const PinsListItem = ({ name, type, pin }: MirnaPinsListItemProps): JSX.Element => { + 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"> + <Icon name="pin" className={twMerge('mr-2 shrink-0', getPinColor(type))} /> + <p> + Full name: <span className="w-full font-bold">{name}</span> + </p> + </div> + <ul className="leading-6"> + <div className="font-bold">Elements:</div> + {'targetParticipants' in pin && + pin.targetParticipants.map(element => { + return ( + <li key={element.id} className="my-2 px-2"> + <a + href={element.link} + target="_blank" + className="cursor-pointer text-primary-500 underline" + > + {element.type} ({element.resource}) + </a> + </li> + ); + })} + </ul> + <ul className="leading-6"> + <div className="font-bold">References:</div> + {pin.references.map(reference => { + return ( + <li key={reference.id} className="my-2 px-2"> + <a + href={reference.article?.link} + target="_blank" + className="cursor-pointer text-primary-500 underline" + > + {reference.type} ({reference.resource}) + </a> + </li> + ); + })} + </ul> + </div> + ); +}; diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/index.ts b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/index.ts index bae1522bf7880387fdfe76183d5557f743d4ef34..89b9aebca900ed5e4282564c6b0221ff861325d5 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/index.ts +++ b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/index.ts @@ -1,2 +1 @@ export { PinsListItem } from './PinsListItem.component'; -export { MirnaPinsListItem } from './MirnaPinsListItem.component'; diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/ResultsList.component.test.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/ResultsList.component.test.tsx index c6c94821d33764ff3bc1f385e2d147f91b197c64..b11dfdebadff9fd0248d74ec56ed359c721e13fd 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/ResultsList.component.test.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/ResultsList.component.test.tsx @@ -20,6 +20,7 @@ const INITIAL_STATE: InitialStoreState = { currentStep: 2, stepType: 'drugs', selectedValue: undefined, + listOfBioEnitites: [], }, }, drugs: { diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/SearchDrawerWrapper.component.test.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/SearchDrawerWrapper.component.test.tsx index 6322951135c2f2c34a38c96226e93783a3af004b..5938b15b4f44202aff293f803d8cc3c7c3b46624 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/SearchDrawerWrapper.component.test.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/SearchDrawerWrapper.component.test.tsx @@ -1,6 +1,4 @@ import { SearchDrawerWrapper } from '@/components/Map/Drawer/SearchDrawerWrapper'; -import { bioEntityContentFixture } from '@/models/fixtures/bioEntityContentsFixture'; -import { drugFixture } from '@/models/fixtures/drugFixtures'; import { drawerSearchStepOneFixture } from '@/redux/drawer/drawerFixture'; import { StoreType } from '@/redux/store'; import { @@ -42,6 +40,7 @@ describe('SearchDrawerWrapper - component', () => { currentStep: 2, stepType: 'bioEntity', selectedValue: undefined, + listOfBioEnitites: [], }, }, }); @@ -58,42 +57,11 @@ describe('SearchDrawerWrapper - component', () => { currentStep: 2, stepType: 'drugs', selectedValue: undefined, + listOfBioEnitites: [], }, }, }); expect(screen.getByTestId('search-second-step')).toBeInTheDocument(); }); - - it('should display the third step for value type bioEntity', () => { - renderComponent({ - drawer: { - isOpen: true, - drawerName: 'search', - searchDrawerState: { - currentStep: 3, - stepType: 'bioEntity', - selectedValue: bioEntityContentFixture, - }, - }, - }); - - expect(screen.getByTestId('search-third-step')).toBeInTheDocument(); - }); - - it('should display the third step for value type drugs', () => { - renderComponent({ - drawer: { - isOpen: true, - drawerName: 'search', - searchDrawerState: { - currentStep: 3, - stepType: 'drugs', - selectedValue: drugFixture, - }, - }, - }); - - expect(screen.getByTestId('search-third-step')).toBeInTheDocument(); - }); }); diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/SearchDrawerWrapper.component.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/SearchDrawerWrapper.component.tsx index 23aa97631a454e639c903932d0b297ad644b60ce..280330ea4dfe137b51786c272957de30858dea68 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/SearchDrawerWrapper.component.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/SearchDrawerWrapper.component.tsx @@ -7,6 +7,7 @@ import { import { useSelector } from 'react-redux'; import { ResultsList } from '@/components/Map/Drawer/SearchDrawerWrapper/ResultsList'; import { GroupedSearchResults } from '@/components/Map/Drawer/SearchDrawerWrapper/GroupedSearchResults'; +import { BioEntitiesResultsList } from './BioEntitiesResultsList'; export const SearchDrawerWrapper = (): JSX.Element => { const currentStep = useSelector(currentStepDrawerStateSelector); @@ -21,7 +22,9 @@ export const SearchDrawerWrapper = (): JSX.Element => { {currentStep === STEP.FIRST && <GroupedSearchResults />} {/* 2nd step for bioEntities aka content */} {currentStep === STEP.SECOND && isBioEntityType && ( - <div data-testid="search-second-step">The second step</div> + <div data-testid="search-second-step"> + <BioEntitiesResultsList /> + </div> )} {/* 2nd step for drugs,chemicals,mirna */} {currentStep === STEP.SECOND && isChemicalsDrugsOrMirnaType && ( @@ -29,14 +32,6 @@ export const SearchDrawerWrapper = (): JSX.Element => { <ResultsList /> </div> )} - {/* last step for bioentity */} - {currentStep === STEP.THIRD && isBioEntityType && ( - <div data-testid="search-third-step">The third step</div> - )} - {/* last step for drugs,chemicals,mirna */} - {currentStep === STEP.THIRD && isChemicalsDrugsOrMirnaType && ( - <div data-testid="search-third-step">The third step</div> - )} </div> ); }; diff --git a/src/redux/bioEntity/bioEntity.selectors.ts b/src/redux/bioEntity/bioEntity.selectors.ts index dac3b8c71cb696d8c9a2bd6289f35aa7df5dfccd..941dfb6ea540d7a174833dd105e031ed5a767985 100644 --- a/src/redux/bioEntity/bioEntity.selectors.ts +++ b/src/redux/bioEntity/bioEntity.selectors.ts @@ -22,21 +22,23 @@ export const numberOfBioEntitiesSelector = createSelector(bioEntitySelector, sta state.data ? state.data.length : SIZE_OF_EMPTY_ARRAY, ); -export const numberOfBioEntitiesPerModelSelector = createSelector(rootSelector, state => { +export const bioEntitiesPerModelSelector = createSelector(rootSelector, state => { const { models, bioEntity: { data: bioEntities }, } = state; - const numberOfBioEntitiesPerModel = (models.data || []).map(model => { + const bioEntitiesPerModel = (models.data || []).map(model => { const bioEntitiesInGivenModel = (bioEntities || []).filter( entity => model.idObject === entity.bioEntity.model, ); - return { modelName: model.name, numberOfEntities: bioEntitiesInGivenModel.length }; + return { + modelName: model.name, + numberOfEntities: bioEntitiesInGivenModel.length, + bioEntities: bioEntitiesInGivenModel, + }; }); - return numberOfBioEntitiesPerModel.filter( - model => model.numberOfEntities !== SIZE_OF_EMPTY_ARRAY, - ); + return bioEntitiesPerModel.filter(model => model.numberOfEntities !== SIZE_OF_EMPTY_ARRAY); }); diff --git a/src/redux/drawer/drawer.reducers.test.ts b/src/redux/drawer/drawer.reducers.test.ts index a4a172f27d699a73c645d83d48c74ba37af4b52f..c275ef7ad6aa9ec8479d0c3df9c81bf90ab3e628 100644 --- a/src/redux/drawer/drawer.reducers.test.ts +++ b/src/redux/drawer/drawer.reducers.test.ts @@ -21,6 +21,7 @@ const INITIAL_STATE: DrawerState = { currentStep: 0, stepType: 'none', selectedValue: undefined, + listOfBioEnitites: [], }, }; diff --git a/src/redux/drawer/drawer.reducers.ts b/src/redux/drawer/drawer.reducers.ts index 8efdb78007bef6b3c4d22105975d2077cd8c63e6..87675251d7a296c19649a31ae80da4632b03282d 100644 --- a/src/redux/drawer/drawer.reducers.ts +++ b/src/redux/drawer/drawer.reducers.ts @@ -45,6 +45,16 @@ export const displayMirnaListReducer = (state: DrawerState): void => { state.searchDrawerState.stepType = 'mirna'; }; +export const displayBioEntitiesListReducer = ( + state: DrawerState, + action: PayloadAction<DrawerState['searchDrawerState']['listOfBioEnitites']>, +): void => { + state.drawerName = 'search'; + state.searchDrawerState.currentStep = STEP.SECOND; + state.searchDrawerState.listOfBioEnitites = action.payload; + state.searchDrawerState.stepType = 'bioEntity'; +}; + export const displayGroupedSearchResultsReducer = (state: DrawerState): void => { state.searchDrawerState.currentStep = STEP.FIRST; state.searchDrawerState.stepType = 'none'; diff --git a/src/redux/drawer/drawer.selectors.ts b/src/redux/drawer/drawer.selectors.ts index 6c8a5e3adf0a2669edb07e363c882e135e964aca..c140fbd73cb1d7b46099109150137c2bd69d437b 100644 --- a/src/redux/drawer/drawer.selectors.ts +++ b/src/redux/drawer/drawer.selectors.ts @@ -56,3 +56,7 @@ export const resultListSelector = createSelector(rootSelector, state => { return assertNever(selectedType); } }); + +export const bioEnititiesResultListSelector = createSelector(rootSelector, state => { + return state.drawer.searchDrawerState.listOfBioEnitites; +}); diff --git a/src/redux/drawer/drawer.slice.ts b/src/redux/drawer/drawer.slice.ts index 612009e1a9173bab17c6c8e8b9555c17edc1a3ce..de472f28b44574c899521b6d18a68a1128f0e6c7 100644 --- a/src/redux/drawer/drawer.slice.ts +++ b/src/redux/drawer/drawer.slice.ts @@ -2,6 +2,7 @@ import { DrawerState } from '@/redux/drawer/drawer.types'; import { createSlice } from '@reduxjs/toolkit'; import { closeDrawerReducer, + displayBioEntitiesListReducer, displayChemicalsListReducer, displayDrugsListReducer, displayEntityDetailsReducer, @@ -19,6 +20,7 @@ const initialState: DrawerState = { currentStep: 0, stepType: 'none', selectedValue: undefined, + listOfBioEnitites: [], }, }; @@ -33,6 +35,7 @@ const drawerSlice = createSlice({ displayDrugsList: displayDrugsListReducer, displayChemicalsList: displayChemicalsListReducer, displayMirnaList: displayMirnaListReducer, + displayBioEntitiesList: displayBioEntitiesListReducer, displayGroupedSearchResults: displayGroupedSearchResultsReducer, displayEntityDetails: displayEntityDetailsReducer, }, @@ -46,6 +49,7 @@ export const { displayDrugsList, displayChemicalsList, displayMirnaList, + displayBioEntitiesList, displayGroupedSearchResults, displayEntityDetails, } = drawerSlice.actions; diff --git a/src/redux/drawer/drawer.types.ts b/src/redux/drawer/drawer.types.ts index e39ff163a7d9ac9eb764d1228e4cc58e50e4e422..7e4a14b1310a81acbdfe3f2c51b90ac7d4cedb39 100644 --- a/src/redux/drawer/drawer.types.ts +++ b/src/redux/drawer/drawer.types.ts @@ -5,6 +5,7 @@ export type SearchDrawerState = { currentStep: number; stepType: 'bioEntity' | 'drugs' | 'mirna' | 'chemicals' | 'none'; selectedValue: BioEntityContent | Drug | Mirna | Chemical | undefined; + listOfBioEnitites: BioEntityContent[]; }; export type DrawerState = { diff --git a/src/redux/drawer/drawerFixture.ts b/src/redux/drawer/drawerFixture.ts index 987c01d30345dc72d97f44b28cd5281a2474033e..6d1306b1504c2718b09d6a92f15d2970ec78a572 100644 --- a/src/redux/drawer/drawerFixture.ts +++ b/src/redux/drawer/drawerFixture.ts @@ -7,6 +7,7 @@ export const initialStateFixture: DrawerState = { currentStep: 0, stepType: 'none', selectedValue: undefined, + listOfBioEnitites: [], }, }; @@ -17,6 +18,7 @@ export const openedDrawerSubmapsFixture: DrawerState = { currentStep: 0, stepType: 'none', selectedValue: undefined, + listOfBioEnitites: [], }, }; @@ -27,6 +29,7 @@ export const drawerSearchStepOneFixture: DrawerState = { currentStep: 1, stepType: 'none', selectedValue: undefined, + listOfBioEnitites: [], }, }; @@ -37,5 +40,6 @@ export const drawerSearchDrugsStepTwoFixture: DrawerState = { currentStep: 2, stepType: 'drugs', selectedValue: undefined, + listOfBioEnitites: [], }, }; diff --git a/src/redux/drugs/drugs.selectors.ts b/src/redux/drugs/drugs.selectors.ts index af9a8d7fa58659446deb5e8685b489cc67cfdcbf..e999bf835d46b40c6607d6f31bb22cf51899b4fd 100644 --- a/src/redux/drugs/drugs.selectors.ts +++ b/src/redux/drugs/drugs.selectors.ts @@ -10,11 +10,5 @@ export const numberOfDrugsSelector = createSelector(drugsSelector, state => { return SIZE_OF_EMPTY_ARRAY; } - let numberOfDrugs = 0; - - state.data.forEach(element => { - numberOfDrugs += element.targets.length; - }); - - return numberOfDrugs; + return state.data.length && state.data.map(e => e.targets.length)?.reduce((a, b) => a + b); }); diff --git a/src/redux/mirnas/mirnas.selectors.ts b/src/redux/mirnas/mirnas.selectors.ts index 6460f8b818d8a42329c6f0e7a4086394ceaf1a32..29020f54aa404bb365e3fd4a2f3449931f927831 100644 --- a/src/redux/mirnas/mirnas.selectors.ts +++ b/src/redux/mirnas/mirnas.selectors.ts @@ -10,11 +10,5 @@ export const numberOfMirnasSelector = createSelector(mirnasSelector, state => { return SIZE_OF_EMPTY_ARRAY; } - let numberOfMirnas = 0; - - state.data.forEach(element => { - numberOfMirnas += element.targets.length; - }); - - return numberOfMirnas; + return state.data.length && state.data.map(e => e.targets.length)?.reduce((a, b) => a + b); }); diff --git a/src/types/models.ts b/src/types/models.ts index 38b9e6b3b02c92a5de57a41fea8c27bacb411fe4..2033c775a05a4431881a77f1f7c450d299ca244a 100644 --- a/src/types/models.ts +++ b/src/types/models.ts @@ -25,7 +25,7 @@ export type Organism = z.infer<typeof organism>; export type Disease = z.infer<typeof disease>; export type Drug = z.infer<typeof drugSchema>; export type Mirna = z.infer<typeof mirnaSchema>; -export type MirnaItems = z.infer<typeof targetSchema>; +export type PinDetailsItem = z.infer<typeof targetSchema>; export type BioEntity = z.infer<typeof bioEntitySchema>; export type BioEntityContent = z.infer<typeof bioEntityContentSchema>; export type BioEntityResponse = z.infer<typeof bioEntityResponseSchema>; diff --git a/yarn.lock b/yarn.lock index 3ba2ee3e331785c9cd9c4f37c51d09a81789e163..d403655e3377f5c0dc897ba526a0756ced375814 100644 --- a/yarn.lock +++ b/yarn.lock @@ -847,9 +847,9 @@ "resolved" "https://registry.npmjs.org/@next/font/-/font-13.5.4.tgz" "version" "13.5.4" -"@next/swc-darwin-arm64@13.4.19": - "integrity" "sha512-vv1qrjXeGbuF2mOkhkdxMDtv9np7W4mcBtaDnHU+yJG+bBwa6rYsYSCI/9Xm5+TuF5SbZbrWO6G1NfTh1TMjvQ==" - "resolved" "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.19.tgz" +"@next/swc-darwin-x64@13.4.19": + "integrity" "sha512-jyzO6wwYhx6F+7gD8ddZfuqO4TtpJdw3wyOduR4fxTUCm3aLw7YmHGYNjS0xRSYGAkLpBkH1E0RcelyId6lNsw==" + "resolved" "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.19.tgz" "version" "13.4.19" "@nodelib/fs.scandir@2.1.5":