feat(B05,B08,B09): 269-3 B05 이상 좌측 컨테이너 공용 양식 점검 · 맞춤
- B05 칸 틀(페이지 설정 · 계획노선 · 선택 포인트) = .ui-panel-form - B08 옵션 카드 · B09 데이터 점검 카드 = createPanelCard · 틈 덧칠 정리 - 아래 단추 묶음은 그대로 - 시험 test_269 점검(빠진 곳 0) · 122 · 203-1 · 240-1 기대값 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QND7Co43B24zK2P937rdxt
This commit is contained in:
@@ -82,15 +82,15 @@ export function createSectionFrame(
|
|||||||
heading.textContent = title;
|
heading.textContent = title;
|
||||||
if (view === "profile") {
|
if (view === "profile") {
|
||||||
// ui-sidebar-section: 사이드 컨테이너 공통 외곽선(진하게, 2026-08-05 사용자 지시).
|
// ui-sidebar-section: 사이드 컨테이너 공통 외곽선(진하게, 2026-08-05 사용자 지시).
|
||||||
|
// ui-panel-form: 좌측 패널 컨테이너 공용 양식(269 · 「구조물 배치」 기준 칸 · 라벨 · 단추) — 두 보기 모두.
|
||||||
// 접힘 초기값만 여기서 준다 — 펼치기·접기 토글은 ui_template_collapsible 전역 몫.
|
// 접힘 초기값만 여기서 준다 — 펼치기·접기 토글은 ui_template_collapsible 전역 몫.
|
||||||
root.className = `b05-route__panel-section ui-collapsible ui-sidebar-section${collapsed ? " is-collapsed" : ""}`;
|
root.className = `b05-route__panel-section ui-collapsible ui-sidebar-section ui-panel-form${collapsed ? " is-collapsed" : ""}`;
|
||||||
heading.className = "ui-collapsible__title";
|
heading.className = "ui-collapsible__title";
|
||||||
const body = document.createElement("div");
|
const body = document.createElement("div");
|
||||||
body.className = "b05-route__panel-body";
|
body.className = "b05-route__panel-body";
|
||||||
root.append(heading, body);
|
root.append(heading, body);
|
||||||
return { root, body };
|
return { root, body };
|
||||||
}
|
}
|
||||||
// ui-panel-form: 좌측 패널 컨테이너 공용 양식(269 · 「구조물 배치」 기준 칸 · 라벨 · 단추).
|
|
||||||
root.className = `b06-profile__group ui-collapsible ui-sidebar-section ui-panel-form${collapsed ? " is-collapsed" : ""}`;
|
root.className = `b06-profile__group ui-collapsible ui-sidebar-section ui-panel-form${collapsed ? " is-collapsed" : ""}`;
|
||||||
heading.className = "b06-profile__group-legend ui-collapsible__title";
|
heading.className = "b06-profile__group-legend ui-collapsible__title";
|
||||||
root.append(heading);
|
root.append(heading);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import {
|
|||||||
showLoadingOverlay,
|
showLoadingOverlay,
|
||||||
showToast,
|
showToast,
|
||||||
} from "@ui/ui_template_elements";
|
} from "@ui/ui_template_elements";
|
||||||
import { attachCollapsible } from "@ui/ui_template_collapsible";
|
import { attachCollapsible, createPanelCard } from "@ui/ui_template_collapsible";
|
||||||
import { ui_locales, currentLanguageIndex } from "@ui/ui_template_locale";
|
import { ui_locales, currentLanguageIndex } from "@ui/ui_template_locale";
|
||||||
import { clearState, readState, writeState } from "../A00_Common/b_page_state";
|
import { clearState, readState, writeState } from "../A00_Common/b_page_state";
|
||||||
import { request } from "./B08_Quantity_UI_Hydro";
|
import { request } from "./B08_Quantity_UI_Hydro";
|
||||||
@@ -85,14 +85,11 @@ export function onOptionsChange(host: HTMLElement, fn: () => void): void {
|
|||||||
|
|
||||||
const pctText = (value: number): string => String(Math.round(value * 1e6) / 1e6);
|
const pctText = (value: number): string => String(Math.round(value * 1e6) / 1e6);
|
||||||
|
|
||||||
|
/** 카드 = 좌측 패널 공용 카드(269 · 「구조물 배치」 양식). */
|
||||||
function card(id: string, title: keyof typeof ui_locales, ...body: HTMLElement[]): HTMLElement {
|
function card(id: string, title: keyof typeof ui_locales, ...body: HTMLElement[]): HTMLElement {
|
||||||
const section = document.createElement("section");
|
const section = createPanelCard(L(title));
|
||||||
section.className = "ui-collapsible ui-sidebar-section ui-sidebar-card";
|
|
||||||
section.dataset.b08Options = id;
|
section.dataset.b08Options = id;
|
||||||
const heading = document.createElement("h3");
|
section.append(...body);
|
||||||
heading.className = "ui-collapsible__title";
|
|
||||||
heading.textContent = L(title);
|
|
||||||
section.append(heading, ...body);
|
|
||||||
return section;
|
return section;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,8 +82,9 @@
|
|||||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 칸과의 틈 = 공용 카드 틈(269) */
|
||||||
.b08-options__hint {
|
.b08-options__hint {
|
||||||
margin: var(--spacing-4) 0 0;
|
margin: 0;
|
||||||
color: var(--color-text-secondary);
|
color: var(--color-text-secondary);
|
||||||
font-size: var(--text-caption);
|
font-size: var(--text-caption);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,9 +179,9 @@
|
|||||||
background: var(--color-warning);
|
background: var(--color-warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 122 데이터 점검 [업데이트] — 제목 아래 틈 = 카드 왼쪽 여유와 같게 */
|
/* 122 데이터 점검 [업데이트] — 제목 아래 틈 = 카드 왼쪽 여유와 같게(공용 카드 틈 8 + 4) */
|
||||||
.b09-options [data-b09-refresh] {
|
.b09-options [data-b09-refresh] {
|
||||||
margin-top: calc(var(--spacing-8) + var(--spacing-4));
|
margin-top: var(--spacing-4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 연결 점검 목록 — 이름 · 탭(작게) · 알림 글 */
|
/* 연결 점검 목록 — 이름 · 탭(작게) · 알림 글 */
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import {
|
|||||||
showLoadingOverlay,
|
showLoadingOverlay,
|
||||||
showToast,
|
showToast,
|
||||||
} from "@ui/ui_template_elements";
|
} from "@ui/ui_template_elements";
|
||||||
import { attachCollapsible } from "@ui/ui_template_collapsible";
|
import { attachCollapsible, createPanelCard } from "@ui/ui_template_collapsible";
|
||||||
import { cellColumn, createDataTable, type DataTable } from "@ui/ui_template_data_table";
|
import { cellColumn, createDataTable, type DataTable } from "@ui/ui_template_data_table";
|
||||||
import { attachHoverInfo } from "@ui/ui_template_hover_info";
|
import { attachHoverInfo } from "@ui/ui_template_hover_info";
|
||||||
import { ui_locales, currentLanguageIndex } from "@ui/ui_template_locale";
|
import { ui_locales, currentLanguageIndex } from "@ui/ui_template_locale";
|
||||||
@@ -359,12 +359,9 @@ export function renderB09Estimation(root: HTMLElement): void {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
reset.dataset.b09BillReset = "";
|
reset.dataset.b09BillReset = "";
|
||||||
const section = document.createElement("section");
|
// 카드 = 좌측 패널 공용 카드(269 · 「구조물 배치」 양식)
|
||||||
section.className = "ui-collapsible ui-sidebar-section ui-sidebar-card";
|
const section = createPanelCard("데이터 점검");
|
||||||
const heading = document.createElement("h3");
|
section.append(refresh, check.list);
|
||||||
heading.className = "ui-collapsible__title";
|
|
||||||
heading.textContent = "데이터 점검";
|
|
||||||
section.append(heading, refresh, check.list);
|
|
||||||
const actions = document.createElement("div");
|
const actions = document.createElement("div");
|
||||||
actions.className = "ui-sidebar-actions";
|
actions.className = "ui-sidebar-actions";
|
||||||
actions.append(save, reset);
|
actions.append(save, reset);
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ def test_좌측_패널_컨테이너_셋과_저장_줄():
|
|||||||
)
|
)
|
||||||
assert 'card("summary", "B08_Quantity_Tab_StructureSummary", one.root),' in panel
|
assert 'card("summary", "B08_Quantity_Tab_StructureSummary", one.root),' in panel
|
||||||
assert 'card("material", "B08_Quantity_Tab_Materials", ...surchargeBlock),' in panel
|
assert 'card("material", "B08_Quantity_Tab_Materials", ...surchargeBlock),' in panel
|
||||||
assert "ui-collapsible ui-sidebar-section ui-sidebar-card" in panel
|
assert "createPanelCard(L(title))" in panel # 269 좌측 패널 공용 카드
|
||||||
assert (
|
assert (
|
||||||
'actions.className = "ui-sidebar-actions"' in panel and "attachCollapsible(panel)" in panel
|
'actions.className = "ui-sidebar-actions"' in panel and "attachCollapsible(panel)" in panel
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ SHELL = (ROOT / "B09_Estimation/B09_Estimation_UI_Shell.ts").read_text("utf-8")
|
|||||||
|
|
||||||
|
|
||||||
def test_묶음_이름_단추_글_설명_없음():
|
def test_묶음_이름_단추_글_설명_없음():
|
||||||
assert 'heading.textContent = "데이터 점검";' in SHELL and "원가 단가" not in SHELL
|
assert 'createPanelCard("데이터 점검")' in SHELL and "원가 단가" not in SHELL # 269 공용 카드
|
||||||
assert 'label: "업데이트",' in SHELL and "단가 갱신" not in SHELL
|
assert 'label: "업데이트",' in SHELL and "단가 갱신" not in SHELL
|
||||||
# 옛 굳힌 시각 안내 글(made) 없음 · 묶음 = 제목 · [업데이트] · 연결 점검
|
# 옛 굳힌 시각 안내 글(made) 없음 · 묶음 = 제목 · [업데이트] · 연결 점검
|
||||||
assert "made.textContent" not in SHELL and "b09-estimation__hint" not in SHELL
|
assert "made.textContent" not in SHELL and "b09-estimation__hint" not in SHELL
|
||||||
assert "section.append(heading, refresh, check.list);" in SHELL
|
assert "section.append(refresh, check.list);" in SHELL # 제목 = 공용 카드(269)
|
||||||
assert "check.draw(payload, sheets);" in SHELL
|
assert "check.draw(payload, sheets);" in SHELL
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,12 @@ def test_끌기_미리_보기_어디_안_몇_레벨_폴더_테두리_끄는_줄_
|
|||||||
def test_데이터_점검_업데이트_위_틈_카드_왼쪽_여유와_같음():
|
def test_데이터_점검_업데이트_위_틈_카드_왼쪽_여유와_같음():
|
||||||
css = _read(B09 / "B09_Estimation_UI_Page.css")
|
css = _read(B09 / "B09_Estimation_UI_Page.css")
|
||||||
m = re.search(r"\.b09-options \[data-b09-refresh\] \{\s*margin-top: ([^;]+);", css)
|
m = re.search(r"\.b09-options \[data-b09-refresh\] \{\s*margin-top: ([^;]+);", css)
|
||||||
assert m and m.group(1) == "calc(var(--spacing-8) + var(--spacing-4))"
|
# 269 — 공용 카드 틈(8) + 4 = 카드 왼쪽 여유(12)
|
||||||
|
assert m and m.group(1) == "var(--spacing-4)"
|
||||||
|
overlay = _read(ROOT / "ui_template" / "ui_template_overlay.css")
|
||||||
|
assert re.search(
|
||||||
|
r":where\(\.ui-sidebar-card\.ui-panel-form\) \{[^}]*gap: var\(--spacing-8\);", overlay
|
||||||
|
)
|
||||||
card = _read(ROOT / "ui_template" / "ui_template_overlay.css")
|
card = _read(ROOT / "ui_template" / "ui_template_overlay.css")
|
||||||
assert re.search(
|
assert re.search(
|
||||||
r"\.ui-sidebar-card \{\s*padding: calc\(var\(--spacing-8\) \+ var\(--spacing-4\)\);", card
|
r"\.ui-sidebar-card \{\s*padding: calc\(var\(--spacing-8\) \+ var\(--spacing-4\)\);", card
|
||||||
|
|||||||
@@ -122,3 +122,53 @@ def test_B06_컨테이너_공용_양식():
|
|||||||
rule = _block(B06_CSS, line[:-2])
|
rule = _block(B06_CSS, line[:-2])
|
||||||
for prop in ("height", "padding", "font-size"):
|
for prop in ("height", "padding", "font-size"):
|
||||||
assert not re.search(r"(?:^|\s)" + prop + r"\s*:", rule), (line, prop)
|
assert not re.search(r"(?:^|\s)" + prop + r"\s*:", rule), (line, prop)
|
||||||
|
|
||||||
|
|
||||||
|
B08_OPTIONS = _read("B08_Quantity/B08_Quantity_UI_Options.ts")
|
||||||
|
B09_SHELL = _read("B09_Estimation/B09_Estimation_UI_Shell.ts")
|
||||||
|
# 기준(「구조물 배치」 폼 자신) · 부르는 곳 없는 옛 함수는 점검 밖
|
||||||
|
PANEL_DIRS = (
|
||||||
|
"A00_Common/design",
|
||||||
|
"B05_Profile",
|
||||||
|
"B06_Section",
|
||||||
|
"B07_DesignDetail",
|
||||||
|
"B08_Quantity",
|
||||||
|
"B09_Estimation",
|
||||||
|
)
|
||||||
|
REFERENCE = {
|
||||||
|
"B05_Profile/B05_Profile_UI_Structures_Form.ts",
|
||||||
|
"B05_Profile/B05_Profile_UI_IrregularStations.ts",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_B05_칸_틀_두_보기_모두_공용_양식():
|
||||||
|
frame = DESIGN_PANEL[DESIGN_PANEL.index("export function createSectionFrame(") :]
|
||||||
|
frame = frame[: frame.index("\n}\n")]
|
||||||
|
assert frame.count("ui-sidebar-section ui-panel-form") == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_B08_B09_카드_공용_카드():
|
||||||
|
assert "createPanelCard(L(title))" in B08_OPTIONS
|
||||||
|
assert 'createPanelCard("데이터 점검")' in B09_SHELL
|
||||||
|
for src in (B08_OPTIONS, B09_SHELL):
|
||||||
|
assert "ui-sidebar-card" not in src
|
||||||
|
|
||||||
|
|
||||||
|
def test_점검_B05_이상_좌측_컨테이너는_모두_공용_양식():
|
||||||
|
"""손으로 짠 컨테이너(ui-sidebar-section)에 공용 양식이 빠진 곳 = 0."""
|
||||||
|
misses, users = [], []
|
||||||
|
for page in PANEL_DIRS:
|
||||||
|
for path in (ROOT / page).glob("*.ts"):
|
||||||
|
rel = path.relative_to(ROOT).as_posix()
|
||||||
|
text = path.read_text(encoding="utf-8")
|
||||||
|
if "createIrregularStationsSection(" in text:
|
||||||
|
users.append(path.name)
|
||||||
|
if rel in REFERENCE:
|
||||||
|
continue
|
||||||
|
for n, line in enumerate(text.splitlines(), 1):
|
||||||
|
code = line.split("//")[0]
|
||||||
|
if "ui-sidebar-section" in code and "ui-panel-form" not in code:
|
||||||
|
misses.append(f"{rel}:{n}")
|
||||||
|
assert misses == []
|
||||||
|
# 점검 밖 옛 함수 = 정말 부르는 곳 없음(살아나면 점검에 넣음)
|
||||||
|
assert users == ["B05_Profile_UI_IrregularStations.ts"]
|
||||||
|
|||||||
Reference in New Issue
Block a user