Compliance Audit Log
${title}
Framework:${type}
Lead Auditor:${auditor}
Period End Date:${date}
Total Findings:${entries.length}
Detailed Findings
${entries.length > 0 ? entriesHTML : 'No findings have been logged.
'} `; }; const handleDownloadPdf = async () => { const { jsPDF } = window.jspdf; const content = document.getElementById('log-output-content'); if (!content) return; const originalButtonText = downloadPdfBtn.innerHTML; downloadPdfBtn.innerHTML = 'Generating...'; downloadPdfBtn.disabled = true; try { const canvas = await html2canvas(content, { scale: 2, backgroundColor: '#ffffff' }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF('p', 'mm', 'a4'); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const margin = 15; const contentWidth = pdfWidth - (margin * 2); const imgProps = pdf.getImageProperties(imgData); const imgHeight = (imgProps.height * contentWidth) / imgProps.width; let heightLeft = imgHeight; let position = margin; pdf.addImage(imgData, 'PNG', margin, position, contentWidth, imgHeight); heightLeft -= (pdfHeight - margin * 2); while (heightLeft > 0) { position = heightLeft - imgHeight + margin; pdf.addPage(); pdf.addImage(imgData, 'PNG', margin, position, contentWidth, imgHeight); heightLeft -= (pdfHeight - margin); } const fileName = `${(document.getElementById('audit-title').value || 'compliance_audit').replace(/\s+/g, '_')}_log.pdf`; pdf.save(fileName); } catch (error) { console.error("PDF generation failed:", error); } finally { downloadPdfBtn.innerHTML = originalButtonText; downloadPdfBtn.disabled = false; } }; // Event Listeners tabButtons.forEach((btn, i) => btn.addEventListener('click', () => switchTab(i + 1))); prevBtn.addEventListener('click', () => switchTab(currentTab - 1)); nextBtn.addEventListener('click', () => switchTab(currentTab + 1)); addEntryBtn.addEventListener('click', () => addEntry()); downloadPdfBtn.addEventListener('click', handleDownloadPdf); // Initial setup with sample data addEntry({ control: 'CC7.1 - Access Control', risk: 'High', finding: 'Quarterly access reviews for production systems were not completed for the engineering team.', recommendation: 'Implement an automated reminder and ticketing system to ensure access reviews are performed and documented on time.', status: 'In Progress' }); addEntry({ control: 'CC3.2 - Data Encryption', risk: 'Medium', finding: 'A subset of S3 buckets containing non-sensitive, internal-only data was found without encryption at rest enabled.', recommendation: 'Enforce a global AWS policy to enable AES-256 encryption by default for all new S3 buckets.', status: 'Open' }); updateNavButtons(); });