فهرست منبع

fix(ui): add firewall to navigation routing and dynamic section switcher

Proxmox Router 1 هفته پیش
والد
کامیت
497a6007f8
1فایلهای تغییر یافته به همراه40 افزوده شده و 22 حذف شده
  1. 40 22
      internal/web/static/app.js

+ 40 - 22
internal/web/static/app.js

@@ -6,6 +6,8 @@ let state = {
   vpnStatus: null,
   routes: [],
   activeTab: 'dashboard',
+  fwSubTab: 'filter',
+  routesSubTab: 'routes',
   ifaceFilter: 'all',
   currentModalIface: null,
   isPolling: true,
@@ -14,7 +16,15 @@ let state = {
   wgData: null,
   ipsecData: null,
   l2tpData: null,
-  pptpData: null
+  pptpData: null,
+  fwSummary: null,
+  filterRules: [],
+  natRules: [],
+  mangleRules: [],
+  addressLists: [],
+  connections: [],
+  policyRules: [],
+  routingTables: []
 };
 
 const API_BASE = '/api';
@@ -53,7 +63,8 @@ function navigate(tabName) {
     dashboard: { title: 'Dashboard Overview', sub: 'Live router performance and network telemetry' },
     interfaces: { title: 'Network Interfaces', sub: 'Hierarchical view of physical interfaces and nested 802.1Q VLANs' },
     vlans: { title: 'VLAN Virtual Networks', sub: 'IEEE 802.1Q sub-interface segmentation and routing' },
-    routes: { title: 'Kernel Routing Table', sub: 'Active IPv4 / IPv6 Linux kernel routes and gateways' },
+    firewall: { title: 'MikroTik Firewall', sub: 'Filter rules, NAT, Mangle, Address Lists & Active Connections tracking' },
+    routes: { title: 'Routing & Policy', sub: 'Routing tables, static routes (DAS/DAC), and policy routing rules' },
     pppoe: { title: 'PPPoE Client WAN', sub: 'Point-to-Point Protocol over Ethernet WAN access' },
     wireguard: { title: 'WireGuard Kernel VPN', sub: 'Modern ultra-fast cryptographic VPN tunnel manager' },
     ipsec: { title: 'IPSec (IKEv2) strongSwan', sub: 'Enterprise Site-to-Site & Roadwarrior IPSec controller' },
@@ -63,18 +74,17 @@ function navigate(tabName) {
   };
 
   const header = titles[tabName] || titles.dashboard;
-  document.getElementById('page-title').innerText = header.title;
-  document.getElementById('page-subtitle').innerText = header.sub;
-
-  // Toggle sections
-  ['dashboard', 'interfaces', 'vlans', 'routes', 'pppoe', 'wireguard', 'ipsec', 'l2tp', 'pptp', 'persistence'].forEach(sec => {
-    const el = document.getElementById(`section-${sec}`);
-    if (el) {
-      if (sec === tabName) {
-        el.classList.remove('hidden');
-      } else {
-        el.classList.add('hidden');
-      }
+  const pTitle = document.getElementById('page-title');
+  if (pTitle) pTitle.innerText = header.title;
+  const pSub = document.getElementById('page-subtitle');
+  if (pSub) pSub.innerText = header.sub;
+
+  // Toggle sections dynamically for all section elements
+  document.querySelectorAll('main section[id^="section-"]').forEach(el => {
+    if (el.id === `section-${tabName}`) {
+      el.classList.remove('hidden');
+    } else {
+      el.classList.add('hidden');
     }
   });
 
@@ -2111,10 +2121,14 @@ async function loadFirewall(populateDropdowns = true) {
     if (addrlistRes.ok) state.addressLists = await addrlistRes.json();
 
     // Badges
-    document.getElementById('fw-badge-filter').innerText = (state.filterRules || []).length;
-    document.getElementById('fw-badge-nat').innerText = (state.natRules || []).length;
-    document.getElementById('fw-badge-mangle').innerText = (state.mangleRules || []).length;
-    document.getElementById('fw-badge-addrlist').innerText = (state.addressLists || []).length;
+    const bFilter = document.getElementById('fw-badge-filter');
+    if (bFilter) bFilter.innerText = (state.filterRules || []).length;
+    const bNat = document.getElementById('fw-badge-nat');
+    if (bNat) bNat.innerText = (state.natRules || []).length;
+    const bMangle = document.getElementById('fw-badge-mangle');
+    if (bMangle) bMangle.innerText = (state.mangleRules || []).length;
+    const bAddr = document.getElementById('fw-badge-addrlist');
+    if (bAddr) bAddr.innerText = (state.addressLists || []).length;
 
     renderFilterRules();
     renderNATRules();
@@ -2981,10 +2995,14 @@ async function loadRoutes() {
     if (rulesRes.ok) state.policyRules = await rulesRes.json();
     if (tablesRes.ok) state.routingTables = await tablesRes.json();
 
-    document.getElementById('routes-badge-routes').innerText = (state.routes || []).length;
-    document.getElementById('routes-badge-rules').innerText = (state.policyRules || []).length;
-    document.getElementById('routes-badge-tables').innerText = (state.routingTables || []).length;
-    document.getElementById('badge-routes-count').innerText = (state.routes || []).length;
+    const bRoutes = document.getElementById('routes-badge-routes');
+    if (bRoutes) bRoutes.innerText = (state.routes || []).length;
+    const bRules = document.getElementById('routes-badge-rules');
+    if (bRules) bRules.innerText = (state.policyRules || []).length;
+    const bTables = document.getElementById('routes-badge-tables');
+    if (bTables) bTables.innerText = (state.routingTables || []).length;
+    const bRoutesCount = document.getElementById('badge-routes-count');
+    if (bRoutesCount) bRoutesCount.innerText = (state.routes || []).length;
 
     renderRoutesList();
     renderPolicyRules();