adding sync
Deploy / deploy (push) Successful in 39s

This commit is contained in:
2026-05-12 10:29:42 +02:00
parent 0acfff6bc7
commit 13d8420976
+36 -17
View File
@@ -280,6 +280,7 @@ async function loadTeams() {
async function loadEvents() { async function loadEvents() {
events = await apiFetch('events'); events = await apiFetch('events');
syncHashes.events = JSON.stringify(events);
loadAllTags(); loadAllTags();
renderTimeline(); renderTimeline();
} }
@@ -1209,7 +1210,7 @@ function setupCanvasDrop() {
} else { } else {
await apiFetch('nodes', { method: 'POST', body: JSON.stringify({ await apiFetch('nodes', { method: 'POST', body: JSON.stringify({
label: data.charAt(0).toUpperCase() + data.slice(1), label: data.charAt(0).toUpperCase() + data.slice(1),
ip_address: '', node_type: data, status: 'unknown', ip_address: '', node_type: data || 'host', status: 'unknown',
group_name: 'default', notes: '', group_name: 'default', notes: '',
pos_x: mx, pos_y: my pos_x: mx, pos_y: my
})}); })});
@@ -1218,25 +1219,46 @@ function setupCanvasDrop() {
}); });
} }
// Real-time sync: poll backend every 5 seconds only when network tab is visible // Real-time sync: poll backend every 5 seconds for all data
let syncInterval = null; let syncInterval = null;
let lastSyncData = null; let syncHashes = { events: null, documents: null, network: null };
function startSync() { function startSync() {
if (syncInterval) return; if (syncInterval) return;
syncInterval = setInterval(async () => { syncInterval = setInterval(async () => {
const netTab = document.getElementById('network-tab'); // Skip sync if a modal is open (user is editing)
if (!netTab || !netTab.classList.contains('active')) return; const openModals = document.querySelectorAll('.modal.show');
if (openModals.length > 0) return;
try { try {
const [n, l, s] = await Promise.all([ const [eventsData, docsData, nodesData, linksData, shapesData] = await Promise.all([
apiFetch('nodes'), apiFetch('links'), apiFetch('shapes') apiFetch('events'),
apiFetch('documents'),
apiFetch('nodes'),
apiFetch('links'),
apiFetch('shapes'),
]); ]);
const hash = JSON.stringify({ n, l, s });
if (hash !== lastSyncData) { const eventsHash = JSON.stringify(eventsData);
lastSyncData = hash; if (eventsHash !== syncHashes.events) {
nodes = Array.isArray(n) ? n : []; syncHashes.events = eventsHash;
links = Array.isArray(l) ? l : []; events = Array.isArray(eventsData) ? eventsData : [];
shapes = Array.isArray(s) ? s : []; loadAllTags();
renderTimeline();
}
const docsHash = JSON.stringify(docsData);
if (docsHash !== syncHashes.documents) {
syncHashes.documents = docsHash;
documents = Array.isArray(docsData) ? docsData : [];
renderDocuments();
}
const netHash = JSON.stringify({ n: nodesData, l: linksData, s: shapesData });
if (netHash !== syncHashes.network) {
syncHashes.network = netHash;
nodes = Array.isArray(nodesData) ? nodesData : [];
links = Array.isArray(linksData) ? linksData : [];
shapes = Array.isArray(shapesData) ? shapesData : [];
populateNodeSelects(); populateNodeSelects();
renderNodeList(); renderNodeList();
renderShapeList(); renderShapeList();
@@ -1248,10 +1270,6 @@ function startSync() {
}, 5000); }, 5000);
} }
function stopSync() {
if (syncInterval) { clearInterval(syncInterval); syncInterval = null; }
}
function getCanvasNodeAt(mx, my) { function getCanvasNodeAt(mx, my) {
return canvasNodes.find(n => Math.hypot(mx - n.x, my - n.y) < 28); return canvasNodes.find(n => Math.hypot(mx - n.x, my - n.y) < 28);
} }
@@ -1491,6 +1509,7 @@ document.getElementById('registrationToggle').addEventListener('change', saveReg
async function loadDocuments() { async function loadDocuments() {
try { try {
documents = await apiFetch('documents'); documents = await apiFetch('documents');
syncHashes.documents = JSON.stringify(documents);
} catch (e) { } catch (e) {
documents = []; documents = [];
} }