123 lines
3.7 KiB
TypeScript
Executable File
123 lines
3.7 KiB
TypeScript
Executable File
import React, { FC } from 'react';
|
|
import Navigation from './Navbar';
|
|
import { Container } from 'reactstrap';
|
|
|
|
import { BrowserRouter as Router, Redirect, Switch, Route } from 'react-router-dom';
|
|
import {
|
|
AgentPage,
|
|
AlertsPage,
|
|
ConfigPage,
|
|
FlagsPage,
|
|
RulesPage,
|
|
ServiceDiscoveryPage,
|
|
StatusPage,
|
|
TargetsPage,
|
|
TSDBStatusPage,
|
|
PanelListPage,
|
|
} from './pages';
|
|
import { PathPrefixContext } from './contexts/PathPrefixContext';
|
|
import { ThemeContext, themeName, themeSetting } from './contexts/ThemeContext';
|
|
import { Theme, themeLocalStorageKey } from './Theme';
|
|
import { useLocalStorage } from './hooks/useLocalStorage';
|
|
import useMedia from './hooks/useMedia';
|
|
|
|
interface AppProps {
|
|
consolesLink: string | null;
|
|
agentMode: boolean;
|
|
}
|
|
|
|
const App: FC<AppProps> = ({ consolesLink, agentMode }) => {
|
|
// 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.
|
|
let basePath = window.location.pathname;
|
|
const paths = [
|
|
'/agent',
|
|
'/graph',
|
|
'/alerts',
|
|
'/status',
|
|
'/tsdb-status',
|
|
'/flags',
|
|
'/config',
|
|
'/rules',
|
|
'/targets',
|
|
'/service-discovery',
|
|
];
|
|
if (basePath.endsWith('/')) {
|
|
basePath = basePath.slice(0, -1);
|
|
}
|
|
if (basePath.length > 1) {
|
|
for (let i = 0; i < paths.length; i++) {
|
|
if (basePath.endsWith(paths[i])) {
|
|
basePath = basePath.slice(0, basePath.length - paths[i].length);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
const [userTheme, setUserTheme] = useLocalStorage<themeSetting>(themeLocalStorageKey, 'auto');
|
|
const browserHasThemes = useMedia('(prefers-color-scheme)');
|
|
const browserWantsDarkTheme = useMedia('(prefers-color-scheme: dark)');
|
|
|
|
let theme: themeName;
|
|
if (userTheme !== 'auto') {
|
|
theme = userTheme;
|
|
} else {
|
|
theme = browserHasThemes ? (browserWantsDarkTheme ? 'dark' : 'light') : 'light';
|
|
}
|
|
|
|
return (
|
|
<ThemeContext.Provider
|
|
value={{ theme: theme, userPreference: userTheme, setTheme: (t: themeSetting) => setUserTheme(t) }}
|
|
>
|
|
<Theme />
|
|
<PathPrefixContext.Provider value={basePath}>
|
|
<Router basename={basePath}>
|
|
<Navigation consolesLink={consolesLink} agentMode={agentMode} />
|
|
<Container fluid style={{ paddingTop: 70 }}>
|
|
<Switch>
|
|
<Redirect exact from="/" to={agentMode ? '/agent' : '/graph'} />
|
|
{/*
|
|
NOTE: Any route added here needs to also be added to the list of
|
|
React-handled router paths ("reactRouterPaths") in /web/web.go.
|
|
*/}
|
|
<Route path="/agent">
|
|
<AgentPage />
|
|
</Route>
|
|
<Route path="/graph">
|
|
<PanelListPage />
|
|
</Route>
|
|
<Route path="/alerts">
|
|
<AlertsPage />
|
|
</Route>
|
|
<Route path="/config">
|
|
<ConfigPage />
|
|
</Route>
|
|
<Route path="/flags">
|
|
<FlagsPage />
|
|
</Route>
|
|
<Route path="/rules">
|
|
<RulesPage />
|
|
</Route>
|
|
<Route path="/service-discovery">
|
|
<ServiceDiscoveryPage />
|
|
</Route>
|
|
<Route path="/status">
|
|
<StatusPage agentMode={agentMode} />
|
|
</Route>
|
|
<Route path="/tsdb-status">
|
|
<TSDBStatusPage />
|
|
</Route>
|
|
<Route path="/targets">
|
|
<TargetsPage />
|
|
</Route>
|
|
</Switch>
|
|
</Container>
|
|
</Router>
|
|
</PathPrefixContext.Provider>
|
|
</ThemeContext.Provider>
|
|
);
|
|
};
|
|
|
|
export default App;
|