InfraCanvas #21: Machines and Clusters pages, and a clean frontend build
My third pull request to InfraCanvas, the live Docker and Kubernetes infrastructure map, was merged on October 5. It closes two issues in the Next.js dashboard: #16, which asked for dedicated Machines and Clusters pages, and #18, which asked to clear the React hook lint warnings printed on every build.
The problem
InfraCanvas’s hosted dashboard has full Machines and Clusters pages with cards, status and a connect flow. The open source dashboard only had collapsible lists in the sidebar, showing a name and a status dot for each entry. That works for one machine and a cluster or two, but it gets cramped quickly once you connect a handful of machines or several kubeconfigs.
Separately, npm run build printed six react-hooks/exhaustive-deps and no-img-element warnings on every build. None of them broke the build, but they buried any new warning in noise.
Machines and Clusters pages (#16)
- Sidebar entries with counts. Machines and Clusters each get a sidebar item with a count. Each opens a card grid as an in-page view, the same way the Audit view works, so there are no new routes and no Go changes.
- Machine cards show online state, when the machine joined or was last seen, how many resources it reports, and its scope.
- Cluster cards also show the context, API server and when the cluster was added, all from the existing
GET /api/clustersendpoint. Clusters added from a kubeconfig get a read-only toggle and a two-click Disconnect, so one stray click can’t remove a cluster. - A capped sidebar. The sidebar lists show at most five entries, with a “View all (N)” link to the full page. The entry you are viewing always stays visible, even when it falls outside the first five.
- Small data additions.
SessionInfogained thepairedAtandlastSeenfields that/api/sessionsalready sent, and the stylesheet gained--healthy,--degradedand--unhealthycolor tokens for the status badges.
A sidebar bug fixed on the way
A long hostname or context name stretched the sidebar past its 200px column. That pushed the read-only/read-write and remove controls out of view, and on mobile the closed navigation drawer covered the menu button. The sidebar is now pinned to its column (flex: 1 with min-width: 0), so a long name no longer pushes the controls out of view.
A build with zero lint warnings (#18)
Each warning got the smallest fix that kept the component’s behavior the same:
AgentOverview:hostMetafell back to a new{}on every render, which made auseMemothat depended on it recompute every time. It is now memoized, so the fallback keeps one identity.LogsPanel:targetNodewas added to the effect’s dependencies. It doesn’t cause extra runs, becausefetchLogsalready changes whenevertargetNodedoes.InfraCanvas: the stablesetNodesandsetEdgessetters were added to the dependencies.spotlightKeystays out of the layout effect on purpose, with a commented suppression: re-running the layout when you toggle the spotlight would reset any nodes you had dragged into place.Logo: the plain<img>stays, with a commented suppression. The dashboard is a static export withimages.unoptimized, sonext/imagewould add nothing.
Testing
next lintreports 0 warnings, down from 6, andtsc --noEmitandnpm run buildpass.- I tested the pages with Playwright against a mock API with seven machines and seven clusters: the read-only toggle, Disconnect, opening a card into the Overview, the sidebar cap, both light and dark themes, and a 390px-wide mobile screen with no horizontal scrolling.
- The change has no Go code, so the Go test suite wasn’t affected. It wasn’t tested against a live hub with real agents.
Review and merge
The pull request was approved and merged on October 5. It came to 478 lines added and 16 removed across 11 files, including three new components in frontend/components/fleet/: MachinesView, ClustersView and the cards they share.
This was my third merged pull request to InfraCanvas, after #12 and #19.