import React, { ComponentType } from 'react'; import { Router, Route, Redirect, Switch } from 'react-router-dom'; import { config, locationService, navigationLogger } from '@grafana/runtime'; import { Provider } from 'react-redux'; import { store } from 'app/store/store'; import { ErrorBoundaryAlert, GlobalStyles, ModalRoot, ModalsProvider } from '@grafana/ui'; import { GrafanaApp } from './app'; import { getAppRoutes } from 'app/routes/routes'; import { ConfigContext, ThemeProvider } from './core/utils/ConfigProvider'; import { RouteDescriptor } from './core/navigation/types'; import { contextSrv } from './core/services/context_srv'; import { NavBar } from './core/components/NavBar/NavBar'; import { NavBarNext } from './core/components/NavBar/NavBarNext'; import { GrafanaRoute } from './core/navigation/GrafanaRoute'; import { AppNotificationList } from './core/components/AppNotifications/AppNotificationList'; import { SearchWrapper } from 'app/features/search'; import { LiveConnectionWarning } from './features/live/LiveConnectionWarning'; import { AngularRoot } from './angular/AngularRoot'; import { I18nProvider } from './core/localisation'; interface AppWrapperProps { app: GrafanaApp; } interface AppWrapperState { ngInjector: any; } /** Used by enterprise */ let bodyRenderHooks: ComponentType[] = []; let pageBanners: ComponentType[] = []; export function addBodyRenderHook(fn: ComponentType) { bodyRenderHooks.push(fn); } export function addPageBanner(fn: ComponentType) { pageBanners.push(fn); } export class AppWrapper extends React.Component { container = React.createRef(); constructor(props: AppWrapperProps) { super(props); this.state = { ngInjector: null, }; } componentDidMount() { if (this.container) { this.bootstrapNgApp(); } else { throw new Error('Failed to boot angular app, no container to attach to'); } } bootstrapNgApp() { const injector = this.props.app.angularApp.bootstrap(); this.setState({ ngInjector: injector }); $('.preloader').remove(); } renderRoute = (route: RouteDescriptor) => { const roles = route.roles ? route.roles() : []; return ( { navigationLogger('AppWrapper', false, 'Rendering route', route, 'with match', props.location); // TODO[Router]: test this logic if (roles?.length) { if (!roles.some((r: string) => contextSrv.hasRole(r))) { return ; } } return ; }} /> ); }; renderRoutes() { return {getAppRoutes().map((r) => this.renderRoute(r))}; } render() { navigationLogger('AppWrapper', false, 'rendering'); const newNavigationEnabled = Boolean(config.featureToggles.newNavigation); return (
{newNavigationEnabled ? : }
{pageBanners.map((Banner, index) => ( ))} {this.state.ngInjector && this.renderRoutes()} {bodyRenderHooks.map((Hook, index) => ( ))}
); } }