feat: WP5 조성 분율 입력 UI 폼 (ff.html/js — /api/ff/composition)
랩/원료분석 분율 입력 패널(columnId/stream/분율 → POST·DELETE) + 입력목록 표시. 정적(재기동 불필요). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -120,3 +120,7 @@
|
||||
/* WP5 2·3단계: 조성 권장SP */
|
||||
.ff-comp { margin-top:4px; font-size:12px; color:#cbd5e1; background:#172033; padding:3px 8px; border-radius:4px; }
|
||||
.ff-comp small { color:#94a3b8; }
|
||||
|
||||
/* WP5 3단계: 조성 입력 폼 */
|
||||
.ff-comp-body { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
|
||||
.ff-comp-list { width:100%; margin-top:4px; font-size:12px; color:#94a3b8; }
|
||||
|
||||
@@ -87,6 +87,32 @@ async function ffSimLoad() {
|
||||
}
|
||||
document.getElementById('ff-sim-apply').onclick = ffSimApply;
|
||||
document.getElementById('ff-sim-clear').onclick = ffSimClear;
|
||||
const ca = document.getElementById('ff-comp-apply');
|
||||
if (ca) { ca.onclick = ffCompApply; document.getElementById('ff-comp-clear').onclick = ffCompClear; ffCompRefresh(); }
|
||||
}
|
||||
async function ffCompRefresh() {
|
||||
try {
|
||||
const d = await ffApi('GET', '/api/ff/composition');
|
||||
const el = document.getElementById('ff-comp-list');
|
||||
const ents = Object.entries(d.fractions || {});
|
||||
el.innerHTML = ents.length ? '입력됨: ' + ents.map(([k, v]) => `${esc(k)}=${v}`).join(' · ') : '<small>입력 없음 (config K 사용)</small>';
|
||||
} catch (e) {}
|
||||
}
|
||||
async function ffCompApply() {
|
||||
const g = id => document.getElementById(id);
|
||||
const st = g('ff-comp-status');
|
||||
try {
|
||||
await ffApi('POST', '/api/ff/composition', { columnId: +g('ff-comp-col').value, streamKey: g('ff-comp-key').value, fraction: +g('ff-comp-frac').value });
|
||||
st.textContent = '입력됨'; st.className = 'ff-msg'; ffCompRefresh();
|
||||
} catch (e) { st.textContent = '실패: ' + e.message; st.className = 'ff-msg err'; }
|
||||
}
|
||||
async function ffCompClear() {
|
||||
const g = id => document.getElementById(id);
|
||||
const st = g('ff-comp-status');
|
||||
try {
|
||||
await ffApi('DELETE', `/api/ff/composition/${+g('ff-comp-col').value}/${encodeURIComponent(g('ff-comp-key').value)}`);
|
||||
st.textContent = '해제됨'; st.className = 'ff-msg'; ffCompRefresh();
|
||||
} catch (e) { st.textContent = '실패: ' + e.message; st.className = 'ff-msg err'; }
|
||||
}
|
||||
async function ffSimApply() {
|
||||
const enabled = document.getElementById('ff-sim-enabled').checked;
|
||||
|
||||
@@ -48,4 +48,18 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- WP5 3단계: 조성 분율 수동입력(랩/원료분석) -->
|
||||
<div id="ff-comp" class="ff-sim">
|
||||
<div class="ff-sim-head">조성 분율 입력 <small>랩/원료분석 — base=분율×feed (미입력 시 config K)</small></div>
|
||||
<div class="ff-sim-body ff-comp-body">
|
||||
<label>columnId <input class="inp" id="ff-comp-col" value="1" size="4"></label>
|
||||
<label>stream <input class="inp" id="ff-comp-key" value="B" size="4"></label>
|
||||
<label>분율 <input class="inp" id="ff-comp-frac" type="number" step="any" placeholder="0.03"></label>
|
||||
<button class="btn" id="ff-comp-apply">입력</button>
|
||||
<button class="btn" id="ff-comp-clear">해제</button>
|
||||
<span id="ff-comp-status" class="ff-msg"></span>
|
||||
<div id="ff-comp-list" class="ff-comp-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user