<!-- To update the visualisation, edit the source table at the bottom of this page --> <p>Our release and support roadmap is always subject to the availability of continuous and sufficient funding. Organisations requiring binding commitments to release and support timelines should consider commercial service offerings linked to conformant products (<a href="https://ec.europa.eu/digital-building-blocks/sites/display/DIGITAL/eDelivery+AS4+conformant+solutions">AS4</a>, <a href="https://ec.europa.eu/digital-building-blocks/sites/display/DIGITAL/eDelivery+SMP+conformant+solutions">SMP</a>). EUIBA services can contact us for additional details.</p> <p>This page shows only upcoming releases.</p> <table class="timeline-table"> <tr> <th>Product</th> </tr> </table> <script> document.addEventListener("DOMContentLoaded", function () { const table = document.querySelector(".wrapped.confluenceTable"); const timelineTable = document.querySelector(".timeline-table"); if (!table || !timelineTable) { console.error("Source table or timeline table not found."); return; } // Helper function to get the quarter from a date const getQuarter = (date) => { const month = date.getMonth() + 1; return `Q${Math.ceil(month / 3)} ${date.getFullYear()}`; }; // Helper function to generate all quarters between two dates const generateQuartersRange = (startDate, endDate) => { const quarters = []; let current = new Date(startDate); while (current <= endDate) { quarters.push(getQuarter(current)); const month = current.getMonth(); current.setMonth(month + 3); // Move to next quarter } return quarters; }; // Map product names to images and links const productData = { Domibus: { image: "https://ec.europa.eu/digital-building-blocks/sites/download/attachments/835452949/domibus_logo.svg", link: "https://ec.europa.eu/digital-building-blocks/sites/x/c4nXGw", }, DomiSMP: { image: "https://ec.europa.eu/digital-building-blocks/sites/download/attachments/835452949/domismp_logo.svg", link: "https://ec.europa.eu/digital-building-blocks/sites/x/8qbXGw", }, DomiSML: { image: "https://ec.europa.eu/digital-building-blocks/sites/download/attachments/835452949/domisml_logo.svg", link: "https://ec.europa.eu/digital-building-blocks/sites/x/TajXGw", }, }; // Parse data from the source table const rows = table.querySelectorAll("tbody tr"); const releases = []; let earliestDate = null; let latestDate = null; rows.forEach(row => { const cells = row.querySelectorAll(".confluenceTd"); if (cells.length < 3) { console.warn("Row does not have enough columns:", row); return; } const product = cells[0]?.textContent.trim(); const version = cells[1]?.textContent.trim(); const releaseDate = cells[2]?.querySelector("time")?.getAttribute("datetime"); if (product && version && releaseDate) { const date = new Date(releaseDate); if (!earliestDate || date < earliestDate) earliestDate = date; if (!latestDate || date > latestDate) latestDate = date; const quarter = getQuarter(date); releases.push({ product, version, quarter }); } else { console.warn("Incomplete data in row:", row); } }); if (releases.length === 0) { console.error("No valid releases found."); return; } // Generate the full range of quarters const quarters = generateQuartersRange(earliestDate, latestDate); // Add header row for quarters const headerRow = timelineTable.querySelector("tr"); quarters.forEach(quarter => { const th = document.createElement("th"); th.textContent = quarter; headerRow.appendChild(th); }); // Add rows for each product const products = [...new Set(releases.map(r => r.product))]; products.forEach(product => { const row = document.createElement("tr"); // Use image with link for the product name const productCell = document.createElement("td"); const productLink = document.createElement("a"); const productImg = document.createElement("img"); productLink.href = productData[product]?.link || "#"; productLink.target = "_blank"; productImg.src = productData[product]?.image || ""; productImg.alt = product; productImg.style.width = "50px"; // Adjust image size as needed productImg.style.height = "auto"; productLink.appendChild(productImg); productCell.appendChild(productLink); row.appendChild(productCell); quarters.forEach(quarter => { const cell = document.createElement("td"); // Find all releases for the product in the current quarter const releasesForQuarter = releases.filter(r => r.product === product && r.quarter === quarter); releasesForQuarter.forEach(release => { const box = document.createElement("div"); box.className = `release-box ${product.toLowerCase()} ${release.version.toLowerCase().includes("rc") ? "rc" : "fr"}`; box.textContent = release.version; cell.appendChild(box); }); row.appendChild(cell); }); timelineTable.appendChild(row); }); // Hide the source table after rendering the visualization table.style.display = "none"; console.log("Timeline table with images and styled boxes generated successfully."); }); </script> <style> /* General styles for the timeline table */ .timeline-table { max-width: 790px; border-collapse: collapse; margin-top: 20px; text-align: center; } /* Remove vertical borders, keep horizontal borders */ .timeline-table th, .timeline-table td { border: none; border-bottom: 1px solid #ddd; /* Horizontal border between rows */ padding: 8px; } /* Ensure all quarter columns are of the same width */ .timeline-table th, .timeline-table td:not(:first-child) { width: 10%; /* Adjust percentage as needed */ text-align: center; } /* Header row styling */ .timeline-table th { background-color: #f4f4f4; font-weight: bold; text-align: center; } /* Product image column width */ .timeline-table td:first-child { width: 15%; /* Adjust based on design preferences */ text-align: center; } /* General styles for the release boxes */ .release-box { padding: 5px 10px; border-radius: 4px; font-size: 12px; color: #fff; text-align: center; display: inline-block; margin: 3px; /* Add spacing between boxes */ } /* Intensity based on version type */ .release-box.rc { opacity: 0.6; /* Less intense for RC */ } .release-box.fr { opacity: 1; /* More intense for FR */ } /* Color based on product */ .release-box.domibus { background-color: blue; } .release-box.domismp { background-color: green; } .release-box.domisml { background-color: red; } </style> |
|