// Kanban view: 4 columns with HTML5 drag-and-drop. Filtered by activeProjectId.
const KBIcons = window.Icons;
const { COLUMNS: KBCOLS, taskProgress: kbProgress, relativeDate: kbRel, isOverdue: kbOverdue } = window.PMStore;
const { Tag: KBTag, Priority: KBPriority } = window.UI;
function Kanban({ state, onSelectTask, onUpdateTask, onDeleteTask, onAddTask, query }) {
const [dragTaskId, setDragTaskId] = React.useState(null);
const [dragOverCol, setDragOverCol] = React.useState(null);
const tagById = Object.fromEntries(state.tags.map(t => [t.id, t]));
const activeProject = state.projects.find(p => p.id === state.activeProjectId);
const filtered = state.tasks.filter(t => {
if (t.projectId !== state.activeProjectId) return false;
if (!query) return true;
const q = query.toLowerCase();
return t.title.toLowerCase().includes(q) ||
(t.description||'').toLowerCase().includes(q) ||
t.tags.some(tid => (tagById[tid]?.name || '').toLowerCase().includes(q));
});
const tasksByCol = Object.fromEntries(KBCOLS.map(c => [c.id, []]));
filtered.forEach(t => { (tasksByCol[t.status] || tasksByCol.todo).push(t); });
const handleDrop = (e, colId) => {
e.preventDefault();
if (dragTaskId) {
onUpdateTask(dragTaskId, { status: colId });
}
setDragTaskId(null);
setDragOverCol(null);
};
if (!activeProject) {
return (
Proje seçilmedi
Soldaki listeden bir proje seçin.
);
}
return (
{KBCOLS.map(col => (
{col.label}
{tasksByCol[col.id].length}
{ e.preventDefault(); setDragOverCol(col.id); }}
onDragLeave={(e) => {
if (e.currentTarget === e.target) setDragOverCol(null);
}}
onDrop={(e) => handleDrop(e, col.id)}
>
{tasksByCol[col.id].map(t => (
setDragTaskId(t.id)}
onDragEnd={() => { setDragTaskId(null); setDragOverCol(null); }}
onClick={() => onSelectTask(t.id)}
onUpdateStatus={(status) => onUpdateTask(t.id, { status })}
onDelete={() => onDeleteTask(t.id)}
/>
))}
{tasksByCol[col.id].length === 0 && (
Henüz görev yok
)}
))}
);
}
function TaskCard({ task, tagById, dragging, onDragStart, onDragEnd, onClick, onUpdateStatus, onDelete }) {
const pct = kbProgress(task);
const overdueT = kbOverdue(task.due, task.status);
const taskTags = (task.tags || []).map(id => tagById[id]).filter(Boolean);
const subtaskDone = (task.subtasks || []).filter(s => s.done).length;
const subtaskTotal = (task.subtasks || []).length;
return (
{
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/plain', task.id);
onDragStart();
}}
onDragEnd={onDragEnd}
onClick={onClick}
>
e.stopPropagation()}>
{taskTags.length > 0 && (
{taskTags.slice(0, 3).map(tag => )}
)}
{task.title}
{subtaskTotal > 0 && (
<>
>
)}
{task.due && (
{kbRel(task.due)}
)}
{subtaskTotal > 0 && (
{subtaskDone}/{subtaskTotal}
)}
e.stopPropagation()}>
Durum
);
}
window.Kanban = Kanban;