From c9dc9772047d1883e0558c5d2dd26a021779b40a Mon Sep 17 00:00:00 2001 From: Ayzen Date: Tue, 30 Sep 2025 14:15:25 +0300 Subject: [PATCH] refactoring step 2 --- vna_system/web_ui/static/js/main.js | 24 +++---- .../web_ui/static/js/modules/acquisition.js | 18 +++--- vna_system/web_ui/static/js/modules/charts.js | 62 +++++++++---------- .../web_ui/static/js/modules/notifications.js | 22 +++---- .../web_ui/static/js/modules/settings.js | 28 ++++----- .../web_ui/static/js/modules/storage.js | 60 +++++++++--------- vna_system/web_ui/static/js/modules/ui.js | 14 ++--- vna_system/web_ui/static/js/modules/utils.js | 38 ++---------- .../web_ui/static/js/modules/websocket.js | 56 ++++++++--------- 9 files changed, 148 insertions(+), 174 deletions(-) diff --git a/vna_system/web_ui/static/js/main.js b/vna_system/web_ui/static/js/main.js index ff35a4e..33b941b 100644 --- a/vna_system/web_ui/static/js/main.js +++ b/vna_system/web_ui/static/js/main.js @@ -63,7 +63,7 @@ class VNADashboard { */ async init() { try { - console.log('🚀 Initializing VNA Dashboard...'); + console.log('Initializing VNA Dashboard...'); // Initialize Lucide icons if (typeof lucide !== 'undefined') { @@ -80,7 +80,7 @@ class VNADashboard { await this.websocket.connect(); this.isInitialized = true; - console.log('✅ VNA Dashboard initialized successfully'); + console.log('VNA Dashboard initialized successfully'); // Show welcome notification this.notifications.show({ @@ -90,7 +90,7 @@ class VNADashboard { }); } catch (error) { - console.error('❌ Failed to initialize VNA Dashboard:', error); + console.error('Failed to initialize VNA Dashboard:', error); this.notifications.show({ type: 'error', title: 'Initialization Failed', @@ -148,7 +148,7 @@ class VNADashboard { setupUIHandlers() { // Navigation this.ui.onViewChange((view) => { - console.log(`📱 Switched to view: ${view}`); + console.log(` Switched to view: ${view}`); if (view === 'settings') { this.settings.refresh(); } @@ -156,7 +156,7 @@ class VNADashboard { // Processor toggles (UI-only visibility) this.ui.onProcessorToggle((processor, enabled) => { - console.log(`🔧 Processor ${processor}: ${enabled ? 'enabled' : 'disabled'}`); + console.log(` Processor ${processor}: ${enabled ? 'enabled' : 'disabled'}`); this.charts.toggleProcessor(processor, enabled); this.savePreferences(); }); @@ -171,7 +171,7 @@ class VNADashboard { if (data.type === 'system_status') { this.ui.updateSystemStatus(data.data); } else if (data.type === 'processor_history') { - console.log('📜 Received processor history:', data); + console.log('Received processor history:', data); } // Note: 'error' is handled by WebSocket manager directly } @@ -247,7 +247,7 @@ class VNADashboard { } } } catch (error) { - console.warn('⚠️ Error applying preferences:', error); + console.warn('Error applying preferences:', error); } } @@ -263,7 +263,7 @@ class VNADashboard { }; await this.storage.savePreferences(preferences); } catch (error) { - console.warn('⚠️ Failed to save preferences:', error); + console.warn('Failed to save preferences:', error); } } @@ -282,7 +282,7 @@ class VNADashboard { destroy() { if (!this.isInitialized) return; - console.log('🧹 Cleaning up VNA Dashboard...'); + console.log('Cleaning up VNA Dashboard...'); document.removeEventListener('visibilitychange', this.handleVisibilityChange); window.removeEventListener('beforeunload', this.handleBeforeUnload); @@ -295,7 +295,7 @@ class VNADashboard { this.notifications.destroy(); this.isInitialized = false; - console.log('✅ VNA Dashboard cleanup complete'); + console.log('VNA Dashboard cleanup complete'); } } @@ -312,11 +312,11 @@ if (document.readyState === 'loading') { // Global error handling window.addEventListener('error', (event) => { - console.error('🚨 Global error:', event.error); + console.error('Global error:', event.error); }); window.addEventListener('unhandledrejection', (event) => { - console.error('🚨 Unhandled promise rejection:', event.reason); + console.error('Unhandled promise rejection:', event.reason); }); // Development helpers diff --git a/vna_system/web_ui/static/js/modules/acquisition.js b/vna_system/web_ui/static/js/modules/acquisition.js index a456358..9d930bf 100644 --- a/vna_system/web_ui/static/js/modules/acquisition.js +++ b/vna_system/web_ui/static/js/modules/acquisition.js @@ -63,14 +63,14 @@ export class AcquisitionManager { const result = await response.json(); if (result.success) { - this.notifications.show({type: 'success', message: result.message}); + this.notifications.show({type: 'success', title: 'Acquisition Started', message: result.message}); await this.updateStatus(); } else { - this.notifications.show({type: 'error', message: result.error || 'Failed to start acquisition'}); + this.notifications.show({type: 'error', title: 'Start Failed', message: result.error || 'Failed to start acquisition'}); } } catch (error) { console.error('Error starting acquisition:', error); - this.notifications.show({type: 'error', message: 'Failed to start acquisition'}); + this.notifications.show({type: 'error', title: 'Start Failed', message: 'Failed to start acquisition'}); } finally { setButtonLoading(this.elements.startBtn, false, originalState); } @@ -88,14 +88,14 @@ export class AcquisitionManager { const result = await response.json(); if (result.success) { - this.notifications.show({type: 'success', message: result.message}); + this.notifications.show({type: 'success', title: 'Acquisition Stopped', message: result.message}); await this.updateStatus(); } else { - this.notifications.show({type: 'error', message: result.error || 'Failed to stop acquisition'}); + this.notifications.show({type: 'error', title: 'Stop Failed', message: result.error || 'Failed to stop acquisition'}); } } catch (error) { console.error('Error stopping acquisition:', error); - this.notifications.show({type: 'error', message: 'Failed to stop acquisition'}); + this.notifications.show({type: 'error', title: 'Stop Failed', message: 'Failed to stop acquisition'}); } finally { setButtonLoading(this.elements.stopBtn, false, originalState); } @@ -113,14 +113,14 @@ export class AcquisitionManager { const result = await response.json(); if (result.success) { - this.notifications.show({type: 'success', message: result.message}); + this.notifications.show({type: 'success', title: 'Single Sweep', message: result.message}); await this.updateStatus(); } else { - this.notifications.show({type: 'error', message: result.error || 'Failed to trigger single sweep'}); + this.notifications.show({type: 'error', title: 'Single Sweep Failed', message: result.error || 'Failed to trigger single sweep'}); } } catch (error) { console.error('Error triggering single sweep:', error); - this.notifications.show({type: 'error', message: 'Failed to trigger single sweep'}); + this.notifications.show({type: 'error', title: 'Single Sweep Failed', message: 'Failed to trigger single sweep'}); } finally { setButtonLoading(this.elements.singleSweepBtn, false, originalState); } diff --git a/vna_system/web_ui/static/js/modules/charts.js b/vna_system/web_ui/static/js/modules/charts.js index 646f345..9c8f236 100644 --- a/vna_system/web_ui/static/js/modules/charts.js +++ b/vna_system/web_ui/static/js/modules/charts.js @@ -68,31 +68,31 @@ export class ChartManager { } async init() { - console.log('📊 Initializing Chart Manager...'); + console.log('Initializing Chart Manager...'); this.chartsGrid = document.getElementById('chartsGrid'); this.emptyState = document.getElementById('emptyState'); if (!this.chartsGrid || !this.emptyState) throw new Error('Required DOM elements not found'); if (typeof Plotly === 'undefined') throw new Error('Plotly.js not loaded'); - console.log('✅ Chart Manager initialized'); + console.log('Chart Manager initialized'); } - /** Новый входной формат — прямо payload от WS: processor_result */ + /** New input format - direct payload from WS: processor_result */ addResult(payload) { try { const { processor_id, timestamp, plotly_config, metadata, data } = payload; if (!processor_id) { - console.warn('⚠️ Invalid result - missing processor_id:', payload); + console.warn('Invalid result - missing processor_id:', payload); return; } if (this.disabledProcessors.has(processor_id)) { - console.log(`⏸️ Skipping disabled processor: ${processor_id}`); + console.log(` Skipping disabled processor: ${processor_id}`); return; } // Store only the latest data (no history needed) this.chartData.set(processor_id, { - timestamp: new Date((timestamp ?? Date.now()) * 1000), // если приходит epoch seconds + timestamp: new Date((timestamp ?? Date.now()) * 1000), // if timestamp is in epoch seconds metadata: metadata || {}, data: data || {}, plotly_config: plotly_config || { data: [], layout: {} } @@ -103,7 +103,7 @@ export class ChartManager { this.updateChart(processor_id, plotly_config || { data: [], layout: {} }); this.hideEmptyState(); } catch (e) { - console.error('❌ Error adding chart result:', e); + console.error('Error adding chart result:', e); this.notifications?.show?.({ type: 'error', title: 'Chart Error', message: `Failed to update chart` }); @@ -111,7 +111,7 @@ export class ChartManager { } createChart(processorId) { - console.log(`📊 Creating chart for processor: ${processorId}`); + console.log(` Creating chart for processor: ${processorId}`); const card = this.createChartCard(processorId); this.chartsGrid.appendChild(card); @@ -144,7 +144,7 @@ export class ChartManager { if (this.isPaused) return; const chart = this.charts.get(processorId); - if (!chart?.plotContainer) { console.warn(`⚠️ Chart not found for processor: ${processorId}`); return; } + if (!chart?.plotContainer) { console.warn(` Chart not found for processor: ${processorId}`); return; } try { const start = performance.now(); @@ -172,7 +172,7 @@ export class ChartManager { this.updatePerformanceStats(dt); }); } catch (e) { - console.error(`❌ Error updating chart ${processorId}:`, e); + console.error(` Error updating chart ${processorId}:`, e); } } @@ -187,7 +187,7 @@ export class ChartManager { while (this.updateQueue.size > 0 && !this.isPaused) { const [id, fn] = this.updateQueue.entries().next().value; this.updateQueue.delete(id); - try { await fn(); } catch (e) { console.error(`❌ Error in queued update for ${id}:`, e); } + try { await fn(); } catch (e) { console.error(` Error in queued update for ${id}:`, e); } await new Promise(r => setTimeout(r, 0)); } this.isUpdating = false; @@ -297,11 +297,11 @@ export class ChartManager { JSON.stringify(uiParameters) !== JSON.stringify(chart.lastUiParameters); if (!parametersChanged) { - console.log(`⚪ No parameter changes for ${processorId}, skipping settings update`); + console.log(` No parameter changes for ${processorId}, skipping settings update`); return; // No need to update if parameters haven't changed } - console.log(`🔄 Updating settings for ${processorId}:`, { + console.log(` Updating settings for ${processorId}:`, { old: chart.lastUiParameters, new: uiParameters }); @@ -341,7 +341,7 @@ export class ChartManager { uiParameters.forEach(param => { const settingKey = `${processorId}_${param.name}`; this.lastSettingValues[settingKey] = param.value; - console.log(`💾 Initialized setting value: ${settingKey} = ${param.value}`); + console.log(` Initialized setting value: ${settingKey} = ${param.value}`); }); } @@ -396,7 +396,7 @@ export class ChartManager { value = value === 'true'; } - console.log(`🔧 Chart setting changed: ${processorId}.${paramName} = ${value}`); + console.log(` Chart setting changed: ${processorId}.${paramName} = ${value}`); // Store the current setting value to prevent loops if (!this.lastSettingValues) this.lastSettingValues = {}; @@ -410,7 +410,7 @@ export class ChartManager { // Check if this is the same value we just set to prevent feedback loop if (lastValue === value) { - console.log(`🔄 Skipping duplicate setting: ${settingKey} = ${value} (was ${this.lastSettingValues[settingKey]})`); + console.log(` Skipping duplicate setting: ${settingKey} = ${value} (was ${this.lastSettingValues[settingKey]})`); return; } @@ -425,13 +425,13 @@ export class ChartManager { } this.settingDebounceTimers[debounceKey] = setTimeout(() => { - console.log(`📤 Sending setting update: ${processorId}.${paramName} = ${value}`); + console.log(` Sending setting update: ${processorId}.${paramName} = ${value}`); // Send update via WebSocket const websocket = window.vnaDashboard?.websocket; if (websocket && websocket.recalculate) { websocket.recalculate(processorId, { [paramName]: value }); } else { - console.warn('⚠️ WebSocket not available for settings update'); + console.warn('WebSocket not available for settings update'); } delete this.settingDebounceTimers[debounceKey]; }, 300); // 300ms delay to prevent rapid updates @@ -445,17 +445,17 @@ export class ChartManager { const paramName = button.dataset.param; if (!paramName) { - console.warn('⚠️ Button missing param data:', button); + console.warn('Button missing param data:', button); return; } // Prevent multiple clicks while processing if (button.disabled) { - console.log('🔘 Button already processing, ignoring click'); + console.log('Button already processing, ignoring click'); return; } - console.log(`🔘 Button clicked: ${processorId}.${paramName}`); + console.log(` Button clicked: ${processorId}.${paramName}`); // Temporarily disable button and show feedback const originalText = button.textContent; @@ -465,10 +465,10 @@ export class ChartManager { // Send button action via WebSocket (set to true to trigger action) - only once const websocket = window.vnaDashboard?.websocket; if (websocket && websocket.recalculate) { - console.log(`📤 Sending button action: ${processorId}.${paramName} = true`); + console.log(` Sending button action: ${processorId}.${paramName} = true`); websocket.recalculate(processorId, { [paramName]: true }); } else { - console.warn('⚠️ WebSocket not available for button action'); + console.warn('WebSocket not available for button action'); } // Re-enable button after a short delay @@ -543,7 +543,7 @@ export class ChartManager { message: `Downloaded ${formatProcessorName(id)} plot and data` }); } catch (e) { - console.error('❌ Chart download failed:', e); + console.error('Chart download failed:', e); this.notifications?.show?.({ type: 'error', title: 'Download Failed', @@ -620,7 +620,7 @@ export class ChartManager { return rawData; } catch (error) { - console.warn('⚠️ Error extracting processor raw data:', error); + console.warn('Error extracting processor raw data:', error); return { error: 'Failed to extract raw data' }; } } @@ -681,8 +681,8 @@ export class ChartManager { this.performanceStats.avgUpdateTime = total / this.performanceStats.updatesProcessed; } - pause() { this.isPaused = true; console.log('⏸️ Chart updates paused'); } - resume() { this.isPaused = false; console.log('▶️ Chart updates resumed'); if (this.updateQueue.size) this.processUpdateQueue(); } + pause() { this.isPaused = true; console.log('Chart updates paused'); } + resume() { this.isPaused = false; console.log('Chart updates resumed'); if (this.updateQueue.size) this.processUpdateQueue(); } /** @@ -706,7 +706,7 @@ export class ChartManager { } }; } catch (error) { - console.warn(`⚠️ Could not extract Plotly data for ${processorId}:`, error); + console.warn(` Could not extract Plotly data for ${processorId}:`, error); return null; } } @@ -760,7 +760,7 @@ export class ChartManager { return { data, layout }; } catch (error) { - console.warn(`⚠️ Could not extract safe Plotly data for ${processorId}:`, error); + console.warn(` Could not extract safe Plotly data for ${processorId}:`, error); return null; } } @@ -790,11 +790,11 @@ export class ChartManager { } destroy() { - console.log('🧹 Cleaning up Chart Manager...'); + console.log('Cleaning up Chart Manager...'); this.clearAll(); this.updateQueue.clear(); this.isUpdating = false; this.isPaused = true; - console.log('✅ Chart Manager cleanup complete'); + console.log('Chart Manager cleanup complete'); } } diff --git a/vna_system/web_ui/static/js/modules/notifications.js b/vna_system/web_ui/static/js/modules/notifications.js index 906c097..6d4a5aa 100644 --- a/vna_system/web_ui/static/js/modules/notifications.js +++ b/vna_system/web_ui/static/js/modules/notifications.js @@ -59,7 +59,7 @@ export class NotificationManager { document.body.appendChild(this.container); } - console.log('📢 Notification Manager initialized'); + console.log('Notification Manager initialized'); } /** @@ -68,7 +68,7 @@ export class NotificationManager { show(options) { // Validate options if (!options || typeof options !== 'object') { - console.warn('⚠️ Invalid notification options:', options); + console.warn('Invalid notification options:', options); return null; } @@ -76,7 +76,7 @@ export class NotificationManager { // Don't show notification if both title and message are empty if (!title && !message) { - console.warn('⚠️ Skipping notification with empty title and message'); + console.warn('Skipping notification with empty title and message'); return null; } @@ -86,7 +86,7 @@ export class NotificationManager { const lastShown = this.recentNotifications.get(notificationKey); if (lastShown && (now - lastShown) < 2000) { - console.log('🔄 Skipping duplicate notification:', notificationKey); + console.log('Skipping duplicate notification:', notificationKey); return null; // Skip duplicate notification } @@ -169,7 +169,7 @@ export class NotificationManager { lucide.createIcons({ attrs: { 'stroke-width': 1.5 } }); } - console.log(`📢 Showing ${notification.type} notification:`, notification.title); + console.log(` Showing ${notification.type} notification:`, notification.title); } /** @@ -249,7 +249,7 @@ export class NotificationManager { try { actionConfig.handler(notification); } catch (error) { - console.error('❌ Error in notification action handler:', error); + console.error('Error in notification action handler:', error); } } @@ -285,7 +285,7 @@ export class NotificationManager { const notification = this.notifications.get(id); if (!notification) return; - console.log(`📢 Dismissing notification: ${id}`); + console.log(` Dismissing notification: ${id}`); // Clear timer if (notification.timer) { @@ -312,7 +312,7 @@ export class NotificationManager { * Dismiss all notifications */ dismissAll() { - console.log('📢 Dismissing all notifications'); + console.log('Dismissing all notifications'); for (const id of this.notifications.keys()) { this.dismiss(id); @@ -323,7 +323,7 @@ export class NotificationManager { * Dismiss notifications by type */ dismissByType(type) { - console.log(`📢 Dismissing all ${type} notifications`); + console.log(` Dismissing all ${type} notifications`); for (const notification of this.notifications.values()) { if (notification.type === type) { @@ -487,7 +487,7 @@ export class NotificationManager { * Cleanup */ destroy() { - console.log('🧹 Cleaning up Notification Manager...'); + console.log('Cleaning up Notification Manager...'); this.dismissAll(); @@ -495,6 +495,6 @@ export class NotificationManager { this.container.parentNode.removeChild(this.container); } - console.log('✅ Notification Manager cleanup complete'); + console.log('Notification Manager cleanup complete'); } } \ No newline at end of file diff --git a/vna_system/web_ui/static/js/modules/settings.js b/vna_system/web_ui/static/js/modules/settings.js index 97f21bb..55eec18 100644 --- a/vna_system/web_ui/static/js/modules/settings.js +++ b/vna_system/web_ui/static/js/modules/settings.js @@ -71,9 +71,9 @@ export class SettingsManager { await this._loadInitialData(); this.isInitialized = true; - console.log('✅ Settings Manager initialized'); + console.log('Settings Manager initialized'); } catch (err) { - console.error('❌ Settings Manager init failed:', err); + console.error('Settings Manager init failed:', err); this._notify('error', 'Settings Error', 'Failed to initialize settings'); } } @@ -83,7 +83,7 @@ export class SettingsManager { this._resetCalibrationCaptureState(); this._detachEvents(); this.isInitialized = false; - console.log('🧹 Settings Manager destroyed'); + console.log('Settings Manager destroyed'); } async refresh() { @@ -287,7 +287,7 @@ export class SettingsManager { calibrations.forEach(c => { const opt = document.createElement('option'); opt.value = c.name; - opt.textContent = `${c.name} ${c.is_complete ? '✓' : '⚠'}`; + opt.textContent = `${c.name} ${c.is_complete ? '✔' : '?'}`; dd.appendChild(opt); }); @@ -392,7 +392,7 @@ export class SettingsManager { btn.title = 'Standard is currently being captured'; } else if (isCompleted) { btn.classList.add('btn--success'); - btn.innerHTML = ` ${std.toUpperCase()} ✓`; + btn.innerHTML = ` ${std.toUpperCase()}`; btn.disabled = false; btn.title = 'Click to recapture this standard'; } else if (isMissing) { @@ -435,7 +435,7 @@ export class SettingsManager { // Reset reference state this.availableReferences = []; this.currentReference = null; - console.log('🔄 Calibration and reference UI reset after preset change'); + console.log('Calibration and reference UI reset after preset change'); } /* ----------------------------- Event Handlers (UI) ----------------------------- */ @@ -470,10 +470,10 @@ export class SettingsManager { this._notify('success', 'Preset Set', result.message); - // Сброс UI калибровки + // Reset calibration UI this._resetCalibrationStateForPresetChange(); - // Обновить статус + // Update status await this._loadStatus(); } catch (e) { console.error('Set preset failed:', e); @@ -521,7 +521,7 @@ export class SettingsManager { this.debouncer.debounce(key, () => this.reqGuard.runExclusive(key, async () => { try { - // Отметим стандарт как «занят» + // Mark standard as busy this.disabledStandards.add(standard); const btn = document.querySelector(`[data-standard="${standard}"]`); @@ -695,13 +695,13 @@ export class SettingsManager { const modal = this.elements.plotsModal; if (!modal) return; - // Запомним пакет + // Store data package this.currentPlotsData = plotsData; - // Рендер карточек/графиков + // Render cards/plots this._renderCalibrationPlots(plotsData.individual_plots, plotsData.preset); - // Заголовок + // Header const title = modal.querySelector('.modal__title'); if (title) { title.innerHTML = ` @@ -711,10 +711,10 @@ export class SettingsManager { if (typeof lucide !== 'undefined') lucide.createIcons(); } - // Кнопки закрытия/скачивания + // Close/download buttons this._setupModalCloseHandlers(modal); - // Показ + // Display modal.classList.add('modal--active'); document.body.style.overflow = 'hidden'; } diff --git a/vna_system/web_ui/static/js/modules/storage.js b/vna_system/web_ui/static/js/modules/storage.js index bf6f265..04b9524 100644 --- a/vna_system/web_ui/static/js/modules/storage.js +++ b/vna_system/web_ui/static/js/modules/storage.js @@ -16,7 +16,7 @@ export class StorageManager { debug: 'debug_info' }; - console.log(`💾 Storage Manager initialized (${this.isAvailable ? 'available' : 'not available'})`); + console.log(` Storage Manager initialized (${this.isAvailable ? 'available' : 'not available'})`); } /** @@ -29,7 +29,7 @@ export class StorageManager { localStorage.removeItem(test); return true; } catch (e) { - console.warn('⚠️ localStorage not available:', e.message); + console.warn('localStorage not available:', e.message); return false; } } @@ -46,7 +46,7 @@ export class StorageManager { */ async save(key, data) { if (!this.isAvailable) { - console.warn('⚠️ Storage not available, cannot save:', key); + console.warn('Storage not available, cannot save:', key); return false; } @@ -58,24 +58,24 @@ export class StorageManager { }); localStorage.setItem(this.getKey(key), serialized); - console.log(`💾 Saved to storage: ${key}`); + console.log(` Saved to storage: ${key}`); return true; } catch (error) { - console.error('❌ Failed to save to storage:', error); + console.error('Failed to save to storage:', error); // Handle quota exceeded error if (error.name === 'QuotaExceededError') { - console.log('🧹 Storage quota exceeded, cleaning up...'); + console.log('Storage quota exceeded, cleaning up...'); this.cleanup(); // Try again after cleanup try { localStorage.setItem(this.getKey(key), serialized); - console.log(`💾 Saved to storage after cleanup: ${key}`); + console.log(` Saved to storage after cleanup: ${key}`); return true; } catch (retryError) { - console.error('❌ Still failed after cleanup:', retryError); + console.error('Still failed after cleanup:', retryError); } } @@ -88,7 +88,7 @@ export class StorageManager { */ async load(key) { if (!this.isAvailable) { - console.warn('⚠️ Storage not available, cannot load:', key); + console.warn('Storage not available, cannot load:', key); return null; } @@ -102,16 +102,16 @@ export class StorageManager { // Validate structure if (!parsed.data || !parsed.timestamp) { - console.warn('⚠️ Invalid storage data format:', key); + console.warn('Invalid storage data format:', key); this.remove(key); // Clean up invalid data return null; } - console.log(`💾 Loaded from storage: ${key} (${new Date(parsed.timestamp).toLocaleString()})`); + console.log(` Loaded from storage: ${key} (${new Date(parsed.timestamp).toLocaleString()})`); return parsed.data; } catch (error) { - console.error('❌ Failed to load from storage:', error); + console.error('Failed to load from storage:', error); this.remove(key); // Clean up corrupted data return null; } @@ -125,10 +125,10 @@ export class StorageManager { try { localStorage.removeItem(this.getKey(key)); - console.log(`🗑️ Removed from storage: ${key}`); + console.log(` Removed from storage: ${key}`); return true; } catch (error) { - console.error('❌ Failed to remove from storage:', error); + console.error('Failed to remove from storage:', error); return false; } } @@ -142,7 +142,7 @@ export class StorageManager { try { return localStorage.getItem(this.getKey(key)) !== null; } catch (error) { - console.error('❌ Failed to check storage existence:', error); + console.error('Failed to check storage existence:', error); return false; } } @@ -215,7 +215,7 @@ export class StorageManager { if (data && data.expiresAt) { if (Date.now() > data.expiresAt) { - console.log('🕒 Session data expired, removing...'); + console.log('Session data expired, removing...'); await this.remove(this.keys.session); return null; } @@ -278,7 +278,7 @@ export class StorageManager { }; } catch (error) { - console.error('❌ Failed to calculate storage stats:', error); + console.error('Failed to calculate storage stats:', error); return { available: false, error: error.message }; } } @@ -310,7 +310,7 @@ export class StorageManager { async cleanup() { if (!this.isAvailable) return; - console.log('🧹 Cleaning up storage...'); + console.log('Cleaning up storage...'); try { const keysToRemove = []; @@ -339,13 +339,13 @@ export class StorageManager { // Remove identified keys keysToRemove.forEach(key => { localStorage.removeItem(key); - console.log(`🗑️ Cleaned up: ${key}`); + console.log(` Cleaned up: ${key}`); }); - console.log(`🧹 Cleanup complete. Removed ${keysToRemove.length} items.`); + console.log(` Cleanup complete. Removed ${keysToRemove.length} items.`); } catch (error) { - console.error('❌ Cleanup failed:', error); + console.error('Cleanup failed:', error); } } @@ -355,7 +355,7 @@ export class StorageManager { async clearAll() { if (!this.isAvailable) return false; - console.log('🗑️ Clearing all storage data...'); + console.log('Clearing all storage data...'); try { const keysToRemove = []; @@ -373,11 +373,11 @@ export class StorageManager { localStorage.removeItem(key); }); - console.log(`🗑️ Cleared ${keysToRemove.length} items from storage`); + console.log(` Cleared ${keysToRemove.length} items from storage`); return true; } catch (error) { - console.error('❌ Failed to clear storage:', error); + console.error('Failed to clear storage:', error); return false; } } @@ -405,11 +405,11 @@ export class StorageManager { } } - console.log('📤 Exported storage data'); + console.log('Exported storage data'); return exportData; } catch (error) { - console.error('❌ Failed to export data:', error); + console.error('Failed to export data:', error); return null; } } @@ -431,11 +431,11 @@ export class StorageManager { localStorage.setItem(fullKey, JSON.stringify(value)); } - console.log(`📥 Imported ${Object.keys(importData.data).length} items`); + console.log(` Imported ${Object.keys(importData.data).length} items`); return true; } catch (error) { - console.error('❌ Failed to import data:', error); + console.error('Failed to import data:', error); return false; } } @@ -444,10 +444,10 @@ export class StorageManager { * Cleanup on destroy */ destroy() { - console.log('🧹 Storage Manager cleanup...'); + console.log('Storage Manager cleanup...'); // Perform any necessary cleanup // For now, just run a cleanup to free up space this.cleanup(); - console.log('✅ Storage Manager cleanup complete'); + console.log('Storage Manager cleanup complete'); } } \ No newline at end of file diff --git a/vna_system/web_ui/static/js/modules/ui.js b/vna_system/web_ui/static/js/modules/ui.js index 018e03e..be613d5 100644 --- a/vna_system/web_ui/static/js/modules/ui.js +++ b/vna_system/web_ui/static/js/modules/ui.js @@ -38,7 +38,7 @@ export class UIManager { * Initialize UI Manager */ async init() { - console.log('🎨 Initializing UI Manager...'); + console.log('Initializing UI Manager...'); // Get DOM elements this.findElements(); @@ -59,7 +59,7 @@ export class UIManager { this.websocket.on('processor_result', (payload) => this.onProcessorResult(payload)); } - console.log('✅ UI Manager initialized'); + console.log('UI Manager initialized'); } /** @@ -263,12 +263,12 @@ export class UIManager { } handleResize() { - console.log('📱 Window resized'); + console.log('Window resized'); // Charts handle their own resize } // System status and theme methods simplified - updateSystemStatus(statusData) { console.log('📊 System status:', statusData); } + updateSystemStatus(statusData) { console.log('System status:', statusData); } setTheme(theme) { document.documentElement.setAttribute('data-theme', theme); } getCurrentTheme() { return document.documentElement.getAttribute('data-theme') || 'dark'; } @@ -280,7 +280,7 @@ export class UIManager { if (this.eventHandlers[eventType]) { this.eventHandlers[eventType].forEach(handler => { try { handler(...args); } - catch (error) { console.error(`❌ Error in ${eventType} handler:`, error); } + catch (error) { console.error(` Error in ${eventType} handler:`, error); } }); } } @@ -294,7 +294,7 @@ export class UIManager { } destroy() { - console.log('🧹 Cleaning up UI Manager...'); + console.log('Cleaning up UI Manager...'); // Clear event handlers Object.keys(this.eventHandlers).forEach(key => { @@ -304,6 +304,6 @@ export class UIManager { // Clear processors this.processors.clear(); - console.log('✅ UI Manager cleanup complete'); + console.log('UI Manager cleanup complete'); } } diff --git a/vna_system/web_ui/static/js/modules/utils.js b/vna_system/web_ui/static/js/modules/utils.js index 181eb88..de10c21 100644 --- a/vna_system/web_ui/static/js/modules/utils.js +++ b/vna_system/web_ui/static/js/modules/utils.js @@ -120,47 +120,21 @@ export class ButtonState { } /** - * Set button to loading state with animation + * Set button to disabled state during request * @param {HTMLElement} button - Button element - * @param {boolean} loading - Whether to set loading state + * @param {boolean} loading - Whether to disable button * @param {Object} originalState - Original button state to restore */ export function setButtonLoading(button, loading, originalState = {}) { - if (!button) return; + if (!button) return originalState; if (loading) { - // Save original state if not provided - if (!originalState.text) { - originalState.text = button.textContent; - originalState.icon = button.querySelector('i')?.getAttribute('data-lucide'); + if (!originalState.disabled) { + originalState.disabled = button.disabled; } - button.disabled = true; - button.classList.add('loading'); - - const icon = button.querySelector('i'); - if (icon) { - icon.setAttribute('data-lucide', 'loader-2'); - icon.style.animation = 'spin 1s linear infinite'; - } - - if (window.lucide) { - window.lucide.createIcons(); - } } else { - button.disabled = false; - button.classList.remove('loading'); - - const icon = button.querySelector('i'); - if (icon) { - icon.style.animation = ''; - if (originalState.icon) { - icon.setAttribute('data-lucide', originalState.icon); - if (window.lucide) { - window.lucide.createIcons(); - } - } - } + button.disabled = originalState.disabled || false; } return originalState; diff --git a/vna_system/web_ui/static/js/modules/websocket.js b/vna_system/web_ui/static/js/modules/websocket.js index 8951057..8e0433f 100644 --- a/vna_system/web_ui/static/js/modules/websocket.js +++ b/vna_system/web_ui/static/js/modules/websocket.js @@ -33,7 +33,7 @@ export class WebSocketManager { async connect() { if (this.isConnected || this.isConnecting) { - console.log('🔌 WebSocket already connected/connecting'); + console.log('WebSocket already connected/connecting'); return; } @@ -41,7 +41,7 @@ export class WebSocketManager { this.isConnecting = true; this.emit('connecting'); - console.log(`🔌 Connecting to WebSocket: ${this.config.url}`); + console.log(` Connecting to WebSocket: ${this.config.url}`); this.ws = new WebSocket(this.config.url); this.setupWebSocketEvents(); @@ -49,7 +49,7 @@ export class WebSocketManager { await this.waitForConnection(5000); } catch (error) { this.isConnecting = false; - console.error('❌ WebSocket connection failed:', error); + console.error('WebSocket connection failed:', error); this.handleConnectionError(error); throw error; } @@ -85,7 +85,7 @@ export class WebSocketManager { if (!this.ws) return; this.ws.onopen = (event) => { - console.log('✅ WebSocket connected'); + console.log('WebSocket connected'); this.isConnected = true; this.isConnecting = false; this.reconnectAttempts = 0; @@ -106,7 +106,7 @@ export class WebSocketManager { try { this.handleMessage(event.data); } catch (error) { - console.error('❌ Error processing WebSocket message:', error); + console.error('Error processing WebSocket message:', error); this.notifications?.show?.({ type: 'error', title: 'Message Error', @@ -116,12 +116,12 @@ export class WebSocketManager { }; this.ws.onerror = (error) => { - console.error('❌ WebSocket error:', error); + console.error('WebSocket error:', error); this.handleConnectionError(error); }; this.ws.onclose = (event) => { - console.log('🔌 WebSocket closed:', event.code, event.reason); + console.log('WebSocket closed:', event.code, event.reason); this.handleDisconnection(event); }; } @@ -134,7 +134,7 @@ export class WebSocketManager { try { if (typeof data !== 'string') { - console.warn('⚠️ Received non-text message, ignoring'); + console.warn('Received non-text message, ignoring'); return; } if (data === 'ping') { this.handlePing(); return; } @@ -144,7 +144,7 @@ export class WebSocketManager { try { payload = JSON.parse(data); } catch (jsonError) { - console.error('❌ Invalid JSON format:', data); + console.error('Invalid JSON format:', data); console.error('JSON parse error:', jsonError); this.notifications?.show?.({ type: 'error', @@ -154,7 +154,7 @@ export class WebSocketManager { return; } - // Публичное событие «data» — для всего, плюс более точечные: + // Public "data" event for everything, plus more specific ones: this.emit('data', payload); switch (payload.type) { @@ -165,8 +165,8 @@ export class WebSocketManager { this.emit('processor_history', payload); break; case 'error': - console.error('🔴 Server error:', payload); - console.error('🔴 Error details:', { + console.error('Server error:', payload); + console.error('Error details:', { message: payload.message, code: payload.code, details: payload.details, @@ -180,11 +180,11 @@ export class WebSocketManager { }); break; default: - console.warn('⚠️ Unknown payload type:', payload.type); + console.warn('Unknown payload type:', payload.type); } } catch (e) { - console.error('❌ Failed to parse WebSocket JSON:', e); - console.log('📝 Raw message:', data); + console.error('Failed to parse WebSocket JSON:', e); + console.log('Raw message:', data); this.notifications?.show?.({ type: 'error', title: 'Message Processing Error', @@ -205,7 +205,7 @@ export class WebSocketManager { } handlePong() { if (this.lastPing) { - console.log(`🏓 WebSocket latency: ${Date.now() - this.lastPing}ms`); + console.log(` WebSocket latency: ${Date.now() - this.lastPing}ms`); this.lastPing = null; } } @@ -251,7 +251,7 @@ export class WebSocketManager { scheduleReconnect() { if (this.reconnectTimer) return; const delay = Math.min(this.config.reconnectInterval * Math.pow(2, this.reconnectAttempts), 30000); - console.log(`🔄 Scheduling reconnect in ${delay}ms (attempt ${this.reconnectAttempts + 1})`); + console.log(` Scheduling reconnect in ${delay}ms (attempt ${this.reconnectAttempts + 1})`); this.reconnectTimer = setTimeout(() => { this.reconnectTimer = null; this.reconnect(); @@ -260,7 +260,7 @@ export class WebSocketManager { async reconnect() { if (this.reconnectAttempts >= this.config.maxReconnectAttempts) { - console.error('❌ Max reconnection attempts reached'); + console.error('Max reconnection attempts reached'); this.notifications?.show?.({ type: 'error', title: 'Connection Failed', @@ -271,16 +271,16 @@ export class WebSocketManager { this.reconnectAttempts++; if (this.ws) { this.ws.close(); this.ws = null; } try { await this.connect(); } - catch (error) { console.error(`❌ Reconnection attempt ${this.reconnectAttempts} failed:`, error); this.scheduleReconnect(); } + catch (error) { console.error(` Reconnection attempt ${this.reconnectAttempts} failed:`, error); this.scheduleReconnect(); } } send(data) { if (!this.isConnected || !this.ws) { if (this.messageQueue.length < this.maxQueueSize) { this.messageQueue.push(data); - console.log('📤 Message queued (not connected)'); + console.log('Message queued (not connected)'); } else { - console.warn('⚠️ Message queue full, dropping message'); + console.warn('Message queue full, dropping message'); } return false; } @@ -289,22 +289,22 @@ export class WebSocketManager { this.ws.send(msg); return true; } catch (e) { - console.error('❌ Failed to send message:', e); + console.error('Failed to send message:', e); return false; } } processPendingMessages() { if (this.messageQueue.length === 0) return; - console.log(`📤 Processing ${this.messageQueue.length} queued messages`); + console.log(` Processing ${this.messageQueue.length} queued messages`); const messages = [...this.messageQueue]; this.messageQueue = []; messages.forEach(m => this.send(m)); } - // === ПУБЛИЧНОЕ API ДЛЯ СОВМЕСТИМОСТИ С БЭКЕНДОМ === + // === PUBLIC API FOR BACKEND COMPATIBILITY === - /** Запросить пересчёт с обновлением конфигурации (СУЩЕСТВУЕТ НА БЭКЕНДЕ) */ + /** Request recalculation with config update (EXISTS ON BACKEND) */ recalculate(processorId, configUpdates = undefined) { return this.send({ type: 'recalculate', @@ -313,7 +313,7 @@ export class WebSocketManager { }); } - /** Получить историю результатов процессора (СУЩЕСТВУЕТ НА БЭКЕНДЕ) */ + /** Get processor results history (EXISTS ON BACKEND) */ getHistory(processorId, limit = 10) { return this.send({ type: 'get_history', @@ -336,12 +336,12 @@ export class WebSocketManager { emit(event, data) { if (!this.eventListeners.has(event)) return; this.eventListeners.get(event).forEach(cb => { - try { cb(data); } catch (e) { console.error(`❌ Error in event listener for ${event}:`, e); } + try { cb(data); } catch (e) { console.error(` Error in event listener for ${event}:`, e); } }); } disconnect() { - console.log('🔌 Disconnecting WebSocket'); + console.log('Disconnecting WebSocket'); if (this.reconnectTimer) { clearTimeout(this.reconnectTimer); this.reconnectTimer = null; } if (this.pingTimer) { clearInterval(this.pingTimer); this.pingTimer = null; } if (this.ws) { this.ws.close(1000, 'Manual disconnect'); this.ws = null; }