feat(render): card owner pill + short ISO date span

closes board-viewer-card-meta-fix

Review found two acceptance fields missing from cards:
- project_owner was in JSON but never displayed
- last_commit_iso was only consumed for relative age; no absolute date

Now both rendered (server-side src/render.ts + client-side static/board.js
in sync), with 4 new TDD tests:
- renders owner pill when project_owner is set
- omits owner pill when empty
- renders short YYYY-MM-DD date when last_commit_iso is set
- omits date span when null

CSS: .badge.owner = transparent + border (visually distinct from solid
.badge.project), .date = small muted tabular-nums. Smoke-verified in browser.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
vitya
2026-05-22 15:42:59 +03:00
parent 7cebeda219
commit 930e404545
6 changed files with 79 additions and 7 deletions

View File

@@ -245,3 +245,15 @@ aside.drawer[hidden] {
.badge.status {
background: var(--badge-bg);
}
.badge.owner {
background: transparent;
border: 1px solid var(--border);
color: var(--muted);
}
.date {
font-variant-numeric: tabular-nums;
color: var(--muted);
font-size: 0.7rem;
}

View File

@@ -76,13 +76,21 @@ function truncate(s, max) {
function renderCard(rec, now, mode) {
const age = formatAge(rec.last_commit_iso, now);
const archived = isArchived(rec, now);
const meta = mode === 'by-project'
const primary = mode === 'by-project'
? `<span class="badge status">${STATUS_EMOJI[rec.status]} ${STATUS_LABEL[rec.status]}</span>`
: `<span class="badge project">${escapeHtml(rec.project)}</span>`;
const ownerPill = rec.project_owner
? `<span class="badge owner">${escapeHtml(rec.project_owner)}</span>`
: '';
const dateSpan = rec.last_commit_iso
? `<span class="date" title="${escapeHtml(rec.last_commit_iso)}">${escapeHtml(rec.last_commit_iso.slice(0, 10))}</span>`
: '';
return `<li class="card" data-slug="${escapeHtml(rec.slug)}" data-raw-url="${escapeHtml(rec.raw_url)}" data-archived="${archived ? 'true' : 'false'}">
<div class="card-title">${escapeHtml(truncate(rec.title, 80))}</div>
<div class="card-meta">
${meta}
${primary}
${ownerPill}
${dateSpan}
${age === null ? '' : `<span class="age">${escapeHtml(age)}</span>`}
</div>
</li>`;