Farmbot-Web-App/frontend/nav/index.tsx

158 lines
5.1 KiB
TypeScript

import * as React from "react";
import { NavBarProps, NavBarState } from "./interfaces";
import { EStopButton } from "../devices/components/e_stop_btn";
import { Session } from "../session";
import { Row, Col } from "../ui/index";
import { getPathArray } from "../history";
import { updatePageInfo } from "../util";
import { SyncButton } from "./sync_button";
import { NavLinks } from "./nav_links";
import { TickerList } from "./ticker_list";
import { AdditionalMenu } from "./additional_menu";
import { MobileMenu } from "./mobile_menu";
import { Popover, Position } from "@blueprintjs/core";
import { ErrorBoundary } from "../error_boundary";
import { RunTour } from "../help/tour";
import { t } from "../i18next_wrapper";
import { Connectivity } from "../devices/connectivity/connectivity";
import { connectivityData } from "../devices/connectivity/generate_data";
import { DiagnosisSaucer } from "../devices/connectivity/diagnosis";
import { maybeSetTimezone } from "../devices/timezones/guess_timezone";
import { BooleanSetting } from "../session_keys";
import { ReadOnlyIcon } from "../read_only_mode";
export class NavBar extends React.Component<NavBarProps, Partial<NavBarState>> {
state: NavBarState = {
mobileMenuOpen: false,
tickerListOpen: false,
accountMenuOpen: false
};
componentDidMount = () => {
const { device } = this.props;
device && maybeSetTimezone(this.props.dispatch, device);
}
logout = () => Session.clear();
toggle = (name: keyof NavBarState) => () =>
this.setState({ [name]: !this.state[name] });
close = (name: keyof NavBarState) => () =>
this.setState({ [name]: false });
ReadOnlyStatus = () =>
<ReadOnlyIcon locked={!!this.props.getConfigValue(
BooleanSetting.user_interface_read_only_mode)} />
SyncButton = () =>
<SyncButton
bot={this.props.bot}
dispatch={this.props.dispatch}
autoSync={this.props.autoSync}
consistent={this.props.consistent} />
EstopButton = () =>
<EStopButton
bot={this.props.bot}
forceUnlock={!!this.props.getConfigValue(
BooleanSetting.disable_emergency_unlock_confirmation)} />
AccountMenu = () => {
const hasName = this.props.user?.body.name;
const firstName = hasName ?
`${hasName.split(" ")[0].slice(0, 9)}` : `${t("Menu")}`;
return <div className="menu-popover">
<Popover
portalClassName={"nav-right"}
popoverClassName={"menu-popover"}
position={Position.BOTTOM_RIGHT}
isOpen={this.state.accountMenuOpen}
onClose={this.close("accountMenuOpen")}>
<div className="nav-name" data-title={firstName}
onClick={this.toggle("accountMenuOpen")}>
{firstName}
</div>
{AdditionalMenu({ logout: this.logout, close: this.close })}
</Popover>
</div>;
}
ConnectionStatus = () => {
const data = connectivityData({
bot: this.props.bot,
device: this.props.device
});
return <div className="connection-status-popover">
<Popover position={Position.BOTTOM_RIGHT}
portalClassName={"connectivity-popover-portal"}
popoverClassName="connectivity-popover">
<DiagnosisSaucer {...data.flags} />
<ErrorBoundary>
<Connectivity
bot={this.props.bot}
rowData={data.rowData}
flags={data.flags}
pings={this.props.pings} />
</ErrorBoundary>
</Popover>
</div>;
}
AppNavLinks = () => {
const { close } = this;
const { mobileMenuOpen } = this.state;
const { alertCount } = this.props;
return <div>
<i className={"fa fa-bars mobile-menu-icon"}
onClick={this.toggle("mobileMenuOpen")} />
<span className="mobile-menu-container">
{MobileMenu({ close, mobileMenuOpen, alertCount })}
</span>
<span className="top-menu-container">
{NavLinks({ close, alertCount })}
</span>
</div>;
}
render() {
/** Change document meta title on every route change. */
updatePageInfo(getPathArray()[2] || "");
const { toggle } = this;
const { tickerListOpen } = this.state;
const { logs, timeSettings, getConfigValue } = this.props;
const tickerListProps = {
logs, tickerListOpen, toggle, timeSettings, getConfigValue
};
return <ErrorBoundary>
<div className="nav-wrapper">
<nav role="navigation">
<Row>
<Col xs={12}>
<div>
<TickerList {...tickerListProps} />
<div className="nav-group">
<div className="nav-left">
<this.AppNavLinks />
</div>
<div className="nav-right">
<ErrorBoundary>
<this.ReadOnlyStatus />
<this.AccountMenu />
<this.EstopButton />
<this.SyncButton />
<this.ConnectionStatus />
<RunTour currentTour={this.props.tour} />
</ErrorBoundary>
</div>
</div>
</div>
</Col>
</Row>
</nav>
</div>
</ErrorBoundary>;
}
}