Skip to content

Instantly share code, notes, and snippets.

@rethna2
Created December 19, 2018 09:08
Show Gist options
  • Save rethna2/c89a6e30dfc96296a1ddb6e1911a6bda to your computer and use it in GitHub Desktop.
Save rethna2/c89a6e30dfc96296a1ddb6e1911a6bda to your computer and use it in GitHub Desktop.
A quick demo on how to use React-dnd library
import React from "react";
import { DragDropContext, DropTarget, DragSource } from "react-dnd";
import HTML5Backend from "react-dnd-html5-backend";
import update from "immutability-helper";
const tasks = [
{ _id: 1, title: "First Task", status: "backlog" },
{ _id: 2, title: "Second Task", status: "backlog" },
{ _id: 3, title: "Third Task", status: "backlog" },
{ _id: 4, title: "Fourth Task", status: "new" },
{ _id: 5, title: "Fifth Task", status: "new" },
{ _id: 6, title: "Sixth Task", status: "wip" },
{ _id: 7, title: "Seventh Task", status: "review" },
{ _id: 8, title: "Eighth Task", status: "review" },
{ _id: 9, title: "Ninth Task", status: "done" },
{ _id: 10, title: "Tenth Task", status: "done" }
];
const channels = ["backlog", "new", "wip", "review", "done"];
const labelsMap = {
backlog: "Backlog",
new: "To Do",
wip: "In Progress",
review: "Review",
done: "Done"
};
const classes = {
board: {
display: "flex",
margin: "0 auto",
width: "90vw",
fontFamily: 'Arial, "Helvetica Neue", sans-serif'
},
column: {
minWidth: 200,
width: "18vw",
height: "80vh",
margin: "0 auto",
backgroundColor: "#FCC8B2"
},
columnHead: {
textAlign: "center",
padding: 10,
fontSize: "1.2em",
backgroundColor: "#C6D8AF"
},
item: {
padding: 10,
margin: 10,
fontSize: "0.8em",
cursor: "pointer",
backgroundColor: "white"
}
};
class Kanban extends React.Component {
constructor(props) {
super(props);
this.state = {
tasks
};
}
update = (id, status) => {
const { tasks } = this.state;
const task = tasks.find(task => task._id === id);
task.status = status;
const taskIndex = tasks.indexOf(task);
const newTasks = update(tasks, {
[taskIndex]: { $set: task }
});
this.setState({ tasks: newTasks });
};
render() {
const { tasks } = this.state;
return (
<main>
<header> Kanban Board </header>
<section style={classes.board}>
{channels.map(channel => (
<KanbanColumn status={channel}>
<div style={classes.column}>
<div style={classes.columnHead}>{labelsMap[channel]}</div>
<div>
{tasks
.filter(item => item.status === channel)
.map(item => (
<KanbanItem id={item._id} onDrop={this.update}>
<div style={classes.item}>{item.title}</div>
</KanbanItem>
))}
</div>
</div>
</KanbanColumn>
))}
</section>
</main>
);
}
}
export default DragDropContext(HTML5Backend)(Kanban);
// Column
const boxTarget = {
drop(props) {
return { name: props.status };
}
};
class KanbanColumn extends React.Component {
render() {
return this.props.connectDropTarget(<div>{this.props.children}</div>);
}
}
KanbanColumn = DropTarget("kanbanItem", boxTarget, (connect, monitor) => ({
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver(),
canDrop: monitor.canDrop()
}))(KanbanColumn);
// Item
const boxSource = {
beginDrag(props) {
return {
name: props.id
};
},
endDrag(props, monitor) {
const item = monitor.getItem();
const dropResult = monitor.getDropResult();
if (dropResult) {
props.onDrop(monitor.getItem().name, dropResult.name);
}
}
};
class KanbanItem extends React.Component {
render() {
return this.props.connectDragSource(<div>{this.props.children}</div>);
}
}
KanbanItem = DragSource("kanbanItem", boxSource, (connect, monitor) => ({
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging()
}))(KanbanItem);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment