* Get pipeline progress from stage IDs * Rename hooks file * Addd first amount filter * Add remaining filters * Design fixes * Add filtering on creation date or amount * Fix card updates and creations with the new state management * Keep ordering when dropping a card * Add remainint sorts * Make board header more generic * Move available filters and sorts to board options * Fix decorators for test * Add pipeline stage ids to mock data * Adapt mock data * Linter
173 lines
5.3 KiB
TypeScript
173 lines
5.3 KiB
TypeScript
import { useEffect, useMemo } from 'react';
|
|
import { useRecoilCallback, useRecoilState } from 'recoil';
|
|
|
|
import { useInitializeCompanyBoardFilters } from '@/companies/hooks/useInitializeCompanyBoardFilters';
|
|
import { companyProgressesFamilyState } from '@/companies/states/companyProgressesFamilyState';
|
|
import {
|
|
CompanyForBoard,
|
|
CompanyProgress,
|
|
PipelineProgressForBoard,
|
|
} from '@/companies/types/CompanyProgress';
|
|
import { boardState } from '@/pipeline/states/boardState';
|
|
import { currentPipelineState } from '@/pipeline/states/currentPipelineState';
|
|
import { isBoardLoadedState } from '@/pipeline/states/isBoardLoadedState';
|
|
import { BoardPipelineStageColumn } from '@/ui/board/components/Board';
|
|
import { filtersScopedState } from '@/ui/filter-n-sort/states/filtersScopedState';
|
|
import { FilterDefinition } from '@/ui/filter-n-sort/types/FilterDefinition';
|
|
import { turnFilterIntoWhereClause } from '@/ui/filter-n-sort/utils/turnFilterIntoWhereClause';
|
|
import { useRecoilScopedValue } from '@/ui/recoil-scope/hooks/useRecoilScopedValue';
|
|
import { PipelineProgressOrderByWithRelationInput as PipelineProgresses_Order_By } from '~/generated/graphql';
|
|
import {
|
|
Pipeline,
|
|
useGetCompaniesQuery,
|
|
useGetPipelineProgressQuery,
|
|
useGetPipelinesQuery,
|
|
} from '~/generated/graphql';
|
|
|
|
import { CompanyBoardContext } from '../states/CompanyBoardContext';
|
|
|
|
export function HooksCompanyBoard({
|
|
availableFilters,
|
|
orderBy,
|
|
}: {
|
|
availableFilters: FilterDefinition[];
|
|
orderBy: PipelineProgresses_Order_By[];
|
|
}) {
|
|
useInitializeCompanyBoardFilters({
|
|
availableFilters,
|
|
});
|
|
const [currentPipeline, setCurrentPipeline] =
|
|
useRecoilState(currentPipelineState);
|
|
|
|
const [, setBoard] = useRecoilState(boardState);
|
|
|
|
const [, setIsBoardLoaded] = useRecoilState(isBoardLoadedState);
|
|
|
|
useGetPipelinesQuery({
|
|
onCompleted: async (data) => {
|
|
const pipeline = data?.findManyPipeline[0] as Pipeline;
|
|
setCurrentPipeline(pipeline);
|
|
const pipelineStages = pipeline?.pipelineStages;
|
|
const orderedPipelineStages = pipelineStages
|
|
? [...pipelineStages].sort((a, b) => {
|
|
if (!a.index || !b.index) return 0;
|
|
return a.index - b.index;
|
|
})
|
|
: [];
|
|
const initialBoard: BoardPipelineStageColumn[] =
|
|
orderedPipelineStages?.map((pipelineStage) => ({
|
|
pipelineStageId: pipelineStage.id,
|
|
title: pipelineStage.name,
|
|
colorCode: pipelineStage.color,
|
|
index: pipelineStage.index || 0,
|
|
pipelineProgressIds: [],
|
|
})) || [];
|
|
setBoard(initialBoard);
|
|
},
|
|
});
|
|
|
|
const pipelineStageIds = currentPipeline?.pipelineStages
|
|
?.map((pipelineStage) => pipelineStage.id)
|
|
.flat();
|
|
|
|
const filters = useRecoilScopedValue(filtersScopedState, CompanyBoardContext);
|
|
|
|
const whereFilters = useMemo(() => {
|
|
return {
|
|
AND: [
|
|
{ pipelineStageId: { in: pipelineStageIds } },
|
|
...filters.map(turnFilterIntoWhereClause),
|
|
],
|
|
};
|
|
}, [filters, pipelineStageIds]) as any;
|
|
|
|
const pipelineProgressesQuery = useGetPipelineProgressQuery({
|
|
variables: {
|
|
where: whereFilters,
|
|
orderBy,
|
|
},
|
|
onCompleted: (data) => {
|
|
const pipelineProgresses = data?.findManyPipelineProgress || [];
|
|
setBoard((board) =>
|
|
board?.map((boardPipelineStage) => ({
|
|
...boardPipelineStage,
|
|
pipelineProgressIds: pipelineProgresses
|
|
.filter(
|
|
(pipelineProgress) =>
|
|
pipelineProgress.pipelineStageId ===
|
|
boardPipelineStage.pipelineStageId,
|
|
)
|
|
.map((pipelineProgress) => pipelineProgress.id),
|
|
})),
|
|
);
|
|
setIsBoardLoaded(true);
|
|
},
|
|
});
|
|
|
|
const pipelineProgresses =
|
|
pipelineProgressesQuery.data?.findManyPipelineProgress || [];
|
|
|
|
const entitiesQueryResult = useGetCompaniesQuery({
|
|
variables: {
|
|
where: {
|
|
id: {
|
|
in: pipelineProgresses.map((item) => item.progressableId),
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
const indexCompanyByIdReducer = (
|
|
acc: { [key: string]: CompanyForBoard },
|
|
company: CompanyForBoard,
|
|
) => ({
|
|
...acc,
|
|
[company.id]: company,
|
|
});
|
|
|
|
const companiesDict =
|
|
entitiesQueryResult.data?.companies.reduce(
|
|
indexCompanyByIdReducer,
|
|
{} as { [key: string]: CompanyForBoard },
|
|
) || {};
|
|
|
|
const indexPipelineProgressByIdReducer = (
|
|
acc: {
|
|
[key: string]: CompanyProgress;
|
|
},
|
|
pipelineProgress: PipelineProgressForBoard,
|
|
) => {
|
|
const company = companiesDict[pipelineProgress.progressableId];
|
|
return {
|
|
...acc,
|
|
[pipelineProgress.id]: {
|
|
pipelineProgress,
|
|
company,
|
|
},
|
|
};
|
|
};
|
|
const companyBoardIndex = pipelineProgresses.reduce(
|
|
indexPipelineProgressByIdReducer,
|
|
{} as { [key: string]: CompanyProgress },
|
|
);
|
|
|
|
const synchronizeCompanyProgresses = useRecoilCallback(
|
|
({ set }) =>
|
|
(companyBoardIndex: { [key: string]: CompanyProgress }) => {
|
|
Object.entries(companyBoardIndex).forEach(([id, companyProgress]) => {
|
|
set(companyProgressesFamilyState(id), companyProgress);
|
|
});
|
|
},
|
|
[],
|
|
);
|
|
|
|
const loading =
|
|
entitiesQueryResult.loading || pipelineProgressesQuery.loading;
|
|
|
|
useEffect(() => {
|
|
!loading && synchronizeCompanyProgresses(companyBoardIndex);
|
|
}, [loading, companyBoardIndex, synchronizeCompanyProgresses]);
|
|
|
|
return <></>;
|
|
}
|