fix(#1940): render merge_config_pr approval cards

renderApprovals had no merge_config_pr case, so those approvals
mis-rendered as generic spawn cards (spawn chip, no sha, 'container will
be created' body). Add a dedicated branch:
- distinct glyph + 'merge-pr' kind chip
- show the reviewed PR-head sha (sha_short), like apply_commit
- a 'review PR on forge' link built from pr_number (now on ApprovalView),
  gated on forge_present, mirroring the apply_commit 'commit on forge' link
- no config-diff side-panel (apply_commit-only for now)
History rows get the 'merge-pr' chip too.
This commit is contained in:
iris 2026-06-23 14:53:42 +02:00 committed by mara
commit d1125207b4

View file

@ -314,17 +314,18 @@ export function renderApprovals() {
for (const a of pending) {
const isApply = a.kind === 'apply_commit';
const isInit = a.kind === 'init_config';
const isMergePr = a.kind === 'merge_config_pr';
const li = el('li', { class: 'approval-card' });
// ── identity header ──────────────────────────────────────────
const head = el('div', { class: 'approval-head' },
el('span', { class: 'glyph' }, isApply ? '→' : '⊕'),
el('span', { class: 'glyph' }, isApply ? '→' : isMergePr ? '⇒' : '⊕'),
el('span', { class: 'id' }, '#' + a.id),
el('span', { class: 'agent' }, a.agent),
el('span', { class: 'kind' + (isApply ? '' : ' kind-spawn') },
isApply ? 'apply' : isInit ? 'init' : 'spawn'),
el('span', { class: 'kind' + ((isApply || isMergePr) ? '' : ' kind-spawn') },
isApply ? 'apply' : isMergePr ? 'merge-pr' : isInit ? 'init' : 'spawn'),
);
if (isApply && a.sha_short) head.append(el('code', {}, a.sha_short));
if ((isApply || isMergePr) && a.sha_short) head.append(el('code', {}, a.sha_short));
// When the approval was requested — relative time, right-aligned.
// Goes amber once it's been pending an hour so a stale request is
// obvious at a glance (see docs/web-ui.md::Approval card).
@ -357,6 +358,19 @@ export function renderApprovals() {
}, '↳ commit on forge ↗'));
}
body.append(drill);
} else if (isMergePr) {
// PR-based config deploy: link to the reviewed PR on the forge
// (mirrors the apply_commit "commit on forge" link). The config
// diff side-panel is apply_commit-only for now.
const drill = el('div', { class: 'drill-ins' });
if (forgeBase && a.pr_number != null) {
drill.append(el('a', {
class: 'panel-trigger', target: '_blank', rel: 'noopener',
href: `${forgeBase}/agent-configs/${a.agent}/pulls/${a.pr_number}`,
title: 'review this config PR on the hive forge',
}, '↳ review PR on forge ↗'));
}
body.append(drill);
} else {
body.append(el('span', { class: 'meta' },
isInit
@ -403,7 +417,7 @@ function renderApprovalHistory(root, history) {
el('span', { class: 'glyph glyph-' + a.status }, glyph), ' ',
el('span', { class: 'id' }, '#' + a.id), ' ',
el('span', { class: 'agent' }, a.agent), ' ',
el('span', { class: 'kind' }, a.kind === 'apply_commit' ? 'apply' : a.kind === 'init_config' ? 'init' : 'spawn'), ' ',
el('span', { class: 'kind' }, a.kind === 'apply_commit' ? 'apply' : a.kind === 'merge_config_pr' ? 'merge-pr' : a.kind === 'init_config' ? 'init' : 'spawn'), ' ',
);
if (a.sha_short) row.append(el('code', {}, a.sha_short), ' ');
row.append(