routes.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. import './dashboard_loaders';
  2. import './ReactContainer';
  3. import { applyRouteRegistrationHandlers } from './registry';
  4. // Pages
  5. import CreateFolderCtrl from 'app/features/folders/CreateFolderCtrl';
  6. import FolderDashboardsCtrl from 'app/features/folders/FolderDashboardsCtrl';
  7. import DashboardImportCtrl from 'app/features/manage-dashboards/DashboardImportCtrl';
  8. import config from 'app/core/config';
  9. import { route, ILocationProvider } from 'angular';
  10. // Types
  11. import { DashboardRouteInfo } from 'app/types';
  12. import { LoginPage } from 'app/core/components/Login/LoginPage';
  13. /** @ngInject */
  14. export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locationProvider: ILocationProvider) {
  15. $locationProvider.html5Mode(true);
  16. // Routes here are guarded both here and server side for react-container routes or just on the server for angular
  17. // ones. That means angular ones could be navigated to in case there is a client side link some where.
  18. const importDashboardPage = () =>
  19. import(/* webpackChunkName: "DashboardPage" */ '../features/dashboard/containers/DashboardPage');
  20. $routeProvider
  21. .when('/', {
  22. template: '<react-container />',
  23. //@ts-ignore
  24. pageClass: 'page-dashboard',
  25. routeInfo: DashboardRouteInfo.Home,
  26. reloadOnSearch: false,
  27. resolve: {
  28. component: importDashboardPage,
  29. },
  30. })
  31. .when('/d/:uid/:slug', {
  32. template: '<react-container />',
  33. pageClass: 'page-dashboard',
  34. routeInfo: DashboardRouteInfo.Normal,
  35. reloadOnSearch: false,
  36. resolve: {
  37. component: importDashboardPage,
  38. },
  39. })
  40. .when('/d/:uid', {
  41. template: '<react-container />',
  42. pageClass: 'page-dashboard',
  43. reloadOnSearch: false,
  44. routeInfo: DashboardRouteInfo.Normal,
  45. resolve: {
  46. component: importDashboardPage,
  47. },
  48. })
  49. .when('/dashboard/:type/:slug', {
  50. template: '<react-container />',
  51. pageClass: 'page-dashboard',
  52. routeInfo: DashboardRouteInfo.Normal,
  53. reloadOnSearch: false,
  54. resolve: {
  55. component: importDashboardPage,
  56. },
  57. })
  58. .when('/dashboard/new', {
  59. template: '<react-container />',
  60. pageClass: 'page-dashboard',
  61. routeInfo: DashboardRouteInfo.New,
  62. reloadOnSearch: false,
  63. resolve: {
  64. component: importDashboardPage,
  65. },
  66. })
  67. .when('/d-solo/:uid/:slug', {
  68. template: '<react-container />',
  69. pageClass: 'dashboard-solo',
  70. routeInfo: DashboardRouteInfo.Normal,
  71. reloadOnSearch: false,
  72. resolve: {
  73. component: () =>
  74. import(/* webpackChunkName: "SoloPanelPage" */ '../features/dashboard/containers/SoloPanelPage'),
  75. },
  76. })
  77. .when('/dashboard-solo/:type/:slug', {
  78. template: '<react-container />',
  79. pageClass: 'dashboard-solo',
  80. routeInfo: DashboardRouteInfo.Normal,
  81. reloadOnSearch: false,
  82. resolve: {
  83. component: () =>
  84. import(/* webpackChunkName: "SoloPanelPage" */ '../features/dashboard/containers/SoloPanelPage'),
  85. },
  86. })
  87. .when('/dashboard/import', {
  88. templateUrl: 'public/app/features/manage-dashboards/partials/dashboard_import.html',
  89. controller: DashboardImportCtrl,
  90. controllerAs: 'ctrl',
  91. })
  92. .when('/datasources', {
  93. template: '<react-container />',
  94. resolve: {
  95. component: () =>
  96. import(/* webpackChunkName: "DataSourcesListPage"*/ 'app/features/datasources/DataSourcesListPage'),
  97. },
  98. })
  99. .when('/datasources/edit/:id/', {
  100. template: '<react-container />',
  101. reloadOnSearch: false, // for tabs
  102. resolve: {
  103. component: () =>
  104. import(/* webpackChunkName: "DataSourceSettingsPage"*/ '../features/datasources/settings/DataSourceSettingsPage'),
  105. },
  106. })
  107. .when('/datasources/edit/:id/dashboards', {
  108. template: '<react-container />',
  109. resolve: {
  110. component: () =>
  111. import(/* webpackChunkName: "DataSourceDashboards"*/ 'app/features/datasources/DataSourceDashboards'),
  112. },
  113. })
  114. .when('/datasources/new', {
  115. template: '<react-container />',
  116. resolve: {
  117. component: () => import(/* webpackChunkName: "NewDataSourcePage"*/ '../features/datasources/NewDataSourcePage'),
  118. },
  119. })
  120. .when('/dashboards', {
  121. templateUrl: 'public/app/features/manage-dashboards/partials/dashboard_list.html',
  122. controller: 'DashboardListCtrl',
  123. controllerAs: 'ctrl',
  124. })
  125. .when('/dashboards/folder/new', {
  126. templateUrl: 'public/app/features/folders/partials/create_folder.html',
  127. controller: CreateFolderCtrl,
  128. controllerAs: 'ctrl',
  129. })
  130. .when('/dashboards/f/:uid/:slug/permissions', {
  131. template: '<react-container />',
  132. resolve: {
  133. component: () => import(/* webpackChunkName: "FolderPermissions"*/ 'app/features/folders/FolderPermissions'),
  134. },
  135. })
  136. .when('/dashboards/f/:uid/:slug/settings', {
  137. template: '<react-container />',
  138. resolve: {
  139. component: () => import(/* webpackChunkName: "FolderSettingsPage"*/ 'app/features/folders/FolderSettingsPage'),
  140. },
  141. })
  142. .when('/dashboards/f/:uid/:slug', {
  143. templateUrl: 'public/app/features/folders/partials/folder_dashboards.html',
  144. controller: FolderDashboardsCtrl,
  145. controllerAs: 'ctrl',
  146. })
  147. .when('/dashboards/f/:uid', {
  148. templateUrl: 'public/app/features/folders/partials/folder_dashboards.html',
  149. controller: FolderDashboardsCtrl,
  150. controllerAs: 'ctrl',
  151. })
  152. .when('/explore', {
  153. template: '<react-container />',
  154. reloadOnSearch: false,
  155. resolve: {
  156. roles: () => (config.viewersCanEdit ? [] : ['Editor', 'Admin']),
  157. component: () => import(/* webpackChunkName: "explore" */ 'app/features/explore/Wrapper'),
  158. },
  159. })
  160. .when('/a/:pluginId/', {
  161. // Someday * and will get a ReactRouter under that path!
  162. template: '<react-container />',
  163. reloadOnSearch: false,
  164. resolve: {
  165. component: () => import(/* webpackChunkName: "AppRootPage" */ 'app/features/plugins/AppRootPage'),
  166. },
  167. })
  168. .when('/org', {
  169. template: '<react-container />',
  170. resolve: {
  171. component: () => import(/* webpackChunkName: "OrgDetailsPage" */ '../features/org/OrgDetailsPage'),
  172. },
  173. })
  174. .when('/org/new', {
  175. templateUrl: 'public/app/features/org/partials/newOrg.html',
  176. controller: 'NewOrgCtrl',
  177. })
  178. .when('/org/users', {
  179. template: '<react-container />',
  180. resolve: {
  181. component: () => import(/* webpackChunkName: "UsersListPage" */ 'app/features/users/UsersListPage'),
  182. },
  183. })
  184. .when('/org/users/invite', {
  185. templateUrl: 'public/app/features/org/partials/invite.html',
  186. controller: 'UserInviteCtrl',
  187. controllerAs: 'ctrl',
  188. })
  189. .when('/org/apikeys', {
  190. template: '<react-container />',
  191. resolve: {
  192. roles: () => ['Editor', 'Admin'],
  193. component: () => import(/* webpackChunkName: "ApiKeysPage" */ 'app/features/api-keys/ApiKeysPage'),
  194. },
  195. })
  196. .when('/org/teams', {
  197. template: '<react-container />',
  198. resolve: {
  199. roles: () => (config.editorsCanAdmin ? [] : ['Editor', 'Admin']),
  200. component: () => import(/* webpackChunkName: "TeamList" */ 'app/features/teams/TeamList'),
  201. },
  202. })
  203. .when('/org/teams/new', {
  204. templateUrl: 'public/app/features/teams/partials/create_team.html',
  205. controller: 'CreateTeamCtrl',
  206. controllerAs: 'ctrl',
  207. })
  208. .when('/org/teams/edit/:id/:page?', {
  209. template: '<react-container />',
  210. resolve: {
  211. roles: () => (config.editorsCanAdmin ? [] : ['Admin']),
  212. component: () => import(/* webpackChunkName: "TeamPages" */ 'app/features/teams/TeamPages'),
  213. },
  214. })
  215. .when('/profile', {
  216. templateUrl: 'public/app/features/profile/partials/profile.html',
  217. controller: 'ProfileCtrl',
  218. controllerAs: 'ctrl',
  219. })
  220. .when('/profile/password', {
  221. template: '<react-container />',
  222. resolve: {
  223. component: () => import(/* webPackChunkName: "ChangePasswordPage" */ 'app/features/profile/ChangePasswordPage'),
  224. },
  225. })
  226. .when('/profile/select-org', {
  227. templateUrl: 'public/app/features/org/partials/select_org.html',
  228. controller: 'SelectOrgCtrl',
  229. })
  230. // ADMIN
  231. .when('/admin', {
  232. templateUrl: 'public/app/features/admin/partials/admin_home.html',
  233. controller: 'AdminHomeCtrl',
  234. controllerAs: 'ctrl',
  235. })
  236. .when('/admin/settings', {
  237. templateUrl: 'public/app/features/admin/partials/settings.html',
  238. controller: 'AdminSettingsCtrl',
  239. controllerAs: 'ctrl',
  240. })
  241. .when('/admin/users', {
  242. templateUrl: 'public/app/features/admin/partials/users.html',
  243. controller: 'AdminListUsersCtrl',
  244. controllerAs: 'ctrl',
  245. })
  246. .when('/admin/users/create', {
  247. templateUrl: 'public/app/features/admin/partials/new_user.html',
  248. controller: 'AdminEditUserCtrl',
  249. })
  250. .when('/admin/users/edit/:id', {
  251. templateUrl: 'public/app/features/admin/partials/edit_user.html',
  252. controller: 'AdminEditUserCtrl',
  253. })
  254. .when('/admin/orgs', {
  255. templateUrl: 'public/app/features/admin/partials/orgs.html',
  256. controller: 'AdminListOrgsCtrl',
  257. controllerAs: 'ctrl',
  258. })
  259. .when('/admin/orgs/edit/:id', {
  260. templateUrl: 'public/app/features/admin/partials/edit_org.html',
  261. controller: 'AdminEditOrgCtrl',
  262. controllerAs: 'ctrl',
  263. })
  264. .when('/admin/stats', {
  265. template: '<react-container />',
  266. resolve: {
  267. component: () => import(/* webpackChunkName: "ServerStats" */ 'app/features/admin/ServerStats'),
  268. },
  269. })
  270. // LOGIN / SIGNUP
  271. .when('/login', {
  272. template: '<react-container/>',
  273. resolve: {
  274. component: () => LoginPage,
  275. },
  276. pageClass: 'login-page sidemenu-hidden',
  277. })
  278. .when('/invite/:code', {
  279. templateUrl: 'public/app/partials/signup_invited.html',
  280. controller: 'InvitedCtrl',
  281. pageClass: 'sidemenu-hidden',
  282. })
  283. .when('/signup', {
  284. templateUrl: 'public/app/partials/signup_step2.html',
  285. controller: 'SignUpCtrl',
  286. pageClass: 'sidemenu-hidden',
  287. })
  288. .when('/user/password/send-reset-email', {
  289. templateUrl: 'public/app/partials/reset_password.html',
  290. controller: 'ResetPasswordCtrl',
  291. pageClass: 'sidemenu-hidden',
  292. })
  293. .when('/user/password/reset', {
  294. templateUrl: 'public/app/partials/reset_password.html',
  295. controller: 'ResetPasswordCtrl',
  296. pageClass: 'sidemenu-hidden',
  297. })
  298. .when('/dashboard/snapshots', {
  299. templateUrl: 'public/app/features/manage-dashboards/partials/snapshot_list.html',
  300. controller: 'SnapshotListCtrl',
  301. controllerAs: 'ctrl',
  302. })
  303. .when('/plugins', {
  304. template: '<react-container />',
  305. resolve: {
  306. component: () => import(/* webpackChunkName: "PluginListPage" */ 'app/features/plugins/PluginListPage'),
  307. },
  308. })
  309. .when('/plugins/:pluginId/', {
  310. template: '<react-container />',
  311. reloadOnSearch: false, // tabs from query parameters
  312. resolve: {
  313. component: () => import(/* webpackChunkName: "PluginPage" */ '../features/plugins/PluginPage'),
  314. },
  315. })
  316. .when('/plugins/:pluginId/page/:slug', {
  317. templateUrl: 'public/app/features/plugins/partials/plugin_page.html',
  318. controller: 'AppPageCtrl',
  319. controllerAs: 'ctrl',
  320. })
  321. .when('/styleguide/:page?', {
  322. controller: 'StyleGuideCtrl',
  323. controllerAs: 'ctrl',
  324. templateUrl: 'public/app/features/admin/partials/styleguide.html',
  325. })
  326. .when('/alerting', {
  327. redirectTo: '/alerting/list',
  328. })
  329. .when('/alerting/list', {
  330. template: '<react-container />',
  331. reloadOnSearch: false,
  332. resolve: {
  333. component: () => import(/* webpackChunkName: "AlertRuleList" */ 'app/features/alerting/AlertRuleList'),
  334. },
  335. })
  336. .when('/alerting/notifications', {
  337. templateUrl: 'public/app/features/alerting/partials/notifications_list.html',
  338. controller: 'AlertNotificationsListCtrl',
  339. controllerAs: 'ctrl',
  340. })
  341. .when('/alerting/notification/new', {
  342. templateUrl: 'public/app/features/alerting/partials/notification_edit.html',
  343. controller: 'AlertNotificationEditCtrl',
  344. controllerAs: 'ctrl',
  345. })
  346. .when('/alerting/notification/:id/edit', {
  347. templateUrl: 'public/app/features/alerting/partials/notification_edit.html',
  348. controller: 'AlertNotificationEditCtrl',
  349. controllerAs: 'ctrl',
  350. })
  351. .otherwise({
  352. templateUrl: 'public/app/partials/error.html',
  353. controller: 'ErrorCtrl',
  354. });
  355. applyRouteRegistrationHandlers($routeProvider);
  356. }