Separate task into a component
This commit is contained in:
parent
fcb90c6e27
commit
d978202f41
115
src/Board.tsx
115
src/Board.tsx
@ -1,34 +1,6 @@
|
|||||||
|
import { DragDropContext, Droppable } from "react-beautiful-dnd";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
|
import Task from './Task';
|
||||||
|
|
||||||
export type task = {
|
|
||||||
id: string,
|
|
||||||
name: string,
|
|
||||||
description: string,
|
|
||||||
column: string,
|
|
||||||
workload?: number,
|
|
||||||
remainingWorkload?: number,
|
|
||||||
progress?: number,
|
|
||||||
metadata: {
|
|
||||||
created: Date,
|
|
||||||
updated?: Date,
|
|
||||||
completed?: Date,
|
|
||||||
assigned?: string
|
|
||||||
},
|
|
||||||
relations: Array<{
|
|
||||||
type: string,
|
|
||||||
task: string
|
|
||||||
}>,
|
|
||||||
subTasks: Array<{
|
|
||||||
text: string,
|
|
||||||
completed: boolean
|
|
||||||
}>,
|
|
||||||
comments: Array<{
|
|
||||||
author: string,
|
|
||||||
date: Date,
|
|
||||||
text: string
|
|
||||||
}>
|
|
||||||
};
|
|
||||||
|
|
||||||
declare var acquireVsCodeApi: any;
|
declare var acquireVsCodeApi: any;
|
||||||
const vscode = acquireVsCodeApi();
|
const vscode = acquireVsCodeApi();
|
||||||
@ -44,7 +16,7 @@ const onDragEnd = (result, columns, setColumns) => {
|
|||||||
const { source, destination } = result;
|
const { source, destination } = result;
|
||||||
|
|
||||||
// The item that was moved
|
// The item that was moved
|
||||||
let removed: task;
|
let removed: KanbnTask;
|
||||||
|
|
||||||
// The task was dragged from one column to another
|
// The task was dragged from one column to another
|
||||||
if (source.droppableId !== destination.droppableId) {
|
if (source.droppableId !== destination.droppableId) {
|
||||||
@ -84,72 +56,53 @@ const onDragEnd = (result, columns, setColumns) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const Board = ({ columns }) => {
|
const Board = ({ columns, startedColumns, completedColumns }: {
|
||||||
|
columns: Record<string, KanbnTask[]>,
|
||||||
|
startedColumns: string[],
|
||||||
|
completedColumns: string[]
|
||||||
|
}) => {
|
||||||
const [, setColumns] = useState(columns);
|
const [, setColumns] = useState(columns);
|
||||||
return (
|
return (
|
||||||
<div style={{ display: "flex", justifyContent: "center", height: "100%" }}>
|
<div
|
||||||
|
className="kanbn-board"
|
||||||
|
style={{
|
||||||
|
display: "flex"
|
||||||
|
}}
|
||||||
|
>
|
||||||
<DragDropContext
|
<DragDropContext
|
||||||
onDragEnd={result => onDragEnd(result, columns, setColumns)}
|
onDragEnd={result => onDragEnd(result, columns, setColumns)}
|
||||||
>
|
>
|
||||||
{Object.entries(columns).map(([columnId, column]) => {
|
{Object.entries(columns).map(([columnName, column]) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
className="kanbn-column"
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
flex: 1
|
||||||
flexDirection: "column",
|
|
||||||
alignItems: "center"
|
|
||||||
}}
|
}}
|
||||||
key={columnId}
|
key={columnName}
|
||||||
>
|
>
|
||||||
<h2>{columnId}</h2>
|
<h2 className="kanbn-column-name">
|
||||||
<div style={{ margin: 8 }}>
|
{columnName}
|
||||||
<Droppable droppableId={columnId} key={columnId}>
|
<span className="kanbn-column-count">{column.length || ''}</span>
|
||||||
|
</h2>
|
||||||
|
{/*
|
||||||
|
// TODO codicons https://github.com/microsoft/vscode-extension-samples/tree/main/webview-codicons-sample
|
||||||
|
// TODO 'Add task' button next to each column header
|
||||||
|
// TODO show count next to header
|
||||||
|
*/}
|
||||||
|
<div>
|
||||||
|
<Droppable droppableId={columnName} key={columnName}>
|
||||||
{(provided, snapshot) => {
|
{(provided, snapshot) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
{...provided.droppableProps}
|
{...provided.droppableProps}
|
||||||
ref={provided.innerRef}
|
ref={provided.innerRef}
|
||||||
style={{
|
className={[
|
||||||
background: snapshot.isDraggingOver
|
'kanbn-column-task-list',
|
||||||
? "lightblue"
|
snapshot.isDraggingOver ? 'drag-over' : null
|
||||||
: "lightgrey",
|
].filter(i => i).join(' ')}
|
||||||
padding: 4,
|
|
||||||
width: 250,
|
|
||||||
minHeight: 500
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{(column as task[]).map((item, index) => {
|
{column.map((task, index) => <Task task={task} index={index} />)}
|
||||||
return (
|
|
||||||
<Draggable
|
|
||||||
key={item.id}
|
|
||||||
draggableId={item.id}
|
|
||||||
index={index}
|
|
||||||
>
|
|
||||||
{(provided, snapshot) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
ref={provided.innerRef}
|
|
||||||
{...provided.draggableProps}
|
|
||||||
{...provided.dragHandleProps}
|
|
||||||
style={{
|
|
||||||
userSelect: "none",
|
|
||||||
padding: 16,
|
|
||||||
margin: "0 0 8px 0",
|
|
||||||
minHeight: "50px",
|
|
||||||
backgroundColor: snapshot.isDragging
|
|
||||||
? "#263B4A"
|
|
||||||
: "#456C86",
|
|
||||||
color: "white",
|
|
||||||
...provided.draggableProps.style
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{item.name}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Draggable>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
{provided.placeholder}
|
{provided.placeholder}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
28
src/KanbnTask.d.ts
vendored
Normal file
28
src/KanbnTask.d.ts
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
declare type KanbnTask = {
|
||||||
|
id: string,
|
||||||
|
name: string,
|
||||||
|
description: string,
|
||||||
|
column: string,
|
||||||
|
workload?: number,
|
||||||
|
remainingWorkload?: number,
|
||||||
|
progress?: number,
|
||||||
|
metadata: {
|
||||||
|
created: Date,
|
||||||
|
updated?: Date,
|
||||||
|
completed?: Date,
|
||||||
|
assigned?: string
|
||||||
|
},
|
||||||
|
relations: Array<{
|
||||||
|
type: string,
|
||||||
|
task: string
|
||||||
|
}>,
|
||||||
|
subTasks: Array<{
|
||||||
|
text: string,
|
||||||
|
completed: boolean
|
||||||
|
}>,
|
||||||
|
comments: Array<{
|
||||||
|
author: string,
|
||||||
|
date: Date,
|
||||||
|
text: string
|
||||||
|
}>
|
||||||
|
};
|
49
src/Task.tsx
Normal file
49
src/Task.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Draggable } from "react-beautiful-dnd";
|
||||||
|
|
||||||
|
const Task = ({ task, index }: { task: KanbnTask, index: number }) => {
|
||||||
|
return (
|
||||||
|
<Draggable
|
||||||
|
key={task.id}
|
||||||
|
draggableId={task.id}
|
||||||
|
index={index}
|
||||||
|
>
|
||||||
|
{(provided, snapshot) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
ref={provided.innerRef}
|
||||||
|
{...provided.draggableProps}
|
||||||
|
{...provided.dragHandleProps}
|
||||||
|
className={[
|
||||||
|
'kanbn-task',
|
||||||
|
snapshot.isDragging ? 'drag' : null
|
||||||
|
].filter(i => i).join(' ')}
|
||||||
|
style={{
|
||||||
|
userSelect: "none",
|
||||||
|
...provided.draggableProps.style
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={e => null} // TODO open task editor modal when clicked
|
||||||
|
title={task.id}
|
||||||
|
>
|
||||||
|
{task.name}
|
||||||
|
</button>
|
||||||
|
{/*
|
||||||
|
// TODO add task info
|
||||||
|
truncated description (?),
|
||||||
|
progress as %-filled bottom border,
|
||||||
|
created/updated (updated date, fallback to created),
|
||||||
|
tags (provide default colours in css, put tagname in className),
|
||||||
|
count sub-tasks (if >0),
|
||||||
|
count comments (if >0)
|
||||||
|
*/}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Draggable>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Task;
|
Loading…
x
Reference in New Issue
Block a user