fix(M01): 계산 멈춤에도 수량 칸 날식 · 까닭 날글 안 찍음 — 마지막 조각 · 빈칸 · 까닭 걸러냄 (PLAN 6장 셋째 줄)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WRFJmmhPi4exAzHgPZHMT
This commit is contained in:
2026-09-24 14:35:19 +09:00
co-authored by Claude Sonnet 5
parent 5e9df81cbd
commit 209654f311
5 changed files with 35 additions and 9 deletions
@@ -20,7 +20,7 @@ import type {
import { buildEditor, qtyKind } from "./M01_MasterData_UI_Logic_Edit";
import { formatMoney, formatPrice } from "./M01_MasterData_UI_Logic_Money";
import { openPicker } from "./M01_MasterData_UI_Logic_Pick";
import { tx } from "./M01_MasterData_UI_Logic_Text";
import { safeReason, tx } from "./M01_MasterData_UI_Logic_Text";
import { buildFormula } from "./M01_MasterData_UI_LogicLab_Formula";
import {
condText,
@@ -64,6 +64,8 @@ export interface DetailContext {
lines: CalcLine[] | null;
/** 마지막 시험 계산의 읽는 식 줄(서버가 줌) */
text: TextAnswer | null;
/** 마지막으로 잘 받은 읽는 식 — `text` 가 멈춤이면 조각을 이걸로 */
lastText?: TextAnswer;
values: Record<string, string>;
/** 자체 로직 편집기 자리 — 다시 그려도 같은 칸을 씀(고치던 값이 안 날아감) */
ownHost: HTMLElement;
@@ -166,7 +168,7 @@ function infoBox(ctx: DetailContext): HTMLElement {
className: "m01-logic__reasons",
children: [
el("strong", { text: tx("Head_Blocked") }),
...ctx.reasons.map((r) => el("div", { text: r })),
...ctx.reasons.map((r) => el("div", { text: safeReason(r) })),
],
}),
]
@@ -287,14 +289,18 @@ function entries(ctx: DetailContext): Entry[] {
* 이름을 차례로 따라가며 줄 차례에 맞춤 · 금액 0 로직 부름 줄처럼 묶음이 달라도 찾음 ·
* 끝내 못 찾으면 날식 대신 빈칸(계산 전 · 서버 실패면 식 글자 그대로) */
function attachPieces(all: Entry[], ctx: DetailContext): void {
if (!ctx.text?.ok) return;
const source = ctx.text?.ok ? ctx.text : ctx.lastText;
if (!source?.ok) {
if (ctx.text) for (const e of all) e.qtyFrag = e.piecesFrag = []; // 멈춤 · 받은 조각 없음 — 날식 대신 빈칸
return;
}
const ho = ctx.row.호표 ?? [];
const names = [
...ho.map((item) => item.이름 ?? (condOf(item) ? condLabel(condOf(item)!) : item.요소)),
...(ctx.row.덧줄 ?? []).map((extra) => extra.이름),
];
const found = new Map<string, TextLine>();
for (const g of ctx.text.groups) {
for (const g of source.groups) {
let from = 0;
for (const line of g.줄) {
const at = names.findIndex((n, i) => i >= from && n === line.이름);