Digital Office Automation System Backend
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /*
  2. * Activiti Modeler component part of the Activiti project
  3. * Copyright 2005-2014 Alfresco Software, Ltd. All rights reserved.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2.1 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with this library; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. 'use strict';
  19. var activitiModeler = angular.module('activitiModeler', [
  20. 'ngCookies',
  21. 'ngResource',
  22. 'ngSanitize',
  23. 'ngRoute',
  24. 'ngDragDrop',
  25. 'mgcrea.ngStrap',
  26. 'ngGrid',
  27. 'ngAnimate',
  28. 'pascalprecht.translate',
  29. 'duScroll'
  30. ]);
  31. var activitiModule = activitiModeler;
  32. activitiModeler
  33. // Initialize routes
  34. .config(['$selectProvider', '$translateProvider', function ($selectProvider, $translateProvider) {
  35. // Override caret for bs-select directive
  36. angular.extend($selectProvider.defaults, {
  37. caretHtml: '&nbsp;<i class="icon icon-caret-down"></i>'
  38. });
  39. // Initialize angular-translate
  40. $translateProvider.useStaticFilesLoader({
  41. prefix: './editor-app/i18n/',
  42. suffix: '.json'
  43. });
  44. // $translateProvider.preferredLanguage('en');
  45. // 多语言支持
  46. if("zh-CN" == navigator.language){
  47. $translateProvider.preferredLanguage('zh-CN');
  48. }else {
  49. $translateProvider.preferredLanguage('en');
  50. }
  51. // remember language
  52. $translateProvider.useCookieStorage();
  53. }])
  54. .run(['$rootScope', '$timeout', '$modal', '$translate', '$location', '$window', '$http', '$q',
  55. function($rootScope, $timeout, $modal, $translate, $location, $window, $http, $q) {
  56. $rootScope.config = ACTIVITI.CONFIG;
  57. $rootScope.editorInitialized = false;
  58. $rootScope.editorFactory = $q.defer();
  59. $rootScope.forceSelectionRefresh = false;
  60. $rootScope.ignoreChanges = false; // by default never ignore changes
  61. $rootScope.validationErrors = [];
  62. $rootScope.staticIncludeVersion = Date.now();
  63. /**
  64. * A 'safer' apply that avoids concurrent updates (which $apply allows).
  65. */
  66. $rootScope.safeApply = function(fn) {
  67. var phase = this.$root.$$phase;
  68. if(phase == '$apply' || phase == '$digest') {
  69. if(fn && (typeof(fn) === 'function')) {
  70. fn();
  71. }
  72. } else {
  73. this.$apply(fn);
  74. }
  75. };
  76. /**
  77. * Initialize the event bus: couple all Oryx events with a dispatch of the
  78. * event of the event bus. This way, it gets much easier to attach custom logic
  79. * to any event.
  80. */
  81. /* Helper method to fetch model from server (always needed) */
  82. function fetchModel(modelId) {
  83. var modelUrl = KISBPM.URL.getModel(modelId);
  84. $http({method: 'GET', url: modelUrl}).
  85. success(function (data, status, headers, config) {
  86. $rootScope.editor = new ORYX.Editor(data);
  87. $rootScope.modelData = angular.fromJson(data);
  88. $rootScope.editorFactory.resolve();
  89. }).
  90. error(function (data, status, headers, config) {
  91. console.log('Error loading model with id ' + modelId + ' ' + data);
  92. });
  93. }
  94. function initScrollHandling() {
  95. var canvasSection = jQuery('#canvasSection');
  96. canvasSection.scroll(function() {
  97. // Hides the resizer and quick menu items during scrolling
  98. var selectedElements = $rootScope.editor.selection;
  99. var subSelectionElements = $rootScope.editor._subSelection;
  100. $rootScope.selectedElements = selectedElements;
  101. $rootScope.subSelectionElements = subSelectionElements;
  102. if (selectedElements && selectedElements.length > 0) {
  103. $rootScope.selectedElementBeforeScrolling = selectedElements[0];
  104. }
  105. jQuery('.Oryx_button').each(function(i, obj) {
  106. $rootScope.orginalOryxButtonStyle = obj.style.display;
  107. obj.style.display = 'none';
  108. });
  109. jQuery('.resizer_southeast').each(function(i, obj) {
  110. $rootScope.orginalResizerSEStyle = obj.style.display;
  111. obj.style.display = 'none';
  112. });
  113. jQuery('.resizer_northwest').each(function(i, obj) {
  114. $rootScope.orginalResizerNWStyle = obj.style.display;
  115. obj.style.display = 'none';
  116. });
  117. $rootScope.editor.handleEvents({type:ORYX.CONFIG.EVENT_CANVAS_SCROLL});
  118. });
  119. canvasSection.scrollStopped(function(){
  120. // Puts the quick menu items and resizer back when scroll is stopped.
  121. $rootScope.editor.setSelection([]); // needed cause it checks for element changes and does nothing if the elements are the same
  122. $rootScope.editor.setSelection($rootScope.selectedElements, $rootScope.subSelectionElements);
  123. $rootScope.selectedElements = undefined;
  124. $rootScope.subSelectionElements = undefined;
  125. function handleDisplayProperty(obj) {
  126. if (jQuery(obj).position().top > 0) {
  127. obj.style.display = 'block';
  128. } else {
  129. obj.style.display = 'none';
  130. }
  131. }
  132. jQuery('.Oryx_button').each(function(i, obj) {
  133. handleDisplayProperty(obj);
  134. });
  135. jQuery('.resizer_southeast').each(function(i, obj) {
  136. handleDisplayProperty(obj);
  137. });
  138. jQuery('.resizer_northwest').each(function(i, obj) {
  139. handleDisplayProperty(obj);
  140. });
  141. });
  142. }
  143. /**
  144. * Initialize the Oryx Editor when the content has been loaded
  145. */
  146. $rootScope.$on('$includeContentLoaded', function (event) {
  147. if (!$rootScope.editorInitialized) {
  148. ORYX._loadPlugins();
  149. var modelId = EDITOR.UTIL.getParameterByName('modelId');
  150. fetchModel(modelId);
  151. $rootScope.window = {};
  152. var updateWindowSize = function() {
  153. $rootScope.window.width = $window.innerWidth;
  154. $rootScope.window.height = $window.innerHeight;
  155. };
  156. // Window resize hook
  157. angular.element($window).bind('resize', function() {
  158. $rootScope.safeApply(updateWindowSize());
  159. });
  160. $rootScope.$watch('window.forceRefresh', function(newValue) {
  161. if(newValue) {
  162. $timeout(function() {
  163. updateWindowSize();
  164. $rootScope.window.forceRefresh = false;
  165. });
  166. }
  167. });
  168. updateWindowSize();
  169. // Hook in resizing of main panels when window resizes
  170. // TODO: perhaps move to a separate JS-file?
  171. jQuery(window).resize(function () {
  172. // Calculate the offset based on the bottom of the module header
  173. var offset = jQuery("#editor-header").offset();
  174. var propSectionHeight = jQuery('#propertySection').height();
  175. var canvas = jQuery('#canvasSection');
  176. var mainHeader = jQuery('#main-header');
  177. if (offset == undefined || offset === null
  178. || propSectionHeight === undefined || propSectionHeight === null
  179. || canvas === undefined || canvas === null || mainHeader === null) {
  180. return;
  181. }
  182. if ($rootScope.editor)
  183. {
  184. var selectedElements = $rootScope.editor.selection;
  185. var subSelectionElements = $rootScope.editor._subSelection;
  186. $rootScope.selectedElements = selectedElements;
  187. $rootScope.subSelectionElements = subSelectionElements;
  188. if (selectedElements && selectedElements.length > 0)
  189. {
  190. $rootScope.selectedElementBeforeScrolling = selectedElements[0];
  191. $rootScope.editor.setSelection([]); // needed cause it checks for element changes and does nothing if the elements are the same
  192. $rootScope.editor.setSelection($rootScope.selectedElements, $rootScope.subSelectionElements);
  193. $rootScope.selectedElements = undefined;
  194. $rootScope.subSelectionElements = undefined;
  195. }
  196. }
  197. var totalAvailable = jQuery(window).height() - offset.top - mainHeader.height() - 21;
  198. canvas.height(totalAvailable - propSectionHeight);
  199. jQuery('#paletteSection').height(totalAvailable);
  200. // Update positions of the resize-markers, according to the canvas
  201. var actualCanvas = null;
  202. if (canvas && canvas[0].children[1]) {
  203. actualCanvas = canvas[0].children[1];
  204. }
  205. var canvasTop = canvas.position().top;
  206. var canvasLeft = canvas.position().left;
  207. var canvasHeight = canvas[0].clientHeight;
  208. var canvasWidth = canvas[0].clientWidth;
  209. var iconCenterOffset = 8;
  210. var widthDiff = 0;
  211. var actualWidth = 0;
  212. if(actualCanvas) {
  213. // In some browsers, the SVG-element clientwidth isn't available, so we revert to the parent
  214. actualWidth = actualCanvas.clientWidth || actualCanvas.parentNode.clientWidth;
  215. }
  216. if(actualWidth < canvas[0].clientWidth) {
  217. widthDiff = actualWidth - canvas[0].clientWidth;
  218. // In case the canvas is smaller than the actual viewport, the resizers should be moved
  219. canvasLeft -= widthDiff / 2;
  220. canvasWidth += widthDiff;
  221. }
  222. var iconWidth = 17;
  223. var iconOffset = 20;
  224. var north = jQuery('#canvas-grow-N');
  225. north.css('top', canvasTop + iconOffset + 'px');
  226. north.css('left', canvasLeft - 10 + (canvasWidth - iconWidth) / 2 + 'px');
  227. var south = jQuery('#canvas-grow-S');
  228. south.css('top', (canvasTop + canvasHeight - iconOffset - iconCenterOffset) + 'px');
  229. south.css('left', canvasLeft - 10 + (canvasWidth - iconWidth) / 2 + 'px');
  230. var east = jQuery('#canvas-grow-E');
  231. east.css('top', canvasTop - 10 + (canvasHeight - iconWidth) / 2 + 'px');
  232. east.css('left', (canvasLeft + canvasWidth - iconOffset - iconCenterOffset) + 'px');
  233. var west = jQuery('#canvas-grow-W');
  234. west.css('top', canvasTop -10 + (canvasHeight - iconWidth) / 2 + 'px');
  235. west.css('left', canvasLeft + iconOffset + 'px');
  236. north = jQuery('#canvas-shrink-N');
  237. north.css('top', canvasTop + iconOffset + 'px');
  238. north.css('left', canvasLeft + 10 + (canvasWidth - iconWidth) / 2 + 'px');
  239. south = jQuery('#canvas-shrink-S');
  240. south.css('top', (canvasTop + canvasHeight - iconOffset - iconCenterOffset) + 'px');
  241. south.css('left', canvasLeft +10 + (canvasWidth - iconWidth) / 2 + 'px');
  242. east = jQuery('#canvas-shrink-E');
  243. east.css('top', canvasTop + 10 + (canvasHeight - iconWidth) / 2 + 'px');
  244. east.css('left', (canvasLeft + canvasWidth - iconOffset - iconCenterOffset) + 'px');
  245. west = jQuery('#canvas-shrink-W');
  246. west.css('top', canvasTop + 10 + (canvasHeight - iconWidth) / 2 + 'px');
  247. west.css('left', canvasLeft + iconOffset + 'px');
  248. });
  249. jQuery(window).trigger('resize');
  250. jQuery.fn.scrollStopped = function(callback) {
  251. jQuery(this).scroll(function(){
  252. var self = this, $this = jQuery(self);
  253. if ($this.data('scrollTimeout')) {
  254. clearTimeout($this.data('scrollTimeout'));
  255. }
  256. $this.data('scrollTimeout', setTimeout(callback,50,self));
  257. });
  258. };
  259. // Always needed, cause the DOM element on which the scroll event listeners are attached are changed for every new model
  260. initScrollHandling();
  261. $rootScope.editorInitialized = true;
  262. }
  263. });
  264. /**
  265. * Initialize the event bus: couple all Oryx events with a dispatch of the
  266. * event of the event bus. This way, it gets much easier to attach custom logic
  267. * to any event.
  268. */
  269. $rootScope.editorFactory.promise.then(function() {
  270. KISBPM.eventBus.editor = $rootScope.editor;
  271. var eventMappings = [
  272. { oryxType : ORYX.CONFIG.EVENT_SELECTION_CHANGED, kisBpmType : KISBPM.eventBus.EVENT_TYPE_SELECTION_CHANGE },
  273. { oryxType : ORYX.CONFIG.EVENT_DBLCLICK, kisBpmType : KISBPM.eventBus.EVENT_TYPE_DOUBLE_CLICK },
  274. { oryxType : ORYX.CONFIG.EVENT_MOUSEOUT, kisBpmType : KISBPM.eventBus.EVENT_TYPE_MOUSE_OUT },
  275. { oryxType : ORYX.CONFIG.EVENT_MOUSEOVER, kisBpmType : KISBPM.eventBus.EVENT_TYPE_MOUSE_OVER }
  276. ];
  277. eventMappings.forEach(function(eventMapping) {
  278. $rootScope.editor.registerOnEvent(eventMapping.oryxType, function(event) {
  279. KISBPM.eventBus.dispatch(eventMapping.kisBpmType, event);
  280. });
  281. });
  282. $rootScope.editor.registerOnEvent(ORYX.CONFIG.EVENT_SHAPEREMOVED, function (event) {
  283. var validateButton = document.getElementById(event.shape.resourceId + "-validate-button");
  284. if (validateButton)
  285. {
  286. validateButton.style.display = 'none';
  287. }
  288. });
  289. // The Oryx canvas is ready (we know since we're in this promise callback) and the
  290. // event bus is ready. The editor is now ready for use
  291. KISBPM.eventBus.dispatch(KISBPM.eventBus.EVENT_TYPE_EDITOR_READY, {type : KISBPM.eventBus.EVENT_TYPE_EDITOR_READY});
  292. });
  293. // Alerts
  294. $rootScope.alerts = {
  295. queue: []
  296. };
  297. $rootScope.showAlert = function(alert) {
  298. if(alert.queue.length > 0) {
  299. alert.current = alert.queue.shift();
  300. // Start timout for message-pruning
  301. alert.timeout = $timeout(function() {
  302. if (alert.queue.length == 0) {
  303. alert.current = undefined;
  304. alert.timeout = undefined;
  305. } else {
  306. $rootScope.showAlert(alert);
  307. }
  308. }, (alert.current.type == 'error' ? 5000 : 1000));
  309. } else {
  310. $rootScope.alerts.current = undefined;
  311. }
  312. };
  313. $rootScope.addAlert = function(message, type) {
  314. var newAlert = {message: message, type: type};
  315. if (!$rootScope.alerts.timeout) {
  316. // Timeout for message queue is not running, start one
  317. $rootScope.alerts.queue.push(newAlert);
  318. $rootScope.showAlert($rootScope.alerts);
  319. } else {
  320. $rootScope.alerts.queue.push(newAlert);
  321. }
  322. };
  323. $rootScope.dismissAlert = function() {
  324. if (!$rootScope.alerts.timeout) {
  325. $rootScope.alerts.current = undefined;
  326. } else {
  327. $timeout.cancel($rootScope.alerts.timeout);
  328. $rootScope.alerts.timeout = undefined;
  329. $rootScope.showAlert($rootScope.alerts);
  330. }
  331. };
  332. $rootScope.addAlertPromise = function(promise, type) {
  333. if (promise) {
  334. promise.then(function(data) {
  335. $rootScope.addAlert(data, type);
  336. });
  337. }
  338. };
  339. }
  340. ])
  341. // Moment-JS date-formatting filter
  342. .filter('dateformat', function() {
  343. return function(date, format) {
  344. if (date) {
  345. if (format) {
  346. return moment(date).format(format);
  347. } else {
  348. return moment(date).calendar();
  349. }
  350. }
  351. return '';
  352. };
  353. });