107 lines
6.1 KiB
JavaScript
107 lines
6.1 KiB
JavaScript
/* -*- coding: utf-8 -*- */
|
|
/**
|
|
* 표준중기공식 편집 화면 (scr_edit_eq.js) — wM_Edit_EQ · 추가 · 삭제 · 저장 · 취소 · 적용(공식 / 공식+코드)
|
|
* 근거: 지식DB 28 §1.1(사용자 등록부 — 「수정된 중기공식을 저장하시겠습니까?」 · 「신규공식 추가」 · 「공식+코드」) ·
|
|
* REA 30 TWM_EDIT_EQ(mBtn_Insert · mBtn_Delete · mBtn_Save · mBtn_Cancel · cBx_INS_X · MEMOC) · EQSYNC(NAME · SYNC · INS_X)
|
|
* 저장 = api_qty.py /api/qty/eq (work_dbf/EQSYNC.json) · 불러 쓰기 = 산출근거 편집기 「중기공식 불러오기」
|
|
*/
|
|
(function (global) {
|
|
"use strict";
|
|
const P = (global.STMATE_PLUGINS = global.STMATE_PLUGINS || { screens: {}, actions: {}, menus: [] });
|
|
const esc = (s) =>
|
|
String(s == null ? "" : s).replace(/[&<>"]/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[c]);
|
|
|
|
function load(ctx, app) {
|
|
if (ctx.uiState.eqDraft || ctx.uiState.eqDraftLoading) return;
|
|
ctx.uiState.eqDraftLoading = true;
|
|
fetch("/api/qty/eq")
|
|
.then((r) => r.json())
|
|
.then((r) => {
|
|
ctx.uiState.eqItems = r.items || [];
|
|
ctx.uiState.eqDraft = JSON.parse(JSON.stringify(ctx.uiState.eqItems));
|
|
ctx.uiState.eqDraftLoading = false;
|
|
app.renderWorkspace();
|
|
})
|
|
.catch(() => ((ctx.uiState.eqDraft = []), (ctx.uiState.eqDraftLoading = false)));
|
|
}
|
|
|
|
function render(ctx, app) {
|
|
load(ctx, app);
|
|
const u = ctx.uiState;
|
|
const items = u.eqDraft || [];
|
|
const i = Math.min(u.eqSel || 0, Math.max(0, items.length - 1));
|
|
const it = items[i];
|
|
const ev = it ? global.STMATE_ENGINE.evaluateSmtFormulaText(it.text || "", ctx, "") : null;
|
|
const dirty = JSON.stringify(items) !== JSON.stringify(u.eqItems || []);
|
|
return `
|
|
<div class="win-form">
|
|
<div class="win-form-header"><span>표준중기공식 편집. [wM_Edit_EQ]</span><span>${items.length}개 공식${dirty ? " · 고친 뒤 저장 안 함" : ""}</span></div>
|
|
<div class="win-subbar">
|
|
<button class="win-btn" id="eq-add">추 가</button>
|
|
<button class="win-btn" id="eq-del">삭 제</button>
|
|
<button class="win-btn primary" id="eq-save">저 장</button>
|
|
<button class="win-btn" id="eq-cancel">취 소</button>
|
|
<button class="win-btn" id="eq-close" style="margin-left:auto;">종 료</button>
|
|
</div>
|
|
<div class="split-horiz">
|
|
<div class="pane-box" style="width:300px;"><div class="grid-scroll"><table class="dbgrid">
|
|
<thead><tr><th style="width:30px">No</th><th>명칭</th><th style="width:70px">적용</th></tr></thead>
|
|
<tbody>${items.map((e, k) => `<tr class="eq-row ${k === i ? "selected" : ""}" data-i="${k}" style="cursor:pointer;"><td class="center">${k + 1}</td><td>${esc(e.name)}</td><td class="center">${e.ins_x ? "공식+코드" : "공식"}</td></tr>`).join("")}</tbody>
|
|
</table></div></div>
|
|
<div class="split-vert" style="flex:1;padding:0;">
|
|
${
|
|
it
|
|
? `<div class="win-subbar"><label>명칭 <input id="eq-name" value="${esc(it.name)}" style="width:260px"></label>
|
|
<label>적용 <select id="eq-insx"><option value="0" ${!it.ins_x ? "selected" : ""}>공 식</option><option value="1" ${it.ins_x ? "selected" : ""}>공식+코드</option></select></label></div>
|
|
<div class="pane-box" style="flex:1;"><textarea id="eq-text" class="smt-editor-area" spellcheck="false">${esc(it.text)}</textarea></div>
|
|
<div class="pane-box" style="max-height:120px;overflow:auto;font-size:12px;">
|
|
<div class="pane-title"><span>문법 검사 ${ev.errors.length}건 · 변수 ${esc(Object.entries(ev.vars).map(([k, v]) => `${k}=${v}`).join(", ") || "없음")}</span></div>
|
|
${ev.errors.map((e) => `<div style="color:#b91c1c">${e.lineNo}번째줄: ${esc(e.msg)}</div>`).join("")}
|
|
</div>`
|
|
: "<div class='pane-box'>등록된 중기공식 없음 — [추가]</div>"
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>`;
|
|
}
|
|
|
|
function bind(ctx, app) {
|
|
const u = ctx.uiState;
|
|
const $ = (id) => document.getElementById(id);
|
|
const items = u.eqDraft || [];
|
|
const i = Math.min(u.eqSel || 0, Math.max(0, items.length - 1));
|
|
const redraw = () => app.renderWorkspace();
|
|
document.querySelectorAll(".eq-row").forEach((tr) => (tr.onclick = () => ((u.eqSel = Number(tr.dataset.i)), redraw())));
|
|
if ($("eq-name")) $("eq-name").onchange = (e) => ((items[i].name = e.target.value), redraw());
|
|
if ($("eq-insx")) $("eq-insx").onchange = (e) => ((items[i].ins_x = Number(e.target.value)), redraw());
|
|
if ($("eq-text")) $("eq-text").onchange = (e) => ((items[i].text = e.target.value), redraw());
|
|
$("eq-add").onclick = () => {
|
|
if (!confirm("새로운 중기공식을 추가하시겠습니까?")) return;
|
|
items.push({ name: `신규공식 ${items.length + 1}`, text: "q = 0.7 , K = 0.9 , f = 1/1.25 , E = 0.6\r\nCm = 21\r\nQ = 3600*q*K*f*E/Cm =", ins_x: 0 });
|
|
u.eqSel = items.length - 1;
|
|
redraw();
|
|
};
|
|
$("eq-del").onclick = () => {
|
|
if (!items.length || !confirm("선택된 중기공식을 삭제하시겠습니까?")) return;
|
|
items.splice(i, 1);
|
|
redraw();
|
|
};
|
|
$("eq-cancel").onclick = () => ((u.eqDraft = JSON.parse(JSON.stringify(u.eqItems || []))), redraw());
|
|
$("eq-save").onclick = async () => {
|
|
if (!confirm("수정된 중기공식을 저장하시겠습니까?")) return;
|
|
try {
|
|
await app.postJson("/api/qty/eq", { items });
|
|
u.eqItems = JSON.parse(JSON.stringify(items));
|
|
redraw();
|
|
} catch (err) {
|
|
alert("중기공식 저장 실패: " + err.message);
|
|
}
|
|
};
|
|
$("eq-close").onclick = () => ((u.activeScreen = "wM_Edit_iLWi"), redraw());
|
|
}
|
|
|
|
P.screens.wM_Edit_EQ = { render, bind };
|
|
P.actions.Act_Qty_EditEQ = (ctx, app) => ((ctx.uiState.activeScreen = "wM_Edit_EQ"), app.renderWorkspace());
|
|
if (!P.menus.some((m) => m.act === "Act_Qty_EditEQ")) P.menus.push({ menu: "m2", label: "표준중기공식 편집", act: "Act_Qty_EditEQ" });
|
|
})(window);
|