auto: 2026-09-22 01:42 (EOMSANGDON-HOME)

This commit is contained in:
2026-09-22 01:42:02 +09:00
parent 5b2f678147
commit cce77d16a7
3 changed files with 60 additions and 10 deletions
+51 -9
View File
@@ -65,21 +65,47 @@ export function mountM01Combo(
let items: ComboSummary[] = [];
let logics = new Map<string, LogicSummary>();
let pick = { sub: "", detail: "" };
/** 화면을 바꾼 횟수 — 늦게 온 답은 이 값이 달라졌으면 버림 */
let nav = 0;
/** 열어 둔 상세 — 다른 화면에 갔다 와도 그대로 돌아오게 기억 */
let current: { combo: Combo; version: string } | null = null;
let logicsReady: Promise<void> = Promise.resolve();
const filterHost = el("div");
side.comboHost.replaceChildren(filterHost);
const view = el("div", { className: "m01-logic__editor" });
host.replaceChildren(view);
const load = async (): Promise<void> => {
/** 목록만 받음 — 로직 이름표(1300여 개)는 따로 받아 목록을 붙잡지 않음 */
const load = async (redraw = true): Promise<void> => {
const my = nav;
try {
const [combos, all] = await Promise.all([fetchCombos(), fetchLogics()]);
items = combos;
logics = new Map(all.map((x) => [x., x]));
items = await fetchCombos();
} catch (error) {
showToast(error instanceof Error ? error.message : tc("Load_Failed"), "error");
}
drawFilter();
drawList();
if (redraw && my === nav) drawList();
};
const loadLogics = (): void => {
logicsReady = fetchLogics()
.then((all) => {
logics = new Map(all.map((x) => [x., x]));
})
.catch((error) =>
showToast(error instanceof Error ? error.message : tc("Load_Failed"), "error"),
);
};
const show = async (): Promise<void> => {
if (!logics.size) loadLogics();
if (!items.length && !current) {
view.replaceChildren(el("p", { className: "m01-logic__muted", text: tc("Loading") }));
}
await load(false);
if (!current) drawList();
await logicsReady;
if (current) draw(current.combo, current.version);
};
/* --- 왼쪽 거름 --- */
@@ -124,6 +150,8 @@ export function mountM01Combo(
});
const drawList = (): void => {
nav++;
current = null;
const shown = items.filter(
(x) => (!pick.sub || x. === pick.sub) && (!pick.detail || x. === pick.detail),
);
@@ -169,7 +197,10 @@ export function mountM01Combo(
const open = async (key: string): Promise<void> => {
try {
const my = ++nav;
const one = await fetchCombo(key);
await logicsReady;
if (my !== nav) return;
draw(one.combo, one.version);
} catch (error) {
showToast(error instanceof Error ? error.message : tc("Load_Failed"), "error");
@@ -178,6 +209,9 @@ export function mountM01Combo(
/* --- 상세 --- */
const draw = (combo: Combo, version: string): void => {
nav++;
current = { combo, version };
const saved = JSON.stringify(combo);
const field = (label: string, name: "이름" | "구분" | "상세구분" | "단위" | "비고") => {
const f = createInputField({ type: "text", label });
f.input.value = combo[name] ?? "";
@@ -190,7 +224,7 @@ export function mountM01Combo(
return f.root;
};
const preview = buildPreview(() => combo);
const table = el("div");
const table = el("div", { className: "m01-master__grid-wrap" });
const drawTable = (): void => {
const move = (i: number, d: number): void => {
const j = i + d;
@@ -208,7 +242,10 @@ export function mountM01Combo(
text: info?.이름 ?? row.,
attrs: { type: "button", title: tc("Open") },
});
name.addEventListener("click", () => onOpenLogic(row.));
name.addEventListener("click", async () => {
if (JSON.stringify(combo) !== saved && !(await showConfirmDialog(tc("LeaveAsk")))) return;
onOpenLogic(row.);
});
const btns = el("div", {
className: "m01-logic__chips",
children: [
@@ -274,11 +311,16 @@ export function mountM01Combo(
variant: "filled",
onClick: async () => {
if (!combo..trim()) return showToast(tc("NeedName"), "error");
const my = nav;
try {
const key = combo. ? combo. : (await newCombo(combo)).key;
if (combo.) await editCombo(combo., version, combo);
showToast(tc("Saved"), "success");
await load();
await load(false);
if (my !== nav) {
if (current?.combo === combo) current = null; // 저장 사이에 나감 — 옛 판본을 붙들지 않음
return;
}
await open(key);
} catch (error) {
showToast(reason(error), "error");
@@ -335,5 +377,5 @@ export function mountM01Combo(
drawTable();
};
return { show: load };
return { show };
}
@@ -54,7 +54,10 @@ export function buildPreview(combo: () => Combo): PreviewHandle {
/** 서버가 받을 꼴 — 원래 숫자·고르기 값으로 되돌림 */
const inputs = new Map<string, LogicInput[]>();
const form = el("div", { className: "m01-logic__stack" });
const out = el("div", { attrs: { "data-combo": "preview" } });
const out = el("div", {
className: "m01-master__grid-wrap",
attrs: { "data-combo": "preview" },
});
const rowOf = (cells: string[], note = "", bold = false): HTMLElement =>
el("tr", {
className: bold ? "m01lab__subtotal" : "",
@@ -18,6 +18,11 @@ const TEXT = {
Saved: ["저장함", "Saved"],
Deleted: ["지움", "Deleted"],
Stale: ["그 사이 조합 파일이 바뀜 — 다시 열어 주세요", "The file changed — reopen it"],
Loading: ["불러오는 중…", "Loading…"],
LeaveAsk: [
"저장 안 한 고침이 있음 — 로직 상세로 가면 이 화면에서는 그대로 두고 옮겨 감. 갈까요?",
"Unsaved edits — go to the logic anyway?",
],
NeedName: ["이름을 적어야 저장됨", "A name is required"],
Load_Failed: ["불러오지 못함", "Load failed"],
Head_Key: ["키", "Key"],