import React, { Suspense, lazy } from 'react'; import { Route, Switch } from 'react-router-dom'; import { hot } from 'react-hot-loader/root'; import { Helmet } from 'react-helmet'; import { ConnectedRouter } from 'connected-react-router'; import { Provider } from 'react-redux'; import { RedocStandalone } from 'redoc'; import { permaLinkPrefix } from './perfherder/perf-helpers/constants'; import { configureStore, history } from './job-view/redux/configureStore'; import LoadingSpinner from './shared/LoadingSpinner'; import LoginCallback from './login-callback/LoginCallback'; import TaskclusterCallback from './taskcluster-auth-callback/TaskclusterCallback'; import UserGuideApp from './userguide/App'; import treeFavicon from './img/tree_open.png'; import logFavicon from './img/logviewerIcon.png'; import perfFavicon from './img/line_chart.png'; import healthFavicon from './img/push-health-ok.png'; const IntermittentFailuresApp = lazy(() => import('./intermittent-failures/App'), ); const PerfherderApp = lazy(() => import('./perfherder/App')); const PushHealthApp = lazy(() => import('./push-health/App')); const JobsViewApp = lazy(() => import('./job-view/App')); const LogviewerApp = lazy(() => import('./logviewer/App')); // backwards compatibility for routes like this: treeherder.mozilla.org/perf.html#/alerts?id=26622&hideDwnToInv=0 const updateOldUrls = () => { const { pathname, hash, search } = history.location; const updates = {}; const urlMatch = { '/perf.html': '/perfherder', '/pushhealth.html': '/push-health', '/': '/jobs', }; if ( pathname.endsWith('.html') || (pathname === '/' && hash.length) || urlMatch[pathname] ) { updates.pathname = urlMatch[pathname] || pathname.replace(/.html|\//g, ''); } if (hash.length) { const index = hash.indexOf('?'); updates.search = hash.substring(index); const subRoute = hash.substring(1, index); // there are old subroutes such as with the logviewer we want to ignore, i.e.: // https://treeherder.mozilla.org/logviewer.html#/jobs?job_id=319893964&repo=autoland&lineNumber=2728 if (index >= 2 && updates.pathname !== subRoute && subRoute !== '/jobs') { updates.pathname += subRoute; } } else if (search.length) { updates.search = search; } if (Object.keys(updates).length === 0) { return; } history.push(updates); }; // the urls need to be update for compatibility reasons, but we need to have exceptions from this // the link created by the permalink functionality is broken by the updateOldUrls function // for more information - https://bugzilla.mozilla.org/show_bug.cgi?id=1725329 const updateUrls = () => { if (!history.location.hash.includes(permaLinkPrefix)) { updateOldUrls(); } }; const faviconPaths = { '/jobs': { title: 'Treeherder Jobs View', favicon: treeFavicon }, '/logviewer': { title: 'Treeherder Logviewer', favicon: logFavicon, }, '/perfherder': { title: 'Perfherder', favicon: perfFavicon }, '/userguide': { title: 'Treeherder User Guide', favicon: treeFavicon, }, '/intermittent-failures': { title: 'Intermittent Failures View', favicon: treeFavicon, }, '/push-health': { title: 'Push Health', favicon: healthFavicon, }, }; const withFavicon = (element, route) => { let { title } = faviconPaths[route]; const { favicon } = faviconPaths[route]; const searchParams = new URLSearchParams(history.location.search); const id = searchParams.get('id'); if (history.location.pathname === '/perfherder/alerts' && id) { title = `Alert #${id.toString()}`; } return ( {element} ); }; const App = () => { updateUrls(); return ( }> } /> } /> withFavicon(, props.location.pathname) } /> withFavicon( , props.location.pathname, ) } /> withFavicon( , props.location.pathname, ) } /> withFavicon(, '/push-health') } /> withFavicon( , '/intermittent-failures', ) } /> withFavicon(, '/perfherder') } /> ( )} /> ); }; export default hot(App);