refactor(M02): 띠 알림 · 빈 상태 · 보조 글 · 배지 · 탭 · 표 · 목록 줄 · 도구줄 · 체크를 부품으로 (PLAN 553-5)

- DataFlow: 표 넷 = 데이터표 · 함수 판 알림 · 선/알약 경고 · 끊긴 곳 = 띠 알림 · 알약 · 칸 종류 = 배지 · 고르는 줄 = 목록 줄 · 입력 넷 = 입력 · 도구줄 여섯 · 날 색 → 공통 값
- 구조물 옵션 · 구조물 · 도면 · 면적 · 품목 고르기: 판 띠 = 띠 알림 · 한눈/종류별/부품 = 탭 · 표 둘 = 데이터표 · 체크 둘 = 체크 · 카드 · 번호 = 카드 · 배지 · 도면 도구줄
- 일위대가 · 호표 · 실무자료 · 본 화면 · 서고: 알림 = 띠 알림 · 빈 상태 · 보조 글 · 도구줄 여섯 · 옛 보라 별칭 0
- M01 로직 입력칸 = 입력 부품(작은 칸) · 일위대가 상세 줄 수 고정 시험 693 · 지킴 시험 M02 몫 더함

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 23:44:19 +09:00
co-authored by Claude Opus 5.5
parent 022eff69f5
commit 09134bab84
86 changed files with 583 additions and 705 deletions
+28 -16
View File
@@ -38,6 +38,9 @@ import { checkBox, pickBox, textBox } from "./M02_SO_Def_Ui";
import { addFromTemplate, templates } from "./M02_SO_Def_Add";
import { buildGroupBlock } from "./M02_SO_Groups";
import { to } from "./M02_SO_Text";
import { createText } from "@ui/ui_template_text";
import { createEmpty } from "@ui/ui_template_empty";
import { createTabs } from "@ui/ui_template_tabs";
/** 옛 편집기(옵션 · 배치 · 그룹 · 규칙 · 기준 측점) — 모든 종류에서 숨김(52-12 · 정의 화면 = 이름만) */
const OLD_EDITOR = false;
@@ -93,7 +96,11 @@ function drawDef(first: StructDef, opt: DefScreenOptions): void {
const canEdit = (): boolean => opt.isAdmin && !past;
const kindList = el("div", { className: "m02-opts__kinds", attrs: { "data-sod-kinds": "" } });
const detail = el("div", { className: "m02-opts__list", attrs: { "data-sod-detail": "" } });
const banner = el("div", { className: "m02-sod__banner", attrs: { "data-sod-banner": "" } });
// 판 띠 = 띠 알림 부품 꼴(정보 · 지난 판 = 경고)
const banner = el("div", {
className: "ui-banner ui-banner--info m02-sod__banner",
attrs: { "data-sod-banner": "" },
});
const issues = el("div", { className: "m02-sod__issues", attrs: { "data-sod-issues": "" } });
const historyBox = el("div", {
className: "m02-sod__history",
@@ -161,8 +168,8 @@ function drawDef(first: StructDef, opt: DefScreenOptions): void {
const off = t.enabled === false;
const groups = d.그룹[t.type_id]?.length ?? 0;
const b = el("button", {
className: `m02-opts__kind${t.type_id === current ? " is-active" : ""}${off ? " is-off" : ""}`,
attrs: { type: "button", "data-sod-kind": t.type_id },
className: `m02-opts__kind ui-list-row ui-sidebar-row${t.type_id === current ? " is-active" : ""}${off ? " is-off" : ""}`,
attrs: { type: "button", "data-sod-kind": t.type_id, "data-size": "32" },
children: [
el("span", { text: t.name }),
...(groups ? [createTag(to("GroupTag", String(groups)), "accent")] : []),
@@ -204,7 +211,7 @@ function drawDef(first: StructDef, opt: DefScreenOptions): void {
const d = shown();
const type = d.types.find((t) => t.type_id === current);
if (!type) {
detail.replaceChildren(el("p", { className: "m02-side__empty", text: to("Pick") }));
detail.replaceChildren(createEmpty({ text: to("Pick"), small: true }));
return;
}
const edit = canEdit();
@@ -220,7 +227,7 @@ function drawDef(first: StructDef, opt: DefScreenOptions): void {
attr: "data-sod-kind-name",
cls: "m02-sod__name",
}),
el("small", { className: "m02-opts__key", text: type.type_id }),
el("small", { className: "ui-text ui-text--muted m02-opts__key", text: type.type_id }),
// 안 씀 = 목록 B06 만(enabled 는 목록 짝 · 322-2) · 숨김(hidden)은 한눈 표 목록 칸에서
checkBox(
to("Unused"),
@@ -269,14 +276,17 @@ function drawDef(first: StructDef, opt: DefScreenOptions): void {
["kinds", to("TabKinds")],
["parts", to("TabParts")],
];
tabBar.replaceChildren(
...pairs.map(([key, label]) => {
const b = createButton({ label, variant: key === tab ? "filled" : "ghost", size: "sm" });
b.setAttribute("data-sod-tab", key);
b.addEventListener("click", () => ((tab = key), paint()));
return b;
}),
);
// 탭 부품(보조 탭) — 칸마다 data-sod-tab 그대로
const tabs = createTabs({
kind: "pill",
tabs: pairs.map(([key, label]) => ({ key, label })),
value: tab,
onChange: (key) => ((tab = key as Tab), paint()),
});
tabs.root.querySelectorAll<HTMLElement>("[data-tab]").forEach((b) => {
b.setAttribute("data-sod-tab", b.dataset.tab ?? "");
});
tabBar.replaceChildren(tabs.root);
const edit = canEdit();
if (tab === "table")
body.replaceChildren(buildTable({ def: shown(), edit, changed, issues: allProblems() }));
@@ -297,8 +307,10 @@ function drawDef(first: StructDef, opt: DefScreenOptions): void {
]),
);
banner.classList.toggle("is-past", !!past);
banner.classList.toggle("ui-banner--warning", !!past);
banner.classList.toggle("ui-banner--info", !past);
const list = allProblems();
issues.replaceChildren(...list.map((t) => el("p", { className: "m02-sod__bad", text: t })));
issues.replaceChildren(...list.map((t) => createText(t, "error")));
save.disabled = !opt.isAdmin || !!past || !dirty || list.length > 0;
};
@@ -366,7 +378,7 @@ function drawDef(first: StructDef, opt: DefScreenOptions): void {
});
return b;
})
: [el("p", { className: "m02-side__empty", text: to("PastNone") })]),
: [createEmpty({ text: to("PastNone"), small: true })]),
);
};
const history = createButton({ label: to("PastList"), variant: "ghost" });
@@ -387,7 +399,7 @@ function drawDef(first: StructDef, opt: DefScreenOptions): void {
const node = el("div", {
className: "m02-opts m02-sod",
children: [
el("p", { className: "m02-side__empty", text: to("DefNote") }),
createText(to("DefNote")),
banner,
tabBar,
body,