278 refactor uiboard opportunitiesboard + put state in recoil (#280)

* refactor: move Board file to opportunities

* refactor: dropable props are move in ui component

* refactor: rename provided in droppableProvided

* refactor: rename provided in draggableProvided

* refactor: rename BoardCard in BoardItem

* refactor: rename BoardCard in BoardItem file

* refactor: BoardItem use children instead of content

* refactor: Extract StyledColumnContainer

* refactor: create method to get optimistic new board after update

* refactor: move getOptimisticNewBoard in board UI

* refactor: make provided nullable

* lint: remove unused import
This commit is contained in:
Sammy Teillet
2023-06-13 17:02:09 +02:00
committed by GitHub
parent 3a719001de
commit c20fd458ae
8 changed files with 139 additions and 131 deletions

View File

@ -0,0 +1,76 @@
import { useCallback, useState } from 'react';
import {
DragDropContext,
Draggable,
Droppable,
OnDragEndResponder,
} from '@hello-pangea/dnd';
import {
Column,
getOptimisticlyUpdatedBoard,
Items,
StyledBoard,
} from '../../ui/components/board/Board';
import {
ItemsContainer,
StyledColumn,
StyledColumnTitle,
} from '../../ui/components/board/BoardColumn';
// Atlassian dnd does not support StrictMode from RN 18, so we use a fork @hello-pangea/dnd
// https://github.com/atlassian/react-beautiful-dnd/issues/2350
import { BoardItem } from '../../ui/components/board/BoardItem';
import { NewButton } from '../../ui/components/board/BoardNewButton';
type BoardProps = {
initialBoard: Column[];
items: Items;
};
export const Board = ({ initialBoard, items }: BoardProps) => {
const [board, setBoard] = useState<Column[]>(initialBoard);
const onDragEnd: OnDragEndResponder = useCallback(
(result) => {
const newBoard = getOptimisticlyUpdatedBoard(board, result);
if (!newBoard) return;
setBoard(newBoard);
// TODO implement update board mutation
},
[board],
);
return (
<DragDropContext onDragEnd={onDragEnd}>
<StyledBoard>
{board.map((column) => (
<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}>
<p>{items[itemKey].content}</p>
</BoardItem>
)}
</Draggable>
))}
</ItemsContainer>
<NewButton />
</StyledColumn>
)}
</Droppable>
))}
</StyledBoard>
</DragDropContext>
);
};

View File

@ -0,0 +1,22 @@
import { StrictMode } from 'react';
import { Meta, StoryObj } from '@storybook/react';
import { Board } from '../Board';
import { initialBoard, items } from './mock-data';
const meta: Meta<typeof Board> = {
title: 'UI/Board/Board',
component: Board,
};
export default meta;
type Story = StoryObj<typeof Board>;
export const OneColumnBoard: Story = {
render: () => (
<StrictMode>
<Board initialBoard={initialBoard} items={items} />
</StrictMode>
),
};

View File

@ -0,0 +1,55 @@
import { Column, Items } from '../../../ui/components/board/Board';
export const items: Items = {
'item-1': { id: 'item-1', content: 'Item 1' },
'item-2': { id: 'item-2', content: 'Item 2' },
'item-3': { id: 'item-3', content: 'Item 3' },
'item-4': { id: 'item-4', content: 'Item 4' },
'item-5': { id: 'item-5', content: 'Item 5' },
'item-6': { id: 'item-6', content: 'Item 6' },
};
for (let i = 7; i <= 20; i++) {
const key = `item-${i}`;
items[key] = { id: key, content: `Item ${i}` };
}
export const initialBoard = [
{
id: 'column-1',
title: 'New',
colorCode: '#B76796',
itemKeys: [
'item-1',
'item-2',
'item-3',
'item-4',
'item-7',
'item-8',
'item-9',
],
},
{
id: 'column-2',
title: 'Screening',
colorCode: '#CB912F',
itemKeys: ['item-5', 'item-6'],
},
{
id: 'column-3',
colorCode: '#9065B0',
title: 'Meeting',
itemKeys: [],
},
{
id: 'column-4',
title: 'Proposal',
colorCode: '#337EA9',
itemKeys: [],
},
{
id: 'column-5',
colorCode: '#079039',
title: 'Customer',
itemKeys: [],
},
] satisfies Column[];