nai-aclab 1.0.10 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/web/main.js +37 -21
- package/web/styles.css +6 -0
package/package.json
CHANGED
package/web/main.js
CHANGED
|
@@ -149,20 +149,26 @@ function scheduleSave() {
|
|
|
149
149
|
saveTimer = setTimeout(saveNow, 450);
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
async function saveNow() {
|
|
153
|
-
if (!state) return;
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
152
|
+
async function saveNow() {
|
|
153
|
+
if (!state) return;
|
|
154
|
+
const tokenInput = $("#api_token");
|
|
155
|
+
const hadPendingToken = Boolean(tokenInput?.value.trim());
|
|
156
|
+
syncEditorsToState();
|
|
157
|
+
try {
|
|
158
|
+
const data = await request("/api/state", {
|
|
159
|
+
method: "POST",
|
|
160
|
+
body: JSON.stringify({ state }),
|
|
161
|
+
});
|
|
162
|
+
state = data.state;
|
|
163
|
+
if (hadPendingToken && tokenInput) {
|
|
164
|
+
tokenInput.value = "";
|
|
165
|
+
tokenInput.placeholder = "저장된 토큰을 사용합니다. 새 토큰을 입력하면 교체됩니다.";
|
|
166
|
+
}
|
|
167
|
+
setSaveState(hadPendingToken ? "API 토큰 변경 저장됨" : "자동 저장됨");
|
|
168
|
+
} catch (error) {
|
|
169
|
+
setSaveState("저장 실패");
|
|
170
|
+
console.error(error);
|
|
171
|
+
}
|
|
166
172
|
}
|
|
167
173
|
|
|
168
174
|
function syncEditorsToState() {
|
|
@@ -601,9 +607,17 @@ function renderSettings() {
|
|
|
601
607
|
input.value = key === "token" ? "" : state.api[key] ?? "";
|
|
602
608
|
}
|
|
603
609
|
if (key === "token") {
|
|
604
|
-
input.placeholder = state.api.token_saved
|
|
610
|
+
input.placeholder = state.api.token_saved
|
|
611
|
+
? "저장된 토큰을 사용합니다. 새 토큰을 입력하면 교체됩니다."
|
|
612
|
+
: "API 토큰을 입력하세요";
|
|
605
613
|
input.autocomplete = "off";
|
|
606
|
-
|
|
614
|
+
const help = document.createElement("small");
|
|
615
|
+
help.className = "field-help";
|
|
616
|
+
help.textContent = state.api.token_saved
|
|
617
|
+
? "보안을 위해 저장된 토큰은 다시 표시하지 않습니다. 새 토큰을 입력하고 설정 저장을 누르면 기존 토큰을 교체합니다."
|
|
618
|
+
: "토큰은 브라우저에 다시 노출하지 않고 로컬에만 저장합니다.";
|
|
619
|
+
wrap.appendChild(help);
|
|
620
|
+
}
|
|
607
621
|
if (type === "number") input.step = "any";
|
|
608
622
|
}
|
|
609
623
|
$("#mockMode").checked = !!state.api.mock_mode;
|
|
@@ -1619,11 +1633,13 @@ function bindAutosaveInputs(root = document) {
|
|
|
1619
1633
|
root.querySelectorAll("input, textarea, select").forEach((node) => {
|
|
1620
1634
|
if (node.id === "compareHistorySelect") return;
|
|
1621
1635
|
if (node.id === "deleteFilesToggle" || node.closest("#historyList")) return;
|
|
1622
|
-
if (node.id === "api_token") {
|
|
1623
|
-
node.oninput =
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1636
|
+
if (node.id === "api_token") {
|
|
1637
|
+
node.oninput = () => {
|
|
1638
|
+
setSaveState(node.value.trim() ? "새 API 토큰 입력됨" : "저장된 API 토큰 유지");
|
|
1639
|
+
};
|
|
1640
|
+
node.onchange = () => {
|
|
1641
|
+
syncEditorsToState();
|
|
1642
|
+
scheduleSave();
|
|
1627
1643
|
};
|
|
1628
1644
|
return;
|
|
1629
1645
|
}
|