Automated Task Progress Monitor
Add New Task
Monitored Tasks
Task Summary
Understanding the Monitor
- Actual Progress
- This is the percentage of work you manually report as completed for the task.
- Expected Progress
- This is a calculated percentage based on the current date, task start date, and task end date. It represents how much of the task *should ideally* be completed if work is spread evenly over the task's duration.
Formula (simplified):(Days Passed Since Start / Total Task Duration Days) * 100%.
It's 0% if the task hasn't started and 100% if the end date has passed. - Status
-
Not Started: The current date is before the task's start date.
On Track: Actual progress is close to or greater than the expected progress (within a -5% tolerance).
Ahead: Actual progress is significantly greater (more than 10%) than expected progress.
Behind: Actual progress is less than the expected progress (by more than 5%).
Overdue: The current date is past the task's end date, and actual progress is less than 100%.
Completed: Actual progress is 100%. - Days Remaining / Overdue
- Indicates the number of days left until the end date. If negative, it shows how many days the task is overdue (if not completed).
- Progress Bar
- The main colored bar shows your 'Actual Progress'. A thin vertical line/marker on the progress bar indicates the 'Expected Progress' point for quick visual comparison.
- Refresh Calculations
- Click this button on the "Task Monitor" tab if you've had the page open for a while, to ensure all calculations are based on the very latest time.
×
Edit Task
No tasks added yet. Use the form above to add your first task.
${taskWithMetrics.name}
${taskWithMetrics.assignee ? `Assignee: ${taskWithMetrics.assignee}
` : ''}Dates: ${taskWithMetrics.startDate} to ${taskWithMetrics.endDate}
Actual Progress: ${taskWithMetrics.actualProgress}%
${taskWithMetrics.actualProgress}%
${ taskWithMetrics.status !== "Completed" && taskWithMetrics.status !== "Not Started" ?
`` : ''}
Expected Progress: ${taskWithMetrics.expectedProgress}%
Status: ${taskWithMetrics.status}
Time: ${taskWithMetrics.daysRemaining}
${summary.total}Total Tasks
${summary.completed}Completed
${summary.onTrack}On Track
${summary.ahead}Ahead
${summary.behind}Behind
${summary.overdue}Overdue
${summary.notStarted}Not Started
`;
}
// --- PDF Export ---
if(atpmDownloadPdfBtn) {
atpmDownloadPdfBtn.addEventListener('click', function() {
const doc = new jsPDF();
const reportDate = new Date().toLocaleDateString();
const primaryColor = getComputedStyle(document.documentElement).getPropertyValue('--atpm-primary-color').trim();
const secondaryColor = getComputedStyle(document.documentElement).getPropertyValue('--atpm-secondary-color').trim();
doc.setFontSize(18);
doc.setTextColor(primaryColor);
doc.text("Automated Task Progress Report", 14, 22);
doc.setFontSize(11);
doc.setTextColor(100);
doc.text(`Report Date: ${reportDate}`, 14, 30);
const tableColumn = ["Task Name", "Assignee", "Start", "End", "Actual %", "Expected %", "Status", "Time Details"];
const tableRows = [];
atpmTasks.map(task => atpmCalculateTaskMetrics(task)).forEach(task => {
const taskData = [
task.name || "N/A",
task.assignee || "N/A",
task.startDate || "N/A",
task.endDate || "N/A",
`${task.actualProgress}%`,
`${task.expectedProgress}%`,
task.status || "N/A",
task.daysRemaining || "N/A"
];
tableRows.push(taskData);
});
if (tableRows.length > 0) {
doc.autoTable({
head: [tableColumn],
body: tableRows,
startY: 40,
theme: 'grid',
headStyles: { fillColor: secondaryColor, textColor: '#ffffff' },
styles: { font: 'Arial', fontSize: 9, cellPadding: 2, overflow: 'linebreak' },
columnStyles: {
0: { cellWidth: 40 }, // Task Name
6: { cellWidth: 25 }, // Status
7: { cellWidth: 30 } // Time Details
}
});
} else {
doc.setFontSize(12);
doc.setTextColor(100);
doc.text("No tasks to report.", 14, 45);
}
doc.save(`Task_Progress_Report_${reportDate.replace(/\//g, '-')}.pdf`);
});
}
// --- Initialization ---
document.addEventListener('DOMContentLoaded', () => {
atpmLoadTasks();
const firstTabButton = document.querySelector('#automatedTaskProgressMonitorTool .atpm-tab-button');
if (firstTabButton) {
firstTabButton.click();
}
// Close modal if clicked outside (generic for any modal with this structure)
window.addEventListener('click', function(event) {
if (event.target.classList.contains('atpm-modal')) {
event.target.style.display = 'none';
}
});
});
