const RadiusAVMScanner = { name: 'RadiusAVMScanner', template: `
Scan läuft... {{ state.progress?.current || 0 }} / {{ state.progress?.total || 0 }}
Aktuell: {{ state.currentDevice.mac }} ({{ state.currentDevice.ip }})
{{ filteredDevices.length }} von {{ state.devices.length }} Geräten Keine Geräte
`, data: () => ({ window: window, state: null, isLoading: false, polling: null, deviceTypeFilter: '', showErledigt: true }), computed: { progressPercent() { if (!this.state?.progress?.total) return 0; return Math.round((this.state.progress.current / this.state.progress.total) * 100); }, deviceTypes() { if (!this.state?.devices) return []; const types = new Set(); this.state.devices.forEach(d => { if (d.deviceType) types.add(d.deviceType); }); return Array.from(types).sort(); }, filteredDevices() { if (!this.state?.devices) return []; return this.state.devices.filter(d => { if (this.deviceTypeFilter && d.deviceType !== this.deviceTypeFilter) return false; if (!this.showErledigt && d.erledigt) return false; return true; }); } }, methods: { initIfNeeded() { this.refreshState(); }, startPolling() { if (this.polling) return; this.polling = setInterval(() => { this.refreshState(true); }, 3000); // Poll every 3 seconds }, stopPolling() { if (this.polling) { clearInterval(this.polling); this.polling = null; } }, async refreshState(silent = false) { if (!silent) this.isLoading = true; try { const { data } = await axios.get(`${window.TT_CONFIG.BASE_PATH}/Radius/avmScannerGetState`); this.state = data; // Start/stop polling based on scanning state if (data.scanning && !this.polling) { this.startPolling(); } else if (!data.scanning && this.polling) { this.stopPolling(); } } catch (e) { console.error('Failed to fetch AVM scanner state:', e); } if (!silent) this.isLoading = false; }, async startScan() { try { const { data } = await axios.post(`${window.TT_CONFIG.BASE_PATH}/Radius/avmScannerStart`); if (data.success) { window.notify('success', `Scan gestartet für ${data.total} Geräte`); this.startPolling(); // Start polling immediately } else { window.notify('warning', data.message || 'Scan konnte nicht gestartet werden'); } this.refreshState(); } catch (e) { console.error('Failed to start scan:', e); window.notify('error', 'Fehler beim Starten des Scans'); } }, async stopScan() { try { const { data } = await axios.post(`${window.TT_CONFIG.BASE_PATH}/Radius/avmScannerStop`); if (data.success) { window.notify('info', 'Scan wird gestoppt...'); } } catch (e) { console.error('Failed to stop scan:', e); window.notify('error', 'Fehler beim Stoppen des Scans'); } }, async toggleErledigt(mac) { try { await axios.post(`${window.TT_CONFIG.BASE_PATH}/Radius/avmScannerToggleErledigt`, { mac }); this.refreshState(true); } catch (e) { console.error('Failed to toggle erledigt:', e); window.notify('error', 'Fehler beim Aktualisieren'); } }, formatDate(dateStr) { if (!dateStr) return '—'; const d = new Date(dateStr); return d.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' }); } }, beforeUnmount() { this.stopPolling(); } }; if (window.VueApp) { window.VueApp.component('radius-avm-scanner', RadiusAVMScanner); }