commit b38dcad7db508bd5a1cce5293c4a1ce3750ec692 Author: Eiichi Shimazu Date: Sat Nov 14 23:13:32 2026 +0900 判定の画面で確定済みの回を開いたら記録した pick / place のボタンを塗る (依頼 190). index.html だけ. 回を開いたら人の確定の行 (なければ確定の行) の pick / place を button.on で塗る (AI だけの回は塗らない・書けたか分からない操作の回はその入力を戻す). 押して変えたら押したものが塗られ, 回を移ると記録の値に戻る. 今の判定の札を 1 回にし, 札・人が確定済み・日時・pick / place を 1 行目にまとめる. 書き込み・キー・数え方・見た目の決まりは変えない. テスト test_verdicts 39 OK Co-Authored-By: Claude Opus 5.5 --- pi05/verdict_viewer/index.html | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/pi05/verdict_viewer/index.html b/pi05/verdict_viewer/index.html index b8a1443..044143c 100644 --- a/pi05/verdict_viewer/index.html +++ b/pi05/verdict_viewer/index.html @@ -238,6 +238,10 @@ async function select(stem) { catch (e) { if (seq === selSeq) { $("#title").textContent = stem; status("この回を読めませんでした: " + e.message + " ・ 一覧でもう一度選んでください", "err"); } return false; } if (seq !== selSeq || d.run_stem !== cur) return false; detail = d; loading = false; + if (!po) { // 記録した pick / place を塗る (人の確定があればそれ, なければ確定の行. 依頼 190) + const r = recordedRow(); + if (r) { pp = {pick: r.pick || null, place: r.place || null}; markPP(); } + } $("#title").textContent = stem; $("#meta").textContent = `送ったチャンク ${detail.executed_chunks} ・ 終わり方 ${detail.end_reason || "記録なし"} ・ ${detail.model || ""}`; renderMedia(); renderInfo(); renderChart(); @@ -272,8 +276,8 @@ function renderInfo() { const a = detail.ai, l = detail.latest; $("#ai").innerHTML = a ? `
${OC_JA[a.outcome]}
pick ${a.pick} / place ${a.place} ・ 素材 ${a.evidence || "なし"}
${esc(a.ai_reason)}
` : `AI の判定はありません`; const h = detail.history.filter(r => HUMAN.includes(r.labeler)).pop(); // 人が確定した行 (依頼 187) - const hl = h ? `
人が確定済み ${tag(h.outcome, false)} ・ ${esc(h.labeled_at.slice(0, 10))} ${hm(h.labeled_at)}
` : ""; - $("#cur").innerHTML = l ? `
${tag(l.outcome, l.labeler === "ai")} ${LB_JA[l.labeler]}
${hl}
pick ${l.pick} / place ${l.place} ・ ${esc(l.labeled_at)}
${l.note ? `
${esc(l.note)}
` : ""}` : `まだ判定がありません`; + const c = h || l; // 札は 1 回だけ. 札・人が確定・時刻・pick / place を 1 行目に (依頼 190) + $("#cur").innerHTML = c ? `
${tag(c.outcome, c.labeler === "ai")} ${h ? "人が確定済み" : `${LB_JA[c.labeler]}`} ・ ${esc(c.labeled_at.slice(0, 10))} ${hm(c.labeled_at)} ・ pick ${c.pick} / place ${c.place}
${c.note ? `
${esc(c.note)}
` : ""}` : `まだ判定がありません`; markOC(); $("#hist").innerHTML = detail.history.length ? `${detail.history.map(r => ``).join("")}
時刻判定pick/place付けた
${esc(r.labeled_at)}${tag(r.outcome, r.labeler === "ai")}${r.pick}/${r.place}${LB_JA[r.labeler]}
` : `なし`; } @@ -338,6 +342,13 @@ function cursor(vt) { } // 判定するのボタン: 指定がなければ開いている回の人の確定を塗る (依頼 189) +// 開いた回の記録した行: 人の確定があればそれ, なければ確定の行 (AI だけの回は null. 依頼 190) +function recordedRow() { + if (!detail) return null; + const h = detail.history.filter(r => HUMAN.includes(r.labeler)).pop(); + const l = detail.latest; + return h || (l && l.labeler !== "ai" ? l : null); +} function humanOc() { const h = detail ? detail.history.filter(r => HUMAN.includes(r.labeler)).pop() : null; return h ? h.outcome : null; } function markOC(oc = humanOc()) { document.querySelectorAll("[data-oc]").forEach(b => b.classList.toggle("on", b.dataset.oc === oc)); } function markPP() {