From 7eecfacca3fc55cb273e18ebaf2f66bf1aa0e645 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 14 Sep 2026 09:14:50 +0900 Subject: [PATCH] =?UTF-8?q?fix(b05):=20=EA=B8=B0=EB=B3=B8=EA=B0=92=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=EA=B3=A0=EB=A5=B4=EA=B8=B0=20=EC=B9=B8?= =?UTF-8?q?=EC=9D=80=20=E3=80=8C=EC=95=88=20=EC=A0=95=ED=95=A8=E3=80=8D?= =?UTF-8?q?=EC=9D=B4=20=EC=8B=A4=EC=A0=9C=20=EC=83=81=ED=83=9C=20=E2=80=94?= =?UTF-8?q?=20=EC=B2=AB=20=EC=84=A0=ED=83=9D=EC=A7=80=EB=A5=BC=20=EB=AF=B8?= =?UTF-8?q?=EB=A6=AC=20=EA=B3=A0=EB=A5=B4=EC=A7=80=20=EC=95=8A=EC=9D=8C(?= =?UTF-8?q?=ED=8F=BC=20=E2=91=A0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 뿌리: 사용자가 고른 적 없는 첫 선택지가 저장돼 확정으로 굳음(옛 2026-08-17 「빈 보기 두지 않음」 걷음) - 구조물 목록 일반 폼: 기본값 없는 고르기 칸은 늘 빈 보기(필수 「— 선택 —」 · 아니면 「— 안 정함 —」) - 시설 폼 optionalSelect: 맨 앞 빈 보기(날개벽 「안 놓음」 등) — 기본값이 있는 칸은 다음 차례(②③) - ORCA 936be972 B05 관 폼: 날개벽 「안 놓음」 빈 값으로 섬 확인 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq --- .../B05_Profile_UI_Drainage_Facility.ts | 2 +- ...B05_Profile_UI_Drainage_Facility_Fields.ts | 12 +++++++---- .../B05_Profile_UI_Structures_Panel.ts | 20 ++++++++----------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/B05_Profile/B05_Profile_UI_Drainage_Facility.ts b/B05_Profile/B05_Profile_UI_Drainage_Facility.ts index bd9acc19..a909b640 100644 --- a/B05_Profile/B05_Profile_UI_Drainage_Facility.ts +++ b/B05_Profile/B05_Profile_UI_Drainage_Facility.ts @@ -284,7 +284,7 @@ export function createFacilityOptionsForm( // 나눈다(2026-08-30 사용자). 설치 측이 한쪽이면 그 칸만 뜬다. // 좌·우가 저장 채널(유입/유출) 중 어느 쪽인지는 측점 지형이 정하므로 이름표만 // 바꿔 단다(`setRevetSideLabels`) — 값은 언제나 그 채널 키로 오간다. - const revetSide = optionalSelect("양쪽", ["양쪽", "좌", "우"]); + const revetSide = optionalSelect("— 안 정함 —", ["양쪽", "좌", "우"]); revetSide.value = "양쪽"; const revetTopRow = grid(labeled("설치 측", revetSide)); const revetInlet = createRevetSideGroup(INLET_REVET_KEYS, "돌쌓기(메)"); diff --git a/B05_Profile/B05_Profile_UI_Drainage_Facility_Fields.ts b/B05_Profile/B05_Profile_UI_Drainage_Facility_Fields.ts index 36d3a3a6..2116f882 100644 --- a/B05_Profile/B05_Profile_UI_Drainage_Facility_Fields.ts +++ b/B05_Profile/B05_Profile_UI_Drainage_Facility_Fields.ts @@ -153,14 +153,18 @@ export function putNumber(target: Record, key: string, if (Number.isFinite(value) && value > 0) target[key] = Number(value.toFixed(1)); } -/** 선택지 셀렉트 — 빈("미지정") 항목을 두지 않는다. 첫 항목이 곧 기본값이고, - * 기본값은 구조물별로 따로 지정한다(2026-08-17 사용자 지시 1). */ +/** 선택지 셀렉트 — **맨 앞에 빈 보기(「안 정함」)** 를 둠. 첫 보기를 미리 고르지 않음 + * (2026-09-14 브레인 판정 · 옛 2026-08-17 「빈 항목 두지 않음」 걷음) — 고른 적 없는 첫 값이 저장돼 + * 확정으로 굳지 않게. 기본값이 있는 칸은 부르는 쪽이 값을 넣음(그것은 따로 차례). */ export function optionalSelect( - _blankLabel: string, + blankLabel: string, choices: ReadonlyArray, ): HTMLSelectElement { const element = document.createElement("select"); - element.replaceChildren(...choices.map((choice) => new Option(choice, choice))); + element.replaceChildren( + new Option(blankLabel, ""), + ...choices.map((choice) => new Option(choice, choice)), + ); return element; } diff --git a/B05_Profile/B05_Profile_UI_Structures_Panel.ts b/B05_Profile/B05_Profile_UI_Structures_Panel.ts index b106e926..023e352b 100644 --- a/B05_Profile/B05_Profile_UI_Structures_Panel.ts +++ b/B05_Profile/B05_Profile_UI_Structures_Panel.ts @@ -320,20 +320,16 @@ export function createStructuresSection( const preset = values[option.key] ?? option.default ?? ""; let input: HTMLInputElement | HTMLSelectElement; if (option.input === "select") { - // 빈("선택하세요") 항목은 두지 않는다 — 첫 항목이 곧 기본값이고, 기본값은 - // 구조물별로 레지스트리에서 지정한다(2026-08-17 사용자 지시 1). const choices = option.choices.map((choice) => [choice, choice] as [string, string]); - // 기본값 없는 필수 항목은 **빈 칸으로** — 첫 항목을 슬쩍 고르면 근거 없는 값이 나간다. - const mustPick = option.required === true && (option.default ?? "") === ""; - // **비워 두는 것이 뜻인 칸**(`empty_means`)도 같다 — 비면 계산 쪽이 기준값으로 도는데 - // 첫 보기가 골라져 저장되면 기준과 다른 값이 조용히 나간다(2026-09-13: - // `fill_concrete_mpa` 가 180 으로 박혀 엔진 기준 210 과 갈렸다). 기본값이 **있는** 칸은 - // 그대로 첫 보기를 쓴다 — 2026-08-17 「빈 보기 두지 않음」 지시가 그 자리다. - const meansEmpty = (option.empty_means ?? "") !== "" && (option.default ?? "") === ""; - const keepEmpty = mustPick || meansEmpty; - if (keepEmpty) choices.unshift(["", mustPick ? "— 선택 —" : "— 안 정함 —"]); + // ⭐ 기본값 없는 고르기 칸은 **「안 정함」이 실제 상태** — 첫 보기를 미리 고르지 않음 + // (2026-09-14 브레인 판정, 옛 2026-08-17 「빈 보기 두지 않음」을 걷음). 사용자가 고른 적 + // 없는 첫 값이 저장돼 확정으로 굳는 뿌리였음(2026-09-13 `fill_concrete_mpa` 180 박힘도 + // 같은 병). 저장에는 빈 값이 가고 표가 사유를 보임. + if ((option.default ?? "") === "") { + choices.unshift(["", option.required === true ? "— 선택 —" : "— 안 정함 —"]); + } input = select(choices); - input.value = String(preset || (keepEmpty ? "" : (option.choices[0] ?? ""))); + input.value = String(preset); } else if (option.input === "number") { input = numberInput("0.1", "0"); input.value = String(preset ?? "");