feat: Tekniikka-moduuli sub-tabeilla (Laitteet + Sijainnit + IPAM)

- Laitteet-tabi → Tekniikka (sub-tabit: Laitteet, Sijainnit, IPAM)
- Sijainnit siirretty omaksi taulukkonäkymäksi (+ "Lisää sijainti" laitteiden yhteydessä)
- Uusi IPAM-näkymä: IP-osoitteet, subnetit ja VLANit hallintaan
- IPAM: tyyppi (subnet/vlan/ip), verkko, VLAN-nro, sijainti, tila, asiakas
- Sub-tab-tyylit ja logiikka
- Yhteensopivuus: vanha 'devices' moduuli → 'tekniikka'

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 20:18:56 +02:00
parent e37da2b40d
commit 9140c912cd
5 changed files with 558 additions and 56 deletions

47
api.php
View File

@@ -1408,6 +1408,53 @@ switch ($action) {
echo json_encode(['success' => true]);
break;
// ---------- IPAM ----------
case 'ipam':
requireAuth();
$companyId = requireCompany();
echo json_encode(dbLoadIpam($companyId));
break;
case 'ipam_save':
requireAuth();
$companyId = requireCompany();
if ($method !== 'POST') break;
$input = json_decode(file_get_contents('php://input'), true);
$entry = [
'id' => $input['id'] ?? generateId(),
'tyyppi' => $input['tyyppi'] ?? 'ip',
'nimi' => trim($input['nimi'] ?? ''),
'verkko' => trim($input['verkko'] ?? ''),
'vlan_id' => $input['vlan_id'] ?? null,
'site_id' => $input['site_id'] ?? null,
'tila' => $input['tila'] ?? 'vapaa',
'asiakas' => trim($input['asiakas'] ?? ''),
'lisatiedot' => trim($input['lisatiedot'] ?? ''),
'luotu' => $input['luotu'] ?? date('Y-m-d H:i:s'),
'muokattu' => date('Y-m-d H:i:s'),
'muokkaaja' => currentUser(),
];
dbSaveIpam($companyId, $entry);
$action_label = isset($input['id']) && !empty($input['id']) ? 'ipam_update' : 'ipam_create';
$desc = ($entry['tyyppi'] === 'vlan' ? 'VLAN ' . ($entry['vlan_id'] ?? '') : $entry['verkko']) . ' ' . $entry['nimi'];
dbAddLog($companyId, currentUser(), $action_label, $entry['id'], $desc, $action_label === 'ipam_create' ? 'Lisäsi IPAM-merkinnän' : 'Muokkasi IPAM-merkintää');
echo json_encode($entry);
break;
case 'ipam_delete':
requireAuth();
$companyId = requireCompany();
if ($method !== 'POST') break;
$input = json_decode(file_get_contents('php://input'), true);
$id = $input['id'] ?? '';
$all = dbLoadIpam($companyId);
$entryName = '';
foreach ($all as $e) { if ($e['id'] === $id) { $entryName = ($e['tyyppi'] === 'vlan' ? 'VLAN ' . $e['vlan_id'] : $e['verkko']) . ' ' . $e['nimi']; break; } }
dbDeleteIpam($id);
dbAddLog($companyId, currentUser(), 'ipam_delete', $id, $entryName, 'Poisti IPAM-merkinnän');
echo json_encode(['success' => true]);
break;
// ---------- ARCHIVE ----------
case 'archived_customers':
requireAuth();