routes.tsx 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935
  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 OrganizationContextContainer 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
  751. path="/onboarding/:orgId/"
  752. component={errorHandler(OrganizationContextContainer)}
  753. >
  754. <IndexRedirect to="welcome/" />
  755. <Route
  756. path=":step/"
  757. componentPromise={() => import('app/views/onboarding/onboarding')}
  758. component={SafeLazyLoad}
  759. />
  760. </Route>
  761. {/* Settings routes */}
  762. <Route component={errorHandler(OrganizationDetails)}>
  763. <Route path="/settings/" name="Settings" component={SettingsWrapper}>
  764. <IndexRoute
  765. getComponent={lazyLoad(() => import('app/views/settings/settingsIndex'))}
  766. />
  767. <Route
  768. path="account/"
  769. name="Account"
  770. getComponent={lazyLoad(
  771. () => import('app/views/settings/account/accountSettingsLayout')
  772. )}
  773. >
  774. {accountSettingsRoutes}
  775. </Route>
  776. <Route name="Organization" path=":orgId/">
  777. <Route
  778. getComponent={lazyLoad(
  779. () =>
  780. import('app/views/settings/organization/organizationSettingsLayout')
  781. )}
  782. >
  783. {hook('routes:organization')}
  784. {orgSettingsRoutes}
  785. </Route>
  786. <Route
  787. name="Project"
  788. path="projects/:projectId/"
  789. getComponent={lazyLoad(
  790. () => import('app/views/settings/project/projectSettingsLayout')
  791. )}
  792. >
  793. <Route component={errorHandler(SettingsProjectProvider)}>
  794. {projectSettingsRoutes}
  795. </Route>
  796. </Route>
  797. <Redirect from=":projectId/" to="projects/:projectId/" />
  798. <Redirect from=":projectId/alerts/" to="projects/:projectId/alerts/" />
  799. <Redirect
  800. from=":projectId/alerts/rules/"
  801. to="projects/:projectId/alerts/rules/"
  802. />
  803. <Redirect
  804. from=":projectId/alerts/rules/:ruleId/"
  805. to="projects/:projectId/alerts/rules/:ruleId/"
  806. />
  807. </Route>
  808. </Route>
  809. </Route>
  810. {/* A route tree for lightweight organizational detail views. We place
  811. this above the heavyweight organization detail views because there
  812. exist some redirects from deprecated routes which should not take
  813. precedence over these lightweight routes */}
  814. <Route component={errorHandler(LightWeightOrganizationDetails)}>
  815. <Route
  816. path="/organizations/:orgId/projects/"
  817. componentPromise={() => import('app/views/projectsDashboard')}
  818. component={SafeLazyLoad}
  819. />
  820. <Route
  821. path="/organizations/:orgId/teamInsights/"
  822. componentPromise={() => import('app/views/teamInsights')}
  823. component={SafeLazyLoad}
  824. >
  825. <IndexRoute
  826. componentPromise={() => import('app/views/teamInsights/overview')}
  827. component={SafeLazyLoad}
  828. />
  829. </Route>
  830. <Route
  831. path="/organizations/:orgId/dashboards/"
  832. componentPromise={() => import('app/views/dashboardsV2')}
  833. component={SafeLazyLoad}
  834. >
  835. <IndexRoute
  836. componentPromise={() => import('app/views/dashboardsV2/manage')}
  837. component={SafeLazyLoad}
  838. />
  839. </Route>
  840. <Route
  841. path="/organizations/:orgId/user-feedback/"
  842. componentPromise={() => import('app/views/userFeedback')}
  843. component={SafeLazyLoad}
  844. />
  845. <Route
  846. path="/organizations/:orgId/issues/"
  847. component={errorHandler(IssueListContainer)}
  848. >
  849. <Redirect from="/organizations/:orgId/" to="/organizations/:orgId/issues/" />
  850. <IndexRoute component={errorHandler(IssueListOverview)} />
  851. <Route
  852. path="searches/:searchId/"
  853. component={errorHandler(IssueListOverview)}
  854. />
  855. <Route
  856. path="sessionPercent"
  857. componentPromise={() => import('app/views/issueList/testSessionPercent')}
  858. component={SafeLazyLoad}
  859. />
  860. </Route>
  861. {/* Once org issues is complete, these routes can be nested under
  862. /organizations/:orgId/issues */}
  863. <Route
  864. path="/organizations/:orgId/issues/:groupId/"
  865. componentPromise={() => import('app/views/organizationGroupDetails')}
  866. component={SafeLazyLoad}
  867. >
  868. <IndexRoute
  869. componentPromise={() =>
  870. import('app/views/organizationGroupDetails/groupEventDetails')
  871. }
  872. component={SafeLazyLoad}
  873. props={{
  874. currentTab: Tab.DETAILS,
  875. isEventRoute: false,
  876. }}
  877. />
  878. <Route
  879. path="/organizations/:orgId/issues/:groupId/activity/"
  880. componentPromise={() =>
  881. import('app/views/organizationGroupDetails/groupActivity')
  882. }
  883. component={SafeLazyLoad}
  884. props={{
  885. currentTab: Tab.ACTIVITY,
  886. isEventRoute: false,
  887. }}
  888. />
  889. <Route
  890. path="/organizations/:orgId/issues/:groupId/events/"
  891. componentPromise={() =>
  892. import('app/views/organizationGroupDetails/groupEvents')
  893. }
  894. component={SafeLazyLoad}
  895. props={{
  896. currentTab: Tab.EVENTS,
  897. isEventRoute: false,
  898. }}
  899. />
  900. <Route
  901. path="/organizations/:orgId/issues/:groupId/tags/"
  902. componentPromise={() =>
  903. import('app/views/organizationGroupDetails/groupTags')
  904. }
  905. component={SafeLazyLoad}
  906. props={{
  907. currentTab: Tab.TAGS,
  908. isEventRoute: false,
  909. }}
  910. />
  911. <Route
  912. path="/organizations/:orgId/issues/:groupId/tags/:tagKey/"
  913. componentPromise={() =>
  914. import('app/views/organizationGroupDetails/groupTagValues')
  915. }
  916. component={SafeLazyLoad}
  917. props={{
  918. currentTab: Tab.TAGS,
  919. isEventRoute: false,
  920. }}
  921. />
  922. <Route
  923. path="/organizations/:orgId/issues/:groupId/feedback/"
  924. componentPromise={() =>
  925. import('app/views/organizationGroupDetails/groupUserFeedback')
  926. }
  927. component={SafeLazyLoad}
  928. props={{
  929. currentTab: Tab.USER_FEEDBACK,
  930. isEventRoute: false,
  931. }}
  932. />
  933. <Route
  934. path="/organizations/:orgId/issues/:groupId/attachments/"
  935. componentPromise={() =>
  936. import('app/views/organizationGroupDetails/groupEventAttachments')
  937. }
  938. component={SafeLazyLoad}
  939. props={{
  940. currentTab: Tab.ATTACHMENTS,
  941. isEventRoute: false,
  942. }}
  943. />
  944. <Route
  945. path="/organizations/:orgId/issues/:groupId/similar/"
  946. componentPromise={() =>
  947. import('app/views/organizationGroupDetails/groupSimilarIssues')
  948. }
  949. component={SafeLazyLoad}
  950. props={{
  951. currentTab: Tab.SIMILAR_ISSUES,
  952. isEventRoute: false,
  953. }}
  954. />
  955. <Route
  956. path="/organizations/:orgId/issues/:groupId/merged/"
  957. componentPromise={() =>
  958. import('app/views/organizationGroupDetails/groupMerged')
  959. }
  960. component={SafeLazyLoad}
  961. props={{
  962. currentTab: Tab.MERGED,
  963. isEventRoute: false,
  964. }}
  965. />
  966. <Route
  967. path="/organizations/:orgId/issues/:groupId/grouping/"
  968. componentPromise={() =>
  969. import('app/views/organizationGroupDetails/grouping')
  970. }
  971. component={SafeLazyLoad}
  972. props={{
  973. currentTab: Tab.GROUPING,
  974. isEventRoute: false,
  975. }}
  976. />
  977. <Route path="/organizations/:orgId/issues/:groupId/events/:eventId/">
  978. <IndexRoute
  979. componentPromise={() =>
  980. import('app/views/organizationGroupDetails/groupEventDetails')
  981. }
  982. component={SafeLazyLoad}
  983. props={{
  984. currentTab: Tab.DETAILS,
  985. isEventRoute: true,
  986. }}
  987. />
  988. <Route
  989. path="activity/"
  990. componentPromise={() =>
  991. import('app/views/organizationGroupDetails/groupActivity')
  992. }
  993. component={SafeLazyLoad}
  994. props={{
  995. currentTab: Tab.ACTIVITY,
  996. isEventRoute: true,
  997. }}
  998. />
  999. <Route
  1000. path="events/"
  1001. componentPromise={() =>
  1002. import('app/views/organizationGroupDetails/groupEvents')
  1003. }
  1004. component={SafeLazyLoad}
  1005. props={{
  1006. currentTab: Tab.EVENTS,
  1007. isEventRoute: true,
  1008. }}
  1009. />
  1010. <Route
  1011. path="similar/"
  1012. componentPromise={() =>
  1013. import('app/views/organizationGroupDetails/groupSimilarIssues')
  1014. }
  1015. component={SafeLazyLoad}
  1016. props={{
  1017. currentTab: Tab.SIMILAR_ISSUES,
  1018. isEventRoute: true,
  1019. }}
  1020. />
  1021. <Route
  1022. path="tags/"
  1023. componentPromise={() =>
  1024. import('app/views/organizationGroupDetails/groupTags')
  1025. }
  1026. component={SafeLazyLoad}
  1027. props={{
  1028. currentTab: Tab.TAGS,
  1029. isEventRoute: true,
  1030. }}
  1031. />
  1032. <Route
  1033. path="tags/:tagKey/"
  1034. componentPromise={() =>
  1035. import('app/views/organizationGroupDetails/groupTagValues')
  1036. }
  1037. component={SafeLazyLoad}
  1038. props={{
  1039. currentTab: Tab.TAGS,
  1040. isEventRoute: true,
  1041. }}
  1042. />
  1043. <Route
  1044. path="feedback/"
  1045. componentPromise={() =>
  1046. import('app/views/organizationGroupDetails/groupUserFeedback')
  1047. }
  1048. component={SafeLazyLoad}
  1049. props={{
  1050. currentTab: Tab.USER_FEEDBACK,
  1051. isEventRoute: true,
  1052. }}
  1053. />
  1054. <Route
  1055. path="attachments/"
  1056. componentPromise={() =>
  1057. import('app/views/organizationGroupDetails/groupEventAttachments')
  1058. }
  1059. component={SafeLazyLoad}
  1060. props={{
  1061. currentTab: Tab.ATTACHMENTS,
  1062. isEventRoute: true,
  1063. }}
  1064. />
  1065. <Route
  1066. path="merged/"
  1067. componentPromise={() =>
  1068. import('app/views/organizationGroupDetails/groupMerged')
  1069. }
  1070. component={SafeLazyLoad}
  1071. props={{
  1072. currentTab: Tab.MERGED,
  1073. isEventRoute: true,
  1074. }}
  1075. />
  1076. <Route
  1077. path="grouping/"
  1078. componentPromise={() =>
  1079. import('app/views/organizationGroupDetails/grouping')
  1080. }
  1081. component={SafeLazyLoad}
  1082. props={{
  1083. currentTab: Tab.GROUPING,
  1084. isEventRoute: true,
  1085. }}
  1086. />
  1087. </Route>
  1088. </Route>
  1089. <Route
  1090. path="/organizations/:orgId/alerts/"
  1091. componentPromise={() => import('app/views/alerts')}
  1092. component={SafeLazyLoad}
  1093. >
  1094. <IndexRoute
  1095. componentPromise={() => import('app/views/alerts/list')}
  1096. component={SafeLazyLoad}
  1097. />
  1098. <Route
  1099. path="rules/details/:ruleId/"
  1100. name="Alert Rule Details"
  1101. component={SafeLazyLoad}
  1102. componentPromise={() => import('app/views/alerts/rules/details')}
  1103. />
  1104. <Route path="rules/">
  1105. <IndexRoute
  1106. component={SafeLazyLoad}
  1107. componentPromise={() => import('app/views/alerts/rules')}
  1108. />
  1109. <Route
  1110. path=":projectId/"
  1111. componentPromise={() =>
  1112. import('app/views/alerts/builder/projectProvider')
  1113. }
  1114. component={SafeLazyLoad}
  1115. >
  1116. <IndexRedirect to="/organizations/:orgId/alerts/rules/" />
  1117. <Route
  1118. path=":ruleId/"
  1119. name="Edit Alert Rule"
  1120. componentPromise={() => import('app/views/alerts/edit')}
  1121. component={SafeLazyLoad}
  1122. />
  1123. </Route>
  1124. </Route>
  1125. <Route path="metric-rules/">
  1126. <IndexRedirect to="/organizations/:orgId/alerts/rules/" />
  1127. <Route
  1128. path=":projectId/"
  1129. componentPromise={() =>
  1130. import('app/views/alerts/builder/projectProvider')
  1131. }
  1132. component={SafeLazyLoad}
  1133. >
  1134. <IndexRedirect to="/organizations/:orgId/alerts/rules/" />
  1135. <Route
  1136. path=":ruleId/"
  1137. name="Edit Alert Rule"
  1138. componentPromise={() => import('app/views/alerts/edit')}
  1139. component={SafeLazyLoad}
  1140. />
  1141. </Route>
  1142. </Route>
  1143. <Route
  1144. path="rules/"
  1145. componentPromise={() => import('app/views/alerts/rules')}
  1146. component={SafeLazyLoad}
  1147. />
  1148. <Route
  1149. path=":alertId/"
  1150. componentPromise={() => import('app/views/alerts/details')}
  1151. component={SafeLazyLoad}
  1152. />
  1153. <Route
  1154. path=":projectId/"
  1155. componentPromise={() => import('app/views/alerts/builder/projectProvider')}
  1156. component={SafeLazyLoad}
  1157. >
  1158. <Route
  1159. path="new/"
  1160. name="New Alert Rule"
  1161. component={SafeLazyLoad}
  1162. componentPromise={() => import('app/views/alerts/create')}
  1163. />
  1164. <Route
  1165. path="wizard/"
  1166. name="Alert Creation Wizard"
  1167. component={SafeLazyLoad}
  1168. componentPromise={() => import('app/views/alerts/wizard')}
  1169. />
  1170. </Route>
  1171. </Route>
  1172. <Route
  1173. path="/organizations/:orgId/monitors/"
  1174. componentPromise={() => import('app/views/monitors')}
  1175. component={SafeLazyLoad}
  1176. >
  1177. <IndexRoute
  1178. componentPromise={() => import('app/views/monitors/monitors')}
  1179. component={SafeLazyLoad}
  1180. />
  1181. <Route
  1182. path="/organizations/:orgId/monitors/create/"
  1183. componentPromise={() => import('app/views/monitors/create')}
  1184. component={SafeLazyLoad}
  1185. />
  1186. <Route
  1187. path="/organizations/:orgId/monitors/:monitorId/"
  1188. componentPromise={() => import('app/views/monitors/details')}
  1189. component={SafeLazyLoad}
  1190. />
  1191. <Route
  1192. path="/organizations/:orgId/monitors/:monitorId/edit/"
  1193. componentPromise={() => import('app/views/monitors/edit')}
  1194. component={SafeLazyLoad}
  1195. />
  1196. </Route>
  1197. <Route
  1198. path="/organizations/:orgId/releases/"
  1199. componentPromise={() => import('app/views/releases')}
  1200. component={SafeLazyLoad}
  1201. >
  1202. <IndexRoute
  1203. componentPromise={() => import('app/views/releases/list')}
  1204. component={SafeLazyLoad}
  1205. />
  1206. <Route
  1207. path=":release/"
  1208. componentPromise={() => import('app/views/releases/detail')}
  1209. component={SafeLazyLoad}
  1210. >
  1211. <IndexRoute
  1212. componentPromise={() => import('app/views/releases/detail/overview')}
  1213. component={SafeLazyLoad}
  1214. />
  1215. <Route
  1216. path="commits/"
  1217. componentPromise={() => import('app/views/releases/detail/commits')}
  1218. component={SafeLazyLoad}
  1219. />
  1220. <Route
  1221. path="files-changed/"
  1222. componentPromise={() => import('app/views/releases/detail/filesChanged')}
  1223. component={SafeLazyLoad}
  1224. />
  1225. <Redirect
  1226. from="new-events/"
  1227. to="/organizations/:orgId/releases/:release/"
  1228. />
  1229. <Redirect
  1230. from="all-events/"
  1231. to="/organizations/:orgId/releases/:release/"
  1232. />
  1233. </Route>
  1234. </Route>
  1235. <Route
  1236. path="/organizations/:orgId/activity/"
  1237. componentPromise={() => import('app/views/organizationActivity')}
  1238. component={SafeLazyLoad}
  1239. />
  1240. <Route
  1241. path="/organizations/:orgId/stats/"
  1242. componentPromise={() => import('app/views/organizationStats')}
  1243. component={SafeLazyLoad}
  1244. />
  1245. <Route
  1246. path="/organizations/:orgId/projects/:projectId/events/:eventId/"
  1247. component={errorHandler(ProjectEventRedirect)}
  1248. />
  1249. {/*
  1250. TODO(mark) Long term this /queries route should go away and /discover should be the
  1251. canonical route for discover2. We have a redirect right now as /discover was for
  1252. discover 1 and most of the application is linking to /discover/queries and not /discover
  1253. */}
  1254. <Redirect
  1255. from="/organizations/:orgId/discover/"
  1256. to="/organizations/:orgId/discover/queries/"
  1257. />
  1258. <Route
  1259. path="/organizations/:orgId/discover/"
  1260. componentPromise={() => import('app/views/eventsV2')}
  1261. component={SafeLazyLoad}
  1262. >
  1263. <Route
  1264. path="queries/"
  1265. componentPromise={() => import('app/views/eventsV2/landing')}
  1266. component={SafeLazyLoad}
  1267. />
  1268. <Route
  1269. path="results/"
  1270. componentPromise={() => import('app/views/eventsV2/results')}
  1271. component={SafeLazyLoad}
  1272. />
  1273. <Route
  1274. path=":eventSlug/"
  1275. componentPromise={() => import('app/views/eventsV2/eventDetails')}
  1276. component={SafeLazyLoad}
  1277. />
  1278. </Route>
  1279. <Route
  1280. path="/organizations/:orgId/performance/"
  1281. componentPromise={() => import('app/views/performance')}
  1282. component={SafeLazyLoad}
  1283. >
  1284. <IndexRoute
  1285. componentPromise={() => import('app/views/performance/content')}
  1286. component={SafeLazyLoad}
  1287. />
  1288. </Route>
  1289. <Route
  1290. path="/organizations/:orgId/performance/trends/"
  1291. componentPromise={() => import('app/views/performance')}
  1292. component={SafeLazyLoad}
  1293. >
  1294. <IndexRoute
  1295. componentPromise={() => import('app/views/performance/trends')}
  1296. component={SafeLazyLoad}
  1297. />
  1298. </Route>
  1299. <Route
  1300. path="/organizations/:orgId/performance/summary/"
  1301. componentPromise={() => import('app/views/performance')}
  1302. component={SafeLazyLoad}
  1303. >
  1304. <IndexRoute
  1305. componentPromise={() =>
  1306. import('app/views/performance/transactionSummary/transactionOverview')
  1307. }
  1308. component={SafeLazyLoad}
  1309. />
  1310. <Route
  1311. path="/organizations/:orgId/performance/summary/vitals/"
  1312. componentPromise={() =>
  1313. import('app/views/performance/transactionSummary/transactionVitals')
  1314. }
  1315. component={SafeLazyLoad}
  1316. />
  1317. <Route
  1318. path="/organizations/:orgId/performance/summary/tags/"
  1319. componentPromise={() =>
  1320. import('app/views/performance/transactionSummary/transactionTags')
  1321. }
  1322. component={SafeLazyLoad}
  1323. />
  1324. <Route
  1325. path="/organizations/:orgId/performance/summary/events/"
  1326. componentPromise={() =>
  1327. import('app/views/performance/transactionSummary/transactionEvents')
  1328. }
  1329. component={SafeLazyLoad}
  1330. />
  1331. </Route>
  1332. <Route
  1333. path="/organizations/:orgId/performance/vitaldetail/"
  1334. componentPromise={() => import('app/views/performance')}
  1335. component={SafeLazyLoad}
  1336. >
  1337. <IndexRoute
  1338. componentPromise={() => import('app/views/performance/vitalDetail')}
  1339. component={SafeLazyLoad}
  1340. />
  1341. </Route>
  1342. <Route
  1343. path="/organizations/:orgId/performance/trace/:traceSlug/"
  1344. componentPromise={() => import('app/views/performance')}
  1345. component={SafeLazyLoad}
  1346. >
  1347. <IndexRoute
  1348. componentPromise={() => import('app/views/performance/traceDetails')}
  1349. component={SafeLazyLoad}
  1350. />
  1351. </Route>
  1352. <Route
  1353. path="/organizations/:orgId/performance/:eventSlug/"
  1354. componentPromise={() => import('app/views/performance')}
  1355. component={SafeLazyLoad}
  1356. >
  1357. <IndexRoute
  1358. componentPromise={() => import('app/views/performance/transactionDetails')}
  1359. component={SafeLazyLoad}
  1360. />
  1361. </Route>
  1362. <Route
  1363. path="/organizations/:orgId/performance/compare/:baselineEventSlug/:regressionEventSlug/"
  1364. componentPromise={() => import('app/views/performance')}
  1365. component={SafeLazyLoad}
  1366. >
  1367. <IndexRoute
  1368. componentPromise={() => import('app/views/performance/compare')}
  1369. component={SafeLazyLoad}
  1370. />
  1371. </Route>
  1372. <Route
  1373. path="/organizations/:orgId/dashboards/new/"
  1374. componentPromise={() => import('app/views/dashboardsV2/create')}
  1375. component={SafeLazyLoad}
  1376. >
  1377. <Route
  1378. path="widget/:widgetId/edit/"
  1379. componentPromise={() => import('app/views/dashboardsV2/widget')}
  1380. component={SafeLazyLoad}
  1381. />
  1382. <Route
  1383. path="widget/new/"
  1384. componentPromise={() => import('app/views/dashboardsV2/widget')}
  1385. component={SafeLazyLoad}
  1386. />
  1387. </Route>
  1388. <Redirect
  1389. from="/organizations/:orgId/dashboards/:dashboardId/"
  1390. to="/organizations/:orgId/dashboard/:dashboardId/"
  1391. />
  1392. <Route
  1393. path="/organizations/:orgId/dashboard/:dashboardId/"
  1394. componentPromise={() => import('app/views/dashboardsV2/view')}
  1395. component={SafeLazyLoad}
  1396. >
  1397. <Route
  1398. path="widget/:widgetId/edit/"
  1399. componentPromise={() => import('app/views/dashboardsV2/widget')}
  1400. component={SafeLazyLoad}
  1401. />
  1402. <Route
  1403. path="widget/new/"
  1404. componentPromise={() => import('app/views/dashboardsV2/widget')}
  1405. component={SafeLazyLoad}
  1406. />
  1407. </Route>
  1408. {/* Admin/manage routes */}
  1409. <Route
  1410. name="Admin"
  1411. path="/manage/"
  1412. componentPromise={() => import('app/views/admin/adminLayout')}
  1413. component={SafeLazyLoad}
  1414. >
  1415. <IndexRoute
  1416. componentPromise={() => import('app/views/admin/adminOverview')}
  1417. component={SafeLazyLoad}
  1418. />
  1419. <Route
  1420. name="Buffer"
  1421. path="buffer/"
  1422. componentPromise={() => import('app/views/admin/adminBuffer')}
  1423. component={SafeLazyLoad}
  1424. />
  1425. <Route
  1426. name="Relays"
  1427. path="relays/"
  1428. componentPromise={() => import('app/views/admin/adminRelays')}
  1429. component={SafeLazyLoad}
  1430. />
  1431. <Route
  1432. name="Organizations"
  1433. path="organizations/"
  1434. componentPromise={() => import('app/views/admin/adminOrganizations')}
  1435. component={SafeLazyLoad}
  1436. />
  1437. <Route
  1438. name="Projects"
  1439. path="projects/"
  1440. componentPromise={() => import('app/views/admin/adminProjects')}
  1441. component={SafeLazyLoad}
  1442. />
  1443. <Route
  1444. name="Queue"
  1445. path="queue/"
  1446. componentPromise={() => import('app/views/admin/adminQueue')}
  1447. component={SafeLazyLoad}
  1448. />
  1449. <Route
  1450. name="Quotas"
  1451. path="quotas/"
  1452. componentPromise={() => import('app/views/admin/adminQuotas')}
  1453. component={SafeLazyLoad}
  1454. />
  1455. <Route
  1456. name="Settings"
  1457. path="settings/"
  1458. componentPromise={() => import('app/views/admin/adminSettings')}
  1459. component={SafeLazyLoad}
  1460. />
  1461. <Route name="Users" path="users/">
  1462. <IndexRoute
  1463. componentPromise={() => import('app/views/admin/adminUsers')}
  1464. component={SafeLazyLoad}
  1465. />
  1466. <Route
  1467. path=":id"
  1468. componentPromise={() => import('app/views/admin/adminUserEdit')}
  1469. component={SafeLazyLoad}
  1470. />
  1471. </Route>
  1472. <Route
  1473. name="Mail"
  1474. path="status/mail/"
  1475. componentPromise={() => import('app/views/admin/adminMail')}
  1476. component={SafeLazyLoad}
  1477. />
  1478. <Route
  1479. name="Environment"
  1480. path="status/environment/"
  1481. componentPromise={() => import('app/views/admin/adminEnvironment')}
  1482. component={SafeLazyLoad}
  1483. />
  1484. <Route
  1485. name="Packages"
  1486. path="status/packages/"
  1487. componentPromise={() => import('app/views/admin/adminPackages')}
  1488. component={SafeLazyLoad}
  1489. />
  1490. <Route
  1491. name="Warnings"
  1492. path="status/warnings/"
  1493. componentPromise={() => import('app/views/admin/adminWarnings')}
  1494. component={SafeLazyLoad}
  1495. />
  1496. {hook('routes:admin')}
  1497. </Route>
  1498. </Route>
  1499. {/* The heavyweight organization detail views */}
  1500. <Route path="/:orgId/" component={errorHandler(OrganizationDetails)}>
  1501. <Route component={errorHandler(OrganizationRoot)}>
  1502. {hook('routes:organization-root')}
  1503. <Route
  1504. path="/organizations/:orgId/projects/:projectId/getting-started/"
  1505. componentPromise={() => import('app/views/projectInstall/gettingStarted')}
  1506. component={SafeLazyLoad}
  1507. >
  1508. <IndexRoute
  1509. componentPromise={() => import('app/views/projectInstall/overview')}
  1510. component={SafeLazyLoad}
  1511. />
  1512. <Route
  1513. path=":platform/"
  1514. componentPromise={() =>
  1515. import('app/views/projectInstall/platformOrIntegration')
  1516. }
  1517. component={SafeLazyLoad}
  1518. />
  1519. </Route>
  1520. <Route
  1521. path="/organizations/:orgId/teams/new/"
  1522. componentPromise={() => import('app/views/teamCreate')}
  1523. component={SafeLazyLoad}
  1524. />
  1525. <Route path="/organizations/:orgId/">
  1526. {hook('routes:organization')}
  1527. <Redirect
  1528. from="/organizations/:orgId/teams/"
  1529. to="/settings/:orgId/teams/"
  1530. />
  1531. <Redirect
  1532. from="/organizations/:orgId/teams/your-teams/"
  1533. to="/settings/:orgId/teams/"
  1534. />
  1535. <Redirect
  1536. from="/organizations/:orgId/teams/all-teams/"
  1537. to="/settings/:orgId/teams/"
  1538. />
  1539. <Redirect
  1540. from="/organizations/:orgId/teams/:teamId/"
  1541. to="/settings/:orgId/teams/:teamId/"
  1542. />
  1543. <Redirect
  1544. from="/organizations/:orgId/teams/:teamId/members/"
  1545. to="/settings/:orgId/teams/:teamId/members/"
  1546. />
  1547. <Redirect
  1548. from="/organizations/:orgId/teams/:teamId/projects/"
  1549. to="/settings/:orgId/teams/:teamId/projects/"
  1550. />
  1551. <Redirect
  1552. from="/organizations/:orgId/teams/:teamId/settings/"
  1553. to="/settings/:orgId/teams/:teamId/settings/"
  1554. />
  1555. <Redirect from="/organizations/:orgId/settings/" to="/settings/:orgId/" />
  1556. <Redirect
  1557. from="/organizations/:orgId/api-keys/"
  1558. to="/settings/:orgId/api-keys/"
  1559. />
  1560. <Redirect
  1561. from="/organizations/:orgId/api-keys/:apiKey/"
  1562. to="/settings/:orgId/api-keys/:apiKey/"
  1563. />
  1564. <Redirect
  1565. from="/organizations/:orgId/members/"
  1566. to="/settings/:orgId/members/"
  1567. />
  1568. <Redirect
  1569. from="/organizations/:orgId/members/:memberId/"
  1570. to="/settings/:orgId/members/:memberId/"
  1571. />
  1572. <Redirect
  1573. from="/organizations/:orgId/rate-limits/"
  1574. to="/settings/:orgId/rate-limits/"
  1575. />
  1576. <Redirect
  1577. from="/organizations/:orgId/repos/"
  1578. to="/settings/:orgId/repos/"
  1579. />
  1580. </Route>
  1581. <Route
  1582. path="/organizations/:orgId/projects/new/"
  1583. componentPromise={() => import('app/views/projectInstall/newProject')}
  1584. component={SafeLazyLoad}
  1585. />
  1586. </Route>
  1587. <Route
  1588. path=":projectId/getting-started/"
  1589. componentPromise={() => import('app/views/projectInstall/gettingStarted')}
  1590. component={SafeLazyLoad}
  1591. >
  1592. <IndexRoute
  1593. componentPromise={() => import('app/views/projectInstall/overview')}
  1594. component={SafeLazyLoad}
  1595. />
  1596. <Route
  1597. path=":platform/"
  1598. componentPromise={() =>
  1599. import('app/views/projectInstall/platformOrIntegration')
  1600. }
  1601. component={SafeLazyLoad}
  1602. />
  1603. </Route>
  1604. </Route>
  1605. {/* A route tree for lightweight organizational detail views.
  1606. This is strictly for deprecated URLs that we need to maintain */}
  1607. <Route component={errorHandler(LightWeightOrganizationDetails)}>
  1608. {/* This is in the bottom lightweight group because "/organizations/:orgId/projects/new/" in heavyweight needs to be matched first */}
  1609. <Route
  1610. path="/organizations/:orgId/projects/:projectId/"
  1611. componentPromise={() => import('app/views/projectDetail')}
  1612. component={SafeLazyLoad}
  1613. />
  1614. <Route name="Organization" path="/:orgId/">
  1615. <Route path=":projectId/">
  1616. {/* Support for deprecated URLs (pre-Sentry 10). We just redirect users to new canonical URLs. */}
  1617. <IndexRoute
  1618. component={errorHandler(
  1619. redirectDeprecatedProjectRoute(
  1620. ({orgId, projectId}) =>
  1621. `/organizations/${orgId}/issues/?project=${projectId}`
  1622. )
  1623. )}
  1624. />
  1625. <Route
  1626. path="issues/"
  1627. component={errorHandler(
  1628. redirectDeprecatedProjectRoute(
  1629. ({orgId, projectId}) =>
  1630. `/organizations/${orgId}/issues/?project=${projectId}`
  1631. )
  1632. )}
  1633. />
  1634. <Route
  1635. path="dashboard/"
  1636. component={errorHandler(
  1637. redirectDeprecatedProjectRoute(
  1638. ({orgId, projectId}) =>
  1639. `/organizations/${orgId}/dashboards/?project=${projectId}`
  1640. )
  1641. )}
  1642. />
  1643. <Route
  1644. path="user-feedback/"
  1645. component={errorHandler(
  1646. redirectDeprecatedProjectRoute(
  1647. ({orgId, projectId}) =>
  1648. `/organizations/${orgId}/user-feedback/?project=${projectId}`
  1649. )
  1650. )}
  1651. />
  1652. <Route
  1653. path="releases/"
  1654. component={errorHandler(
  1655. redirectDeprecatedProjectRoute(
  1656. ({orgId, projectId}) =>
  1657. `/organizations/${orgId}/releases/?project=${projectId}`
  1658. )
  1659. )}
  1660. />
  1661. <Route
  1662. path="releases/:version/"
  1663. component={errorHandler(
  1664. redirectDeprecatedProjectRoute(
  1665. ({orgId, projectId, router}) =>
  1666. `/organizations/${orgId}/releases/${router.params.version}/?project=${projectId}`
  1667. )
  1668. )}
  1669. />
  1670. <Route
  1671. path="releases/:version/new-events/"
  1672. component={errorHandler(
  1673. redirectDeprecatedProjectRoute(
  1674. ({orgId, projectId, router}) =>
  1675. `/organizations/${orgId}/releases/${router.params.version}/new-events/?project=${projectId}`
  1676. )
  1677. )}
  1678. />
  1679. <Route
  1680. path="releases/:version/all-events/"
  1681. component={errorHandler(
  1682. redirectDeprecatedProjectRoute(
  1683. ({orgId, projectId, router}) =>
  1684. `/organizations/${orgId}/releases/${router.params.version}/all-events/?project=${projectId}`
  1685. )
  1686. )}
  1687. />
  1688. <Route
  1689. path="releases/:version/commits/"
  1690. component={errorHandler(
  1691. redirectDeprecatedProjectRoute(
  1692. ({orgId, projectId, router}) =>
  1693. `/organizations/${orgId}/releases/${router.params.version}/commits/?project=${projectId}`
  1694. )
  1695. )}
  1696. />
  1697. </Route>
  1698. </Route>
  1699. </Route>
  1700. <Route path="/:orgId/">
  1701. <Route path=":projectId/settings/">
  1702. <Redirect from="teams/" to="/settings/:orgId/projects/:projectId/teams/" />
  1703. <Redirect from="alerts/" to="/settings/:orgId/projects/:projectId/alerts/" />
  1704. <Redirect
  1705. from="alerts/rules/"
  1706. to="/settings/:orgId/projects/:projectId/alerts/rules/"
  1707. />
  1708. <Redirect
  1709. from="alerts/rules/new/"
  1710. to="/settings/:orgId/projects/:projectId/alerts/rules/new/"
  1711. />
  1712. <Redirect
  1713. from="alerts/rules/:ruleId/"
  1714. to="/settings/:orgId/projects/:projectId/alerts/rules/:ruleId/"
  1715. />
  1716. <Redirect
  1717. from="environments/"
  1718. to="/settings/:orgId/projects/:projectId/environments/"
  1719. />
  1720. <Redirect
  1721. from="environments/hidden/"
  1722. to="/settings/:orgId/projects/:projectId/environments/hidden/"
  1723. />
  1724. <Redirect
  1725. from="tags/"
  1726. to="/settings/projects/:orgId/projects/:projectId/tags/"
  1727. />
  1728. <Redirect
  1729. from="issue-tracking/"
  1730. to="/settings/:orgId/projects/:projectId/issue-tracking/"
  1731. />
  1732. <Redirect
  1733. from="release-tracking/"
  1734. to="/settings/:orgId/projects/:projectId/release-tracking/"
  1735. />
  1736. <Redirect
  1737. from="ownership/"
  1738. to="/settings/:orgId/projects/:projectId/ownership/"
  1739. />
  1740. <Redirect
  1741. from="data-forwarding/"
  1742. to="/settings/:orgId/projects/:projectId/data-forwarding/"
  1743. />
  1744. <Redirect
  1745. from="debug-symbols/"
  1746. to="/settings/:orgId/projects/:projectId/debug-symbols/"
  1747. />
  1748. <Redirect
  1749. from="processing-issues/"
  1750. to="/settings/:orgId/projects/:projectId/processing-issues/"
  1751. />
  1752. <Redirect
  1753. from="filters/"
  1754. to="/settings/:orgId/projects/:projectId/filters/"
  1755. />
  1756. <Redirect from="hooks/" to="/settings/:orgId/projects/:projectId/hooks/" />
  1757. <Redirect from="keys/" to="/settings/:orgId/projects/:projectId/keys/" />
  1758. <Redirect
  1759. from="keys/:keyId/"
  1760. to="/settings/:orgId/projects/:projectId/keys/:keyId/"
  1761. />
  1762. <Redirect
  1763. from="user-feedback/"
  1764. to="/settings/:orgId/projects/:projectId/user-feedback/"
  1765. />
  1766. <Redirect
  1767. from="security-headers/"
  1768. to="/settings/:orgId/projects/:projectId/security-headers/"
  1769. />
  1770. <Redirect
  1771. from="security-headers/csp/"
  1772. to="/settings/:orgId/projects/:projectId/security-headers/csp/"
  1773. />
  1774. <Redirect
  1775. from="security-headers/expect-ct/"
  1776. to="/settings/:orgId/projects/:projectId/security-headers/expect-ct/"
  1777. />
  1778. <Redirect
  1779. from="security-headers/hpkp/"
  1780. to="/settings/:orgId/projects/:projectId/security-headers/hpkp/"
  1781. />
  1782. <Redirect
  1783. from="plugins/"
  1784. to="/settings/:orgId/projects/:projectId/plugins/"
  1785. />
  1786. <Redirect
  1787. from="plugins/:pluginId/"
  1788. to="/settings/:orgId/projects/:projectId/plugins/:pluginId/"
  1789. />
  1790. <Redirect
  1791. from="integrations/:providerKey/"
  1792. to="/settings/:orgId/projects/:projectId/integrations/:providerKey/"
  1793. />
  1794. <Redirect
  1795. from="install/"
  1796. to="/settings/:orgId/projects/:projectId/install/"
  1797. />
  1798. <Redirect
  1799. from="install/:platform'"
  1800. to="/settings/:orgId/projects/:projectId/install/:platform/"
  1801. />
  1802. </Route>
  1803. <Redirect from=":projectId/group/:groupId/" to="issues/:groupId/" />
  1804. <Redirect
  1805. from=":projectId/issues/:groupId/"
  1806. to="/organizations/:orgId/issues/:groupId/"
  1807. />
  1808. <Redirect
  1809. from=":projectId/issues/:groupId/events/"
  1810. to="/organizations/:orgId/issues/:groupId/events/"
  1811. />
  1812. <Redirect
  1813. from=":projectId/issues/:groupId/events/:eventId/"
  1814. to="/organizations/:orgId/issues/:groupId/events/:eventId/"
  1815. />
  1816. <Redirect
  1817. from=":projectId/issues/:groupId/tags/"
  1818. to="/organizations/:orgId/issues/:groupId/tags/"
  1819. />
  1820. <Redirect
  1821. from=":projectId/issues/:groupId/tags/:tagKey/"
  1822. to="/organizations/:orgId/issues/:groupId/tags/:tagKey/"
  1823. />
  1824. <Redirect
  1825. from=":projectId/issues/:groupId/feedback/"
  1826. to="/organizations/:orgId/issues/:groupId/feedback/"
  1827. />
  1828. <Redirect
  1829. from=":projectId/issues/:groupId/similar/"
  1830. to="/organizations/:orgId/issues/:groupId/similar/"
  1831. />
  1832. <Redirect
  1833. from=":projectId/issues/:groupId/merged/"
  1834. to="/organizations/:orgId/issues/:groupId/merged/"
  1835. />
  1836. <Route
  1837. path=":projectId/events/:eventId/"
  1838. component={errorHandler(ProjectEventRedirect)}
  1839. />
  1840. </Route>
  1841. {hook('routes')}
  1842. <Route path="*" component={errorHandler(RouteNotFound)} />
  1843. </Route>
  1844. </Route>
  1845. );
  1846. }
  1847. export default routes;