364 lines
9.8 KiB
JavaScript
Raw Normal View History

/**
*
* Admin
*
*/
import React from 'react';
2019-04-03 13:05:18 +02:00
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';
import { bindActionCreators, compose } from 'redux';
2019-04-03 13:05:18 +02:00
import { Switch, Route } from 'react-router-dom';
2019-04-03 13:05:18 +02:00
// Components from strapi-helper-plugin
2019-04-16 11:53:29 +02:00
import {
LoadingIndicatorPage,
OverlayBlocker,
injectHooks,
} from 'strapi-helper-plugin';
2019-07-12 09:30:32 +02:00
import { SHOW_TUTORIALS } from '../../config';
2019-04-03 13:05:18 +02:00
import Header from '../../components/Header/index';
import Logout from '../../components/Logout';
2019-09-05 17:13:17 +02:00
import NavTopRightWrapper from '../../components/NavTopRightWrapper';
2019-04-03 13:05:18 +02:00
import ComingSoonPage from '../ComingSoonPage';
import LeftMenu from '../LeftMenu';
2019-04-16 11:53:29 +02:00
import ListPluginsPage from '../ListPluginsPage';
2019-04-03 13:05:18 +02:00
import LocaleToggle from '../LocaleToggle';
2019-04-16 11:53:29 +02:00
import HomePage from '../HomePage';
import Marketplace from '../Marketplace';
import NotFoundPage from '../NotFoundPage';
2019-04-03 14:10:42 +02:00
import Onboarding from '../Onboarding';
2019-04-03 13:05:18 +02:00
import PluginDispatcher from '../PluginDispatcher';
2019-04-12 18:23:26 +02:00
import {
disableGlobalOverlayBlocker,
enableGlobalOverlayBlocker,
updatePlugin,
} from '../App/actions';
2019-04-03 13:05:18 +02:00
import makeSelecApp from '../App/selectors';
import injectSaga from '../../utils/injectSaga';
import injectReducer from '../../utils/injectReducer';
import {
resetLocaleDefaultClassName,
setLocaleCustomClassName,
} from '../LocaleToggle/actions';
import {
emitEvent,
getInitData,
getSecuredData,
hideLeftMenu,
hideLogout,
setAppError,
setAppSecured,
showLeftMenu,
showLogout,
unsetAppSecured,
} from './actions';
import makeSelectAdmin from './selectors';
import reducer from './reducer';
import saga from './saga';
2019-04-03 13:05:18 +02:00
import styles from './styles.scss';
export class Admin extends React.Component {
// eslint-disable-line react/prefer-stateless-function
2019-04-03 13:05:18 +02:00
state = { shouldSecureAfterAllPluginsAreMounted: true };
getChildContext = () => ({
emitEvent: this.props.emitEvent,
currentEnvironment: this.props.global.currentEnvironment,
2019-04-03 13:05:18 +02:00
disableGlobalOverlayBlocker: this.props.disableGlobalOverlayBlocker,
enableGlobalOverlayBlocker: this.props.enableGlobalOverlayBlocker,
plugins: this.props.global.plugins,
updatePlugin: this.props.updatePlugin,
});
componentDidMount() {
/* istanbul ignore next */
// Retrieve the main settings of the application
this.props.getInitData();
}
/* istanbul ignore next */
2019-04-03 13:05:18 +02:00
componentDidUpdate(prevProps) {
const {
admin: { didGetSecuredData, isLoading, isSecured },
2019-04-08 19:54:30 +02:00
getHook,
getSecuredData,
2019-04-03 13:05:18 +02:00
location: { pathname },
} = this.props;
if (!isLoading && this.state.shouldSecureAfterAllPluginsAreMounted) {
if (!this.hasApluginNotReady(this.props)) {
2019-04-08 19:54:30 +02:00
getHook('willSecure');
2019-04-03 13:05:18 +02:00
}
}
if (prevProps.location.pathname !== pathname) {
2019-04-08 19:54:30 +02:00
getHook('willSecure');
2019-04-03 13:05:18 +02:00
}
if (prevProps.admin.isSecured !== isSecured && isSecured) {
2019-04-08 19:54:30 +02:00
getSecuredData();
2019-04-03 13:05:18 +02:00
}
if (prevProps.admin.didGetSecuredData !== didGetSecuredData) {
2019-04-08 19:54:30 +02:00
getHook('didGetSecuredData');
2019-04-03 13:05:18 +02:00
}
}
/* istanbul ignore next */
componentDidCatch(error, info) {
/* eslint-disable */
console.log('An error has occured');
console.log('--------------------');
console.log(error);
console.log('Here is some infos');
console.log(info);
/* eslint-enable */
// Display the error log component which is not designed yet
this.props.setAppError();
}
// TODO remove
2019-04-03 13:05:18 +02:00
getContentWrapperStyle = () => {
const {
admin: { showMenu },
} = this.props;
return showMenu
? { main: {}, sub: styles.content }
: { main: { width: '100%' }, sub: styles.wrapper };
};
hasApluginNotReady = props => {
const {
global: { plugins },
} = props;
return !Object.keys(plugins).every(
2019-07-12 09:30:32 +02:00
plugin => plugins[plugin].isReady === true
2019-04-03 13:05:18 +02:00
);
};
helpers = {
hideLeftMenu: this.props.hideLeftMenu,
hideLogout: this.props.hideLogout,
setAppSecured: this.props.setAppSecured,
showLeftMenu: this.props.showLeftMenu,
showLogout: this.props.showLogout,
unsetAppSecured: this.props.unsetAppSecured,
updatePlugin: this.props.updatePlugin,
};
/**
* Display the app loader until the app is ready
* @returns {Boolean}
*/
showLoader = () => {
return this.hasApluginNotReady(this.props);
};
renderInitializers = () => {
const {
global: { plugins },
} = this.props;
return Object.keys(plugins).reduce((acc, current) => {
const InitializerComponent = plugins[current].initializer;
const key = plugins[current].id;
acc.push(
2019-07-12 09:30:32 +02:00
<InitializerComponent key={key} {...this.props} {...this.helpers} />
);
2019-04-03 13:05:18 +02:00
return acc;
}, []);
};
renderMarketPlace = props => <Marketplace {...props} {...this.props} />;
renderPluginDispatcher = props => {
// NOTE: Send the needed props instead of everything...
return <PluginDispatcher {...this.props} {...props} {...this.helpers} />;
};
2019-08-21 09:23:51 +02:00
renderRoute = (props, Component) => <Component {...this.props} {...props} />;
render() {
2019-04-03 13:05:18 +02:00
const {
admin: { isLoading, showLogoutComponent, showMenu },
global: {
blockApp,
overlayBlockerData,
plugins,
showGlobalAppBlocker,
strapiVersion,
},
2019-04-03 13:05:18 +02:00
} = this.props;
if (isLoading) {
return <LoadingIndicatorPage />;
}
// We need the admin data in order to make the initializers work
if (this.showLoader()) {
return (
<React.Fragment>
{this.renderInitializers()}
<LoadingIndicatorPage />
</React.Fragment>
);
}
return (
<div className={styles.adminPage}>
{showMenu && <LeftMenu version={strapiVersion} plugins={plugins} />}
<NavTopRightWrapper>
{/* Injection zone not ready yet */}
{showLogoutComponent && <Logout />}
<LocaleToggle isLogged />
</NavTopRightWrapper>
<div
className={styles.adminPageRightWrapper}
style={this.getContentWrapperStyle().main}
>
{showMenu ? <Header /> : ''}
<div className={this.getContentWrapperStyle().sub}>
<Switch>
2019-08-21 09:23:51 +02:00
<Route
path="/"
render={props => this.renderRoute(props, HomePage)}
exact
/>
2019-04-03 13:05:18 +02:00
<Route
path="/plugins/:pluginId"
2019-04-03 13:05:18 +02:00
render={this.renderPluginDispatcher}
/>
<Route path="/plugins" component={ComingSoonPage} />
<Route
path="/list-plugins"
render={props => this.renderRoute(props, ListPluginsPage)}
exact
/>
{/* <Route path="/list-plugins" component={ListPluginsPage} exact /> */}
2019-04-03 13:05:18 +02:00
<Route
path="/marketplace"
2019-04-03 13:05:18 +02:00
render={this.renderMarketPlace}
exact
/>
<Route path="/configuration" component={ComingSoonPage} exact />
<Route key="7" path="" component={NotFoundPage} />
<Route key="8" path="404" component={NotFoundPage} />
2019-04-03 13:05:18 +02:00
</Switch>
</div>
</div>
<OverlayBlocker
key="overlayBlocker"
2019-04-03 13:05:18 +02:00
isOpen={blockApp && showGlobalAppBlocker}
{...overlayBlockerData}
/>
2019-07-12 09:30:32 +02:00
{showLogoutComponent && SHOW_TUTORIALS && <Onboarding />}
2019-04-03 13:05:18 +02:00
</div>
);
}
}
2019-04-03 13:05:18 +02:00
Admin.childContextTypes = {
emitEvent: PropTypes.func,
currentEnvironment: PropTypes.string,
disableGlobalOverlayBlocker: PropTypes.func,
enableGlobalOverlayBlocker: PropTypes.func,
plugins: PropTypes.object,
updatePlugin: PropTypes.func,
};
Admin.propTypes = {
admin: PropTypes.shape({
autoReload: PropTypes.bool,
appError: PropTypes.bool,
currentEnvironment: PropTypes.string,
didGetSecuredData: PropTypes.bool,
isLoading: PropTypes.bool,
isSecured: PropTypes.bool,
layout: PropTypes.object,
showLogoutComponent: PropTypes.bool,
showMenu: PropTypes.bool,
}).isRequired,
disableGlobalOverlayBlocker: PropTypes.func.isRequired,
emitEvent: PropTypes.func.isRequired,
enableGlobalOverlayBlocker: PropTypes.func.isRequired,
getHook: PropTypes.func.isRequired,
getInitData: PropTypes.func.isRequired,
getSecuredData: PropTypes.func.isRequired,
global: PropTypes.shape({
blockApp: PropTypes.bool,
currentEnvironment: PropTypes.string.isRequired,
2019-04-03 13:05:18 +02:00
overlayBlockerData: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
plugins: PropTypes.object,
showGlobalAppBlocker: PropTypes.bool,
strapiVersion: PropTypes.string,
2019-04-03 13:05:18 +02:00
}).isRequired,
hideLeftMenu: PropTypes.func.isRequired,
hideLogout: PropTypes.func.isRequired,
location: PropTypes.object.isRequired,
resetLocaleDefaultClassName: PropTypes.func.isRequired,
setAppError: PropTypes.func.isRequired,
setAppSecured: PropTypes.func.isRequired,
showLeftMenu: PropTypes.func.isRequired,
showLogout: PropTypes.func.isRequired,
unsetAppSecured: PropTypes.func.isRequired,
updatePlugin: PropTypes.func.isRequired,
};
const mapStateToProps = createStructuredSelector({
admin: makeSelectAdmin(),
2019-04-03 13:05:18 +02:00
global: makeSelecApp(),
});
2019-04-03 13:05:18 +02:00
export function mapDispatchToProps(dispatch) {
return bindActionCreators(
{
disableGlobalOverlayBlocker,
emitEvent,
enableGlobalOverlayBlocker,
getInitData,
getSecuredData,
hideLeftMenu,
hideLogout,
resetLocaleDefaultClassName,
setAppError,
setAppSecured,
setLocaleCustomClassName,
showLeftMenu,
showLogout,
unsetAppSecured,
updatePlugin,
},
2019-07-12 09:30:32 +02:00
dispatch
2019-04-03 13:05:18 +02:00
);
}
const withConnect = connect(
mapStateToProps,
2019-07-12 09:30:32 +02:00
mapDispatchToProps
);
2019-04-03 13:05:18 +02:00
const withReducer = injectReducer({ key: 'admin', reducer });
const withSaga = injectSaga({ key: 'admin', saga });
const withHooks = injectHooks({ key: 'admin' });
export default compose(
withReducer,
withSaga,
withConnect,
2019-07-12 09:30:32 +02:00
withHooks
)(Admin);