Smart Task History Log
Smart Task History Log

Manage Current Task

Add Manual Log Entry

Filter & Search History

Logged Activities

TimestampTask NameEvent TypeDetails/Duration
No log entries yet.
"; } analyticsHTML += '
'; analyticsHTML += '

Event Type Counts:

'; if(Object.keys(eventTypeCounts).length > 0) { for(const type in eventTypeCounts) analyticsHTML += `

${type}: ${eventTypeCounts[type]}

`; } else { analyticsHTML += "

No events.

"; } analyticsHTML += '
'; analyticsDiv.innerHTML = analyticsHTML; } function sthl_clearEntireHistory() { if (confirm("Are you sure you want to clear the entire task history log? This cannot be undone.")) { if (sthl_activeTask && sthl_activeTask.timerInterval) clearInterval(sthl_activeTask.timerInterval); sthl_activeTask = null; sthl_logEntries = []; sthl_logIdCounter = 0; sthl_updateActiveTaskDisplay(); sthl_renderHistoryLog(); sthl_renderAnalytics([]); // Clear analytics } } function sthl_downloadPDF() { if (!tpc_jsPDF_loaded_STHL || !tpc_autoTable_loaded_STHL) { alert("STHL Error: PDF libraries not loaded."); return; } // Use currently filtered data for PDF const fromDateStr = document.getElementById('sthl-filter-from-date').value; const toDateStr = document.getElementById('sthl-filter-to-date').value; const taskNameFilter = document.getElementById('sthl-filter-task-name').value.toLowerCase(); const eventTypeFilter = document.getElementById('sthl-filter-event-type').value; const keywordSearch = document.getElementById('sthl-search-keyword').value.toLowerCase(); const fromDate = fromDateStr ? new Date(fromDateStr + "T00:00:00") : null; const toDate = toDateStr ? new Date(toDateStr + "T23:59:59") : null; const dataForPdf = sthl_logEntries.filter(entry => { const entryTimestamp = entry.timestamp; if (fromDate && entryTimestamp < fromDate) return false; if (toDate && entryTimestamp > toDate) return false; if (taskNameFilter && !entry.taskName.toLowerCase().includes(taskNameFilter)) return false; if (eventTypeFilter && entry.eventType !== eventTypeFilter) return false; if (keywordSearch && !(entry.taskName.toLowerCase().includes(keywordSearch) || entry.details.toLowerCase().includes(keywordSearch) || entry.eventType.toLowerCase().includes(keywordSearch))) return false; return true; }); if (dataForPdf.length === 0) { alert("No log entries to export based on current filters."); return; } const doc = new TPC_jsPDF_STHL(); const primaryColor = getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim(); const darkColor = getComputedStyle(document.documentElement).getPropertyValue('--dark-color').trim(); let finalY = 15; const reportDateStr = new Date().toLocaleDateString(); doc.setFontSize(18); doc.setTextColor(primaryColor); doc.text("Smart Task History Log Report", doc.internal.pageSize.getWidth() / 2, finalY, { align: 'center' }); finalY += 8; doc.setFontSize(10); doc.setTextColor(darkColor); doc.text(`Report Date: ${reportDateStr}`, doc.internal.pageSize.getWidth() / 2, finalY, { align: 'center'}); if(fromDateStr || toDateStr) { finalY += 5; doc.text(`Log Period: ${fromDateStr || 'Start'} to ${toDateStr || 'End'}`, doc.internal.pageSize.getWidth() / 2, finalY, { align: 'center'}); } finalY += 10; // Analytics for PDF let totalTimeSpentMinutes = 0; const taskTimes = {}; let completedTasksCount = 0; const eventTypeCountsPdf = {}; dataForPdf.forEach(entry => { if (entry.eventType === 'Complete' && entry.durationMinutes !== null) { totalTimeSpentMinutes += entry.durationMinutes; taskTimes[entry.taskName] = (taskTimes[entry.taskName] || 0) + entry.durationMinutes; completedTasksCount++; } eventTypeCountsPdf[entry.eventType] = (eventTypeCountsPdf[entry.eventType] || 0) + 1; }); doc.setFontSize(12); doc.setTextColor(primaryColor); doc.text("Summary Analytics (for displayed log)", 14, finalY); finalY += 6; doc.setFontSize(9); doc.setTextColor(darkColor); doc.text(`Total Log Entries: ${dataForPdf.length} | Tasks Completed: ${completedTasksCount} | Total Time on Tasks: ${sthl_formatDurationFromMinutes(totalTimeSpentMinutes)}`, 14, finalY); finalY += 5; let taskTimesText = "Time per Task: "; if(Object.keys(taskTimes).length > 0) { for(const task in taskTimes) taskTimesText += `${task}: ${sthl_formatDurationFromMinutes(taskTimes[task])}; `; } else { taskTimesText += "N/A"; } doc.text(taskTimesText, 14, finalY, {maxWidth: doc.internal.pageSize.getWidth() - 28}); finalY += (Math.ceil(doc.getTextDimensions(taskTimesText).h / (doc.internal.pageSize.getWidth() - 28)) * 4) + 5 ; finalY += 5; // Space before table doc.setFontSize(12); doc.setTextColor(primaryColor); doc.text("Detailed Log", 14, finalY); finalY += 6; const tableBody = dataForPdf.map(entry => [ entry.timestamp.toLocaleString(), entry.taskName, entry.eventType, entry.details || (entry.durationMinutes !== null ? `Duration: ${sthl_formatDurationFromMinutes(entry.durationMinutes)}` : '-') ]); doc.autoTable({ startY: finalY, head: [['Timestamp', 'Task Name', 'Event Type', 'Details/Duration']], body: tableBody, theme: 'grid', headStyles: { fillColor: primaryColor, textColor: '#ffffff', fontSize: 9 }, styles: { fontSize: 8, cellPadding: 1.5, overflow: 'linebreak' } }); doc.save(`Smart_Task_Log_${new Date().toISOString().slice(0,10)}.pdf`); }
Scroll to Top