refactor(B05): 노선 추천 창 칸 · 후보 표를 부품 입력 · 표로 (PLAN 553-2)
- 제약 · 비중 · 목표 기울기 칸 = 부품 입력 단 32(옛 작은 칸 30 + 페이지 덮음 둥글기 4 · 글 16 지움) · 지형 고르기 = 단 32 - 후보 표 = 부품 표 데이터표(줄 28 · 수 칸 오른쪽) · 페이지 표 CSS 지움 - 표 부품 CSS 를 design_page 가 실음 · 시험(test_63_4) 머리 칸 글 고침 - 그림 색 전후 다름 0(밝음 · 어두움) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -49,9 +49,10 @@ import {
|
||||
peekSectionDetail,
|
||||
} from "../../B06_Section/B06_Section_Section_Store";
|
||||
import "./design_page.css";
|
||||
// 클래스로 붙이는 부품(체크 · 빈 상태 · 보조 글)의 CSS — B05 · B06 화면 파일이 시험 때문에 import 없이 클래스만 씀(553-2)
|
||||
// 클래스로 붙이는 부품(체크 · 빈 상태 · 보조 글 · 표)의 CSS — B05 · B06 화면 파일이 시험 때문에 import 없이 클래스만 씀(553-2)
|
||||
import "@ui/ui_template_checkbox";
|
||||
import "@ui/ui_template_empty";
|
||||
import "@ui/ui_template_table";
|
||||
import "@ui/ui_template_text";
|
||||
|
||||
export type { DesignPageShared } from "./design_shared";
|
||||
|
||||
@@ -229,7 +229,7 @@ export function openRecommendModal(params: RecommendParams): void {
|
||||
</div>
|
||||
<label class="b05-routerec__terrain" data-terrain-row hidden
|
||||
title="추천 · 초기 종단을 셀 지형 — [적용]하면 이 지형이 설계 지형(평면 · 종단 · 횡단)">지형
|
||||
<select class="ui-select ui-select--sm" data-act="terrain">
|
||||
<select class="ui-select ui-select--sm" data-size="32" data-act="terrain">
|
||||
<option value="las">라이다</option>
|
||||
<option value="sheet">수치지형도</option>
|
||||
</select></label>
|
||||
@@ -287,7 +287,7 @@ export function openRecommendModal(params: RecommendParams): void {
|
||||
for (const key of WEIGHT_KEYS) {
|
||||
const bar = document.createElement("div");
|
||||
bar.className = "b05-routerec__bar";
|
||||
const numField = createInputField({ type: "number", min: 0, max: 100, compact: true });
|
||||
const numField = createInputField({ type: "number", min: 0, max: 100, size: 32 }); // 부품 입력 단 32(553-2)
|
||||
numField.input.step = "1";
|
||||
numField.input.inputMode = "numeric";
|
||||
numField.input.classList.add("b05-routerec__num");
|
||||
@@ -321,7 +321,7 @@ export function openRecommendModal(params: RecommendParams): void {
|
||||
row.title = field.title;
|
||||
const name = document.createElement("span");
|
||||
name.textContent = field.label;
|
||||
const input = createInputField({ type: "number", min: 0, compact: true });
|
||||
const input = createInputField({ type: "number", min: 0, size: 32 }); // 부품 입력 단 32(553-2)
|
||||
input.input.inputMode = "decimal";
|
||||
input.input.step = "0.1";
|
||||
input.input.dataset.criteria = key;
|
||||
@@ -332,7 +332,7 @@ export function openRecommendModal(params: RecommendParams): void {
|
||||
criteriaBox.append(row);
|
||||
}
|
||||
|
||||
const targetField = createInputField({ type: "number", min: 0, max: 100, compact: true });
|
||||
const targetField = createInputField({ type: "number", min: 0, max: 100, size: 32 }); // 부품 입력 단 32(553-2)
|
||||
targetField.input.inputMode = "decimal";
|
||||
targetField.input.step = "0.1";
|
||||
targetField.input.dataset.criteria = TARGET_GRADE_KEY;
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
* (`initial_profile` · 438 직선화 · 종단곡선 포함)을 펴서 같은 그림에 선 하나 · 한 줄로 더한다.
|
||||
* ========================================================================== */
|
||||
|
||||
import { renderDataTableHtml, type DataColumn } from "@ui/ui_template_data_table";
|
||||
|
||||
/** 후보 하나의 균형 종단 — 서버 `metrics.profile`. */
|
||||
export interface BalanceProfile {
|
||||
stationsM: number[];
|
||||
@@ -193,25 +191,26 @@ export function profileLegend(hasPlan: boolean, hasInitial: boolean): string {
|
||||
].join("")}</div>`;
|
||||
}
|
||||
|
||||
const CANDIDATE_COLUMNS: DataColumn[] = [
|
||||
{ key: "name", label: "후보" },
|
||||
{ key: "cut", label: "절토" },
|
||||
{ key: "fill", label: "성토" },
|
||||
{ key: "mass", label: "누가토량" },
|
||||
{ key: "grade", label: "최대 종단경사" },
|
||||
];
|
||||
const CANDIDATE_COLUMNS = ["후보", "절토", "성토", "누가토량", "최대 종단경사"];
|
||||
|
||||
/** 이 모달에서 셈한 후보들 — 갈래 이름 · 절 · 성 · 누가토량(±) · 최대 종단경사 표. 비면 빈 글. */
|
||||
const escapeHtml = (text: string): string =>
|
||||
text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
||||
|
||||
/** 이 모달에서 셈한 후보들 — 갈래 이름 · 절 · 성 · 누가토량(±) · 최대 종단경사 표. 비면 빈 글.
|
||||
* 꼴 = 부품 「표」 데이터표(`ui-table--data` · 553-2) — 이름 칸 왼쪽 · 수 칸 오른쪽. */
|
||||
export function candidatesTable(rows: Array<[string, BalanceProfile]>): string {
|
||||
if (!rows.length) return "";
|
||||
return renderDataTableHtml({
|
||||
columns: CANDIDATE_COLUMNS,
|
||||
rows: rows.map(([name, b]) => ({
|
||||
name,
|
||||
cut: m3(b.cutM3),
|
||||
fill: m3(b.fillM3),
|
||||
mass: signedM3(b.massEndM3),
|
||||
grade: pct(b.maxGradePct),
|
||||
})),
|
||||
const end = (i: number): string => (i ? ' class="is-end"' : "");
|
||||
const head = CANDIDATE_COLUMNS.map((label, i) => `<th scope="col"${end(i)}>${label}</th>`);
|
||||
const body = rows.map(([name, b]) => {
|
||||
const cells = [
|
||||
escapeHtml(name),
|
||||
m3(b.cutM3),
|
||||
m3(b.fillM3),
|
||||
signedM3(b.massEndM3),
|
||||
pct(b.maxGradePct),
|
||||
];
|
||||
return `<tr>${cells.map((cell, i) => `<td${end(i)}>${cell}</td>`).join("")}</tr>`;
|
||||
});
|
||||
return `<div class="ui-table-wrap"><table class="ui-table ui-table--data"><thead><tr>${head.join("")}</tr></thead><tbody>${body.join("")}</tbody></table></div>`;
|
||||
}
|
||||
|
||||
@@ -326,16 +326,11 @@
|
||||
accent-color: var(--color-primary);
|
||||
}
|
||||
|
||||
/* 값 칸 — 슬라이더 옆에서 숫자를 직접 넣는다. 합 100 을 못 맞추면 빨간 테두리. */
|
||||
.b05-routerec__num {
|
||||
/* 값 칸 = 부품 입력 단 32(553-2) — 슬라이더 옆에서 숫자를 직접 넣는다. 합 100 을 못 맞추면 빨간 테두리. */
|
||||
.b05-routerec__num.ui-input {
|
||||
width: 100%;
|
||||
min-width: 3.2em;
|
||||
padding: 2px 4px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-4, 4px);
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text-body);
|
||||
font-size: var(--text-body);
|
||||
padding-inline: 4px;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
appearance: textfield;
|
||||
@@ -401,15 +396,10 @@
|
||||
color: var(--color-text-body);
|
||||
}
|
||||
|
||||
.b05-routerec__criteria input,
|
||||
.b05-routerec__target input {
|
||||
/* 제약 칸 = 부품 입력 단 32(553-2) — 자리 · 오른쪽 맞춤만 */
|
||||
.b05-routerec__criteria input.ui-input,
|
||||
.b05-routerec__target input.ui-input {
|
||||
width: 100%;
|
||||
padding: 4px 8px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-4, 4px);
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text-body);
|
||||
font-size: var(--text-body);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
@@ -546,22 +536,11 @@
|
||||
}
|
||||
|
||||
/* 이 모달에서 셈한 후보 표 — 절 · 성 · 반입 · 최대 종단경사. */
|
||||
.b05-routerec__cands table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: var(--text-caption);
|
||||
/* 후보 표 = 부품 표 데이터표(553-2) — 수 칸 자리 맞춤 · 한 줄 */
|
||||
.b05-routerec__cands .ui-table {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.b05-routerec__cands th,
|
||||
.b05-routerec__cands td {
|
||||
padding: 2px var(--spacing-8);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
text-align: right;
|
||||
.b05-routerec__cands .ui-table td {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.b05-routerec__cands th[scope="row"],
|
||||
.b05-routerec__cands thead th:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@@ -122,6 +122,6 @@ def test_균형_종단은_캐시에_안_남는다() -> None:
|
||||
assert result["svg"].count("<path") == 2
|
||||
assert "<td>토공 최소</td>" in result["table"]
|
||||
assert (
|
||||
'<th scope="col" rowspan="1" title="누가토량">누가토량</th>' in result["table"]
|
||||
'<th scope="col" class="is-end">누가토량</th>' in result["table"] # 부품 표(553-2)
|
||||
and "반입" not in result["table"]
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user