From ab2c7a706d8f452a1585c577a0881426820dc2f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tadeusz=20Miesi=C4=85c?= <tadeusz.miesiac@gmail.com> Date: Thu, 12 Oct 2023 21:16:07 +0800 Subject: [PATCH] feat(results 2nd step): created dummy component for results --- Group.svg | 4 ++ src/assets/vectors/icons/Group.svg | 5 ++ .../Results/PinsList/PinsList.component.tsx | 14 ++++ .../Results/PinsList/PinsList.types.tsx | 3 + .../PinsListItem/PinsListItem.component.tsx | 13 ++++ .../Results/PinsList/PinsListItem/index.ts | 1 + .../Results/PinsList/index.ts | 1 + .../Results/Results.component.tsx | 26 ++++++++ .../SearchDrawerContent/Results/index.ts | 1 + src/redux/store.ts | 1 + ...erHeadingBackwardButton.component.test.tsx | 65 +++++++++++++++++++ .../DrawerHeadingBackwardButton.component.tsx | 53 +++++++++++++++ .../DrawerHeadingBackwardButton/index.ts | 1 + src/shared/Icon/Icon.component.tsx | 2 + src/shared/Icon/Icons/PinOrance.tsx | 20 ++++++ src/types/iconTypes.ts | 3 +- src/utils/getReduxWrapperWithStore.tsx | 61 +++++++++++++++++ 17 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 Group.svg create mode 100644 src/assets/vectors/icons/Group.svg create mode 100644 src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsList.component.tsx create mode 100644 src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsList.types.tsx create mode 100644 src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsListItem/PinsListItem.component.tsx create mode 100644 src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsListItem/index.ts create mode 100644 src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/index.ts create mode 100644 src/components/Map/Drawer/SearchDrawerContent/Results/Results.component.tsx create mode 100644 src/components/Map/Drawer/SearchDrawerContent/Results/index.ts create mode 100644 src/shared/DrawerHeadingBackwardButton/DrawerHeadingBackwardButton.component.test.tsx create mode 100644 src/shared/DrawerHeadingBackwardButton/DrawerHeadingBackwardButton.component.tsx create mode 100644 src/shared/DrawerHeadingBackwardButton/index.ts create mode 100644 src/shared/Icon/Icons/PinOrance.tsx create mode 100644 src/utils/getReduxWrapperWithStore.tsx diff --git a/Group.svg b/Group.svg new file mode 100644 index 00000000..6c9f4a0e --- /dev/null +++ b/Group.svg @@ -0,0 +1,4 @@ +<svg width="18" height="24" viewBox="0 0 18 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M9 0C4.575 0 0 3.375 0 9C0 14.325 8.1 22.65 8.475 23.025C8.625 23.175 8.775 23.25 9 23.25C9.225 23.25 9.375 23.175 9.525 23.025C9.9 22.65 18 14.4 18 9C18 3.375 13.425 0 9 0ZM9 12C7.35 12 6 10.65 6 9C6 7.35 7.35 6 9 6C10.65 6 12 7.35 12 9C12 10.65 10.65 12 9 12Z" fill="#E17221"/> +<circle cx="9.0002" cy="8.99922" r="4.8" fill="#E17221"/> +</svg> diff --git a/src/assets/vectors/icons/Group.svg b/src/assets/vectors/icons/Group.svg new file mode 100644 index 00000000..6d6e49d3 --- /dev/null +++ b/src/assets/vectors/icons/Group.svg @@ -0,0 +1,5 @@ +<svg width="18" height="24" viewBox="0 0 18 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M9 0C4.575 0 0 3.375 0 9C0 14.325 8.1 22.65 8.475 23.025C8.625 23.175 8.775 23.25 9 23.25C9.225 23.25 9.375 23.175 9.525 23.025C9.9 22.65 18 14.4 18 9C18 3.375 13.425 0 9 0ZM9 12C7.35 12 6 10.65 6 9C6 7.35 7.35 6 9 6C10.65 6 12 7.35 12 9C12 10.65 10.65 12 9 12Z" fill="#E17221"/> +<circle cx="9.0002" cy="8.99922" r="4.8" fill="#E17221"/> +<path d="M8.846 15V7.344L7.22 8.322V7.332L8.846 6.36H9.74V15H8.846Z" fill="white"/> +</svg> diff --git a/src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsList.component.tsx b/src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsList.component.tsx new file mode 100644 index 00000000..2678ebb1 --- /dev/null +++ b/src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsList.component.tsx @@ -0,0 +1,14 @@ +import { PinItem } from './PinsList.types'; +import { PinsListItem } from './PinsListItem'; + +interface PinsListProps { + pinsList: PinItem[]; +} + +export const PinsList = ({ pinsList }: PinsListProps): JSX.Element => ( + <ul className="px-6 py-2"> + {pinsList.map(pin => ( + <PinsListItem key={pin.name} name={pin.name} /> + ))} + </ul> +); diff --git a/src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsList.types.tsx b/src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsList.types.tsx new file mode 100644 index 00000000..ce02ca44 --- /dev/null +++ b/src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsList.types.tsx @@ -0,0 +1,3 @@ +export type PinItem = { + name: string; +}; diff --git a/src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsListItem/PinsListItem.component.tsx b/src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsListItem/PinsListItem.component.tsx new file mode 100644 index 00000000..754795e9 --- /dev/null +++ b/src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsListItem/PinsListItem.component.tsx @@ -0,0 +1,13 @@ +import { Icon } from '@/shared/Icon'; + +interface PinsListItemProps { + name: string; +} + +export const PinsListItem = ({ name }: PinsListItemProps): JSX.Element => ( + <div className="flex flex-row justify-between pt-4"> + <Icon name="pin-orange" className="mr-2 shrink-0" /> + <p className="w-full text-left">{name}</p> + <Icon name="chevron-right" className="h-6 w-6 shrink-0" /> + </div> +); diff --git a/src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsListItem/index.ts b/src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsListItem/index.ts new file mode 100644 index 00000000..89b9aebc --- /dev/null +++ b/src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/PinsListItem/index.ts @@ -0,0 +1 @@ +export { PinsListItem } from './PinsListItem.component'; diff --git a/src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/index.ts b/src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/index.ts new file mode 100644 index 00000000..c9d388b0 --- /dev/null +++ b/src/components/Map/Drawer/SearchDrawerContent/Results/PinsList/index.ts @@ -0,0 +1 @@ +export { PinsList } from './PinsList.component'; diff --git a/src/components/Map/Drawer/SearchDrawerContent/Results/Results.component.tsx b/src/components/Map/Drawer/SearchDrawerContent/Results/Results.component.tsx new file mode 100644 index 00000000..c6f7edad --- /dev/null +++ b/src/components/Map/Drawer/SearchDrawerContent/Results/Results.component.tsx @@ -0,0 +1,26 @@ +import { DrawerHeadingBackwardButton } from '@/shared/DrawerHeadingBackwardButton'; +import { PinsList } from './PinsList'; + +const PINS_LIST = [ + { name: 'Glyceraldehyde-3-phosphate dehydrogenase' }, + { name: 'D-3-phosphoglycerate dehydrogenase' }, + { name: 'Glutathione reductase, mitochondrial' }, + { name: 'NADH dehydrogenase [ubiquinone] iron-sulfur protein 8, mitochondrial' }, +]; + +export const Results = (): JSX.Element => { + const drugName = 'Aspirin'; + + const navigateToGroupedSearchResults = (): void => {}; + + return ( + <div> + <DrawerHeadingBackwardButton + title="Drugs" + value={drugName} + backwardFunction={navigateToGroupedSearchResults} + /> + <PinsList pinsList={PINS_LIST} /> + </div> + ); +}; diff --git a/src/components/Map/Drawer/SearchDrawerContent/Results/index.ts b/src/components/Map/Drawer/SearchDrawerContent/Results/index.ts new file mode 100644 index 00000000..0b2da8f8 --- /dev/null +++ b/src/components/Map/Drawer/SearchDrawerContent/Results/index.ts @@ -0,0 +1 @@ +export { Results } from './Results.component'; diff --git a/src/redux/store.ts b/src/redux/store.ts index 1999d33f..f4251783 100644 --- a/src/redux/store.ts +++ b/src/redux/store.ts @@ -26,3 +26,4 @@ export const store = configureStore({ export type RootState = ReturnType<typeof store.getState>; // Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState} export type AppDispatch = typeof store.dispatch; +export type StoreType = typeof store; diff --git a/src/shared/DrawerHeadingBackwardButton/DrawerHeadingBackwardButton.component.test.tsx b/src/shared/DrawerHeadingBackwardButton/DrawerHeadingBackwardButton.component.test.tsx new file mode 100644 index 00000000..c6ef266e --- /dev/null +++ b/src/shared/DrawerHeadingBackwardButton/DrawerHeadingBackwardButton.component.test.tsx @@ -0,0 +1,65 @@ +import { StoreType } from '@/redux/store'; +import { InitialStoreState, getReduxWrapperWithStore } from '@/utils/getReduxWrapperWithStore'; +import { render, screen } from '@testing-library/react'; +import { DrawerHeadingBackwardButton } from './DrawerHeadingBackwardButton.component'; + +const backwardFunction = jest.fn(); + +const renderComponent = ( + title: string, + value: string, + initialStoreState: InitialStoreState = {}, +): { store: StoreType } => { + const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState); + + return ( + render( + <Wrapper> + <DrawerHeadingBackwardButton + title={title} + value={value} + backwardFunction={backwardFunction} + /> + </Wrapper>, + ), + { + store, + } + ); +}; + +describe('DrawerHeadingBackwardButton - component', () => { + beforeEach(() => { + backwardFunction.mockReset(); + }); + + it('should render passed values', () => { + renderComponent('Title', 'value'); + + expect(screen.getByRole('back-button')).toBeInTheDocument(); + expect(screen.getByText('Title:')).toBeInTheDocument(); + expect(screen.getByText('value')).toBeInTheDocument(); + expect(screen.getByRole('close-drawer-button')).toBeInTheDocument(); + }); + + it('should call backward function on back button click', () => { + renderComponent('Title', 'value'); + + const backButton = screen.getByRole('back-button'); + backButton.click(); + + expect(backwardFunction).toBeCalled(); + }); + + it('should call class drawer on close button click', () => { + const { store } = renderComponent('Title', 'value', { + drawer: { open: true, drawerName: 'search' }, + }); + expect(store.getState().drawer.open).toBe(true); + + const closeButton = screen.getByRole('close-drawer-button'); + closeButton.click(); + + expect(store.getState().drawer.open).toBe(false); + }); +}); diff --git a/src/shared/DrawerHeadingBackwardButton/DrawerHeadingBackwardButton.component.tsx b/src/shared/DrawerHeadingBackwardButton/DrawerHeadingBackwardButton.component.tsx new file mode 100644 index 00000000..d5b6394a --- /dev/null +++ b/src/shared/DrawerHeadingBackwardButton/DrawerHeadingBackwardButton.component.tsx @@ -0,0 +1,53 @@ +import { useAppDispatch } from '@/redux/hooks/useAppDispatch'; +import { closeDrawer } from '@/redux/drawer/drawer.slice'; +import { IconButton } from '@/shared/IconButton'; + +export const CLOSE_BUTTON_ROLE = 'close-drawer-button'; +export const BACK_BUTTON_ROLE = 'back-button'; + +export interface DrawerHeadingBackwardButtonProps { + title: string; + value: string; + backwardFunction: () => void; +} + +export const DrawerHeadingBackwardButton = ({ + backwardFunction, + title, + value, +}: DrawerHeadingBackwardButtonProps): JSX.Element => { + const dispatch = useAppDispatch(); + + const handleCloseDrawer = (): void => { + dispatch(closeDrawer()); + }; + + const onBackwardClick = (): void => { + backwardFunction(); + }; + + return ( + <div className="flex items-center justify-between border-b border-b-divide pl-4 pr-5"> + <div className="flex flex-row flex-nowrap items-center"> + <IconButton + className="h-6 w-6 bg-white-pearl" + icon="chevron-left" + classNameIcon="fill-font-500 h-6 w-6" + onClick={onBackwardClick} + role={BACK_BUTTON_ROLE} + /> + <div className="ml-2 py-8 text-xl"> + <span className="font-normal">{title}: </span> + <span className="font-semibold">{value}</span> + </div> + </div> + <IconButton + className="bg-white-pearl" + classNameIcon="fill-font-500" + icon="close" + role={CLOSE_BUTTON_ROLE} + onClick={handleCloseDrawer} + /> + </div> + ); +}; diff --git a/src/shared/DrawerHeadingBackwardButton/index.ts b/src/shared/DrawerHeadingBackwardButton/index.ts new file mode 100644 index 00000000..b3fb4674 --- /dev/null +++ b/src/shared/DrawerHeadingBackwardButton/index.ts @@ -0,0 +1 @@ +export { DrawerHeadingBackwardButton } from './DrawerHeadingBackwardButton.component'; diff --git a/src/shared/Icon/Icon.component.tsx b/src/shared/Icon/Icon.component.tsx index b23a3ad4..89943cae 100644 --- a/src/shared/Icon/Icon.component.tsx +++ b/src/shared/Icon/Icon.component.tsx @@ -12,6 +12,7 @@ import { PageIcon } from '@/shared/Icon/Icons/PageIcon'; import { PluginIcon } from '@/shared/Icon/Icons/PluginIcon'; import { PlusIcon } from '@/shared/Icon/Icons/PlusIcon'; import { CloseIcon } from '@/shared/Icon/Icons/CloseIcon'; +import { PinOrange } from '@/shared/Icon/Icons/PinOrance'; import type { IconTypes } from '@/types/iconTypes'; @@ -25,6 +26,7 @@ const icons = { 'chevron-left': ChevronLeftIcon, 'chevron-up': ChevronUpIcon, 'chevron-down': ChevronDownIcon, + 'pin-orange': PinOrange, plus: PlusIcon, arrow: ArrowIcon, dots: DotsIcon, diff --git a/src/shared/Icon/Icons/PinOrance.tsx b/src/shared/Icon/Icons/PinOrance.tsx new file mode 100644 index 00000000..d2adc98f --- /dev/null +++ b/src/shared/Icon/Icons/PinOrance.tsx @@ -0,0 +1,20 @@ +interface PinOrangeProps { + className: string; +} + +export const PinOrange = ({ className }: PinOrangeProps): JSX.Element => ( + <svg + width="18" + height="24" + viewBox="0 0 18 24" + fill="none" + xmlns="http://www.w3.org/2000/svg" + className={className} + > + <path + d="M9 0C4.575 0 0 3.375 0 9C0 14.325 8.1 22.65 8.475 23.025C8.625 23.175 8.775 23.25 9 23.25C9.225 23.25 9.375 23.175 9.525 23.025C9.9 22.65 18 14.4 18 9C18 3.375 13.425 0 9 0ZM9 12C7.35 12 6 10.65 6 9C6 7.35 7.35 6 9 6C10.65 6 12 7.35 12 9C12 10.65 10.65 12 9 12Z" + fill="#E17221" + /> + <circle cx="9.0002" cy="8.99922" r="4.8" fill="#E17221" /> + </svg> +); diff --git a/src/types/iconTypes.ts b/src/types/iconTypes.ts index 9b14f66b..f4db4670 100644 --- a/src/types/iconTypes.ts +++ b/src/types/iconTypes.ts @@ -12,4 +12,5 @@ export type IconTypes = | 'legend' | 'page' | 'plugin' - | 'close'; + | 'close' + | 'pin-orange'; diff --git a/src/utils/getReduxWrapperWithStore.tsx b/src/utils/getReduxWrapperWithStore.tsx new file mode 100644 index 00000000..1382f962 --- /dev/null +++ b/src/utils/getReduxWrapperWithStore.tsx @@ -0,0 +1,61 @@ +import { StoreType } from '@/redux/store'; +import { configureStore } from '@reduxjs/toolkit'; +import { Provider } from 'react-redux'; +import bioEntityContentsReducer from '@/redux/bioEntityContents/bioEntityContents.slice'; +import chemicalsReducer from '@/redux/chemicals/chemicals.slice'; +import drawerReducer from '@/redux/drawer/drawer.slice'; +import drugsReducer from '@/redux/drugs/drugs.slice'; +import mirnasReducer from '@/redux/mirnas/mirnas.slice'; +import projectReducer from '@/redux/project/project.slice'; +import searchReducer from '@/redux/search/search.slice'; +import modelsReducer from '@/redux/models/models.slice'; +import { SearchState } from '@/redux/search/search.types'; +import { ProjectState } from '@/redux/project/project.types'; +import { DrugsState } from '@/redux/drugs/drugs.types'; +import { MirnasState } from '@/redux/mirnas/mirnas.types'; +import { ChemicalsState } from '@/redux/chemicals/chemicals.types'; +import { BioEntityContentsState } from '@/redux/bioEntityContents/bioEntityContents.types'; +import { DrawerState } from '@/redux/drawer/drawer.types'; + +interface WrapperProps { + children: React.ReactNode; +} + +export type InitialStoreState = { + search?: SearchState; + project?: ProjectState; + drugs?: DrugsState; + mirnas?: MirnasState; + chemicals?: ChemicalsState; + bioEntityContents?: BioEntityContentsState; + drawer?: DrawerState; +}; + +type GetReduxWrapperUsingSliceReducer = (initialState?: InitialStoreState) => { + Wrapper: ({ children }: WrapperProps) => JSX.Element; + store: StoreType; +}; + +export const getReduxWrapperWithStore: GetReduxWrapperUsingSliceReducer = ( + preloadedState: InitialStoreState = {}, +) => { + const testStore = configureStore({ + reducer: { + search: searchReducer, + project: projectReducer, + drugs: drugsReducer, + mirnas: mirnasReducer, + chemicals: chemicalsReducer, + bioEntityContents: bioEntityContentsReducer, + drawer: drawerReducer, + models: modelsReducer, + }, + preloadedState, + }); + + const Wrapper = ({ children }: WrapperProps): JSX.Element => ( + <Provider store={testStore}>{children}</Provider> + ); + + return { Wrapper, store: testStore }; +}; -- GitLab