improve typing

This commit is contained in:
Emilien 2023-07-12 21:47:32 -07:00
parent 4e4c534bfe
commit 49bf7929b6
5 changed files with 48 additions and 47 deletions

View File

@ -73,21 +73,22 @@ export function CompanyBoardCard({
entity: Company; entity: Company;
pipelineProgress: PipelineProgressProp; pipelineProgress: PipelineProgressProp;
selected: boolean; selected: boolean;
onSelect: (entity: any) => void; onSelect: (entity: Company) => void;
onCardUpdate: (pipelineProgress: PipelineProgressProp) => Promise<void>; onCardUpdate: (pipelineProgress: PipelineProgressProp) => Promise<void>;
}) { }) {
const theme = useTheme(); const theme = useTheme();
const company = entity;
return ( return (
<StyledBoardCardWrapper> <StyledBoardCardWrapper>
<StyledBoardCard selected={selected}> <StyledBoardCard selected={selected}>
<StyledBoardCardHeader> <StyledBoardCardHeader>
<img <img
src={getLogoUrlFromDomainName(entity.domainName).toString()} src={getLogoUrlFromDomainName(company.domainName).toString()}
alt={`${entity.name}-company-logo`} alt={`${company.name}-company-logo`}
/> />
<span>{entity.name}</span> <span>{company.name}</span>
<div style={{ display: 'flex', flex: 1 }} /> <div style={{ display: 'flex', flex: 1 }} />
<Checkbox checked={selected} onChange={() => onSelect(entity)} /> <Checkbox checked={selected} onChange={() => onSelect(company)} />
</StyledBoardCardHeader> </StyledBoardCardHeader>
<StyledBoardCardBody> <StyledBoardCardBody>
<span> <span>

View File

@ -24,10 +24,13 @@ type BoardProps = {
}; };
export function CompanyProgressBoard({ pipeline }: BoardProps) { export function CompanyProgressBoard({ pipeline }: BoardProps) {
const { initialBoard, items } = useBoard(useGetCompaniesQuery, pipeline); const { initialBoard, items } = useBoard<Company>(
useGetCompaniesQuery,
pipeline,
);
return ( return (
<EntityProgressBoard <EntityProgressBoard<Company>
initialBoard={initialBoard} initialBoard={initialBoard}
initialItems={items} initialItems={items}
pipeline={pipeline} pipeline={pipeline}

View File

@ -29,24 +29,24 @@ import { boardColumnsState } from '../states/boardColumnsState';
import { boardItemsState } from '../states/boardItemsState'; import { boardItemsState } from '../states/boardItemsState';
import { selectedBoardItemsState } from '../states/selectedBoardItemsState'; import { selectedBoardItemsState } from '../states/selectedBoardItemsState';
export type EntityProgress = { export type EntityProgress<T> = {
entity: any; entity: T;
pipelineProgress: Pick<PipelineProgress, 'id' | 'amount' | 'closeDate'>; pipelineProgress: Pick<PipelineProgress, 'id' | 'amount' | 'closeDate'>;
}; };
export type EntityProgressDict = { export type EntityProgressDict<T> = {
[key: string]: EntityProgress; [key: string]: EntityProgress<T>;
}; };
type BoardProps = { type BoardProps<T> = {
pipeline: Pipeline; pipeline: Pipeline;
initialBoard: Column[]; initialBoard: Column[];
initialItems: EntityProgressDict; initialItems: EntityProgressDict<T>;
EntityCardComponent: React.FC<{ EntityCardComponent: React.FC<{
entity: any; entity: T;
pipelineProgress: Pick<PipelineProgress, 'id' | 'amount' | 'closeDate'>; pipelineProgress: Pick<PipelineProgress, 'id' | 'amount' | 'closeDate'>;
selected: boolean; selected: boolean;
onSelect: (entityProgress: EntityProgress) => void; onSelect: () => void;
onCardUpdate: ( onCardUpdate: (
pipelineProgress: Pick<PipelineProgress, 'id' | 'amount' | 'closeDate'>, pipelineProgress: Pick<PipelineProgress, 'id' | 'amount' | 'closeDate'>,
) => Promise<void>; ) => Promise<void>;
@ -79,13 +79,13 @@ const BoardColumnCardsContainer = ({
); );
}; };
export function EntityProgressBoard({ export function EntityProgressBoard<T>({
initialBoard, initialBoard,
initialItems, initialItems,
pipeline, pipeline,
EntityCardComponent, EntityCardComponent,
NewEntityButtonComponent, NewEntityButtonComponent,
}: BoardProps) { }: BoardProps<T>) {
const [board, setBoard] = useRecoilState(boardColumnsState); const [board, setBoard] = useRecoilState(boardColumnsState);
const [boardItems, setBoardItems] = useRecoilState(boardItemsState); const [boardItems, setBoardItems] = useRecoilState(boardItemsState);
const [selectedBoardItems, setSelectedBoardItems] = useRecoilState( const [selectedBoardItems, setSelectedBoardItems] = useRecoilState(
@ -154,26 +154,29 @@ export function EntityProgressBoard({
isInitialBoardLoaded, isInitialBoardLoaded,
]); ]);
const calculateColumnTotals = ( const calculateColumnTotals = useCallback(
columns: Column[], (
items: { columns: Column[],
[key: string]: EntityProgress; items: {
[key: string]: EntityProgress<T>;
},
): { [key: string]: number } => {
return columns.reduce<{ [key: string]: number }>((acc, column) => {
acc[column.id] = column.itemKeys.reduce(
(total: number, itemKey: string) => {
return total + (items[itemKey]?.pipelineProgress?.amount || 0);
},
0,
);
return acc;
}, {});
}, },
): { [key: string]: number } => { [],
return columns.reduce<{ [key: string]: number }>((acc, column) => { );
acc[column.id] = column.itemKeys.reduce(
(total: number, itemKey: string) => {
return total + (items[itemKey]?.pipelineProgress?.amount || 0);
},
0,
);
return acc;
}, {});
};
const columnTotals = useMemo( const columnTotals = useMemo(
() => calculateColumnTotals(board, boardItems), () => calculateColumnTotals(board, boardItems),
[board, boardItems], [board, boardItems, calculateColumnTotals],
); );
const onDragEnd: OnDragEndResponder = useCallback( const onDragEnd: OnDragEndResponder = useCallback(

View File

@ -5,19 +5,18 @@ import {
} from '../../../generated/graphql'; } from '../../../generated/graphql';
import { Column } from '../../ui/board/components/Board'; import { Column } from '../../ui/board/components/Board';
type ItemEntity = any;
type ItemPipelineProgress = Pick< type ItemPipelineProgress = Pick<
PipelineProgress, PipelineProgress,
'id' | 'amount' | 'progressableId' 'id' | 'amount' | 'progressableId'
>; >;
type Item = { type Item<T> = {
entity: ItemEntity; entity: T;
pipelineProgress: ItemPipelineProgress; pipelineProgress: ItemPipelineProgress;
}; };
type Items = { [key: string]: Item }; type Items<T> = { [key: string]: Item<T> };
export function useBoard( export function useBoard<T extends { id: string }>(
useGetEntitiesQuery: any, useGetEntitiesQuery: any,
pipeline: Pipeline | undefined, pipeline: Pipeline | undefined,
) { ) {
@ -63,17 +62,14 @@ export function useBoard(
}, },
}); });
const indexEntityByIdReducer = ( const indexEntityByIdReducer = (acc: { [key: string]: T }, entity: T) => ({
acc: { [key: string]: ItemEntity },
entity: ItemEntity,
) => ({
...acc, ...acc,
[entity.id]: entity, [entity.id]: entity,
}); });
const entitiesDict = entitiesQueryResult.data?.companies.reduce( const entitiesDict = entitiesQueryResult.data?.companies.reduce(
indexEntityByIdReducer, indexEntityByIdReducer,
{} as { [key: string]: ItemEntity }, {} as { [key: string]: T },
); );
const items = pipelineProgresses?.reduce((acc, pipelineProgress) => { const items = pipelineProgresses?.reduce((acc, pipelineProgress) => {
@ -84,7 +80,7 @@ export function useBoard(
}; };
} }
return acc; return acc;
}, {} as Items); }, {} as Items<T>);
return { return {
initialBoard, initialBoard,

View File

@ -1,8 +1,6 @@
import { atom } from 'recoil'; import { atom } from 'recoil';
import { EntityProgressDict } from '../components/EntityProgressBoard'; export const boardItemsState = atom<any>({
export const boardItemsState = atom<EntityProgressDict>({
key: 'boardItemsState', key: 'boardItemsState',
default: {}, default: {},
}); });