NetAdmin-moduuli: liittymien listaus ja haku
Kokoaa kaikki asiakkaiden liittymät yhteen näkymään haulla ja suodattimilla. Sarakkeet: asiakas, osoite, kaupunki, nopeus, VLAN, laite, portti, IP, hinta. Suodattimet: kaupunki, nopeus, laite. Laitetietojen ping-status näkyvissä. Klikkaus avaa asiakkaan muokkaukseen. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
105
script.js
105
script.js
@@ -200,7 +200,7 @@ async function showDashboard() {
|
||||
// Avaa oikea tabi URL-hashin perusteella (tai customers oletuks)
|
||||
const hash = window.location.hash.replace('#', '');
|
||||
const [mainHash, subHash] = hash.split('/');
|
||||
const validTabs = ['customers', 'leads', 'tekniikka', 'ohjeet', 'todo', 'documents', 'laitetilat', 'archive', 'changelog', 'support', 'users', 'settings', 'companies'];
|
||||
const validTabs = ['customers', 'leads', 'tekniikka', 'ohjeet', 'todo', 'documents', 'laitetilat', 'netadmin', 'archive', 'changelog', 'support', 'users', 'settings', 'companies'];
|
||||
const startTab = validTabs.includes(mainHash) ? mainHash : 'customers';
|
||||
switchToTab(startTab, subHash);
|
||||
}
|
||||
@@ -265,6 +265,7 @@ function switchToTab(target, subTab) {
|
||||
if (target === 'support') { loadTickets(); showTicketListView(); if (document.getElementById('ticket-auto-refresh').checked) startTicketAutoRefresh(); }
|
||||
if (target === 'documents') { loadDocuments(); showDocsListView(); }
|
||||
if (target === 'laitetilat') { loadLaitetilat(); showLaitetilatListView(); }
|
||||
if (target === 'netadmin') loadNetadmin();
|
||||
if (target === 'users') loadUsers();
|
||||
if (target === 'settings') loadSettings();
|
||||
if (target === 'companies') loadCompaniesTab();
|
||||
@@ -4394,6 +4395,106 @@ document.getElementById('btn-time-cancel')?.addEventListener('click', () => {
|
||||
});
|
||||
document.getElementById('btn-time-save')?.addEventListener('click', () => addTimeEntry());
|
||||
|
||||
// ==================== NETADMIN ====================
|
||||
|
||||
let netadminData = { connections: [], devices: [] };
|
||||
|
||||
async function loadNetadmin() {
|
||||
try {
|
||||
netadminData = await apiCall('netadmin_connections');
|
||||
populateNetadminFilters();
|
||||
renderNetadminTable();
|
||||
} catch (e) { console.error('NetAdmin lataus epäonnistui:', e); }
|
||||
}
|
||||
|
||||
function populateNetadminFilters() {
|
||||
const conns = netadminData.connections || [];
|
||||
|
||||
// Kaupungit
|
||||
const cities = [...new Set(conns.map(c => c.kaupunki).filter(Boolean))].sort();
|
||||
const citySel = document.getElementById('netadmin-filter-city');
|
||||
const cityVal = citySel.value;
|
||||
citySel.innerHTML = '<option value="">Kaikki kaupungit</option>' +
|
||||
cities.map(c => `<option value="${c}">${esc(c)}</option>`).join('');
|
||||
citySel.value = cityVal;
|
||||
|
||||
// Nopeudet
|
||||
const speeds = [...new Set(conns.map(c => c.liittymanopeus).filter(Boolean))].sort();
|
||||
const speedSel = document.getElementById('netadmin-filter-speed');
|
||||
const speedVal = speedSel.value;
|
||||
speedSel.innerHTML = '<option value="">Kaikki nopeudet</option>' +
|
||||
speeds.map(s => `<option value="${s}">${esc(s)}</option>`).join('');
|
||||
speedSel.value = speedVal;
|
||||
|
||||
// Laitteet
|
||||
const devs = [...new Set(conns.map(c => c.laite).filter(Boolean))].sort();
|
||||
const devSel = document.getElementById('netadmin-filter-device');
|
||||
const devVal = devSel.value;
|
||||
devSel.innerHTML = '<option value="">Kaikki laitteet</option>' +
|
||||
devs.map(d => `<option value="${d}">${esc(d)}</option>`).join('');
|
||||
devSel.value = devVal;
|
||||
}
|
||||
|
||||
function renderNetadminTable() {
|
||||
const query = (document.getElementById('netadmin-search')?.value || '').toLowerCase().trim();
|
||||
const filterCity = document.getElementById('netadmin-filter-city')?.value || '';
|
||||
const filterSpeed = document.getElementById('netadmin-filter-speed')?.value || '';
|
||||
const filterDevice = document.getElementById('netadmin-filter-device')?.value || '';
|
||||
|
||||
let filtered = netadminData.connections || [];
|
||||
|
||||
if (query) {
|
||||
filtered = filtered.filter(c => {
|
||||
const searchStr = [
|
||||
c.customer_name, c.asennusosoite, c.kaupunki, c.postinumero,
|
||||
c.liittymanopeus, c.vlan, c.laite, c.portti, c.ip
|
||||
].filter(Boolean).join(' ').toLowerCase();
|
||||
return searchStr.includes(query);
|
||||
});
|
||||
}
|
||||
if (filterCity) filtered = filtered.filter(c => c.kaupunki === filterCity);
|
||||
if (filterSpeed) filtered = filtered.filter(c => c.liittymanopeus === filterSpeed);
|
||||
if (filterDevice) filtered = filtered.filter(c => c.laite === filterDevice);
|
||||
|
||||
const tbody = document.getElementById('netadmin-tbody');
|
||||
const noEl = document.getElementById('no-netadmin');
|
||||
const countEl = document.getElementById('netadmin-count');
|
||||
|
||||
countEl.textContent = `${filtered.length} / ${(netadminData.connections || []).length} liittymää`;
|
||||
|
||||
if (filtered.length === 0) {
|
||||
tbody.innerHTML = '';
|
||||
noEl.style.display = '';
|
||||
return;
|
||||
}
|
||||
noEl.style.display = 'none';
|
||||
|
||||
tbody.innerHTML = filtered.map(c => {
|
||||
const addr = c.asennusosoite || '-';
|
||||
const deviceInfo = c.device_info;
|
||||
const pingClass = deviceInfo?.ping_status === 'up' ? 'netadmin-status-up' :
|
||||
deviceInfo?.ping_status === 'down' ? 'netadmin-status-down' : '';
|
||||
const deviceDisplay = c.laite ? `<span class="${pingClass}">${esc(c.laite)}</span>` : '-';
|
||||
|
||||
return `<tr onclick="editCustomer('${c.customer_id}')" style="cursor:pointer;" title="Avaa asiakas">
|
||||
<td><strong>${esc(c.customer_name || '-')}</strong></td>
|
||||
<td>${esc(addr)}</td>
|
||||
<td>${esc(c.kaupunki || '-')}</td>
|
||||
<td><span class="netadmin-speed">${esc(c.liittymanopeus || '-')}</span></td>
|
||||
<td>${esc(c.vlan || '-')}</td>
|
||||
<td>${deviceDisplay}</td>
|
||||
<td>${esc(c.portti || '-')}</td>
|
||||
<td><code>${esc(c.ip || '-')}</code></td>
|
||||
<td class="price-cell">${c.hinta ? parseFloat(c.hinta).toFixed(2) + ' €' : '-'}</td>
|
||||
</tr>`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
document.getElementById('netadmin-search')?.addEventListener('input', renderNetadminTable);
|
||||
document.getElementById('netadmin-filter-city')?.addEventListener('change', renderNetadminTable);
|
||||
document.getElementById('netadmin-filter-speed')?.addEventListener('change', renderNetadminTable);
|
||||
document.getElementById('netadmin-filter-device')?.addEventListener('change', renderNetadminTable);
|
||||
|
||||
// ==================== DOKUMENTIT ====================
|
||||
|
||||
let allDocuments = [];
|
||||
@@ -4910,7 +5011,7 @@ document.getElementById('laitetila-edit-form')?.addEventListener('submit', async
|
||||
|
||||
// ==================== MODUULIT ====================
|
||||
|
||||
const ALL_MODULES = ['customers', 'support', 'leads', 'tekniikka', 'ohjeet', 'todo', 'documents', 'laitetilat', 'archive', 'changelog', 'settings'];
|
||||
const ALL_MODULES = ['customers', 'support', 'leads', 'tekniikka', 'ohjeet', 'todo', 'documents', 'laitetilat', 'netadmin', 'archive', 'changelog', 'settings'];
|
||||
const DEFAULT_MODULES = ['customers', 'support', 'archive', 'changelog', 'settings'];
|
||||
|
||||
function applyModules(modules) {
|
||||
|
||||
Reference in New Issue
Block a user