Untitled
src\modules\main\components\table\hooks\table.hook.tsunknown
plain_text
3 years ago
2.6 kB
7
Indexable
import { PlanningStatus } from '@/modules/shared/consts';
import { useAppDispatch, useAppSelector } from '@/store/hooks';
import { ActionCreatorWithPayload, AsyncThunk, CombinedState } from '@reduxjs/toolkit';
import { useEffect, useMemo } from 'react';
import { useForm, UseFormReturn } from 'react-hook-form';
import { StoreType } from '../../../../../store';
import { EntityState } from './../../../pages/settings/redux/entity-state.type';
import { IdentifiableEntity, IdType } from './../../../pages/settings/redux/thunks';
interface UseTableDataType<Entity, EntityMapped extends IdentifiableEntity> {
loading: boolean | undefined;
uiData: EntityMapped[];
data: Entity[];
form: UseFormReturn<{ search: string; status: number | string | undefined }, any>;
}
interface UseTableDataProps<Entity, EntityMapped extends IdentifiableEntity, SingleEntity> {
filterThunk: ActionCreatorWithPayload<string, string>;
readThunk: AsyncThunk<Entity[], IdType, Record<string, unknown>>;
stateSelector: (state: CombinedState<StoreType>) => EntityState<Entity, SingleEntity>;
mapEntityToUiData: (entity: Entity) => EntityMapped;
shouldFilterByStatus?: boolean;
}
export const useTableData = <Entity, EntityMapped extends IdentifiableEntity, SingleEntity>({
filterThunk,
readThunk,
stateSelector,
mapEntityToUiData,
shouldFilterByStatus = false,
}: UseTableDataProps<Entity, EntityMapped & IdentifiableEntity, SingleEntity>): UseTableDataType<
Entity,
EntityMapped & IdentifiableEntity
> => {
const dispatch = useAppDispatch();
const form = useForm<{ search: string; status: number | string | undefined }>({
defaultValues: {
search: '',
status: 1,
},
});
const { search, status } = form.watch();
useEffect(() => {
dispatch(filterThunk(search));
}, [search, dispatch, filterThunk]);
const { filtered, loading, data } = useAppSelector(stateSelector);
const filteredByText: EntityMapped[] = useMemo(
() => filtered.map(mapEntityToUiData),
[filtered, mapEntityToUiData],
);
const filterUiDataByStatus = (): EntityMapped[] => {
if (status === 1 || !shouldFilterByStatus) return filteredByText;
const filteredByStatus = filteredByText.filter((entity: EntityMapped) => {
return entity.status?.toString().toLowerCase() === PlanningStatus[status as number];
});
return filteredByStatus;
};
const uiData = filterUiDataByStatus();
useEffect(() => {
dispatch(readThunk());
}, [dispatch, readThunk]);
return {
loading,
uiData,
data,
form,
};
};
Editor is loading...