Progress-Based Task Sorting

Progress-Based Task Sorting

Task Summary

Tips for Managing Task Progress

1. Break Down Large Tasks
Smaller tasks are easier to estimate progress for and complete, giving a better sense of momentum.
2. Update Progress Regularly
Make it a habit to update the progress percentage of your tasks at consistent intervals (e.g., daily or at the end of work sessions). This keeps the board accurate.
3. Be Honest with Progress
Resist the urge to inflate progress. Accurate reporting helps in identifying real bottlenecks early.
4. Use Priorities Wisely
Assign priorities (High, Medium, Low) to help you decide what to work on next, especially within the same progress category.
5. Set Realistic Due Dates
If using due dates, ensure they are achievable. Overdue tasks can be demotivating, so use them as a planning guide.
6. Focus on "In Progress"
Try to limit the number of tasks "In Progress" at any one time (Work In Progress - WIP limit). This helps improve focus and throughput.
7. Review "Blocked" or "Stuck" Tasks
If a task isn't moving from "Early Stage" or "Mid Progress" for a long time, investigate why. It might need to be broken down further, or there might be an obstacle.
8. Celebrate Completions!
Moving tasks to "Completed" provides a sense of accomplishment and motivates further work.
×

Add New Task

No tasks here.

'; } else { tasksInCategory.forEach(task => { cardsContainerEl.appendChild(pbtsCreateTaskCard(task)); }); } columnEl.appendChild(cardsContainerEl); pbtsTaskBoardEl.appendChild(columnEl); }); } function pbtsCreateTaskCard(task) { const cardEl = document.createElement('div'); cardEl.className = 'pbts-task-card'; cardEl.setAttribute('data-task-id', task.id); // Priority border if(task.priority === "High") cardEl.style.borderLeftColor = 'var(--pbts-priority-high)'; else if(task.priority === "Medium") cardEl.style.borderLeftColor = 'var(--pbts-priority-medium)'; else cardEl.style.borderLeftColor = 'var(--pbts-priority-low)'; const isOverdue = pbtsIsOverdue(task.dueDate, task.progress); if(isOverdue) cardEl.classList.add('overdue'); let progressBarColor = 'var(--pbts-col-todo)'; if (task.progress === 100) progressBarColor = 'var(--pbts-col-completed)'; else if (task.progress >= 67) progressBarColor = 'var(--pbts-col-advanced)'; else if (task.progress >= 34) progressBarColor = 'var(--pbts-col-mid)'; else if (task.progress >= 1) progressBarColor = 'var(--pbts-col-early)'; cardEl.innerHTML = `
${task.name} ${isOverdue ? '(Overdue!)': ''}
Progress: ${task.progress}% ${task.priority}
${task.dueDate ? `
Due: ${pbtsFormatDateForDisplay(task.dueDate)}
` : ''}
`; return cardEl; } // --- Modal & Task CRUD --- window.pbtsOpenTaskModal = function(taskId = null) { pbtsTaskForm.reset(); pbtsTaskIdInput.value = ''; pbtsTaskProgressValueEl.textContent = '0%'; // Reset slider display const today = new Date().toISOString().split('T')[0]; if (taskId) { const task = pbtsTasks.find(t => t.id === taskId); if (task) { pbtsModalTitleEl.textContent = 'Edit Task'; pbtsTaskIdInput.value = task.id; pbtsTaskNameInput.value = task.name; pbtsTaskProgressInput.value = task.progress; pbtsTaskProgressValueEl.textContent = task.progress + '%'; pbtsTaskPriorityInput.value = task.priority; pbtsTaskDueDateInput.value = task.dueDate || ''; } } else { pbtsModalTitleEl.textContent = 'Add New Task'; pbtsTaskDueDateInput.value = today; // Default due date for new tasks pbtsTaskProgressInput.value = 0; // Ensure slider starts at 0 pbtsTaskProgressValueEl.textContent = '0%'; pbtsTaskPriorityInput.value = "Medium"; // Default priority } pbtsTaskModalEl.style.display = 'block'; } window.pbtsCloseModal = function(modalId) { const modal = document.getElementById(modalId); if (modal) modal.style.display = 'none'; } if(pbtsTaskForm) { pbtsTaskForm.addEventListener('submit', function(e) { e.preventDefault(); const taskId = pbtsTaskIdInput.value; const taskData = { name: pbtsTaskNameInput.value.trim(), progress: parseInt(pbtsTaskProgressInput.value), priority: pbtsTaskPriorityInput.value, dueDate: pbtsTaskDueDateInput.value || null // Store as null if empty }; if (!taskData.name) { alert("Task name cannot be empty."); return; } if (taskId) { // Editing const index = pbtsTasks.findIndex(t => t.id === taskId); if (index > -1) { pbtsTasks[index] = { ...pbtsTasks[index], ...taskData }; } } else { // Adding new const newTask = { id: 'pbts-task-' + Date.now(), ...taskData }; pbtsTasks.push(newTask); } pbtsSaveTasks(); pbtsRenderTaskBoard(); pbtsCloseModal('pbtsTaskModal'); }); } window.pbtsDeleteTask = function(taskId) { if (confirm('Are you sure you want to delete this task?')) { pbtsTasks = pbtsTasks.filter(t => t.id !== taskId); pbtsSaveTasks(); pbtsRenderTaskBoard(); } } // --- Summary --- function pbtsRenderSummary() { if (!pbtsSummaryOutputEl) return; let summaryCounts = {}; pbtsProgressCategories.forEach(cat => summaryCounts[cat.name] = 0); summaryCounts.total = pbtsTasks.length; pbtsTasks.forEach(task => { const category = pbtsProgressCategories.find(cat => task.progress >= cat.min && task.progress <= cat.max); if (category) { summaryCounts[category.name]++; } }); pbtsSummaryOutputEl.innerHTML = `
${summaryCounts.total}Total Tasks
${pbtsProgressCategories.map(cat => `
${summaryCounts[cat.name]} ${cat.name}
`).join('')} `; } // --- PDF Export --- if(pbtsDownloadPdfBtn) { pbtsDownloadPdfBtn.addEventListener('click', function() { const { jsPDF } = window.jspdf; const doc = new jsPDF(); const reportDate = new Date().toLocaleDateString(); const primaryColor = getComputedStyle(document.documentElement).getPropertyValue('--pbts-primary-color').trim(); doc.setFontSize(18); doc.setTextColor(primaryColor); doc.text("Progress-Based Task Report", 14, 22); doc.setFontSize(10); doc.setTextColor(100); doc.text(`Report Date: ${reportDate}`, 14, 30); let yPos = 40; pbtsProgressCategories.forEach(category => { const tasksInCategory = pbtsTasks.filter(task => task.progress >= category.min && task.progress <= category.max ).sort((a,b) => { const priorityOrder = { "High": 0, "Medium": 1, "Low": 2 }; return priorityOrder[a.priority] - priorityOrder[b.priority]; }); if (tasksInCategory.length > 0) { if (yPos > 260) { doc.addPage(); yPos = 20; } // Add new page if needed doc.setFontSize(14); doc.setFillColor(category.color.startsWith('var(') ? getComputedStyle(document.documentElement).getPropertyValue(category.color.slice(4,-1)).trim() : category.color); // Resolve CSS Var for PDF doc.setTextColor(255,255,255); // White text on colored bg doc.rect(14, yPos - 5, doc.internal.pageSize.getWidth() - 28, 8, 'F'); // Category Header BG doc.text(category.name, 16, yPos); yPos += 10; doc.setTextColor(0,0,0); // Reset text color for table const tableColumn = ["Task Name", "Progress (%)", "Priority", "Due Date"]; const tableRows = []; tasksInCategory.forEach(task => { tableRows.push([ task.name, task.progress, task.priority, task.dueDate ? pbtsFormatDateForDisplay(task.dueDate) : 'N/A' ]); }); doc.autoTable({ head: [tableColumn], body: tableRows, startY: yPos, theme: 'grid', headStyles: { fillColor: getComputedStyle(document.documentElement).getPropertyValue('--pbts-secondary-color').trim() }, styles: { fontSize: 9, cellPadding: 1.5 }, didDrawPage: function (data) { // Update yPos after table draw yPos = data.cursor.y + 10; } }); yPos = doc.lastAutoTable.finalY + 10; // Ensure yPos is after the table } }); if (pbtsTasks.length === 0) { doc.setFontSize(12); doc.setTextColor(100); doc.text("No tasks to report.", 14, yPos); } doc.save(`Task_Progress_Report_${reportDate.replace(/\//g, '-')}.pdf`); }); } // --- Initialization --- document.addEventListener('DOMContentLoaded', () => { pbtsLoadTasks(); const firstTabButton = document.querySelector('#progressBasedTaskSortingTool .pbts-tab-button'); if (firstTabButton) { firstTabButton.click(); } // Close modal if clicked outside window.addEventListener('click', function(event) { const modal = document.getElementById('pbtsTaskModal'); if (modal && event.target == modal) { pbtsCloseModal('pbtsTaskModal'); } }); // Update progress value display when slider changes in add/edit modal if(pbtsTaskProgressInput && pbtsTaskProgressValueEl) { pbtsTaskProgressInput.addEventListener('input', function() { pbtsTaskProgressValueEl.textContent = this.value + '%'; }); } });
Scroll to Top