电子档案
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

393 lines
14 KiB

  1. /* Licensed under the Apache License, Version 2.0 (the "License");
  2. * you may not use this file except in compliance with the License.
  3. * You may obtain a copy of the License at
  4. *
  5. * http://www.apache.org/licenses/LICENSE-2.0
  6. *
  7. * Unless required by applicable law or agreed to in writing, software
  8. * distributed under the License is distributed on an "AS IS" BASIS,
  9. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. * See the License for the specific language governing permissions and
  11. * limitations under the License.
  12. */
  13. 'use strict';
  14. var flowableApp = angular.module('flowableApp', [
  15. 'http-auth-interceptor',
  16. 'ngCookies',
  17. 'ngResource',
  18. 'ngSanitize',
  19. 'ngRoute',
  20. 'mgcrea.ngStrap',
  21. 'ngAnimate',
  22. 'ngFileUpload',
  23. 'pascalprecht.translate',
  24. 'ui.grid',
  25. 'ui.grid.edit',
  26. 'ui.grid.selection',
  27. 'ui.grid.autoResize',
  28. 'ui.grid.cellNav'
  29. ]);
  30. var flowableModule = flowableApp;
  31. flowableApp
  32. // Initialize routes
  33. .config(['$provide', '$routeProvider', '$selectProvider', '$datepickerProvider', '$translateProvider', function ($provide, $routeProvider, $selectProvider, $datepickerProvider, $translateProvider) {
  34. var appName = '';
  35. $provide.value('appName', appName);
  36. var ctx = FLOWABLE.CONFIG.webContextRoot;
  37. // Override caret for bs-select directive
  38. angular.extend($selectProvider.defaults, {
  39. caretHtml: '&nbsp;<i class="icon icon-caret-down"></i>'
  40. });
  41. // Override carets for bs-datepicker directive
  42. angular.extend($datepickerProvider.defaults, {
  43. iconLeft: 'icon icon-caret-left',
  44. iconRight: 'icon icon-caret-right'
  45. });
  46. /*
  47. * Route resolver for all authenticated routes
  48. */
  49. var authRouteResolver = ['$rootScope', 'AuthenticationSharedService', function($rootScope, AuthenticationSharedService) {
  50. if(!$rootScope.authenticated) {
  51. // Return auth-promise. On success, the promise resolves and user is assumed authenticated from now on. If
  52. // promise is rejected, route will not be followed (no unneeded HTTP-calls will be done, which case a 401 in the end, anyway)
  53. return AuthenticationSharedService.authenticate();
  54. } else {
  55. // Authentication done on rootscope, no need to call service again. Any unauthenticated access to REST will result in
  56. // a 401 and will redirect to login anyway. Done to prevent additional call to authenticate every route-change
  57. $rootScope.authenticated = true;
  58. return true;
  59. }
  60. }];
  61. /*
  62. * Route resolver for all unauthenticated routes
  63. */
  64. var unauthRouteResolver = ['$rootScope', function($rootScope) {
  65. $rootScope.authenticationChecked = true;
  66. }];
  67. $routeProvider
  68. .when('/login', {
  69. templateUrl: 'views/login.html',
  70. controller: 'LoginController',
  71. resolve: {
  72. verify: unauthRouteResolver
  73. }
  74. })
  75. .when('/user-mgmt', {
  76. controller: 'IdmUserMgmtController',
  77. templateUrl: 'views/idm-user-mgmt.html',
  78. resolve: {
  79. verify: authRouteResolver
  80. }
  81. })
  82. .when('/group-mgmt', {
  83. controller: 'GroupMgmtController',
  84. templateUrl: 'views/idm-group-mgmt.html',
  85. resolve: {
  86. verify: authRouteResolver
  87. }
  88. })
  89. .when('/privilege-mgmt', {
  90. controller: 'PrivilegeMgmtController',
  91. templateUrl: 'views/idm-privilege-mgmt.html',
  92. resolve: {
  93. verify: authRouteResolver
  94. }
  95. })
  96. .when('/logout', {
  97. templateUrl: 'views/empty.html',
  98. controller: 'LogoutController'
  99. })
  100. .otherwise({
  101. redirectTo: FLOWABLE.CONFIG.appDefaultRoute || '/user-mgmt'
  102. });
  103. // Initialize angular-translate
  104. $translateProvider.useStaticFilesLoader({
  105. prefix: './i18n/',
  106. suffix: '.json'
  107. })
  108. /*
  109. This can be used to map multiple browser language keys to a
  110. angular translate language key.
  111. */
  112. // .registerAvailableLanguageKeys(['en'], {
  113. // 'en-*': 'en'
  114. // })
  115. .useSanitizeValueStrategy('escapeParameters')
  116. .uniformLanguageTag('bcp47')
  117. .determinePreferredLanguage();
  118. }])
  119. .run(['$rootScope', function($rootScope) {
  120. $rootScope.$on( "$routeChangeStart", function(event, next, current) {
  121. if (next !== null && next !== undefined) {
  122. $rootScope.onLogin = next.templateUrl === 'views/login.html';
  123. }
  124. });
  125. }])
  126. .run(['$rootScope', '$timeout', '$translate', '$location', '$window', 'AuthenticationSharedService',
  127. function($rootScope, $timeout, $translate, $location, $window, AuthenticationSharedService) {
  128. // set angular translate fallback language
  129. $translate.fallbackLanguage(['en']);
  130. // setting Moment-JS (global) locale
  131. if (FLOWABLE.CONFIG.datesLocalization) {
  132. moment.locale($translate.proposedLanguage());
  133. }
  134. // Common model (eg selected tenant id)
  135. $rootScope.common = {};
  136. $rootScope.webRootUrl = function() {
  137. return FLOWABLE.CONFIG.webContextRoot;
  138. };
  139. $rootScope.restRootUrl = function() {
  140. return FLOWABLE.CONFIG.contextIdmRestRoot;
  141. };
  142. // Needed for auto-height
  143. $rootScope.window = {};
  144. var updateWindowSize = function() {
  145. $rootScope.window.width = $window.innerWidth;
  146. $rootScope.window.height = $window.innerHeight;
  147. };
  148. // Window resize hook
  149. angular.element($window).bind('resize', function() {
  150. $rootScope.$apply(updateWindowSize());
  151. });
  152. $rootScope.$watch('window.forceRefresh', function(newValue) {
  153. if(newValue) {
  154. $timeout(function() {
  155. updateWindowSize();
  156. $rootScope.window.forceRefresh = false;
  157. });
  158. }
  159. });
  160. updateWindowSize();
  161. // Main navigation depends on the account being fetched
  162. $rootScope.$watch('account', function() {
  163. $rootScope.mainNavigation = [
  164. {
  165. id: 'userMgmt',
  166. title: 'IDM.GENERAL.NAVIGATION.USER-MGMT',
  167. path: '/user-mgmt'
  168. },
  169. {
  170. id: 'groupMgmt',
  171. title: 'IDM.GENERAL.NAVIGATION.GROUP-MGMT',
  172. path: '/group-mgmt'
  173. },
  174. {
  175. id: 'privilegeMgmt',
  176. title: 'IDM.GENERAL.NAVIGATION.PRIVILEGE-MGMT',
  177. path: '/privilege-mgmt'
  178. }
  179. ];
  180. /*
  181. * Set the current main page, using the page object. If the page is already active,
  182. * this is a no-op.
  183. */
  184. $rootScope.setMainPage = function(mainPage) {
  185. $rootScope.mainPage = mainPage;
  186. $location.path($rootScope.mainPage.path);
  187. };
  188. /*
  189. * Set the current main page, using the page ID. If the page is already active,
  190. * this is a no-op.
  191. */
  192. $rootScope.setMainPageById = function(mainPageId) {
  193. for (var i=0; i<$rootScope.mainNavigation.length; i++) {
  194. if (mainPageId == $rootScope.mainNavigation[i].id) {
  195. $rootScope.mainPage = $rootScope.mainNavigation[i];
  196. break;
  197. }
  198. }
  199. };
  200. });
  201. }
  202. ])
  203. .run(['$rootScope', '$timeout', '$translate', '$location', '$http', '$window', '$popover',
  204. function($rootScope, $timeout, $translate, $location, $http, $window, $popover) {
  205. // Alerts
  206. $rootScope.alerts = {
  207. queue: []
  208. };
  209. $rootScope.webRootUrl = function() {
  210. return FLOWABLE.CONFIG.webContextRoot;
  211. };
  212. $rootScope.restRootUrl = function() {
  213. return FLOWABLE.CONFIG.contextRoot;
  214. };
  215. $rootScope.showAlert = function(alert) {
  216. if(alert.queue.length > 0) {
  217. alert.current = alert.queue.shift();
  218. // Start timout for message-pruning
  219. alert.timeout = $timeout(function() {
  220. if(alert.queue.length == 0) {
  221. alert.current = undefined;
  222. alert.timeout = undefined;
  223. } else {
  224. $rootScope.showAlert(alert);
  225. }
  226. }, (alert.current.type == 'error' ? 5000 : 1000));
  227. } else {
  228. $rootScope.alerts.current = undefined;
  229. }
  230. };
  231. $rootScope.addAlert = function(message, type) {
  232. var newAlert = {message: message, type: type};
  233. if(!$rootScope.alerts.timeout) {
  234. // Timeout for message queue is not running, start one
  235. $rootScope.alerts.queue.push(newAlert);
  236. $rootScope.showAlert($rootScope.alerts);
  237. } else {
  238. $rootScope.alerts.queue.push(newAlert);
  239. }
  240. };
  241. $rootScope.dismissAlert = function() {
  242. if(!$rootScope.alerts.timeout) {
  243. $rootScope.alerts.current = undefined;
  244. } else {
  245. $timeout.cancel($rootScope.alerts.timeout);
  246. $rootScope.alerts.timeout = undefined;
  247. $rootScope.showAlert($rootScope.alerts);
  248. }
  249. };
  250. $rootScope.addAlertPromise = function(promise, type) {
  251. if(promise) {
  252. promise.then(function(data) {
  253. $rootScope.addAlert(data, type);
  254. });
  255. }
  256. };
  257. }])
  258. .run(['$rootScope', '$location', '$window', 'AuthenticationSharedService', '$translate', '$modal',
  259. function($rootScope, $location, $window, AuthenticationSharedService, $translate, $modal) {
  260. /* Auto-height */
  261. $rootScope.window = {};
  262. var updateWindowSize = function() {
  263. $rootScope.window.width = $window.innerWidth;
  264. $rootScope.window.height = $window.innerHeight;
  265. };
  266. // Window resize hook
  267. angular.element($window).bind('resize', function() {
  268. $rootScope.$apply(updateWindowSize());
  269. });
  270. $rootScope.$watch('window.forceRefresh', function(newValue) {
  271. if(newValue) {
  272. $timeout(function() {
  273. updateWindowSize();
  274. $rootScope.window.forceRefresh = false;
  275. });
  276. }
  277. });
  278. updateWindowSize();
  279. $rootScope.logout = function() {
  280. // Changing the href causes a reload, so no need to do a new reload again
  281. $window.location.href = FLOWABLE.CONFIG.contextRoot + '/app/logout';
  282. };
  283. // Call when the 401 response is returned by the client
  284. $rootScope.$on('event:auth-loginRequired', function(rejection) {
  285. $rootScope.authenticated = false;
  286. $rootScope.authenticationChecked = true;
  287. if (FLOWABLE.CONFIG.loginUrl) {
  288. $window.location.href = FLOWABLE.CONFIG.loginUrl.replace("{url}", $location.absUrl());
  289. $window.reload();
  290. }
  291. else {
  292. $location.path('/login').replace();
  293. }
  294. });
  295. // Call when the user is authenticated
  296. $rootScope.$on('event:auth-authConfirmed', function(event, data) {
  297. $rootScope.authenticated = true;
  298. $rootScope.authenticationChecked = true;
  299. var redirectUrl = $location.search().redirectUrl;
  300. if (redirectUrl !== null && redirectUrl !== undefined && redirectUrl.length > 0) {
  301. $window.location.href = redirectUrl;
  302. } else {
  303. var locationPath = $location.path();
  304. if (locationPath === '' || locationPath === '#' || locationPath === '/login') {
  305. if (FLOWABLE.CONFIG.contextRoot === '') {
  306. // When running on root (no context root)
  307. $window.location.href = "/";
  308. } else {
  309. $window.location.href = FLOWABLE.CONFIG.contextRoot;
  310. }
  311. } else if (locationPath.indexOf('/account/activate/') >= 0 || locationPath.indexOf('/account/reset-password/') >= 0) {
  312. $location.path('/');
  313. }
  314. }
  315. });
  316. // Call when the user logs in
  317. $rootScope.$on('event:auth-loginConfirmed', function() {
  318. AuthenticationSharedService.authenticate();
  319. });
  320. // Call when the user logs out
  321. $rootScope.$on('event:auth-loginCancelled', function() {
  322. $rootScope.authenticated = false;
  323. // Changing the href causes a reload, so no need to do a new reload again
  324. $window.location.href = FLOWABLE.CONFIG.contextRoot;
  325. });
  326. // Call when login fails
  327. $rootScope.$on('event:auth-loginFailed', function() {
  328. $rootScope.addAlertPromise($translate('LOGIN.MESSAGES.ERROR.AUTHENTICATION'), 'error');
  329. });
  330. $rootScope.backToLanding = function() {
  331. $window.location.href = FLOWABLE.CONFIG.contextRoot;
  332. };
  333. }])
  334. // Moment-JS date-formatting filter
  335. .filter('dateformat', function() {
  336. return function(date, format) {
  337. if (date) {
  338. if (format) {
  339. return moment(date).format(format);
  340. } else {
  341. return moment(date).calendar();
  342. }
  343. }
  344. return '';
  345. };
  346. });