338 on opportunities page when i associate a new company to a pipelinestage its persisted in db (#339)

* feature: add navigation for opportunities

* chore: add companies in pipeline seed

* feature: make the board scrollable

* feature: make the board scrollable vertically

* feature: remove board container

* feature: fix newButton style

* feature: add onClickNew method on board

* feature: call backend with hardcoded id for new pipeline progressable

* feature: refetch board on click on new

* feature: use pipelineProgressId instead of entityId to ensure unicity of itemKey

* feature: avoid rerender of columns when refetching
This commit is contained in:
Sammy Teillet
2023-06-21 04:27:02 +02:00
committed by GitHub
parent 8790369f72
commit 294b290939
11 changed files with 263 additions and 48 deletions

View File

@ -1,4 +1,6 @@
import { useCallback } from 'react';
import { useCallback, useMemo } from 'react';
import { getOperationName } from '@apollo/client/utilities';
import { useTheme } from '@emotion/react';
import { IconTargetArrow } from '@/ui/icons/index';
import { WithTopBarContainer } from '@/ui/layout/containers/WithTopBarContainer';
@ -6,36 +8,79 @@ import { WithTopBarContainer } from '@/ui/layout/containers/WithTopBarContainer'
import {
PipelineProgress,
PipelineStage,
useCreateOnePipelineProgressMutation,
useUpdateOnePipelineProgressMutation,
} from '../../generated/graphql';
import { Board } from '../../modules/opportunities/components/Board';
import { useBoard } from '../../modules/opportunities/hooks/useBoard';
import { GET_PIPELINES } from '../../modules/opportunities/queries';
export function Opportunities() {
const { initialBoard, items, loading, error, pipelineEntityIdsMapper } =
const theme = useTheme();
const { initialBoard, items, error, pipelineId, pipelineEntityType } =
useBoard();
const columns = useMemo(
() =>
initialBoard?.map(({ id, colorCode, title }) => ({
id,
colorCode,
title,
})),
[initialBoard],
);
const [updatePipelineProgress] = useUpdateOnePipelineProgressMutation();
const [createPipelineProgress] = useCreateOnePipelineProgressMutation();
const onUpdate = useCallback(
async (
entityId: NonNullable<PipelineProgress['progressableId']>,
pipelineProgressId: NonNullable<PipelineProgress['id']>,
pipelineStageId: NonNullable<PipelineStage['id']>,
) => {
const pipelineProgressId = pipelineEntityIdsMapper(entityId);
updatePipelineProgress({
variables: { id: pipelineProgressId, pipelineStageId },
});
},
[updatePipelineProgress, pipelineEntityIdsMapper],
[updatePipelineProgress],
);
const onClickNew = useCallback(
(
columnId: PipelineStage['id'],
newItem: Partial<PipelineProgress> & { id: string },
) => {
if (!pipelineId || !pipelineEntityType) return;
const variables = {
pipelineStageId: columnId,
pipelineId,
entityId: newItem.id,
entityType: pipelineEntityType,
};
createPipelineProgress({
variables,
refetchQueries: [getOperationName(GET_PIPELINES) ?? ''],
});
},
[pipelineId, pipelineEntityType, createPipelineProgress],
);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error...</div>;
if (!initialBoard || !items)
if (!initialBoard || !items) {
return <div>Initial board or items not found</div>;
}
return (
<WithTopBarContainer title="Opportunities" icon={<IconTargetArrow />}>
<Board initialBoard={initialBoard} items={items} onUpdate={onUpdate} />
<WithTopBarContainer
title="Opportunities"
icon={<IconTargetArrow size={theme.iconSizeMedium} />}
>
<Board
columns={columns || []}
initialBoard={initialBoard}
items={items}
onUpdate={onUpdate}
onClickNew={onClickNew}
/>
</WithTopBarContainer>
);
}