first commit
This commit is contained in:
438
bin/WebRoot/editor-app/app.js
Normal file
438
bin/WebRoot/editor-app/app.js
Normal file
@ -0,0 +1,438 @@
|
||||
/*
|
||||
* Activiti Modeler component part of the Activiti project
|
||||
* Copyright 2005-2014 Alfresco Software, Ltd. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var activitiModeler = angular.module('activitiModeler', [
|
||||
'ngCookies',
|
||||
'ngResource',
|
||||
'ngSanitize',
|
||||
'ngRoute',
|
||||
'ngDragDrop',
|
||||
'mgcrea.ngStrap',
|
||||
'ngGrid',
|
||||
'ngAnimate',
|
||||
'pascalprecht.translate',
|
||||
'duScroll'
|
||||
]);
|
||||
|
||||
var activitiModule = activitiModeler;
|
||||
|
||||
activitiModeler
|
||||
// Initialize routes
|
||||
.config(['$selectProvider', '$translateProvider', function ($selectProvider, $translateProvider) {
|
||||
|
||||
// Override caret for bs-select directive
|
||||
angular.extend($selectProvider.defaults, {
|
||||
caretHtml: ' <i class="icon icon-caret-down"></i>'
|
||||
});
|
||||
|
||||
// Initialize angular-translate
|
||||
$translateProvider.useStaticFilesLoader({
|
||||
prefix: './editor-app/i18n/',
|
||||
suffix: '.json'
|
||||
});
|
||||
|
||||
$translateProvider.preferredLanguage('en');
|
||||
/*var language = navigator.language;
|
||||
console.log("language",language)
|
||||
if("zh-CN" == language){
|
||||
$translateProvider.preferredLanguage('zh-CN');
|
||||
}else{
|
||||
$translateProvider.preferredLanguage('en');
|
||||
} */
|
||||
// remember language
|
||||
$translateProvider.useCookieStorage();
|
||||
|
||||
}])
|
||||
.run(['$rootScope', '$timeout', '$modal', '$translate', '$location', '$window', '$http', '$q',
|
||||
function($rootScope, $timeout, $modal, $translate, $location, $window, $http, $q) {
|
||||
|
||||
$rootScope.config = ACTIVITI.CONFIG;
|
||||
|
||||
$rootScope.editorInitialized = false;
|
||||
|
||||
$rootScope.editorFactory = $q.defer();
|
||||
|
||||
$rootScope.forceSelectionRefresh = false;
|
||||
|
||||
$rootScope.ignoreChanges = false; // by default never ignore changes
|
||||
|
||||
$rootScope.validationErrors = [];
|
||||
|
||||
$rootScope.staticIncludeVersion = Date.now();
|
||||
|
||||
/**
|
||||
* A 'safer' apply that avoids concurrent updates (which $apply allows).
|
||||
*/
|
||||
$rootScope.safeApply = function(fn) {
|
||||
var phase = this.$root.$$phase;
|
||||
if(phase == '$apply' || phase == '$digest') {
|
||||
if(fn && (typeof(fn) === 'function')) {
|
||||
fn();
|
||||
}
|
||||
} else {
|
||||
this.$apply(fn);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the event bus: couple all Oryx events with a dispatch of the
|
||||
* event of the event bus. This way, it gets much easier to attach custom logic
|
||||
* to any event.
|
||||
*/
|
||||
|
||||
/* Helper method to fetch model from server (always needed) */
|
||||
function fetchModel(modelId) {
|
||||
|
||||
var modelUrl = KISBPM.URL.getModel(modelId);
|
||||
|
||||
$http({method: 'GET', url: modelUrl}).
|
||||
success(function (data, status, headers, config) {
|
||||
$rootScope.editor = new ORYX.Editor(data);
|
||||
$rootScope.modelData = angular.fromJson(data);
|
||||
$rootScope.editorFactory.resolve();
|
||||
}).
|
||||
error(function (data, status, headers, config) {
|
||||
console.log('Error loading model with id ' + modelId + ' ' + data);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function initScrollHandling() {
|
||||
var canvasSection = jQuery('#canvasSection');
|
||||
canvasSection.scroll(function() {
|
||||
|
||||
// Hides the resizer and quick menu items during scrolling
|
||||
|
||||
var selectedElements = $rootScope.editor.selection;
|
||||
var subSelectionElements = $rootScope.editor._subSelection;
|
||||
|
||||
$rootScope.selectedElements = selectedElements;
|
||||
$rootScope.subSelectionElements = subSelectionElements;
|
||||
if (selectedElements && selectedElements.length > 0) {
|
||||
$rootScope.selectedElementBeforeScrolling = selectedElements[0];
|
||||
}
|
||||
|
||||
jQuery('.Oryx_button').each(function(i, obj) {
|
||||
$rootScope.orginalOryxButtonStyle = obj.style.display;
|
||||
obj.style.display = 'none';
|
||||
});
|
||||
|
||||
jQuery('.resizer_southeast').each(function(i, obj) {
|
||||
$rootScope.orginalResizerSEStyle = obj.style.display;
|
||||
obj.style.display = 'none';
|
||||
});
|
||||
jQuery('.resizer_northwest').each(function(i, obj) {
|
||||
$rootScope.orginalResizerNWStyle = obj.style.display;
|
||||
obj.style.display = 'none';
|
||||
});
|
||||
$rootScope.editor.handleEvents({type:ORYX.CONFIG.EVENT_CANVAS_SCROLL});
|
||||
});
|
||||
|
||||
canvasSection.scrollStopped(function(){
|
||||
|
||||
// Puts the quick menu items and resizer back when scroll is stopped.
|
||||
|
||||
$rootScope.editor.setSelection([]); // needed cause it checks for element changes and does nothing if the elements are the same
|
||||
$rootScope.editor.setSelection($rootScope.selectedElements, $rootScope.subSelectionElements);
|
||||
$rootScope.selectedElements = undefined;
|
||||
$rootScope.subSelectionElements = undefined;
|
||||
|
||||
function handleDisplayProperty(obj) {
|
||||
if (jQuery(obj).position().top > 0) {
|
||||
obj.style.display = 'block';
|
||||
} else {
|
||||
obj.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
jQuery('.Oryx_button').each(function(i, obj) {
|
||||
handleDisplayProperty(obj);
|
||||
});
|
||||
|
||||
jQuery('.resizer_southeast').each(function(i, obj) {
|
||||
handleDisplayProperty(obj);
|
||||
});
|
||||
jQuery('.resizer_northwest').each(function(i, obj) {
|
||||
handleDisplayProperty(obj);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the Oryx Editor when the content has been loaded
|
||||
*/
|
||||
$rootScope.$on('$includeContentLoaded', function (event) {
|
||||
if (!$rootScope.editorInitialized) {
|
||||
|
||||
ORYX._loadPlugins();
|
||||
|
||||
var modelId = EDITOR.UTIL.getParameterByName('modelId');
|
||||
fetchModel(modelId);
|
||||
|
||||
$rootScope.window = {};
|
||||
var updateWindowSize = function() {
|
||||
$rootScope.window.width = $window.innerWidth;
|
||||
$rootScope.window.height = $window.innerHeight;
|
||||
};
|
||||
|
||||
// Window resize hook
|
||||
angular.element($window).bind('resize', function() {
|
||||
$rootScope.safeApply(updateWindowSize());
|
||||
});
|
||||
|
||||
$rootScope.$watch('window.forceRefresh', function(newValue) {
|
||||
if(newValue) {
|
||||
$timeout(function() {
|
||||
updateWindowSize();
|
||||
$rootScope.window.forceRefresh = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
updateWindowSize();
|
||||
|
||||
// Hook in resizing of main panels when window resizes
|
||||
// TODO: perhaps move to a separate JS-file?
|
||||
jQuery(window).resize(function () {
|
||||
|
||||
// Calculate the offset based on the bottom of the module header
|
||||
var offset = jQuery("#editor-header").offset();
|
||||
var propSectionHeight = jQuery('#propertySection').height();
|
||||
var canvas = jQuery('#canvasSection');
|
||||
var mainHeader = jQuery('#main-header');
|
||||
|
||||
if (offset == undefined || offset === null
|
||||
|| propSectionHeight === undefined || propSectionHeight === null
|
||||
|| canvas === undefined || canvas === null || mainHeader === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($rootScope.editor)
|
||||
{
|
||||
var selectedElements = $rootScope.editor.selection;
|
||||
var subSelectionElements = $rootScope.editor._subSelection;
|
||||
|
||||
$rootScope.selectedElements = selectedElements;
|
||||
$rootScope.subSelectionElements = subSelectionElements;
|
||||
if (selectedElements && selectedElements.length > 0)
|
||||
{
|
||||
$rootScope.selectedElementBeforeScrolling = selectedElements[0];
|
||||
|
||||
$rootScope.editor.setSelection([]); // needed cause it checks for element changes and does nothing if the elements are the same
|
||||
$rootScope.editor.setSelection($rootScope.selectedElements, $rootScope.subSelectionElements);
|
||||
$rootScope.selectedElements = undefined;
|
||||
$rootScope.subSelectionElements = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
var totalAvailable = jQuery(window).height() - offset.top - mainHeader.height() - 21;
|
||||
canvas.height(totalAvailable - propSectionHeight);
|
||||
jQuery('#paletteSection').height(totalAvailable);
|
||||
|
||||
// Update positions of the resize-markers, according to the canvas
|
||||
|
||||
var actualCanvas = null;
|
||||
if (canvas && canvas[0].children[1]) {
|
||||
actualCanvas = canvas[0].children[1];
|
||||
}
|
||||
|
||||
var canvasTop = canvas.position().top;
|
||||
var canvasLeft = canvas.position().left;
|
||||
var canvasHeight = canvas[0].clientHeight;
|
||||
var canvasWidth = canvas[0].clientWidth;
|
||||
var iconCenterOffset = 8;
|
||||
var widthDiff = 0;
|
||||
|
||||
var actualWidth = 0;
|
||||
if(actualCanvas) {
|
||||
// In some browsers, the SVG-element clientwidth isn't available, so we revert to the parent
|
||||
actualWidth = actualCanvas.clientWidth || actualCanvas.parentNode.clientWidth;
|
||||
}
|
||||
|
||||
|
||||
if(actualWidth < canvas[0].clientWidth) {
|
||||
widthDiff = actualWidth - canvas[0].clientWidth;
|
||||
// In case the canvas is smaller than the actual viewport, the resizers should be moved
|
||||
canvasLeft -= widthDiff / 2;
|
||||
canvasWidth += widthDiff;
|
||||
}
|
||||
|
||||
var iconWidth = 17;
|
||||
var iconOffset = 20;
|
||||
|
||||
var north = jQuery('#canvas-grow-N');
|
||||
north.css('top', canvasTop + iconOffset + 'px');
|
||||
north.css('left', canvasLeft - 10 + (canvasWidth - iconWidth) / 2 + 'px');
|
||||
|
||||
var south = jQuery('#canvas-grow-S');
|
||||
south.css('top', (canvasTop + canvasHeight - iconOffset - iconCenterOffset) + 'px');
|
||||
south.css('left', canvasLeft - 10 + (canvasWidth - iconWidth) / 2 + 'px');
|
||||
|
||||
var east = jQuery('#canvas-grow-E');
|
||||
east.css('top', canvasTop - 10 + (canvasHeight - iconWidth) / 2 + 'px');
|
||||
east.css('left', (canvasLeft + canvasWidth - iconOffset - iconCenterOffset) + 'px');
|
||||
|
||||
var west = jQuery('#canvas-grow-W');
|
||||
west.css('top', canvasTop -10 + (canvasHeight - iconWidth) / 2 + 'px');
|
||||
west.css('left', canvasLeft + iconOffset + 'px');
|
||||
|
||||
north = jQuery('#canvas-shrink-N');
|
||||
north.css('top', canvasTop + iconOffset + 'px');
|
||||
north.css('left', canvasLeft + 10 + (canvasWidth - iconWidth) / 2 + 'px');
|
||||
|
||||
south = jQuery('#canvas-shrink-S');
|
||||
south.css('top', (canvasTop + canvasHeight - iconOffset - iconCenterOffset) + 'px');
|
||||
south.css('left', canvasLeft +10 + (canvasWidth - iconWidth) / 2 + 'px');
|
||||
|
||||
east = jQuery('#canvas-shrink-E');
|
||||
east.css('top', canvasTop + 10 + (canvasHeight - iconWidth) / 2 + 'px');
|
||||
east.css('left', (canvasLeft + canvasWidth - iconOffset - iconCenterOffset) + 'px');
|
||||
|
||||
west = jQuery('#canvas-shrink-W');
|
||||
west.css('top', canvasTop + 10 + (canvasHeight - iconWidth) / 2 + 'px');
|
||||
west.css('left', canvasLeft + iconOffset + 'px');
|
||||
});
|
||||
|
||||
jQuery(window).trigger('resize');
|
||||
|
||||
jQuery.fn.scrollStopped = function(callback) {
|
||||
jQuery(this).scroll(function(){
|
||||
var self = this, $this = jQuery(self);
|
||||
if ($this.data('scrollTimeout')) {
|
||||
clearTimeout($this.data('scrollTimeout'));
|
||||
}
|
||||
$this.data('scrollTimeout', setTimeout(callback,50,self));
|
||||
});
|
||||
};
|
||||
|
||||
// Always needed, cause the DOM element on which the scroll event listeners are attached are changed for every new model
|
||||
initScrollHandling();
|
||||
|
||||
$rootScope.editorInitialized = true;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Initialize the event bus: couple all Oryx events with a dispatch of the
|
||||
* event of the event bus. This way, it gets much easier to attach custom logic
|
||||
* to any event.
|
||||
*/
|
||||
|
||||
$rootScope.editorFactory.promise.then(function() {
|
||||
|
||||
KISBPM.eventBus.editor = $rootScope.editor;
|
||||
|
||||
var eventMappings = [
|
||||
{ oryxType : ORYX.CONFIG.EVENT_SELECTION_CHANGED, kisBpmType : KISBPM.eventBus.EVENT_TYPE_SELECTION_CHANGE },
|
||||
{ oryxType : ORYX.CONFIG.EVENT_DBLCLICK, kisBpmType : KISBPM.eventBus.EVENT_TYPE_DOUBLE_CLICK },
|
||||
{ oryxType : ORYX.CONFIG.EVENT_MOUSEOUT, kisBpmType : KISBPM.eventBus.EVENT_TYPE_MOUSE_OUT },
|
||||
{ oryxType : ORYX.CONFIG.EVENT_MOUSEOVER, kisBpmType : KISBPM.eventBus.EVENT_TYPE_MOUSE_OVER }
|
||||
|
||||
];
|
||||
|
||||
eventMappings.forEach(function(eventMapping) {
|
||||
$rootScope.editor.registerOnEvent(eventMapping.oryxType, function(event) {
|
||||
KISBPM.eventBus.dispatch(eventMapping.kisBpmType, event);
|
||||
});
|
||||
});
|
||||
|
||||
$rootScope.editor.registerOnEvent(ORYX.CONFIG.EVENT_SHAPEREMOVED, function (event) {
|
||||
var validateButton = document.getElementById(event.shape.resourceId + "-validate-button");
|
||||
if (validateButton)
|
||||
{
|
||||
validateButton.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// The Oryx canvas is ready (we know since we're in this promise callback) and the
|
||||
// event bus is ready. The editor is now ready for use
|
||||
KISBPM.eventBus.dispatch(KISBPM.eventBus.EVENT_TYPE_EDITOR_READY, {type : KISBPM.eventBus.EVENT_TYPE_EDITOR_READY});
|
||||
|
||||
});
|
||||
|
||||
// Alerts
|
||||
$rootScope.alerts = {
|
||||
queue: []
|
||||
};
|
||||
|
||||
$rootScope.showAlert = function(alert) {
|
||||
if(alert.queue.length > 0) {
|
||||
alert.current = alert.queue.shift();
|
||||
// Start timout for message-pruning
|
||||
alert.timeout = $timeout(function() {
|
||||
if (alert.queue.length == 0) {
|
||||
alert.current = undefined;
|
||||
alert.timeout = undefined;
|
||||
} else {
|
||||
$rootScope.showAlert(alert);
|
||||
}
|
||||
}, (alert.current.type == 'error' ? 5000 : 1000));
|
||||
} else {
|
||||
$rootScope.alerts.current = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
$rootScope.addAlert = function(message, type) {
|
||||
var newAlert = {message: message, type: type};
|
||||
if (!$rootScope.alerts.timeout) {
|
||||
// Timeout for message queue is not running, start one
|
||||
$rootScope.alerts.queue.push(newAlert);
|
||||
$rootScope.showAlert($rootScope.alerts);
|
||||
} else {
|
||||
$rootScope.alerts.queue.push(newAlert);
|
||||
}
|
||||
};
|
||||
|
||||
$rootScope.dismissAlert = function() {
|
||||
if (!$rootScope.alerts.timeout) {
|
||||
$rootScope.alerts.current = undefined;
|
||||
} else {
|
||||
$timeout.cancel($rootScope.alerts.timeout);
|
||||
$rootScope.alerts.timeout = undefined;
|
||||
$rootScope.showAlert($rootScope.alerts);
|
||||
}
|
||||
};
|
||||
|
||||
$rootScope.addAlertPromise = function(promise, type) {
|
||||
if (promise) {
|
||||
promise.then(function(data) {
|
||||
$rootScope.addAlert(data, type);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
])
|
||||
|
||||
// Moment-JS date-formatting filter
|
||||
.filter('dateformat', function() {
|
||||
return function(date, format) {
|
||||
if (date) {
|
||||
if (format) {
|
||||
return moment(date).format(format);
|
||||
} else {
|
||||
return moment(date).calendar();
|
||||
}
|
||||
}
|
||||
return '';
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user