React UI: Move global /graph settings to navbar

This saves precious space at the top and makes the page look less
awkward.

Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
Julius Volz 2020-01-25 00:54:55 +01:00
parent d996ba20ec
commit c36a781b1c
3 changed files with 48 additions and 16 deletions

View file

@ -1,4 +1,4 @@
import React, { FC } from 'react';
import React, { FC, useState } from 'react';
import Navigation from './Navbar';
import { Container } from 'reactstrap';
@ -8,9 +8,11 @@ import { Alerts, Config, Flags, Rules, Services, Status, Targets, TSDBStatus, Pa
import PathPrefixProps from './types/PathPrefixProps';
const App: FC<PathPrefixProps> = ({ pathPrefix }) => {
const [extraNavItem, setExtraNavItem] = useState<React.ReactNode>(null);
return (
<>
<Navigation pathPrefix={pathPrefix} />
<Navigation pathPrefix={pathPrefix} extraNavItem={extraNavItem} />
<Container fluid style={{ paddingTop: 70 }}>
<Router basepath={`${pathPrefix}/new`}>
<Redirect from="/" to={`${pathPrefix}/new/graph`} />
@ -19,7 +21,7 @@ const App: FC<PathPrefixProps> = ({ pathPrefix }) => {
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" pathPrefix={pathPrefix} />
<PanelList path="/graph" pathPrefix={pathPrefix} setExtraNavItem={setExtraNavItem} />
<Alerts path="/alerts" pathPrefix={pathPrefix} />
<Config path="/config" pathPrefix={pathPrefix} />
<Flags path="/flags" pathPrefix={pathPrefix} />

View file

@ -14,9 +14,14 @@ import {
} from 'reactstrap';
import PathPrefixProps from './types/PathPrefixProps';
const Navigation: FC<PathPrefixProps> = ({ pathPrefix }) => {
interface NavigationProps {
extraNavItem: React.ReactNode;
}
const Navigation: FC<PathPrefixProps & NavigationProps> = ({ pathPrefix, extraNavItem }) => {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => setIsOpen(!isOpen);
return (
<Navbar className="mb-3" dark color="dark" expand="md" fixed="top">
<NavbarToggler onClick={toggle} />
@ -70,6 +75,7 @@ const Navigation: FC<PathPrefixProps> = ({ pathPrefix }) => {
<NavLink href={`${pathPrefix}/`}>Classic UI</NavLink>
</NavItem>
</Nav>
{extraNavItem}
</Collapse>
</Navbar>
);

View file

@ -1,16 +1,22 @@
import React, { Component, ChangeEvent } from 'react';
import React, { Component, ChangeEvent, CSSProperties } from 'react';
import { RouteComponentProps } from '@reach/router';
import { Alert, Button, Col, Row } from 'reactstrap';
import { Alert, Button, Col, Row, DropdownToggle, DropdownMenu, UncontrolledDropdown } from 'reactstrap';
import Panel, { PanelOptions, PanelDefaultOptions } from './Panel';
import Checkbox from '../../components/Checkbox';
import PathPrefixProps from '../../types/PathPrefixProps';
import { generateID, decodePanelOptionsFromQueryString, encodePanelOptionsToQueryString } from '../../utils';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCog } from '@fortawesome/free-solid-svg-icons';
export type MetricGroup = { title: string; items: string[] };
export type PanelMeta = { key: string; options: PanelOptions; id: string };
interface PanelListProps {
setExtraNavItem: (item: React.ReactNode) => void;
}
interface PanelListState {
panels: PanelMeta[];
pastQueries: string[];
@ -20,8 +26,8 @@ interface PanelListState {
useLocalTime: boolean;
}
class PanelList extends Component<RouteComponentProps & PathPrefixProps, PanelListState> {
constructor(props: RouteComponentProps & PathPrefixProps) {
class PanelList extends Component<RouteComponentProps & PathPrefixProps & PanelListProps, PanelListState> {
constructor(props: RouteComponentProps & PathPrefixProps & PanelListProps) {
super(props);
this.state = {
@ -35,6 +41,8 @@ class PanelList extends Component<RouteComponentProps & PathPrefixProps, PanelLi
}
componentDidMount() {
this.props.setExtraNavItem(this.panelSettingsDropdown());
!this.state.panels.length && this.addPanel();
fetch(`${this.props.pathPrefix}/api/v1/label/__name__/values`, { cache: 'no-store', credentials: 'same-origin' })
.then(resp => {
@ -82,6 +90,10 @@ class PanelList extends Component<RouteComponentProps & PathPrefixProps, PanelLi
this.updatePastQueries();
}
componentWillUnmount() {
this.props.setExtraNavItem(null);
}
isHistoryEnabled = () => JSON.parse(localStorage.getItem('enable-query-history') || 'false') as boolean;
getHistoryItems = () => JSON.parse(localStorage.getItem('history') || '[]') as string[];
@ -154,15 +166,18 @@ class PanelList extends Component<RouteComponentProps & PathPrefixProps, PanelLi
);
};
render() {
const { metricNames, pastQueries, timeDriftError, fetchMetricsError, panels } = this.state;
const { pathPrefix } = this.props;
panelSettingsDropdown() {
const wrapperStyles: CSSProperties = { margin: '3px 15px', alignSelf: 'center', whiteSpace: 'nowrap' };
return (
<>
<Row className="mb-2">
<UncontrolledDropdown className="float-right">
<DropdownToggle>
<FontAwesomeIcon icon={faCog} fixedWidth />
</DropdownToggle>
<DropdownMenu right>
<Checkbox
id="query-history-checkbox"
wrapperStyles={{ margin: '0 0 0 15px', alignSelf: 'center' }}
wrapperStyles={wrapperStyles}
onChange={this.toggleQueryHistory}
defaultChecked={this.isHistoryEnabled()}
>
@ -170,13 +185,22 @@ class PanelList extends Component<RouteComponentProps & PathPrefixProps, PanelLi
</Checkbox>
<Checkbox
id="use-local-time-checkbox"
wrapperStyles={{ margin: '0 0 0 15px', alignSelf: 'center' }}
wrapperStyles={wrapperStyles}
onChange={this.toggleUseLocalTime}
defaultChecked={this.useLocalTime()}
>
Use local time
</Checkbox>
</Row>
</DropdownMenu>
</UncontrolledDropdown>
);
}
render() {
const { metricNames, pastQueries, timeDriftError, fetchMetricsError, panels } = this.state;
const { pathPrefix } = this.props;
return (
<>
<Row>
<Col>
{timeDriftError && (