import React, { createElement, Component, ComponentType, SFC } from 'react'; import PropTypes from 'prop-types'; import { Provider } from 'react-redux'; import { History } from 'history'; import { createHashHistory } from 'history'; import { Switch, Route } from 'react-router-dom'; import { ConnectedRouter } from 'react-router-redux'; import withContext from 'recompose/withContext'; import createAdminStore from './createAdminStore'; import TranslationProvider from './i18n/TranslationProvider'; import CoreAdminRouter from './CoreAdminRouter'; import { AuthProvider, I18nProvider, DataProvider, TitleComponent, LoginComponent, LayoutComponent, LayoutProps, AdminChildren, CatchAllComponent, CustomRoutes, DashboardComponent, } from './types'; export type ChildrenFunction = () => ComponentType[]; const DefaultLayout: SFC = ({ children }) => <>{children}; export interface AdminProps { appLayout: LayoutComponent; authProvider?: AuthProvider; children?: AdminChildren; catchAll: CatchAllComponent; customSagas?: any[]; customReducers?: object; customRoutes?: CustomRoutes; dashboard?: DashboardComponent; dataProvider: DataProvider; history: History; i18nProvider?: I18nProvider; initialState?: object; loading: ComponentType; locale?: string; loginPage: LoginComponent | boolean; logoutButton?: ComponentType; menu?: ComponentType; theme?: object; title?: TitleComponent; } interface AdminContext { authProvider: AuthProvider; } class CoreAdminBase extends Component { static contextTypes = { store: PropTypes.object, }; static defaultProps: Partial = { catchAll: () => null, appLayout: DefaultLayout, loading: () => null, loginPage: false, }; reduxIsAlreadyInitialized = false; history = null; constructor(props, context) { super(props, context); if (context.store) { this.reduxIsAlreadyInitialized = true; if (!props.history) { throw new Error(`Missing history prop. When integrating react-admin inside an existing redux Provider, you must provide the same 'history' prop to the as the one used to bootstrap your routerMiddleware. React-admin uses this history for its own ConnectedRouter.`); } this.history = props.history; } else { if (!props.dataProvider) { throw new Error(`Missing dataProvider prop. React-admin requires a valid dataProvider function to work.`); } this.history = props.history || createHashHistory(); } } renderCore() { const { appLayout, authProvider, children, customRoutes = [], dashboard, menu, // deprecated, use a custom layout instead catchAll, theme, title = 'React Admin', loading, loginPage, logoutButton, } = this.props; const logout = authProvider ? createElement(logoutButton) : null; if (loginPage === true && process.env.NODE_ENV !== 'production') { console.warn( 'You passed true to the loginPage prop. You must either pass false to disable it or a component class to customize it' ); } return ( {loginPage !== false && loginPage !== true ? ( createElement(loginPage, { ...props, title, theme, }) } /> ) : null} ( {children} )} /> ); } render() { const { authProvider, customReducers, customSagas, dataProvider, i18nProvider, initialState, locale, } = this.props; return this.reduxIsAlreadyInitialized ? ( this.renderCore() ) : ( {this.renderCore()} ); } } const CoreAdmin = withContext( { authProvider: PropTypes.func, }, ({ authProvider }) => ({ authProvider }) )(CoreAdminBase) as ComponentType; export default CoreAdmin;