From 5ef189ca4517da5c2228e109d035162c2fe931b6 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Thu, 1 Oct 2026 20:33:13 +0900 Subject: [PATCH] =?UTF-8?q?fix(M02-=ED=9D=90=EB=A6=84=EB=8F=84):=20?= =?UTF-8?q?=EC=95=8C=EC=95=BD=20=ED=8C=90=20=EC=88=AB=EC=9E=90=EC=97=90=20?= =?UTF-8?q?=EC=B2=9C=20=EB=8B=A8=EC=9C=84=20=EC=89=BC=ED=91=9C=20=C2=B7=20?= =?UTF-8?q?=EC=98=A8=20=EA=B8=B8=20=EC=A4=84=EC=97=90=20=EC=84=A0=20?= =?UTF-8?q?=EA=B7=9C=EC=B9=99=20=EA=B8=80(=EB=B3=B4=EB=82=B8=20=EC=95=8C?= =?UTF-8?q?=EC=95=BD=20=E2=86=92=20(=EA=B7=9C=EC=B9=99)=20=E2=86=92=20?= =?UTF-8?q?=EB=B0=9B=EB=8A=94=20=EC=95=8C=EC=95=BD)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01D2nUMUMTsqm93PbQtipo6c --- M02_MasterTemplete/DataFlow/M02_DF_Detail.ts | 6 +++- .../DataFlow/M02_DF_LinkPanel.ts | 9 +++-- .../DataFlow/M02_DF_PillPanel.ts | 34 ++++++++++++------- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/M02_MasterTemplete/DataFlow/M02_DF_Detail.ts b/M02_MasterTemplete/DataFlow/M02_DF_Detail.ts index 30b1312f8..2f4cf9fc2 100644 --- a/M02_MasterTemplete/DataFlow/M02_DF_Detail.ts +++ b/M02_MasterTemplete/DataFlow/M02_DF_Detail.ts @@ -69,11 +69,15 @@ export function evalSafe(lg: CfLogic, o: DetailOptions = {}): CfEvalResult | nul export const valueOf = (ev: CfEvalResult | null, p: CfPort): CfValue | undefined => ev?.ports[p.box]?.[p.name]; +/** 숫자 글 — 천 단위 쉼표 · 군더더기 소수는 뗌 */ +export const commas = (n: number): string => + Number(n.toPrecision(12)).toLocaleString("ko-KR", { maximumFractionDigits: 6 }); + /** 화면에 보일 값 글 — 표는 줄 수 */ export function showValue(v: CfValue | undefined): string { if (v === undefined || v === null) return td("Empty"); if (Array.isArray(v)) return td("Table", { n: Math.max(0, v.length - 1) }); - return typeof v === "number" ? String(Number(v.toPrecision(12))) : String(v); + return typeof v === "number" ? commas(v) : String(v); } export function unitOf(lg: CfLogic, p: CfPort): string { diff --git a/M02_MasterTemplete/DataFlow/M02_DF_LinkPanel.ts b/M02_MasterTemplete/DataFlow/M02_DF_LinkPanel.ts index 1d7c4043c..5b4be1dc6 100644 --- a/M02_MasterTemplete/DataFlow/M02_DF_LinkPanel.ts +++ b/M02_MasterTemplete/DataFlow/M02_DF_LinkPanel.ts @@ -19,6 +19,7 @@ import { } from "./M02_DF_Model"; import { GATE_OPS, + commas, SCALE_OPS, evalSafe, labelOf, @@ -127,6 +128,7 @@ function select( return s; } +/** 숫자 칸 — 보일 때만 천 단위 쉼표 · 고치는 동안은 쉼표 없이 */ function numberBox( ctx: Ctx, value: number | string, @@ -135,10 +137,13 @@ function numberBox( ): HTMLElement { const i = el("input", { className: "ui-input ui-input--sm m02-dflink-num", - attrs: { type: "text", "aria-label": aria }, + attrs: { type: "text", inputmode: "decimal", "aria-label": aria }, }); - i.value = String(value); + const shown = (): string => (typeof value === "number" ? commas(value) : String(value)); + i.value = shown(); i.readOnly = ctx.readOnly; + i.addEventListener("focus", () => (i.value = String(value))); + i.addEventListener("blur", () => (i.value = shown())); i.addEventListener("change", () => { const t = i.value.trim().replace(/,/g, ""); onCommit(t !== "" && Number.isFinite(Number(t)) ? Number(t) : t); diff --git a/M02_MasterTemplete/DataFlow/M02_DF_PillPanel.ts b/M02_MasterTemplete/DataFlow/M02_DF_PillPanel.ts index dcd3a4aa3..deff36790 100644 --- a/M02_MasterTemplete/DataFlow/M02_DF_PillPanel.ts +++ b/M02_MasterTemplete/DataFlow/M02_DF_PillPanel.ts @@ -47,6 +47,7 @@ const line = (label: string, ...value: (HTMLElement | string)[]): HTMLElement => children: [el("span", { className: "m02-dflink-label", text: label }), ...value], }); +/** 한 줄 = 선 하나면 「보낸 알약 → (규칙 글) → 받는 알약」 · 함수 안 걸음이면 알약 하나 */ function steps( lg: CfLogic, list: CfStep[], @@ -55,21 +56,30 @@ function steps( onBox?: (id: string) => void, ): HTMLElement { if (!list.length) return el("p", { className: "m02-dflink-note", text: empty }); + const pill = (box: string, name: string): HTMLElement | string => + onBox + ? createButton({ + label: portText(lg, { box, name }), + variant: "ghost", + size: "sm", + onClick: () => onBox(box), + }) + : portText(lg, { box, name }); return el("ol", { className: "m02-dfpill-list", children: list.map((s) => { - const parts: (HTMLElement | string)[] = [ - arrow, - onBox - ? createButton({ - label: portText(lg, { box: s.box, name: s.port }), - variant: "ghost", - size: "sm", - onClick: () => onBox(s.box), - }) - : portText(lg, { box: s.box, name: s.port }), - ]; - if (s.rule) parts.push(el("span", { className: "m02-dfpill-rule", text: labelOf(s.rule) })); + const link = s.link ? lg.links.find((l) => l.id === s.link) : undefined; + const parts: (HTMLElement | string)[] = link + ? [ + arrow, + pill(link.from.box, link.from.name), + "→", + ...(s.rule + ? [el("span", { className: "m02-dfpill-rule", text: `(${labelOf(s.rule)})` }), "→"] + : []), + pill(link.to.box, link.to.name), + ] + : [arrow, pill(s.box, s.port)]; return el("li", { className: "m02-dfpill-step", children: parts }); }), });