diff --git a/M01_MasterData/M01_MasterData_UI_Logic_Api.ts b/M01_MasterData/M01_MasterData_UI_Logic_Api.ts index fb180409..8d4d8356 100644 --- a/M01_MasterData/M01_MasterData_UI_Logic_Api.ts +++ b/M01_MasterData/M01_MasterData_UI_Logic_Api.ts @@ -186,3 +186,9 @@ export const runCalc = (body: { export const saveFiles = ( files: SaveFile[], ): Promise<{ files: { file: string; version: string }[] }> => request("/save", { files }); + +/** 본떠 만들기 — 정본·자체 둘 다 본뜸 · 새 키(`GX…`)는 서버가 줌(계약 5장) */ +export const copyLogic = ( + key: string, +): Promise<{ file: string; version: string; key: string; logic: LogicRow }> => + request("/logic/copy", { key }); diff --git a/M01_MasterData/M01_MasterData_UI_Logic_Flow.ts b/M01_MasterData/M01_MasterData_UI_Logic_Flow.ts index 80df10cc..8f31326e 100644 --- a/M01_MasterData/M01_MasterData_UI_Logic_Flow.ts +++ b/M01_MasterData/M01_MasterData_UI_Logic_Flow.ts @@ -32,7 +32,10 @@ import "./M01_MasterData_UI_Logic_Flow_Style.css"; const title = (kind: FlowKind): string => tx(`Col_${kind}` as TextKey); -/** 자체 로직인지 — 자체 파일이거나 키가 `GX…` · 아직 저장 안 한 새 줄(키 "")도 고칠 수 있음 */ +/** + * 자체 로직인지 — 자체 파일(`로직_자체.json`)이거나 키가 `GX…`(계약 5장). + * 아직 저장 안 한 새 줄(키 "")도 고칠 수 있음 · 정본은 「본떠 만들기」 뒤에야 고침. + */ export const isOwnLogic = (file: string, row: LogicRow): boolean => file.startsWith("로직_자체") || (row.키 ?? "").startsWith("GX") || (row.키 ?? "") === ""; diff --git a/M01_MasterData/M01_MasterData_UI_Logic_Page.ts b/M01_MasterData/M01_MasterData_UI_Logic_Page.ts index b3ca491d..01b7d9b9 100644 --- a/M01_MasterData/M01_MasterData_UI_Logic_Page.ts +++ b/M01_MasterData/M01_MasterData_UI_Logic_Page.ts @@ -18,6 +18,7 @@ import { } from "@ui/ui_template_elements"; import { ApiError, + copyLogic, fetchLogic, fetchLogicFiles, fetchLogics, @@ -195,6 +196,7 @@ export async function mountM01Logic( row: shown, editable: isOwnLogic(current.file, shown), onChange: touch, + onCopy: () => void onCopy(current), }); return; } @@ -320,6 +322,22 @@ export async function mountM01Logic( show(next); }; + /** 「본떠 만들기」 — 정본을 자체 파일로 복제하고(계약 5장) 그 새 로직을 바로 엶 */ + const onCopy = async (from: Opened): Promise => { + if (!from.origKey) return; + showLoadingOverlay(); + try { + const made = await copyLogic(from.origKey); + await reload(); + showToast(tx("Edit_Copied", { v: made.key }), "success"); + await open(logicId("자체", made.key), "자체", made.key); + } catch (error) { + failed(error); + } finally { + hideLoadingOverlay(); + } + }; + const onDelete = async (): Promise => { if (!opened?.row) return; if ( diff --git a/M01_MasterData/M01_MasterData_UI_Logic_Text.ts b/M01_MasterData/M01_MasterData_UI_Logic_Text.ts index 615687bd..a727482f 100644 --- a/M01_MasterData/M01_MasterData_UI_Logic_Text.ts +++ b/M01_MasterData/M01_MasterData_UI_Logic_Text.ts @@ -134,6 +134,7 @@ const TEXT = { "Master logics are read-only here — use “Copy as mine” first", ], Edit_Copy: ["본떠 만들기", "Copy as mine"], + Edit_Copied: ["내 로직 「{v}」 을 만들었음 — 여기서 고치면 됨", "Made your logic “{v}”"], Edit_CopySoon: [ "복제 길(API)이 아직 없음 — 서버가 준비되면 여기서 바로 됨", "The copy API is not ready yet",