IPAM: VLAN-duplikaattivaroitus "jatketaanko silti" -dialogilla

API palauttaa 409 kun VLAN-numero on jo olemassa, frontend
näyttää confirm-dialogin. Käyttäjä voi valita jatkaako vai ei.
IP/verkko-duplikaatti estää edelleen kokonaan (400).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 10:08:34 +02:00
parent 410e46a4fb
commit 6a84231cce
2 changed files with 38 additions and 8 deletions

29
api.php
View File

@@ -1836,14 +1836,29 @@ switch ($action) {
'muokattu' => date('Y-m-d H:i:s'), 'muokattu' => date('Y-m-d H:i:s'),
'muokkaaja' => currentUser(), 'muokkaaja' => currentUser(),
]; ];
// Duplikaatti-tarkistus: sama verkko/IP ei saa olla jo olemassa // Duplikaatti-tarkistus
if ($entry['verkko'] !== '' && $entry['tyyppi'] !== 'vlan') { $skipDuplicateCheck = !empty($input['force']);
if (!$skipDuplicateCheck) {
$existingAll = dbLoadIpam($companyId); $existingAll = dbLoadIpam($companyId);
foreach ($existingAll as $ex) { // Verkko/IP duplikaatti — estä kokonaan
if ($ex['verkko'] === $entry['verkko'] && $ex['id'] !== $entry['id'] && $ex['tyyppi'] !== 'vlan') { if ($entry['verkko'] !== '' && $entry['tyyppi'] !== 'vlan') {
http_response_code(400); foreach ($existingAll as $ex) {
echo json_encode(['error' => 'IP-osoite tai verkko "' . $entry['verkko'] . '" on jo olemassa (' . ($ex['nimi'] ?: 'nimetön') . ')']); if ($ex['verkko'] === $entry['verkko'] && $ex['id'] !== $entry['id'] && $ex['tyyppi'] !== 'vlan') {
exit; http_response_code(400);
echo json_encode(['error' => 'IP-osoite tai verkko "' . $entry['verkko'] . '" on jo olemassa (' . ($ex['nimi'] ?: 'nimetön') . ')']);
exit;
}
}
}
// VLAN duplikaatti — varoitus (409 = confirm)
if ($entry['tyyppi'] === 'vlan' && !empty($entry['vlan_id'])) {
$vlanNum = (int)$entry['vlan_id'];
foreach ($existingAll as $ex) {
if ($ex['tyyppi'] === 'vlan' && (int)$ex['vlan_id'] === $vlanNum && $ex['id'] !== $entry['id']) {
http_response_code(409);
echo json_encode(['warning' => 'VLAN ' . $vlanNum . ' on jo olemassa (' . ($ex['nimi'] ?: 'nimetön') . '). Lisätäänkö silti?']);
exit;
}
} }
} }
} }

View File

@@ -3470,7 +3470,22 @@ document.getElementById('ipam-form')?.addEventListener('submit', async (e) => {
}; };
if (id) data.id = id; if (id) data.id = id;
try { try {
await apiCall('ipam_save', 'POST', data); const res = await fetch(`${API}?action=ipam_save`, {
method: 'POST', credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
const result = await res.json();
if (res.status === 409 && result.warning) {
if (confirm(result.warning)) {
data.force = true;
await apiCall('ipam_save', 'POST', data);
} else {
return;
}
} else if (!res.ok) {
throw new Error(result.error || 'Virhe');
}
document.getElementById('ipam-modal').style.display = 'none'; document.getElementById('ipam-modal').style.display = 'none';
loadIpam(); loadIpam();
} catch (e) { alert(e.message); } } catch (e) { alert(e.message); }