- Eine abhängige Aufgabe bleibt gesperrt (in "Offen"), bis jede Voraussetzung in "Wartet" oder "Erledigt" steht – vorher erst bei "Erledigt" - Server (UNLOCKING), Karte, Dialog und Meldungen angepasst; Test prüft "In Arbeit" (gesperrt) und "Wartet" (frei) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
2.2 KiB
React
61 lines
2.2 KiB
React
import { initials, PRIORITIES, UNLOCKING } from './board.js';
|
|
|
|
// Karte einer Aufgabe im Board (ziehbar) und Anzeige des Bearbeiters
|
|
|
|
export function Assignee({ id, users }) {
|
|
const person = users.find((u) => u.id === id);
|
|
if (!person) return <span className="assignee none">Niemand</span>;
|
|
return (
|
|
<span className="assignee">
|
|
<span className="avatar" aria-hidden="true">{initials(person.name)}</span>
|
|
{person.name}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
// Titel der Voraussetzungen, die noch nicht in "Wartet" oder "Erledigt" stehen
|
|
export function waitingFor(task, tasks) {
|
|
return (task.requires || [])
|
|
.map((id) => tasks.find((t) => t.id === id))
|
|
.filter((t) => t && !UNLOCKING.includes(t.status))
|
|
.map((t) => t.title);
|
|
}
|
|
|
|
export default function TaskCard({ task, users, waitingFor: waiting = [], dragging, onOpen, onDragStart, onDragEnd }) {
|
|
const done = task.checklist?.filter((c) => c.done).length ?? 0;
|
|
const total = task.checklist?.length ?? 0;
|
|
return (
|
|
<button
|
|
type="button"
|
|
className={`task-card prio-card-${task.priority}${dragging ? ' dragging' : ''}${task.blocked ? ' blocked' : ''}`}
|
|
draggable
|
|
onDragStart={onDragStart}
|
|
onDragEnd={onDragEnd}
|
|
onClick={onOpen}
|
|
>
|
|
<span className="task-top">
|
|
<strong className="task-title">{task.title}</strong>
|
|
{task.priority !== 'mittel' && (
|
|
<span className={`prio prio-${task.priority}`} title={`Priorität: ${PRIORITIES.find((p) => p.key === task.priority)?.title}`}>
|
|
{PRIORITIES.find((p) => p.key === task.priority)?.title}
|
|
</span>
|
|
)}
|
|
</span>
|
|
{task.description && <span className="task-desc">{task.description}</span>}
|
|
{task.blocked && (
|
|
<span className="task-blocked" title="Gesperrt, bis die Voraussetzungen in „Wartet“ oder „Erledigt“ stehen">
|
|
<span aria-hidden="true">🔒</span> wartet auf {waiting.join(', ') || 'Voraussetzungen'}
|
|
</span>
|
|
)}
|
|
<span className="task-meta">
|
|
<Assignee id={task.assignee} users={users} />
|
|
{total > 0 && (
|
|
<span className={`task-checks${done === total ? ' complete' : ''}`} title="Checkliste">
|
|
☑ {done}/{total}
|
|
</span>
|
|
)}
|
|
</span>
|
|
</button>
|
|
);
|
|
}
|