refactor(D01·D02): 날 입력 · 안내 글을 부품으로 — 측점 표기 · 연도 지점 칸 · 안내 줄 (PLAN 553-4)
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
||||
} from "@ui/ui_template_elements";
|
||||
import { createGeneralLayout } from "@ui/ui_template_general_layout";
|
||||
import { createHelpButton } from "@ui/ui_template_help";
|
||||
import { createText } from "@ui/ui_template_text";
|
||||
import { t } from "@ui/ui_template_locale";
|
||||
import { stationLabel } from "../common_util/common_util_station";
|
||||
import { createGroupProject } from "../A00_Common/group_workflow";
|
||||
@@ -70,8 +71,7 @@ export function renderD01PlanRegister(root: HTMLElement): void {
|
||||
const endM = createInputField({ label: t("DE_Reg_EndM"), type: "number", min: 0 });
|
||||
// 누가거리 칸 옆 즉시 측점 표기(저장값 · 서버 검사는 m 그대로)
|
||||
for (const field of [startM, endM]) {
|
||||
const shown = document.createElement("span");
|
||||
shown.style.cssText = "font-size:12px;color:var(--color-text-muted)";
|
||||
const shown = createText("", "muted");
|
||||
shown.dataset.station = "";
|
||||
field.root.insertBefore(shown, field.root.lastElementChild);
|
||||
field.input.addEventListener("input", () => {
|
||||
|
||||
@@ -11,12 +11,14 @@ import "./D02_PlanBase_UI_Style.css";
|
||||
import { API_BASE_URL, CURRENT_PROJECT_ID_KEY, ROUTES } from "@config/config_frontend";
|
||||
import {
|
||||
createButton,
|
||||
createInputField,
|
||||
el,
|
||||
hideLoadingOverlay,
|
||||
showLoadingOverlay,
|
||||
showToast,
|
||||
} from "@ui/ui_template_elements";
|
||||
import { createPanelCard } from "@ui/ui_template_collapsible";
|
||||
import { createText } from "@ui/ui_template_text";
|
||||
import { editMap, type MapPin } from "@ui/ui_template_kakao_map";
|
||||
import { t } from "@ui/ui_template_locale";
|
||||
import { mountGroupStep } from "../A00_Common/group_workflow";
|
||||
@@ -66,9 +68,11 @@ export async function renderD02PlanBase(root: HTMLElement): Promise<void> {
|
||||
const projectId = localStorage.getItem(CURRENT_PROJECT_ID_KEY) ?? "";
|
||||
const mapHost = el("div", { className: "d02-map" });
|
||||
const table = el("div", { className: "d02-points" });
|
||||
const info = el("p", { className: "d02-info" });
|
||||
const info = createText("", "muted");
|
||||
info.classList.add("d02-info");
|
||||
const card = createPanelCard(t("D02_Points_Title"), false);
|
||||
const pointsHint = el("p", { className: "d02-info", text: t("D02_Points_Hint") });
|
||||
const pointsHint = createText(t("D02_Points_Hint"), "muted");
|
||||
pointsHint.classList.add("d02-info");
|
||||
card.append(pointsHint, table, info);
|
||||
const save = createButton({
|
||||
label: t("D02_Save"),
|
||||
@@ -139,12 +143,11 @@ export async function renderD02PlanBase(root: HTMLElement): Promise<void> {
|
||||
|
||||
function drawTable(): void {
|
||||
const rows = points.map((p, i) => {
|
||||
const lon = el("input", { className: "d02-points__input" }) as HTMLInputElement;
|
||||
const lat = el("input", { className: "d02-points__input" }) as HTMLInputElement;
|
||||
lon.type = lat.type = "number";
|
||||
const lon = createInputField({ type: "number", placeholder: t("D02_Lon"), size: 24 }).input;
|
||||
const lat = createInputField({ type: "number", placeholder: t("D02_Lat"), size: 24 }).input;
|
||||
lon.classList.add("d02-points__input");
|
||||
lat.classList.add("d02-points__input");
|
||||
lon.step = lat.step = "any";
|
||||
lon.placeholder = t("D02_Lon");
|
||||
lat.placeholder = t("D02_Lat");
|
||||
lon.value = p ? String(p.lon) : "";
|
||||
lat.value = p ? String(p.lat) : "";
|
||||
lon.disabled = lat.disabled = !editable;
|
||||
@@ -154,8 +157,11 @@ export async function renderD02PlanBase(root: HTMLElement): Promise<void> {
|
||||
const typed = (): void => {
|
||||
const at = { lon: Number.parseFloat(lon.value), lat: Number.parseFloat(lat.value) };
|
||||
const ok = at.lon >= 120 && at.lon <= 135 && at.lat >= 30 && at.lat <= 45;
|
||||
lon.classList.toggle("is-invalid", !ok);
|
||||
lat.classList.toggle("is-invalid", !ok);
|
||||
for (const box of [lon, lat]) {
|
||||
box.classList.toggle("is-error", !ok);
|
||||
if (ok) box.removeAttribute("aria-invalid");
|
||||
else box.setAttribute("aria-invalid", "true");
|
||||
}
|
||||
if (ok) place(i, at);
|
||||
};
|
||||
lon.addEventListener("change", typed);
|
||||
@@ -254,8 +260,6 @@ export async function renderD02PlanBase(root: HTMLElement): Promise<void> {
|
||||
active = firstEmpty();
|
||||
paint();
|
||||
} catch (error) {
|
||||
table.replaceChildren(
|
||||
el("p", { className: "d02-info", text: error instanceof Error ? error.message : "" }),
|
||||
);
|
||||
table.replaceChildren(createText(error instanceof Error ? error.message : "", "muted"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,17 +35,5 @@
|
||||
}
|
||||
|
||||
.d02-points__input {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
font-size: var(--text-caption);
|
||||
}
|
||||
|
||||
.d02-points__input.is-invalid {
|
||||
outline: 1px solid var(--color-danger, #d92d20);
|
||||
}
|
||||
|
||||
.d02-info {
|
||||
margin: 0;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: var(--text-caption);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
"""553-4 예정노선(D01~D04) · 안정성평가(E01~E07) 부품 옮김 지킴 시험 — 서버 · 화면 없이 소스만 본다.
|
||||
옮긴 페이지는 날 `<input>` · `<progress>` · 날 색 · 안 쓰는 변종 CSS 가 다시 생기면 안 됨."""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def _src(path: str) -> str:
|
||||
return (ROOT / path).read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def _no_hex(path: str) -> None:
|
||||
css = re.sub(r"/\*.*?\*/", "", _src(path), flags=re.S)
|
||||
assert not re.search(r"#[0-9a-fA-F]{3,8}\b", css), f"{path}: 날 색"
|
||||
|
||||
|
||||
def test_d01_station_label_is_text_part():
|
||||
ts = _src("D01_PlanRegister/D01_PlanRegister_UI_Page.ts")
|
||||
assert "style.cssText" not in ts
|
||||
assert 'createText("", "muted")' in ts
|
||||
assert 'dataset.station = ""' in ts # 시험 · 촬영이 잡음
|
||||
|
||||
|
||||
def test_d02_parts():
|
||||
ts = _src("D02_PlanBase/D02_PlanBase_UI_Page.ts")
|
||||
css = _src("D02_PlanBase/D02_PlanBase_UI_Style.css")
|
||||
assert 'el("input"' not in ts
|
||||
assert 'createInputField({ type: "number"' in ts
|
||||
assert 'classList.add("d02-info")' in ts # 촬영 장면이 `p.d02-info` 로 잡음
|
||||
for dead in (".d02-info", "is-invalid", "font-size: var(--text-caption);\n}\n\n.d02-info"):
|
||||
assert dead not in css
|
||||
assert "data-axis" in ts or "dataset.axis" in ts
|
||||
Reference in New Issue
Block a user