Kanban: Checklisten und Voraussetzungen zwischen Aufgaben
- Checkliste je Aufgabe (Tabelle kanban_checklist): im Dialog anlegen, abhaken, entfernen; Karte zeigt den Fortschritt - "Setzt voraus" (Tabelle kanban_dependencies): Aufgabe ist gesperrt und bleibt in "Offen", bis alle Voraussetzungen erledigt sind; nur innerhalb eines Projekts, Kreise und Selbstbezug werden abgelehnt; gelöschte Voraussetzungen entsperren, archivierte zählen als erledigt - Ziehen einer gesperrten Karte aus "Offen" zeigt, worauf sie wartet - Migrationen: Tabellen-Neuaufbau über Zwischennamen, damit Fremdschlüssel anderer Tabellen nicht auf die gelöschte Alt-Tabelle umgebogen werden (Test für ganz alte Datenbanken) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a1a1998d1e
commit
9df0e38f52
10 files changed
+375
-28
No files matched your search
@@ -13,11 +13,21 @@ export function Assignee({ id, users }) {
|
||||
);
|
||||
}
|
||||
|
||||
export default function TaskCard({ task, users, dragging, onOpen, onDragStart, onDragEnd }) {
|
||||
// Titel der noch offenen Voraussetzungen einer Aufgabe
|
||||
export function waitingFor(task, tasks) {
|
||||
return (task.requires || [])
|
||||
.map((id) => tasks.find((t) => t.id === id))
|
||||
.filter((t) => t && t.status !== 'erledigt')
|
||||
.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' : ''}`}
|
||||
className={`task-card prio-card-${task.priority}${dragging ? ' dragging' : ''}${task.blocked ? ' blocked' : ''}`}
|
||||
draggable
|
||||
onDragStart={onDragStart}
|
||||
onDragEnd={onDragEnd}
|
||||
@@ -32,8 +42,18 @@ export default function TaskCard({ task, users, dragging, onOpen, onDragStart, o
|
||||
)}
|
||||
</span>
|
||||
{task.description && <span className="task-desc">{task.description}</span>}
|
||||
{task.blocked && (
|
||||
<span className="task-blocked" title="Gesperrt, bis die Voraussetzungen erledigt sind">
|
||||
<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>
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user