Agile Sprint Planning Sheet Generator

Agile Sprint Planning Sheet Generator

Sprint Details

Tasks & User Stories

${startDate} to ${endDate}

Sprint Goal:

${sprintGoal.replace(/\n/g, '
')}

Sprint Summary

${totalTasks} Total Tasks
${totalPoints} Total Story Points
${statusTodo} To Do
${statusInProgress} In Progress
${statusDone} Done

Sprint Backlog

${tableRowsHTML}
User Story / Task Assignee Points Status Notes

Team Members

    ${teamHTML}
`; // 5. Inject into DOM and switch tab reportOutputWrapper.innerHTML = finalReportHTML; showTab('agile-tab-dashboard'); } // --- PDF Download Function --- function downloadPDF() { if (typeof jspdf === 'undefined' || typeof html2canvas === 'undefined') { console.error('AGILE SPRINT TOOL: jsPDF or html2canvas is not loaded.'); return; } const reportElement = document.getElementById('agile-output-wrapper'); if (reportElement.innerHTML.trim() === '') { // Do not use alert(). console.warn("AGILE SPRINT TOOL: No report to download."); return; } const originalBtnText = pdfDownloadBtn.textContent; pdfDownloadBtn.textContent = 'Generating...'; pdfDownloadBtn.disabled = true; try { html2canvas(reportElement, { scale: 2, // Improve resolution useCORS: true, backgroundColor: '#ffffff' }).then((canvas) => { const imgData = canvas.toDataURL('image/png'); const { jsPDF } = window.jspdf; // A4 size: 210 x 297 mm const pdfWidth = 210; const pageHeight = 297; const imgWidth = canvas.width; const imgHeight = canvas.height; const ratio = imgWidth / pdfWidth; let scaledHeight = imgHeight / ratio; const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' }); let position = 0; let pageImgHeight = (pageHeight - 20); // 10mm margin top/bottom doc.addImage(imgData, 'PNG', 10, 10, pdfWidth - 20, scaledHeight); scaledHeight -= pageImgHeight; // Handle multiple pages if content is too long while (scaledHeight > 0) { doc.addPage(); position = -pageImgHeight; // We are moving the *image* up relative to the new page doc.addImage(imgData, 'PNG', 10, position + 10, pdfWidth - 20, imgHeight / ratio); scaledHeight -= pageImgHeight; } doc.save('agile-sprint-plan.pdf'); pdfDownloadBtn.textContent = originalBtnText; pdfDownloadBtn.disabled = false; }).catch(err => { console.error('AGILE SPRINT TOOL: html2canvas error:', err); pdfDownloadBtn.textContent = originalBtnText; pdfDownloadBtn.disabled = false; }); } catch(e) { console.error('AGILE SPRINT TOOL: PDF generation failed.', e); pdfDownloadBtn.textContent = originalBtnText; pdfDownloadBtn.disabled = false; } } // --- Utility Function --- function escapeHTML(str) { if (!str) return ''; return str.toString().replace(/[&<>"']/g, function(match) { return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[match]; }); } // --- Attach Event Listeners --- addTaskBtn.addEventListener('click', () => addTaskRow()); generateBtn.addEventListener('click', generateReport); pdfDownloadBtn.addEventListener('click', downloadPDF); // --- Initial Setup --- updateNavButtons(); // Add US-relevant sample data addTaskRow('As a user, I want to see my cart total (in USD).', 'Michael', 5, 'todo', 'Includes sales tax calculation for CA, NY, TX.'); addTaskRow('As a user, I want to create an account.', 'Emily', 8, 'todo', 'Needs password confirmation and email validation.'); addTaskRow('QA: Test user login flow on mobile (iOS/Android).', 'David', 3, 'todo', ''); // Set default dates (Oct 22 2025 is a Wednesday, so start next Monday) startDateInput.value = '2025-10-27'; endDateInput.value = '2025-11-07'; // Generate the initial report on load generateReport(); // Start on the dashboard tab showTab('agile-tab-dashboard'); });
Scroll to Top