fix(M02 실무자료): 339 덧고침 2 — 본 칸 호표 목록 제안 수 · 셈 중 표시 셈 끝까지 다시 읽음

- 본 칸 호표 표: 뒤 숫자 판정 셈 중이면 3 초마다 다시 읽어 「제안 n / 줄 m」 · 호표 줄 갱신(찾기 글 그대로)
- 머리 줄 「숫자 판정 셈 중 n/m」 표시 · 셈 끝 · 호표 하나로 감 · 못 읽음이면 멈춤

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWh5wNNycMkbwMpACz1rte
This commit is contained in:
2026-10-16 01:13:13 +09:00
co-authored by Claude Opus 5.5
parent 480a93ce1c
commit ca5485b208
2 changed files with 42 additions and 3 deletions
@@ -14,7 +14,7 @@ import {
type HopyoScope,
type HopyoView,
} from "./M02_MasterTemplete_Hopyo_Api";
import { buildHopyoCheck } from "./M02_MasterTemplete_Hopyo_Check";
import { buildHopyoCheck, POLL_MS } from "./M02_MasterTemplete_Hopyo_Check";
import type { HopyoSheetOptions } from "./M02_MasterTemplete_Hopyo_Sheet";
import "./M02_MasterTemplete_Hopyo.css";
@@ -79,6 +79,7 @@ export function buildHopyoView(key: string, opt: HopyoViewOptions): HTMLElement
() => void drawFile(),
);
if (!file) return;
let hopyos = file.호표;
const search = el("input", {
className: "ui-input ui-input--sm m02-hopyo__search",
attrs: { type: "search", placeholder: "호표 · 품명 · 규격 찾기", value: query },
@@ -88,7 +89,7 @@ export function buildHopyoView(key: string, opt: HopyoViewOptions): HTMLElement
const q = search.value.trim().toLowerCase();
query = search.value;
body.replaceChildren(
...file.호표
...hopyos
.filter((h) => !q || `제${h.번}호표 ${h.이름} ${h.규격}`.toLowerCase().includes(q))
.map((h) => {
const tr = el("tr", {
@@ -110,6 +111,32 @@ export function buildHopyoView(key: string, opt: HopyoViewOptions): HTMLElement
};
search.addEventListener("input", paint);
paint();
// 뒤 숫자 판정 셈 중이면 3 초마다 다시 읽어 「제안 n / 줄 m」 갱신 — 셈 끝 · 다른 화면 · 못 읽음이면 멈춤
const ready = note("");
const calc = note("");
const show = (f: HopyoView): void => {
ready.textContent = `제안 ${f.맞춤[0]} / 줄 ${f.맞춤[1]}`;
const c = f.셈 && !f.셈.끝 ? f.셈 : null;
calc.textContent = c
? `숫자 판정 셈 중 ${c.한}/${c.모두 ?? "?"}${c.까닭 ? ` · ${c.까닭}` : ""}`
: "";
calc.hidden = !c;
};
const my = nav;
const live = (): boolean => my === nav && view.isConnected;
const poll = (f: HopyoView): void => {
if (!f.셈 || f.셈.끝) return;
window.setTimeout(async () => {
const next = live() ? await readHopyo(opt.scope, key).catch(() => null) : null;
if (!next || !live()) return;
hopyos = next.호표;
show(next);
paint();
poll(next);
}, POLL_MS);
};
show(file);
poll(file);
const wrong = file.검산.어긋남;
view.replaceChildren(
el("div", {
@@ -119,7 +146,8 @@ export function buildHopyoView(key: string, opt: HopyoViewOptions): HTMLElement
note(`시트 ${file.시트}`),
note(`호표 ${file.호표수}`),
note(wrong.length ? `검산 어긋남 ${wrong.length}` : "검산 맞음"),
note(`제안 ${file.맞춤[0]} / 줄 ${file.맞춤[1]}`),
ready,
calc,
createButton({
label: "엑셀로 보기",
size: "sm",
+11
View File
@@ -394,3 +394,14 @@ def test_확인_창_손질_339():
assert "poll(file);" in sheet and "poll(next);" in sheet and "POLL_MS" in sheet
assert "if (ok) document.dispatchEvent(new Event(HOPYO_BUILT));" in sheet
assert '`맞음 ${tally("맞음")} · 다른 점 ${tally("다른 점")}`' in sheet
def test_본_칸_호표_목록_셈_끝까지_다시_읽음_339():
"""339 덧고침 2 — 본 칸 호표 표 「제안 n / 줄 m」 · 머리 「셈 중」 — 셈 중이면 3 초마다 다시 읽음."""
view = _text("M02_MasterTemplete_Hopyo_View.ts")
assert "poll(file);" in view and "poll(next);" in view and "POLL_MS" in view
assert "hopyos = next.호표;" in view and "...hopyos" in view
assert (
"const live = (): boolean => my === nav && view.isConnected;" in view
) # 호표 하나로 가면 멈춤
assert "숫자 판정 셈 중" in view