// WOL Manager JavaScript let scanModal, addModal, renameModal; // Initialize on page load window.onload = function() { scanModal = document.getElementById('scanModal'); addModal = document.getElementById('addModal'); renameModal = document.getElementById('renameModal'); refreshComputers(); }; function showMessage(message, type) { const messageArea = document.getElementById('message-area'); messageArea.innerHTML = `
${message}
`; setTimeout(() => { messageArea.innerHTML = ''; }, 5000); } function refreshComputers() { fetch('/api/computers') .then(response => response.json()) .then(computers => { displayComputers(computers); }) .catch(error => { showMessage('Eroare la încărcarea calculatoarelor: ' + error.message, 'error'); }); } function displayComputers(computers) { const tbody = document.getElementById('computers-tbody'); const noComputersDiv = document.getElementById('no-computers'); if (computers.length === 0) { tbody.innerHTML = ''; noComputersDiv.style.display = 'block'; return; } noComputersDiv.style.display = 'none'; tbody.innerHTML = computers.map(computer => ` ${computer.name} ${computer.mac} ${computer.ip || '-'} ${computer.status} `).join(''); } function wakeComputer(mac, name, ip) { showMessage(`Se trimite magic packet pentru ${name}...`, 'success'); fetch('/api/wake', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({mac: mac, name: name, ip: ip}) }) .then(response => response.json()) .then(result => { if (result.success) { showMessage(result.message, 'success'); setTimeout(refreshComputers, 2000); } else { showMessage(result.message, 'error'); } }) .catch(error => { showMessage('Eroare la trezirea calculatorului: ' + error.message, 'error'); }); } function wakeAllComputers() { showMessage('Se trezesc toate calculatoarele...', 'success'); fetch('/api/wake-all', { method: 'POST', headers: { 'Content-Type': 'application/json', } }) .then(response => response.json()) .then(data => { let message = 'Comenzi trimise:
'; data.results.forEach(result => { message += `• ${result.name}: ${result.result.message}
`; }); showMessage(message, 'success'); setTimeout(refreshComputers, 3000); }) .catch(error => { showMessage('Eroare la trezirea calculatoarelor: ' + error.message, 'error'); }); } function openAddModal() { addModal.style.display = 'block'; } function closeAddModal() { addModal.style.display = 'none'; document.getElementById('computerName').value = ''; document.getElementById('computerMac').value = ''; document.getElementById('computerIp').value = ''; } function addComputer() { const name = document.getElementById('computerName').value; const mac = document.getElementById('computerMac').value; const ip = document.getElementById('computerIp').value; if (!name || !mac) { showMessage('Numele și MAC-ul sunt obligatorii!', 'error'); return; } fetch('/api/add', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({name: name, mac: mac, ip: ip}) }) .then(response => response.json()) .then(result => { if (result.success) { showMessage(result.message, 'success'); closeAddModal(); refreshComputers(); } else { showMessage(result.message, 'error'); } }) .catch(error => { showMessage('Eroare la adăugarea calculatorului: ' + error.message, 'error'); }); } function toggleCustomNetwork() { const select = document.getElementById('networkSelect'); const customInput = document.getElementById('customNetwork'); if (select.value === 'custom') { customInput.style.display = 'inline'; customInput.focus(); } else { customInput.style.display = 'none'; } } function getSelectedNetwork() { const select = document.getElementById('networkSelect'); const customInput = document.getElementById('customNetwork'); if (select.value === 'custom') { return customInput.value.trim(); } else { return select.value; } } function scanNetwork() { scanModal.style.display = 'block'; document.getElementById('scan-loading').style.display = 'block'; document.getElementById('scan-results').innerHTML = ''; const network = getSelectedNetwork(); const requestData = network ? { network: network } : {}; fetch('/api/scan', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(requestData) }) .then(response => response.json()) .then(result => { document.getElementById('scan-loading').style.display = 'none'; if (result.success) { if (result.computers && result.computers.length > 0) { displayScanResults(result.computers); if (result.message) { // Afișează mesajul deasupra tabelului document.getElementById('scan-results').innerHTML = `
${result.message}
` + document.getElementById('scan-results').innerHTML; } } else if (result.message) { document.getElementById('scan-results').innerHTML = `
${result.message}
`; } } else { document.getElementById('scan-results').innerHTML = `
${result.message}
`; } }) .catch(error => { document.getElementById('scan-loading').style.display = 'none'; document.getElementById('scan-results').innerHTML = `
Eroare la scanare: ${error.message}
`; }); } function triggerWindowsScan() { scanModal.style.display = 'block'; document.getElementById('scan-loading').style.display = 'block'; document.getElementById('scan-results').innerHTML = ''; const network = getSelectedNetwork(); const requestData = network ? { network: network } : {}; showMessage('Declanșând scanul Windows...', 'success'); fetch('/api/scan/windows', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(requestData) }) .then(response => response.json()) .then(data => { document.getElementById('scan-loading').style.display = 'none'; if (data.success && data.computers) { showMessage(data.message || 'Scan Windows completat cu succes!', 'success'); displayScanResults(data.computers); } else { let message = data.message || 'Scanul Windows a eșuat'; if (data.instructions) { message += '

Instrucțiuni:
' + data.instructions; if (data.commands) { message += '
Comenzi disponibile:'; data.commands.forEach(cmd => { message += `
${cmd}`; }); } } showMessage(message, 'error'); document.getElementById('scan-results').innerHTML = '
' + '

Scanul Windows nu poate fi executat din container

' + '

Pentru a scana rețeaua Windows și obține MAC addresses:

' + '
    ' + '
  1. Deschide Command Prompt sau PowerShell ca Administrator pe Windows
  2. ' + '
  3. Navighează la directorul proiectului WOL Manager
  4. ' + '
  5. Rulează una din comenzile de mai jos:
  6. ' + '
' + '
' + (data.commands ? data.commands.map(cmd => `
${cmd}
`).join('') : 'scripts\\scan-network.bat') + '
' + '

După rularea comenzii, apasă "Scanează Rețeaua" pentru a vedea rezultatele.

' + '
'; } }) .catch(error => { document.getElementById('scan-loading').style.display = 'none'; showMessage('Eroare la declanșarea scanului Windows: ' + error.message, 'error'); console.error('Error:', error); }); } function displayScanResults(computers) { if (computers.length === 0) { document.getElementById('scan-results').innerHTML = '
Nu s-au găsit calculatoare în rețea
'; return; } let html = `
`; computers.forEach((computer, index) => { html += ` `; }); html += '
Selectează IP MAC Hostname Status Acțiune
${computer.ip} ${computer.mac} ${computer.hostname} ${computer.status}
'; document.getElementById('scan-results').innerHTML = html; } function toggleSelectAll() { const selectAllCheckbox = document.getElementById('selectAll'); const deviceCheckboxes = document.querySelectorAll('.device-checkbox'); deviceCheckboxes.forEach(checkbox => { checkbox.checked = selectAllCheckbox.checked; }); updateAddButton(); } function updateAddButton() { const deviceCheckboxes = document.querySelectorAll('.device-checkbox'); const checkedBoxes = document.querySelectorAll('.device-checkbox:checked'); const addButton = document.querySelector('.add-selected-btn'); const selectAllCheckbox = document.getElementById('selectAll'); // Enable/disable the "Add Selected" button if (addButton) { addButton.disabled = checkedBoxes.length === 0; addButton.textContent = checkedBoxes.length > 0 ? `➕ Adaugă Selectate (${checkedBoxes.length})` : '➕ Adaugă Selectate'; } // Update "Select All" checkbox state if (selectAllCheckbox) { if (checkedBoxes.length === 0) { selectAllCheckbox.indeterminate = false; selectAllCheckbox.checked = false; } else if (checkedBoxes.length === deviceCheckboxes.length) { selectAllCheckbox.indeterminate = false; selectAllCheckbox.checked = true; } else { selectAllCheckbox.indeterminate = true; } } } function addSelectedFromScan() { const checkedBoxes = document.querySelectorAll('.device-checkbox:checked'); if (checkedBoxes.length === 0) { showMessage('Nu ai selectat niciun dispozitiv!', 'error'); return; } const devices = Array.from(checkedBoxes).map(checkbox => ({ name: checkbox.dataset.hostname, mac: checkbox.dataset.mac, ip: checkbox.dataset.ip })); // Show progress message showMessage(`Se adaugă ${devices.length} dispozitive...`, 'success'); // Add devices one by one let addedCount = 0; let failedCount = 0; let duplicateCount = 0; let failedDevices = []; let duplicateDevices = []; const addDevice = (device, index) => { return fetch('/api/add', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(device) }) .then(response => response.json()) .then(result => { if (result.success) { addedCount++; } else { // Verifică dacă este o eroare de duplicat if (result.message.includes('există deja')) { duplicateCount++; duplicateDevices.push(`${device.name} (${result.message})`); } else { failedCount++; failedDevices.push(`${device.name}: ${result.message}`); } console.warn(`Failed to add ${device.name}:`, result.message); } }) .catch(error => { failedCount++; failedDevices.push(`${device.name}: ${error.message}`); console.error(`Error adding ${device.name}:`, error); }); }; // Add all devices in parallel Promise.all(devices.map(addDevice)) .then(() => { let message = ''; let messageType = 'success'; if (addedCount > 0 && failedCount === 0 && duplicateCount === 0) { message = `${addedCount} dispozitive adăugate cu succes!`; } else if (addedCount > 0) { message = `${addedCount} dispozitive adăugate cu succes`; if (duplicateCount > 0) { message += `, ${duplicateCount} duplicate ignorate`; } if (failedCount > 0) { message += `, ${failedCount} eșuate`; } message += '.'; if (duplicateCount > 0 || failedCount > 0) { messageType = 'warning'; } } else { if (duplicateCount > 0 && failedCount === 0) { message = `Toate ${duplicateCount} dispozitivele selectate există deja în sistem.`; messageType = 'warning'; } else if (duplicateCount > 0) { message = `${duplicateCount} dispozitive duplicate, ${failedCount} eșuate.`; messageType = 'error'; } else { message = `Toate ${failedCount} dispozitivele au eșuat să fie adăugate.`; messageType = 'error'; } } // Dacă există duplicate sau erori, afișează detalii suplimentare în consolă if (duplicateDevices.length > 0) { console.info('Dispozitive duplicate:', duplicateDevices); } if (failedDevices.length > 0) { console.warn('Dispozitive eșuate:', failedDevices); } showMessage(message, messageType); if (addedCount > 0) { closeScanModal(); refreshComputers(); } }); } function addFromScan(hostname, mac, ip) { fetch('/api/add', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({name: hostname, mac: mac, ip: ip}) }) .then(response => response.json()) .then(result => { if (result.success) { showMessage(result.message, 'success'); closeScanModal(); refreshComputers(); } else { showMessage(result.message, 'error'); } }) .catch(error => { showMessage('Eroare la adăugarea calculatorului: ' + error.message, 'error'); }); } function closeScanModal() { scanModal.style.display = 'none'; } function openRenameModal(currentName) { document.getElementById('currentName').value = currentName; document.getElementById('newName').value = ''; renameModal.style.display = 'block'; document.getElementById('newName').focus(); } function closeRenameModal() { renameModal.style.display = 'none'; document.getElementById('currentName').value = ''; document.getElementById('newName').value = ''; } function performRename() { const oldName = document.getElementById('currentName').value; const newName = document.getElementById('newName').value.trim(); if (!newName) { showMessage('Numele nou nu poate fi gol!', 'error'); return; } if (oldName === newName) { showMessage('Numele nou trebuie să fie diferit de cel actual!', 'error'); return; } fetch('/api/rename', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({old_name: oldName, new_name: newName}) }) .then(response => response.json()) .then(result => { if (result.success) { showMessage(result.message, 'success'); closeRenameModal(); refreshComputers(); } else { showMessage(result.message, 'error'); } }) .catch(error => { showMessage('Eroare la redenumirea calculatorului: ' + error.message, 'error'); }); } function deleteComputer(name, mac) { const displayName = name && name.trim() ? name : `Calculator cu MAC ${mac}`; if (!confirm(`Sigur vrei să ștergi calculatorul "${displayName}"?`)) { return; } fetch('/api/delete', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({name: name, mac: mac}) }) .then(response => response.json()) .then(result => { if (result.success) { showMessage(result.message, 'success'); refreshComputers(); } else { showMessage(result.message, 'error'); } }) .catch(error => { showMessage('Eroare la ștergerea calculatorului: ' + error.message, 'error'); }); } // Close modals when clicking outside window.onclick = function(event) { if (event.target == addModal) { closeAddModal(); } if (event.target == scanModal) { closeScanModal(); } if (event.target == renameModal) { closeRenameModal(); } } // Allow Enter key to perform rename document.addEventListener('keydown', function(event) { if (event.key === 'Enter' && renameModal.style.display === 'block') { performRename(); } });