// --- Global State Variables --- // MOVED chart instances to chartManager.js // let chartInstancesScada = {}; // Separate instances for SCADA // let chartInstancesDrawing = {}; // Separate instances for Drawing let currentProjectData = {}; // Stores the LATEST full data received from SSE { project: {status, commit, progress}, ... } let selectedProjectName = null; // Track the currently selected project (string) let selectedProject = null; // Duplicate of selectedProjectName? Keep for now, investigate later. // MOVED to modalManager.js // let detailsModalInstance = null; // Bootstrap modal instance for the details popup let currentVisibleSection = 'scada'; // Track visible section: 'scada', 'drawings', 'conflicts' let eventSource = null; // Reference to the SSE EventSource object let initialStatuses = {}; // Initial statuses passed from server (if any) let isAnalysisGloballyActive = false; // NEW: Flag to indicate if *any* background analysis/check might be running // Map backend list keys for modal clicks const scadaListKeysMap = { found: ['found_both_list', 'found_scada_only_list'], notFound: ['found_drawing_only_list', 'missing_list'] }; const drawingListKeysMap = { found: ['found_both_list', 'found_drawing_only_list'], notFound: ['found_scada_only_list', 'missing_list'] }; // --- Utility Functions --- // Debounce function to limit the rate at which a function can fire. function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } // Checks if the status message indicates ongoing processing function isProcessing(statusMsg) { if (!statusMsg) return false; // Handle undefined/null status const lowerStatus = statusMsg.toLowerCase(); // --- Keywords that indicate FINAL/NON-PROCESSING states --- // (Return false immediately if any of these are found) if (lowerStatus.includes('analysis complete') || lowerStatus.includes('no changes') || // Covers "Checked repo... No changes." lowerStatus.includes('error') || // Any error message is a final state lowerStatus.includes('warning') || // Warnings are usually non-processing lowerStatus.includes('n/a') || // Not applicable / initial state before selection lowerStatus.includes('no project') || // No project selected state lowerStatus.includes('updated successfully') || // Manifest/PDF upload success lowerStatus.includes('deleted successfully') // PDF/Project deletion success ) { return false; } // --- Keywords indicating ACTIVE processing --- // (Return true if any of these are found AFTER checking final states) return lowerStatus.includes('initializ') || // initializing, initial... lowerStatus.includes('cloning') || lowerStatus.includes('fetching') || lowerStatus.includes('pulling') || lowerStatus.includes('checking') || // checking repo, checking scada, checking drawings (but NOT "Checked repo... no changes") lowerStatus.includes('reading manifest') || lowerStatus.includes('calculating') || lowerStatus.includes('extracting') || // If PDF extraction status is sent lowerStatus.includes('loading data') || // From handleProjectChange initial state lowerStatus.includes('pending') || // e.g., Re-analysis pending lowerStatus.includes('triggered'); // e.g., Manual analysis triggered... } // Function to update the selected project state globally function setSelectedProject(projectName) { selectedProjectName = projectName; selectedProject = projectName; // Keep both synced for now console.log(`[State] Selected project updated to: ${selectedProjectName}`); } // --- Export (if using modules in the future) --- // export { chartInstancesScada, chartInstancesDrawing, currentProjectData, selectedProjectName, ... }; // For now, these are global, but designed for future modularity.