🚧 Add broker status page
This commit is contained in:
+37
-5
@@ -10,6 +10,7 @@ import { GroupsPage } from "./pages/Groups";
|
||||
import { BrokerConfigPage } from "./pages/BrokerConfig";
|
||||
import { CertificatesPage } from "./pages/Certificates";
|
||||
import { SystemPage } from "./pages/System";
|
||||
import { StatusPage } from "./pages/Status";
|
||||
|
||||
// Navigation structure per spec section 57. Entries with a `to` route are
|
||||
// implemented; entries without one are planned pages, rendered greyed out
|
||||
@@ -21,7 +22,7 @@ const NAV_SECTIONS: {
|
||||
{
|
||||
title: "Broker",
|
||||
items: [
|
||||
{ label: "Status", hint: "Dashboard / $SYS monitoring (Release 3)" },
|
||||
{ label: "Status", to: "/broker/status" },
|
||||
{ label: "Configuration", to: "/broker" },
|
||||
{ label: "Listeners", to: "/broker#listeners" },
|
||||
{ label: "Bridges", hint: "Bridge management (post-MVP)" },
|
||||
@@ -82,6 +83,19 @@ function RestartIndicator() {
|
||||
);
|
||||
}
|
||||
|
||||
// Hash-aware active matching: an item is active only when BOTH its path
|
||||
// AND its hash (if any) match the current location. NavLink's default
|
||||
// prefix matching lights up every /broker* item on /broker/status, and
|
||||
// hash items (#listeners, #revisions) all match on pathname alone.
|
||||
function isItemActive(
|
||||
to: string,
|
||||
location: { pathname: string; hash: string },
|
||||
): boolean {
|
||||
const [path, hash] = to.split("#");
|
||||
if (path !== location.pathname) return false;
|
||||
return hash ? location.hash === `#${hash}` : location.hash === "";
|
||||
}
|
||||
|
||||
function Layout({ children }: { children: React.ReactNode }) {
|
||||
const { session, logout } = useAuth();
|
||||
const location = useLocation();
|
||||
@@ -92,9 +106,7 @@ function Layout({ children }: { children: React.ReactNode }) {
|
||||
|
||||
const activeSection = NAV_SECTIONS.find((section) =>
|
||||
section.items.some(
|
||||
(item) =>
|
||||
item.to &&
|
||||
item.to.split("#")[0] === location.pathname,
|
||||
(item) => item.to && isItemActive(item.to, location),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -129,7 +141,19 @@ function Layout({ children }: { children: React.ReactNode }) {
|
||||
<div>
|
||||
{section.items.map((item) =>
|
||||
item.to ? (
|
||||
<NavLink key={item.label} to={item.to}>
|
||||
<NavLink
|
||||
key={item.label}
|
||||
to={item.to}
|
||||
end
|
||||
// Full control of the active class: NavLink's
|
||||
// own prefix matching would mark every /broker*
|
||||
// item active on /broker/status.
|
||||
className={() =>
|
||||
isItemActive(item.to!, location)
|
||||
? "active"
|
||||
: ""
|
||||
}
|
||||
>
|
||||
{item.label}
|
||||
</NavLink>
|
||||
) : (
|
||||
@@ -206,6 +230,14 @@ export function App() {
|
||||
</Protected>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/broker/status"
|
||||
element={
|
||||
<Protected>
|
||||
<StatusPage />
|
||||
</Protected>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/certificates"
|
||||
element={
|
||||
|
||||
Reference in New Issue
Block a user