feat(help): B02~B09 좌측 패널 [?] 설명서 모달 · 패널 안 설명 글을 파일로 옮김(54-2)
- [?] = 좌측 패널 아래 단추 묶음 맨 왼쪽(공용 한 벌 · B02 는 아래 단추 줄 · B08·B09 는 [?] 줄만) - 모달 = 왼쪽 차례 · 오른쪽 글 · 고른 구조물 종류 · 연 상자 항목 먼저 - 글 = resources/help/<B0N>/*.md · 서버가 열 때마다 읽음(파일만 고치면 반영) · 설명서는 뼈대 - 옮김 = B03 안내 셋 · B05 구조물 저장 규칙 · 측구 주인 · 기슭막이 근거 · 칸 기본값 근거 · B06 표준 횡단면 두 줄 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NPJGtfXo6GMbcpiboQC4uK
This commit is contained in:
@@ -373,16 +373,11 @@ export function createFacilityOptionsForm(
|
||||
// 옛 월류 폭 · 높이 · 바닥 경사 · 두께 · 길이 칸은 뺌(지난 정의 값) ──
|
||||
const paveForm = createSpecForm(specLinks, { onChange: () => emit() });
|
||||
|
||||
// 10-A ⑲ 저장 규칙을 폼 머리에 드러냄 — 병합은 `_Drainage_Facility_Merge`(2026-09-14 브레인 판정).
|
||||
const saveNote = document.createElement("p");
|
||||
saveNote.className = "b05-structure__owner-note";
|
||||
saveNote.textContent =
|
||||
"[저장]은 이 폼에 있는 칸만 바꿈 — 폼에 없는 칸(집계표·구조물도로 적은 값)은 그대로 둠 · 시설 종류를 바꾸면 새로 씀";
|
||||
// 10-A ⑲ 저장 규칙 글은 [?] 설명서 `구조물_<시설>.md` 로 옮김(54-2) — 병합은 `_Drainage_Facility_Merge`.
|
||||
|
||||
// 세월교·물넘이 항목은 **관종·관경 바로 다음**에 둔다(2026-08-30 사용자 지시 2) —
|
||||
// 월류 폭·높이 → 바닥 경사 → 수량 → 개략 단면 결과. 다른 시설에서는 전부 숨는다.
|
||||
root.append(
|
||||
saveNote,
|
||||
pipeForm.root,
|
||||
fordForm.root,
|
||||
paveForm.root,
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
* ========================================================================== */
|
||||
|
||||
import { FORD_MANNING_N, FORD_SLOPE } from "@config/config_frontend";
|
||||
import revetmentSabang from "../resources/data_masonry/revetment_sabang_2026-01-01.json";
|
||||
|
||||
/* ── 유입구 구조 ──────────────────────────────────────────────────────────── */
|
||||
|
||||
@@ -245,39 +244,18 @@ export interface RevetSideGroup {
|
||||
slot: HTMLElement;
|
||||
}
|
||||
|
||||
/** 독립 기슭막이 치수 근거 줄 — `revetment_sabang_*.json` 한 벌(B08 사유와 같은 파일 · 쪽·줄 번호).
|
||||
* ⚠ 파일 판이 바뀌면 이 import 도 옮길 것 — 시험(`test_b05_revetment_sabang_basis`)이 최신 판을 대조. */
|
||||
function sabangBasisLines(): string[] {
|
||||
const { items, scope } = revetmentSabang;
|
||||
const span = (values: number[], unit = ""): string => `${values[0]}~${values[1]}${unit}`;
|
||||
return [
|
||||
`높이 — ${items.height.rule}(${items.height.source}) · ${items.height.input}`,
|
||||
`계획비탈 1:${span(items.face_slope.standard_ratio)}(${items.face_slope.source}) — 제안값은 품셈 표준경사`,
|
||||
`둑마루 두께 ${span(items.crown_thickness.standard_m, "m")}(${items.crown_thickness.source}) — 콘크리트 기준 · 돌쌓기는 뒷길이 + 0.30 식`,
|
||||
`뒷채움 조약돌 두께 — ${items.backfill_pebble.source}`,
|
||||
scope,
|
||||
];
|
||||
}
|
||||
|
||||
export function createRevetSideGroup(keys: RevetmentKeys): RevetSideGroup {
|
||||
const box = group("기슭막이");
|
||||
const kind = document.createElement("select");
|
||||
kind.replaceChildren(new Option("기슭막이", "기슭막이"));
|
||||
// 높이는 기본값 없음 — 설계자 입력(계획홍수위 + 여유고 · 2026-09-14 브레인 판정).
|
||||
const fields = createRevetmentFields(keys, { height: "" });
|
||||
const basis = document.createElement("p");
|
||||
basis.className = "b05-route__note";
|
||||
basis.replaceChildren(
|
||||
...sabangBasisLines().flatMap((line, index) =>
|
||||
index ? [document.createElement("br"), line] : [line],
|
||||
),
|
||||
);
|
||||
// 치수 근거 글(사방기술교본)은 [?] 설명서 `구조물_기슭막이.md` 로 옮김(54-2)
|
||||
const slot = document.createElement("div");
|
||||
slot.className = "b05-structure__adjust-slot";
|
||||
box.body.append(
|
||||
grid(labeled("구조", kind), fields.formField),
|
||||
...fields.rows,
|
||||
basis,
|
||||
// 단 수는 여기 두지 않는다 — 조정창에서 옮겨 오는 [추가 기슭막이(단)] 행과
|
||||
// 같은 값이라 두 벌이면 헷갈린다(2026-08-30 사용자).
|
||||
slot,
|
||||
|
||||
@@ -9,23 +9,13 @@
|
||||
|
||||
import { chainageToStation, stationToChainage } from "./B05_Profile_Util_Station";
|
||||
|
||||
export function field(
|
||||
labelText: string,
|
||||
input: HTMLElement,
|
||||
basis?: string | null,
|
||||
): HTMLLabelElement {
|
||||
export function field(labelText: string, input: HTMLElement): HTMLLabelElement {
|
||||
const wrapper = document.createElement("label");
|
||||
wrapper.className = "b05-route__field";
|
||||
const caption = document.createElement("span");
|
||||
caption.textContent = labelText;
|
||||
// 칸 밑 근거 글(`default_basis`)은 [?] 설명서 `구조물_<종류>.md` 로 옮김(54-2)
|
||||
wrapper.append(caption, input);
|
||||
// 칸 밑 근거 한 줄 — 등록부 `default_basis`(기본값의 뜻 · 10-A 2026-09-14 사용자 확정).
|
||||
if (basis) {
|
||||
const note = document.createElement("small");
|
||||
note.className = "b05-structure__basis";
|
||||
note.textContent = basis;
|
||||
wrapper.append(note);
|
||||
}
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,8 +35,6 @@ export interface StructuresFormElements {
|
||||
body: HTMLElement;
|
||||
groupSelect: HTMLSelectElement;
|
||||
typeSelect: HTMLSelectElement;
|
||||
/** 「제원·수량은 다른 화면이 냅니다」 안내 한 줄 — `design_owner` 가 있을 때만 보인다. */
|
||||
ownerNote: HTMLElement;
|
||||
startFields: StationFields;
|
||||
anchorFields: StationFields;
|
||||
endFields: StationFields;
|
||||
@@ -113,13 +111,6 @@ export function buildStructuresForm(options: {
|
||||
typeRow.className = "b05-structure__grid";
|
||||
typeRow.append(field("구조물군", groupSelect), field("종류", typeSelect));
|
||||
|
||||
// 「제원·수량은 다른 화면이 냅니다」 안내 한 줄 — 목록 항목은 [측점][이름]만 적는 규칙이라
|
||||
// (2026-08-18 사용자 지시) 표시는 이 폼에 둔다. 측구(옆도랑)가 그 경우다(2026-09-07 사용자:
|
||||
// 「두되 표시만 해줘」). 문구는 레지스트리 `design_owner` 값으로 만든다.
|
||||
const ownerNote = document.createElement("p");
|
||||
ownerNote.className = "b05-structure__owner-note";
|
||||
ownerNote.hidden = true;
|
||||
|
||||
// 옵션 칸은 타입마다 다르므로 선택할 때마다 새로 그린다.
|
||||
const optionRow = document.createElement("div");
|
||||
optionRow.className = "b05-structure__grid";
|
||||
@@ -178,7 +169,6 @@ export function buildStructuresForm(options: {
|
||||
|
||||
body.append(
|
||||
typeRow,
|
||||
ownerNote,
|
||||
positionRow,
|
||||
summary.root, // 종류 단위 「구조물 조합」 잇기 — 기준 측점 바로 아래(PLAN 52-1 · 컨테이너 없는 종류)
|
||||
positionDivider,
|
||||
@@ -195,7 +185,6 @@ export function buildStructuresForm(options: {
|
||||
body,
|
||||
groupSelect,
|
||||
typeSelect,
|
||||
ownerNote,
|
||||
startFields,
|
||||
anchorFields,
|
||||
endFields,
|
||||
|
||||
@@ -78,7 +78,6 @@ export function createStructuresSection(
|
||||
body,
|
||||
groupSelect,
|
||||
typeSelect,
|
||||
ownerNote,
|
||||
startFields,
|
||||
anchorFields,
|
||||
endFields,
|
||||
@@ -233,12 +232,8 @@ export function createStructuresSection(
|
||||
startFields.wrap.hidden = !isInterval;
|
||||
endFields.wrap.hidden = !isInterval;
|
||||
primary.disabled = !type;
|
||||
// 제원·수량 주인이 다른 화면인 타입은 그 사실을 폼에 적는다 — 목록에서 안 보이면
|
||||
// 「측구가 왜 없지」로 헤매고, 그렇다고 수량에 넣으면 이중 계상이다(2026-09-07 사용자).
|
||||
ownerNote.textContent = type?.design_owner
|
||||
? `${type.design_owner}에서 관리 — 여기서 넣어도 제원·수량은 그쪽 값을 씁니다.`
|
||||
: "";
|
||||
ownerNote.hidden = !type?.design_owner;
|
||||
// [?] 설명서가 먼저 여는 항목 = `구조물_<종류 이름>.md`(54-2 · 종류 안내 글은 그 파일로 옮김)
|
||||
root.dataset.helpTopic = type ? `구조물_${type.name}` : "";
|
||||
// 정의가 기준 측점을 끈 종류(48-3) — 기준 측점이 곧 위치인 종류(점형 · 범위 계산)는 늘 보임
|
||||
anchorFields.wrap.hidden = isInterval && !showsAnchor(type!);
|
||||
anchorFields.wrap.querySelector("span")!.textContent = isInterval
|
||||
|
||||
@@ -101,11 +101,7 @@ export function renderOptionFields(
|
||||
// 정의 그룹 상자로 옮겨 갈 숫자 칸 = 명세 컨테이너와 같은 [-][숫자][+](52-18)
|
||||
const grouped =
|
||||
option.input === "number" && !!type.groups?.some((g) => g.options.includes(option.key));
|
||||
const wrap = field(
|
||||
label,
|
||||
grouped ? stepper(input as HTMLInputElement, 0.1) : input,
|
||||
option.default_basis,
|
||||
);
|
||||
const wrap = field(label, grouped ? stepper(input as HTMLInputElement, 0.1) : input);
|
||||
if (grouped) wrap.htmlFor = input.id; // 라벨 대상 = 숫자 칸(첫 버튼으로 새지 않게)
|
||||
wrap.dataset.optionKeys = option.key; // 옵션 그룹 상자가 이 표식으로 칸을 옮김(PLAN 46-3)
|
||||
// 배치 격자(48-3) — 정의 `배치` 의 줄 · 칸 · 너비 · 없으면 흐름대로
|
||||
|
||||
@@ -215,13 +215,6 @@
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 칸 밑 근거 한 줄 — 등록부 `default_basis`(10-A). 회색 작은 글씨. */
|
||||
.b05-structure__basis {
|
||||
color: var(--color-text-muted, #9aa1ad);
|
||||
font-size: var(--text-caption, 12px);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
/* 시작·기준·종료 측점 = 3행. 한 행은 [라벨][측점][+거리] 가로 배치
|
||||
* (2026-08-17 사용자 지시 2). */
|
||||
.b05-structure__position-row {
|
||||
|
||||
Reference in New Issue
Block a user