fixed default network

This commit is contained in:
2026-06-29 15:06:48 +03:00
parent 980608a279
commit e9e2cbbfec
18 changed files with 1227 additions and 138 deletions
+99 -5
View File
@@ -162,6 +162,93 @@ if (list && window.Sortable) {
const dlg = $("#btn-dialog");
const form = $("#btn-form");
function defaultResponseCheck() {
return {
enabled: false,
requireHttpSuccess: true,
defaultResult: "error",
rules: [],
poll: { intervalMs: 3000, maxAttempts: 20, timeoutMs: 120000 },
};
}
function createRuleRow(rule = {}) {
const row = document.createElement("div");
row.className = "response-rule-row";
row.innerHTML = `
<input type="text" class="rc-field" placeholder="поле (success)" value="${rule.field || ""}">
<select class="rc-op">
<option value="equals">равно</option>
<option value="contains">содержит</option>
</select>
<input type="text" class="rc-value" placeholder="значение" value="${rule.equals ?? rule.contains ?? ""}">
<select class="rc-result">
<option value="error">Ошибка</option>
<option value="ok">Принято</option>
<option value="pending">Ожидание</option>
</select>
<input type="text" class="rc-message" placeholder="сообщение (опц.)" value="${rule.message || ""}">
<button type="button" class="ghost rc-del" title="Удалить">×</button>
`;
row.querySelector(".rc-op").value = rule.contains != null && rule.contains !== "" ? "contains" : "equals";
row.querySelector(".rc-result").value = rule.result || "error";
row.querySelector(".rc-del").addEventListener("click", () => row.remove());
return row;
}
function fillResponseCheckForm(rc) {
const cfg = rc || defaultResponseCheck();
$("#b-rc-enabled").checked = !!cfg.enabled;
$("#b-rc-require-http").checked = cfg.requireHttpSuccess !== false;
$("#b-rc-default").value = cfg.defaultResult || "error";
$("#b-rc-poll-interval").value = cfg.poll?.intervalMs ?? 3000;
$("#b-rc-poll-attempts").value = cfg.poll?.maxAttempts ?? 20;
$("#b-rc-poll-timeout").value = cfg.poll?.timeoutMs ?? 120000;
const wrap = $("#b-rc-rules");
wrap.innerHTML = "";
(cfg.rules || []).forEach(rule => wrap.appendChild(createRuleRow(rule)));
syncResponseCheckUi();
}
function readResponseCheckFromForm() {
if (!$("#b-rc-enabled").checked) {
return { enabled: false };
}
const rules = Array.from($$("#b-rc-rules .response-rule-row")).map(row => {
const field = row.querySelector(".rc-field").value.trim();
const op = row.querySelector(".rc-op").value;
const value = row.querySelector(".rc-value").value;
const result = row.querySelector(".rc-result").value;
const message = row.querySelector(".rc-message").value.trim();
const rule = { field, result };
rule[op] = value;
if (message) rule.message = message;
return rule;
}).filter(r => r.field);
return {
enabled: true,
requireHttpSuccess: $("#b-rc-require-http").checked,
defaultResult: $("#b-rc-default").value,
rules,
poll: {
intervalMs: parseInt($("#b-rc-poll-interval").value, 10) || 3000,
maxAttempts: parseInt($("#b-rc-poll-attempts").value, 10) || 20,
timeoutMs: parseInt($("#b-rc-poll-timeout").value, 10) || 120000,
},
};
}
function syncResponseCheckUi() {
const on = $("#b-rc-enabled")?.checked;
const adv = $("#b-rc-advanced");
if (adv) adv.classList.toggle("show", !!on);
}
$("#b-rc-enabled")?.addEventListener("change", syncResponseCheckUi);
$("#b-rc-add-rule")?.addEventListener("click", () => {
$("#b-rc-rules")?.appendChild(createRuleRow());
});
function syncHoldRow() {
const mode = $("#b-trigger-mode").value;
$("#b-hold-row").style.display = mode === "click" ? "none" : "";
@@ -181,6 +268,7 @@ function openDialogFor(btn) {
$("#b-color").value = btn?.color || "#7b007b";
$("#b-trigger-mode").value = btn?.trigger?.mode || "hold";
$("#b-hold").value = btn?.trigger?.holdMs || 800;
fillResponseCheckForm(btn?.action?.responseCheck);
syncHoldRow();
dlg.showModal();
}
@@ -223,6 +311,7 @@ form?.addEventListener("submit", async (e) => {
color: $("#b-color").value,
triggerMode: $("#b-trigger-mode").value,
holdMs: parseInt($("#b-hold").value, 10),
responseCheck: readResponseCheckFromForm(),
};
if (id) await api("PUT", `/api/buttons/${encodeURIComponent(id)}`, payload);
else await api("POST", "/api/buttons", payload);
@@ -325,17 +414,22 @@ function renderButtonLog(entries) {
return;
}
body.innerHTML = entries.map(e => {
const ok = e.ok;
const result = ok
? (e.http ? `OK ${e.http}` : "OK") + (e.message ? `${e.message}` : "")
: (e.http ? `ERR ${e.http}` : "ERR") + (e.message ? `${e.message}` : "");
const outcome = e.outcome || (e.ok ? "ok" : "error");
const ok = outcome === "ok";
const pending = outcome === "pending";
const http = e.http ? ` ${e.http}` : "";
const attempt = e.attempt > 1 ? ` [${e.attempt}]` : "";
const result = (ok ? "OK" : pending ? "WAIT" : "ERR") + http
+ attempt
+ (e.message ? `${e.message}` : "");
const cls = ok ? "log-ok" : pending ? "log-wait" : "log-err";
return `
<tr>
<td>${e.ts || "—"}</td>
<td>${e.label || "—"}</td>
<td>${e.method || "—"}</td>
<td class="log-path" title="${e.url || ""}">${e.url || "—"}</td>
<td class="${ok ? "log-ok" : "log-err"}">${result}</td>
<td class="${cls}">${result}</td>
<td>${e.ms != null ? e.ms : "—"}</td>
</tr>`;
}).join("");