import PropTypes from 'prop-types'; import React from 'react'; import { hot } from 'react-hot-loader'; import { translate } from 'react-polyglot'; import ImmutablePropTypes from 'react-immutable-proptypes'; import styled from '@emotion/styled'; import { connect } from 'react-redux'; import { Route, Switch, Redirect } from 'react-router-dom'; import { Notifs } from 'redux-notifications'; import TopBarProgress from 'react-topbar-progress-indicator'; import { loadConfig } from 'Actions/config'; import { loginUser, logoutUser } from 'Actions/auth'; import { currentBackend } from 'coreSrc/backend'; import { createNewEntry } from 'Actions/collections'; import { openMediaLibrary } from 'Actions/mediaLibrary'; import MediaLibrary from 'MediaLibrary/MediaLibrary'; import { Toast } from 'UI'; import { Loader, colors } from 'netlify-cms-ui-default'; import history from 'Routing/history'; import { SIMPLE, EDITORIAL_WORKFLOW } from 'Constants/publishModes'; import Collection from 'Collection/Collection'; import Workflow from 'Workflow/Workflow'; import Editor from 'Editor/Editor'; import NotFoundPage from './NotFoundPage'; import Header from './Header'; TopBarProgress.config({ barColors: { '0': colors.active, '1.0': colors.active, }, shadowBlur: 0, barThickness: 2, }); const AppMainContainer = styled.div` min-width: 800px; max-width: 1440px; margin: 0 auto; `; const ErrorContainer = styled.div` margin: 20px; `; const ErrorCodeBlock = styled.pre` margin-left: 20px; font-size: 15px; line-height: 1.5; `; class App extends React.Component { static propTypes = { auth: ImmutablePropTypes.map, config: ImmutablePropTypes.map, collections: ImmutablePropTypes.orderedMap, loadConfig: PropTypes.func.isRequired, loginUser: PropTypes.func.isRequired, logoutUser: PropTypes.func.isRequired, user: ImmutablePropTypes.map, isFetching: PropTypes.bool.isRequired, publishMode: PropTypes.oneOf([SIMPLE, EDITORIAL_WORKFLOW]), siteId: PropTypes.string, useMediaLibrary: PropTypes.bool, openMediaLibrary: PropTypes.func.isRequired, showMediaButton: PropTypes.bool, t: PropTypes.func.isRequired, }; configError(config) { const t = this.props.t; return (

{t('app.app.errorHeader')}

{t('app.app.configErrors')}: {config.get('error')} {t('app.app.checkConfigYml')}
); } componentDidMount() { const { loadConfig } = this.props; loadConfig(); } handleLogin(credentials) { this.props.loginUser(credentials); } authenticating() { const { auth, t } = this.props; const backend = currentBackend(this.props.config); if (backend == null) { return (

{t('app.app.waitingBackend')}

); } return (
{React.createElement(backend.authComponent(), { onLogin: this.handleLogin.bind(this), error: auth && auth.get('error'), isFetching: auth && auth.get('isFetching'), inProgress: (auth && auth.get('isFetching')) || false, siteId: this.props.config.getIn(['backend', 'site_domain']), base_url: this.props.config.getIn(['backend', 'base_url'], null), authEndpoint: this.props.config.getIn(['backend', 'auth_endpoint']), config: this.props.config, clearHash: () => history.replace('/'), })}
); } handleLinkClick(event, handler, ...args) { event.preventDefault(); handler(...args); } render() { const { user, config, collections, logoutUser, isFetching, publishMode, useMediaLibrary, openMediaLibrary, t, showMediaButton, } = this.props; if (config === null) { return null; } if (config.get('error')) { return this.configError(config); } if (config.get('isFetching')) { return {t('app.app.loadingConfig')}; } if (user == null) { return this.authenticating(t); } const defaultPath = `/collections/${collections.first().get('name')}`; const hasWorkflow = publishMode === EDITORIAL_WORKFLOW; return ( <>
{isFetching && } {hasWorkflow ? : null} { const collectionExists = collections.get(props.match.params.name); return collectionExists ? : ; }} /> } /> } /> { const { collectionName, entryName } = match.params; return ; }} /> {useMediaLibrary ? : null} ); } } function mapStateToProps(state) { const { auth, config, collections, globalUI, mediaLibrary } = state; const user = auth && auth.get('user'); const isFetching = globalUI.get('isFetching'); const publishMode = config && config.get('publish_mode'); const useMediaLibrary = !mediaLibrary.get('externalLibrary'); const showMediaButton = mediaLibrary.get('showMediaButton'); return { auth, config, collections, user, isFetching, publishMode, showMediaButton, useMediaLibrary, }; } const mapDispatchToProps = { openMediaLibrary, loadConfig, loginUser, logoutUser, }; export default hot(module)( connect( mapStateToProps, mapDispatchToProps, )(translate()(App)), );