feat(m02-cf): 시작 화면 내 로직 · 견본 목록을 cfList 로(속이 오기 전엔 빈 목록)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016PSXsvyDxjNmufteN5bqmt
This commit is contained in:
2026-10-01 16:03:23 +09:00
co-authored by Claude Opus 5.5
parent 87dcc4b288
commit e837e5965e
2 changed files with 66 additions and 2 deletions
@@ -153,3 +153,39 @@
grid-template-columns: minmax(0, 1fr);
}
}
.m02-cf__list {
display: flex;
flex-direction: column;
gap: var(--spacing-4);
}
.m02-cf__item {
display: flex;
align-items: center;
gap: var(--spacing-8);
width: 100%;
padding: var(--spacing-8) var(--spacing-12);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
background: var(--color-surface);
color: var(--color-text);
font: inherit;
text-align: left;
cursor: pointer;
}
.m02-cf__item:hover {
border-color: var(--color-accent);
}
.m02-cf__item-name {
flex: 1;
min-width: 0;
}
.m02-cf__item-unit {
color: var(--color-text-muted);
font-size: var(--text-body-sm);
white-space: nowrap;
}
+30 -2
View File
@@ -18,6 +18,7 @@ import {
showToast,
} from "@ui/ui_template_elements";
import { fetchLogics } from "../../M01_MasterData/M01_MasterData_UI_Logic_Api";
import type { CfListItem } from "./M02_CF_Api";
import type { CfLogic } from "./M02_CF_Model";
import "./M02_CF_Entry.css";
@@ -62,6 +63,8 @@ const muted = (text: string): HTMLElement => el("p", { className: "m02-cf__muted
/* ponytail: Model(sub7) · Api(sub4) · Sample(sub6) 속이 「준비 중」 인 동안만 대신함 — 채워지면 catch 를 지움 */
const blankLogic = (name: string, unit: string): Promise<CfLogic | null> =>
import("./M02_CF_Model").then((m) => m.newLogic(name, unit)).catch(() => null);
const loadList = (): Promise<CfListItem[]> =>
import("./M02_CF_Api").then((m) => m.cfList()).catch(() => []);
/** 결과 단위 후보 — 품셈 로직에 다섯 번 넘게 쓰인 「원/…」 차례(설명 붙은 드문 단위는 뺌) */
async function unitChoices(): Promise<string[]> {
@@ -133,9 +136,34 @@ function openCostFlow(): void {
/* ---------- 시작 화면 ---------- */
const listRow = (item: CfListItem): HTMLElement => {
const row = el("button", {
className: "m02-cf__item",
attrs: { type: "button", title: item.saved },
children: [
el("span", { className: "m02-cf__item-name", text: item.name }),
el("span", { className: "m02-cf__item-unit", text: item.resultUnit }),
],
});
row.addEventListener("click", () => showToast(te("NotYet"), "info"));
return row;
};
const showStart = (): void => {
paper = null;
strip.replaceChildren();
const mineHost = el("div", { className: "m02-cf__list", children: [muted(te("Loading"))] });
const sampleHost = el("div", { className: "m02-cf__list", children: [muted(te("Loading"))] });
void loadList().then((all) => {
const mine = all.filter((x) => !x.sample);
const samples = all.filter((x) => x.sample);
mineHost.replaceChildren(
...(mine.length ? mine.map(listRow) : [muted(te("Start_MineNone"))]),
);
sampleHost.replaceChildren(
...(samples.length ? samples.map(listRow) : [muted(te("Start_MineNone"))]),
);
});
body.replaceChildren(
el("div", {
className: "m02-cf__start",
@@ -145,12 +173,12 @@ function openCostFlow(): void {
children: [
bigButton(te("Start_New"), () => void openNew()),
el("h3", { text: te("Start_Mine") }),
muted(te("Start_MineNone")),
mineHost,
],
}),
el("section", {
className: "m02-cf__start-col",
children: [el("h3", { text: te("Start_Samples") }), muted(te("NotYet"))],
children: [el("h3", { text: te("Start_Samples") }), sampleHost],
}),
],
}),