feat(E03): 탐색 한계 고르기를 왼쪽 판 분할 고르기로 · 「이 결과 탐색 한계」 한 줄 · 바꾼 뒤 해석 전 표시 (PLAN 567-4)
This commit is contained in:
@@ -22,6 +22,7 @@ import {
|
||||
showToast,
|
||||
} from "@ui/ui_template_elements";
|
||||
import { t, type LocaleKey } from "@ui/ui_template_locale";
|
||||
import { createSegment } from "@ui/ui_template_segment";
|
||||
import { mountGroupStep } from "../A00_Common/group_workflow";
|
||||
import { buildMissingBanner } from "../E01_StabRegister/E01_StabRegister_UI_Missing";
|
||||
import { buildList } from "./E03_StabSection_UI_List";
|
||||
@@ -142,28 +143,56 @@ export function renderE03StabSection(root: HTMLElement): void {
|
||||
paintList();
|
||||
},
|
||||
});
|
||||
const reachField = createSelectField({
|
||||
label: t("E03_Reach"),
|
||||
type ReachPick = "model_end" | "2h" | "m";
|
||||
const reachSegment = createSegment({
|
||||
options: [
|
||||
{ value: "model_end", text: t("E03_Reach_model_end") },
|
||||
{ value: "2h", text: t("E03_Reach_2h") },
|
||||
{ value: "m", text: t("E03_Reach_m") },
|
||||
{ value: "model_end", label: t("E03_Reach_model_end") },
|
||||
{ value: "2h", label: t("E03_Reach_2h_Short"), title: t("E03_Reach_2h") },
|
||||
{ value: "m", label: t("E03_Reach_m_Short"), title: t("E03_Reach_m") },
|
||||
],
|
||||
compact: true,
|
||||
value: "model_end",
|
||||
size: 24,
|
||||
ariaLabel: t("E03_Reach"),
|
||||
onChange: () => paintReach(),
|
||||
});
|
||||
reachField.select.dataset.role = "reach";
|
||||
reachField.select.title = t("E03_Reach_Hint");
|
||||
const reachMeters = createInputField({ type: "number", min: 0.1, compact: true, unit: "m" });
|
||||
reachSegment.root.dataset.role = "reach";
|
||||
reachSegment.root.title = t("E03_Reach_Hint");
|
||||
const reachMeters = createInputField({
|
||||
type: "number",
|
||||
min: 0.1,
|
||||
compact: true,
|
||||
unit: "m",
|
||||
onInput: () => paintReach(),
|
||||
});
|
||||
reachMeters.input.dataset.role = "reach-m";
|
||||
reachMeters.input.title = t("E03_Reach_Hint");
|
||||
const reachLabelNode = muted(t("E03_Reach"));
|
||||
const reachNote = muted("", "reach-note");
|
||||
const reachLabel = (reach: string | number | undefined): string =>
|
||||
typeof reach === "number"
|
||||
? t("E03_Reach_m_Value").replace("{v}", String(reach))
|
||||
: t(reach === "2h" ? "E03_Reach_2h" : "E03_Reach_model_end");
|
||||
/** 고른 값(서버로 보낼 꼴) — 정한 m 이 비면 null */
|
||||
const reachPicked = (): string | number | null => {
|
||||
const pick = reachSegment.get() as ReachPick;
|
||||
if (pick !== "m") return pick;
|
||||
const meters = Number(reachMeters.input.value);
|
||||
return meters > 0 ? meters : null;
|
||||
};
|
||||
/** 정한 m 칸 보임 · 「이 결과」 한 줄 — 고른 값이 결과와 다르면 「해석 전」 */
|
||||
const paintReach = (): void => {
|
||||
reachMeters.root.hidden = reachField.select.value !== "m";
|
||||
reachMeters.root.hidden = reachSegment.get() !== "m";
|
||||
if (result?.status !== "ok") return void (reachNote.textContent = "");
|
||||
const used = result.search_reach ?? "model_end";
|
||||
const picked = reachPicked();
|
||||
reachNote.textContent =
|
||||
`${t("E03_Reach_Used")} ${reachLabel(used)}` +
|
||||
(picked !== null && picked !== used ? ` · ${t("E03_Reach_Pending")}` : "");
|
||||
};
|
||||
/** 서버 저장값을 칸에 맞춤 */
|
||||
const showReach = (reach: string | number | undefined): void => {
|
||||
const custom = typeof reach === "number";
|
||||
reachField.select.value = custom ? "m" : reach === "2h" ? "2h" : "model_end";
|
||||
reachSegment.set(custom ? "m" : reach === "2h" ? "2h" : "model_end");
|
||||
if (custom) reachMeters.input.value = String(reach);
|
||||
paintReach();
|
||||
};
|
||||
@@ -190,7 +219,17 @@ export function renderE03StabSection(root: HTMLElement): void {
|
||||
controls.append(condField.root, sortField.root);
|
||||
const actions = el("div", { className: "ui-sidebar-actions" });
|
||||
actions.append(view3dButton, analyzeButton);
|
||||
panel.append(controls, reachField.root, reachMeters.root, ngBox, status, listHost, actions);
|
||||
panel.append(
|
||||
controls,
|
||||
reachLabelNode,
|
||||
reachSegment.root,
|
||||
reachMeters.root,
|
||||
reachNote,
|
||||
ngBox,
|
||||
status,
|
||||
listHost,
|
||||
actions,
|
||||
);
|
||||
|
||||
// ---- 본문 ----
|
||||
const missingHost = el("div");
|
||||
@@ -239,7 +278,8 @@ export function renderE03StabSection(root: HTMLElement): void {
|
||||
if (result && !result.editable) lines.push(t("E03_ReadOnly"));
|
||||
status.textContent = lines.join("\n");
|
||||
analyzeButton.disabled = !result?.editable;
|
||||
reachField.select.disabled = reachMeters.input.disabled = !result?.editable;
|
||||
reachMeters.input.disabled = !result?.editable;
|
||||
reachSegment.root.querySelectorAll("button").forEach((b) => (b.disabled = !result?.editable));
|
||||
view3dButton.disabled = result?.status !== "ok";
|
||||
};
|
||||
|
||||
@@ -503,9 +543,8 @@ export function renderE03StabSection(root: HTMLElement): void {
|
||||
}
|
||||
|
||||
async function analyze(): Promise<void> {
|
||||
const pick = reachField.select.value;
|
||||
const meters = Number(reachMeters.input.value);
|
||||
if (pick === "m" && !(meters > 0)) {
|
||||
const reach = reachPicked();
|
||||
if (reach === null) {
|
||||
reachMeters.setError(t("E03_Reach_Invalid"));
|
||||
return;
|
||||
}
|
||||
@@ -513,7 +552,7 @@ export function renderE03StabSection(root: HTMLElement): void {
|
||||
try {
|
||||
const response = await api<{ status: string }>(`${base}/analyze2d`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ search_reach: pick === "m" ? meters : pick }),
|
||||
body: JSON.stringify({ search_reach: reach }),
|
||||
});
|
||||
if (response.status === "fresh") {
|
||||
showToast(t("E03_Fresh"), "info");
|
||||
|
||||
@@ -76,6 +76,11 @@ export const ui_locales_e03 = {
|
||||
E03_Reach_model_end: ["모형 끝", "Model edge"],
|
||||
E03_Reach_2h: ["비탈 끝 + 2H", "Slope end + 2H"],
|
||||
E03_Reach_m: ["비탈 끝 + 정한 m", "Slope end + set m"],
|
||||
E03_Reach_2h_Short: ["+ 2H", "+ 2H"],
|
||||
E03_Reach_m_Short: ["+ 정한 m", "+ set m"],
|
||||
E03_Reach_m_Value: ["비탈 끝 + {v} m", "Slope end + {v} m"],
|
||||
E03_Reach_Used: ["이 결과 탐색 한계 —", "This result's reach —"],
|
||||
E03_Reach_Pending: ["지금 고른 값은 해석 전", "current pick not analyzed yet"],
|
||||
E03_Reach_Hint: [
|
||||
"[해석]을 누르면 이 값으로 셈 · 저장됨",
|
||||
"Applied and saved when you press Analyze",
|
||||
|
||||
Reference in New Issue
Block a user