Transform rename button to full edit functionality
- Replace rename modal with comprehensive edit modal supporting name, MAC, and IP changes - Add edit_computer() method with full validation (MAC format, duplicates) - Create new /api/edit endpoint accepting all computer attributes - Update frontend JavaScript for multi-field editing with client-side validation - Rename functions from openRenameModal/performRename to openEditModal/performEdit - Pre-populate edit form with current values and validate MAC address format 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
81
app/app.py
81
app/app.py
@@ -198,6 +198,76 @@ class WOLManager:
|
|||||||
|
|
||||||
return {'success': True, 'message': f'Computerul {deleted_name} a fost șters!'}
|
return {'success': True, 'message': f'Computerul {deleted_name} a fost șters!'}
|
||||||
|
|
||||||
|
def edit_computer(self, old_name, new_name, new_mac, new_ip=None):
|
||||||
|
"""Editează un calculator existent - permite modificarea numelui, MAC-ului și IP-ului"""
|
||||||
|
if not new_name.strip():
|
||||||
|
return {'success': False, 'message': 'Numele nou nu poate fi gol!'}
|
||||||
|
|
||||||
|
if not new_mac.strip():
|
||||||
|
return {'success': False, 'message': 'Adresa MAC nu poate fi goală!'}
|
||||||
|
|
||||||
|
# Validează formatul MAC-ului (XX:XX:XX:XX:XX:XX)
|
||||||
|
import re
|
||||||
|
mac_pattern = r'^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$'
|
||||||
|
if not re.match(mac_pattern, new_mac):
|
||||||
|
return {'success': False, 'message': 'Formatul MAC-ului este invalid! Folosește formatul XX:XX:XX:XX:XX:XX'}
|
||||||
|
|
||||||
|
# Normalizează MAC-ul (lowercase și cu :)
|
||||||
|
new_mac = new_mac.lower().replace('-', ':')
|
||||||
|
|
||||||
|
computers = []
|
||||||
|
found = False
|
||||||
|
old_mac = None
|
||||||
|
|
||||||
|
# Citește toate computerele
|
||||||
|
if os.path.exists(CONFIG_FILE):
|
||||||
|
with open(CONFIG_FILE, 'r') as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if line and not line.startswith('#'):
|
||||||
|
parts = line.split('|')
|
||||||
|
if len(parts) >= 2:
|
||||||
|
if parts[0] == old_name:
|
||||||
|
old_mac = parts[1]
|
||||||
|
found = True
|
||||||
|
# Verifică dacă noul MAC este diferit și nu există deja
|
||||||
|
if new_mac != old_mac.lower():
|
||||||
|
# Verifică dacă noul MAC există deja la alt computer
|
||||||
|
for check_line in computers:
|
||||||
|
if not check_line.startswith('#') and check_line.strip():
|
||||||
|
check_parts = check_line.split('|')
|
||||||
|
if len(check_parts) >= 2 and check_parts[1].lower() == new_mac:
|
||||||
|
return {'success': False, 'message': f'Adresa MAC {new_mac} este deja folosită de alt computer!'}
|
||||||
|
|
||||||
|
# Actualizează computerul cu noile valori
|
||||||
|
new_ip_value = new_ip.strip() if new_ip else ''
|
||||||
|
computers.append(f"{new_name}|{new_mac}|{new_ip_value}")
|
||||||
|
else:
|
||||||
|
# Verifică dacă noul MAC este folosit de alt computer
|
||||||
|
if parts[1].lower() == new_mac and parts[0] != old_name:
|
||||||
|
return {'success': False, 'message': f'Adresa MAC {new_mac} este deja folosită de computerul "{parts[0]}"!'}
|
||||||
|
computers.append(line)
|
||||||
|
else:
|
||||||
|
computers.append(line)
|
||||||
|
|
||||||
|
if not found:
|
||||||
|
return {'success': False, 'message': f'Computerul "{old_name}" nu a fost găsit!'}
|
||||||
|
|
||||||
|
# Verifică dacă noul nume există deja (doar dacă s-a schimbat numele)
|
||||||
|
if new_name != old_name:
|
||||||
|
for computer_line in computers:
|
||||||
|
if not computer_line.startswith('#') and computer_line.strip():
|
||||||
|
parts = computer_line.split('|')
|
||||||
|
if len(parts) >= 2 and parts[0] == new_name and not computer_line.startswith(f"{new_name}|{new_mac}|"):
|
||||||
|
return {'success': False, 'message': f'Numele "{new_name}" este deja folosit de alt computer!'}
|
||||||
|
|
||||||
|
# Rescrie fișierul
|
||||||
|
with open(CONFIG_FILE, 'w') as f:
|
||||||
|
for computer_line in computers:
|
||||||
|
f.write(computer_line + '\n')
|
||||||
|
|
||||||
|
return {'success': True, 'message': f'Computerul a fost actualizat cu succes!'}
|
||||||
|
|
||||||
def scan_network(self, custom_network=None):
|
def scan_network(self, custom_network=None):
|
||||||
try:
|
try:
|
||||||
# Încearcă să citească rezultatele scanului Windows mai întâi
|
# Încearcă să citească rezultatele scanului Windows mai întâi
|
||||||
@@ -398,6 +468,17 @@ def rename_computer():
|
|||||||
)
|
)
|
||||||
return jsonify(result)
|
return jsonify(result)
|
||||||
|
|
||||||
|
@app.route('/api/edit', methods=['POST'])
|
||||||
|
def edit_computer():
|
||||||
|
data = request.get_json()
|
||||||
|
result = wol_manager.edit_computer(
|
||||||
|
data.get('old_name'),
|
||||||
|
data.get('new_name'),
|
||||||
|
data.get('new_mac'),
|
||||||
|
data.get('new_ip')
|
||||||
|
)
|
||||||
|
return jsonify(result)
|
||||||
|
|
||||||
@app.route('/api/delete', methods=['POST'])
|
@app.route('/api/delete', methods=['POST'])
|
||||||
def delete_computer():
|
def delete_computer():
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
// WOL Manager JavaScript
|
// WOL Manager JavaScript
|
||||||
let scanModal, addModal, renameModal;
|
let scanModal, addModal, editModal;
|
||||||
|
|
||||||
// Initialize on page load
|
// Initialize on page load
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
scanModal = document.getElementById('scanModal');
|
scanModal = document.getElementById('scanModal');
|
||||||
addModal = document.getElementById('addModal');
|
addModal = document.getElementById('addModal');
|
||||||
renameModal = document.getElementById('renameModal');
|
editModal = document.getElementById('editModal');
|
||||||
refreshComputers();
|
refreshComputers();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ function displayComputers(computers) {
|
|||||||
<button class="wake-btn" onclick="wakeComputer('${computer.mac}', '${computer.name}', '${computer.ip || ''}')" title="Trezește calculatorul">
|
<button class="wake-btn" onclick="wakeComputer('${computer.mac}', '${computer.name}', '${computer.ip || ''}')" title="Trezește calculatorul">
|
||||||
⚡
|
⚡
|
||||||
</button>
|
</button>
|
||||||
<button class="rename-btn" onclick="openRenameModal('${computer.name}')" title="Redenumește calculatorul">
|
<button class="edit-btn" onclick="openEditModal('${computer.name}', '${computer.mac}', '${computer.ip || ''}')" title="Editează calculatorul">
|
||||||
📝
|
📝
|
||||||
</button>
|
</button>
|
||||||
<button class="delete-btn" onclick="deleteComputer('${computer.name}', '${computer.mac}')" title="Șterge calculatorul">
|
<button class="delete-btn" onclick="deleteComputer('${computer.name}', '${computer.mac}')" title="Șterge calculatorul">
|
||||||
@@ -510,52 +510,69 @@ function closeScanModal() {
|
|||||||
scanModal.style.display = 'none';
|
scanModal.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
function openRenameModal(currentName) {
|
function openEditModal(currentName, currentMac, currentIp) {
|
||||||
document.getElementById('currentName').value = currentName;
|
document.getElementById('editName').value = currentName;
|
||||||
document.getElementById('newName').value = '';
|
document.getElementById('editName').dataset.originalName = currentName;
|
||||||
renameModal.style.display = 'block';
|
document.getElementById('editMac').value = currentMac;
|
||||||
document.getElementById('newName').focus();
|
document.getElementById('editIp').value = currentIp || '';
|
||||||
|
editModal.style.display = 'block';
|
||||||
|
document.getElementById('editName').focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeRenameModal() {
|
function closeEditModal() {
|
||||||
renameModal.style.display = 'none';
|
editModal.style.display = 'none';
|
||||||
document.getElementById('currentName').value = '';
|
document.getElementById('editName').value = '';
|
||||||
document.getElementById('newName').value = '';
|
document.getElementById('editMac').value = '';
|
||||||
|
document.getElementById('editIp').value = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function performRename() {
|
function performEdit() {
|
||||||
const oldName = document.getElementById('currentName').value;
|
const oldName = document.getElementById('editName').dataset.originalName || document.getElementById('editName').value;
|
||||||
const newName = document.getElementById('newName').value.trim();
|
const newName = document.getElementById('editName').value.trim();
|
||||||
|
const newMac = document.getElementById('editMac').value.trim();
|
||||||
|
const newIp = document.getElementById('editIp').value.trim();
|
||||||
|
|
||||||
if (!newName) {
|
if (!newName) {
|
||||||
showMessage('Numele nou nu poate fi gol!', 'error');
|
showMessage('Numele nu poate fi gol!', 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldName === newName) {
|
if (!newMac) {
|
||||||
showMessage('Numele nou trebuie să fie diferit de cel actual!', 'error');
|
showMessage('Adresa MAC nu poate fi goală!', 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch('/api/rename', {
|
// Validare simplă pentru formatul MAC-ului
|
||||||
|
const macPattern = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;
|
||||||
|
if (!macPattern.test(newMac)) {
|
||||||
|
showMessage('Formatul MAC-ului este invalid! Folosește formatul XX:XX:XX:XX:XX:XX', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch('/api/edit', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({old_name: oldName, new_name: newName})
|
body: JSON.stringify({
|
||||||
|
old_name: oldName,
|
||||||
|
new_name: newName,
|
||||||
|
new_mac: newMac,
|
||||||
|
new_ip: newIp
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(result => {
|
.then(result => {
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
showMessage(result.message, 'success');
|
showMessage(result.message, 'success');
|
||||||
closeRenameModal();
|
closeEditModal();
|
||||||
refreshComputers();
|
refreshComputers();
|
||||||
} else {
|
} else {
|
||||||
showMessage(result.message, 'error');
|
showMessage(result.message, 'error');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
showMessage('Eroare la redenumirea calculatorului: ' + error.message, 'error');
|
showMessage('Eroare la editarea calculatorului: ' + error.message, 'error');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -595,14 +612,14 @@ window.onclick = function(event) {
|
|||||||
if (event.target == scanModal) {
|
if (event.target == scanModal) {
|
||||||
closeScanModal();
|
closeScanModal();
|
||||||
}
|
}
|
||||||
if (event.target == renameModal) {
|
if (event.target == editModal) {
|
||||||
closeRenameModal();
|
closeEditModal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow Enter key to perform rename
|
// Allow Enter key to perform edit
|
||||||
document.addEventListener('keydown', function(event) {
|
document.addEventListener('keydown', function(event) {
|
||||||
if (event.key === 'Enter' && renameModal.style.display === 'block') {
|
if (event.key === 'Enter' && editModal.style.display === 'block') {
|
||||||
performRename();
|
performEdit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -100,26 +100,30 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Modal pentru redenumirea calculatoarelor -->
|
<!-- Modal pentru editarea calculatoarelor -->
|
||||||
<div id="renameModal" class="modal">
|
<div id="editModal" class="modal">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h2>Redenumește Calculator</h2>
|
<h2>Editează Calculator</h2>
|
||||||
<span class="close" onclick="closeRenameModal()">×</span>
|
<span class="close" onclick="closeEditModal()">×</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="currentName">Nume Actual:</label>
|
<label for="editName">Nume Calculator:</label>
|
||||||
<input type="text" id="currentName" readonly>
|
<input type="text" id="editName" placeholder="ex: PC Birou">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="newName">Nume Nou:</label>
|
<label for="editMac">Adresa MAC:</label>
|
||||||
<input type="text" id="newName" placeholder="Introdu noul nume">
|
<input type="text" id="editMac" placeholder="ex: 00:11:22:33:44:55">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editIp">IP (opțional):</label>
|
||||||
|
<input type="text" id="editIp" placeholder="ex: 192.168.1.100">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button type="button" onclick="closeRenameModal()">Anulează</button>
|
<button type="button" onclick="closeEditModal()">Anulează</button>
|
||||||
<button type="button" onclick="performRename()">Redenumește</button>
|
<button type="button" onclick="performEdit()">Salvează</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user