109 lines
6.8 KiB
TypeScript
109 lines
6.8 KiB
TypeScript
import { useState } from 'react'
|
|
import { taskTypes, taskStatuses } from './consts';
|
|
import { EnumSelect } from './enum-select';
|
|
|
|
export function TaskRow({ task, updateTask, deleteTask, orderTasks }: TaskProps & { task: TodoTask }) {
|
|
const [edit, setEdit] = useState(false);
|
|
const [classnames, setClassnames] = useState<string[]>([]);
|
|
|
|
return (
|
|
<form
|
|
className={["tr", ...classnames].join(' ')}
|
|
onSubmit={event => {
|
|
event.preventDefault();
|
|
|
|
const data = Object.fromEntries(new FormData(event.currentTarget));
|
|
|
|
updateTask({
|
|
id: task.id,
|
|
type: data.type as TaskType,
|
|
title: data.title as string,
|
|
status: data.status as TaskStatus,
|
|
});
|
|
|
|
setEdit(false)
|
|
}}
|
|
draggable
|
|
onDragStart={event => {
|
|
event.dataTransfer.setData('text/plain', task.id.toString());
|
|
event.dataTransfer.effectAllowed = 'move';
|
|
setClassnames(['dragged'])
|
|
}}
|
|
onDragOver={event => {
|
|
event.preventDefault();
|
|
const fromId = +event.dataTransfer.getData('text/plain');
|
|
if (fromId !== task.id) {
|
|
setClassnames(['dropover']);
|
|
}
|
|
}}
|
|
onDragLeave={event => {
|
|
const fromId = +event.dataTransfer.getData('text/plain');
|
|
if (fromId !== task.id) {
|
|
setClassnames([])
|
|
}
|
|
}}
|
|
onDrop={event => {
|
|
event.stopPropagation();
|
|
setClassnames([])
|
|
orderTasks(+event.dataTransfer.getData('text/plain'), task.id);
|
|
}}
|
|
onDragEnd={() => {
|
|
setClassnames([])
|
|
}}
|
|
>
|
|
<div className="td">
|
|
<svg className="w-5 h-5 stroke-neutral-200" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M21 10L3 10M21 14L3 14M12 4L12 10M12 14L12 20M15 18L12 21L9 18M15 6L12 3L9 6" strokeWidth="1" strokeLinecap="round" strokeLinejoin="round"></path>
|
|
</svg>
|
|
</div>
|
|
<div className="td">
|
|
{edit
|
|
? <EnumSelect entries={taskTypes} name="type" defaultValue={task.type} />
|
|
: taskTypes[task.type]
|
|
}
|
|
</div>
|
|
<div className="td">
|
|
{edit
|
|
? <input type="text" name="title" defaultValue={task.title} />
|
|
: task.title}
|
|
</div>
|
|
<div className="td">
|
|
{edit
|
|
? <EnumSelect entries={taskStatuses} name="status" defaultValue={task.status} />
|
|
: taskStatuses[task.status]
|
|
}
|
|
</div>
|
|
<div className="td">
|
|
{edit ? <>
|
|
<button type="submit" className="mr-3">
|
|
<svg className="w-5 h-5 fill-indigo-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
|
|
<path d="M 25 2 C 12.317 2 2 12.317 2 25 C 2 37.683 12.317 48 25 48 C 37.683 48 48 37.683 48 25 C 48 20.44 46.660281 16.189328 44.363281 12.611328 L 42.994141 14.228516 C 44.889141 17.382516 46 21.06 46 25 C 46 36.579 36.579 46 25 46 C 13.421 46 4 36.579 4 25 C 4 13.421 13.421 4 25 4 C 30.443 4 35.393906 6.0997656 39.128906 9.5097656 L 40.4375 7.9648438 C 36.3525 4.2598437 30.935 2 25 2 z M 43.236328 7.7539062 L 23.914062 30.554688 L 15.78125 22.96875 L 14.417969 24.431641 L 24.083984 33.447266 L 44.763672 9.046875 L 43.236328 7.7539062 z"></path>
|
|
</svg>
|
|
</button>
|
|
<button type="button" onClick={event => {
|
|
event.preventDefault()
|
|
setEdit(false)
|
|
}}>
|
|
<svg className="w-5 h-5 fill-indigo-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
|
|
<path d="M 25 2 C 12.309534 2 2 12.309534 2 25 C 2 37.690466 12.309534 48 25 48 C 37.690466 48 48 37.690466 48 25 C 48 12.309534 37.690466 2 25 2 z M 25 4 C 36.609534 4 46 13.390466 46 25 C 46 36.609534 36.609534 46 25 46 C 13.390466 46 4 36.609534 4 25 C 4 13.390466 13.390466 4 25 4 z M 32.990234 15.986328 A 1.0001 1.0001 0 0 0 32.292969 16.292969 L 25 23.585938 L 17.707031 16.292969 A 1.0001 1.0001 0 0 0 16.990234 15.990234 A 1.0001 1.0001 0 0 0 16.292969 17.707031 L 23.585938 25 L 16.292969 32.292969 A 1.0001 1.0001 0 1 0 17.707031 33.707031 L 25 26.414062 L 32.292969 33.707031 A 1.0001 1.0001 0 1 0 33.707031 32.292969 L 26.414062 25 L 33.707031 17.707031 A 1.0001 1.0001 0 0 0 32.990234 15.986328 z"></path>
|
|
</svg>
|
|
</button>
|
|
</> : <>
|
|
<button type="button" className="mr-3" onClick={event => {
|
|
event.preventDefault()
|
|
setEdit(true)
|
|
}}>
|
|
<svg className="w-5 h-5 fill-indigo-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
|
|
<path d="M 43.125 2 C 41.878906 2 40.636719 2.488281 39.6875 3.4375 L 38.875 4.25 L 45.75 11.125 C 45.746094 11.128906 46.5625 10.3125 46.5625 10.3125 C 48.464844 8.410156 48.460938 5.335938 46.5625 3.4375 C 45.609375 2.488281 44.371094 2 43.125 2 Z M 37.34375 6.03125 C 37.117188 6.0625 36.90625 6.175781 36.75 6.34375 L 4.3125 38.8125 C 4.183594 38.929688 4.085938 39.082031 4.03125 39.25 L 2.03125 46.75 C 1.941406 47.09375 2.042969 47.457031 2.292969 47.707031 C 2.542969 47.957031 2.90625 48.058594 3.25 47.96875 L 10.75 45.96875 C 10.917969 45.914063 11.070313 45.816406 11.1875 45.6875 L 43.65625 13.25 C 44.054688 12.863281 44.058594 12.226563 43.671875 11.828125 C 43.285156 11.429688 42.648438 11.425781 42.25 11.8125 L 9.96875 44.09375 L 5.90625 40.03125 L 38.1875 7.75 C 38.488281 7.460938 38.578125 7.011719 38.410156 6.628906 C 38.242188 6.246094 37.855469 6.007813 37.4375 6.03125 C 37.40625 6.03125 37.375 6.03125 37.34375 6.03125 Z"></path>
|
|
</svg>
|
|
</button>
|
|
<button type="button" onClick={() => deleteTask(task.id)}>
|
|
<svg className="w-5 h-5 fill-indigo-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
|
|
<path d="M 21 2 C 19.354545 2 18 3.3545455 18 5 L 18 7 L 10.154297 7 A 1.0001 1.0001 0 0 0 9.984375 6.9863281 A 1.0001 1.0001 0 0 0 9.8398438 7 L 8 7 A 1.0001 1.0001 0 1 0 8 9 L 9 9 L 9 45 C 9 46.645455 10.354545 48 12 48 L 38 48 C 39.645455 48 41 46.645455 41 45 L 41 9 L 42 9 A 1.0001 1.0001 0 1 0 42 7 L 40.167969 7 A 1.0001 1.0001 0 0 0 39.841797 7 L 32 7 L 32 5 C 32 3.3545455 30.645455 2 29 2 L 21 2 z M 21 4 L 29 4 C 29.554545 4 30 4.4454545 30 5 L 30 7 L 20 7 L 20 5 C 20 4.4454545 20.445455 4 21 4 z M 11 9 L 18.832031 9 A 1.0001 1.0001 0 0 0 19.158203 9 L 30.832031 9 A 1.0001 1.0001 0 0 0 31.158203 9 L 39 9 L 39 45 C 39 45.554545 38.554545 46 38 46 L 12 46 C 11.445455 46 11 45.554545 11 45 L 11 9 z M 18.984375 13.986328 A 1.0001 1.0001 0 0 0 18 15 L 18 40 A 1.0001 1.0001 0 1 0 20 40 L 20 15 A 1.0001 1.0001 0 0 0 18.984375 13.986328 z M 24.984375 13.986328 A 1.0001 1.0001 0 0 0 24 15 L 24 40 A 1.0001 1.0001 0 1 0 26 40 L 26 15 A 1.0001 1.0001 0 0 0 24.984375 13.986328 z M 30.984375 13.986328 A 1.0001 1.0001 0 0 0 30 15 L 30 40 A 1.0001 1.0001 0 1 0 32 40 L 32 15 A 1.0001 1.0001 0 0 0 30.984375 13.986328 z"></path>
|
|
</svg>
|
|
</button>
|
|
</>}
|
|
</div>
|
|
</form>
|
|
);
|
|
} |