Task Breakdown Assistant
Task Hierarchy
Breakdown Summary
Tips for Effective Task Breakdown
- 1. Start with the Main Goal
- Clearly define the overall project or the largest task you want to accomplish.
- 2. Identify Major Phases or Deliverables
- Break the main goal into high-level components or phases. These become your first level of tasks.
- 3. Decompose Further
- For each major task, ask "What smaller steps are needed to complete this?" Continue breaking down tasks until they are manageable and actionable.
- 4. Aim for Manageable Chunks
- A common rule of thumb is that a task should be small enough to be completed by one person (or a small team) in a reasonable timeframe (e.g., a few hours to a few days). If a task seems too big, break it down further.
- 5. Ensure Clarity
- Each task should have a clear description so that anyone involved understands what needs to be done.
- 6. Define Outputs/Deliverables
- For each task, know what the expected output or result is. This helps in determining when the task is truly "Completed".
- 7. The 100% Rule (WBS Principle)
- The sum of all sub-tasks should represent the entirety of the work required for their parent task. Avoid gold-plating or missing scope.
- 8. Review and Refine
- Once you have an initial breakdown, review it. Does it make sense? Are there any gaps? Is anything unclear? Get feedback if possible.
×
Add New Task
No tasks yet. Click "Add Root Task" to start breaking down your project.
${totalTasks}Total Tasks
${statusCounts["To Do"]}To Do
${statusCounts["In Progress"]}In Progress
${statusCounts["Completed"]}Completed
`;
}
// --- PDF Export ---
function tbaAddTasksToPdf(doc, tasks, level, currentY, lineheight, startX) {
let y = currentY;
const indentSpace = " "; // 4 spaces for indentation per level
tasks.forEach(task => {
if (y > 270) { // Check for page break
doc.addPage();
y = 20; // Reset Y for new page
}
let taskText = `${indentSpace.repeat(level)}${level > 0 ? '\u2022 ' : ''}${task.name}`;
doc.text(taskText, startX, y);
y += (lineheight * 0.7); // Smaller line for details
let detailsText = "";
if (task.effort) detailsText += `Effort: ${task.effort} | `;
if (task.assignee) detailsText += `Assignee: ${task.assignee} | `;
if (task.status) detailsText += `Status: ${task.status}`;
if(detailsText.endsWith(" | ")) detailsText = detailsText.slice(0, -3);
if (detailsText) {
if (y > 275) { doc.addPage(); y = 20; }
doc.setFontSize(8);
doc.setTextColor(80); // Lighter text for details
doc.text(`${indentSpace.repeat(level + 1)}${detailsText}`, startX, y);
doc.setFontSize(10); // Reset font size
doc.setTextColor(40); // Reset text color
y += lineheight * 0.8;
}
y += lineheight * 0.4; // Spacing after task item
if (task.children && task.children.length > 0) {
y = tbaAddTasksToPdf(doc, task.children, level + 1, y, lineheight, startX);
}
});
return y;
}
if(tbaDownloadPdfBtn) {
tbaDownloadPdfBtn.addEventListener('click', function() {
const { jsPDF } = window.jspdf; // Ensure jsPDF is from the global scope
const doc = new jsPDF();
const projectName = tbaProjectData.projectName || "Task Breakdown";
const reportDate = new Date().toLocaleDateString();
const primaryColor = getComputedStyle(document.documentElement).getPropertyValue('--tba-primary-color').trim();
doc.setFontSize(18);
doc.setTextColor(primaryColor);
doc.text(projectName, 14, 22);
doc.setFontSize(10);
doc.setTextColor(100);
doc.text(`Report Date: ${reportDate}`, 14, 30);
doc.setFontSize(10);
doc.setTextColor(40); // Default text color for tasks
tbaAddTasksToPdf(doc, tbaProjectData.tasks, 0, 40, 7, 14); // startY, lineheight, startX
doc.save(`${projectName.replace(/\s+/g, '_')}_Breakdown_${reportDate.replace(/\//g, '-')}.pdf`);
});
}
// --- Initialization ---
document.addEventListener('DOMContentLoaded', () => {
tbaLoadData();
const firstTabButton = document.querySelector('#taskBreakdownAssistantTool .tba-tab-button');
if (firstTabButton) {
firstTabButton.click();
}
// Close modal if clicked outside
window.addEventListener('click', function(event) {
const modal = document.getElementById('tbaTaskModal');
if (modal && event.target == modal) {
tbaCloseModal('tbaTaskModal');
}
});
});
