routes.tsx 67 KB

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