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

64
db.php
View File

@@ -381,6 +381,24 @@ function initDatabase(): void {
INDEX idx_company (company_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
"CREATE TABLE IF NOT EXISTS ipam (
id VARCHAR(20) PRIMARY KEY,
company_id VARCHAR(50) NOT NULL,
tyyppi VARCHAR(20) NOT NULL DEFAULT 'ip',
nimi VARCHAR(255) DEFAULT '',
verkko VARCHAR(50) DEFAULT '',
vlan_id INT DEFAULT NULL,
site_id VARCHAR(20) NULL,
tila VARCHAR(20) DEFAULT 'vapaa',
asiakas VARCHAR(255) DEFAULT '',
lisatiedot TEXT,
luotu DATETIME,
muokattu DATETIME NULL,
muokkaaja VARCHAR(100) DEFAULT '',
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
INDEX idx_company (company_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
"CREATE TABLE IF NOT EXISTS files (
id INT AUTO_INCREMENT PRIMARY KEY,
company_id VARCHAR(50) NOT NULL,
@@ -868,6 +886,52 @@ function dbDeleteDevice(string $deviceId): void {
_dbExecute("DELETE FROM devices WHERE id = ?", [$deviceId]);
}
// ==================== IPAM ====================
function dbLoadIpam(string $companyId): array {
$rows = _dbFetchAll("
SELECT i.*, s.nimi AS site_name
FROM ipam i
LEFT JOIN sites s ON i.site_id = s.id
WHERE i.company_id = ?
ORDER BY i.tyyppi, i.vlan_id, i.verkko
", [$companyId]);
foreach ($rows as &$r) {
unset($r['company_id']);
}
return $rows;
}
function dbSaveIpam(string $companyId, array $entry): void {
_dbExecute("
INSERT INTO ipam (id, company_id, tyyppi, nimi, verkko, vlan_id, site_id, tila, asiakas, lisatiedot, luotu, muokattu, muokkaaja)
VALUES (:id, :company_id, :tyyppi, :nimi, :verkko, :vlan_id, :site_id, :tila, :asiakas, :lisatiedot, :luotu, :muokattu, :muokkaaja)
ON DUPLICATE KEY UPDATE
tyyppi = VALUES(tyyppi), nimi = VALUES(nimi), verkko = VALUES(verkko),
vlan_id = VALUES(vlan_id), site_id = VALUES(site_id), tila = VALUES(tila),
asiakas = VALUES(asiakas), lisatiedot = VALUES(lisatiedot),
muokattu = VALUES(muokattu), muokkaaja = VALUES(muokkaaja)
", [
'id' => $entry['id'],
'company_id' => $companyId,
'tyyppi' => $entry['tyyppi'] ?? 'ip',
'nimi' => $entry['nimi'] ?? '',
'verkko' => $entry['verkko'] ?? '',
'vlan_id' => !empty($entry['vlan_id']) ? (int)$entry['vlan_id'] : null,
'site_id' => !empty($entry['site_id']) ? $entry['site_id'] : null,
'tila' => $entry['tila'] ?? 'vapaa',
'asiakas' => $entry['asiakas'] ?? '',
'lisatiedot' => $entry['lisatiedot'] ?? '',
'luotu' => $entry['luotu'] ?? date('Y-m-d H:i:s'),
'muokattu' => $entry['muokattu'] ?? null,
'muokkaaja' => $entry['muokkaaja'] ?? '',
]);
}
function dbDeleteIpam(string $id): void {
_dbExecute("DELETE FROM ipam WHERE id = ?", [$id]);
}
// ==================== LIIDIT ====================
function dbLoadLeads(string $companyId): array {