Renewable Energy Log Generator

Release Notes Documenter

Release Notes Documenter

Review the formatted release notes. The content is automatically grouped and styled for clarity, ready for final distribution.

${summary}

`; // Render Sections const sortedTypes = Object.keys(groupedItems).sort((a, b) => TYPE_ORDER[a] - TYPE_ORDER[b]); sortedTypes.forEach(type => { const items = groupedItems[type]; if (items.length === 0) return; output += `

${type}

    ${items.map(item => `
  • ${ITEM_ICONS[type]} ${rnd_escapeHTML(item.description)}
  • `).join('')}
`; }); return output; } function rnd_renderDashboard(targetDiv = rnd_dashboardOutput, isPDF = false) { if (!targetDiv) return; targetDiv.innerHTML = rnd_generateNotesHTML(rnd_data); } function rnd_renderPdfClone() { rnd_pdfRenderClone.innerHTML = `
${rnd_generateNotesHTML(rnd_data)}
`; } /** * Generates and downloads a PDF of the notes */ async function rnd_downloadPDF() { if (!rnd_data.version) { alert("Please enter a version number before downloading."); return; } if (typeof jspdf === 'undefined' || typeof html2canvas === 'undefined') { alert("Error: PDF libraries failed to load."); return; } rnd_renderPdfClone(); const { jsPDF } = window.jspdf; try { const contentDiv = rnd_pdfRenderClone.querySelector('.pdf-content'); if (!contentDiv) return; const canvas = await html2canvas(contentDiv, { scale: 1.5, useCORS: true }); const imgData = canvas.toDataURL('image/png'); const imgProps = { width: canvas.width, height: canvas.height }; const pdf = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const margin = 40; const contentWidth = pdfWidth - (margin * 2); const contentHeight = (contentWidth * imgProps.height) / imgProps.width; let heightLeft = contentHeight; let position = 0; pdf.addImage(imgData, 'PNG', margin, position + margin, contentWidth, contentHeight); heightLeft -= (pdfHeight - margin * 2); while (heightLeft > 0) { position -= (pdfHeight - margin * 2); pdf.addPage(); pdf.addImage(imgData, 'PNG', margin, position + margin, contentWidth, contentHeight); heightLeft -= (pdfHeight - margin * 2); } const safeName = (rnd_data.version || 'release').replace(/[^a-z0-9]/gi, '_').toLowerCase(); pdf.save(`Release_Notes_${safeName}.pdf`); } catch (error) { console.error("PDF generation failed:", error); alert("An error occurred while generating the PDF."); } } // --- EVENT LISTENERS --- // Tab link clicks rnd_tabLinks.forEach((link, index) => { link.addEventListener('click', () => rnd_switchTab(index)); }); // Next/Prev button clicks if (rnd_prevButton) { rnd_prevButton.addEventListener('click', () => { if (rnd_currentTab > 0) rnd_switchTab(rnd_currentTab - 1); }); } if (rnd_nextButton) { rnd_nextButton.addEventListener('click', () => { if (rnd_currentTab === rnd_tabLinks.length - 1) { rnd_updateDataFromConfig(); rnd_switchTab(0); } else { if (rnd_currentTab < rnd_tabLinks.length - 1) rnd_switchTab(rnd_currentTab + 1); } }); } // PDF download if (rnd_downloadPdfButton) { rnd_downloadPdfButton.addEventListener('click', rnd_downloadPDF); } // --- Config Tab Listeners --- if (rnd_addItemButton) { rnd_addItemButton.addEventListener('click', () => { rnd_itemsContainer.appendChild(rnd_createItemInput()); }); } if (rnd_configTab) { // Handle remove rnd_configTab.addEventListener('click', (e) => { const removeButton = e.target.closest('.rnd-remove-item'); if (removeButton) { removeButton.closest('.flex[data-id]').remove(); } }); } // --- INITIALIZATION --- rnd_renderConfig(); rnd_renderDashboard(); // Set initial tab state rnd_tabPanes.forEach((pane, index) => { pane.classList.toggle('hidden', index !== 0); pane.classList.toggle('rnd-active', index === 0); }); rnd_tabLinks.forEach((link, index) => { TAB_CLASSES.active.forEach(cls => link.classList.remove(cls)); TAB_CLASSES.inactive.forEach(cls => link.classList.remove(cls)); if (index === 0) { TAB_CLASSES.active.forEach(cls => link.classList.add(cls)); } else { TAB_CLASSES.inactive.forEach(cls => link.classList.add(cls)); } }); });
Scroll to Top