User Log and Persistent Faction Information
This commit is contained in:
@@ -23,6 +23,21 @@ function toInt(v) {
|
||||
return Number.isNaN(n) ? null : n;
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
// Activity logging
|
||||
// ---------------------------
|
||||
async function logAction(action, details = "") {
|
||||
try {
|
||||
await fetch("/api/log_action", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ action, details })
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("Failed to log action:", err);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
// Status CSS helpers
|
||||
// ---------------------------
|
||||
@@ -428,6 +443,11 @@ function setupDropZones() {
|
||||
if (prev) prev.removeChild(member.domElement);
|
||||
zone.appendChild(member.domElement);
|
||||
}
|
||||
|
||||
// Log the assignment
|
||||
if (member) {
|
||||
await logAction("Assigned Member to Group", `${member.name} (${kind}) -> Group ${groupKey}`);
|
||||
}
|
||||
} else {
|
||||
console.warn("Unexpected zone id format", zone.id);
|
||||
}
|
||||
@@ -443,6 +463,11 @@ function setupDropZones() {
|
||||
if (prev) prev.removeChild(member.domElement);
|
||||
container.appendChild(member.domElement);
|
||||
}
|
||||
|
||||
// Log the removal
|
||||
if (member) {
|
||||
await logAction("Removed Member from Group", `${member.name} (${kind})`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -516,6 +541,9 @@ async function populateFriendly() {
|
||||
// Refresh assignments & status UI
|
||||
await loadMembers("enemy"); // in case population changed cross lists
|
||||
await pollAssignments();
|
||||
|
||||
// Log the action
|
||||
await logAction("Populated Friendly Faction", `Faction ID: ${id}, Members: ${data.members ? data.members.length : 0}`);
|
||||
} catch (err) {
|
||||
console.error("populateFriendly error:", err);
|
||||
}
|
||||
@@ -583,6 +611,9 @@ async function populateEnemy() {
|
||||
// Refresh assignments & status UI
|
||||
await loadMembers("friendly");
|
||||
await pollAssignments();
|
||||
|
||||
// Log the action
|
||||
await logAction("Populated Enemy Faction", `Faction ID: ${id}, Members: ${data.members ? data.members.length : 0}`);
|
||||
} catch (err) {
|
||||
console.error("populateEnemy error:", err);
|
||||
}
|
||||
@@ -620,6 +651,9 @@ async function toggleFriendlyStatus() {
|
||||
btn.textContent = "Start";
|
||||
btn.dataset.running = "false";
|
||||
btn.style.backgroundColor = "";
|
||||
// Notify server that status refresh stopped
|
||||
await fetch("/api/stop_friendly_status", { method: "POST" });
|
||||
await logAction("Stopped Friendly Status Refresh");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -637,6 +671,7 @@ async function toggleFriendlyStatus() {
|
||||
btn.textContent = "Stop";
|
||||
btn.dataset.running = "true";
|
||||
btn.style.backgroundColor = "#ff6b6b";
|
||||
await logAction("Started Friendly Status Refresh", `Interval: ${interval}s`);
|
||||
}
|
||||
|
||||
async function toggleEnemyStatus() {
|
||||
@@ -647,6 +682,9 @@ async function toggleEnemyStatus() {
|
||||
btn.textContent = "Start";
|
||||
btn.dataset.running = "false";
|
||||
btn.style.backgroundColor = "";
|
||||
// Notify server that status refresh stopped
|
||||
await fetch("/api/stop_enemy_status", { method: "POST" });
|
||||
await logAction("Stopped Enemy Status Refresh");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -664,6 +702,7 @@ async function toggleEnemyStatus() {
|
||||
btn.textContent = "Stop";
|
||||
btn.dataset.running = "true";
|
||||
btn.style.backgroundColor = "#ff6b6b";
|
||||
await logAction("Started Enemy Status Refresh", `Interval: ${interval}s`);
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
@@ -694,6 +733,9 @@ async function toggleBotControl() {
|
||||
btn.style.backgroundColor = data.bot_running ? "#ff4444" : "#4CAF50";
|
||||
|
||||
console.log(`Bot ${data.bot_running ? "started" : "stopped"}`);
|
||||
|
||||
// Log the action
|
||||
await logAction(data.bot_running ? "Started Bot" : "Stopped Bot");
|
||||
} catch (err) {
|
||||
console.error("toggleBotControl error:", err);
|
||||
}
|
||||
@@ -707,6 +749,8 @@ async function resetGroups() {
|
||||
await clearAssignmentsOnServer();
|
||||
// reload assignments & UI
|
||||
await pollAssignments();
|
||||
// Log the action
|
||||
await logAction("Reset All Groups");
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
@@ -765,6 +809,104 @@ async function handleLogout() {
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
// Restore dashboard state from server
|
||||
// ---------------------------
|
||||
async function restoreDashboardState() {
|
||||
try {
|
||||
const res = await fetch("/api/dashboard_state", { cache: "no-store" });
|
||||
if (!res.ok) {
|
||||
console.log("No dashboard state to restore");
|
||||
return;
|
||||
}
|
||||
|
||||
const state = await res.json();
|
||||
console.log("Restoring dashboard state:", state);
|
||||
|
||||
// Restore friendly faction
|
||||
if (state.friendly_faction_id && state.friendly_members && state.friendly_members.length > 0) {
|
||||
document.getElementById("friendly-id").value = state.friendly_faction_id;
|
||||
|
||||
// Load members into UI
|
||||
for (const m of state.friendly_members) {
|
||||
const newMember = {
|
||||
id: m.id,
|
||||
name: m.name,
|
||||
level: m.level,
|
||||
estimate: m.estimate,
|
||||
status: m.status || "Unknown",
|
||||
hits: m.hits || 0,
|
||||
domElement: null
|
||||
};
|
||||
friendlyMembers.set(m.id, newMember);
|
||||
const card = createMemberCard(newMember, "friendly");
|
||||
friendlyContainer.appendChild(card);
|
||||
}
|
||||
console.log(`Restored ${state.friendly_members.length} friendly members`);
|
||||
|
||||
// Restore status refresh if it was running
|
||||
if (state.friendly_status_running) {
|
||||
const interval = state.friendly_status_interval || 10;
|
||||
document.getElementById("friendly-refresh-interval").value = interval;
|
||||
|
||||
const btn = document.getElementById("friendly-status-btn");
|
||||
friendlyStatusIntervalHandle = setInterval(() => refreshStatus("friendly"), interval * 1000);
|
||||
refreshStatus("friendly");
|
||||
btn.textContent = "Stop";
|
||||
btn.dataset.running = "true";
|
||||
btn.style.backgroundColor = "#ff6b6b";
|
||||
console.log(`Restored friendly status refresh (${interval}s)`);
|
||||
}
|
||||
}
|
||||
|
||||
// Restore enemy faction
|
||||
if (state.enemy_faction_id && state.enemy_members && state.enemy_members.length > 0) {
|
||||
document.getElementById("enemy-id").value = state.enemy_faction_id;
|
||||
|
||||
// Load members into UI
|
||||
for (const m of state.enemy_members) {
|
||||
const newMember = {
|
||||
id: m.id,
|
||||
name: m.name,
|
||||
level: m.level,
|
||||
estimate: m.estimate,
|
||||
status: m.status || "Unknown",
|
||||
hits: m.hits || 0,
|
||||
domElement: null
|
||||
};
|
||||
enemyMembers.set(m.id, newMember);
|
||||
const card = createMemberCard(newMember, "enemy");
|
||||
enemyContainer.appendChild(card);
|
||||
}
|
||||
console.log(`Restored ${state.enemy_members.length} enemy members`);
|
||||
|
||||
// Restore status refresh if it was running
|
||||
if (state.enemy_status_running) {
|
||||
const interval = state.enemy_status_interval || 10;
|
||||
document.getElementById("enemy-refresh-interval").value = interval;
|
||||
|
||||
const btn = document.getElementById("enemy-status-btn");
|
||||
enemyStatusIntervalHandle = setInterval(() => refreshStatus("enemy"), interval * 1000);
|
||||
refreshStatus("enemy");
|
||||
btn.textContent = "Stop";
|
||||
btn.dataset.running = "true";
|
||||
btn.style.backgroundColor = "#ff6b6b";
|
||||
console.log(`Restored enemy status refresh (${interval}s)`);
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh assignments after restoring members
|
||||
if ((state.friendly_members && state.friendly_members.length > 0) ||
|
||||
(state.enemy_members && state.enemy_members.length > 0)) {
|
||||
await pollAssignments();
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
console.error("Error restoring dashboard state:", err);
|
||||
console.error("Error stack:", err.stack);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
// Initial load
|
||||
// ---------------------------
|
||||
@@ -772,9 +914,9 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
console.log(">>> DOMContentLoaded fired");
|
||||
wireUp();
|
||||
|
||||
// DON'T load members on initial page load - wait for user to click Populate
|
||||
// This prevents showing stale data from server STATE
|
||||
// Restore previous state from server (faction IDs, members, status refresh)
|
||||
await restoreDashboardState();
|
||||
|
||||
// Start polling for assignments (but there won't be any until members are populated)
|
||||
// Start polling for assignments
|
||||
startAssignmentsPolling();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user