Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/components/Kanban/Kanban.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ WithCards.args = {
rows: [
{
name: "two",
id: "12",
},
],
},
Expand All @@ -37,9 +38,11 @@ WithCards.args = {
rows: [
{
name: "three",
id: "1",
},
{
name: "fsdf",
id: "2",
},
],
},
Expand Down
63 changes: 50 additions & 13 deletions src/components/Kanban/Kanban.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React, { useState } from "react";
import { Box } from "grommet";
import {
Droppable,
Expand All @@ -14,7 +14,7 @@ export interface KColumn {
title?: string;
ttl?: number;
menu?: { label: string; onClick?: any }[];
rows?: any[];
rows: any[];
}

export interface BaseKanbanProps {
Expand All @@ -25,7 +25,7 @@ export interface BaseKanbanProps {

renderCard?: (item?: any) => any;
onDrag?: (result: DropResult) => void;

onCreateColumn?: () => void;
columns?: Array<KColumn>;
}
Expand All @@ -39,22 +39,59 @@ export const Kanban: React.FC<BaseKanbanProps> = ({
onCreateColumn,
columns = [],
}) => {
// USING REACT STATE TO UPDATE COLOMNS AS THEY ARE DRAGGED

const [columnsState, setColumnsState] = useState(columns);
const onDragEnd = (result: DropResult) => {
console.log(result);

let origin: number = parseInt(result.source.droppableId);
let dest = result.destination?.droppableId;

if (dest) {
let item_ix = columns[origin].rows
?.map((x) => x.id)
.indexOf(result.draggableId);
if (item_ix && item_ix > -1) {
let item = columns[origin].rows?.splice(item_ix, 1);
columns[parseInt(dest)].rows?.push(item);
}
if (!result.destination) return;
// IF THER MOVE IS INVALID
else if (origin !== parseInt(dest!)) {
// IF THE ITEM IS MOVED TO ANOTHER COLUMN
const items = Array.from(columns[origin].rows);
const itemsDest = Array.from(columns[parseInt(dest!)].rows);

const [reorderedItem] = items.splice(result.source.index, 1);
itemsDest.splice(result.destination.index, 0, reorderedItem);

console.log(items, itemsDest);

let newColumns = [...columns];

newColumns[origin].rows = items;
newColumns[parseInt(dest!)].rows = itemsDest;

setColumnsState(newColumns);
} else {
// IF THE ITEM IS MOVED TO THE SAME COLUMN
const items = Array.from(columns[origin].rows);

const [reorderedItem] = items.splice(result.source.index, 1);
items.splice(result.destination.index, 0, reorderedItem);

let newColumns = [...columns];

newColumns[origin].rows = items;

setColumnsState(newColumns);
}

// if (dest) {
// let item_ix = columns[origin].rows
// ?.map((x) => x.id)
// .indexOf(result.draggableId);
// console.log(item_ix);

// if (item_ix && item_ix > -1) {
// let item = columns[origin].rows?.splice(item_ix, 1);
// columns[parseInt(dest)].rows?.push(item);
// }
// }

// onChange?.(columns)
};

Expand Down Expand Up @@ -91,15 +128,15 @@ export const Kanban: React.FC<BaseKanbanProps> = ({
<Box>
{onCreateColumn && <KanbanCreateColumn onCreate={onCreateColumn} />}
</Box>

{provided.placeholder}
</Box>
)}
</Droppable>
);

return (
<DragDropContext onDragEnd={onDrag || onDragEnd}>
<DragDropContext onDragEnd={onDragEnd || onDrag}>
<Box flex>{board}</Box>
</DragDropContext>
);
Expand Down
134 changes: 67 additions & 67 deletions src/components/Kanban/KanbanColumn.tsx
Original file line number Diff line number Diff line change
@@ -1,62 +1,64 @@
import { Box, Text, Heading, Button } from 'grommet';
import React from 'react';
import { More } from 'grommet-icons'
import { Draggable, DraggableProvided, DraggableStateSnapshot } from 'react-beautiful-dnd';
import { KanbanList } from './KanbanList';
import { KanbanColumnMenu } from './KanbanColumnMenu';
import { dateFromObjectID } from '@hexhive/utils';

import { Box, Text, Heading, Button } from "grommet";
import React from "react";
import { More } from "grommet-icons";
import {
Draggable,
DraggableProvided,
DraggableStateSnapshot,
} from "react-beautiful-dnd";
import { KanbanList } from "./KanbanList";
import { KanbanColumnMenu } from "./KanbanColumnMenu";
import { dateFromObjectID } from "@hexhive/utils";

export interface KanbanColumnProps {
title?: string;
ttl?: number;
menu?: {
label?: string;
onClick?: string;
}[]
index?: number;
items?: any[];
title?: string;
ttl?: number;
menu?: {
label?: string;
onClick?: string;
}[];
index?: number;
items?: any[];

isCombineEnabled?: boolean,
useClone?: boolean,
isScrollable?: boolean;
renderCard?: any;
isCombineEnabled?: boolean;
useClone?: boolean;
isScrollable?: boolean;
renderCard?: any;
}

export const KanbanColumn : React.FC<KanbanColumnProps> = ({
title = '',
index = 0,
ttl,
items = [{status: 'Issued', name: ''}],
isCombineEnabled,
useClone,
isScrollable,
renderCard,
menu = []
export const KanbanColumn: React.FC<KanbanColumnProps> = ({
title = "",
index = 0,
ttl,
items = [{ status: "Issued", name: "" }],
isCombineEnabled,
useClone,
isScrollable,
renderCard,
menu = [],
}) => {
return (
<Box
overflow="hidden"
background="accent-1"
round="xsmall"
direction="column"
width="300px"
return (
<Box
overflow="hidden"
background="accent-1"
round="xsmall"
direction="column"
width="300px"
>
<Box
background="accent-2"
pad={{ horizontal: "xxsmall" }}
align="center"
justify="between"
border={{ side: "bottom", color: "dark-2" }}
direction="row"
>
<Heading margin="small" level="4">
{title}
</Heading>

>
<Box
background="accent-2"
pad={{horizontal: "xxsmall"}}
align="center"
justify="between"
border={{side: 'bottom', color: 'dark-2'}}
direction="row"
>
<Heading
margin="small"
level='4'>{title}</Heading>

<KanbanColumnMenu menu={menu} />
{/* <Box
<KanbanColumnMenu menu={menu} />
{/* <Box
style={{userSelect: 'none'}}
align="center"
justify="center"
Expand All @@ -67,18 +69,16 @@ export const KanbanColumn : React.FC<KanbanColumnProps> = ({
round="large">
<Text size="small">{items?.length}</Text>
</Box> */}
</Box>
<Box
pad="small"
overflow={{vertical: 'auto'}}
flex>
<KanbanList
droppableId={`${index}`}
renderCard={renderCard}
items={items.filter((a) => (!ttl || (Date.now() - dateFromObjectID(a.id).getTime()) < ttl))}/>

</Box>
</Box>

)
}
</Box>
<Box pad="small" overflow={{ vertical: "auto" }} flex>
<KanbanList
droppableId={`${index}`}
renderCard={renderCard}
items={items.filter(
(a) => !ttl || Date.now() - dateFromObjectID(a.id).getTime() < ttl
)}
/>
</Box>
</Box>
);
};
90 changes: 49 additions & 41 deletions src/components/Kanban/KanbanList.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,59 @@
import { Box } from 'grommet';
import React from 'react';
import { Draggable, DraggableProvided, DraggableStateSnapshot, Droppable, DroppableProps, DroppableProvided } from 'react-beautiful-dnd';
import { KanbanListItem } from './KanbanListItem';
import { Box } from "grommet";
import React from "react";
import {
Draggable,
DraggableProvided,
DraggableStateSnapshot,
Droppable,
DroppableProps,
DroppableProvided,
} from "react-beautiful-dnd";
import { KanbanListItem } from "./KanbanListItem";

export interface KanbanListProps{
items?: {id: string}[];
renderCard?: any;
droppableId?: string;
export interface KanbanListProps {
items?: { id: string }[];
renderCard?: any;
droppableId?: string;
}

export const KanbanList : React.FC<KanbanListProps> = (props) => {

return <Droppable
droppableId={props.droppableId || ''}
type="LIST">
{(
dropProvided: DroppableProvided
) => (
<Box
{...dropProvided.droppableProps}
ref={dropProvided.innerRef}
gap="small"
style={{minHeight: 'min-content'}}
pad={{vertical: 'small'}}
direction="column"
flex>
{props.items?.map((item, index) =>
export const KanbanList: React.FC<KanbanListProps> = (props) => {
return (
<Droppable droppableId={props.droppableId || ""} type="LIST">
{(dropProvided: DroppableProvided) => (
<Box
{...dropProvided.droppableProps}
ref={dropProvided.innerRef}
gap="small"
style={{ minHeight: "min-content" }}
pad={{ vertical: "small" }}
direction="column"
flex
>
{props.items?.map((item, index) => (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(
dragProvided: DraggableProvided,
dragSnapshot: DraggableStateSnapshot,
) => (
dragSnapshot: DraggableStateSnapshot
) => (
<Box
round="xsmall"
border={{side: 'all', color: 'lightblue', size: dragSnapshot.isDragging ? '2px' : '0px'}}
ref={dragProvided.innerRef}
{...dragProvided.draggableProps}
{...dragProvided.dragHandleProps}
>
{props?.renderCard?.(item) || 'div'}
round="xsmall"
border={{
side: "all",
color: "lightblue",
size: dragSnapshot.isDragging ? "2px" : "0px",
}}
ref={dragProvided.innerRef}
{...dragProvided.draggableProps}
{...dragProvided.dragHandleProps}
>
{props?.renderCard?.(item) || "div"}
</Box>
)}
)}
</Draggable>
)}
{dropProvided.placeholder}
))}
{dropProvided.placeholder}
</Box>
)}
</Droppable>

}
)}
</Droppable>
);
};