Merge remote-tracking branch 'origin/sub_laptop_7' into main_laptop_1

This commit is contained in:
2026-10-17 00:36:14 +09:00
6 changed files with 75 additions and 0 deletions
@@ -245,6 +245,33 @@ function spread(state: StandardCrossSection, spec: NumberFieldSpec, value: numbe
}
}
const GROUP_LABELS: Partial<Record<StandardCrossKey, keyof typeof ui_locales>> = {
rock: "B06_Std_Note_Rock",
paved: "B06_Std_Note_Paved",
};
/**
* 공통 칸이 보이는 토사 값과 다른 그룹의 실제 값 — 「암 0.69」(보기 전용 · 364-6).
* 고치면 한 벌로 펼쳐져(`spread`) 빈 글이 됨.
*/
export function commonGroupNote(
state: StandardCrossSection,
label: keyof typeof ui_locales,
): string {
const spec = FIELD_SPECS.find((one) => one.scope === "common" && one.label === label);
if (!spec || !state.soil) return "";
const shown = spec.get(state.soil);
const unit = label.startsWith("B06_Std_Field_CrossSlope") ? " %" : "";
const notes: string[] = [];
for (const [key, name] of Object.entries(GROUP_LABELS) as [StandardCrossKey, string][]) {
const group = state[key];
if (!group || spec.exclude === key) continue;
const value = spec.get(group);
if (value !== shown) notes.push(`${L(name as keyof typeof ui_locales)} ${value}${unit}`);
}
return notes.join(" · ");
}
/**
* 표준 횡단면 설정 패널을 만든다.
* @param projectId 세션 캐시 스코프.
@@ -301,6 +328,13 @@ export function createStandardPanel(
const buildField = (spec: NumberFieldSpec, grid: HTMLElement): void => {
const source = spec.scope === "common" ? state.soil : state[spec.scope];
if (!source) return;
// 같은 줄 끝 작은 글 — 고치기 전 다른 그룹이 실제로 쓰는 값(364-6)
const note = document.createElement("span");
note.className = "b06-std__group-note";
const showNote = (): void => {
note.textContent = spec.scope === "common" ? commonGroupNote(state, spec.label) : "";
note.hidden = !note.textContent;
};
const field = createInputField({
label: L(spec.label),
type: "number",
@@ -311,8 +345,11 @@ export function createStandardPanel(
if (spec.scope === "common") spread(state, spec, parsed);
else spec.set(source, parsed);
persist();
showNote();
},
});
showNote();
field.root.querySelector(".ui-field__label")?.append(note);
field.input.step = "0.1";
field.input.min = "0";
// 경사 칸은 **각도도 함께 보인다** — 카드의 개별 절토각 칸이 도(°)로 받으므로 두 자리의
+9
View File
@@ -295,6 +295,15 @@
color: var(--color-text-secondary);
}
/* 공통 칸 라벨 끝 작은 글 — 고치기 전 암 · 포장이 실제로 쓰는 값(364-6 · 보기 전용) */
.b06-std__group-note {
margin-left: var(--spacing-4);
font-size: 0.9em;
font-weight: normal;
color: var(--color-text-muted);
white-space: nowrap;
}
.b06-std__actions {
display: flex;
gap: var(--spacing-8);
+1
View File
@@ -1,6 +1,7 @@
/* 364-6 시험 묶음 진입점 — 표준 횡단 패널 열기 전후 같은 다시 셈인지 잼(vite ssr). */
export { refreshCrossDesigns } from "../../B06_Section/B06_Section_Cross_Refresh";
export {
commonGroupNote,
createStandardPanel,
effectiveStandardCross,
rememberStandardDefaults,
@@ -60,7 +60,21 @@ async function scenario(pid, seed) {
return { b05, b06, session: m.readState("std-cross", pid) };
}
/** 공통 칸 끝 글(364-6 덧) — 고치기 전 · 공통 칸을 고친 뒤(토사 값을 다른 그룹에 펼침 = spread). */
const LABELS = [
"B06_Std_Field_DitchTop",
"B06_Std_Field_CrossSlopeMin",
"B06_Std_Field_CrossSlopeMax",
"B06_Std_Field_CutSlope",
];
const notesOf = (state) => Object.fromEntries(LABELS.map((l) => [l, m.commonGroupNote(state, l)]));
const edited = JSON.parse(JSON.stringify(standard));
edited.rock.ditch.top_width_m = edited.soil.ditch.top_width_m;
edited.paved.ditch.top_width_m = edited.soil.ditch.top_width_m;
edited.rock.cross_slope_pct.max = edited.soil.cross_slope_pct.max;
const out = {
notes: { before: notesOf(standard), after: notesOf(edited) },
server: areas(fixture.detail.cross_sections),
standard,
config: await scenario("p364a", null),
@@ -82,3 +82,15 @@ def test_B06_칸_열어도_B05_값(case, out):
@pytest.mark.parametrize("case", ["config", "stored"])
def test_칸_열기는_표준_횡단을_안_고침(case, out):
assert out[case]["session"] == out["standard"]
def test_고치기_전_공통_칸_끝에_암_값(out):
before = out["notes"]["before"]
assert before["B06_Std_Field_DitchTop"] == "암 0.69"
assert before["B06_Std_Field_CrossSlopeMax"] == "암 3 %"
assert before["B06_Std_Field_CrossSlopeMin"] == ""
assert before["B06_Std_Field_CutSlope"] == "" # 암은 자기 칸 · 포장은 같은 값
def test_고친_뒤_끝_글_없음(out):
assert set(out["notes"]["after"].values()) == {""}
+2
View File
@@ -1045,4 +1045,6 @@ export const ui_locales_b2 = {
"입금 확인이 완료되면 설계문서와 DWG 다운로드가 활성화됩니다.",
"Design document and DWG downloads are enabled after deposit confirmation.",
],
B06_Std_Note_Rock: ["암", "Rock"],
B06_Std_Note_Paved: ["포장", "Paved"],
} as const satisfies Record<string, LocaleEntry>;