import React, { Component, Fragment } from 'react'; import { global_breakpoint_md } from '@patternfly/react-tokens'; import { Nav, NavList, Page, PageHeader as PFPageHeader, PageSidebar, } from '@patternfly/react-core'; import styled from 'styled-components'; import { t } from '@lingui/macro'; import { withI18n } from '@lingui/react'; import { ConfigAPI, MeAPI, RootAPI } from '@api'; import About from '@components/About'; import AlertModal from '@components/AlertModal'; import NavExpandableGroup from '@components/NavExpandableGroup'; import BrandLogo from '@components/BrandLogo'; import PageHeaderToolbar from '@components/PageHeaderToolbar'; import ErrorDetail from '@components/ErrorDetail'; import { ConfigProvider } from '@contexts/Config'; const PageHeader = styled(PFPageHeader)` & .pf-c-page__header-brand-link { color: inherit; &:hover { color: inherit; } & svg { height: 76px; } } `; class App extends Component { constructor (props) { super(props); // initialize with a closed navbar if window size is small const isNavOpen = typeof window !== 'undefined' && window.innerWidth >= parseInt(global_breakpoint_md.value, 10); this.state = { ansible_version: null, custom_virtualenvs: null, me: null, version: null, isAboutModalOpen: false, isNavOpen, configError: null }; this.handleLogout = this.handleLogout.bind(this); this.handleAboutClose = this.handleAboutClose.bind(this); this.handleAboutOpen = this.handleAboutOpen.bind(this); this.handleNavToggle = this.handleNavToggle.bind(this); this.handleConfigErrorClose = this.handleConfigErrorClose.bind(this); } async componentDidMount () { await this.loadConfig(); } // eslint-disable-next-line class-methods-use-this async handleLogout () { await RootAPI.logout(); window.location.replace('/#/login'); } handleAboutOpen () { this.setState({ isAboutModalOpen: true }); } handleAboutClose () { this.setState({ isAboutModalOpen: false }); } handleNavToggle () { this.setState(({ isNavOpen }) => ({ isNavOpen: !isNavOpen })); } handleConfigErrorClose () { this.setState({ configError: null }); } async loadConfig () { try { const [configRes, meRes] = await Promise.all([ConfigAPI.read(), MeAPI.read()]); const { data: { ansible_version, custom_virtualenvs, version } } = configRes; const { data: { results: [me] } } = meRes; this.setState({ ansible_version, custom_virtualenvs, version, me }); } catch (err) { this.setState({ configError: err }); } } render () { const { ansible_version, custom_virtualenvs, isAboutModalOpen, isNavOpen, me, version, configError } = this.state; const { i18n, render = () => {}, routeGroups = [], navLabel = '', } = this.props; const header = ( } logoProps={{ href: '/' }} toolbar={( )} /> ); const sidebar = ( {routeGroups.map( ({ groupId, groupTitle, routes }) => ( ) )} )} /> ); return ( {render({ routeGroups })} {i18n._(t`Failed to retrieve configuration.`)} ); } } export { App as _App }; export default withI18n()(App);