prometheus/web/ui/react-app/src/App.tsx
Levi Harrison 7bc11dcb06
React UI: Add Starting Screen (#8662)
* Added walreplay API endpoint

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Added starting page to react-ui

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Documented the new endpoint

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Fixed typos

Signed-off-by: Levi Harrison <git@leviharrison.dev>

Co-authored-by: Julius Volz <julius.volz@gmail.com>

* Removed logo

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Changed isResponding to isUnexpected

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Changed width of progress bar

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Changed width of progress bar

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Added DB stats object

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Updated starting page to work with new fields

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Passing nil

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Passing nil (pt. 2)

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Passing nil (pt. 3)

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Passing nil (and also implementing a method this time) (pt. 4)

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Passing nil (and also implementing a method this time) (pt. 5)

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Changed const to let

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Passing nil (pt. 6)

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Remove SetStats method

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Added comma

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Changed api

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Changed to triple equals

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Fixed data response types

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Don't return pointer

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Changed version

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Fixed interface issue

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Fixed pointer

Signed-off-by: Levi Harrison <git@leviharrison.dev>

* Fixed copying lock value error

Signed-off-by: Levi Harrison <git@leviharrison.dev>

Co-authored-by: Julius Volz <julius.volz@gmail.com>
2021-06-05 15:29:32 +01:00

99 lines
3.3 KiB
TypeScript
Executable file

import React, { FC } from 'react';
import Navigation from './Navbar';
import { Container } from 'reactstrap';
import { Router, Redirect, navigate } from '@reach/router';
import useMedia from 'use-media';
import { Alerts, Config, Flags, Rules, ServiceDiscovery, Status, Targets, TSDBStatus, PanelList, Starting } 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 { useFetchReady } from './hooks/useFetch';
import { usePathPrefix } from './contexts/PathPrefixContext';
interface AppProps {
consolesLink: string | null;
}
const App: FC<AppProps> = ({ consolesLink }) => {
// 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 = [
'/graph',
'/alerts',
'/status',
'/tsdb-status',
'/flags',
'/config',
'/rules',
'/targets',
'/service-discovery',
'/starting',
];
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 pathPrefix = usePathPrefix();
const { ready, isLoading, isUnexpected } = useFetchReady(pathPrefix);
if (basePath !== '/starting') {
if (!ready && !isLoading && !isUnexpected) {
navigate('/starting');
}
}
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}>
<Navigation consolesLink={consolesLink} />
<Container fluid style={{ paddingTop: 70 }}>
<Router basepath={`${basePath}`}>
<Redirect from="/" to={`graph`} noThrow />
{/*
NOTE: Any route added here needs to also be added to the list of
React-handled router paths ("reactRouterPaths") in /web/web.go.
*/}
<PanelList path="/graph" />
<Alerts path="/alerts" />
<Config path="/config" />
<Flags path="/flags" />
<Rules path="/rules" />
<ServiceDiscovery path="/service-discovery" />
<Status path="/status" />
<TSDBStatus path="/tsdb-status" />
<Targets path="/targets" />
<Starting path="/starting" />
</Router>
</Container>
</PathPrefixContext.Provider>
</ThemeContext.Provider>
);
};
export default App;