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
@@ -1,4 +1,4 @@
import { useCallback, useState } from 'react';
import { useCallback, useMemo, useState } from 'react';
import {
DragDropContext,
Draggable,
@@ -10,11 +10,13 @@ import {
BoardItemKey,
Column,
getOptimisticlyUpdatedBoard,
Item,
Items,
StyledBoard,
} from '../../ui/components/board/Board';
import {
ItemsContainer,
ScrollableColumn,
StyledColumn,
StyledColumnTitle,
} from '../../ui/components/board/BoardColumn';
@@ -24,21 +26,43 @@ import { NewButton } from '../../ui/components/board/BoardNewButton';
import { BoardCard } from './BoardCard';
type BoardProps = {
columns: Omit<Column, 'itemKeys'>[];
initialBoard: Column[];
items: Items;
onUpdate?: (itemKey: BoardItemKey, columnId: Column['id']) => Promise<void>;
onClickNew?: (
columnId: Column['id'],
newItem: Partial<Item> & { id: string },
) => void;
};
export const Board = ({ initialBoard, items, onUpdate }: BoardProps) => {
export const Board = ({
columns,
initialBoard,
items,
onUpdate,
onClickNew,
}: BoardProps) => {
const [board, setBoard] = useState<Column[]>(initialBoard);
const onClickFunctions = useMemo<
Record<Column['id'], (newItem: Partial<Item> & { id: string }) => void>
>(() => {
return board.reduce((acc, column) => {
acc[column.id] = (newItem: Partial<Item> & { id: string }) => {
onClickNew && onClickNew(column.id, newItem);
};
return acc;
}, {} as Record<Column['id'], (newItem: Partial<Item> & { id: string }) => void>);
}, [board, onClickNew]);
const onDragEnd: OnDragEndResponder = useCallback(
async (result) => {
const newBoard = getOptimisticlyUpdatedBoard(board, result);
if (!newBoard) return;
setBoard(newBoard);
try {
const draggedEntityId = items[result.draggableId]?.id;
const draggedEntityId = result.draggableId;
const destinationColumnId = result.destination?.droppableId;
draggedEntityId &&
destinationColumnId &&
@@ -48,35 +72,38 @@ export const Board = ({ initialBoard, items, onUpdate }: BoardProps) => {
console.error(e);
}
},
[board, onUpdate, items],
[board, onUpdate],
);
console.log('board', board);
return (
<StyledBoard>
<DragDropContext onDragEnd={onDragEnd}>
{board.map((column) => (
{columns.map((column, columnIndex) => (
<Droppable key={column.id} droppableId={column.id}>
{(droppableProvided) => (
<StyledColumn>
<StyledColumnTitle color={column.colorCode}>
{column.title}
</StyledColumnTitle>
<ItemsContainer droppableProvided={droppableProvided}>
{column.itemKeys.map((itemKey, index) => (
<Draggable
key={itemKey}
draggableId={itemKey}
index={index}
>
{(draggableProvided) => (
<BoardItem draggableProvided={draggableProvided}>
<BoardCard item={items[itemKey]} />
</BoardItem>
)}
</Draggable>
))}
</ItemsContainer>
<NewButton />
<ScrollableColumn>
<ItemsContainer droppableProvided={droppableProvided}>
{board[columnIndex].itemKeys.map((itemKey, index) => (
<Draggable
key={itemKey}
draggableId={itemKey}
index={index}
>
{(draggableProvided) => (
<BoardItem draggableProvided={draggableProvided}>
<BoardCard item={items[itemKey]} />
</BoardItem>
)}
</Draggable>
))}
</ItemsContainer>
<NewButton onClick={onClickFunctions[column.id]} />
</ScrollableColumn>
</StyledColumn>
)}
</Droppable>
@@ -16,7 +16,7 @@ type Story = StoryObj<typeof Board>;
export const OneColumnBoard: Story = {
render: () => (
<StrictMode>
<Board initialBoard={initialBoard} items={items} />
<Board columns={initialBoard} initialBoard={initialBoard} items={items} />
</StrictMode>
),
};