diff --git a/html/i18n.js b/html/i18n.js index a8d43cb..b11b8e7 100644 --- a/html/i18n.js +++ b/html/i18n.js @@ -117,6 +117,7 @@ var LANG = { l2_col_port: 'Port', l2_col_type: 'Type', l2_col_remove: 'Remove Entry', + l2_shown: 'Shown:', l2_delete: 'Delete', l2_static: 'static', l2_learned: 'learned', @@ -299,6 +300,7 @@ var LANG = { l2_col_port: 'ポート', l2_col_type: 'タイプ', l2_col_remove: 'エントリ削除', + l2_shown: 'Shown:', l2_delete: '削除', l2_static: '静的', l2_learned: '学習', @@ -481,6 +483,7 @@ var LANG = { l2_col_port: '端口', l2_col_type: '类型', l2_col_remove: '删除条目', + l2_shown: 'Shown:', l2_delete: '删除', l2_static: '静态', l2_learned: '动态学习', diff --git a/html/l2.html b/html/l2.html index 029c4e9..6134372 100644 --- a/html/l2.html +++ b/html/l2.html @@ -10,8 +10,18 @@

L2 Configuration

+

Shown: -

- + + + + + +
Port MAC VLAN Type Remove Entry
Port
+
MAC
+
VLAN
+
Type
+
Remove Entry
diff --git a/html/l2.js b/html/l2.js index 25b1b1d..d3a058b 100644 --- a/html/l2.js +++ b/html/l2.js @@ -64,6 +64,51 @@ function delL2(idx) { xhttp.timeout = 1500; xhttp.send(); } +var l2All = []; +const l2Cols = ['port', 'mac', 'vlan', 'type']; +var l2SortCol = 'port'; +var l2SortDir = 1; + +function l2Key(e, col) { + if (col === 'port') return e.port === 'CPU' ? Number.MAX_SAFE_INTEGER : Number(e.port); + if (col === 'vlan') return Number(e.vlan); + return String(e[col]).toLowerCase(); +} + +function l2SortBy(col) { + l2SortDir = (col === l2SortCol) ? -l2SortDir : 1; + l2SortCol = col; + renderL2(); +} + +function l2FilterChanged() { renderL2(); } + +function renderL2() { + var tbl = document.getElementById('l2table'); + if (!tbl) return; + var f = {}; + l2Cols.forEach(function(c) { + var el = document.getElementById('l2f_' + c); + f[c] = el ? el.value.trim().toLowerCase() : ''; + }); + var rows = l2All.filter(function(e) { + return l2Cols.every(function(c) { + return !f[c] || String(e[c]).toLowerCase().indexOf(f[c]) !== -1; + }); + }); + rows.sort(function(a, b) { + var x = l2Key(a, l2SortCol), y = l2Key(b, l2SortCol); + return (x < y ? -1 : x > y ? 1 : 0) * l2SortDir; + }); + l2Cols.forEach(function(c) { + var a = document.getElementById('l2a_' + c); + if (a) a.textContent = (c === l2SortCol) ? (l2SortDir > 0 ? ' \u25b2' : ' \u25bc') : ' \u21c5'; + }); + paintL2(tbl, rows); + var cnt = document.getElementById('l2count'); + if (cnt) cnt.textContent = rows.length + ' / ' + l2All.length; +} + function fillL2(s) { var tbl = document.getElementById('l2table'); @@ -71,7 +116,13 @@ function fillL2(s) return; s.sort(l2CMP); s = uniq(s); - var s = s.map(function(e) { e.port = e.port != 9 ? e.port : 'CPU'; return e; }); + l2All = s; + renderL2(); + l2Entries = []; +} + +function paintL2(tbl, s) +{ console.log("L2: ", JSON.stringify(s)); for (let i = 0; i < s.length; i++) { var e = s[i]; @@ -80,6 +131,7 @@ function fillL2(s) tbl.rows[i+1].cells[0].innerHTML = `${e.port}`; tbl.rows[i+1].cells[1].innerHTML = `${e.mac}`; tbl.rows[i+1].cells[2].innerHTML = `${e.vlan}`; + tbl.rows[i+1].cells[3].innerHTML = `${e.type}`; tbl.rows[i+1].cells[4].innerHTML = ''; } else { const tr = tbl.insertRow(); @@ -92,7 +144,6 @@ function fillL2(s) } for (let i = tbl.rows.length - 1; i > s.length; i--) tbl.deleteRow(i); - l2Entries = []; } function getL2() { @@ -104,7 +155,7 @@ function getL2() { e.vlan = parseInt(e.vlan, 16); e.idx = parseInt(e.idx, 16); e.type = e.type == "s" ? t('l2_static') : t('l2_learned'); - e.port = e.port == 9 ? 9 : logToPhysPort[e.port]; + e.port = e.port == 9 ? 'CPU' : logToPhysPort[e.port]; return e; }); l2Entries.push(...s); diff --git a/html/style.css b/html/style.css index 84d3a2e..1830557 100644 --- a/html/style.css +++ b/html/style.css @@ -164,3 +164,8 @@ margin: 30px 0; select { text-align-last: right; font-family: monospace} option { direction: rtl; font-family: sans-serif} #vlanTable td { text-align: left; } + +.l2sort{cursor:pointer;user-select:none} +.l2sort:hover{text-decoration:underline} +.l2arrow{opacity:0.55;font-size:0.85em} +.l2filter{width:100%;box-sizing:border-box;font-weight:normal;font-size:0.9em}