routes.tsx 67 KB

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