prometheus/web/ui/react-app/src/Navbar.tsx
Julius Volz 95554074d8
React UI: Support custom path prefixes (#6264)
* React UI: Support custom path prefixes

The challenge was that the path prefix can be set dynamically as a flag
on Prometheus, but the React app bundle is statically compiled in to
expect a given path prefix. By adding a placeholder value to the React
app's index.html and replacing it in Prometheus with the right path
prefix during serving, this injects Prometheus's path prefix into the
React app via a global const.

Threading the path prefix into the different React components could have
been done with React's Contexts (https://reactjs.org/docs/context.html),
but I found the consumer side of context values to be a bit cumbersome
(wrapping entire components in context consumers), so I ended up
preferring direct threading of the path prefix values to components that
needed them. Also, using contexts in tests is more verbose than just
passing in path prefix values directly.

Fixes https://github.com/prometheus/prometheus/issues/6163

Signed-off-by: Julius Volz <julius.volz@gmail.com>

* Review feedback

Signed-off-by: Julius Volz <julius.volz@gmail.com>
2019-11-04 09:17:50 +01:00

78 lines
2.5 KiB
TypeScript

import React, { FC, useState } from 'react';
import { Link } from '@reach/router';
import {
Collapse,
Navbar,
NavbarToggler,
Nav,
NavItem,
NavLink,
UncontrolledDropdown,
DropdownToggle,
DropdownMenu,
DropdownItem,
} from 'reactstrap';
import PathPrefixProps from './PathPrefixProps';
const Navigation: FC<PathPrefixProps> = ({ pathPrefix }) => {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => setIsOpen(!isOpen);
return (
<Navbar className="mb-3" dark color="dark" expand="md" fixed="top">
<NavbarToggler onClick={toggle} />
<Link className="pt-0 navbar-brand" to={`${pathPrefix}/new/graph`}>
Prometheus
</Link>
<Collapse isOpen={isOpen} navbar style={{ justifyContent: 'space-between' }}>
<Nav className="ml-0" navbar>
<NavItem>
<NavLink tag={Link} to={`${pathPrefix}/new/alerts`}>
Alerts
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to={`${pathPrefix}/new/graph`}>
Graph
</NavLink>
</NavItem>
<UncontrolledDropdown nav inNavbar>
<DropdownToggle nav caret>
Status
</DropdownToggle>
<DropdownMenu>
<DropdownItem tag={Link} to={`${pathPrefix}/new/status`}>
Runtime & Build Information
</DropdownItem>
<DropdownItem tag={Link} to={`${pathPrefix}/new/flags`}>
Command-Line Flags
</DropdownItem>
<DropdownItem tag={Link} to={`${pathPrefix}/new/config`}>
Configuration
</DropdownItem>
<DropdownItem tag={Link} to={`${pathPrefix}/new/rules`}>
Rules
</DropdownItem>
<DropdownItem tag={Link} to={`${pathPrefix}/new/targets`}>
Targets
</DropdownItem>
<DropdownItem tag={Link} to={`${pathPrefix}/new/service-discovery`}>
Service Discovery
</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
<NavItem>
<NavLink href="https://prometheus.io/docs/prometheus/latest/getting_started/">Help</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to={pathPrefix}>
Classic UI
</NavLink>
</NavItem>
</Nav>
</Collapse>
</Navbar>
);
};
export default Navigation;