Skip to content
Snippets Groups Projects
Commit 2b664a24 authored by Mateusz Bolewski's avatar Mateusz Bolewski
Browse files

Feature/search chemicals details

parent d9900888
No related branches found
No related tags found
2 merge requests!223reset the pin numbers before search results are fetch (so the results will be...,!55Feature/search chemicals details
......@@ -33,7 +33,7 @@ describe('DrugsAccordion - component', () => {
renderComponent({
chemicals: { data: chemicalsFixture, loading: 'succeeded', error: { name: '', message: '' } },
});
expect(screen.getByText('Chemicals (2)')).toBeInTheDocument();
expect(screen.getByText('Chemicals (4)')).toBeInTheDocument();
});
it('should display loading indicator while waiting for chemicals search response', () => {
renderComponent({
......
/* eslint-disable no-magic-numbers */
import { drugsFixture } from '@/models/fixtures/drugFixtures';
import { chemicalsFixture } from '@/models/fixtures/chemicalsFixture';
import { StoreType } from '@/redux/store';
import {
InitialStoreState,
getReduxWrapperWithStore,
} from '@/utils/testing/getReduxWrapperWithStore';
import { render, screen } from '@testing-library/react';
import { PinItem, PinType } from '../PinsList/PinsList.types';
import { AccordionsDetails } from './AccordionsDetails.component';
const PINS_LIST = drugsFixture.map(drug => ({
const DRUGS_PINS_LIST = drugsFixture.map(drug => ({
id: drug.id,
name: drug.name,
data: drug,
}));
const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => {
const CHEMICALS_PINS_LIST = chemicalsFixture.map(chemical => ({
id: chemical.id.id,
name: chemical.name,
data: chemical,
}));
const renderComponent = (
pinsList: PinItem[],
type: PinType,
initialStoreState: InitialStoreState = {},
): { store: StoreType } => {
const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState);
return (
render(
<Wrapper>
<AccordionsDetails pinsList={PINS_LIST} />
<AccordionsDetails pinsList={pinsList} type={type} />
</Wrapper>,
),
{
......@@ -31,21 +43,21 @@ const renderComponent = (initialStoreState: InitialStoreState = {}): { store: St
describe('AccordionsDetails - component', () => {
it('should display name of drug', () => {
renderComponent();
renderComponent(DRUGS_PINS_LIST, 'drugs');
const drugName = drugsFixture[0].name;
expect(screen.getByText(drugName, { exact: false })).toBeInTheDocument();
});
it('should display description of drug', () => {
renderComponent();
renderComponent(DRUGS_PINS_LIST, 'drugs');
const drugDescription = drugsFixture[0].description;
expect(screen.getByText(drugDescription, { exact: false })).toBeInTheDocument();
});
it('should display synonyms of drug', () => {
renderComponent();
renderComponent(DRUGS_PINS_LIST, 'drugs');
const firstDrugSynonym = drugsFixture[0].synonyms[0];
const secondDrugSynonym = drugsFixture[0].synonyms[1];
......@@ -53,11 +65,20 @@ describe('AccordionsDetails - component', () => {
expect(screen.getByText(firstDrugSynonym, { exact: false })).toBeInTheDocument();
expect(screen.getByText(secondDrugSynonym, { exact: false })).toBeInTheDocument();
});
it('should display additional info about drug', () => {
renderComponent();
it('should display blood brain barrier for drug', () => {
renderComponent(DRUGS_PINS_LIST, 'drugs');
const drugAdditionalInfo = drugsFixture[0].bloodBrainBarrier;
expect(screen.getByText(drugAdditionalInfo, { exact: false })).toBeInTheDocument();
});
it('should display direct evidence publications for chemicals', () => {
renderComponent(CHEMICALS_PINS_LIST, 'chemicals');
const chemicalsAdditionalInfo = chemicalsFixture[0].directEvidence
? chemicalsFixture[0].directEvidence
: '';
expect(screen.getAllByText(chemicalsAdditionalInfo, { exact: false })[0]).toBeInTheDocument();
});
});
......@@ -5,7 +5,7 @@ import {
AccordionItemHeading,
AccordionItemPanel,
} from '@/shared/Accordion';
import { PinItem } from '../PinsList/PinsList.types';
import { PinItem, PinType } from '../PinsList/PinsList.types';
import {
getAdditionalInfo,
getEntityDescriptions,
......@@ -15,15 +15,16 @@ import {
interface AccordionsDetailsProps {
pinsList: PinItem[];
type: PinType;
}
export const AccordionsDetails = ({ pinsList }: AccordionsDetailsProps): JSX.Element => {
export const AccordionsDetails = ({ pinsList, type }: AccordionsDetailsProps): JSX.Element => {
return (
<>
<Accordion allowZeroExpanded className="px-6">
<AccordionItem>
<AccordionItemHeading>
<AccordionItemButton>Drug</AccordionItemButton>
<AccordionItemButton className="capitalize">{type}</AccordionItemButton>
</AccordionItemHeading>
<AccordionItemPanel>{getEntityNames(pinsList)}</AccordionItemPanel>
</AccordionItem>
......@@ -40,10 +41,18 @@ export const AccordionsDetails = ({ pinsList }: AccordionsDetailsProps): JSX.Ele
<AccordionItemPanel>{getEntitySynonyms(pinsList)}</AccordionItemPanel>
</AccordionItem>
</Accordion>
<div className="flex justify-between px-6 py-4 text-sm font-bold">
<div>Blood brain barrier</div>
<div>{getAdditionalInfo(pinsList)}</div>
</div>
{type === 'drugs' && (
<div className="flex justify-between px-6 py-4 text-sm font-bold">
<div>Blood brain barrier</div>
<div>{getAdditionalInfo(pinsList, type)}</div>
</div>
)}
{type === 'chemicals' && (
<div className="flex justify-between px-6 py-4 text-sm">
<div className="font-bold">Direct Evidence Publications</div>
<div>{getAdditionalInfo(pinsList, type)}</div>
</div>
)}
</>
);
};
import { PinItem } from '../PinsList/PinsList.types';
import { PinItem, PinType } from '../PinsList/PinsList.types';
export const getEntityNames = (pinsList: PinItem[]): string => {
let name = '';
......@@ -34,14 +34,22 @@ export const getEntitySynonyms = (pinsList: PinItem[]): string => {
return synonyms;
};
export const getAdditionalInfo = (pinsList: PinItem[]): string => {
let additionalDetails = '';
pinsList.forEach(element => {
if ('bloodBrainBarrier' in element.data) {
additionalDetails += element.data.bloodBrainBarrier;
}
});
return additionalDetails;
export const getAdditionalInfo = (pinsList: PinItem[], type: PinType): string => {
if (type === 'drugs') {
return pinsList
.map(element => ('bloodBrainBarrier' in element.data ? element.data.bloodBrainBarrier : ''))
.join(', ');
}
if (type === 'chemicals') {
return pinsList
.map(element =>
'directEvidence' in element.data && element.data.directEvidence
? element.data.directEvidence
: 'No annotations',
)
.join(', ');
}
return '';
};
......@@ -13,7 +13,7 @@ export const PinsList = ({ pinsList, type }: PinsListProps): JSX.Element => {
case 'drugs':
return (
<div className="h-[calc(100vh-198px)] overflow-auto">
<AccordionsDetails pinsList={pinsList} />
<AccordionsDetails pinsList={pinsList} type={type} />
<ul className="px-6 py-2">
{pinsList.map(result => {
return result.data.targets.map(pin => (
......@@ -26,7 +26,18 @@ export const PinsList = ({ pinsList, type }: PinsListProps): JSX.Element => {
case 'bioEntity':
return <div />;
case 'chemicals':
return <div />;
return (
<div className="h-[calc(100vh-198px)] overflow-auto">
<AccordionsDetails pinsList={pinsList} type={type} />
<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} />
));
})}
</ul>
</div>
);
case 'mirna':
return (
<ul className="h-[calc(100vh-198px)] overflow-auto px-6 py-2">
......
......@@ -9,6 +9,10 @@ export const loadingChemicalsStatusSelector = createSelector(
state => state.loading,
);
export const numberOfChemicalsSelector = createSelector(chemicalsSelector, state =>
state.data ? state.data.length : SIZE_OF_EMPTY_ARRAY,
);
export const numberOfChemicalsSelector = createSelector(chemicalsSelector, state => {
if (!state.data) {
return SIZE_OF_EMPTY_ARRAY;
}
return state.data.length && state.data.map(e => e.targets.length)?.reduce((a, b) => a + b);
});
import { twMerge } from 'tailwind-merge';
import { AccordionItemButton as AIB } from 'react-accessible-accordion';
import './AccordionItemButton.style.css';
import { Variant } from './AccordionItemButton.types';
......@@ -8,6 +9,7 @@ type AccordionItemButtonProps = {
variant?: Variant;
onClick?: () => void;
disabled?: boolean;
className?: string;
};
export const AccordionItemButton = ({
......@@ -15,6 +17,7 @@ export const AccordionItemButton = ({
variant = 'expandable',
onClick,
disabled,
className,
}: AccordionItemButtonProps): JSX.Element => {
const ButtonIcon = getIcon(variant);
......@@ -23,7 +26,7 @@ export const AccordionItemButton = ({
<button
onClick={onClick}
disabled={disabled}
className="flex w-full flex-row flex-nowrap justify-between text-sm"
className={twMerge('flex w-full flex-row flex-nowrap justify-between text-sm', className)}
type="button"
data-testid="accordion-item-button"
>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment