import * as React from 'react'
import {Component} from 'react'
import {Grommet} from "grommet"
import {HashRouter as Router} from 'react-router-dom'
import jcuTheme from '../themes/jcu'
import sithTheme from '../themes/sith'
import {ResponsiveLayoutProvider, JcuNotificationLayer, ErrorBoundary} from './layout'
import {NavItem} from './navigation'
import {ApiContextProvider, ConfigContextProvider, AxaOidcProvider, ConfigContext} from '../services'
import {JcuInnerApp} from "./JcuInnerApp"
import {FullAppErrorPage, LogoutPage} from "./pages";
/**
* Enum for different login modes for the JcuApp
* @enum {number}
* @memberOf JcuApp
* @property NONE No login required or offered
* @property OPTIONAL No login required, but login can be required for access to restricted content
* @property FORCED Login is required to use the app. Automatically redirects users to Forgerock when the app loads.
*/
export enum LoginMode {
NONE,
OPTIONAL,
REQUIRED,
FORCED
}
/**
* Different "shapes" JcuApp content can be, used to control the size and behaviour
* of the wrapping elements.
*
* Later we will add a shape for apps that fill the screen without scrolling, like
* a slippy map.
*
* @enum {number}
* @memberOf JcuApp
* @property COLUMN Assume that the app's content is in a vertically-scrolling column constrained
* to some reasonable width, where "reasonable" is defined by the theme (usually around 1000 pixels)
* @property WIDECOLUMN App content can fill the full width of the browser window, no matter how
* silly that gets
*/
export enum Shape {
COLUMN,
WIDECOLUMN
}
type JcuAppProps = {
title: string
basePath: string
login: LoginMode
navItems?: NavItem[]
popup?: boolean
theme?: string
logoutPage?: React.ReactElement
openPage?: React.ReactElement
closePage?: React.ReactElement
safePaths?: string[]
shape?: Shape,
legacyHeader?: boolean
}
/**
* @param {string} title Title to appear in heading of application
* @param {string} basePath Base path of the application (e.g. App-specific hosting URL)
* @param {LoginMode} login Enum dictating the login type (e.g FORCED login)
* @param {NavItem[]} [navItems] An array of NavItems to be added to the app router and navigation bar
* @param {boolean} [popup] Boolean prop to set whether the login mode should be popup or redirect
* @param {string} [theme] Theme to be used by application, specified by a predefined name
* @param {React.ReactElement} [logoutPage] React element to load upon successful user logout
* @param {React.ReactElement} [openPage] React element to load before the config provided application open date
* @param {React.ReactElement} [closePage] React element to load after the config provided application close date
* @param {string[]} [safePaths] List of internal app routes that can be accessed without authentication (e.g. for FORCED login apps)
* @param {Shape} [shape] The layout "shape" of this app. Defaults to `COLUMN`, a vertically scrolling column
* with the width constrained to some reasonable limit.
* @component
* @category Core
*/
export class JcuApp extends Component<JcuAppProps> {
static defaultProps = {
login: LoginMode.NONE,
popup: false,
theme: 'jcu',
safePaths: [],
shape: Shape.COLUMN,
legacyHeader: false
}
constructor(props: JcuAppProps) {
super(props)
}
render = () => {
if (process.env.NODE_ENV !== 'production') {
// non-production warning space
if (this.props.legacyHeader) {
console.warn(
"The legacyHeader flag is deprecated. " +
"It should only be used to maintain legacy layout functionality for applications that are unable to be updated for functional reasons." +
"It should not be used to maintain a legacy layout for aesthetic purposes."
)
}
}
if (window.location.pathname === this.props.basePath + '/loggedout') {
return (
//@ts-ignore
<Grommet theme={jcuTheme} full>
{this.props.logoutPage || <LogoutPage basePath={this.props.basePath || '/'}/>}
</Grommet>
)
} else {
return (
<ErrorBoundary errorPage={<FullAppErrorPage/>}>
<ConfigContextProvider basePath={this.props.basePath}>
<ConfigContext.Consumer>
{(config) => {
// get the theme selection from config
let theme: any = jcuTheme // jcuTheme is the default
if (config && config.appearance && config.appearance.theme === 'sith') {
theme = sithTheme
}
// @ts-ignore
return (
<Grommet theme={theme} full>
<Router>
<AxaOidcProvider>
<ApiContextProvider>
<ResponsiveLayoutProvider>
<JcuNotificationLayer/>
<JcuInnerApp title={this.props.title}
navItems={this.props.navItems}
login={this.props.login}
safePaths={this.props.safePaths}
shape={this.props.shape}
legacyHeader={this.props.legacyHeader}
openPage={this.props.openPage}
closePage={this.props.closePage}
>
{this.props.children}
</JcuInnerApp>
</ResponsiveLayoutProvider>
</ApiContextProvider>
</AxaOidcProvider>
</Router>
</Grommet>
)
}}
</ConfigContext.Consumer>
</ConfigContextProvider>
</ErrorBoundary>
)
}
}
}
Source