routes.tsx 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922
  1. import * as React from 'react';
  2. import {
  3. IndexRedirect,
  4. IndexRoute as BaseIndexRoute,
  5. IndexRouteProps,
  6. Redirect,
  7. Route as BaseRoute,
  8. RouteProps,
  9. } from 'react-router';
  10. import LazyLoad from 'app/components/lazyLoad';
  11. import {EXPERIMENTAL_SPA} from 'app/constants';
  12. import {t} from 'app/locale';
  13. import HookStore from 'app/stores/hookStore';
  14. import {HookName} from 'app/types/hooks';
  15. import errorHandler from 'app/utils/errorHandler';
  16. import App from 'app/views/app';
  17. import AuthLayout from 'app/views/auth/layout';
  18. import IssueListContainer from 'app/views/issueList/container';
  19. import IssueListOverview from 'app/views/issueList/overview';
  20. import OrganizationContext from 'app/views/organizationContext';
  21. import OrganizationDetails, {
  22. LightWeightOrganizationDetails,
  23. } from 'app/views/organizationDetails';
  24. import {Tab} from 'app/views/organizationGroupDetails/types';
  25. import OrganizationRoot from 'app/views/organizationRoot';
  26. import ProjectEventRedirect from 'app/views/projectEventRedirect';
  27. import redirectDeprecatedProjectRoute from 'app/views/projects/redirectDeprecatedProjectRoute';
  28. import RouteNotFound from 'app/views/routeNotFound';
  29. import SettingsProjectProvider from 'app/views/settings/components/settingsProjectProvider';
  30. import SettingsWrapper from 'app/views/settings/components/settingsWrapper';
  31. type CustomProps = {
  32. name?: string;
  33. componentPromise?: () => Promise<any>;
  34. };
  35. /**
  36. * We add some additional props to our routes
  37. */
  38. const Route = BaseRoute as React.ComponentClass<RouteProps & CustomProps>;
  39. const IndexRoute = BaseIndexRoute as React.ComponentClass<IndexRouteProps & CustomProps>;
  40. /**
  41. * Use react-router to lazy load a route. Use this for codesplitting containers
  42. * (e.g. SettingsLayout)
  43. *
  44. * The typical method for lazy loading a route leaf node is using the
  45. * <LazyLoad> component + `componentPromise`
  46. *
  47. * For wrapper / layout views react-router handles the route tree better by
  48. * using getComponent with this lazyLoad helper. If we just use <LazyLoad> it
  49. * will end up having to re-render more components than necessary.
  50. */
  51. const lazyLoad =
  52. (load: () => Promise<any>): RouteProps['getComponent'] =>
  53. (_loc, cb) =>
  54. load().then(module => cb(null, module.default));
  55. const hook = (name: HookName) => HookStore.get(name).map(cb => cb());
  56. const SafeLazyLoad = errorHandler(LazyLoad);
  57. function routes() {
  58. const accountSettingsRoutes = (
  59. <React.Fragment>
  60. <IndexRedirect to="details/" />
  61. <Route
  62. path="details/"
  63. name="Details"
  64. componentPromise={() => import('app/views/settings/account/accountDetails')}
  65. component={SafeLazyLoad}
  66. />
  67. <Route path="notifications/" name="Notifications">
  68. <IndexRoute
  69. componentPromise={() =>
  70. import('app/views/settings/account/notifications/notificationSettings')
  71. }
  72. component={SafeLazyLoad}
  73. />
  74. <Route
  75. path=":fineTuneType/"
  76. name="Fine Tune Alerts"
  77. componentPromise={() =>
  78. import('app/views/settings/account/accountNotificationFineTuning')
  79. }
  80. component={SafeLazyLoad}
  81. />
  82. </Route>
  83. <Route
  84. path="emails/"
  85. name="Emails"
  86. componentPromise={() => import('app/views/settings/account/accountEmails')}
  87. component={SafeLazyLoad}
  88. />
  89. <Route
  90. path="authorizations/"
  91. componentPromise={() =>
  92. import('app/views/settings/account/accountAuthorizations')
  93. }
  94. component={SafeLazyLoad}
  95. />
  96. <Route name="Security" path="security/">
  97. <Route
  98. componentPromise={() =>
  99. import('app/views/settings/account/accountSecurity/accountSecurityWrapper')
  100. }
  101. component={SafeLazyLoad}
  102. >
  103. <IndexRoute
  104. componentPromise={() => import('app/views/settings/account/accountSecurity')}
  105. component={SafeLazyLoad}
  106. />
  107. <Route
  108. path="session-history/"
  109. name="Session History"
  110. componentPromise={() =>
  111. import('app/views/settings/account/accountSecurity/sessionHistory')
  112. }
  113. component={SafeLazyLoad}
  114. />
  115. <Route
  116. path="mfa/:authId/"
  117. name="Details"
  118. componentPromise={() =>
  119. import('app/views/settings/account/accountSecurity/accountSecurityDetails')
  120. }
  121. component={SafeLazyLoad}
  122. />
  123. </Route>
  124. <Route
  125. path="mfa/:authId/enroll/"
  126. name="Enroll"
  127. componentPromise={() =>
  128. import('app/views/settings/account/accountSecurity/accountSecurityEnroll')
  129. }
  130. component={SafeLazyLoad}
  131. />
  132. </Route>
  133. <Route
  134. path="subscriptions/"
  135. name="Subscriptions"
  136. componentPromise={() => import('app/views/settings/account/accountSubscriptions')}
  137. component={SafeLazyLoad}
  138. />
  139. <Route
  140. path="identities/"
  141. name="Identities"
  142. componentPromise={() => import('app/views/settings/account/accountIdentities')}
  143. component={SafeLazyLoad}
  144. />
  145. <Route path="api/" name="API">
  146. <IndexRedirect to="auth-tokens/" />
  147. <Route path="auth-tokens/" name="Auth Tokens">
  148. <IndexRoute
  149. componentPromise={() => import('app/views/settings/account/apiTokens')}
  150. component={SafeLazyLoad}
  151. />
  152. <Route
  153. path="new-token/"
  154. name="Create New Token"
  155. componentPromise={() => import('app/views/settings/account/apiNewToken')}
  156. component={SafeLazyLoad}
  157. />
  158. </Route>
  159. <Route path="applications/" name="Applications">
  160. <IndexRoute
  161. componentPromise={() => import('app/views/settings/account/apiApplications')}
  162. component={SafeLazyLoad}
  163. />
  164. <Route
  165. path=":appId/"
  166. name="Details"
  167. componentPromise={() =>
  168. import('app/views/settings/account/apiApplications/details')
  169. }
  170. component={SafeLazyLoad}
  171. />
  172. </Route>
  173. {hook('routes:api')}
  174. </Route>
  175. <Route
  176. path="close-account/"
  177. name="Close Account"
  178. componentPromise={() => import('app/views/settings/account/accountClose')}
  179. component={SafeLazyLoad}
  180. />
  181. </React.Fragment>
  182. );
  183. const projectSettingsRoutes = (
  184. <React.Fragment>
  185. <IndexRoute
  186. name="General"
  187. componentPromise={() => import('app/views/settings/projectGeneralSettings')}
  188. component={SafeLazyLoad}
  189. />
  190. <Route
  191. path="teams/"
  192. name="Teams"
  193. componentPromise={() => import('app/views/settings/project/projectTeams')}
  194. component={SafeLazyLoad}
  195. />
  196. <Route
  197. name="Alerts"
  198. path="alerts/"
  199. component={SafeLazyLoad}
  200. componentPromise={() => import('app/views/settings/projectAlerts')}
  201. >
  202. <IndexRoute
  203. component={SafeLazyLoad}
  204. componentPromise={() => import('app/views/settings/projectAlerts/settings')}
  205. />
  206. <Redirect from="new/" to="/organizations/:orgId/alerts/:projectId/new/" />
  207. <Redirect from="rules/" to="/organizations/:orgId/alerts/rules/" />
  208. <Redirect from="rules/new/" to="/organizations/:orgId/alerts/:projectId/new/" />
  209. <Redirect
  210. from="metric-rules/new/"
  211. to="/organizations/:orgId/alerts/:projectId/new/"
  212. />
  213. <Redirect
  214. from="rules/:ruleId/"
  215. to="/organizations/:orgId/alerts/rules/:projectId/:ruleId/"
  216. />
  217. <Redirect
  218. from="metric-rules/:ruleId/"
  219. to="/organizations/:orgId/alerts/metric-rules/:projectId/:ruleId/"
  220. />
  221. </Route>
  222. <Route
  223. name="Environments"
  224. path="environments/"
  225. componentPromise={() => import('app/views/settings/project/projectEnvironments')}
  226. component={SafeLazyLoad}
  227. >
  228. <IndexRoute />
  229. <Route path="hidden/" />
  230. </Route>
  231. <Route
  232. name="Tags"
  233. path="tags/"
  234. componentPromise={() => import('app/views/settings/projectTags')}
  235. component={SafeLazyLoad}
  236. />
  237. <Redirect from="issue-tracking/" to="/settings/:orgId/:projectId/plugins/" />
  238. <Route
  239. path="release-tracking/"
  240. name="Release Tracking"
  241. componentPromise={() =>
  242. import('app/views/settings/project/projectReleaseTracking')
  243. }
  244. component={SafeLazyLoad}
  245. />
  246. <Route
  247. path="ownership/"
  248. name="Issue Owners"
  249. componentPromise={() => import('app/views/settings/project/projectOwnership')}
  250. component={SafeLazyLoad}
  251. />
  252. <Route
  253. path="data-forwarding/"
  254. name="Data Forwarding"
  255. componentPromise={() => import('app/views/settings/projectDataForwarding')}
  256. component={SafeLazyLoad}
  257. />
  258. <Route
  259. name={t('Security & Privacy')}
  260. path="security-and-privacy/"
  261. component={SafeLazyLoad}
  262. componentPromise={() => import('app/views/settings/projectSecurityAndPrivacy')}
  263. />
  264. <Route
  265. path="debug-symbols/"
  266. name="Debug Information Files"
  267. componentPromise={() => import('app/views/settings/projectDebugFiles')}
  268. component={SafeLazyLoad}
  269. />
  270. <Route
  271. path="proguard/"
  272. name={t('ProGuard Mappings')}
  273. componentPromise={() => import('app/views/settings/projectProguard')}
  274. component={SafeLazyLoad}
  275. />
  276. <Route
  277. path="performance/"
  278. name={t('Performance')}
  279. componentPromise={() => import('app/views/settings/projectPerformance')}
  280. component={SafeLazyLoad}
  281. />
  282. <Route
  283. path="source-maps/"
  284. name={t('Source Maps')}
  285. componentPromise={() => import('app/views/settings/projectSourceMaps')}
  286. component={SafeLazyLoad}
  287. >
  288. <IndexRoute
  289. componentPromise={() => import('app/views/settings/projectSourceMaps/list')}
  290. component={SafeLazyLoad}
  291. />
  292. <Route
  293. path=":name/"
  294. name={t('Archive')}
  295. componentPromise={() => import('app/views/settings/projectSourceMaps/detail')}
  296. component={SafeLazyLoad}
  297. />
  298. </Route>
  299. <Route
  300. path="processing-issues/"
  301. name="Processing Issues"
  302. componentPromise={() =>
  303. import('app/views/settings/project/projectProcessingIssues')
  304. }
  305. component={SafeLazyLoad}
  306. />
  307. <Route
  308. path="filters/"
  309. name="Inbound Filters"
  310. componentPromise={() => import('app/views/settings/project/projectFilters')}
  311. component={SafeLazyLoad}
  312. >
  313. <IndexRedirect to="data-filters/" />
  314. <Route path=":filterType/" />
  315. </Route>
  316. <Route
  317. name={t('Filters & Sampling')}
  318. path="filters-and-sampling/"
  319. componentPromise={() => import('app/views/settings/project/filtersAndSampling')}
  320. component={SafeLazyLoad}
  321. />
  322. <Route
  323. path="issue-grouping/"
  324. name={t('Issue Grouping')}
  325. componentPromise={() => import('app/views/settings/projectIssueGrouping')}
  326. component={SafeLazyLoad}
  327. />
  328. <Route
  329. path="hooks/"
  330. name="Service Hooks"
  331. componentPromise={() => import('app/views/settings/project/projectServiceHooks')}
  332. component={SafeLazyLoad}
  333. />
  334. <Route
  335. path="hooks/new/"
  336. name="Create Service Hook"
  337. componentPromise={() =>
  338. import('app/views/settings/project/projectCreateServiceHook')
  339. }
  340. component={SafeLazyLoad}
  341. />
  342. <Route
  343. path="hooks/:hookId/"
  344. name="Service Hook Details"
  345. componentPromise={() =>
  346. import('app/views/settings/project/projectServiceHookDetails')
  347. }
  348. component={SafeLazyLoad}
  349. />
  350. <Route path="keys/" name="Client Keys">
  351. <IndexRoute
  352. componentPromise={() => import('app/views/settings/project/projectKeys/list')}
  353. component={SafeLazyLoad}
  354. />
  355. <Route
  356. path=":keyId/"
  357. name="Details"
  358. componentPromise={() =>
  359. import('app/views/settings/project/projectKeys/details')
  360. }
  361. component={SafeLazyLoad}
  362. />
  363. </Route>
  364. <Route
  365. path="user-feedback/"
  366. name="User Feedback"
  367. componentPromise={() => import('app/views/settings/project/projectUserFeedback')}
  368. component={SafeLazyLoad}
  369. />
  370. <Redirect from="csp/" to="security-headers/" />
  371. <Route path="security-headers/" name="Security Headers">
  372. <IndexRoute
  373. componentPromise={() => import('app/views/settings/projectSecurityHeaders')}
  374. component={SafeLazyLoad}
  375. />
  376. <Route
  377. path="csp/"
  378. name="Content Security Policy"
  379. componentPromise={() => import('app/views/settings/projectSecurityHeaders/csp')}
  380. component={SafeLazyLoad}
  381. />
  382. <Route
  383. path="expect-ct/"
  384. name="Certificate Transparency"
  385. componentPromise={() =>
  386. import('app/views/settings/projectSecurityHeaders/expectCt')
  387. }
  388. component={SafeLazyLoad}
  389. />
  390. <Route
  391. path="hpkp/"
  392. name="HPKP"
  393. componentPromise={() =>
  394. import('app/views/settings/projectSecurityHeaders/hpkp')
  395. }
  396. component={SafeLazyLoad}
  397. />
  398. </Route>
  399. <Route path="plugins/" name="Legacy Integrations">
  400. <IndexRoute
  401. componentPromise={() => import('app/views/settings/projectPlugins')}
  402. component={SafeLazyLoad}
  403. />
  404. <Route
  405. path=":pluginId/"
  406. name="Integration Details"
  407. componentPromise={() => import('app/views/settings/projectPlugins/details')}
  408. component={SafeLazyLoad}
  409. />
  410. </Route>
  411. <Route path="install/" name="Configuration">
  412. <IndexRoute
  413. componentPromise={() => import('app/views/projectInstall/overview')}
  414. component={SafeLazyLoad}
  415. />
  416. <Route
  417. path=":platform/"
  418. name="Docs"
  419. componentPromise={() =>
  420. import('app/views/projectInstall/platformOrIntegration')
  421. }
  422. component={SafeLazyLoad}
  423. />
  424. </Route>
  425. </React.Fragment>
  426. );
  427. // This is declared in the routes() function because some routes need the
  428. // hook store which is not available at import time.
  429. const orgSettingsRoutes = (
  430. <React.Fragment>
  431. <IndexRoute
  432. name="General"
  433. componentPromise={() => import('app/views/settings/organizationGeneralSettings')}
  434. component={SafeLazyLoad}
  435. />
  436. <Route
  437. path="projects/"
  438. name="Projects"
  439. componentPromise={() => import('app/views/settings/organizationProjects')}
  440. component={SafeLazyLoad}
  441. />
  442. <Route path="api-keys/" name="API Key">
  443. <IndexRoute
  444. componentPromise={() => import('app/views/settings/organizationApiKeys')}
  445. component={SafeLazyLoad}
  446. />
  447. <Route
  448. path=":apiKey/"
  449. name="Details"
  450. componentPromise={() =>
  451. import('app/views/settings/organizationApiKeys/organizationApiKeyDetails')
  452. }
  453. component={SafeLazyLoad}
  454. />
  455. </Route>
  456. <Route
  457. path="audit-log/"
  458. name="Audit Log"
  459. componentPromise={() => import('app/views/settings/organizationAuditLog')}
  460. component={SafeLazyLoad}
  461. />
  462. <Route
  463. path="auth/"
  464. name="Auth Providers"
  465. componentPromise={() => import('app/views/settings/organizationAuth')}
  466. component={SafeLazyLoad}
  467. />
  468. <Redirect from="members/requests" to="members/" />
  469. <Route path="members/" name="Members">
  470. <Route
  471. componentPromise={() =>
  472. import('app/views/settings/organizationMembers/organizationMembersWrapper')
  473. }
  474. component={SafeLazyLoad}
  475. >
  476. <IndexRoute
  477. componentPromise={() =>
  478. import('app/views/settings/organizationMembers/organizationMembersList')
  479. }
  480. component={SafeLazyLoad}
  481. />
  482. </Route>
  483. <Route
  484. path=":memberId/"
  485. name="Details"
  486. componentPromise={() =>
  487. import('app/views/settings/organizationMembers/organizationMemberDetail')
  488. }
  489. component={SafeLazyLoad}
  490. />
  491. </Route>
  492. <Route
  493. path="rate-limits/"
  494. name="Rate Limits"
  495. componentPromise={() => import('app/views/settings/organizationRateLimits')}
  496. component={SafeLazyLoad}
  497. />
  498. <Route
  499. name={t('Relay')}
  500. path="relay/"
  501. componentPromise={() => import('app/views/settings/organizationRelay')}
  502. component={SafeLazyLoad}
  503. />
  504. <Route
  505. path="repos/"
  506. name="Repositories"
  507. componentPromise={() => import('app/views/settings/organizationRepositories')}
  508. component={SafeLazyLoad}
  509. />
  510. <Route
  511. path="performance/"
  512. name={t('Performance')}
  513. componentPromise={() => import('app/views/settings/organizationPerformance')}
  514. component={SafeLazyLoad}
  515. />
  516. <Route
  517. path="settings/"
  518. componentPromise={() => import('app/views/settings/organizationGeneralSettings')}
  519. component={SafeLazyLoad}
  520. />
  521. <Route
  522. name={t('Security & Privacy')}
  523. path="security-and-privacy/"
  524. componentPromise={() =>
  525. import('app/views/settings/organizationSecurityAndPrivacy')
  526. }
  527. component={SafeLazyLoad}
  528. />
  529. <Route name="Teams" path="teams/">
  530. <IndexRoute
  531. componentPromise={() => import('app/views/settings/organizationTeams')}
  532. component={SafeLazyLoad}
  533. />
  534. <Route
  535. name="Team"
  536. path=":teamId/"
  537. componentPromise={() =>
  538. import('app/views/settings/organizationTeams/teamDetails')
  539. }
  540. component={SafeLazyLoad}
  541. >
  542. <IndexRedirect to="members/" />
  543. <Route
  544. path="members/"
  545. name="Members"
  546. componentPromise={() =>
  547. import('app/views/settings/organizationTeams/teamMembers')
  548. }
  549. component={SafeLazyLoad}
  550. />
  551. <Route
  552. path="notifications/"
  553. name="Notifications"
  554. componentPromise={() =>
  555. import('app/views/settings/organizationTeams/teamNotifications')
  556. }
  557. component={SafeLazyLoad}
  558. />
  559. <Route
  560. path="projects/"
  561. name="Projects"
  562. componentPromise={() =>
  563. import('app/views/settings/organizationTeams/teamProjects')
  564. }
  565. component={SafeLazyLoad}
  566. />
  567. <Route
  568. path="settings/"
  569. name="Settings"
  570. componentPromise={() =>
  571. import('app/views/settings/organizationTeams/teamSettings')
  572. }
  573. component={SafeLazyLoad}
  574. />
  575. </Route>
  576. </Route>
  577. <Redirect from="plugins/" to="integrations/" />
  578. <Route name="Integrations" path="plugins/">
  579. <Route
  580. name="Integration Details"
  581. path=":integrationSlug/"
  582. componentPromise={() =>
  583. import('app/views/organizationIntegrations/pluginDetailedView')
  584. }
  585. component={SafeLazyLoad}
  586. />
  587. </Route>
  588. <Redirect from="sentry-apps/" to="integrations/" />
  589. <Route name="Integrations" path="sentry-apps/">
  590. <Route
  591. name="Details"
  592. path=":integrationSlug"
  593. componentPromise={() =>
  594. import('app/views/organizationIntegrations/sentryAppDetailedView')
  595. }
  596. component={SafeLazyLoad}
  597. />
  598. </Route>
  599. <Redirect from="document-integrations/" to="integrations/" />
  600. <Route name="Integrations" path="document-integrations/">
  601. <Route
  602. name="Details"
  603. path=":integrationSlug"
  604. componentPromise={() =>
  605. import('app/views/organizationIntegrations/docIntegrationDetailedView')
  606. }
  607. component={SafeLazyLoad}
  608. />
  609. </Route>
  610. <Route name="Integrations" path="integrations/">
  611. <IndexRoute
  612. componentPromise={() =>
  613. import('app/views/organizationIntegrations/integrationListDirectory')
  614. }
  615. component={SafeLazyLoad}
  616. />
  617. <Route
  618. name="Integration Details"
  619. path=":integrationSlug"
  620. componentPromise={() =>
  621. import('app/views/organizationIntegrations/integrationDetailedView')
  622. }
  623. component={SafeLazyLoad}
  624. />
  625. <Route
  626. name="Configure Integration"
  627. path=":providerKey/:integrationId/"
  628. componentPromise={() =>
  629. import('app/views/settings/organizationIntegrations/configureIntegration')
  630. }
  631. component={SafeLazyLoad}
  632. />
  633. </Route>
  634. <Route name="Developer Settings" path="developer-settings/">
  635. <IndexRoute
  636. componentPromise={() =>
  637. import('app/views/settings/organizationDeveloperSettings')
  638. }
  639. component={SafeLazyLoad}
  640. />
  641. <Route
  642. name="New Public Integration"
  643. path="new-public/"
  644. componentPromise={() =>
  645. import(
  646. 'app/views/settings/organizationDeveloperSettings/sentryApplicationDetails'
  647. )
  648. }
  649. component={SafeLazyLoad}
  650. />
  651. <Route
  652. name="New Internal Integration"
  653. path="new-internal/"
  654. componentPromise={() =>
  655. import(
  656. 'app/views/settings/organizationDeveloperSettings/sentryApplicationDetails'
  657. )
  658. }
  659. component={SafeLazyLoad}
  660. />
  661. <Route
  662. name="Edit Integration"
  663. path=":appSlug/"
  664. componentPromise={() =>
  665. import(
  666. 'app/views/settings/organizationDeveloperSettings/sentryApplicationDetails'
  667. )
  668. }
  669. component={SafeLazyLoad}
  670. />
  671. <Route
  672. name="Integration Dashboard"
  673. path=":appSlug/dashboard/"
  674. componentPromise={() =>
  675. import(
  676. 'app/views/settings/organizationDeveloperSettings/sentryApplicationDashboard'
  677. )
  678. }
  679. component={SafeLazyLoad}
  680. />
  681. </Route>
  682. </React.Fragment>
  683. );
  684. return (
  685. <Route>
  686. {EXPERIMENTAL_SPA && (
  687. <Route path="/auth/login/" component={errorHandler(AuthLayout)}>
  688. <IndexRoute
  689. componentPromise={() => import('app/views/auth/login')}
  690. component={SafeLazyLoad}
  691. />
  692. </Route>
  693. )}
  694. <Route path="/" component={errorHandler(App)}>
  695. <IndexRoute
  696. componentPromise={() => import('app/views/app/root')}
  697. component={SafeLazyLoad}
  698. />
  699. <Route
  700. path="/accept/:memberId/:token/"
  701. componentPromise={() => import('app/views/acceptOrganizationInvite')}
  702. component={SafeLazyLoad}
  703. />
  704. <Route
  705. path="/accept-transfer/"
  706. componentPromise={() => import('app/views/acceptProjectTransfer')}
  707. component={SafeLazyLoad}
  708. />
  709. <Route
  710. path="/extensions/external-install/:integrationSlug/:installationId"
  711. componentPromise={() => import('app/views/integrationOrganizationLink')}
  712. component={SafeLazyLoad}
  713. />
  714. <Route
  715. path="/extensions/:integrationSlug/link/"
  716. getComponent={lazyLoad(() => import('app/views/integrationOrganizationLink'))}
  717. />
  718. <Route
  719. path="/sentry-apps/:sentryAppSlug/external-install/"
  720. componentPromise={() => import('app/views/sentryAppExternalInstallation')}
  721. component={SafeLazyLoad}
  722. />
  723. <Redirect from="/account/" to="/settings/account/details/" />
  724. <Redirect from="/share/group/:shareId/" to="/share/issue/:shareId/" />
  725. <Route
  726. path="/share/issue/:shareId/"
  727. componentPromise={() => import('app/views/sharedGroupDetails')}
  728. component={SafeLazyLoad}
  729. />
  730. <Route
  731. path="/organizations/new/"
  732. componentPromise={() => import('app/views/organizationCreate')}
  733. component={SafeLazyLoad}
  734. />
  735. <Route
  736. path="/organizations/:orgId/data-export/:dataExportId"
  737. componentPromise={() => import('app/views/dataExport/dataDownload')}
  738. component={SafeLazyLoad}
  739. />
  740. <Route
  741. path="/organizations/:orgId/disabled-member/"
  742. componentPromise={() => import('app/views/disabledMember')}
  743. component={SafeLazyLoad}
  744. />
  745. <Route
  746. path="/join-request/:orgId/"
  747. componentPromise={() => import('app/views/organizationJoinRequest')}
  748. component={SafeLazyLoad}
  749. />
  750. <Route path="/onboarding/:orgId/" component={errorHandler(OrganizationContext)}>
  751. <IndexRedirect to="welcome/" />
  752. <Route
  753. path=":step/"
  754. componentPromise={() => import('app/views/onboarding/onboarding')}
  755. component={SafeLazyLoad}
  756. />
  757. </Route>
  758. {/* Settings routes */}
  759. <Route component={errorHandler(OrganizationDetails)}>
  760. <Route path="/settings/" name="Settings" component={SettingsWrapper}>
  761. <IndexRoute
  762. getComponent={lazyLoad(() => import('app/views/settings/settingsIndex'))}
  763. />
  764. <Route
  765. path="account/"
  766. name="Account"
  767. getComponent={lazyLoad(
  768. () => import('app/views/settings/account/accountSettingsLayout')
  769. )}
  770. >
  771. {accountSettingsRoutes}
  772. </Route>
  773. <Route name="Organization" path=":orgId/">
  774. <Route
  775. getComponent={lazyLoad(
  776. () =>
  777. import('app/views/settings/organization/organizationSettingsLayout')
  778. )}
  779. >
  780. {hook('routes:organization')}
  781. {orgSettingsRoutes}
  782. </Route>
  783. <Route
  784. name="Project"
  785. path="projects/:projectId/"
  786. getComponent={lazyLoad(
  787. () => import('app/views/settings/project/projectSettingsLayout')
  788. )}
  789. >
  790. <Route component={errorHandler(SettingsProjectProvider)}>
  791. {projectSettingsRoutes}
  792. </Route>
  793. </Route>
  794. <Redirect from=":projectId/" to="projects/:projectId/" />
  795. <Redirect from=":projectId/alerts/" to="projects/:projectId/alerts/" />
  796. <Redirect
  797. from=":projectId/alerts/rules/"
  798. to="projects/:projectId/alerts/rules/"
  799. />
  800. <Redirect
  801. from=":projectId/alerts/rules/:ruleId/"
  802. to="projects/:projectId/alerts/rules/:ruleId/"
  803. />
  804. </Route>
  805. </Route>
  806. </Route>
  807. {/* A route tree for lightweight organizational detail views. We place
  808. this above the heavyweight organization detail views because there
  809. exist some redirects from deprecated routes which should not take
  810. precedence over these lightweight routes */}
  811. <Route component={errorHandler(LightWeightOrganizationDetails)}>
  812. <Route
  813. path="/organizations/:orgId/projects/"
  814. componentPromise={() => import('app/views/projectsDashboard')}
  815. component={SafeLazyLoad}
  816. />
  817. <Route
  818. path="/organizations/:orgId/dashboards/"
  819. componentPromise={() => import('app/views/dashboardsV2')}
  820. component={SafeLazyLoad}
  821. >
  822. <IndexRoute
  823. componentPromise={() => import('app/views/dashboardsV2/manage')}
  824. component={SafeLazyLoad}
  825. />
  826. </Route>
  827. <Route
  828. path="/organizations/:orgId/user-feedback/"
  829. componentPromise={() => import('app/views/userFeedback')}
  830. component={SafeLazyLoad}
  831. />
  832. <Route
  833. path="/organizations/:orgId/issues/"
  834. component={errorHandler(IssueListContainer)}
  835. >
  836. <Redirect from="/organizations/:orgId/" to="/organizations/:orgId/issues/" />
  837. <IndexRoute component={errorHandler(IssueListOverview)} />
  838. <Route
  839. path="searches/:searchId/"
  840. component={errorHandler(IssueListOverview)}
  841. />
  842. <Route
  843. path="sessionPercent"
  844. componentPromise={() => import('app/views/issueList/testSessionPercent')}
  845. component={SafeLazyLoad}
  846. />
  847. </Route>
  848. {/* Once org issues is complete, these routes can be nested under
  849. /organizations/:orgId/issues */}
  850. <Route
  851. path="/organizations/:orgId/issues/:groupId/"
  852. componentPromise={() => import('app/views/organizationGroupDetails')}
  853. component={SafeLazyLoad}
  854. >
  855. <IndexRoute
  856. componentPromise={() =>
  857. import('app/views/organizationGroupDetails/groupEventDetails')
  858. }
  859. component={SafeLazyLoad}
  860. props={{
  861. currentTab: Tab.DETAILS,
  862. isEventRoute: false,
  863. }}
  864. />
  865. <Route
  866. path="/organizations/:orgId/issues/:groupId/activity/"
  867. componentPromise={() =>
  868. import('app/views/organizationGroupDetails/groupActivity')
  869. }
  870. component={SafeLazyLoad}
  871. props={{
  872. currentTab: Tab.ACTIVITY,
  873. isEventRoute: false,
  874. }}
  875. />
  876. <Route
  877. path="/organizations/:orgId/issues/:groupId/events/"
  878. componentPromise={() =>
  879. import('app/views/organizationGroupDetails/groupEvents')
  880. }
  881. component={SafeLazyLoad}
  882. props={{
  883. currentTab: Tab.EVENTS,
  884. isEventRoute: false,
  885. }}
  886. />
  887. <Route
  888. path="/organizations/:orgId/issues/:groupId/tags/"
  889. componentPromise={() =>
  890. import('app/views/organizationGroupDetails/groupTags')
  891. }
  892. component={SafeLazyLoad}
  893. props={{
  894. currentTab: Tab.TAGS,
  895. isEventRoute: false,
  896. }}
  897. />
  898. <Route
  899. path="/organizations/:orgId/issues/:groupId/tags/:tagKey/"
  900. componentPromise={() =>
  901. import('app/views/organizationGroupDetails/groupTagValues')
  902. }
  903. component={SafeLazyLoad}
  904. props={{
  905. currentTab: Tab.TAGS,
  906. isEventRoute: false,
  907. }}
  908. />
  909. <Route
  910. path="/organizations/:orgId/issues/:groupId/feedback/"
  911. componentPromise={() =>
  912. import('app/views/organizationGroupDetails/groupUserFeedback')
  913. }
  914. component={SafeLazyLoad}
  915. props={{
  916. currentTab: Tab.USER_FEEDBACK,
  917. isEventRoute: false,
  918. }}
  919. />
  920. <Route
  921. path="/organizations/:orgId/issues/:groupId/attachments/"
  922. componentPromise={() =>
  923. import('app/views/organizationGroupDetails/groupEventAttachments')
  924. }
  925. component={SafeLazyLoad}
  926. props={{
  927. currentTab: Tab.ATTACHMENTS,
  928. isEventRoute: false,
  929. }}
  930. />
  931. <Route
  932. path="/organizations/:orgId/issues/:groupId/similar/"
  933. componentPromise={() =>
  934. import('app/views/organizationGroupDetails/groupSimilarIssues')
  935. }
  936. component={SafeLazyLoad}
  937. props={{
  938. currentTab: Tab.SIMILAR_ISSUES,
  939. isEventRoute: false,
  940. }}
  941. />
  942. <Route
  943. path="/organizations/:orgId/issues/:groupId/merged/"
  944. componentPromise={() =>
  945. import('app/views/organizationGroupDetails/groupMerged')
  946. }
  947. component={SafeLazyLoad}
  948. props={{
  949. currentTab: Tab.MERGED,
  950. isEventRoute: false,
  951. }}
  952. />
  953. <Route
  954. path="/organizations/:orgId/issues/:groupId/grouping/"
  955. componentPromise={() =>
  956. import('app/views/organizationGroupDetails/grouping')
  957. }
  958. component={SafeLazyLoad}
  959. props={{
  960. currentTab: Tab.GROUPING,
  961. isEventRoute: false,
  962. }}
  963. />
  964. <Route path="/organizations/:orgId/issues/:groupId/events/:eventId/">
  965. <IndexRoute
  966. componentPromise={() =>
  967. import('app/views/organizationGroupDetails/groupEventDetails')
  968. }
  969. component={SafeLazyLoad}
  970. props={{
  971. currentTab: Tab.DETAILS,
  972. isEventRoute: true,
  973. }}
  974. />
  975. <Route
  976. path="activity/"
  977. componentPromise={() =>
  978. import('app/views/organizationGroupDetails/groupActivity')
  979. }
  980. component={SafeLazyLoad}
  981. props={{
  982. currentTab: Tab.ACTIVITY,
  983. isEventRoute: true,
  984. }}
  985. />
  986. <Route
  987. path="events/"
  988. componentPromise={() =>
  989. import('app/views/organizationGroupDetails/groupEvents')
  990. }
  991. component={SafeLazyLoad}
  992. props={{
  993. currentTab: Tab.EVENTS,
  994. isEventRoute: true,
  995. }}
  996. />
  997. <Route
  998. path="similar/"
  999. componentPromise={() =>
  1000. import('app/views/organizationGroupDetails/groupSimilarIssues')
  1001. }
  1002. component={SafeLazyLoad}
  1003. props={{
  1004. currentTab: Tab.SIMILAR_ISSUES,
  1005. isEventRoute: true,
  1006. }}
  1007. />
  1008. <Route
  1009. path="tags/"
  1010. componentPromise={() =>
  1011. import('app/views/organizationGroupDetails/groupTags')
  1012. }
  1013. component={SafeLazyLoad}
  1014. props={{
  1015. currentTab: Tab.TAGS,
  1016. isEventRoute: true,
  1017. }}
  1018. />
  1019. <Route
  1020. path="tags/:tagKey/"
  1021. componentPromise={() =>
  1022. import('app/views/organizationGroupDetails/groupTagValues')
  1023. }
  1024. component={SafeLazyLoad}
  1025. props={{
  1026. currentTab: Tab.TAGS,
  1027. isEventRoute: true,
  1028. }}
  1029. />
  1030. <Route
  1031. path="feedback/"
  1032. componentPromise={() =>
  1033. import('app/views/organizationGroupDetails/groupUserFeedback')
  1034. }
  1035. component={SafeLazyLoad}
  1036. props={{
  1037. currentTab: Tab.USER_FEEDBACK,
  1038. isEventRoute: true,
  1039. }}
  1040. />
  1041. <Route
  1042. path="attachments/"
  1043. componentPromise={() =>
  1044. import('app/views/organizationGroupDetails/groupEventAttachments')
  1045. }
  1046. component={SafeLazyLoad}
  1047. props={{
  1048. currentTab: Tab.ATTACHMENTS,
  1049. isEventRoute: true,
  1050. }}
  1051. />
  1052. <Route
  1053. path="merged/"
  1054. componentPromise={() =>
  1055. import('app/views/organizationGroupDetails/groupMerged')
  1056. }
  1057. component={SafeLazyLoad}
  1058. props={{
  1059. currentTab: Tab.MERGED,
  1060. isEventRoute: true,
  1061. }}
  1062. />
  1063. <Route
  1064. path="grouping/"
  1065. componentPromise={() =>
  1066. import('app/views/organizationGroupDetails/grouping')
  1067. }
  1068. component={SafeLazyLoad}
  1069. props={{
  1070. currentTab: Tab.GROUPING,
  1071. isEventRoute: true,
  1072. }}
  1073. />
  1074. </Route>
  1075. </Route>
  1076. <Route
  1077. path="/organizations/:orgId/alerts/"
  1078. componentPromise={() => import('app/views/alerts')}
  1079. component={SafeLazyLoad}
  1080. >
  1081. <IndexRoute
  1082. componentPromise={() => import('app/views/alerts/list')}
  1083. component={SafeLazyLoad}
  1084. />
  1085. <Route
  1086. path="rules/details/:ruleId/"
  1087. name="Alert Rule Details"
  1088. component={SafeLazyLoad}
  1089. componentPromise={() => import('app/views/alerts/rules/details')}
  1090. />
  1091. <Route path="rules/">
  1092. <IndexRoute
  1093. component={SafeLazyLoad}
  1094. componentPromise={() => import('app/views/alerts/rules')}
  1095. />
  1096. <Route
  1097. path=":projectId/"
  1098. componentPromise={() =>
  1099. import('app/views/alerts/builder/projectProvider')
  1100. }
  1101. component={SafeLazyLoad}
  1102. >
  1103. <IndexRedirect to="/organizations/:orgId/alerts/rules/" />
  1104. <Route
  1105. path=":ruleId/"
  1106. name="Edit Alert Rule"
  1107. componentPromise={() => import('app/views/alerts/edit')}
  1108. component={SafeLazyLoad}
  1109. />
  1110. </Route>
  1111. </Route>
  1112. <Route path="metric-rules/">
  1113. <IndexRedirect to="/organizations/:orgId/alerts/rules/" />
  1114. <Route
  1115. path=":projectId/"
  1116. componentPromise={() =>
  1117. import('app/views/alerts/builder/projectProvider')
  1118. }
  1119. component={SafeLazyLoad}
  1120. >
  1121. <IndexRedirect to="/organizations/:orgId/alerts/rules/" />
  1122. <Route
  1123. path=":ruleId/"
  1124. name="Edit Alert Rule"
  1125. componentPromise={() => import('app/views/alerts/edit')}
  1126. component={SafeLazyLoad}
  1127. />
  1128. </Route>
  1129. </Route>
  1130. <Route
  1131. path="rules/"
  1132. componentPromise={() => import('app/views/alerts/rules')}
  1133. component={SafeLazyLoad}
  1134. />
  1135. <Route
  1136. path=":alertId/"
  1137. componentPromise={() => import('app/views/alerts/details')}
  1138. component={SafeLazyLoad}
  1139. />
  1140. <Route
  1141. path=":projectId/"
  1142. componentPromise={() => import('app/views/alerts/builder/projectProvider')}
  1143. component={SafeLazyLoad}
  1144. >
  1145. <Route
  1146. path="new/"
  1147. name="New Alert Rule"
  1148. component={SafeLazyLoad}
  1149. componentPromise={() => import('app/views/alerts/create')}
  1150. />
  1151. <Route
  1152. path="wizard/"
  1153. name="Alert Creation Wizard"
  1154. component={SafeLazyLoad}
  1155. componentPromise={() => import('app/views/alerts/wizard')}
  1156. />
  1157. </Route>
  1158. </Route>
  1159. <Route
  1160. path="/organizations/:orgId/monitors/"
  1161. componentPromise={() => import('app/views/monitors')}
  1162. component={SafeLazyLoad}
  1163. >
  1164. <IndexRoute
  1165. componentPromise={() => import('app/views/monitors/monitors')}
  1166. component={SafeLazyLoad}
  1167. />
  1168. <Route
  1169. path="/organizations/:orgId/monitors/create/"
  1170. componentPromise={() => import('app/views/monitors/create')}
  1171. component={SafeLazyLoad}
  1172. />
  1173. <Route
  1174. path="/organizations/:orgId/monitors/:monitorId/"
  1175. componentPromise={() => import('app/views/monitors/details')}
  1176. component={SafeLazyLoad}
  1177. />
  1178. <Route
  1179. path="/organizations/:orgId/monitors/:monitorId/edit/"
  1180. componentPromise={() => import('app/views/monitors/edit')}
  1181. component={SafeLazyLoad}
  1182. />
  1183. </Route>
  1184. <Route
  1185. path="/organizations/:orgId/releases/"
  1186. componentPromise={() => import('app/views/releases')}
  1187. component={SafeLazyLoad}
  1188. >
  1189. <IndexRoute
  1190. componentPromise={() => import('app/views/releases/list')}
  1191. component={SafeLazyLoad}
  1192. />
  1193. <Route
  1194. path=":release/"
  1195. componentPromise={() => import('app/views/releases/detail')}
  1196. component={SafeLazyLoad}
  1197. >
  1198. <IndexRoute
  1199. componentPromise={() => import('app/views/releases/detail/overview')}
  1200. component={SafeLazyLoad}
  1201. />
  1202. <Route
  1203. path="commits/"
  1204. componentPromise={() => import('app/views/releases/detail/commits')}
  1205. component={SafeLazyLoad}
  1206. />
  1207. <Route
  1208. path="files-changed/"
  1209. componentPromise={() => import('app/views/releases/detail/filesChanged')}
  1210. component={SafeLazyLoad}
  1211. />
  1212. <Redirect
  1213. from="new-events/"
  1214. to="/organizations/:orgId/releases/:release/"
  1215. />
  1216. <Redirect
  1217. from="all-events/"
  1218. to="/organizations/:orgId/releases/:release/"
  1219. />
  1220. </Route>
  1221. </Route>
  1222. <Route
  1223. path="/organizations/:orgId/activity/"
  1224. componentPromise={() => import('app/views/organizationActivity')}
  1225. component={SafeLazyLoad}
  1226. />
  1227. <Route
  1228. path="/organizations/:orgId/stats/"
  1229. componentPromise={() => import('app/views/organizationStats')}
  1230. component={SafeLazyLoad}
  1231. />
  1232. <Route
  1233. path="/organizations/:orgId/projects/:projectId/events/:eventId/"
  1234. component={errorHandler(ProjectEventRedirect)}
  1235. />
  1236. {/*
  1237. TODO(mark) Long term this /queries route should go away and /discover should be the
  1238. canonical route for discover2. We have a redirect right now as /discover was for
  1239. discover 1 and most of the application is linking to /discover/queries and not /discover
  1240. */}
  1241. <Redirect
  1242. from="/organizations/:orgId/discover/"
  1243. to="/organizations/:orgId/discover/queries/"
  1244. />
  1245. <Route
  1246. path="/organizations/:orgId/discover/"
  1247. componentPromise={() => import('app/views/eventsV2')}
  1248. component={SafeLazyLoad}
  1249. >
  1250. <Route
  1251. path="queries/"
  1252. componentPromise={() => import('app/views/eventsV2/landing')}
  1253. component={SafeLazyLoad}
  1254. />
  1255. <Route
  1256. path="results/"
  1257. componentPromise={() => import('app/views/eventsV2/results')}
  1258. component={SafeLazyLoad}
  1259. />
  1260. <Route
  1261. path=":eventSlug/"
  1262. componentPromise={() => import('app/views/eventsV2/eventDetails')}
  1263. component={SafeLazyLoad}
  1264. />
  1265. </Route>
  1266. <Route
  1267. path="/organizations/:orgId/performance/"
  1268. componentPromise={() => import('app/views/performance')}
  1269. component={SafeLazyLoad}
  1270. >
  1271. <IndexRoute
  1272. componentPromise={() => import('app/views/performance/content')}
  1273. component={SafeLazyLoad}
  1274. />
  1275. </Route>
  1276. <Route
  1277. path="/organizations/:orgId/performance/trends/"
  1278. componentPromise={() => import('app/views/performance')}
  1279. component={SafeLazyLoad}
  1280. >
  1281. <IndexRoute
  1282. componentPromise={() => import('app/views/performance/trends')}
  1283. component={SafeLazyLoad}
  1284. />
  1285. </Route>
  1286. <Route
  1287. path="/organizations/:orgId/performance/summary/"
  1288. componentPromise={() => import('app/views/performance')}
  1289. component={SafeLazyLoad}
  1290. >
  1291. <IndexRoute
  1292. componentPromise={() =>
  1293. import('app/views/performance/transactionSummary/transactionOverview')
  1294. }
  1295. component={SafeLazyLoad}
  1296. />
  1297. <Route
  1298. path="/organizations/:orgId/performance/summary/vitals/"
  1299. componentPromise={() =>
  1300. import('app/views/performance/transactionSummary/transactionVitals')
  1301. }
  1302. component={SafeLazyLoad}
  1303. />
  1304. <Route
  1305. path="/organizations/:orgId/performance/summary/tags/"
  1306. componentPromise={() =>
  1307. import('app/views/performance/transactionSummary/transactionTags')
  1308. }
  1309. component={SafeLazyLoad}
  1310. />
  1311. <Route
  1312. path="/organizations/:orgId/performance/summary/events/"
  1313. componentPromise={() =>
  1314. import('app/views/performance/transactionSummary/transactionEvents')
  1315. }
  1316. component={SafeLazyLoad}
  1317. />
  1318. </Route>
  1319. <Route
  1320. path="/organizations/:orgId/performance/vitaldetail/"
  1321. componentPromise={() => import('app/views/performance')}
  1322. component={SafeLazyLoad}
  1323. >
  1324. <IndexRoute
  1325. componentPromise={() => import('app/views/performance/vitalDetail')}
  1326. component={SafeLazyLoad}
  1327. />
  1328. </Route>
  1329. <Route
  1330. path="/organizations/:orgId/performance/trace/:traceSlug/"
  1331. componentPromise={() => import('app/views/performance')}
  1332. component={SafeLazyLoad}
  1333. >
  1334. <IndexRoute
  1335. componentPromise={() => import('app/views/performance/traceDetails')}
  1336. component={SafeLazyLoad}
  1337. />
  1338. </Route>
  1339. <Route
  1340. path="/organizations/:orgId/performance/:eventSlug/"
  1341. componentPromise={() => import('app/views/performance')}
  1342. component={SafeLazyLoad}
  1343. >
  1344. <IndexRoute
  1345. componentPromise={() => import('app/views/performance/transactionDetails')}
  1346. component={SafeLazyLoad}
  1347. />
  1348. </Route>
  1349. <Route
  1350. path="/organizations/:orgId/performance/compare/:baselineEventSlug/:regressionEventSlug/"
  1351. componentPromise={() => import('app/views/performance')}
  1352. component={SafeLazyLoad}
  1353. >
  1354. <IndexRoute
  1355. componentPromise={() => import('app/views/performance/compare')}
  1356. component={SafeLazyLoad}
  1357. />
  1358. </Route>
  1359. <Route
  1360. path="/organizations/:orgId/dashboards/new/"
  1361. componentPromise={() => import('app/views/dashboardsV2/create')}
  1362. component={SafeLazyLoad}
  1363. >
  1364. <Route
  1365. path="widget/:widgetId/edit/"
  1366. componentPromise={() => import('app/views/dashboardsV2/widget')}
  1367. component={SafeLazyLoad}
  1368. />
  1369. <Route
  1370. path="widget/new/"
  1371. componentPromise={() => import('app/views/dashboardsV2/widget')}
  1372. component={SafeLazyLoad}
  1373. />
  1374. </Route>
  1375. <Redirect
  1376. from="/organizations/:orgId/dashboards/:dashboardId/"
  1377. to="/organizations/:orgId/dashboard/:dashboardId/"
  1378. />
  1379. <Route
  1380. path="/organizations/:orgId/dashboard/:dashboardId/"
  1381. componentPromise={() => import('app/views/dashboardsV2/view')}
  1382. component={SafeLazyLoad}
  1383. >
  1384. <Route
  1385. path="widget/:widgetId/edit/"
  1386. componentPromise={() => import('app/views/dashboardsV2/widget')}
  1387. component={SafeLazyLoad}
  1388. />
  1389. <Route
  1390. path="widget/new/"
  1391. componentPromise={() => import('app/views/dashboardsV2/widget')}
  1392. component={SafeLazyLoad}
  1393. />
  1394. </Route>
  1395. {/* Admin/manage routes */}
  1396. <Route
  1397. name="Admin"
  1398. path="/manage/"
  1399. componentPromise={() => import('app/views/admin/adminLayout')}
  1400. component={SafeLazyLoad}
  1401. >
  1402. <IndexRoute
  1403. componentPromise={() => import('app/views/admin/adminOverview')}
  1404. component={SafeLazyLoad}
  1405. />
  1406. <Route
  1407. name="Buffer"
  1408. path="buffer/"
  1409. componentPromise={() => import('app/views/admin/adminBuffer')}
  1410. component={SafeLazyLoad}
  1411. />
  1412. <Route
  1413. name="Relays"
  1414. path="relays/"
  1415. componentPromise={() => import('app/views/admin/adminRelays')}
  1416. component={SafeLazyLoad}
  1417. />
  1418. <Route
  1419. name="Organizations"
  1420. path="organizations/"
  1421. componentPromise={() => import('app/views/admin/adminOrganizations')}
  1422. component={SafeLazyLoad}
  1423. />
  1424. <Route
  1425. name="Projects"
  1426. path="projects/"
  1427. componentPromise={() => import('app/views/admin/adminProjects')}
  1428. component={SafeLazyLoad}
  1429. />
  1430. <Route
  1431. name="Queue"
  1432. path="queue/"
  1433. componentPromise={() => import('app/views/admin/adminQueue')}
  1434. component={SafeLazyLoad}
  1435. />
  1436. <Route
  1437. name="Quotas"
  1438. path="quotas/"
  1439. componentPromise={() => import('app/views/admin/adminQuotas')}
  1440. component={SafeLazyLoad}
  1441. />
  1442. <Route
  1443. name="Settings"
  1444. path="settings/"
  1445. componentPromise={() => import('app/views/admin/adminSettings')}
  1446. component={SafeLazyLoad}
  1447. />
  1448. <Route name="Users" path="users/">
  1449. <IndexRoute
  1450. componentPromise={() => import('app/views/admin/adminUsers')}
  1451. component={SafeLazyLoad}
  1452. />
  1453. <Route
  1454. path=":id"
  1455. componentPromise={() => import('app/views/admin/adminUserEdit')}
  1456. component={SafeLazyLoad}
  1457. />
  1458. </Route>
  1459. <Route
  1460. name="Mail"
  1461. path="status/mail/"
  1462. componentPromise={() => import('app/views/admin/adminMail')}
  1463. component={SafeLazyLoad}
  1464. />
  1465. <Route
  1466. name="Environment"
  1467. path="status/environment/"
  1468. componentPromise={() => import('app/views/admin/adminEnvironment')}
  1469. component={SafeLazyLoad}
  1470. />
  1471. <Route
  1472. name="Packages"
  1473. path="status/packages/"
  1474. componentPromise={() => import('app/views/admin/adminPackages')}
  1475. component={SafeLazyLoad}
  1476. />
  1477. <Route
  1478. name="Warnings"
  1479. path="status/warnings/"
  1480. componentPromise={() => import('app/views/admin/adminWarnings')}
  1481. component={SafeLazyLoad}
  1482. />
  1483. {hook('routes:admin')}
  1484. </Route>
  1485. </Route>
  1486. {/* The heavyweight organization detail views */}
  1487. <Route path="/:orgId/" component={errorHandler(OrganizationDetails)}>
  1488. <Route component={errorHandler(OrganizationRoot)}>
  1489. {hook('routes:organization-root')}
  1490. <Route
  1491. path="/organizations/:orgId/projects/:projectId/getting-started/"
  1492. componentPromise={() => import('app/views/projectInstall/gettingStarted')}
  1493. component={SafeLazyLoad}
  1494. >
  1495. <IndexRoute
  1496. componentPromise={() => import('app/views/projectInstall/overview')}
  1497. component={SafeLazyLoad}
  1498. />
  1499. <Route
  1500. path=":platform/"
  1501. componentPromise={() =>
  1502. import('app/views/projectInstall/platformOrIntegration')
  1503. }
  1504. component={SafeLazyLoad}
  1505. />
  1506. </Route>
  1507. <Route
  1508. path="/organizations/:orgId/teams/new/"
  1509. componentPromise={() => import('app/views/teamCreate')}
  1510. component={SafeLazyLoad}
  1511. />
  1512. <Route path="/organizations/:orgId/">
  1513. {hook('routes:organization')}
  1514. <Redirect
  1515. from="/organizations/:orgId/teams/"
  1516. to="/settings/:orgId/teams/"
  1517. />
  1518. <Redirect
  1519. from="/organizations/:orgId/teams/your-teams/"
  1520. to="/settings/:orgId/teams/"
  1521. />
  1522. <Redirect
  1523. from="/organizations/:orgId/teams/all-teams/"
  1524. to="/settings/:orgId/teams/"
  1525. />
  1526. <Redirect
  1527. from="/organizations/:orgId/teams/:teamId/"
  1528. to="/settings/:orgId/teams/:teamId/"
  1529. />
  1530. <Redirect
  1531. from="/organizations/:orgId/teams/:teamId/members/"
  1532. to="/settings/:orgId/teams/:teamId/members/"
  1533. />
  1534. <Redirect
  1535. from="/organizations/:orgId/teams/:teamId/projects/"
  1536. to="/settings/:orgId/teams/:teamId/projects/"
  1537. />
  1538. <Redirect
  1539. from="/organizations/:orgId/teams/:teamId/settings/"
  1540. to="/settings/:orgId/teams/:teamId/settings/"
  1541. />
  1542. <Redirect from="/organizations/:orgId/settings/" to="/settings/:orgId/" />
  1543. <Redirect
  1544. from="/organizations/:orgId/api-keys/"
  1545. to="/settings/:orgId/api-keys/"
  1546. />
  1547. <Redirect
  1548. from="/organizations/:orgId/api-keys/:apiKey/"
  1549. to="/settings/:orgId/api-keys/:apiKey/"
  1550. />
  1551. <Redirect
  1552. from="/organizations/:orgId/members/"
  1553. to="/settings/:orgId/members/"
  1554. />
  1555. <Redirect
  1556. from="/organizations/:orgId/members/:memberId/"
  1557. to="/settings/:orgId/members/:memberId/"
  1558. />
  1559. <Redirect
  1560. from="/organizations/:orgId/rate-limits/"
  1561. to="/settings/:orgId/rate-limits/"
  1562. />
  1563. <Redirect
  1564. from="/organizations/:orgId/repos/"
  1565. to="/settings/:orgId/repos/"
  1566. />
  1567. </Route>
  1568. <Route
  1569. path="/organizations/:orgId/projects/new/"
  1570. componentPromise={() => import('app/views/projectInstall/newProject')}
  1571. component={SafeLazyLoad}
  1572. />
  1573. </Route>
  1574. <Route
  1575. path=":projectId/getting-started/"
  1576. componentPromise={() => import('app/views/projectInstall/gettingStarted')}
  1577. component={SafeLazyLoad}
  1578. >
  1579. <IndexRoute
  1580. componentPromise={() => import('app/views/projectInstall/overview')}
  1581. component={SafeLazyLoad}
  1582. />
  1583. <Route
  1584. path=":platform/"
  1585. componentPromise={() =>
  1586. import('app/views/projectInstall/platformOrIntegration')
  1587. }
  1588. component={SafeLazyLoad}
  1589. />
  1590. </Route>
  1591. </Route>
  1592. {/* A route tree for lightweight organizational detail views.
  1593. This is strictly for deprecated URLs that we need to maintain */}
  1594. <Route component={errorHandler(LightWeightOrganizationDetails)}>
  1595. {/* This is in the bottom lightweight group because "/organizations/:orgId/projects/new/" in heavyweight needs to be matched first */}
  1596. <Route
  1597. path="/organizations/:orgId/projects/:projectId/"
  1598. componentPromise={() => import('app/views/projectDetail')}
  1599. component={SafeLazyLoad}
  1600. />
  1601. <Route name="Organization" path="/:orgId/">
  1602. <Route path=":projectId/">
  1603. {/* Support for deprecated URLs (pre-Sentry 10). We just redirect users to new canonical URLs. */}
  1604. <IndexRoute
  1605. component={errorHandler(
  1606. redirectDeprecatedProjectRoute(
  1607. ({orgId, projectId}) =>
  1608. `/organizations/${orgId}/issues/?project=${projectId}`
  1609. )
  1610. )}
  1611. />
  1612. <Route
  1613. path="issues/"
  1614. component={errorHandler(
  1615. redirectDeprecatedProjectRoute(
  1616. ({orgId, projectId}) =>
  1617. `/organizations/${orgId}/issues/?project=${projectId}`
  1618. )
  1619. )}
  1620. />
  1621. <Route
  1622. path="dashboard/"
  1623. component={errorHandler(
  1624. redirectDeprecatedProjectRoute(
  1625. ({orgId, projectId}) =>
  1626. `/organizations/${orgId}/dashboards/?project=${projectId}`
  1627. )
  1628. )}
  1629. />
  1630. <Route
  1631. path="user-feedback/"
  1632. component={errorHandler(
  1633. redirectDeprecatedProjectRoute(
  1634. ({orgId, projectId}) =>
  1635. `/organizations/${orgId}/user-feedback/?project=${projectId}`
  1636. )
  1637. )}
  1638. />
  1639. <Route
  1640. path="releases/"
  1641. component={errorHandler(
  1642. redirectDeprecatedProjectRoute(
  1643. ({orgId, projectId}) =>
  1644. `/organizations/${orgId}/releases/?project=${projectId}`
  1645. )
  1646. )}
  1647. />
  1648. <Route
  1649. path="releases/:version/"
  1650. component={errorHandler(
  1651. redirectDeprecatedProjectRoute(
  1652. ({orgId, projectId, router}) =>
  1653. `/organizations/${orgId}/releases/${router.params.version}/?project=${projectId}`
  1654. )
  1655. )}
  1656. />
  1657. <Route
  1658. path="releases/:version/new-events/"
  1659. component={errorHandler(
  1660. redirectDeprecatedProjectRoute(
  1661. ({orgId, projectId, router}) =>
  1662. `/organizations/${orgId}/releases/${router.params.version}/new-events/?project=${projectId}`
  1663. )
  1664. )}
  1665. />
  1666. <Route
  1667. path="releases/:version/all-events/"
  1668. component={errorHandler(
  1669. redirectDeprecatedProjectRoute(
  1670. ({orgId, projectId, router}) =>
  1671. `/organizations/${orgId}/releases/${router.params.version}/all-events/?project=${projectId}`
  1672. )
  1673. )}
  1674. />
  1675. <Route
  1676. path="releases/:version/commits/"
  1677. component={errorHandler(
  1678. redirectDeprecatedProjectRoute(
  1679. ({orgId, projectId, router}) =>
  1680. `/organizations/${orgId}/releases/${router.params.version}/commits/?project=${projectId}`
  1681. )
  1682. )}
  1683. />
  1684. </Route>
  1685. </Route>
  1686. </Route>
  1687. <Route path="/:orgId/">
  1688. <Route path=":projectId/settings/">
  1689. <Redirect from="teams/" to="/settings/:orgId/projects/:projectId/teams/" />
  1690. <Redirect from="alerts/" to="/settings/:orgId/projects/:projectId/alerts/" />
  1691. <Redirect
  1692. from="alerts/rules/"
  1693. to="/settings/:orgId/projects/:projectId/alerts/rules/"
  1694. />
  1695. <Redirect
  1696. from="alerts/rules/new/"
  1697. to="/settings/:orgId/projects/:projectId/alerts/rules/new/"
  1698. />
  1699. <Redirect
  1700. from="alerts/rules/:ruleId/"
  1701. to="/settings/:orgId/projects/:projectId/alerts/rules/:ruleId/"
  1702. />
  1703. <Redirect
  1704. from="environments/"
  1705. to="/settings/:orgId/projects/:projectId/environments/"
  1706. />
  1707. <Redirect
  1708. from="environments/hidden/"
  1709. to="/settings/:orgId/projects/:projectId/environments/hidden/"
  1710. />
  1711. <Redirect
  1712. from="tags/"
  1713. to="/settings/projects/:orgId/projects/:projectId/tags/"
  1714. />
  1715. <Redirect
  1716. from="issue-tracking/"
  1717. to="/settings/:orgId/projects/:projectId/issue-tracking/"
  1718. />
  1719. <Redirect
  1720. from="release-tracking/"
  1721. to="/settings/:orgId/projects/:projectId/release-tracking/"
  1722. />
  1723. <Redirect
  1724. from="ownership/"
  1725. to="/settings/:orgId/projects/:projectId/ownership/"
  1726. />
  1727. <Redirect
  1728. from="data-forwarding/"
  1729. to="/settings/:orgId/projects/:projectId/data-forwarding/"
  1730. />
  1731. <Redirect
  1732. from="debug-symbols/"
  1733. to="/settings/:orgId/projects/:projectId/debug-symbols/"
  1734. />
  1735. <Redirect
  1736. from="processing-issues/"
  1737. to="/settings/:orgId/projects/:projectId/processing-issues/"
  1738. />
  1739. <Redirect
  1740. from="filters/"
  1741. to="/settings/:orgId/projects/:projectId/filters/"
  1742. />
  1743. <Redirect from="hooks/" to="/settings/:orgId/projects/:projectId/hooks/" />
  1744. <Redirect from="keys/" to="/settings/:orgId/projects/:projectId/keys/" />
  1745. <Redirect
  1746. from="keys/:keyId/"
  1747. to="/settings/:orgId/projects/:projectId/keys/:keyId/"
  1748. />
  1749. <Redirect
  1750. from="user-feedback/"
  1751. to="/settings/:orgId/projects/:projectId/user-feedback/"
  1752. />
  1753. <Redirect
  1754. from="security-headers/"
  1755. to="/settings/:orgId/projects/:projectId/security-headers/"
  1756. />
  1757. <Redirect
  1758. from="security-headers/csp/"
  1759. to="/settings/:orgId/projects/:projectId/security-headers/csp/"
  1760. />
  1761. <Redirect
  1762. from="security-headers/expect-ct/"
  1763. to="/settings/:orgId/projects/:projectId/security-headers/expect-ct/"
  1764. />
  1765. <Redirect
  1766. from="security-headers/hpkp/"
  1767. to="/settings/:orgId/projects/:projectId/security-headers/hpkp/"
  1768. />
  1769. <Redirect
  1770. from="plugins/"
  1771. to="/settings/:orgId/projects/:projectId/plugins/"
  1772. />
  1773. <Redirect
  1774. from="plugins/:pluginId/"
  1775. to="/settings/:orgId/projects/:projectId/plugins/:pluginId/"
  1776. />
  1777. <Redirect
  1778. from="integrations/:providerKey/"
  1779. to="/settings/:orgId/projects/:projectId/integrations/:providerKey/"
  1780. />
  1781. <Redirect
  1782. from="install/"
  1783. to="/settings/:orgId/projects/:projectId/install/"
  1784. />
  1785. <Redirect
  1786. from="install/:platform'"
  1787. to="/settings/:orgId/projects/:projectId/install/:platform/"
  1788. />
  1789. </Route>
  1790. <Redirect from=":projectId/group/:groupId/" to="issues/:groupId/" />
  1791. <Redirect
  1792. from=":projectId/issues/:groupId/"
  1793. to="/organizations/:orgId/issues/:groupId/"
  1794. />
  1795. <Redirect
  1796. from=":projectId/issues/:groupId/events/"
  1797. to="/organizations/:orgId/issues/:groupId/events/"
  1798. />
  1799. <Redirect
  1800. from=":projectId/issues/:groupId/events/:eventId/"
  1801. to="/organizations/:orgId/issues/:groupId/events/:eventId/"
  1802. />
  1803. <Redirect
  1804. from=":projectId/issues/:groupId/tags/"
  1805. to="/organizations/:orgId/issues/:groupId/tags/"
  1806. />
  1807. <Redirect
  1808. from=":projectId/issues/:groupId/tags/:tagKey/"
  1809. to="/organizations/:orgId/issues/:groupId/tags/:tagKey/"
  1810. />
  1811. <Redirect
  1812. from=":projectId/issues/:groupId/feedback/"
  1813. to="/organizations/:orgId/issues/:groupId/feedback/"
  1814. />
  1815. <Redirect
  1816. from=":projectId/issues/:groupId/similar/"
  1817. to="/organizations/:orgId/issues/:groupId/similar/"
  1818. />
  1819. <Redirect
  1820. from=":projectId/issues/:groupId/merged/"
  1821. to="/organizations/:orgId/issues/:groupId/merged/"
  1822. />
  1823. <Route
  1824. path=":projectId/events/:eventId/"
  1825. component={errorHandler(ProjectEventRedirect)}
  1826. />
  1827. </Route>
  1828. {hook('routes')}
  1829. <Route path="*" component={errorHandler(RouteNotFound)} />
  1830. </Route>
  1831. </Route>
  1832. );
  1833. }
  1834. export default routes;