import React, {useEffect, useRef} from 'react'; import {withRouter, RouteComponentProps} from 'react-router-dom'; import {connect, ConnectedProps} from 'react-redux'; import {Loader} from 'UI'; import {fetchUserInfo, setJwt} from 'Duck/user'; import {fetchList as fetchSiteList} from 'Duck/site'; import {withStore} from 'App/mstore'; import {Map} from 'immutable'; import * as routes from './routes'; import {fetchTenants} from 'Duck/user'; import {setSessionPath} from 'Duck/sessions'; import {ModalProvider} from 'Components/Modal'; import {GLOBAL_DESTINATION_PATH, IFRAME, JWT_PARAM} from 'App/constants/storageKeys'; import PublicRoutes from 'App/PublicRoutes'; import Layout from 'App/layout/Layout'; import {fetchListActive as fetchMetadata} from 'Duck/customField'; import {init as initSite} from 'Duck/site'; import PrivateRoutes from 'App/PrivateRoutes'; import {checkParam} from 'App/utils'; import IFrameRoutes from 'App/IFrameRoutes'; import {ModalProvider as NewModalProvider} from 'Components/ModalContext'; interface RouterProps extends RouteComponentProps, ConnectedProps { isLoggedIn: boolean; sites: Map; loading: boolean; changePassword: boolean; isEnterprise: boolean; fetchUserInfo: () => any; fetchTenants: () => any; setSessionPath: (path: any) => any; fetchSiteList: (siteId?: number) => any; match: { params: { siteId: string; } }; mstore: any; setJwt: (jwt: string) => any; fetchMetadata: (siteId: string) => void; initSite: (site: any) => void; } const Router: React.FC = (props) => { const { isLoggedIn, siteId, sites, loading, location, fetchUserInfo, fetchSiteList, history, match: {params: {siteId: siteIdFromPath}}, setSessionPath, } = props; const [isIframe, setIsIframe] = React.useState(false); const [isJwt, setIsJwt] = React.useState(false); const handleJwtFromUrl = () => { const urlJWT = new URLSearchParams(location.search).get('jwt'); if (urlJWT) { props.setJwt(urlJWT); } }; const handleDestinationPath = () => { if (!isLoggedIn && location.pathname !== routes.login()) { localStorage.setItem(GLOBAL_DESTINATION_PATH, location.pathname + location.search); } }; const handleUserLogin = async () => { await fetchUserInfo(); const siteIdFromPath = parseInt(location.pathname.split('/')[1]); await fetchSiteList(siteIdFromPath); props.mstore.initClient(); const destinationPath = localStorage.getItem(GLOBAL_DESTINATION_PATH); if ( destinationPath && destinationPath !== routes.login() && destinationPath !== routes.signup() && destinationPath !== '/' ) { const url = new URL(destinationPath, window.location.origin); checkParams(url.search) history.push(destinationPath); localStorage.removeItem(GLOBAL_DESTINATION_PATH); } }; const checkParams = (search?: string) => { const _isIframe = checkParam('iframe', IFRAME, search); const _isJwt = checkParam('jwt', JWT_PARAM, search); setIsIframe(_isIframe); setIsJwt(_isJwt); } useEffect(() => { checkParams(); handleJwtFromUrl(); }, []); useEffect(() => { // handleJwtFromUrl(); handleDestinationPath(); setSessionPath(previousLocation ? previousLocation : location); }, [location]); useEffect(() => { if (prevIsLoggedIn !== isLoggedIn && isLoggedIn) { handleUserLogin(); } }, [isLoggedIn]); useEffect(() => { if (siteId && siteId !== lastFetchedSiteIdRef.current) { const activeSite = sites.find((s) => s.id == siteId); props.initSite(activeSite); props.fetchMetadata(siteId); lastFetchedSiteIdRef.current = siteId; } }, [siteId]); const lastFetchedSiteIdRef = useRef(null); function usePrevious(value: any) { const ref = useRef(); useEffect(() => { ref.current = value; }, [value]); return ref.current; } const prevIsLoggedIn = usePrevious(isLoggedIn); const previousLocation = usePrevious(location); const hideHeader = (location.pathname && location.pathname.includes('/session/')) || location.pathname.includes('/assist/') || location.pathname.includes('multiview'); if (isIframe) { return ; } return isLoggedIn ? ( ) : ; }; const mapStateToProps = (state: Map) => { const siteId = state.getIn(['site', 'siteId']); const jwt = state.getIn(['user', 'jwt']); const changePassword = state.getIn(['user', 'account', 'changePassword']); const userInfoLoading = state.getIn(['user', 'fetchUserInfoRequest', 'loading']); const sitesLoading = state.getIn(['site', 'fetchListRequest', 'loading']); return { siteId, changePassword, sites: state.getIn(['site', 'list']), isLoggedIn: jwt !== null && !changePassword, loading: siteId === null || userInfoLoading || sitesLoading, email: state.getIn(['user', 'account', 'email']), account: state.getIn(['user', 'account']), organisation: state.getIn(['user', 'account', 'name']), tenantId: state.getIn(['user', 'account', 'tenantId']), tenants: state.getIn(['user', 'tenants']), isEnterprise: state.getIn(['user', 'account', 'edition']) === 'ee' || state.getIn(['user', 'authDetails', 'edition']) === 'ee' }; }; const mapDispatchToProps = { fetchUserInfo, fetchTenants, setSessionPath, fetchSiteList, setJwt, fetchMetadata, initSite }; const connector = connect(mapStateToProps, mapDispatchToProps); export default withStore(withRouter(connector(Router)));