routes.tsx 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. import React from 'react';
  2. import { Redirect } from 'react-router-dom';
  3. import ErrorPage from 'app/core/components/ErrorPage/ErrorPage';
  4. import { LoginPage } from 'app/core/components/Login/LoginPage';
  5. import config from 'app/core/config';
  6. import { contextSrv } from 'app/core/services/context_srv';
  7. import UserAdminPage from 'app/features/admin/UserAdminPage';
  8. import LdapPage from 'app/features/admin/ldap/LdapPage';
  9. import { getAlertingRoutes } from 'app/features/alerting/routes';
  10. import { getLiveRoutes } from 'app/features/live/pages/routes';
  11. import { getRoutes as getPluginCatalogRoutes } from 'app/features/plugins/admin/routes';
  12. import { getProfileRoutes } from 'app/features/profile/routes';
  13. import { ServiceAccountPage } from 'app/features/serviceaccounts/ServiceAccountPage';
  14. import { AccessControlAction, DashboardRoutes } from 'app/types';
  15. import { SafeDynamicImport } from '../core/components/DynamicImports/SafeDynamicImport';
  16. import { RouteDescriptor } from '../core/navigation/types';
  17. export const extraRoutes: RouteDescriptor[] = [];
  18. export function getAppRoutes(): RouteDescriptor[] {
  19. return [
  20. {
  21. path: '/',
  22. pageClass: 'page-dashboard',
  23. routeName: DashboardRoutes.Home,
  24. component: SafeDynamicImport(
  25. () => import(/* webpackChunkName: "DashboardPage" */ '../features/dashboard/containers/DashboardPage')
  26. ),
  27. },
  28. {
  29. path: '/d/:uid/:slug?',
  30. pageClass: 'page-dashboard',
  31. routeName: DashboardRoutes.Normal,
  32. component: SafeDynamicImport(
  33. () => import(/* webpackChunkName: "DashboardPage" */ '../features/dashboard/containers/DashboardPage')
  34. ),
  35. },
  36. {
  37. path: '/dashboard/:type/:slug',
  38. pageClass: 'page-dashboard',
  39. routeName: DashboardRoutes.Normal,
  40. component: SafeDynamicImport(
  41. () => import(/* webpackChunkName: "DashboardPage" */ '../features/dashboard/containers/DashboardPage')
  42. ),
  43. },
  44. {
  45. path: '/dashboard/new',
  46. pageClass: 'page-dashboard',
  47. routeName: DashboardRoutes.New,
  48. // TODO[Router]
  49. //roles: () => (contextSrv.hasEditPermissionInFolders ? [contextSrv.user.orgRole] : ['Admin']),
  50. component: SafeDynamicImport(
  51. () => import(/* webpackChunkName: "DashboardPage" */ '../features/dashboard/containers/DashboardPage')
  52. ),
  53. },
  54. {
  55. path: '/d-solo/:uid/:slug',
  56. pageClass: 'dashboard-solo',
  57. routeName: DashboardRoutes.Normal,
  58. component: SafeDynamicImport(
  59. () => import(/* webpackChunkName: "SoloPanelPage" */ '../features/dashboard/containers/SoloPanelPage')
  60. ),
  61. },
  62. // This route handles embedding of snapshot/scripted dashboard panels
  63. {
  64. path: '/dashboard-solo/:type/:slug',
  65. pageClass: 'dashboard-solo',
  66. routeName: DashboardRoutes.Normal,
  67. component: SafeDynamicImport(
  68. () => import(/* webpackChunkName: "SoloPanelPage" */ '../features/dashboard/containers/SoloPanelPage')
  69. ),
  70. },
  71. {
  72. path: '/d-solo/:uid',
  73. pageClass: 'dashboard-solo',
  74. routeName: DashboardRoutes.Normal,
  75. component: SafeDynamicImport(
  76. () => import(/* webpackChunkName: "SoloPanelPage" */ '../features/dashboard/containers/SoloPanelPage')
  77. ),
  78. },
  79. {
  80. path: '/dashboard/import',
  81. component: SafeDynamicImport(
  82. () => import(/* webpackChunkName: "DashboardImport"*/ 'app/features/manage-dashboards/DashboardImportPage')
  83. ),
  84. },
  85. {
  86. path: '/datasources',
  87. component: SafeDynamicImport(
  88. () => import(/* webpackChunkName: "DataSourcesListPage"*/ 'app/features/datasources/DataSourcesListPage')
  89. ),
  90. },
  91. {
  92. path: '/datasources/edit/:uid/',
  93. component: SafeDynamicImport(
  94. () =>
  95. import(
  96. /* webpackChunkName: "DataSourceSettingsPage"*/ '../features/datasources/settings/DataSourceSettingsPage'
  97. )
  98. ),
  99. },
  100. {
  101. path: '/datasources/edit/:uid/dashboards',
  102. component: SafeDynamicImport(
  103. () => import(/* webpackChunkName: "DataSourceDashboards"*/ 'app/features/datasources/DataSourceDashboards')
  104. ),
  105. },
  106. {
  107. path: '/datasources/new',
  108. component: SafeDynamicImport(
  109. () => import(/* webpackChunkName: "NewDataSourcePage"*/ '../features/datasources/NewDataSourcePage')
  110. ),
  111. },
  112. {
  113. path: '/dashboards',
  114. component: SafeDynamicImport(
  115. () => import(/* webpackChunkName: "DashboardListPage"*/ 'app/features/search/components/DashboardListPage')
  116. ),
  117. },
  118. {
  119. path: '/dashboards/folder/new',
  120. component: SafeDynamicImport(
  121. () => import(/* webpackChunkName: "NewDashboardsFolder"*/ 'app/features/folders/components/NewDashboardsFolder')
  122. ),
  123. },
  124. {
  125. path: '/dashboards/f/:uid/:slug/permissions',
  126. component:
  127. config.rbacEnabled && contextSrv.hasPermission(AccessControlAction.FoldersPermissionsRead)
  128. ? SafeDynamicImport(
  129. () =>
  130. import(/* webpackChunkName: "FolderPermissions"*/ 'app/features/folders/AccessControlFolderPermissions')
  131. )
  132. : SafeDynamicImport(
  133. () => import(/* webpackChunkName: "FolderPermissions"*/ 'app/features/folders/FolderPermissions')
  134. ),
  135. },
  136. {
  137. path: '/dashboards/f/:uid/:slug/settings',
  138. component: SafeDynamicImport(
  139. () => import(/* webpackChunkName: "FolderSettingsPage"*/ 'app/features/folders/FolderSettingsPage')
  140. ),
  141. },
  142. {
  143. path: '/dashboards/f/:uid/:slug',
  144. component: SafeDynamicImport(
  145. () => import(/* webpackChunkName: "DashboardListPage"*/ 'app/features/search/components/DashboardListPage')
  146. ),
  147. },
  148. {
  149. path: '/dashboards/f/:uid',
  150. component: SafeDynamicImport(
  151. () => import(/* webpackChunkName: "DashboardListPage"*/ 'app/features/search/components/DashboardListPage')
  152. ),
  153. },
  154. {
  155. path: '/explore',
  156. pageClass: 'page-explore',
  157. roles: () =>
  158. contextSrv.evaluatePermission(
  159. () => (config.viewersCanEdit ? [] : ['Editor', 'Admin']),
  160. [AccessControlAction.DataSourcesExplore]
  161. ),
  162. component: SafeDynamicImport(() =>
  163. config.exploreEnabled
  164. ? import(/* webpackChunkName: "explore" */ 'app/features/explore/Wrapper')
  165. : import(/* webpackChunkName: "explore-feature-toggle-page" */ 'app/features/explore/FeatureTogglePage')
  166. ),
  167. },
  168. {
  169. path: '/a/:pluginId/',
  170. exact: false,
  171. // Someday * and will get a ReactRouter under that path!
  172. component: SafeDynamicImport(
  173. () => import(/* webpackChunkName: "AppRootPage" */ 'app/features/plugins/components/AppRootPage')
  174. ),
  175. },
  176. {
  177. path: '/org',
  178. component: SafeDynamicImport(
  179. () => import(/* webpackChunkName: "OrgDetailsPage" */ '../features/org/OrgDetailsPage')
  180. ),
  181. },
  182. {
  183. path: '/org/new',
  184. component: SafeDynamicImport(() => import(/* webpackChunkName: "NewOrgPage" */ 'app/features/org/NewOrgPage')),
  185. },
  186. {
  187. path: '/org/users',
  188. component: SafeDynamicImport(
  189. () => import(/* webpackChunkName: "UsersListPage" */ 'app/features/users/UsersListPage')
  190. ),
  191. },
  192. {
  193. path: '/org/users/invite',
  194. component: SafeDynamicImport(
  195. () => import(/* webpackChunkName: "UserInvitePage" */ 'app/features/org/UserInvitePage')
  196. ),
  197. },
  198. {
  199. path: '/org/apikeys',
  200. roles: () => contextSrv.evaluatePermission(() => ['Admin'], [AccessControlAction.ActionAPIKeysRead]),
  201. component: SafeDynamicImport(
  202. () => import(/* webpackChunkName: "ApiKeysPage" */ 'app/features/api-keys/ApiKeysPage')
  203. ),
  204. },
  205. {
  206. path: '/org/serviceaccounts',
  207. roles: () => contextSrv.evaluatePermission(() => ['Admin'], [AccessControlAction.ServiceAccountsRead]),
  208. component: SafeDynamicImport(
  209. () =>
  210. import(/* webpackChunkName: "ServiceAccountsPage" */ 'app/features/serviceaccounts/ServiceAccountsListPage')
  211. ),
  212. },
  213. {
  214. path: '/org/serviceaccounts/create',
  215. component: SafeDynamicImport(
  216. () =>
  217. import(
  218. /* webpackChunkName: "ServiceAccountCreatePage" */ 'app/features/serviceaccounts/ServiceAccountCreatePage'
  219. )
  220. ),
  221. },
  222. {
  223. path: '/org/serviceaccounts/:id',
  224. component: ServiceAccountPage,
  225. },
  226. {
  227. path: '/org/teams',
  228. roles: () =>
  229. contextSrv.evaluatePermission(
  230. () => (config.editorsCanAdmin ? ['Editor', 'Admin'] : ['Admin']),
  231. [AccessControlAction.ActionTeamsRead, AccessControlAction.ActionTeamsCreate]
  232. ),
  233. component: SafeDynamicImport(() => import(/* webpackChunkName: "TeamList" */ 'app/features/teams/TeamList')),
  234. },
  235. {
  236. path: '/org/teams/new',
  237. roles: () =>
  238. contextSrv.evaluatePermission(
  239. () => (config.editorsCanAdmin ? ['Editor', 'Admin'] : ['Admin']),
  240. [AccessControlAction.ActionTeamsCreate]
  241. ),
  242. component: SafeDynamicImport(() => import(/* webpackChunkName: "CreateTeam" */ 'app/features/teams/CreateTeam')),
  243. },
  244. {
  245. path: '/org/teams/edit/:id/:page?',
  246. roles: () =>
  247. contextSrv.evaluatePermission(
  248. () => (config.editorsCanAdmin ? ['Editor', 'Admin'] : ['Admin']),
  249. [AccessControlAction.ActionTeamsRead, AccessControlAction.ActionTeamsCreate]
  250. ),
  251. component: SafeDynamicImport(() => import(/* webpackChunkName: "TeamPages" */ 'app/features/teams/TeamPages')),
  252. },
  253. // ADMIN
  254. {
  255. path: '/admin',
  256. // eslint-disable-next-line react/display-name
  257. component: () => <Redirect to="/admin/users" />,
  258. },
  259. {
  260. path: '/admin/settings',
  261. component: SafeDynamicImport(
  262. () => import(/* webpackChunkName: "AdminSettings" */ 'app/features/admin/AdminSettings')
  263. ),
  264. },
  265. {
  266. path: '/admin/upgrading',
  267. component: SafeDynamicImport(() => import('app/features/admin/UpgradePage')),
  268. },
  269. {
  270. path: '/admin/users',
  271. component: SafeDynamicImport(
  272. () => import(/* webpackChunkName: "UserListAdminPage" */ 'app/features/admin/UserListAdminPage')
  273. ),
  274. },
  275. {
  276. path: '/admin/users/create',
  277. component: SafeDynamicImport(
  278. () => import(/* webpackChunkName: "UserCreatePage" */ 'app/features/admin/UserCreatePage')
  279. ),
  280. },
  281. {
  282. path: '/admin/users/edit/:id',
  283. component: UserAdminPage,
  284. },
  285. {
  286. path: '/admin/orgs',
  287. component: SafeDynamicImport(
  288. () => import(/* webpackChunkName: "AdminListOrgsPage" */ 'app/features/admin/AdminListOrgsPage')
  289. ),
  290. },
  291. {
  292. path: '/admin/orgs/edit/:id',
  293. component: SafeDynamicImport(
  294. () => import(/* webpackChunkName: "AdminEditOrgPage" */ 'app/features/admin/AdminEditOrgPage')
  295. ),
  296. },
  297. {
  298. path: '/admin/stats',
  299. component: SafeDynamicImport(
  300. () => import(/* webpackChunkName: "ServerStats" */ 'app/features/admin/ServerStats')
  301. ),
  302. },
  303. {
  304. path: '/admin/ldap',
  305. component: LdapPage,
  306. },
  307. // LOGIN / SIGNUP
  308. {
  309. path: '/login',
  310. component: LoginPage,
  311. pageClass: 'login-page sidemenu-hidden',
  312. },
  313. {
  314. path: '/invite/:code',
  315. component: SafeDynamicImport(
  316. () => import(/* webpackChunkName: "SignupInvited" */ 'app/features/invites/SignupInvited')
  317. ),
  318. pageClass: 'sidemenu-hidden',
  319. },
  320. {
  321. path: '/verify',
  322. component: !config.verifyEmailEnabled
  323. ? () => <Redirect to="/signup" />
  324. : SafeDynamicImport(
  325. () => import(/* webpackChunkName "VerifyEmailPage"*/ 'app/core/components/Signup/VerifyEmailPage')
  326. ),
  327. pageClass: 'login-page sidemenu-hidden',
  328. },
  329. {
  330. path: '/signup',
  331. component: config.disableUserSignUp
  332. ? () => <Redirect to="/login" />
  333. : SafeDynamicImport(() => import(/* webpackChunkName "SignupPage"*/ 'app/core/components/Signup/SignupPage')),
  334. pageClass: 'sidemenu-hidden login-page',
  335. },
  336. {
  337. path: '/user/password/send-reset-email',
  338. pageClass: 'sidemenu-hidden',
  339. component: SafeDynamicImport(
  340. () =>
  341. import(/* webpackChunkName: "SendResetMailPage" */ 'app/core/components/ForgottenPassword/SendResetMailPage')
  342. ),
  343. },
  344. {
  345. path: '/user/password/reset',
  346. component: SafeDynamicImport(
  347. () =>
  348. import(
  349. /* webpackChunkName: "ChangePasswordPage" */ 'app/core/components/ForgottenPassword/ChangePasswordPage'
  350. )
  351. ),
  352. pageClass: 'sidemenu-hidden login-page',
  353. },
  354. {
  355. path: '/dashboard/snapshots',
  356. component: SafeDynamicImport(
  357. () => import(/* webpackChunkName: "SnapshotListPage" */ 'app/features/manage-dashboards/SnapshotListPage')
  358. ),
  359. },
  360. {
  361. path: '/playlists',
  362. component: SafeDynamicImport(
  363. () => import(/* webpackChunkName: "PlaylistPage"*/ 'app/features/playlist/PlaylistPage')
  364. ),
  365. },
  366. {
  367. path: '/playlists/play/:uid',
  368. component: SafeDynamicImport(
  369. () => import(/* webpackChunkName: "PlaylistStartPage"*/ 'app/features/playlist/PlaylistStartPage')
  370. ),
  371. },
  372. {
  373. path: '/playlists/new',
  374. component: SafeDynamicImport(
  375. () => import(/* webpackChunkName: "PlaylistNewPage"*/ 'app/features/playlist/PlaylistNewPage')
  376. ),
  377. },
  378. {
  379. path: '/playlists/edit/:uid',
  380. component: SafeDynamicImport(
  381. () => import(/* webpackChunkName: "PlaylistEditPage"*/ 'app/features/playlist/PlaylistEditPage')
  382. ),
  383. },
  384. {
  385. path: '/sandbox/benchmarks',
  386. component: SafeDynamicImport(
  387. () => import(/* webpackChunkName: "BenchmarksPage"*/ 'app/features/sandbox/BenchmarksPage')
  388. ),
  389. },
  390. {
  391. path: '/sandbox/test',
  392. component: SafeDynamicImport(
  393. () => import(/* webpackChunkName: "TestStuffPage"*/ 'app/features/sandbox/TestStuffPage')
  394. ),
  395. },
  396. {
  397. path: '/dashboards/f/:uid/:slug/library-panels',
  398. component: SafeDynamicImport(
  399. () => import(/* webpackChunkName: "FolderLibraryPanelsPage"*/ 'app/features/folders/FolderLibraryPanelsPage')
  400. ),
  401. },
  402. {
  403. path: '/dashboards/f/:uid/:slug/alerting',
  404. roles: () =>
  405. contextSrv.evaluatePermission(() => ['Viewer', 'Editor', 'Admin'], [AccessControlAction.AlertingRuleRead]),
  406. component: SafeDynamicImport(
  407. () => import(/* webpackChunkName: "FolderAlerting"*/ 'app/features/folders/FolderAlerting')
  408. ),
  409. },
  410. {
  411. path: '/library-panels',
  412. component: SafeDynamicImport(
  413. () => import(/* webpackChunkName: "LibraryPanelsPage"*/ 'app/features/library-panels/LibraryPanelsPage')
  414. ),
  415. },
  416. {
  417. path: '/notifications',
  418. component: SafeDynamicImport(
  419. () => import(/* webpackChunkName: "NotificationsPage"*/ 'app/features/notifications/NotificationsPage')
  420. ),
  421. },
  422. ...getPluginCatalogRoutes(),
  423. ...getLiveRoutes(),
  424. ...getAlertingRoutes(),
  425. ...getProfileRoutes(),
  426. ...extraRoutes,
  427. {
  428. path: '/*',
  429. component: ErrorPage,
  430. },
  431. // TODO[Router]
  432. // ...playlistRoutes,
  433. ];
  434. }