Skip to content
Snippets Groups Projects
Commit 3d70b54f authored by Tadeusz Miesiąc's avatar Tadeusz Miesiąc
Browse files

refactor: removed local state from background selector component

parent f7d1f940
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...,!53feat(background selector): added component to allow switch between backgrounds
Pipeline #81466 passed
...@@ -31,12 +31,12 @@ export const MapNavigation = (): JSX.Element => { ...@@ -31,12 +31,12 @@ export const MapNavigation = (): JSX.Element => {
}; };
return ( return (
<div className="flex h-10 w-full flex-row flex-nowrap justify-start overflow-y-auto bg-white-pearl shadow-map-navigation-bar"> <div className="flex h-10 w-full flex-row flex-nowrap justify-start overflow-y-auto bg-white-pearl text-xs shadow-primary">
{openedMaps.map(map => ( {openedMaps.map(map => (
<Button <Button
key={map.modelId} key={map.modelId}
className={twMerge( className={twMerge(
'h-10 whitespace-nowrap ', 'h-10 whitespace-nowrap',
isActive(map.modelId) ? 'bg-[#EBF4FF]' : 'font-normal', isActive(map.modelId) ? 'bg-[#EBF4FF]' : 'font-normal',
)} )}
variantStyles={isActive(map.modelId) ? 'secondary' : 'ghost'} variantStyles={isActive(map.modelId) ? 'secondary' : 'ghost'}
......
/* eslint-disable no-magic-numbers */ /* eslint-disable no-magic-numbers */
import { StoreType } from '@/redux/store'; import { StoreType } from '@/redux/store';
import { useRouter } from 'next/router';
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import { act } from 'react-dom/test-utils'; import { act } from 'react-dom/test-utils';
import { initialMapStateFixture } from '@/redux/map/map.fixtures'; import { initialMapDataFixture, initialMapStateFixture } from '@/redux/map/map.fixtures';
import { import {
InitialStoreState, InitialStoreState,
getReduxWrapperWithStore, getReduxWrapperWithStore,
...@@ -29,14 +28,6 @@ const renderComponent = (initialStoreState: InitialStoreState = {}): { store: St ...@@ -29,14 +28,6 @@ const renderComponent = (initialStoreState: InitialStoreState = {}): { store: St
); );
}; };
jest.mock('next/router', () => ({
useRouter: jest.fn(),
}));
(useRouter as jest.Mock).mockReturnValue({
query: {},
});
describe('BackgroundSelector - component', () => { describe('BackgroundSelector - component', () => {
it('should initialy display default value', () => { it('should initialy display default value', () => {
renderComponent(); renderComponent();
...@@ -88,11 +79,8 @@ describe('BackgroundSelector - component', () => { ...@@ -88,11 +79,8 @@ describe('BackgroundSelector - component', () => {
describe('query params', () => { describe('query params', () => {
it('should display default value when main background id is in query params', async () => { it('should display default value when main background id is in query params', async () => {
(useRouter as jest.Mock).mockReturnValue({
query: { backgroundId: '13' },
});
await renderComponent({ await renderComponent({
map: initialMapStateFixture, map: { ...initialMapStateFixture, data: { ...initialMapDataFixture, backgroundId: 13 } },
backgrounds: { ...BACKGROUND_INITIAL_STATE_MOCK, data: BACKGROUNDS_MOCK }, backgrounds: { ...BACKGROUND_INITIAL_STATE_MOCK, data: BACKGROUNDS_MOCK },
}); });
...@@ -100,11 +88,8 @@ describe('BackgroundSelector - component', () => { ...@@ -100,11 +88,8 @@ describe('BackgroundSelector - component', () => {
expect(buttonName.textContent).toBe('Background'); expect(buttonName.textContent).toBe('Background');
}); });
it('should display correct background when background id is in query params', async () => { it('should display correct background when background id is in query params', async () => {
(useRouter as jest.Mock).mockReturnValue({
query: { backgroundId: '15' },
});
await renderComponent({ await renderComponent({
map: initialMapStateFixture, map: { ...initialMapStateFixture, data: { ...initialMapDataFixture, backgroundId: 15 } },
backgrounds: { ...BACKGROUND_INITIAL_STATE_MOCK, data: BACKGROUNDS_MOCK }, backgrounds: { ...BACKGROUND_INITIAL_STATE_MOCK, data: BACKGROUNDS_MOCK },
}); });
......
import { useEffect, useState } from 'react';
import { useSelect } from 'downshift'; import { useSelect } from 'downshift';
import { import {
backgroundsDataSelector, backgroundsDataSelector,
currentBackgroundSelector,
mainBackgroundIdSelector, mainBackgroundIdSelector,
} from '@/redux/backgrounds/background.selectors'; } from '@/redux/backgrounds/background.selectors';
import { useAppSelector } from '@/redux/hooks/useAppSelector'; import { useAppSelector } from '@/redux/hooks/useAppSelector';
...@@ -10,69 +10,56 @@ import { Icon } from '@/shared/Icon'; ...@@ -10,69 +10,56 @@ import { Icon } from '@/shared/Icon';
import { MapBackground } from '@/types/models'; import { MapBackground } from '@/types/models';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch'; import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { setMapBackground } from '@/redux/map/map.slice'; import { setMapBackground } from '@/redux/map/map.slice';
import { useRouter } from 'next/router';
import { parseQueryToTypes } from '@/utils/parseQueryToTypes';
const DEFAULT_TOGGLE_BUTTON_TEXT = 'Background'; const DEFAULT_TOGGLE_BUTTON_TEXT = 'Background';
export const BackgroundSelector = (): JSX.Element => { export const BackgroundSelector = (): JSX.Element => {
const [selectedItem, setSelectedItem] = useState<MapBackground | undefined>(undefined); const selectedBackground = useAppSelector(currentBackgroundSelector);
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { query } = useRouter();
const backgrounds = useAppSelector(backgroundsDataSelector); const backgrounds = useAppSelector(backgroundsDataSelector);
const mainBackgroundId = useAppSelector(mainBackgroundIdSelector); const mainBackgroundId = useAppSelector(mainBackgroundIdSelector);
useEffect(() => {
const onApplicationLoadSetInitialSelectedItem = (): void => {
const backgroundId = parseQueryToTypes(query)?.backgroundId;
const initialBackground = backgrounds?.find(({ id }) => id === backgroundId);
setSelectedItem(initialBackground);
};
if (!selectedItem) {
onApplicationLoadSetInitialSelectedItem();
}
}, [selectedItem, query, backgrounds]);
const onItemSelect = (background: MapBackground | undefined | null): void => { const onItemSelect = (background: MapBackground | undefined | null): void => {
if (background) { if (background) {
dispatch(setMapBackground(background.id)); dispatch(setMapBackground(background.id));
setSelectedItem(background);
} }
}; };
const { isOpen, getToggleButtonProps, getMenuProps, highlightedIndex, getItemProps } = useSelect({ const { isOpen, getToggleButtonProps, getMenuProps, highlightedIndex, getItemProps } = useSelect({
items: backgrounds || [], items: backgrounds || [],
selectedItem, selectedItem: selectedBackground,
onSelectedItemChange: ({ selectedItem: newSelectedItem }) => onItemSelect(newSelectedItem), onSelectedItemChange: ({ selectedItem: newSelectedItem }) => onItemSelect(newSelectedItem),
}); });
const getToggleButtonName = (): string => { const getToggleButtonName = (): string => {
const isSelectedBackgroundMainBackground = selectedItem?.id === mainBackgroundId; const isSelectedBackgroundMainBackground = selectedBackground?.id === mainBackgroundId;
if (!selectedItem || isSelectedBackgroundMainBackground) { if (!selectedBackground || isSelectedBackgroundMainBackground) {
return DEFAULT_TOGGLE_BUTTON_TEXT; return DEFAULT_TOGGLE_BUTTON_TEXT;
} }
return selectedItem.name; return selectedBackground.name;
}; };
return ( return (
<div data-testid="background-selector"> <div
<div className="flex w-72 flex-col gap-1"> data-testid="background-selector"
className={twMerge('rounded-t bg-white text-xs shadow-primary', !isOpen && 'rounded-b')}
>
<div className={twMerge('flex w-72 flex-col rounded-t py-2 pl-4 pr-3')}>
<div <div
className="flex cursor-pointer justify-between bg-white p-2" className="flex cursor-pointer flex-row items-center justify-between bg-white"
{...getToggleButtonProps()} {...getToggleButtonProps()}
> >
<span data-testid="background-dropdown-button-name">{getToggleButtonName()}</span> <span data-testid="background-dropdown-button-name" className="font-medium">
<span className="px-2"> {getToggleButtonName()}
<Icon
name="chevron-down"
className={twMerge('arrow-button h-6 w-6 fill-font-500', isOpen && 'rotate-180')}
/>
</span> </span>
<Icon
name="chevron-down"
className={twMerge('arrow-button h-6 w-6 fill-primary-500', isOpen && 'rotate-180')}
/>
</div> </div>
</div> </div>
<ul <ul
className={`absolute z-10 mt-1 max-h-80 w-72 overflow-scroll bg-white p-0 shadow-md ${ className={`absolute z-10 max-h-80 w-72 overflow-scroll rounded-b bg-white p-0 ${
!isOpen && 'hidden' !isOpen && 'hidden'
}`} }`}
{...getMenuProps()} {...getMenuProps()}
...@@ -82,9 +69,10 @@ export const BackgroundSelector = (): JSX.Element => { ...@@ -82,9 +69,10 @@ export const BackgroundSelector = (): JSX.Element => {
backgrounds.map((item, index) => ( backgrounds.map((item, index) => (
<li <li
className={twMerge( className={twMerge(
highlightedIndex === index && 'bg-blue-300', 'border-t',
selectedItem === item && 'font-bold', highlightedIndex === index && 'text-primary-500',
'flex flex-col px-3 py-2 shadow-sm', selectedBackground === item && 'font-bold',
'flex flex-col px-4 py-2 shadow-sm',
)} )}
key={item.id} key={item.id}
{...getItemProps({ item, index })} {...getItemProps({ item, index })}
......
...@@ -33,7 +33,7 @@ const config: Config = { ...@@ -33,7 +33,7 @@ const config: Config = {
'calc-drawer': 'calc(100% - 104px)', 'calc-drawer': 'calc(100% - 104px)',
}, },
boxShadow: { boxShadow: {
'map-navigation-bar': '4px 8px 32px 0px rgba(0, 0, 0, 0.12)', primary: '4px 8px 32px 0px rgba(0, 0, 0, 0.12)',
}, },
}, },
fontFamily: { fontFamily: {
......
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