diff --git a/M02_MasterTemplete/DataFlow/M02_DF_InputPanel.ts b/M02_MasterTemplete/DataFlow/M02_DF_InputPanel.ts index cce05141a..6f068462c 100644 --- a/M02_MasterTemplete/DataFlow/M02_DF_InputPanel.ts +++ b/M02_MasterTemplete/DataFlow/M02_DF_InputPanel.ts @@ -7,20 +7,14 @@ * ========================================================================== */ import { currentLanguageIndex } from "@ui/ui_template_locale"; -import { - createButton, - createInputField, - createSelectField, - el, - showToast, -} from "@ui/ui_template_elements"; +import { createButton, createInputField, createSelectField, el } from "@ui/ui_template_elements"; import { fetchFiles, fetchRows, fetchSubs, type SubInfo, } from "../../M01_MasterData/M01_MasterData_Api_Fetch"; -import { cfPlain, cfUserElementAdd, cfUserElements, cfValues } from "./M02_DF_Api"; +import { cfPlain, cfValues } from "./M02_DF_Api"; import type { CfBox, CfGroup, CfLogic } from "./M02_DF_Model"; import { GROUPS, @@ -40,7 +34,6 @@ import { } from "./M02_DF_InputPanel_Build"; import { renderLogicInput } from "./M02_DF_InputPanel_Logic"; import { renderGroupRule } from "./M02_DF_InputPanel_Rule"; -import { NO_UNIT, createUnitPick } from "./M02_DF_UnitPick"; import { renderMaterial } from "./M02_DF_InputPanel_Material"; import { renderTablePick } from "./M02_DF_InputPanel_Table"; import { renderVariables } from "./M02_DF_InputPanel_Vars"; @@ -52,17 +45,7 @@ interface Answer { ok: boolean; value?: number | string | null; } -interface UserEl { - id: string; - group: string; - name: string; - spec: string; - unit: string; - value: number | null; -} const apiValues = cfValues as unknown as (items: object[], users?: object[]) => Promise; -const apiUsers = cfUserElements as unknown as () => Promise; -const apiAdd = cfUserElementAdd as unknown as (e: Omit) => Promise; const TEXT = { Kind: ["무엇을 넣을까요?", "What goes in?"], @@ -94,15 +77,6 @@ const TEXT = { Loading: ["찾는 중…", "Searching…"], NoRow: ["찾는 요소 없음", "Nothing found"], Count: ["{n} 개 중 앞 {m} 개", "First {m} of {n}"], - Mine: ["내가 만든 것", "Mine"], - NewHead: ["새 요소 — 마스터에는 안 쓰고 내 것으로만 저장", "New element — saved as mine only"], - NewName: ["이름", "Name"], - NewSpec: ["규격", "Spec"], - NewUnit: ["단위", "Unit"], - NewValue: ["값(숫자)", "Value (number)"], - Make: ["만들어 넣기", "Create and add"], - NeedName: ["이름을 적어 주세요", "Enter a name"], - NeedValue: ["값은 숫자로", "Value must be a number"], BoxUnit: ["상자 단위", "Box unit"], Field: ["값 칸", "Value"], NoValue: ["—", "—"], @@ -208,7 +182,7 @@ function renderGroup( renderGroupRule(body, lg, box.id, group, (l, e) => addElement(l, box.id, e), rulePreview, on); else { const find = el("div", { className: "m02-dfip__find" }); - body.replaceChildren(find, newForm(lg, box, group, on)); + body.replaceChildren(find); void drawFind(find, lg, box, group, on); } }; @@ -306,7 +280,7 @@ function drawChosen( .filter((e) => e.mode !== "rule") .map((e) => ({ id: e.ref, ...queryOf(group, e.ref) })); if (!items.length) return; - void apiValues(items, lg.userElements).then( + void apiValues(items).then( (answers) => answers.forEach((a) => { const node = values.get(a.id); @@ -360,26 +334,10 @@ async function drawFind( list.replaceChildren(el("p", { className: "m02-dfip__muted", text: t("Loading") })); try { const word = q.input.value.trim(); - const [page, users] = await Promise.all([ - fetchRows(file, 1, 40, word, false, sub, detail), - apiUsers().catch((): UserEl[] => []), - ]); + const page = await fetchRows(file, 1, 40, word, false, sub, detail); if (mine !== seq) return; - const known = new Map(); - for (const u of [...lg.userElements, ...users]) - if (u.group === group) known.set(u.id, u as UserEl); - const mineRows: M01Row[] = [...known.values()] - .filter((u) => !word || `${u.name} ${u.spec}`.includes(word)) - .map((u) => ({ - 키: u.id, - 이름: u.name, - 규격: u.spec, - 단위: u.unit, - 값: u.value, - __mine: true, - })); - const rows = [...mineRows, ...(page.rows as M01Row[])]; - count.textContent = t("Count", { n: page.total + mineRows.length, m: rows.length }); + const rows = page.rows as M01Row[]; + count.textContent = t("Count", { n: page.total, m: rows.length }); list.replaceChildren( ...(rows.length ? rows.map((r) => rowOf(r)) @@ -411,7 +369,6 @@ async function drawFind( children: [ el("strong", { text: String(r["이름"] ?? "") }), el("span", { className: "m02-dfip__muted", text: ` ${r["규격"] ?? ""}` }), - ...(r["__mine"] ? [el("span", { className: "m02-dfip__tag", text: t("Mine") })] : []), ], }), el("span", { @@ -448,66 +405,3 @@ async function drawFind( ); void load(); } - -/** 새 요소 — M01 표 「추가」 화면 꼴(이름 · 규격 · 단위 · 값) · 마스터에 안 쓰고 사용자 요소로 */ -function newForm( - lg: CfLogic, - box: CfBox, - group: CfGroup, - on: { change(lg: CfLogic): void }, -): HTMLElement { - const name = createInputField({ type: "text", label: t("NewName"), compact: true }); - const spec = createInputField({ type: "text", label: t("NewSpec"), compact: true }); - let unitValue = ""; - const unit = el("div", { className: "m02-dfip__unitfield" }); - const drawUnit = (): void => - unit.replaceChildren( - el("span", { className: "m02-dfip__muted", text: t("NewUnit") }), - createUnitPick({ - value: unitValue || NO_UNIT, - ariaLabel: t("NewUnit"), - onPick: (u) => ((unitValue = u === NO_UNIT ? "" : u), drawUnit()), - }), - ); - drawUnit(); - const value = createInputField({ type: "text", label: t("NewValue"), compact: true }); - const go = createButton({ - label: t("Make"), - onClick: () => { - const n = - value.input.value.trim() === "" ? null : Number(value.input.value.replace(/,/g, "")); - if (!name.input.value.trim()) return name.setError(t("NeedName")); - if (n !== null && !Number.isFinite(n)) return value.setError(t("NeedValue")); - name.setError(undefined); - value.setError(undefined); - apiAdd({ - group, - name: name.input.value.trim(), - spec: spec.input.value.trim(), - unit: unitValue, - value: n, - }).then( - (made) => { - const el1 = elementOf(group, { - 키: made.id, - 이름: made.name, - 규격: made.spec, - 단위: made.unit, - 값: made.value, - }); - const withUser: CfLogic = { - ...lg, - userElements: [...lg.userElements.filter((u) => u.id !== made.id), { ...made, group }], - }; - on.change(addElement(withUser, box.id, el1)); - }, - (e) => showToast(plain(e), "error"), - ); - }, - }); - const d = el("details", { - className: "m02-dfip__new", - children: [el("summary", { text: t("NewHead") }), name.root, spec.root, unit, value.root, go], - }); - return d; -} diff --git a/M02_MasterTemplete/DataFlow/M02_DF_InputPanel_Build.ts b/M02_MasterTemplete/DataFlow/M02_DF_InputPanel_Build.ts index d52c9bdd8..b650b9eca 100644 --- a/M02_MasterTemplete/DataFlow/M02_DF_InputPanel_Build.ts +++ b/M02_MasterTemplete/DataFlow/M02_DF_InputPanel_Build.ts @@ -45,9 +45,6 @@ export const M01_OF: Record = { /** M01 줄 한 개 — 파일 그대로(한글 칸) */ export type M01Row = Record; -/** 사용자 요소 키 머리 — 마스터가 아니라 시험 폴더 `_data` 에서 옴 */ -export const USER_PREFIX = "UE-"; - /** 기계 요소 한 칸의 값 이름(가격 · 손료계수 …) — ref 는 「EQ000001#가격」 */ export const MACHINE_SEP = "#"; export const machineFields = (row: M01Row): string[] => @@ -85,13 +82,6 @@ export function valueOf(group: CfGroup, row: M01Row, field = "가격"): number | export function elementOf(group: CfGroup, row: M01Row, field = "가격"): CfElementRef { const key = text(row["키"]); const spec = text(row["규격"]); - if (key.startsWith(USER_PREFIX)) - return { - ref: key, - name: [text(row["이름"]), spec].filter(Boolean).join(" "), - spec, - unit: text(row["단위"]) || "-", - }; // 환율 · 유가전력의 규격은 날짜라 알약 이름에 안 넣음(날짜가 바뀌어도 이름이 같게) — 유가전력은 상세구분(지역)으로 가름 const tail = group === "환율" ? "" : group === "유가전력" ? text(row["상세구분"]) : spec; const named = [text(row["이름"]), tail].filter(Boolean).join(" "); // 알약 이름 = 이름 + 규격(규격만 다른 요소가 부딪히지 않게) @@ -123,7 +113,7 @@ export function pillNames(box: CfBox): string[] { /** 입력 값 물음 — Api `cfValues` 한 줄(id 는 부르는 쪽이 정함) */ export function queryOf(group: CfGroup, ref: string): Record { - if (group === "기계" && !ref.startsWith(USER_PREFIX)) { + if (group === "기계") { const [key, field] = ref.split(MACHINE_SEP); return { group, ref: key, field: field || "가격" }; } diff --git a/resources/tester/test_m02_df_inputpanel_build.py b/resources/tester/test_m02_df_inputpanel_build.py index b37fdd1c7..dbfe71c2d 100644 --- a/resources/tester/test_m02_df_inputpanel_build.py +++ b/resources/tester/test_m02_df_inputpanel_build.py @@ -127,12 +127,9 @@ def test_값_읽기_재료는_낮은_값_요율은_비율(): assert call("valueOf", "기계", MACHINE, "가격") == 76547 -def test_사용자_요소는_그_그룹의_ref_로_물음(): - assert call("queryOf", "인력", "UE-0001") == {"group": "인력", "ref": "UE-0001"} +def test_값_물음은_그룹과_ref(): + assert call("queryOf", "인력", "LB000033") == {"group": "인력", "ref": "LB000033"} assert call("queryOf", "재료", "MT1") == {"group": "재료", "ref": "MT1"} - row = {"키": "UE-0001", "이름": "특수공", "규격": "", "단위": "원/일", "값": 300000} - assert call("elementOf", "인력", row)["unit"] == "원/일" - assert call("elementOf", "요율", {**row, "단위": "%"})["unit"] == "%" def test_상자_단위는_같으면_그_단위_여럿이면_하이픈():