Skip to content
Snippets Groups Projects
Commit dcc42dcf authored by Adrian Orłów's avatar Adrian Orłów :fire:
Browse files

Merge branch 'MIN-292-navigating-search-results-in-the-left-panel' into 'development'

fix: navigating search results in the left panel (MIN-292)

Closes MIN-292

See merge request !212
parents 6287d852 8eb96491
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...,!212fix: navigating search results in the left panel (MIN-292)
Pipeline #92637 passed
import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
import { bioEntitiesContentFixture } from '@/models/fixtures/bioEntityContentsFixture'; import { bioEntitiesContentFixture } from '@/models/fixtures/bioEntityContentsFixture';
import { MODELS_MOCK } from '@/models/mocks/modelsMock'; import { MODELS_MOCK } from '@/models/mocks/modelsMock';
import { StoreType } from '@/redux/store'; import { INITIAL_STORE_STATE_MOCK } from '@/redux/root/root.fixtures';
import { AppDispatch, RootState, StoreType } from '@/redux/store';
import { Accordion } from '@/shared/Accordion'; import { Accordion } from '@/shared/Accordion';
import { getReduxStoreWithActionsListener } from '@/utils/testing/getReduxStoreActionsListener';
import { import {
InitialStoreState, InitialStoreState,
getReduxWrapperWithStore, getReduxWrapperWithStore,
} from '@/utils/testing/getReduxWrapperWithStore'; } from '@/utils/testing/getReduxWrapperWithStore';
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import { MockStoreEnhanced } from 'redux-mock-store';
import { BioEntitiesAccordion } from './BioEntitiesAccordion.component'; import { BioEntitiesAccordion } from './BioEntitiesAccordion.component';
const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => { const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => {
...@@ -26,6 +30,25 @@ const renderComponent = (initialStoreState: InitialStoreState = {}): { store: St ...@@ -26,6 +30,25 @@ const renderComponent = (initialStoreState: InitialStoreState = {}): { store: St
); );
}; };
const renderComponentWithActionListener = (
initialStoreState: InitialStoreState = {},
): { store: MockStoreEnhanced<Partial<RootState>, AppDispatch> } => {
const { Wrapper, store } = getReduxStoreWithActionsListener(initialStoreState);
return (
render(
<Wrapper>
<Accordion>
<BioEntitiesAccordion />
</Accordion>
</Wrapper>,
),
{
store,
}
);
};
describe('BioEntitiesAccordion - component', () => { describe('BioEntitiesAccordion - component', () => {
it('should display loading indicator when bioEntity search is pending', () => { it('should display loading indicator when bioEntity search is pending', () => {
renderComponent({ renderComponent({
...@@ -77,4 +100,36 @@ describe('BioEntitiesAccordion - component', () => { ...@@ -77,4 +100,36 @@ describe('BioEntitiesAccordion - component', () => {
expect(screen.getByText('Histamine signaling (4)')).toBeInTheDocument(); expect(screen.getByText('Histamine signaling (4)')).toBeInTheDocument();
expect(screen.getByText('PRKN substrates (3)')).toBeInTheDocument(); expect(screen.getByText('PRKN substrates (3)')).toBeInTheDocument();
}); });
it('should fire toggleIsContentTabOpened on accordion item button click', () => {
const { store } = renderComponentWithActionListener({
...INITIAL_STORE_STATE_MOCK,
bioEntity: {
data: [
{
searchQueryElement: '',
loading: 'succeeded',
error: { name: '', message: '' },
data: bioEntitiesContentFixture,
},
],
loading: 'succeeded',
error: { name: '', message: '' },
isContentTabOpened: false,
},
models: {
data: MODELS_MOCK,
loading: 'succeeded',
error: { name: '', message: '' },
},
});
const button = screen.getByTestId('accordion-item-button');
button.click();
expect(store.getActions()[FIRST_ARRAY_ELEMENT]).toStrictEqual({
payload: true,
type: 'bioEntityContents/toggleIsContentTabOpened',
});
});
}); });
import {
bioEntitiesPerModelSelector,
bioEntityIsContentTabOpenedSelector,
loadingBioEntityStatusSelector,
numberOfBioEntitiesSelector,
} from '@/redux/bioEntity/bioEntity.selectors';
import { toggleIsContentTabOpened } from '@/redux/bioEntity/bioEntity.slice';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { import {
AccordionItem, AccordionItem,
AccordionItemButton, AccordionItemButton,
AccordionItemPanel,
AccordionItemHeading, AccordionItemHeading,
AccordionItemPanel,
} from '@/shared/Accordion'; } from '@/shared/Accordion';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import {
loadingBioEntityStatusSelector,
bioEntitiesPerModelSelector,
numberOfBioEntitiesSelector,
} from '@/redux/bioEntity/bioEntity.selectors';
import { BioEntitiesSubmapItem } from './BioEntitiesSubmapItem'; import { BioEntitiesSubmapItem } from './BioEntitiesSubmapItem';
export const BioEntitiesAccordion = (): JSX.Element => { export const BioEntitiesAccordion = (): JSX.Element => {
const dispatch = useAppDispatch();
const bioEntitiesNumber = useAppSelector(numberOfBioEntitiesSelector); const bioEntitiesNumber = useAppSelector(numberOfBioEntitiesSelector);
const bioEntitiesState = useAppSelector(loadingBioEntityStatusSelector); const bioEntitiesState = useAppSelector(loadingBioEntityStatusSelector);
const bioEntitiesPerModel = useAppSelector(bioEntitiesPerModelSelector); const bioEntitiesPerModel = useAppSelector(bioEntitiesPerModelSelector);
const isContentTabOpened = useAppSelector(bioEntityIsContentTabOpenedSelector);
const toggleTabOpened = (): void => {
dispatch(toggleIsContentTabOpened(!isContentTabOpened));
};
return ( return (
<AccordionItem> <AccordionItem dangerouslySetExpanded={isContentTabOpened}>
<AccordionItemHeading> <AccordionItemHeading>
<AccordionItemButton> <AccordionItemButton onClick={toggleTabOpened}>
Content {bioEntitiesState === 'pending' && ' (Loading...)'} Content {bioEntitiesState === 'pending' && ' (Loading...)'}
{bioEntitiesState === 'succeeded' && ` (${bioEntitiesNumber})`} {bioEntitiesState === 'succeeded' && ` (${bioEntitiesNumber})`}
</AccordionItemButton> </AccordionItemButton>
......
...@@ -20,4 +20,5 @@ export const BIOENTITY_INITIAL_STATE: BioEntityContentsState = { ...@@ -20,4 +20,5 @@ export const BIOENTITY_INITIAL_STATE: BioEntityContentsState = {
loading: 'idle', loading: 'idle',
error: { name: '', message: '' }, error: { name: '', message: '' },
submapConnections: BIOENTITY_SUBMAP_CONNECTIONS_INITIAL_STATE, submapConnections: BIOENTITY_SUBMAP_CONNECTIONS_INITIAL_STATE,
isContentTabOpened: false,
}; };
...@@ -6,8 +6,8 @@ import { ...@@ -6,8 +6,8 @@ import {
createStoreInstanceUsingSliceReducer, createStoreInstanceUsingSliceReducer,
} from '@/utils/createStoreInstanceUsingSliceReducer'; } from '@/utils/createStoreInstanceUsingSliceReducer';
import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse'; import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse';
import { HttpStatusCode } from 'axios';
import { unwrapResult } from '@reduxjs/toolkit'; import { unwrapResult } from '@reduxjs/toolkit';
import { HttpStatusCode } from 'axios';
import bioEntityContentsReducer from './bioEntity.slice'; import bioEntityContentsReducer from './bioEntity.slice';
import { getBioEntity } from './bioEntity.thunks'; import { getBioEntity } from './bioEntity.thunks';
import { BioEntityContentsState } from './bioEntity.types'; import { BioEntityContentsState } from './bioEntity.types';
...@@ -20,6 +20,7 @@ jest.mock('../../utils/error-report/errorReporting'); ...@@ -20,6 +20,7 @@ jest.mock('../../utils/error-report/errorReporting');
const INITIAL_STATE: BioEntityContentsState = { const INITIAL_STATE: BioEntityContentsState = {
data: [], data: [],
loading: 'idle', loading: 'idle',
isContentTabOpened: false,
error: { name: '', message: '' }, error: { name: '', message: '' },
submapConnections: { submapConnections: {
data: [], data: [],
......
import { DEFAULT_ERROR } from '@/constants/errors'; import { DEFAULT_ERROR } from '@/constants/errors';
import { ActionReducerMapBuilder } from '@reduxjs/toolkit'; import { ActionReducerMapBuilder, PayloadAction } from '@reduxjs/toolkit';
import { BIOENTITY_SUBMAP_CONNECTIONS_INITIAL_STATE } from './bioEntity.constants'; import { BIOENTITY_SUBMAP_CONNECTIONS_INITIAL_STATE } from './bioEntity.constants';
import { getBioEntity, getMultiBioEntity } from './bioEntity.thunks'; import { getBioEntity, getMultiBioEntity } from './bioEntity.thunks';
import { BioEntityContentsState } from './bioEntity.types'; import { BioEntityContentsState } from './bioEntity.types';
...@@ -86,3 +86,10 @@ export const clearBioEntitiesDataReducer = (state: BioEntityContentsState): void ...@@ -86,3 +86,10 @@ export const clearBioEntitiesDataReducer = (state: BioEntityContentsState): void
state.submapConnections = BIOENTITY_SUBMAP_CONNECTIONS_INITIAL_STATE; state.submapConnections = BIOENTITY_SUBMAP_CONNECTIONS_INITIAL_STATE;
}; };
export const toggleIsContentTabOpenedReducer = (
state: BioEntityContentsState,
action: PayloadAction<boolean>,
): void => {
state.isContentTabOpened = action.payload;
};
import { rootSelector } from '@/redux/root/root.selectors';
import { ONE, SIZE_OF_EMPTY_ARRAY, ZERO } from '@/constants/common'; import { ONE, SIZE_OF_EMPTY_ARRAY, ZERO } from '@/constants/common';
import { BioEntityWithPinType } from '@/types/bioEntity';
import { ElementIdTabObj } from '@/types/elements';
import { MultiSearchData } from '@/types/fetchDataState';
import { BioEntity, BioEntityContent, Comment, MapModel } from '@/types/models';
import { createSelector } from '@reduxjs/toolkit';
import { import {
allCommentsSelectorOfCurrentMap, allCommentsSelectorOfCurrentMap,
commentElementSelector, commentElementSelector,
} from '@/redux/comment/comment.selectors'; } from '@/redux/comment/comment.selectors';
import { currentDrawerReactionSelector } from '@/redux/reactions/reactions.selector'; import { currentDrawerReactionSelector } from '@/redux/reactions/reactions.selector';
import { rootSelector } from '@/redux/root/root.selectors';
import { BioEntityWithPinType } from '@/types/bioEntity';
import { ElementIdTabObj } from '@/types/elements';
import { MultiSearchData } from '@/types/fetchDataState';
import { BioEntity, BioEntityContent, Comment, MapModel } from '@/types/models';
import { createSelector } from '@reduxjs/toolkit';
import { import {
allChemicalsBioEntitesOfAllMapsSelector, allChemicalsBioEntitesOfAllMapsSelector,
allChemicalsBioEntitesOfCurrentMapSelector, allChemicalsBioEntitesOfCurrentMapSelector,
...@@ -35,6 +35,11 @@ export const bioEntitySelector = createSelector(rootSelector, state => state.bio ...@@ -35,6 +35,11 @@ export const bioEntitySelector = createSelector(rootSelector, state => state.bio
export const bioEntityDataSelector = createSelector(bioEntitySelector, bioEntity => bioEntity.data); export const bioEntityDataSelector = createSelector(bioEntitySelector, bioEntity => bioEntity.data);
export const bioEntityIsContentTabOpenedSelector = createSelector(
bioEntitySelector,
bioEntity => bioEntity.isContentTabOpened,
);
export const bioEntityLoadingSelector = createSelector( export const bioEntityLoadingSelector = createSelector(
bioEntitySelector, bioEntitySelector,
bioEntity => bioEntity.loading, bioEntity => bioEntity.loading,
......
...@@ -5,6 +5,7 @@ import { ...@@ -5,6 +5,7 @@ import {
getBioEntityContentsReducer, getBioEntityContentsReducer,
getMultiBioEntityContentsReducer, getMultiBioEntityContentsReducer,
getSubmapConnectionsBioEntityReducer, getSubmapConnectionsBioEntityReducer,
toggleIsContentTabOpenedReducer,
} from './bioEntity.reducers'; } from './bioEntity.reducers';
export const bioEntityContentsSlice = createSlice({ export const bioEntityContentsSlice = createSlice({
...@@ -12,6 +13,7 @@ export const bioEntityContentsSlice = createSlice({ ...@@ -12,6 +13,7 @@ export const bioEntityContentsSlice = createSlice({
initialState: BIOENTITY_INITIAL_STATE, initialState: BIOENTITY_INITIAL_STATE,
reducers: { reducers: {
clearBioEntitiesData: clearBioEntitiesDataReducer, clearBioEntitiesData: clearBioEntitiesDataReducer,
toggleIsContentTabOpened: toggleIsContentTabOpenedReducer,
}, },
extraReducers: builder => { extraReducers: builder => {
getBioEntityContentsReducer(builder); getBioEntityContentsReducer(builder);
...@@ -20,6 +22,6 @@ export const bioEntityContentsSlice = createSlice({ ...@@ -20,6 +22,6 @@ export const bioEntityContentsSlice = createSlice({
}, },
}); });
export const { clearBioEntitiesData } = bioEntityContentsSlice.actions; export const { clearBioEntitiesData, toggleIsContentTabOpened } = bioEntityContentsSlice.actions;
export default bioEntityContentsSlice.reducer; export default bioEntityContentsSlice.reducer;
...@@ -4,6 +4,7 @@ import { PayloadAction } from '@reduxjs/toolkit'; ...@@ -4,6 +4,7 @@ import { PayloadAction } from '@reduxjs/toolkit';
export type BioEntityContentsState = MultiFetchDataState<BioEntityContent[]> & { export type BioEntityContentsState = MultiFetchDataState<BioEntityContent[]> & {
submapConnections?: FetchDataState<BioEntityContent[]>; submapConnections?: FetchDataState<BioEntityContent[]>;
isContentTabOpened?: boolean;
}; };
export type BioEntityContentSearchQuery = { export type BioEntityContentSearchQuery = {
......
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