refactor(M01): 표 · 모달 · 띠 알림 · 배지 · 알약 · 보조 글 · 빈 상태를 부품으로 (PLAN 553-5)
- 표 둘 = 표 부품(m01-master__grid = 일반표 · m01-logic__grid = 데이터표) · 페이지 CSS 는 폭 · 머리 고정 · 칸 상태만 - 손 모달 다섯(조달 찾기 · 요소 고르기 · 표 바꾸기 · 복사 시트 · 표 고르기) = 모달 부품 openModal - 알림 띠 · 막힘 까닭 = 띠 알림 · 태그 = 배지 · 알약 · × · 삭제 · 로직 키 = 단추 부품 · muted 세 벌 = 보조 글 · 빈 줄 = 빈 상태 - M02 가 빌린 M01 클래스(표 · muted · 고르기 창)도 같은 부품으로 · 죽은 CSS 걷음 · 지킴 시험 test_553_5_m01_m02 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -35,6 +35,7 @@ import { fragmentRow, type Fragment } from "./M01_MasterData_UI_LogicLab_Pill";
|
||||
import { tl, type LabTextKey } from "./M01_MasterData_UI_LogicLab_Text";
|
||||
import "./M01_MasterData_UI_LogicLab_Style.css";
|
||||
import "./M01_MasterData_UI_LogicLab_Pill.css";
|
||||
import { createBadge } from "@ui/ui_template_badge";
|
||||
|
||||
/** 서버 조각(`/text` 줄의 `조각`) → 수량 칸 조각 — 요소·표·로직은 알약(글 = 조각 글) · 나머지는 글자 */
|
||||
function toFragments(pieces: TextPiece[], ctx: DetailContext): Fragment[] {
|
||||
@@ -131,7 +132,7 @@ const section = (title: string, body: HTMLElement[], hint = ""): HTMLElement =>
|
||||
className: "m01-logic__section-head",
|
||||
children: [
|
||||
el("h3", { text: title }),
|
||||
...(hint ? [el("span", { className: "m01-logic__muted", text: hint })] : []),
|
||||
...(hint ? [el("span", { className: "ui-text ui-text--muted", text: hint })] : []),
|
||||
],
|
||||
}),
|
||||
...body,
|
||||
@@ -151,14 +152,14 @@ function infoBox(ctx: DetailContext): HTMLElement {
|
||||
});
|
||||
return el("label", {
|
||||
className: "m01lab__cell",
|
||||
children: [el("span", { className: "m01-logic__muted", text: label }), box],
|
||||
children: [el("span", { className: "ui-text ui-text--muted", text: label }), box],
|
||||
});
|
||||
};
|
||||
const cell = (label: string, value: string): HTMLElement =>
|
||||
el("div", {
|
||||
className: "m01lab__cell",
|
||||
children: [
|
||||
el("span", { className: "m01-logic__muted", text: label }),
|
||||
el("span", { className: "ui-text ui-text--muted", text: label }),
|
||||
el("span", { text: value || "—" }),
|
||||
],
|
||||
});
|
||||
@@ -172,7 +173,7 @@ function infoBox(ctx: DetailContext): HTMLElement {
|
||||
const reasons = ctx.reasons.length
|
||||
? [
|
||||
el("div", {
|
||||
className: "m01-logic__reasons",
|
||||
className: "ui-banner ui-banner--danger m01-logic__reasons",
|
||||
children: [
|
||||
el("strong", { text: tx("Head_Blocked") }),
|
||||
...ctx.reasons.map((r) => el("div", { text: safeReason(r) })),
|
||||
@@ -182,7 +183,7 @@ function infoBox(ctx: DetailContext): HTMLElement {
|
||||
: [];
|
||||
return section(tl("Info_Title"), [
|
||||
el("p", {
|
||||
className: "m01-logic__muted",
|
||||
className: "ui-text ui-text--muted",
|
||||
text: tl(own ? "Info_Own" : ctx.admin ? "Info_Base" : "Info_ReadOnly"),
|
||||
}),
|
||||
...reasons,
|
||||
@@ -198,7 +199,10 @@ function infoBox(ctx: DetailContext): HTMLElement {
|
||||
cell(tx("Head_Owner"), row.소유 ?? ""),
|
||||
el("label", {
|
||||
className: "m01lab__cell m01lab__cell--wide",
|
||||
children: [el("span", { className: "m01-logic__muted", text: tx("Head_Note") }), note],
|
||||
children: [
|
||||
el("span", { className: "ui-text ui-text--muted", text: tx("Head_Note") }),
|
||||
note,
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
@@ -342,27 +346,15 @@ function lineRow(e: Entry): HTMLElement {
|
||||
el("td", {
|
||||
children: [
|
||||
el("div", { text: e.name }),
|
||||
...(e.share
|
||||
? [el("div", { className: "m01-logic__tag", text: `${e.share} ${tl("Share")}` })]
|
||||
: []),
|
||||
...(e.spec ? [el("div", { className: "m01-logic__muted", text: e.spec })] : []),
|
||||
...(e.warn
|
||||
? [
|
||||
el("div", {
|
||||
className: "m01-logic__tag m01lab__warn",
|
||||
text: `${tx("Calc_UnitWarn")} · ${e.warn}`,
|
||||
}),
|
||||
]
|
||||
: []),
|
||||
...(e.share ? [createBadge(`${e.share} ${tl("Share")}`, "accent")] : []),
|
||||
...(e.spec ? [el("div", { className: "ui-text ui-text--muted", text: e.spec })] : []),
|
||||
...(e.warn ? [createBadge(`${tx("Calc_UnitWarn")} · ${e.warn}`, "warning")] : []),
|
||||
],
|
||||
}),
|
||||
cellOf(e.unit),
|
||||
el("td", {
|
||||
className: "m01lab__qty-cell",
|
||||
children: [
|
||||
el("span", { className: "m01-logic__tag", text: e.qtyTag }),
|
||||
fragmentRow(e.qtyFrag),
|
||||
],
|
||||
children: [createBadge(e.qtyTag, "accent"), fragmentRow(e.qtyFrag)],
|
||||
}),
|
||||
cellOf(e.price, "m01-logic__money"),
|
||||
cellOf(e.amount === null ? "" : formatMoney(e.amount), "m01-logic__money"),
|
||||
@@ -379,7 +371,7 @@ function groupTable(group: Group, mine: Entry[], calculated: boolean): HTMLEleme
|
||||
children: [
|
||||
el("td", {
|
||||
attrs: { colspan: "5" },
|
||||
className: "m01-logic__muted",
|
||||
className: "ui-text ui-text--muted",
|
||||
text: tl("Empty_Group"),
|
||||
}),
|
||||
],
|
||||
@@ -405,7 +397,7 @@ function groupTable(group: Group, mine: Entry[], calculated: boolean): HTMLEleme
|
||||
className: "m01-logic__scroll",
|
||||
children: [
|
||||
el("table", {
|
||||
className: "m01-logic__grid m01lab__ho",
|
||||
className: "ui-table ui-table--data m01-logic__grid m01lab__ho",
|
||||
children: [
|
||||
el("thead", {
|
||||
children: [el("tr", { children: headers.map((h) => el("th", { text: h })) })],
|
||||
@@ -447,7 +439,7 @@ function hoBox(ctx: DetailContext): HTMLElement {
|
||||
const money = !("결과" in ctx.row) && (ctx.row.결과단위 ?? "").startsWith("원");
|
||||
if (!money) {
|
||||
return section(tl("Ho_Title"), [
|
||||
el("p", { className: "m01-logic__muted", text: tl("Not_Money") }),
|
||||
el("p", { className: "ui-text ui-text--muted", text: tl("Not_Money") }),
|
||||
el("pre", { className: "m01lab__expr", text: ctx.row.결과?.식 ?? "" }),
|
||||
]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user