IPAM: VLAN- ja asiakas-dropdownit lomakkeeseen

- VLAN-kenttä on nyt dropdown joka populoidaan VLAN-listasta
  (subnetit viittaavat VLANeihin)
- Asiakas-kenttä on dropdown joka populoidaan asiakaslistasta
- Verkkonäkymässä VLAN-sarakkeessa näkyy numero + nimi viitteenä
- VLAN-osio näkyy aina (myös tyhjänä)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 09:18:43 +02:00
parent 565a7b6ab3
commit 75e4ab4b42
2 changed files with 45 additions and 11 deletions

View File

@@ -1016,8 +1016,10 @@
<input type="text" id="ipam-form-verkko" placeholder="esim. 10.0.0.0/24 tai 192.168.1.5"> <input type="text" id="ipam-form-verkko" placeholder="esim. 10.0.0.0/24 tai 192.168.1.5">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="ipam-form-vlan">VLAN-numero</label> <label for="ipam-form-vlan">VLAN</label>
<input type="number" id="ipam-form-vlan" min="1" max="4094" placeholder="esim. 100"> <select id="ipam-form-vlan">
<option value="">— Ei VLANia —</option>
</select>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="ipam-form-nimi">Nimi / Kuvaus</label> <label for="ipam-form-nimi">Nimi / Kuvaus</label>
@@ -1039,7 +1041,9 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="ipam-form-asiakas">Asiakas</label> <label for="ipam-form-asiakas">Asiakas</label>
<input type="text" id="ipam-form-asiakas" placeholder="Kenelle varattu"> <select id="ipam-form-asiakas">
<option value="">— Ei asiakasta —</option>
</select>
</div> </div>
<div class="form-group full-width"> <div class="form-group full-width">
<label for="ipam-form-lisatiedot">Lisätiedot</label> <label for="ipam-form-lisatiedot">Lisätiedot</label>

View File

