import "@mantine/core/styles.css";
import "@mantine/code-highlight/styles.css";
import "@mantine/notifications/styles.css";
import "@mantine/dates/styles.css";
import classes from "./App.module.css";
import PrometheusLogo from "./images/prometheus-logo.svg";
import {
AppShell,
Box,
Burger,
Button,
Group,
MantineProvider,
Menu,
Skeleton,
Text,
createTheme,
rem,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import {
IconBellFilled,
IconChevronDown,
IconChevronRight,
IconCloudDataConnection,
IconDatabase,
IconFlag,
IconHeartRateMonitor,
IconInfoCircle,
IconSearch,
IconServer,
IconServerCog,
} from "@tabler/icons-react";
import {
BrowserRouter,
Link,
NavLink,
Navigate,
Route,
Routes,
} from "react-router-dom";
import { IconTable } from "@tabler/icons-react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import QueryPage from "./pages/query/QueryPage";
import AlertsPage from "./pages/AlertsPage";
import RulesPage from "./pages/RulesPage";
import TargetsPage from "./pages/targets/TargetsPage";
import StatusPage from "./pages/StatusPage";
import TSDBStatusPage from "./pages/TSDBStatusPage";
import FlagsPage from "./pages/FlagsPage";
import ConfigPage from "./pages/ConfigPage";
import AgentPage from "./pages/AgentPage";
import { Suspense } from "react";
import ErrorBoundary from "./components/ErrorBoundary";
import { ThemeSelector } from "./components/ThemeSelector";
import { Notifications } from "@mantine/notifications";
import { useAppDispatch } from "./state/hooks";
import { updateSettings, useSettings } from "./state/settingsSlice";
import SettingsMenu from "./components/SettingsMenu";
import ReadinessWrapper from "./components/ReadinessWrapper";
import { QueryParamProvider } from "use-query-params";
import { ReactRouter6Adapter } from "use-query-params/adapters/react-router-6";
import ServiceDiscoveryPage from "./pages/service-discovery/ServiceDiscoveryPage";
const queryClient = new QueryClient();
const navIconStyle = { width: rem(16), height: rem(16) };
const mainNavPages = [
{
title: "Query",
path: "/query",
icon: ,
element: ,
inAgentMode: false,
},
{
title: "Alerts",
path: "/alerts",
icon: ,
element: ,
inAgentMode: false,
},
];
const monitoringStatusPages = [
{
title: "Target health",
path: "/targets",
icon: ,
element: ,
inAgentMode: true,
},
{
title: "Rule health",
path: "/rules",
icon: ,
element: ,
inAgentMode: false,
},
{
title: "Service discovery",
path: "/service-discovery",
icon: ,
element: ,
inAgentMode: true,
},
];
const serverStatusPages = [
{
title: "Runtime & build information",
path: "/status",
icon: ,
element: ,
inAgentMode: true,
},
{
title: "TSDB status",
path: "/tsdb-status",
icon: ,
element: ,
inAgentMode: false,
},
{
title: "Command-line flags",
path: "/flags",
icon: ,
element: ,
inAgentMode: true,
},
{
title: "Configuration",
path: "/config",
icon: ,
element: ,
inAgentMode: true,
},
];
const allStatusPages = [...monitoringStatusPages, ...serverStatusPages];
const theme = createTheme({
colors: {
"codebox-bg": [
"#f5f5f5",
"#e7e7e7",
"#cdcdcd",
"#b2b2b2",
"#9a9a9a",
"#8b8b8b",
"#848484",
"#717171",
"#656565",
"#575757",
],
},
});
// This dynamically/generically determines the pathPrefix by stripping the first known
// endpoint suffix from the window location path. It works out of the box for both direct
// hosting and reverse proxy deployments with no additional configurations required.
const getPathPrefix = (path: string) => {
if (path.endsWith("/")) {
path = path.slice(0, -1);
}
const pagePaths = [
...mainNavPages,
...allStatusPages,
{ path: "/agent" },
].map((p) => p.path);
const pagePath = pagePaths.find((p) => path.endsWith(p));
return path.slice(0, path.length - (pagePath || "").length);
};
const navLinkXPadding = "md";
function App() {
const [opened, { toggle }] = useDisclosure();
const pathPrefix = getPathPrefix(window.location.pathname);
const dispatch = useAppDispatch();
dispatch(updateSettings({ pathPrefix }));
const { agentMode } = useSettings();
const navLinks = (
<>
{mainNavPages
.filter((p) => !agentMode || p.inAgentMode)
.map((p) => (
))}
{/* }
target="_blank"
px={navLinkXPadding}
>
Help
*/}
>
);
return (
Prometheus{agentMode && " Agent"}
{navLinks}
{navLinks}
{Array.from(Array(10), (_, i) => (
))}
}
>
}
/>
{agentMode ? (
}
/>
) : (
<>
}
/>
}
/>
>
)}
{allStatusPages.map((p) => (
{p.element}
}
/>
))}
{/* */}
);
}
export default App;