- 한눈 표(M02_SO_Def_Table): 군 · 종류 ▲▼ · 이름 · 목록 · 자리꼴 · 정본(고정) · 횡단도 · 카드 이름 · 형상(+ 벽 기본 형태 · 물빼기) · 알약 색 · 3D · 검사 · 처음 값 = 흐림 「기본」 · 바꿈 = 진함 · [처음 값으로] - 종류별: 반영 칸 + 명세 이름 나무 줄마다 보임(컨테이너 = 그 안 칸) · 못 숨김 · 미리보기 숨김 따름 · 「안 씀」 = 목록 B06 만 - 부품 탭(M02_SO_Def_Parts): 부품 · 읽는 칸 · 자리꼴 · 정본 · 쓰는 종류 · 켬/끔(정의 부품 = 끈 것만) - 편집 손질(M02_SO_Def_Reflect): 처음 값이면 반영에서 지움 · [저장] 때 enabled = 목록 both 일 때만 참 - 검사 짝 M02_SO_Def_Check.ts ↔ M02_SO_Check.py(글까지 같음): 반영 · 부품 꼴 · 형상 none → 횡단도 none · 부품 자리꼴 · 정본 · 기본값 없는 읽는 칸 새로 숨김 금지(앞 판 숨김 그대로) · 종류 지우기 · 자리꼴 · 정본 · 군 글자 · 선택지 값 고정 · 서버 check(doc, 지금 판) · 앞 판 없으면 꼴만 - 명세 폼: 쓰는 옵션 키가 모두 숨긴 칸 · 상자는 안 그림(값 그대로) · B05 · B06 시설 · 구조물 명세 폼이 정의 「표시」를 따름 - 판 알림: GET 구조물 목록에 definition_version · structures.json 판 ≠ 지금 판이면 「구조물 정의가 판 N 으로 바뀜 — 저장하면 반영」 한 번 - 시험: test_322_2_check_mirror(거울 · 규칙 · 반영 손질 · 서버 저장 · 422) · 판 알림 · 옛 정의 화면 시험 = 선택지 값 대신 이름 표 · 못 숨김 아닌 칸 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ji4nuyLVHcxrXWHTdb5nRD
74 lines
3.0 KiB
TypeScript
74 lines
3.0 KiB
TypeScript
/* =============================================================================
|
|
* M02_SO_Def_Parts.ts
|
|
* 구조물 정의 「부품」 탭(PLAN 322-2) — 코드가 그리는 방법(부품 상자 `common_util_structure_parts.json`).
|
|
* 갈래마다 부품 · 이름 · 읽는 칸 · 맞는 자리꼴 · 정본 · 쓰는 종류 · 켬/끔(정의 `부품` = 끈 것만).
|
|
* 끈 부품을 쓰는 종류는 그 갈래가 없음(카드 이름은 종류 이름)으로 — 표 줄(`resolveCatalog`)이 따름.
|
|
* ========================================================================== */
|
|
|
|
import { el } from "@ui/ui_template_elements";
|
|
import type { StructDef } from "./M02_SO_Def_Model";
|
|
import { PART_BOX, partsOff, setPartOn, usersOf } from "./M02_SO_Def_Reflect";
|
|
import { checkBox, head } from "./M02_SO_Def_Ui";
|
|
import { to } from "./M02_SO_Text";
|
|
|
|
type Branch = keyof typeof PART_BOX;
|
|
|
|
export function buildParts(opt: {
|
|
def: StructDef;
|
|
edit: boolean;
|
|
changed: () => void;
|
|
}): HTMLElement {
|
|
const { def, edit, changed } = opt;
|
|
const off = partsOff(def);
|
|
const blocks = (Object.keys(PART_BOX) as Branch[]).flatMap((branch) => [
|
|
...head(branch),
|
|
el("table", {
|
|
className: "m02-sod__table",
|
|
attrs: { "data-sod-parts": branch },
|
|
children: [
|
|
el("thead", {
|
|
children: [
|
|
el("tr", {
|
|
children: ["", "ColName", "PartRead", "PartFits", "PartUsers", "PartOn"].map((key) =>
|
|
el("th", { text: key ? to(key as "ColName") : "" }),
|
|
),
|
|
}),
|
|
],
|
|
}),
|
|
el("tbody", {
|
|
children: Object.entries(PART_BOX[branch]).map(([id, part]) => {
|
|
const key = `${branch}.${id}`;
|
|
// 끈 부품을 쓰던 종류도 보이게 — 끈 동안은 표가 none 으로 풀므로 켠 꼴로 셈
|
|
const users = usersOf({ ...def, 부품: {} } as StructDef, branch, id);
|
|
return el("tr", {
|
|
attrs: { "data-sod-part": key },
|
|
className: off[key] === false ? "is-off" : "",
|
|
children: [
|
|
el("td", { children: [el("small", { className: "m02-opts__key", text: id })] }),
|
|
el("td", { text: part.이름 }),
|
|
el("td", { text: part["읽는 칸"].join(" · ") || "—" }),
|
|
el("td", { text: `${part.자리꼴.join(" · ")} / ${part.정본.join(" · ")}` }),
|
|
el("td", { text: users.map((row) => row.name).join(" · ") || "—" }),
|
|
el("td", {
|
|
children: [
|
|
checkBox(
|
|
to("PartOn"),
|
|
off[key] !== false,
|
|
(on) => (setPartOn(def, key, on), changed()),
|
|
{ edit, attr: "data-sod-part-on" },
|
|
),
|
|
],
|
|
}),
|
|
],
|
|
});
|
|
}),
|
|
}),
|
|
],
|
|
}),
|
|
]);
|
|
return el("div", {
|
|
className: "m02-sod__tablewrap",
|
|
children: [el("p", { className: "m02-side__empty", text: to("PartsNote") }), ...blocks],
|
|
});
|
|
}
|