@@ -3129,7 +3129,7 @@ function renderIpam() {
</td> </td>
<td><code class="ipam-network">${esc(e.verkko || '-')}</code>${drillBtn}</td> <td><code class="ipam-network">${esc(e.verkko || '-')}</code>${drillBtn}</td>
<td>${esc(e.nimi || '-')}</td> <td>${esc(e.nimi || '-')}</td>
<td>${e.vlan_id ? '<strong>' + e.vlan_id + '</strong>' : '-'}</td> <td>${vlanRefHtml(e.vlan_id)}</td>
<td>${e.site_name ? esc(e.site_name) : '<span style="color:#ccc;">—</span>'}</td> <td>${e.site_name ? esc(e.site_name) : '<span style="color:#ccc;">—</span>'}</td>
<td><span class="ipam-tila ${tilaClass[e.tila] || ''}">${tilaLabel[e.tila] || e.tila}</span></td> <td><span class="ipam-tila ${tilaClass[e.tila] || ''}">${tilaLabel[e.tila] || e.tila}</span></td>
<td>${esc(e.asiakas || '-')}</td> <td>${esc(e.asiakas || '-')}</td>
@@ -3168,11 +3168,10 @@ function renderIpamVlans(query) {
const tilaClass = { vapaa: 'ipam-tila-vapaa', varattu: 'ipam-tila-varattu', reserved: 'ipam-tila-reserved' }; const tilaClass = { vapaa: 'ipam-tila-vapaa', varattu: 'ipam-tila-varattu', reserved: 'ipam-tila-reserved' };
const tilaLabel = { vapaa: 'Vapaa', varattu: 'Varattu', reserved: 'Reserved' }; const tilaLabel = { vapaa: 'Vapaa', varattu: 'Varattu', reserved: 'Reserved' };
if (vlans.length === 0 && !query) { if (section) section.style.display = '';
tbody.innerHTML = ''; if (vlans.length === 0) {
if (section) section.style.display = 'none'; tbody.innerHTML = '<tr><td colspan="7" style="text-align:center;color:#aaa;padding:1rem;">Ei VLANeja vielä.</td></tr>';
} else { } else {
if (section) section.style.display = '';
tbody.innerHTML = vlans.map(e => `<tr> tbody.innerHTML = vlans.map(e => `<tr>
<td><strong>${e.vlan_id || '-'}</strong></td> <td><strong>${e.vlan_id || '-'}</strong></td>
<td><code style="font-size:0.85rem;">${esc(e.verkko || '-')}</code></td> <td><code style="font-size:0.85rem;">${esc(e.verkko || '-')}</code></td>
@@ -3189,6 +3188,33 @@ function renderIpamVlans(query) {
document.getElementById('ipam-vlan-count').textContent = vlans.length + ' VLANia'; document.getElementById('ipam-vlan-count').textContent = vlans.length + ' VLANia';
} }
// --- VLAN-viite apufunktio ---
function vlanRefHtml(vlanId) {
if (!vlanId) return '<span style="color:#ccc;">—</span>';
const vl = ipamData.find(v => v.tyyppi === 'vlan' && String(v.vlan_id) === String(vlanId));
const label = vl ? esc(vl.nimi) : '';
return `<strong>${vlanId}</strong>${label ? ` <small style="color:#888;">${label}</small>` : ''}`;
}
// --- VLAN-dropdown populointi ---
function populateVlanDropdown(selectedVlanId) {
const sel = document.getElementById('ipam-form-vlan');
const vlans = ipamData.filter(e => e.tyyppi === 'vlan').sort((a, b) => (a.vlan_id || 0) - (b.vlan_id || 0));
sel.innerHTML = '<option value="">— Ei VLANia —</option>' +
vlans.map(v => `<option value="${v.vlan_id}" ${String(v.vlan_id) === String(selectedVlanId) ? 'selected' : ''}>${v.vlan_id}${esc(v.nimi || 'Nimetön')}</option>`).join('');
}
// --- Asiakas-dropdown populointi ---
async function populateIpamCustomerDropdown(selectedName) {
if (!customers || customers.length === 0) {
try { customers = await apiCall('customers'); } catch(e) {}
}
const sel = document.getElementById('ipam-form-asiakas');
const sorted = [...customers].sort((a, b) => (a.nimi || '').localeCompare(b.nimi || ''));
sel.innerHTML = '<option value="">— Ei asiakasta —</option>' +
sorted.map(c => `<option value="${esc(c.nimi)}" ${c.nimi === selectedName ? 'selected' : ''}>${esc(c.nimi)}</option>`).join('');
}
// --- Toggle & Drill --- // --- Toggle & Drill ---
function ipamToggle(id) { function ipamToggle(id) {
if (ipamExpandedIds.has(id)) ipamExpandedIds.delete(id); if (ipamExpandedIds.has(id)) ipamExpandedIds.delete(id);
@@ -3225,14 +3251,14 @@ async function editIpam(id) {
document.getElementById('ipam-form-id').value = e.id; document.getElementById('ipam-form-id').value = e.id;
document.getElementById('ipam-form-tyyppi').value = e.tyyppi || 'ip'; document.getElementById('ipam-form-tyyppi').value = e.tyyppi || 'ip';
document.getElementById('ipam-form-verkko').value = e.verkko || ''; document.getElementById('ipam-form-verkko').value = e.verkko || '';
document.getElementById('ipam-form-vlan').value = e.vlan_id || '';
document.getElementById('ipam-form-nimi').value = e.nimi || ''; document.getElementById('ipam-form-nimi').value = e.nimi || '';
document.getElementById('ipam-form-tila').value = e.tila || 'vapaa'; document.getElementById('ipam-form-tila').value = e.tila || 'vapaa';
document.getElementById('ipam-form-asiakas').value = e.asiakas || '';
document.getElementById('ipam-form-lisatiedot').value = e.lisatiedot || ''; document.getElementById('ipam-form-lisatiedot').value = e.lisatiedot || '';
populateVlanDropdown(e.vlan_id || '');
await populateIpamCustomerDropdown(e.asiakas || '');
await loadIpamSitesDropdown(); await loadIpamSitesDropdown();
document.getElementById('ipam-form-site').value = e.site_id || ''; document.getElementById('ipam-form-site').value = e.site_id || '';
document.getElementById('ipam-modal-title').textContent = 'Muokkaa IPAM-merkintää'; document.getElementById('ipam-modal-title').textContent = e.tyyppi === 'vlan' ? 'Muokkaa VLANia' : 'Muokkaa verkkoa / IP:tä';
document.getElementById('ipam-modal').style.display = 'flex'; document.getElementById('ipam-modal').style.display = 'flex';
} }
@@ -3248,6 +3274,8 @@ document.getElementById('btn-add-ipam')?.addEventListener('click', async () => {
document.getElementById('ipam-form-id').value = ''; document.getElementById('ipam-form-id').value = '';
document.getElementById('ipam-form').reset(); document.getElementById('ipam-form').reset();
document.getElementById('ipam-form-tyyppi').value = 'subnet'; document.getElementById('ipam-form-tyyppi').value = 'subnet';
populateVlanDropdown('');
await populateIpamCustomerDropdown('');
await loadIpamSitesDropdown(); await loadIpamSitesDropdown();
document.getElementById('ipam-modal-title').textContent = 'Lisää verkko / IP'; document.getElementById('ipam-modal-title').textContent = 'Lisää verkko / IP';
document.getElementById('ipam-modal').style.display = 'flex'; document.getElementById('ipam-modal').style.display = 'flex';
@@ -3257,6 +3285,8 @@ document.getElementById('btn-add-vlan')?.addEventListener('click', async () => {
document.getElementById('ipam-form-id').value = ''; document.getElementById('ipam-form-id').value = '';
document.getElementById('ipam-form').reset(); document.getElementById('ipam-form').reset();
document.getElementById('ipam-form-tyyppi').value = 'vlan'; document.getElementById('ipam-form-tyyppi').value = 'vlan';
populateVlanDropdown('');
await populateIpamCustomerDropdown('');
await loadIpamSitesDropdown(); await loadIpamSitesDropdown();
document.getElementById('ipam-modal-title').textContent = 'Lisää VLAN'; document.getElementById('ipam-modal-title').textContent = 'Lisää VLAN';
document.getElementById('ipam-modal').style.display = 'flex'; document.getElementById('ipam-modal').style.display = 'flex';