Task-Based Team Discussion Board

Task-Based Team Discussion Board

Create a New Task

${d.user}:

${d.text}

`).join(''); card.innerHTML = `

${task.title}

Assignee: ${task.assignee}

Discussion
${discussionsHtml}
`; return card; }; /** * Populates the assignee dropdown in the task creation form. */ const populateAssigneeDropdown = () => { taskAssigneeSelect.innerHTML = teamMembers.map(m => ``).join(''); }; /** * Handles the creation of a new task from the form. */ const handleTaskSubmit = (e) => { e.preventDefault(); const title = document.getElementById('taskTitle').value; const assignee = taskAssigneeSelect.value; if (!title.trim()) { alert('Please enter a task title.'); return; } const newTask = { id: nextTaskId++, title: title, assignee: assignee, status: 'To Do', discussions: [] }; tasks.push(newTask); taskForm.reset(); renderBoard(); }; /** * Generates and downloads a PDF report of all tasks. */ const downloadPDF = () => { const { jsPDF } = window.jspdf; const doc = new jsPDF(); doc.setFontSize(22); doc.text('Task Discussion Report', 14, 20); let yPos = 30; tasks.forEach(task => { if (yPos > 260) { doc.addPage(); yPos = 20; } doc.setFontSize(14); doc.setFont('helvetica', 'bold'); doc.text(`Task: ${task.title}`, 14, yPos); yPos += 7; doc.setFontSize(10); doc.setFont('helvetica', 'normal'); doc.text(`Assignee: ${task.assignee} | Status: ${task.status}`, 14, yPos); yPos += 7; if (task.discussions.length > 0) { doc.setFont('helvetica', 'bold'); doc.text('Discussion:', 14, yPos); yPos += 5; doc.setFont('helvetica', 'normal'); task.discussions.forEach(comment => { if (yPos > 270) { doc.addPage(); yPos = 20; } const splitText = doc.splitTextToSize(`- ${comment.user}: ${comment.text}`, 180); doc.text(splitText, 16, yPos); yPos += (splitText.length * 4) + 2; }); } yPos += 5; // Extra space between tasks }); doc.save('task-discussion-report.pdf'); }; // --- Event Listeners --- taskForm.addEventListener('submit', handleTaskSubmit); pdfDownloadBtn.addEventListener('click', downloadPDF); // Event delegation for dynamic elements on the board kanbanBoard.addEventListener('change', (e) => { if (e.target.classList.contains('status-select')) { const taskId = parseInt(e.target.dataset.taskId); const newStatus = e.target.value; const task = tasks.find(t => t.id === taskId); if (task) { task.status = newStatus; renderBoard(); // Re-render to move the card } } }); kanbanBoard.addEventListener('click', (e) => { if (e.target.classList.contains('add-comment-btn')) { const card = e.target.closest('.task-card'); const taskId = parseInt(card.dataset.taskId); const task = tasks.find(t => t.id === taskId); const textarea = card.querySelector('.discussion-input'); const commentText = textarea.value.trim(); if (task && commentText) { // For simplicity, we'll use the assignee's name as the commenter task.discussions.push({ user: task.assignee, text: commentText }); textarea.value = ''; renderBoard(); // Re-render to show the new comment } } }); // --- Initial Setup --- const initializeTool = () => { populateAssigneeDropdown(); renderBoard(); }; initializeTool(); });
Scroll to Top