fix: SNMP status table no longer vanishes after back/return navigation (v0.11.9 Beta)

Root cause: backend filtered switches by status='online', so a mid-poll-cycle
device (briefly 'unknown') caused the endpoint to return [] — and the frontend
rendered nothing when the array was empty.

- Backend: query ALL switch devices (not just online ones); unreachable devices
  already fall through to the Promise.allSettled error path and render with an
  error badge, so no data is lost
- Frontend: replace silent `length > 0 &&` guard with a three-way ternary that
  shows a "No managed switches found" message when the array is empty, so the
  user always sees feedback instead of a blank section
- Frontend: add staleTime: 60_000 to the SNMP query to prevent the hair-trigger
  background refetch that raced with the poller on every navigation
This commit is contained in:
2GT-Rich
2026-05-17 20:04:33 -07:00
parent b1e4944823
commit 3eb85087f2
6 changed files with 12 additions and 7 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
A self-hosted, full-stack network management platform for MikroTik devices. Monitor, configure, and manage your entire MikroTik infrastructure — routers, switches, and wireless access points — from a single web interface.
![Version](https://img.shields.io/badge/version-0.11.8_Beta-blue)
![Version](https://img.shields.io/badge/version-0.11.9_Beta-blue)
![License](https://img.shields.io/badge/license-AGPLv3-blue)
![Docker](https://img.shields.io/badge/docker-compose-2496ED?logo=docker&logoColor=white)
![TypeScript](https://img.shields.io/badge/TypeScript-5.3-3178C6?logo=typescript&logoColor=white)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "mikrotik-manager-backend",
"version": "0.11.8-beta",
"version": "0.11.9-beta",
"description": "Mikrotik Network Management Platform - Backend API",
"main": "dist/index.js",
"scripts": {
+4 -2
View File
@@ -101,10 +101,12 @@ router.put('/lldp', requireWrite, async (req: Request, res: Response) => {
});
});
// GET /api/switches/snmp — SNMP config/status per online switch
// GET /api/switches/snmp — SNMP config/status for all managed switches
// Includes offline/unknown devices so the list never disappears during a poll cycle.
// Unreachable devices fall through to the Promise.allSettled error path and render with an error note.
router.get('/snmp', async (_req: Request, res: Response) => {
const switches = await query<DeviceRow>(
`SELECT * FROM devices WHERE device_type = 'switch' AND status = 'online'`
`SELECT * FROM devices WHERE device_type = 'switch' ORDER BY name`
);
const results = await Promise.allSettled(
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "mikrotik-manager-frontend",
"version": "0.11.8-beta",
"version": "0.11.9-beta",
"private": true,
"type": "module",
"scripts": {
+4 -1
View File
@@ -93,6 +93,7 @@ export default function SwitchesSettingsPage() {
const { data: snmpStatuses = [], isLoading: snmpLoading, refetch: refetchSnmp, isFetching: snmpFetching } =
useQuery({
queryKey: ['switches-snmp'],
staleTime: 60_000,
queryFn: () => switchesApi.getSnmpStatus().then(r => {
// Pre-populate form from first successful result (if form not yet manually edited)
const first = r.data.find(s => s.enabled != null && !s.error);
@@ -436,7 +437,9 @@ export default function SwitchesSettingsPage() {
<div className="flex items-center gap-2 text-sm text-gray-400">
<RefreshCw className="w-4 h-4 animate-spin" /> Checking SNMP status on all switches…
</div>
) : snmpStatuses.length > 0 && (
) : snmpStatuses.length === 0 ? (
<p className="text-sm text-gray-400 dark:text-slate-500 py-1">No managed switches found.</p>
) : (
<div className="rounded-lg border border-gray-200 dark:border-slate-700 overflow-hidden">
<table className="w-full text-sm">
<thead>
+1 -1
View File
@@ -1 +1 @@
export const APP_VERSION = 'v0.11.8 Beta';
export const APP_VERSION = 'v0.11.9 Beta';