Fix Pokedex.stories.tsx for moving filterPokemonCardsByType, sortPokemonCardsByIdOrName, searchPokemonCardsByName into pokedexSlice, so we can have memorized filtered pokedex

This commit is contained in:
Jason Zhu 2023-06-04 16:39:51 +10:00
parent 6fab4b8217
commit c65e946f09
5 changed files with 77 additions and 34 deletions

View File

@ -8,20 +8,12 @@ import { useAppSelector } from 'app/hooks';
function App() {
const selectedRegion = useAppSelector(state => state.filter.selectedRegion);
const selectedType = useAppSelector(state => state.filter.selectedType);
const selectedSort = useAppSelector(state => state.filter.selectedSort);
const selectedSearchInput = useAppSelector(state => state.filter.searchInput);
return (
<div className="App app_container">
<Header />
<Filters />
<Pokedex
selectedRegion={selectedRegion}
selectedType={selectedType}
selectedSort={selectedSort}
searchInput={selectedSearchInput}
/>
<Pokedex selectedRegion={selectedRegion} />
<InfoDialog />
</div>
);

View File

@ -4,12 +4,12 @@ import {
PayloadAction,
Slice,
} from '@reduxjs/toolkit';
import { FilterState } from './types/slice';
import { FilterStateProps } from './types/slice';
import { RegionPokemonRange } from './types/slice';
import { pokeRestApi } from 'app/services/pokeRestApi';
import { fetchPokemonsInTheRegion } from 'features/Pokedex/pokedexSlice';
const initialState: FilterState = {
export const initialState: FilterStateProps = {
regionOptions: [],
typeOptions: [],
sortOptions: [],
@ -46,7 +46,7 @@ export const initializeFilterSlice = createAsyncThunk(
},
);
export const filterSlice: Slice<FilterState> = createSlice({
export const filterSlice: Slice<FilterStateProps> = createSlice({
name: 'filter',
initialState,
reducers: {

View File

@ -1,4 +1,4 @@
export type FilterState = {
export type FilterStateProps = {
regionOptions: RegionPokemonRange[];
typeOptions: string[];
sortOptions: { name: string; value: string }[];

View File

@ -3,8 +3,10 @@ import { configureStore, createSlice } from '@reduxjs/toolkit';
import type { Meta } from '@storybook/react';
import Pokedex from './Pokedex';
import { initialState } from './pokedexSlice';
import { initialState as initialPokedexState } from './pokedexSlice';
import { initialState as initialFilterState } from '../Filters/filterSlice';
import { PokedexStateProps } from './types/slice';
import { FilterStateProps } from 'features/Filters/types/slice';
const MockedState = {
// Copied from Redux DevTools from browser
@ -62,30 +64,55 @@ const MockedState = {
},
],
},
filter: {
regionOptions: [],
typeOptions: [],
sortOptions: [],
selectedRegion: 'kanto',
selectedType: 'All Types',
selectedSort: 'id',
searchInput: '',
},
};
interface MockStoreProps {
pokedexState: PokedexStateProps;
filterState: FilterStateProps;
children: React.ReactNode;
}
// Create a mock store
const mockSlice = (pokedexState: PokedexStateProps) => {
const mockPokedexSlice = (pokedexState: PokedexStateProps) => {
return createSlice({
name: 'pokedex',
initialState: pokedexState,
reducers: {},
});
};
const mockStore = (pokedexState: PokedexStateProps) => {
const mockFilterSlice = (filterState: FilterStateProps) => {
return createSlice({
name: 'filter',
initialState: filterState,
reducers: {},
});
};
const mockStore = (
pokedexState: PokedexStateProps,
filterState: FilterStateProps,
) => {
return configureStore({
reducer: {
pokedex: mockSlice(pokedexState).reducer,
filter: mockFilterSlice(filterState).reducer,
pokedex: mockPokedexSlice(pokedexState).reducer,
},
});
};
const Mockstore: React.FC<MockStoreProps> = ({ pokedexState, children }) => (
<Provider store={mockStore(pokedexState)}>{children}</Provider>
const Mockstore: React.FC<MockStoreProps> = ({
pokedexState,
filterState,
children,
}) => (
<Provider store={mockStore(pokedexState, filterState)}>{children}</Provider>
);
const meta: Meta<typeof Pokedex> = {
@ -105,21 +132,53 @@ export default meta;
export const Loding = {
decorators: [
(story: () => React.ReactNode) => (
<Mockstore pokedexState={initialState}>{story()}</Mockstore>
<Mockstore
pokedexState={initialPokedexState}
filterState={initialFilterState}
>
{story()}
</Mockstore>
),
],
};
export const Primary = {
export const All = {
decorators: [
(story: () => React.ReactNode) => (
<Mockstore pokedexState={MockedState.pokedex}>{story()}</Mockstore>
<Mockstore
pokedexState={MockedState.pokedex}
filterState={MockedState.filter}
>
{story()}
</Mockstore>
),
],
args: {
selectedRegion: 'kanto',
},
};
const filterStateOnlyFire = {
regionOptions: [],
typeOptions: [],
sortOptions: [],
selectedRegion: 'kanto',
selectedType: 'fire',
selectedSort: 'id',
searchInput: '',
};
export const typeFireSelected = {
decorators: [
(story: () => React.ReactNode) => (
<Mockstore
pokedexState={MockedState.pokedex}
filterState={filterStateOnlyFire}
>
{story()}
</Mockstore>
),
],
args: {
selectedRegion: 'kanto',
selectedType: 'All Types',
selectedSort: 'id',
searchInput: '',
},
};

View File

@ -11,17 +11,9 @@ import { fetchSelectedPokemonInfo } from 'features/InfoDialog/infoDialogSlice';
export interface PokedexProps {
selectedRegion: string;
selectedType: string;
selectedSort: string;
searchInput: string;
}
const Pokedex = ({
selectedRegion,
selectedType,
selectedSort,
searchInput,
}: PokedexProps) => {
const Pokedex = ({ selectedRegion }: PokedexProps) => {
const dispatch = useAppDispatch();
const isLoadingPokemons = useAppSelector(