feat: group changelog entries by date into unified cards

This commit is contained in:
jae 2026-04-06 20:52:58 +00:00
parent 2ad39b12ac
commit cb413e2cf9
2 changed files with 93 additions and 19 deletions

View file

@ -161,14 +161,62 @@
margin-left: auto; margin-left: auto;
} }
.changelog-entry-title { /* ─── Grouped Date Header ────────────────────────────── */
.changelog-date-header {
display: flex;
align-items: center;
justify-content: space-between;
padding-bottom: 0.75rem;
margin-bottom: 0.75rem;
border-bottom: 1px solid var(--border);
}
.changelog-date-header .changelog-date {
font-family: var(--font-display); font-family: var(--font-display);
font-size: 1.1rem; font-size: 1rem;
color: var(--status-green);
letter-spacing: 2px;
font-weight: 700;
margin-left: 0;
}
.changelog-version-range {
font-family: var(--font-mono);
font-size: 0.75rem;
color: var(--text-muted);
letter-spacing: 1px;
}
/* ─── Sub-entry within date group ────────────────────── */
.changelog-sub-entry {
padding: 0.6rem 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}
.changelog-sub-entry:last-child {
border-bottom: none;
padding-bottom: 0;
}
.changelog-sub-entry .changelog-entry-header {
margin-bottom: 0.4rem;
gap: 0.6rem;
}
.changelog-sub-entry .changelog-entry-title {
font-family: var(--font-display);
font-size: 0.95rem;
color: var(--text-primary); color: var(--text-primary);
letter-spacing: 0.5px; letter-spacing: 0.5px;
margin-bottom: 0.75rem; margin-bottom: 0;
} }
.changelog-sub-entry .changelog-changes {
margin-top: 0.3rem;
padding-left: 0.5rem;
}
/* ─── Change List ────────────────────────────────────── */ /* ─── Change List ────────────────────────────────────── */
.changelog-changes { .changelog-changes {
list-style: none; list-style: none;

View file

@ -1,5 +1,6 @@
/* /*
CHANGELOG Mission Update Log Controller CHANGELOG Mission Update Log Controller
Groups entries by date into unified cards
*/ */
(function () { (function () {
'use strict'; 'use strict';
@ -26,6 +27,17 @@
const totalChanges = entries.reduce((sum, e) => sum + (e.changes ? e.changes.length : 0), 0); const totalChanges = entries.reduce((sum, e) => sum + (e.changes ? e.changes.length : 0), 0);
const latestVersion = entries.length > 0 ? entries[0].version : '0.0.0'; const latestVersion = entries.length > 0 ? entries[0].version : '0.0.0';
// Group entries by date
const grouped = [];
const dateMap = {};
for (const entry of entries) {
if (!dateMap[entry.date]) {
dateMap[entry.date] = { date: entry.date, entries: [] };
grouped.push(dateMap[entry.date]);
}
dateMap[entry.date].entries.push(entry);
}
let html = ''; let html = '';
// Header // Header
@ -38,31 +50,45 @@
html += `<span class="changelog-stat">TOTAL CHANGES: <span class="changelog-stat-value">${totalChanges}</span></span>`; html += `<span class="changelog-stat">TOTAL CHANGES: <span class="changelog-stat-value">${totalChanges}</span></span>`;
html += `</div></div>`; html += `</div></div>`;
// Timeline // Timeline — grouped by date
html += `<div class="changelog-timeline">`; html += `<div class="changelog-timeline">`;
for (const entry of entries) { for (const group of grouped) {
const badge = entry.category || 'update'; // Version range for this date
const versions = group.entries.map(e => e.version);
const versionRange = versions.length > 1
? `v${esc(versions[versions.length - 1])} — v${esc(versions[0])}`
: `v${esc(versions[0])}`;
html += `<div class="changelog-entry">`; html += `<div class="changelog-entry">`;
html += `<div class="changelog-entry-card">`; html += `<div class="changelog-entry-card">`;
// Header row // Date header
html += `<div class="changelog-entry-header">`; html += `<div class="changelog-date-header">`;
html += `<span class="changelog-version">v${esc(entry.version)}</span>`; html += `<span class="changelog-date">${formatDate(group.date)}</span>`;
html += `<span class="changelog-badge ${esc(badge)}">${esc(badge)}</span>`; html += `<span class="changelog-version-range">${versionRange}</span>`;
html += `<span class="changelog-date">${formatDate(entry.date)}</span>`;
html += `</div>`; html += `</div>`;
// Title // Each sub-entry within this date
html += `<div class="changelog-entry-title">${esc(entry.title)}</div>`; for (const entry of group.entries) {
const badge = entry.category || 'update';
// Changes html += `<div class="changelog-sub-entry">`;
if (entry.changes && entry.changes.length > 0) { html += `<div class="changelog-entry-header">`;
html += `<ul class="changelog-changes">`; html += `<span class="changelog-version">v${esc(entry.version)}</span>`;
for (const change of entry.changes) { html += `<span class="changelog-badge ${esc(badge)}">${esc(badge)}</span>`;
html += `<li>${esc(change)}</li>`; html += `<span class="changelog-entry-title">${esc(entry.title)}</span>`;
html += `</div>`;
if (entry.changes && entry.changes.length > 0) {
html += `<ul class="changelog-changes">`;
for (const change of entry.changes) {
html += `<li>${esc(change)}</li>`;
}
html += `</ul>`;
} }
html += `</ul>`;
html += `</div>`;
} }
html += `</div></div>`; html += `</div></div>`;