This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
const COIL_MAX = 2000;
|
||||
|
||||
const el = (id) => document.getElementById(id);
|
||||
const t = (key, vars) => window.I18n?.t(key, vars) ?? key;
|
||||
const triggerListEl = el("integrationTriggerList");
|
||||
const triggerEmptyEl = el("integrationTriggerEmpty");
|
||||
const coilGridEl = el("integrationCoilGrid");
|
||||
@@ -72,7 +73,7 @@
|
||||
const data = await apiJson("/api/fleet/robots");
|
||||
store.robots = Array.isArray(data) ? data : [];
|
||||
} catch {
|
||||
store.robots = [{ id: "default", name: "Robot chính" }];
|
||||
store.robots = [{ id: "default", name: t("integrations.defaultRobot") }];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +97,7 @@
|
||||
if (!store.missions.length) {
|
||||
const opt = document.createElement("option");
|
||||
opt.value = "";
|
||||
opt.textContent = "— Chưa có mission —";
|
||||
opt.textContent = t("integrations.noMissions");
|
||||
selectEl.appendChild(opt);
|
||||
return;
|
||||
}
|
||||
@@ -122,7 +123,7 @@
|
||||
if (!store.robots.length) {
|
||||
const opt = document.createElement("option");
|
||||
opt.value = "default";
|
||||
opt.textContent = "Robot chính";
|
||||
opt.textContent = t("integrations.defaultRobot");
|
||||
opt.selected = selected === "default";
|
||||
selectEl.appendChild(opt);
|
||||
}
|
||||
@@ -133,24 +134,24 @@
|
||||
triggerListEl.innerHTML = "";
|
||||
if (triggerEmptyEl) triggerEmptyEl.hidden = store.triggers.length > 0;
|
||||
|
||||
store.triggers.forEach((t) => {
|
||||
store.triggers.forEach((trigger) => {
|
||||
const row = document.createElement("div");
|
||||
row.className = "missionListItem integrationRow";
|
||||
const coil = t.coil_id;
|
||||
const coil = trigger.coil_id;
|
||||
const on = store.coils[String(coil)] === true;
|
||||
row.innerHTML = `
|
||||
<div>
|
||||
<div class="missionListItemTitle">${escapeHtml(t.name)}</div>
|
||||
<div class="missionListItemTitle">${escapeHtml(trigger.name)}</div>
|
||||
<div class="missionListItemMeta">
|
||||
Coil <span class="mono">${coil}</span>
|
||||
→ ${escapeHtml(missionName(t.mission_id))}
|
||||
· ${t.enabled === false ? "Tắt" : "Bật"}
|
||||
· coil hiện tại: <span class="mono">${on ? "ON" : "OFF"}</span>
|
||||
→ ${escapeHtml(missionName(trigger.mission_id))}
|
||||
· ${trigger.enabled === false ? t("common.disabled") : t("common.enabled")}
|
||||
· ${t("integrations.coilState", { state: on ? "ON" : "OFF" })}
|
||||
</div>
|
||||
</div>
|
||||
<div class="missionListItemActions">
|
||||
<button type="button" class="btn subtle" data-fire-coil="${coil}">Kích hoạt</button>
|
||||
<button type="button" class="btn subtle danger" data-delete-trigger="${escapeHtml(t.id)}">Xóa</button>
|
||||
<button type="button" class="btn subtle" data-fire-coil="${coil}">${t("integrations.fireTrigger")}</button>
|
||||
<button type="button" class="btn subtle danger" data-delete-trigger="${escapeHtml(trigger.id)}">${t("common.delete")}</button>
|
||||
</div>`;
|
||||
triggerListEl.appendChild(row);
|
||||
});
|
||||
@@ -160,10 +161,10 @@
|
||||
if (!coilGridEl) return;
|
||||
const assigned = new Map(store.triggers.map((t) => [t.coil_id, t]));
|
||||
const chips = [];
|
||||
assigned.forEach((t, coilId) => {
|
||||
assigned.forEach((trigger, coilId) => {
|
||||
const on = store.coils[String(coilId)] === true;
|
||||
chips.push(
|
||||
`<button type="button" class="integrationCoilChip${on ? " on" : ""}" data-fire-coil="${coilId}" title="${escapeHtml(t.name)}">
|
||||
`<button type="button" class="integrationCoilChip${on ? " on" : ""}" data-fire-coil="${coilId}" title="${escapeHtml(trigger.name)}">
|
||||
${coilId}
|
||||
</button>`
|
||||
);
|
||||
@@ -171,11 +172,11 @@
|
||||
coilGridEl.innerHTML =
|
||||
chips.length > 0
|
||||
? chips.join("")
|
||||
: `<span class="mutedNote">Chưa gán coil. Thêm trigger bên trên (1001–2000).</span>`;
|
||||
: `<span class="mutedNote">${t("integrations.coilsEmpty")}</span>`;
|
||||
}
|
||||
|
||||
function formatScheduleTime(s) {
|
||||
if (!s.start_at) return s.start_mode === "scheduled" ? "—" : "Ngay (asap)";
|
||||
if (!s.start_at) return s.start_mode === "scheduled" ? "—" : t("integrations.dialog.schedule.asap");
|
||||
try {
|
||||
return new Date(s.start_at).toLocaleString("vi-VN");
|
||||
} catch {
|
||||
@@ -204,7 +205,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="missionListItemActions">
|
||||
<button type="button" class="btn subtle" data-run-schedule="${escapeHtml(s.id)}">Chạy ngay</button>
|
||||
<button type="button" class="btn subtle" data-run-schedule="${escapeHtml(s.id)}">${t("integrations.schedule.runNow")}</button>
|
||||
<button type="button" class="btn subtle danger" data-delete-schedule="${escapeHtml(s.id)}">Xóa</button>
|
||||
</div>`;
|
||||
scheduleListEl.appendChild(row);
|
||||
@@ -316,7 +317,7 @@
|
||||
}
|
||||
|
||||
async function deleteTrigger(id) {
|
||||
if (!confirm("Xóa trigger Modbus này?")) return;
|
||||
if (!confirm(t("integrations.confirm.deleteTrigger"))) return;
|
||||
try {
|
||||
await apiJson(`/api/triggers/${id}`, { method: "DELETE" });
|
||||
await refreshAll();
|
||||
@@ -326,7 +327,7 @@
|
||||
}
|
||||
|
||||
async function deleteSchedule(id) {
|
||||
if (!confirm("Xóa lịch fleet này?")) return;
|
||||
if (!confirm(t("integrations.confirm.deleteSchedule"))) return;
|
||||
try {
|
||||
await apiJson(`/api/fleet/schedules/${id}`, { method: "DELETE" });
|
||||
await refreshAll();
|
||||
@@ -446,6 +447,12 @@
|
||||
function boot() {
|
||||
init();
|
||||
}
|
||||
window.addEventListener("lm:locale-change", () => {
|
||||
renderTriggers();
|
||||
renderCoilGrid();
|
||||
renderSchedules();
|
||||
});
|
||||
|
||||
if (window.AuthApp?.isReady()) boot();
|
||||
else window.addEventListener("lm:auth-ready", boot, { once: true });
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user