diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/controller/api/ActivitiModelController.java b/module-activiti/src/main/java/ink/wgink/module/activiti/controller/api/ActivitiModelController.java index 2312f21b..5a8a82db 100644 --- a/module-activiti/src/main/java/ink/wgink/module/activiti/controller/api/ActivitiModelController.java +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/controller/api/ActivitiModelController.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject; import ink.wgink.common.base.DefaultBaseController; import ink.wgink.exceptions.ParamsException; import ink.wgink.interfaces.consts.ISystemConstant; +import ink.wgink.module.activiti.pojo.vos.ActivitiModelVO; import ink.wgink.module.activiti.service.activiti.IActivitiModelService; import ink.wgink.pojo.result.ErrorResult; import ink.wgink.pojo.result.SuccessResult; @@ -42,15 +43,14 @@ public class ActivitiModelController extends DefaultBaseController { }) @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) @PutMapping("save/{modelId}") - public SuccessResult saveModel(@PathVariable String modelId, String name, String description, String json_xml, String svg_xml) throws Exception { - name = name.trim().replace("\\s", ""); - if (StringUtils.isBlank(name)) { + public SuccessResult saveModel(@PathVariable String modelId, @RequestBody ActivitiModelVO activitiModelVO) throws Exception { + if (StringUtils.isBlank(activitiModelVO.getName())) { throw new ParamsException("名称不能为空"); } - if (RegexUtil.isChinese(name)) { + if (RegexUtil.isChinese(activitiModelVO.getName())) { throw new ParamsException("名称不能有中文"); } - activitiModelService.saveModel(modelId, name, description, json_xml, svg_xml); + activitiModelService.saveModel(modelId, activitiModelVO.getName(), activitiModelVO.getDescription(), activitiModelVO.getJsonXml(), activitiModelVO.getSvgXml()); return new SuccessResult(); } diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/controller/api/ActivitiProcdefController.java b/module-activiti/src/main/java/ink/wgink/module/activiti/controller/api/ActivitiProcdefController.java new file mode 100644 index 00000000..4def28ba --- /dev/null +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/controller/api/ActivitiProcdefController.java @@ -0,0 +1,44 @@ +package ink.wgink.module.activiti.controller.api; + +import ink.wgink.common.base.DefaultBaseController; +import ink.wgink.interfaces.consts.ISystemConstant; +import ink.wgink.module.activiti.pojo.dtos.ActivitiProcdefDTO; +import ink.wgink.module.activiti.service.activiti.IActivitiProcdefService; +import ink.wgink.pojo.ListPage; +import ink.wgink.pojo.result.ErrorResult; +import ink.wgink.pojo.result.SuccessResultList; +import io.swagger.annotations.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * @ClassName: ActivitiProcdefController + * @Description: 流程定义 + * @Author: wanggeng + * @Date: 2021/12/7 10:14 PM + * @Version: 1.0 + */ +@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "流程定义接口") +@RestController +@RequestMapping(ISystemConstant.API_PREFIX + "/activiti/procdef") +public class ActivitiProcdefController extends DefaultBaseController { + + @Autowired + private IActivitiProcdefService activitiProcdefService; + + @ApiOperation(value = "部署分页列表", notes = "部署分页列表接口") + @ApiImplicitParams({ + @ApiImplicitParam(name = "page", value = "当前页码", paramType = "query", dataType = "Integer", defaultValue = "1"), + @ApiImplicitParam(name = "rows", value = "显示数量", paramType = "query", dataType = "Integer", defaultValue = "20"), + }) + @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) + @GetMapping("listpage") + public SuccessResultList> listPage(ListPage page) { + return activitiProcdefService.listPage(page.getPage(), page.getRows()); + } + +} diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/controller/route/ActivitiProcdefRouteController.java b/module-activiti/src/main/java/ink/wgink/module/activiti/controller/route/ActivitiProcdefRouteController.java new file mode 100644 index 00000000..e7d467b3 --- /dev/null +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/controller/route/ActivitiProcdefRouteController.java @@ -0,0 +1,28 @@ +package ink.wgink.module.activiti.controller.route; + +import ink.wgink.interfaces.consts.ISystemConstant; +import io.swagger.annotations.Api; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; + +/** + * @ClassName: ActivitiProcdefRouteController + * @Description: 流程定义 + * @Author: wanggeng + * @Date: 2021/12/7 10:26 PM + * @Version: 1.0 + */ +@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "流程定义路由") +@Controller +@RequestMapping(ISystemConstant.ROUTE_PREFIX + "/activiti/procdef") +public class ActivitiProcdefRouteController { + + @GetMapping("list") + public ModelAndView list() { + ModelAndView mv = new ModelAndView("activiti/procdef/list"); + return mv; + } + +} diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/pojo/dtos/ActivitiProcdefDTO.java b/module-activiti/src/main/java/ink/wgink/module/activiti/pojo/dtos/ActivitiProcdefDTO.java new file mode 100644 index 00000000..58afe0ab --- /dev/null +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/pojo/dtos/ActivitiProcdefDTO.java @@ -0,0 +1,114 @@ +package ink.wgink.module.activiti.pojo.dtos; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: ActivitiProcdefDTO + * @Description: 流程定义 + * @Author: wanggeng + * @Date: 2021/12/7 10:47 PM + * @Version: 1.0 + */ +public class ActivitiProcdefDTO { + + private String id; + private String name; + private String description; + private String key; + private int version; + private String category; + private String deploymentId; + private String resourceName; + private String diagramResourceName; + private Map variables; + private boolean hasStartFormKey; + + public String getId() { + return id == null ? "" : id.trim(); + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name == null ? "" : name.trim(); + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description == null ? "" : description.trim(); + } + + public void setDescription(String description) { + this.description = description; + } + + public String getKey() { + return key == null ? "" : key.trim(); + } + + public void setKey(String key) { + this.key = key; + } + + public int getVersion() { + return version; + } + + public void setVersion(int version) { + this.version = version; + } + + public String getCategory() { + return category == null ? "" : category.trim(); + } + + public void setCategory(String category) { + this.category = category; + } + + public String getDeploymentId() { + return deploymentId == null ? "" : deploymentId.trim(); + } + + public void setDeploymentId(String deploymentId) { + this.deploymentId = deploymentId; + } + + public String getResourceName() { + return resourceName == null ? "" : resourceName.trim(); + } + + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } + + public String getDiagramResourceName() { + return diagramResourceName == null ? "" : diagramResourceName.trim(); + } + + public void setDiagramResourceName(String diagramResourceName) { + this.diagramResourceName = diagramResourceName; + } + + public Map getVariables() { + return variables == null ? new HashMap<>() : variables; + } + + public void setVariables(Map variables) { + this.variables = variables; + } + + public boolean isHasStartFormKey() { + return hasStartFormKey; + } + + public void setHasStartFormKey(boolean hasStartFormKey) { + this.hasStartFormKey = hasStartFormKey; + } +} diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/pojo/vos/ActivitiModelVO.java b/module-activiti/src/main/java/ink/wgink/module/activiti/pojo/vos/ActivitiModelVO.java new file mode 100644 index 00000000..aec62b9f --- /dev/null +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/pojo/vos/ActivitiModelVO.java @@ -0,0 +1,49 @@ +package ink.wgink.module.activiti.pojo.vos; + +/** + * @ClassName: ActivitiModelVO + * @Description: 模型 + * @Author: wanggeng + * @Date: 2021/12/7 11:36 PM + * @Version: 1.0 + */ + +public class ActivitiModelVO { + + private String name; + private String description; + private String jsonXml; + private String svgXml; + + public String getName() { + return name == null ? "" : name.trim(); + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description == null ? "" : description.trim(); + } + + public void setDescription(String description) { + this.description = description; + } + + public String getJsonXml() { + return jsonXml == null ? "" : jsonXml.trim(); + } + + public void setJsonXml(String jsonXml) { + this.jsonXml = jsonXml; + } + + public String getSvgXml() { + return svgXml == null ? "" : svgXml.trim(); + } + + public void setSvgXml(String svgXml) { + this.svgXml = svgXml; + } +} diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/pojo/vos/ActivitiVO.java b/module-activiti/src/main/java/ink/wgink/module/activiti/pojo/vos/ActivitiVO.java index 2ac51a83..f03e2f2f 100644 --- a/module-activiti/src/main/java/ink/wgink/module/activiti/pojo/vos/ActivitiVO.java +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/pojo/vos/ActivitiVO.java @@ -1,7 +1,6 @@ package ink.wgink.module.activiti.pojo.vos; import ink.wgink.annotation.CheckEmptyAnnotation; -import ink.wgink.annotation.CheckNumberAnnotation; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -26,9 +25,6 @@ public class ActivitiVO { private String modelKey; @ApiModelProperty(name = "modelDescription", value = "模型描述") private String modelDescription; - @ApiModelProperty(name = "modelVersion", value = "模型版本") - @CheckNumberAnnotation(name = "模型版本") - private Integer modelVersion; public String getModelName() { return modelName == null ? "" : modelName.trim().replaceAll("\\s", ""); @@ -53,12 +49,4 @@ public class ActivitiVO { public void setModelDescription(String modelDescription) { this.modelDescription = modelDescription; } - - public Integer getModelVersion() { - return modelVersion; - } - - public void setModelVersion(Integer modelVersion) { - this.modelVersion = modelVersion; - } } diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/IActivitiProcdefService.java b/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/IActivitiProcdefService.java new file mode 100644 index 00000000..9daa321a --- /dev/null +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/IActivitiProcdefService.java @@ -0,0 +1,19 @@ +package ink.wgink.module.activiti.service.activiti; + +import ink.wgink.module.activiti.pojo.dtos.ActivitiProcdefDTO; +import ink.wgink.pojo.result.SuccessResultList; + +import java.util.List; + +/** + * @ClassName: IActivitiDeploymentService + * @Description: 流程定义 + * @Author: wanggeng + * @Date: 2021/12/7 10:11 PM + * @Version: 1.0 + */ +public interface IActivitiProcdefService { + + SuccessResultList> listPage(int page, int rows); + +} diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/IActivitiService.java b/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/IActivitiService.java index 0016a29a..73e6a291 100644 --- a/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/IActivitiService.java +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/IActivitiService.java @@ -67,5 +67,4 @@ public interface IActivitiService { */ SuccessResultList> listPage(int page, int rows); - } diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/impl/ActivitiModelServiceImpl.java b/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/impl/ActivitiModelServiceImpl.java index 2fdd3be2..e2081ded 100644 --- a/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/impl/ActivitiModelServiceImpl.java +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/impl/ActivitiModelServiceImpl.java @@ -1,9 +1,9 @@ package ink.wgink.module.activiti.service.activiti.impl; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import ink.wgink.common.base.DefaultBaseService; import ink.wgink.exceptions.SearchException; -import ink.wgink.exceptions.UpdateException; import ink.wgink.exceptions.base.SystemException; import ink.wgink.interfaces.consts.ISystemConstant; import ink.wgink.module.activiti.service.activiti.IActivitiModelService; @@ -29,7 +29,10 @@ import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletResponse; import java.io.*; -import java.util.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.stream.Collectors; /** @@ -58,15 +61,13 @@ public class ActivitiModelServiceImpl extends DefaultBaseService implements IAct if (model == null) { throw new SearchException("模型不存在"); } - if (!StringUtils.isBlank(model.getDeploymentId())) { - throw new UpdateException("已经部署的流程无法编辑"); - } - JSONObject modelObject = JSONObject.parseObject(model.getMetaInfo()); + JSONObject modelObject = JSONObject.parseObject(model.getMetaInfo()); modelObject.put(MODEL_NAME, name); modelObject.put(MODEL_DESCRIPTION, description); model.setMetaInfo(modelObject.toString()); model.setName(name); + model.setVersion(model.getVersion() + 1); repositoryService.saveModel(model); repositoryService.addModelEditorSource(model.getId(), json_xml.getBytes(ISystemConstant.CHARSET_UTF8)); @@ -115,7 +116,15 @@ public class ActivitiModelServiceImpl extends DefaultBaseService implements IAct } catch (IOException e) { throw e; } - return JSONObject.parseObject(content); + JSONObject jsonObject = JSONObject.parseObject(content); + // 设置默认且唯一的信息 + JSONArray propertyPackagesJsonArray = jsonObject.getJSONArray("propertyPackages"); + + JSONObject processIdPackageJsonObject = propertyPackagesJsonArray.getJSONObject(0); + JSONArray processIdPackagePropertiesJsonArray = processIdPackageJsonObject.getJSONArray("properties"); + JSONObject processIdJsonObject = processIdPackagePropertiesJsonArray.getJSONObject(0); + processIdJsonObject.put("value", "P" + System.currentTimeMillis()); + return jsonObject; } @Override @@ -282,4 +291,5 @@ public class ActivitiModelServiceImpl extends DefaultBaseService implements IAct return new ArrayList<>(flowSet); } + } diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/impl/ActivitiProcdefServiceImpl.java b/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/impl/ActivitiProcdefServiceImpl.java new file mode 100644 index 00000000..ee964865 --- /dev/null +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/impl/ActivitiProcdefServiceImpl.java @@ -0,0 +1,44 @@ +package ink.wgink.module.activiti.service.activiti.impl; + +import ink.wgink.common.base.DefaultBaseService; +import ink.wgink.module.activiti.pojo.dtos.ActivitiProcdefDTO; +import ink.wgink.module.activiti.service.activiti.IActivitiProcdefService; +import ink.wgink.pojo.result.SuccessResultList; +import org.activiti.engine.RepositoryService; +import org.activiti.engine.repository.ProcessDefinition; +import org.activiti.engine.repository.ProcessDefinitionQuery; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * @ClassName: ActivitiProcdefServiceImpl + * @Description: 流程定义 + * @Author: wanggeng + * @Date: 2021/12/7 10:11 PM + * @Version: 1.0 + */ +@Service +public class ActivitiProcdefServiceImpl extends DefaultBaseService implements IActivitiProcdefService { + + @Autowired + private RepositoryService repositoryService; + + @Override + public SuccessResultList> listPage(int page, int rows) { + ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery(); + List processDefinitions = processDefinitionQuery.listPage(page - 1, rows); + + List activitiProcdefDTOs = new ArrayList<>(); + processDefinitions.forEach(processDefinition -> { + ActivitiProcdefDTO activitiProcdefDTO = new ActivitiProcdefDTO(); + BeanUtils.copyProperties(processDefinition, activitiProcdefDTO); + activitiProcdefDTOs.add(activitiProcdefDTO); + }); + return new SuccessResultList<>(activitiProcdefDTOs, page, processDefinitionQuery.count()); + } + +} diff --git a/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/impl/ActivitiServiceImpl.java b/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/impl/ActivitiServiceImpl.java index c0c1c02f..03d8a778 100644 --- a/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/impl/ActivitiServiceImpl.java +++ b/module-activiti/src/main/java/ink/wgink/module/activiti/service/activiti/impl/ActivitiServiceImpl.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import ink.wgink.common.base.DefaultBaseService; +import ink.wgink.exceptions.RemoveException; import ink.wgink.exceptions.SearchException; import ink.wgink.interfaces.consts.ISystemConstant; import ink.wgink.module.activiti.pojo.vos.ActivitiVO; @@ -18,7 +19,7 @@ import org.activiti.engine.RuntimeService; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.Model; import org.activiti.engine.repository.ModelQuery; -import org.activiti.engine.runtime.ProcessInstance; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -48,7 +49,7 @@ public class ActivitiServiceImpl extends DefaultBaseService implements IActiviti @Override public String create(ActivitiVO activitiVO) throws UnsupportedEncodingException { - long count = repositoryService.createModelQuery().modelName(activitiVO.getModelName()).modelKey(activitiVO.getModelKey()).modelVersion(activitiVO.getModelVersion()).count(); + long count = repositoryService.createModelQuery().modelName(activitiVO.getModelName()).modelKey(activitiVO.getModelKey()).count(); if (count >= 1) { throw new SearchException("模型已经存在"); } @@ -56,6 +57,7 @@ public class ActivitiServiceImpl extends DefaultBaseService implements IActiviti model.setName(activitiVO.getModelName()); model.setKey(activitiVO.getModelKey()); model.setMetaInfo(createModelMetaInfo(activitiVO)); + model.setVersion(1); LOG.debug("保存模型"); repositoryService.saveModel(model); addModelEditorSource(model.getId()); @@ -68,13 +70,9 @@ public class ActivitiServiceImpl extends DefaultBaseService implements IActiviti if (model == null) { throw new SearchException("模型不存在"); } - ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processDefinitionKey(model.getKey()).singleResult(); - // 删除模型实例 - if (processInstance != null) { - runtimeService.deleteProcessInstance(processInstance.getId(), ""); - historyService.deleteHistoricProcessInstance(processInstance.getId()); + if (!StringUtils.isBlank(model.getDeploymentId())) { + throw new RemoveException("已部署的模型不能删除"); } - //删除模型模型 repositoryService.deleteModel(modelId); } @@ -93,7 +91,7 @@ public class ActivitiServiceImpl extends DefaultBaseService implements IActiviti Deployment deployment = repositoryService.createDeployment() .name(model.getName()) .key(model.getKey()) - .addBpmnModel(model.getKey() + ".bpmn20.xml", bpmnModel) + .addBpmnModel(model.getKey() + "." + model.getVersion() + ".bpmn20.xml", bpmnModel) .deploy(); model.setDeploymentId(deployment.getId()); repositoryService.saveModel(model); @@ -109,7 +107,7 @@ public class ActivitiServiceImpl extends DefaultBaseService implements IActiviti * 参数不加true:为普通删除,如果当前规则下有正在执行的流程,则抛异常 * 参数加true:为级联删除,会删除和当前规则相关的所有信息,包括历史 */ - repositoryService.deleteDeployment(modelData.getDeploymentId(), true); + repositoryService.deleteDeployment(modelData.getDeploymentId()); } @Override @@ -134,7 +132,6 @@ public class ActivitiServiceImpl extends DefaultBaseService implements IActiviti JSONObject metaInfo = new JSONObject(); metaInfo.put(ModelDataJsonConstants.MODEL_NAME, activitiVO.getModelName()); metaInfo.put(ModelDataJsonConstants.MODEL_DESCRIPTION, activitiVO.getModelDescription()); - metaInfo.put(ModelDataJsonConstants.MODEL_REVISION, activitiVO.getModelVersion()); return metaInfo.toString(); } diff --git a/module-activiti/src/main/resources/static/editor-app/configuration/toolbar-default-actions.js b/module-activiti/src/main/resources/static/editor-app/configuration/toolbar-default-actions.js index 22afe335..95fea30b 100644 --- a/module-activiti/src/main/resources/static/editor-app/configuration/toolbar-default-actions.js +++ b/module-activiti/src/main/resources/static/editor-app/configuration/toolbar-default-actions.js @@ -21,15 +21,64 @@ var KISBPM = KISBPM || {}; KISBPM.TOOLBAR = { ACTIONS: { - saveModel: function (services) { + var scope = services.$scope; + top.dialog.confirm('确定保存吗?', function (index) { + top.dialog.close(index); + var json = scope.editor.getJSON(); + if(!json.properties.name) { + top.dialog.msg('流程的 元素名称 不能为空'); + return; + } + if(json.childShapes.length == 0) { + top.dialog.msg('流程图节点不能为空'); + return; + } + json = JSON.stringify(json); + var selection = scope.editor.getSelection(); + scope.editor.setSelection([]); + // Get the serialized svg image source + var svgClone = scope.editor.getCanvas().getSVGRepresentation(true); + scope.editor.setSelection(selection); + if (scope.editor.getCanvas().properties["oryx-showstripableelements"] === false) { + var stripOutArray = jQuery(svgClone).find(".stripable-element"); + for (var i = stripOutArray.length - 1; i >= 0; i--) { + stripOutArray[i].remove(); + } + } + // Remove all forced stripable elements + var stripOutArray = jQuery(svgClone).find(".stripable-element-force"); + for (var i = stripOutArray.length - 1; i >= 0; i--) { + stripOutArray[i].remove(); + } + // Parse dom to string + var svgDOM = DataManager.serialize(svgClone); - var modal = services.$modal({ - backdrop: true, - keyboard: true, - template: 'editor-app/popups/save-model.html?version=' + Date.now(), - scope: services.$scope - }); + var modelMetaData = scope.editor.getModelMetaData(); + var params = { + jsonXml: json, + svgXml: svgDOM, + name: modelMetaData.name, + description: modelMetaData.description + }; + var loadLayerIndex; + top.restAjax.put(KISBPM.URL.putModel(modelMetaData.modelId), params, null, function (code, data) { + parent.layer.close(parent.layer.getFrameIndex(window.name)); + top.dialog.msg('保存成功'); + }, function (code, data) { + top.dialog.msg(data.msg); + }, function () { + loadLayerIndex = top.dialog.msg(top.dataMessage.committing, {icon: 16, time: 0, shade: 0.3}); + }, function () { + top.dialog.close(loadLayerIndex); + }); + }) + // var modal = services.$modal({ + // backdrop: true, + // keyboard: true, + // template: 'editor-app/popups/save-model.html?version=' + Date.now(), + // scope: services.$scope + // }); }, undo: function (services) { @@ -43,37 +92,34 @@ KISBPM.TOOLBAR = { // Force refresh of selection, might be that the undo command // impacts properties in the selected item - if (services.$rootScope && services.$rootScope.forceSelectionRefresh) - { - services.$rootScope.forceSelectionRefresh = true; + if (services.$rootScope && services.$rootScope.forceSelectionRefresh) { + services.$rootScope.forceSelectionRefresh = true; } - + // Rollback every command for (var i = lastCommands.length - 1; i >= 0; --i) { lastCommands[i].rollback(); } - + // Update and refresh the canvas services.$scope.editor.handleEvents({ type: ORYX.CONFIG.EVENT_UNDO_ROLLBACK, commands: lastCommands }); - + // Update services.$scope.editor.getCanvas().update(); services.$scope.editor.updateSelection(); } - + var toggleUndo = false; - if (services.$scope.undoStack.length == 0) - { - toggleUndo = true; + if (services.$scope.undoStack.length == 0) { + toggleUndo = true; } - + var toggleRedo = false; - if (services.$scope.redoStack.length > 0) - { - toggleRedo = true; + if (services.$scope.redoStack.length > 0) { + toggleRedo = true; } if (toggleUndo || toggleRedo) { @@ -83,8 +129,7 @@ KISBPM.TOOLBAR = { services.$scope.safeApply(function () { item.enabled = false; }); - } - else if (toggleRedo && item.action === 'KISBPM.TOOLBAR.ACTIONS.redo') { + } else if (toggleRedo && item.action === 'KISBPM.TOOLBAR.ACTIONS.redo') { services.$scope.safeApply(function () { item.enabled = true; }); @@ -101,12 +146,11 @@ KISBPM.TOOLBAR = { if (lastCommands) { // Add this commands to the undo stack services.$scope.undoStack.push(lastCommands); - + // Force refresh of selection, might be that the redo command // impacts properties in the selected item - if (services.$rootScope && services.$rootScope.forceSelectionRefresh) - { - services.$rootScope.forceSelectionRefresh = true; + if (services.$rootScope && services.$rootScope.forceSelectionRefresh) { + services.$rootScope.forceSelectionRefresh = true; } // Execute those commands @@ -142,8 +186,7 @@ KISBPM.TOOLBAR = { services.$scope.safeApply(function () { item.enabled = true; }); - } - else if (toggleRedo && item.action === 'KISBPM.TOOLBAR.ACTIONS.redo') { + } else if (toggleRedo && item.action === 'KISBPM.TOOLBAR.ACTIONS.redo') { services.$scope.safeApply(function () { item.enabled = false; }); @@ -190,14 +233,11 @@ KISBPM.TOOLBAR = { var enableAdd = !dockerPlugin.enabledAdd(); dockerPlugin.setEnableAdd(enableAdd); - if (enableAdd) - { - dockerPlugin.setEnableRemove(false); - document.body.style.cursor = 'pointer'; - } - else - { - document.body.style.cursor = 'default'; + if (enableAdd) { + dockerPlugin.setEnableRemove(false); + document.body.style.cursor = 'pointer'; + } else { + document.body.style.cursor = 'default'; } }, @@ -207,14 +247,11 @@ KISBPM.TOOLBAR = { var enableRemove = !dockerPlugin.enabledRemove(); dockerPlugin.setEnableRemove(enableRemove); - if (enableRemove) - { - dockerPlugin.setEnableAdd(false); - document.body.style.cursor = 'pointer'; - } - else - { - document.body.style.cursor = 'default'; + if (enableRemove) { + dockerPlugin.setEnableAdd(false); + document.body.style.cursor = 'pointer'; + } else { + document.body.style.cursor = 'default'; } }, @@ -239,32 +276,32 @@ KISBPM.TOOLBAR = { zoomOut: function (services) { KISBPM.TOOLBAR.ACTIONS._getOryxViewPlugin(services.$scope).zoom([1.0 - ORYX.CONFIG.ZOOM_OFFSET]); }, - + zoomActual: function (services) { KISBPM.TOOLBAR.ACTIONS._getOryxViewPlugin(services.$scope).setAFixZoomLevel(1); }, - + zoomFit: function (services) { - KISBPM.TOOLBAR.ACTIONS._getOryxViewPlugin(services.$scope).zoomFitToModel(); + KISBPM.TOOLBAR.ACTIONS._getOryxViewPlugin(services.$scope).zoomFitToModel(); }, - + alignVertical: function (services) { - KISBPM.TOOLBAR.ACTIONS._getOryxArrangmentPlugin(services.$scope).alignShapes([ORYX.CONFIG.EDITOR_ALIGN_MIDDLE]); + KISBPM.TOOLBAR.ACTIONS._getOryxArrangmentPlugin(services.$scope).alignShapes([ORYX.CONFIG.EDITOR_ALIGN_MIDDLE]); }, - + alignHorizontal: function (services) { - KISBPM.TOOLBAR.ACTIONS._getOryxArrangmentPlugin(services.$scope).alignShapes([ORYX.CONFIG.EDITOR_ALIGN_CENTER]); + KISBPM.TOOLBAR.ACTIONS._getOryxArrangmentPlugin(services.$scope).alignShapes([ORYX.CONFIG.EDITOR_ALIGN_CENTER]); }, - + sameSize: function (services) { - KISBPM.TOOLBAR.ACTIONS._getOryxArrangmentPlugin(services.$scope).alignShapes([ORYX.CONFIG.EDITOR_ALIGN_SIZE]); + KISBPM.TOOLBAR.ACTIONS._getOryxArrangmentPlugin(services.$scope).alignShapes([ORYX.CONFIG.EDITOR_ALIGN_SIZE]); }, - - closeEditor: function(services) { + + closeEditor: function (services) { parent.layer.close(parent.layer.getFrameIndex(window.name)); - // window.location.href = "./"; + // window.location.href = "./"; }, - + /** * Helper method: fetches the Oryx View plugin from the provided scope, * if not on the scope, it is created and put on the scope for further use. @@ -275,7 +312,7 @@ KISBPM.TOOLBAR = { } return $scope.oryxViewPlugin; }, - + _getOryxArrangmentPlugin: function ($scope) { if ($scope.oryxArrangmentPlugin === undefined || $scope.oryxArrangmentPlugin === null) { $scope.oryxArrangmentPlugin = new ORYX.Plugins.Arrangement($scope.editor); @@ -293,141 +330,147 @@ KISBPM.TOOLBAR = { }; /** Custom controller for the save dialog */ -var SaveModelCtrl = [ '$rootScope', '$scope', '$http', '$route', '$location', +var SaveModelCtrl = ['$rootScope', '$scope', '$http', '$route', '$location', function ($rootScope, $scope, $http, $route, $location) { - var modelMetaData = $scope.editor.getModelMetaData(); + var modelMetaData = $scope.editor.getModelMetaData(); - var description = ''; - if (modelMetaData.description) { - description = modelMetaData.description; - } - - var saveDialog = { 'name' : modelMetaData.name, - 'description' : description}; - - $scope.saveDialog = saveDialog; - - var json = $scope.editor.getJSON(); - json = JSON.stringify(json); - - var params = { - modeltype: modelMetaData.model.modelType, - json_xml: json, - name: 'model' - }; - - $scope.status = { - loading: false - }; - - $scope.close = function () { - $scope.$hide(); - }; - - $scope.saveAndClose = function () { - $scope.save(function() { - parent.layer.close(parent.layer.getFrameIndex(window.name)); - // window.location.href = "./"; - }); - }; - $scope.save = function (successCallback) { - - if (!$scope.saveDialog.name || $scope.saveDialog.name.length == 0) { - return; + var description = ''; + if (modelMetaData.description) { + description = modelMetaData.description; } - // Indicator spinner image - $scope.status = { - loading: true + var saveDialog = { + 'name': modelMetaData.name, + 'description': description }; - - modelMetaData.name = $scope.saveDialog.name; - modelMetaData.description = $scope.saveDialog.description; + + $scope.saveDialog = saveDialog; var json = $scope.editor.getJSON(); json = JSON.stringify(json); - - var selection = $scope.editor.getSelection(); - $scope.editor.setSelection([]); - - // Get the serialized svg image source - var svgClone = $scope.editor.getCanvas().getSVGRepresentation(true); - $scope.editor.setSelection(selection); - if ($scope.editor.getCanvas().properties["oryx-showstripableelements"] === false) { - var stripOutArray = jQuery(svgClone).find(".stripable-element"); - for (var i = stripOutArray.length - 1; i >= 0; i--) { - stripOutArray[i].remove(); - } - } - - // Remove all forced stripable elements - var stripOutArray = jQuery(svgClone).find(".stripable-element-force"); - for (var i = stripOutArray.length - 1; i >= 0; i--) { - stripOutArray[i].remove(); - } - - // Parse dom to string - var svgDOM = DataManager.serialize(svgClone); var params = { + modeltype: modelMetaData.model.modelType, json_xml: json, - svg_xml: svgDOM, - name: $scope.saveDialog.name, - description: $scope.saveDialog.description + name: 'model' }; - // Update - $http({ method: 'PUT', - data: params, - ignoreErrors: true, - headers: {'Accept': 'application/json', - 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}, - transformRequest: function (obj) { - var str = []; - for (var p in obj) { - str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); - } - return str.join("&"); - }, - url: KISBPM.URL.putModel(modelMetaData.modelId)}) + $scope.status = { + loading: false + }; - .success(function (data, status, headers, config) { - $scope.editor.handleEvents({ - type: ORYX.CONFIG.EVENT_SAVED - }); - $scope.modelData.name = $scope.saveDialog.name; - $scope.modelData.lastUpdated = data.lastUpdated; - - $scope.status.loading = false; - $scope.$hide(); + $scope.close = function () { + $scope.$hide(); + }; - // Fire event to all who is listening - var saveEvent = { - type: KISBPM.eventBus.EVENT_TYPE_MODEL_SAVED, - model: params, - modelId: modelMetaData.modelId, - eventType: 'update-model' - }; - KISBPM.eventBus.dispatch(KISBPM.eventBus.EVENT_TYPE_MODEL_SAVED, saveEvent); - - // Reset state - $scope.error = undefined; - $scope.status.loading = false; - - // Execute any callback - if (successCallback) { - successCallback(); - } - - }) - .error(function (data, status, headers, config) { - $scope.status.loading = false; - top.dialog.msg(data.msg); - // $scope.error = {}; - // console.log('Something went wrong when updating the process model:' + JSON.stringify(data)); - // $scope.status.loading = false; + $scope.saveAndClose = function () { + $scope.save(function () { + parent.layer.close(parent.layer.getFrameIndex(window.name)); + // window.location.href = "./"; }); - }; + }; + $scope.save = function (successCallback) { -}]; \ No newline at end of file + if (!$scope.saveDialog.name || $scope.saveDialog.name.length == 0) { + return; + } + + // Indicator spinner image + $scope.status = { + loading: true + }; + + modelMetaData.name = $scope.saveDialog.name; + modelMetaData.description = $scope.saveDialog.description; + + var json = $scope.editor.getJSON(); + json = JSON.stringify(json); + + var selection = $scope.editor.getSelection(); + $scope.editor.setSelection([]); + + // Get the serialized svg image source + var svgClone = $scope.editor.getCanvas().getSVGRepresentation(true); + $scope.editor.setSelection(selection); + if ($scope.editor.getCanvas().properties["oryx-showstripableelements"] === false) { + var stripOutArray = jQuery(svgClone).find(".stripable-element"); + for (var i = stripOutArray.length - 1; i >= 0; i--) { + stripOutArray[i].remove(); + } + } + + // Remove all forced stripable elements + var stripOutArray = jQuery(svgClone).find(".stripable-element-force"); + for (var i = stripOutArray.length - 1; i >= 0; i--) { + stripOutArray[i].remove(); + } + + // Parse dom to string + var svgDOM = DataManager.serialize(svgClone); + + var params = { + json_xml: json, + svg_xml: svgDOM, + name: $scope.saveDialog.name, + description: $scope.saveDialog.description + }; + + // Update + $http({ + method: 'PUT', + data: params, + ignoreErrors: true, + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' + }, + transformRequest: function (obj) { + var str = []; + for (var p in obj) { + str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); + } + return str.join("&"); + }, + url: KISBPM.URL.putModel(modelMetaData.modelId) + }) + + .success(function (data, status, headers, config) { + $scope.editor.handleEvents({ + type: ORYX.CONFIG.EVENT_SAVED + }); + $scope.modelData.name = $scope.saveDialog.name; + $scope.modelData.lastUpdated = data.lastUpdated; + + $scope.status.loading = false; + $scope.$hide(); + + // Fire event to all who is listening + var saveEvent = { + type: KISBPM.eventBus.EVENT_TYPE_MODEL_SAVED, + model: params, + modelId: modelMetaData.modelId, + eventType: 'update-model' + }; + KISBPM.eventBus.dispatch(KISBPM.eventBus.EVENT_TYPE_MODEL_SAVED, saveEvent); + + // Reset state + $scope.error = undefined; + $scope.status.loading = false; + + // Execute any callback + if (successCallback) { + successCallback(); + } + + }) + .error(function (data, status, headers, config) { + $scope.status.loading = false; + top.dialog.msg(data.msg); + // $scope.error = {}; + // console.log('Something went wrong when updating the process model:' + JSON.stringify(data)); + // $scope.status.loading = false; + }); + }; + + }]; \ No newline at end of file diff --git a/module-activiti/src/main/resources/static/editor-app/stencil-controller.js b/module-activiti/src/main/resources/static/editor-app/stencil-controller.js index 79293c00..4cf8721f 100644 --- a/module-activiti/src/main/resources/static/editor-app/stencil-controller.js +++ b/module-activiti/src/main/resources/static/editor-app/stencil-controller.js @@ -33,10 +33,10 @@ angular.module('activitiModeler') jQuery(window).trigger('resize'); }); }; - + // Code that is dependent on an initialised Editor is wrapped in a promise for the editor $scope.editorFactory.promise.then(function () { - + /* Build stencil item list */ // Build simple json representation of stencil set @@ -54,7 +54,7 @@ angular.module('activitiModeler') // Helper method: add a new group to an array of groups var addGroup = function (groupName, groupArray) { - var group = { name: groupName, items: [], paletteItems: [], groups: [], visible: true }; + var group = {name: groupName, items: [], paletteItems: [], groups: [], visible: true}; groupArray.push(group); return group; }; @@ -63,30 +63,27 @@ angular.module('activitiModeler') StencilSet items */ $http({method: 'GET', url: KISBPM.URL.getStencilSet()}).success(function (data, status, headers, config) { + var quickMenuDefinition = ['UserTask', 'EndNoneEvent', 'ExclusiveGateway', + 'CatchTimerEvent', 'ThrowNoneEvent', 'TextAnnotation', + 'SequenceFlow', 'Association']; + var ignoreForPaletteDefinition = ['SequenceFlow', 'MessageFlow', 'Association', 'DataAssociation', 'DataStore', 'SendTask']; + var quickMenuItems = []; - var quickMenuDefinition = ['UserTask', 'EndNoneEvent', 'ExclusiveGateway', - 'CatchTimerEvent', 'ThrowNoneEvent', 'TextAnnotation', - 'SequenceFlow', 'Association']; - var ignoreForPaletteDefinition = ['SequenceFlow', 'MessageFlow', 'Association', 'DataAssociation', 'DataStore', 'SendTask']; - var quickMenuItems = []; - - var morphRoles = []; - for (var i = 0; i < data.rules.morphingRules.length; i++) - { + var morphRoles = []; + for (var i = 0; i < data.rules.morphingRules.length; i++) { var role = data.rules.morphingRules[i].role; var roleItem = {'role': role, 'morphOptions': []}; morphRoles.push(roleItem); } - + // Check all received items - for (var stencilIndex = 0; stencilIndex < data.stencils.length; stencilIndex++) - { - // Check if the root group is the 'diagram' group. If so, this item should not be shown. + for (var stencilIndex = 0; stencilIndex < data.stencils.length; stencilIndex++) { + // Check if the root group is the 'diagram' group. If so, this item should not be shown. var currentGroupName = data.stencils[stencilIndex].groups[0]; if (currentGroupName === 'Diagram' || currentGroupName === 'Form') { continue; // go to next item } - + var removed = false; if (data.stencils[stencilIndex].removed) { removed = true; @@ -119,9 +116,10 @@ angular.module('activitiModeler') } } - + // Construct the stencil item - var stencilItem = {'id': data.stencils[stencilIndex].id, + var stencilItem = { + 'id': data.stencils[stencilIndex].id, 'name': data.stencils[stencilIndex].title, 'description': data.stencils[stencilIndex].description, 'icon': data.stencils[stencilIndex].icon, @@ -131,48 +129,49 @@ angular.module('activitiModeler') 'customIcon': false, 'canConnect': false, 'canConnectTo': false, - 'canConnectAssociation': false}; - + 'canConnectAssociation': false + }; + if (data.stencils[stencilIndex].customIconId && data.stencils[stencilIndex].customIconId > 0) { stencilItem.customIcon = true; stencilItem.icon = data.stencils[stencilIndex].customIconId; } - + if (!removed) { if (quickMenuDefinition.indexOf(stencilItem.id) >= 0) { - quickMenuItems[quickMenuDefinition.indexOf(stencilItem.id)] = stencilItem; + quickMenuItems[quickMenuDefinition.indexOf(stencilItem.id)] = stencilItem; } } - + if (stencilItem.id === 'TextAnnotation' || stencilItem.id === 'BoundaryCompensationEvent') { - stencilItem.canConnectAssociation = true; + stencilItem.canConnectAssociation = true; } - + for (var i = 0; i < data.stencils[stencilIndex].roles.length; i++) { - var stencilRole = data.stencils[stencilIndex].roles[i]; - if (stencilRole === 'sequence_start') { - stencilItem.canConnect = true; - } else if (stencilRole === 'sequence_end') { - stencilItem.canConnectTo = true; - } - - for (var j = 0; j < morphRoles.length; j++) { - if (stencilRole === morphRoles[j].role) { - if (!removed) { - morphRoles[j].morphOptions.push(stencilItem); - } - stencilItem.morphRole = morphRoles[j].role; - break; - } - } + var stencilRole = data.stencils[stencilIndex].roles[i]; + if (stencilRole === 'sequence_start') { + stencilItem.canConnect = true; + } else if (stencilRole === 'sequence_end') { + stencilItem.canConnectTo = true; + } + + for (var j = 0; j < morphRoles.length; j++) { + if (stencilRole === morphRoles[j].role) { + if (!removed) { + morphRoles[j].morphOptions.push(stencilItem); + } + stencilItem.morphRole = morphRoles[j].role; + break; + } + } } if (currentGroup) { - // Add the stencil item to the correct group - currentGroup.items.push(stencilItem); - if (ignoreForPaletteDefinition.indexOf(stencilItem.id) < 0) { - currentGroup.paletteItems.push(stencilItem); - } + // Add the stencil item to the correct group + currentGroup.items.push(stencilItem); + if (ignoreForPaletteDefinition.indexOf(stencilItem.id) < 0) { + currentGroup.paletteItems.push(stencilItem); + } } else { // It's a root stencil element @@ -181,39 +180,33 @@ angular.module('activitiModeler') } } } - - for (var i = 0; i < stencilItemGroups.length; i++) - { - if (stencilItemGroups[i].paletteItems && stencilItemGroups[i].paletteItems.length == 0) - { - stencilItemGroups[i].visible = false; - } + + for (var i = 0; i < stencilItemGroups.length; i++) { + if (stencilItemGroups[i].paletteItems && stencilItemGroups[i].paletteItems.length == 0) { + stencilItemGroups[i].visible = false; + } } - + $scope.stencilItemGroups = stencilItemGroups; var containmentRules = []; - for (var i = 0; i < data.rules.containmentRules.length; i++) - { + for (var i = 0; i < data.rules.containmentRules.length; i++) { var rule = data.rules.containmentRules[i]; containmentRules.push(rule); } $scope.containmentRules = containmentRules; - + // remove quick menu items which are not available anymore due to custom pallette var availableQuickMenuItems = []; - for (var i = 0; i < quickMenuItems.length; i++) - { + for (var i = 0; i < quickMenuItems.length; i++) { if (quickMenuItems[i]) { availableQuickMenuItems[availableQuickMenuItems.length] = quickMenuItems[i]; } } - + $scope.quickMenuItems = availableQuickMenuItems; $scope.morphRoles = morphRoles; - }). - - error(function (data, status, headers, config) { + }).error(function (data, status, headers, config) { console.log('Something went wrong when fetching stencil items:' + JSON.stringify(data)); }); @@ -231,22 +224,20 @@ angular.module('activitiModeler') var selectedShape = shapes.first(); var stencil = selectedShape.getStencil(); - - if ($rootScope.selectedElementBeforeScrolling && stencil.id().indexOf('BPMNDiagram') !== -1) - { - // ignore canvas event because of empty selection when scrolling stops - return; + + if ($rootScope.selectedElementBeforeScrolling && stencil.id().indexOf('BPMNDiagram') !== -1) { + // ignore canvas event because of empty selection when scrolling stops + return; } - - if ($rootScope.selectedElementBeforeScrolling && $rootScope.selectedElementBeforeScrolling.getId() === selectedShape.getId()) - { - $rootScope.selectedElementBeforeScrolling = null; - return; + + if ($rootScope.selectedElementBeforeScrolling && $rootScope.selectedElementBeforeScrolling.getId() === selectedShape.getId()) { + $rootScope.selectedElementBeforeScrolling = null; + return; } // Store previous selection $scope.previousSelectedShape = $scope.selectedShape; - + // Only do something if another element is selected (Oryx fires this event multiple times) if ($scope.selectedShape !== undefined && $scope.selectedShape.getId() === selectedShape.getId()) { if ($rootScope.forceSelectionRefresh) { @@ -291,10 +282,9 @@ angular.module('activitiModeler') if (selectedShape.properties[key] === 'true') { selectedShape.properties[key] = true; } - - if (KISBPM.CONFIG.showRemovedProperties == false && property.isHidden()) - { - continue; + + if (KISBPM.CONFIG.showRemovedProperties == false && property.isHidden()) { + continue; } var currentProperty = { @@ -305,7 +295,7 @@ angular.module('activitiModeler') 'hidden': property.isHidden(), 'value': selectedShape.properties[key] }; - + if ((currentProperty.type === 'complex' || currentProperty.type === 'multiplecomplex') && currentProperty.value && currentProperty.value.length > 0) { try { currentProperty.value = JSON.parse(currentProperty.value); @@ -318,14 +308,13 @@ angular.module('activitiModeler') currentProperty.readModeTemplateUrl = propertyConfig.readModeTemplateUrl + '?version=' + $rootScope.staticIncludeVersion; } if (propertyConfig.writeModeTemplateUrl !== null && propertyConfig.writeModeTemplateUrl !== null) { - currentProperty.writeModeTemplateUrl = propertyConfig.writeModeTemplateUrl + '?version=' + $rootScope.staticIncludeVersion; + currentProperty.writeModeTemplateUrl = propertyConfig.writeModeTemplateUrl + '?version=' + $rootScope.staticIncludeVersion; } if (propertyConfig.templateUrl !== undefined && propertyConfig.templateUrl !== null) { currentProperty.templateUrl = propertyConfig.templateUrl + '?version=' + $rootScope.staticIncludeVersion; currentProperty.hasReadWriteMode = false; - } - else { + } else { currentProperty.hasReadWriteMode = true; } @@ -352,25 +341,25 @@ angular.module('activitiModeler') }); } }); - + $scope.editor.registerOnEvent(ORYX.CONFIG.EVENT_SELECTION_CHANGED, function (event) { - - KISBPM.eventBus.dispatch(KISBPM.eventBus.EVENT_TYPE_HIDE_SHAPE_BUTTONS); - var shapes = event.elements; - + + KISBPM.eventBus.dispatch(KISBPM.eventBus.EVENT_TYPE_HIDE_SHAPE_BUTTONS); + var shapes = event.elements; + if (shapes && shapes.length == 1) { var selectedShape = shapes.first(); - + var a = $scope.editor.getCanvas().node.getScreenCTM(); - - var absoluteXY = selectedShape.absoluteXY(); - - absoluteXY.x *= a.a; - absoluteXY.y *= a.d; - - var additionalIEZoom = 1; - if (!isNaN(screen.logicalXDPI) && !isNaN(screen.systemXDPI)) { + + var absoluteXY = selectedShape.absoluteXY(); + + absoluteXY.x *= a.a; + absoluteXY.y *= a.d; + + var additionalIEZoom = 1; + if (!isNaN(screen.logicalXDPI) && !isNaN(screen.systemXDPI)) { var ua = navigator.userAgent; if (ua.indexOf('MSIE') >= 0) { //IE 10 and below @@ -380,131 +369,124 @@ angular.module('activitiModeler') } } } - - if (additionalIEZoom === 1) { - absoluteXY.y = absoluteXY.y - jQuery("#canvasSection").offset().top + 5; - absoluteXY.x = absoluteXY.x - jQuery("#canvasSection").offset().left; - - } else { - var canvasOffsetLeft = jQuery("#canvasSection").offset().left; - var canvasScrollLeft = jQuery("#canvasSection").scrollLeft(); - var canvasScrollTop = jQuery("#canvasSection").scrollTop(); - - var offset = a.e - (canvasOffsetLeft * additionalIEZoom); - var additionaloffset = 0; - if (offset > 10) { - additionaloffset = (offset / additionalIEZoom) - offset; - } - absoluteXY.y = absoluteXY.y - (jQuery("#canvasSection").offset().top * additionalIEZoom) + 5 + ((canvasScrollTop * additionalIEZoom) - canvasScrollTop); - absoluteXY.x = absoluteXY.x - (canvasOffsetLeft * additionalIEZoom) + additionaloffset + ((canvasScrollLeft * additionalIEZoom) - canvasScrollLeft); + + if (additionalIEZoom === 1) { + absoluteXY.y = absoluteXY.y - jQuery("#canvasSection").offset().top + 5; + absoluteXY.x = absoluteXY.x - jQuery("#canvasSection").offset().left; + + } else { + var canvasOffsetLeft = jQuery("#canvasSection").offset().left; + var canvasScrollLeft = jQuery("#canvasSection").scrollLeft(); + var canvasScrollTop = jQuery("#canvasSection").scrollTop(); + + var offset = a.e - (canvasOffsetLeft * additionalIEZoom); + var additionaloffset = 0; + if (offset > 10) { + additionaloffset = (offset / additionalIEZoom) - offset; + } + absoluteXY.y = absoluteXY.y - (jQuery("#canvasSection").offset().top * additionalIEZoom) + 5 + ((canvasScrollTop * additionalIEZoom) - canvasScrollTop); + absoluteXY.x = absoluteXY.x - (canvasOffsetLeft * additionalIEZoom) + additionaloffset + ((canvasScrollLeft * additionalIEZoom) - canvasScrollLeft); + } + + var bounds = new ORYX.Core.Bounds(a.e + absoluteXY.x, a.f + absoluteXY.y, a.e + absoluteXY.x + a.a * selectedShape.bounds.width(), a.f + absoluteXY.y + a.d * selectedShape.bounds.height()); + var shapeXY = bounds.upperLeft(); + + var stencilItem = $scope.getStencilItemById(selectedShape.getStencil().idWithoutNs()); + var morphShapes = []; + if (stencilItem && stencilItem.morphRole) { + for (var i = 0; i < $scope.morphRoles.length; i++) { + if ($scope.morphRoles[i].role === stencilItem.morphRole) { + morphShapes = $scope.morphRoles[i].morphOptions; + } + } + } + + var x = shapeXY.x; + if (bounds.width() < 48) { + x -= 24; + } + + if (morphShapes && morphShapes.length > 0) { + // In case the element is not wide enough, start the 2 bottom-buttons more to the left + // to prevent overflow in the right-menu + var morphButton = document.getElementById('morph-button'); + morphButton.style.display = "block"; + morphButton.style.left = x + 24 + 'px'; + morphButton.style.top = (shapeXY.y + bounds.height() + 2) + 'px'; + } + + var deleteButton = document.getElementById('delete-button'); + deleteButton.style.display = "block"; + deleteButton.style.left = x + 'px'; + deleteButton.style.top = (shapeXY.y + bounds.height() + 2) + 'px'; + + if (stencilItem && (stencilItem.canConnect || stencilItem.canConnectAssociation)) { + var quickButtonCounter = 0; + var quickButtonX = shapeXY.x + bounds.width() + 5; + var quickButtonY = shapeXY.y; + jQuery('.Oryx_button').each(function (i, obj) { + if (obj.id !== 'morph-button' && obj.id != 'delete-button') { + quickButtonCounter++; + if (quickButtonCounter > 3) { + quickButtonX = shapeXY.x + bounds.width() + 5; + quickButtonY += 24; + quickButtonCounter = 1; + + } else if (quickButtonCounter > 1) { + quickButtonX += 24; + } + obj.style.display = "block"; + obj.style.left = quickButtonX + 'px'; + obj.style.top = quickButtonY + 'px'; + } + }); } - - var bounds = new ORYX.Core.Bounds(a.e + absoluteXY.x, a.f + absoluteXY.y, a.e + absoluteXY.x + a.a*selectedShape.bounds.width(), a.f + absoluteXY.y + a.d*selectedShape.bounds.height()); - var shapeXY = bounds.upperLeft(); - - var stencilItem = $scope.getStencilItemById(selectedShape.getStencil().idWithoutNs()); - var morphShapes = []; - if (stencilItem && stencilItem.morphRole) - { - for (var i = 0; i < $scope.morphRoles.length; i++) - { - if ($scope.morphRoles[i].role === stencilItem.morphRole) - { - morphShapes = $scope.morphRoles[i].morphOptions; - } - } - } - - var x = shapeXY.x; - if (bounds.width() < 48) { - x -= 24; - } - - if (morphShapes && morphShapes.length > 0) { - // In case the element is not wide enough, start the 2 bottom-buttons more to the left - // to prevent overflow in the right-menu - var morphButton = document.getElementById('morph-button'); - morphButton.style.display = "block"; - morphButton.style.left = x + 24 +'px'; - morphButton.style.top = (shapeXY.y+bounds.height() + 2) + 'px'; - } - - var deleteButton = document.getElementById('delete-button'); - deleteButton.style.display = "block"; - deleteButton.style.left = x + 'px'; - deleteButton.style.top = (shapeXY.y+bounds.height() + 2) + 'px'; - - if (stencilItem && (stencilItem.canConnect || stencilItem.canConnectAssociation)) { - var quickButtonCounter = 0; - var quickButtonX = shapeXY.x+bounds.width() + 5; - var quickButtonY = shapeXY.y; - jQuery('.Oryx_button').each(function(i, obj) { - if (obj.id !== 'morph-button' && obj.id != 'delete-button') { - quickButtonCounter++; - if (quickButtonCounter > 3) { - quickButtonX = shapeXY.x+bounds.width() + 5; - quickButtonY += 24; - quickButtonCounter = 1; - - } else if (quickButtonCounter > 1) { - quickButtonX += 24; - } - obj.style.display = "block"; - obj.style.left = quickButtonX + 'px'; - obj.style.top = quickButtonY + 'px'; - } - }); - } } }); - + if (!$rootScope.stencilInitialized) { - KISBPM.eventBus.addListener(KISBPM.eventBus.EVENT_TYPE_HIDE_SHAPE_BUTTONS, function (event) { - jQuery('.Oryx_button').each(function(i, obj) { - obj.style.display = "none"; - }); - }); + KISBPM.eventBus.addListener(KISBPM.eventBus.EVENT_TYPE_HIDE_SHAPE_BUTTONS, function (event) { + jQuery('.Oryx_button').each(function (i, obj) { + obj.style.display = "none"; + }); + }); - /* - * Listen to property updates and act upon them - */ - KISBPM.eventBus.addListener(KISBPM.eventBus.EVENT_TYPE_PROPERTY_VALUE_CHANGED, function (event) { - if (event.property && event.property.key) { - // If the name property is been updated, we also need to change the title of the currently selected item - if (event.property.key === 'oryx-name' && $scope.selectedItem !== undefined && $scope.selectedItem !== null) { - $scope.selectedItem.title = event.newValue; - } + /* + * Listen to property updates and act upon them + */ + KISBPM.eventBus.addListener(KISBPM.eventBus.EVENT_TYPE_PROPERTY_VALUE_CHANGED, function (event) { + if (event.property && event.property.key) { + // If the name property is been updated, we also need to change the title of the currently selected item + if (event.property.key === 'oryx-name' && $scope.selectedItem !== undefined && $scope.selectedItem !== null) { + $scope.selectedItem.title = event.newValue; + } - // Update "no value" flag - event.property.noValue = (event.property.value === undefined - || event.property.value === null - || event.property.value.length == 0); - } - }); - - $rootScope.stencilInitialized = true; + // Update "no value" flag + event.property.noValue = (event.property.value === undefined + || event.property.value === null + || event.property.value.length == 0); + } + }); + + $rootScope.stencilInitialized = true; } - - $scope.morphShape = function() { - $scope.safeApply(function () { - - var shapes = $rootScope.editor.getSelection(); - if (shapes && shapes.length == 1) - { - $rootScope.currentSelectedShape = shapes.first(); - var stencilItem = $scope.getStencilItemById($rootScope.currentSelectedShape.getStencil().idWithoutNs()); - var morphShapes = []; - for (var i = 0; i < $scope.morphRoles.length; i++) - { - if ($scope.morphRoles[i].role === stencilItem.morphRole) - { - morphShapes = $scope.morphRoles[i].morphOptions.slice(); - } - } - // Method to open shape select dialog (used later on) - var showSelectShapeDialog = function() - { + $scope.morphShape = function () { + $scope.safeApply(function () { + + var shapes = $rootScope.editor.getSelection(); + if (shapes && shapes.length == 1) { + $rootScope.currentSelectedShape = shapes.first(); + var stencilItem = $scope.getStencilItemById($rootScope.currentSelectedShape.getStencil().idWithoutNs()); + var morphShapes = []; + for (var i = 0; i < $scope.morphRoles.length; i++) { + if ($scope.morphRoles[i].role === stencilItem.morphRole) { + morphShapes = $scope.morphRoles[i].morphOptions.slice(); + } + } + + // Method to open shape select dialog (used later on) + var showSelectShapeDialog = function () { $rootScope.morphShapes = morphShapes; $modal({ backdrop: false, @@ -514,55 +496,56 @@ angular.module('activitiModeler') }; showSelectShapeDialog(); - } - }); + } + }); }; - - $scope.deleteShape = function() { - KISBPM.TOOLBAR.ACTIONS.deleteItem({'$scope': $scope}); - }; - - $scope.quickAddItem = function(newItemId) { - $scope.safeApply(function () { - - var shapes = $rootScope.editor.getSelection(); - if (shapes && shapes.length == 1) - { - $rootScope.currentSelectedShape = shapes.first(); - - var containedStencil = undefined; - var stencilSets = $scope.editor.getStencilSets().values(); - for (var i = 0; i < stencilSets.length; i++) - { - var stencilSet = stencilSets[i]; - var nodes = stencilSet.nodes(); - for (var j = 0; j < nodes.length; j++) - { - if (nodes[j].idWithoutNs() === newItemId) - { - containedStencil = nodes[j]; - break; - } - } - } - - if (!containedStencil) return; - - var option = {type: $scope.currentSelectedShape.getStencil().namespace() + newItemId, namespace: $scope.currentSelectedShape.getStencil().namespace()}; - option['connectedShape'] = $rootScope.currentSelectedShape; - option['parent'] = $rootScope.currentSelectedShape.parent; - option['containedStencil'] = containedStencil; - - var args = { sourceShape: $rootScope.currentSelectedShape, targetStencil: containedStencil }; - var targetStencil = $scope.editor.getRules().connectMorph(args); - if (!targetStencil){ return; }// Check if there can be a target shape - option['connectingType'] = targetStencil.id(); - var command = new KISBPM.CreateCommand(option, undefined, undefined, $scope.editor); - - $scope.editor.executeCommands([command]); - } - }); + $scope.deleteShape = function () { + KISBPM.TOOLBAR.ACTIONS.deleteItem({'$scope': $scope}); + }; + + $scope.quickAddItem = function (newItemId) { + $scope.safeApply(function () { + + var shapes = $rootScope.editor.getSelection(); + if (shapes && shapes.length == 1) { + $rootScope.currentSelectedShape = shapes.first(); + + var containedStencil = undefined; + var stencilSets = $scope.editor.getStencilSets().values(); + for (var i = 0; i < stencilSets.length; i++) { + var stencilSet = stencilSets[i]; + var nodes = stencilSet.nodes(); + for (var j = 0; j < nodes.length; j++) { + if (nodes[j].idWithoutNs() === newItemId) { + containedStencil = nodes[j]; + break; + } + } + } + + if (!containedStencil) return; + + var option = { + type: $scope.currentSelectedShape.getStencil().namespace() + newItemId, + namespace: $scope.currentSelectedShape.getStencil().namespace() + }; + option['connectedShape'] = $rootScope.currentSelectedShape; + option['parent'] = $rootScope.currentSelectedShape.parent; + option['containedStencil'] = containedStencil; + + var args = {sourceShape: $rootScope.currentSelectedShape, targetStencil: containedStencil}; + var targetStencil = $scope.editor.getRules().connectMorph(args); + if (!targetStencil) { + return; + }// Check if there can be a target shape + option['connectingType'] = targetStencil.id(); + + var command = new KISBPM.CreateCommand(option, undefined, undefined, $scope.editor); + + $scope.editor.executeCommands([command]); + } + }); }; }); // end of $scope.editorFactory.promise block @@ -714,7 +697,7 @@ angular.module('activitiModeler') */ $scope.dropCallback = function (event, ui) { - + $scope.editor.handleEvents({ type: ORYX.CONFIG.EVENT_HIGHLIGHT_HIDE, highlightId: "shapeRepo.attached" @@ -723,21 +706,21 @@ angular.module('activitiModeler') type: ORYX.CONFIG.EVENT_HIGHLIGHT_HIDE, highlightId: "shapeRepo.added" }); - + $scope.editor.handleEvents({ type: ORYX.CONFIG.EVENT_HIGHLIGHT_HIDE, highlightId: "shapeMenu" }); - + KISBPM.eventBus.dispatch(KISBPM.eventBus.EVENT_TYPE_HIDE_SHAPE_BUTTONS); if ($scope.dragCanContain) { - var item = $scope.getStencilItemById(ui.draggable[0].id); - - var pos = {x: event.pageX, y: event.pageY}; - - var additionalIEZoom = 1; + var item = $scope.getStencilItemById(ui.draggable[0].id); + + var pos = {x: event.pageX, y: event.pageY}; + + var additionalIEZoom = 1; if (!isNaN(screen.logicalXDPI) && !isNaN(screen.systemXDPI)) { var ua = navigator.userAgent; if (ua.indexOf('MSIE') >= 0) { @@ -748,7 +731,7 @@ angular.module('activitiModeler') } } } - + var screenCTM = $scope.editor.getCanvas().node.getScreenCTM(); // Correcting the UpperLeft-Offset @@ -757,37 +740,31 @@ angular.module('activitiModeler') // Correcting the Zoom-Factor pos.x /= screenCTM.a; pos.y /= screenCTM.d; - + // Correcting the ScrollOffset pos.x -= document.documentElement.scrollLeft; pos.y -= document.documentElement.scrollTop; - + var parentAbs = $scope.dragCurrentParent.absoluteXY(); pos.x -= parentAbs.x; pos.y -= parentAbs.y; var containedStencil = undefined; var stencilSets = $scope.editor.getStencilSets().values(); - for (var i = 0; i < stencilSets.length; i++) - { + for (var i = 0; i < stencilSets.length; i++) { var stencilSet = stencilSets[i]; var nodes = stencilSet.nodes(); - for (var j = 0; j < nodes.length; j++) - { - if (nodes[j].idWithoutNs() === ui.draggable[0].id) - { + for (var j = 0; j < nodes.length; j++) { + if (nodes[j].idWithoutNs() === ui.draggable[0].id) { containedStencil = nodes[j]; break; } } - if (!containedStencil) - { + if (!containedStencil) { var edges = stencilSet.edges(); - for (var j = 0; j < edges.length; j++) - { - if (edges[j].idWithoutNs() === ui.draggable[0].id) - { + for (var j = 0; j < edges.length; j++) { + if (edges[j].idWithoutNs() === ui.draggable[0].id) { containedStencil = edges[j]; break; } @@ -797,60 +774,57 @@ angular.module('activitiModeler') if (!containedStencil) return; - if ($scope.quickMenu) - { - var shapes = $scope.editor.getSelection(); - if (shapes && shapes.length == 1) - { - var currentSelectedShape = shapes.first(); + if ($scope.quickMenu) { + var shapes = $scope.editor.getSelection(); + if (shapes && shapes.length == 1) { + var currentSelectedShape = shapes.first(); - var option = {}; - option.type = currentSelectedShape.getStencil().namespace() + ui.draggable[0].id; - option.namespace = currentSelectedShape.getStencil().namespace(); - option.connectedShape = currentSelectedShape; - option.parent = $scope.dragCurrentParent; - option.containedStencil = containedStencil; - - // If the ctrl key is not pressed, - // snapp the new shape to the center - // if it is near to the center of the other shape - if (!event.ctrlKey){ - // Get the center of the shape - var cShape = currentSelectedShape.bounds.center(); - // Snapp +-20 Pixel horizontal to the center - if (20 > Math.abs(cShape.x - pos.x)){ - pos.x = cShape.x; - } - // Snapp +-20 Pixel vertical to the center - if (20 > Math.abs(cShape.y - pos.y)){ - pos.y = cShape.y; - } - } - - option.position = pos; - - if (containedStencil.idWithoutNs() !== 'SequenceFlow' && containedStencil.idWithoutNs() !== 'Association' && - containedStencil.idWithoutNs() !== 'MessageFlow' && containedStencil.idWithoutNs() !== 'DataAssociation') - { - var args = { sourceShape: currentSelectedShape, targetStencil: containedStencil }; - var targetStencil = $scope.editor.getRules().connectMorph(args); - if (!targetStencil){ return; }// Check if there can be a target shape - option.connectingType = targetStencil.id(); - } - - var command = new KISBPM.CreateCommand(option, $scope.dropTargetElement, pos, $scope.editor); - - $scope.editor.executeCommands([command]); - } - } - else - { + var option = {}; + option.type = currentSelectedShape.getStencil().namespace() + ui.draggable[0].id; + option.namespace = currentSelectedShape.getStencil().namespace(); + option.connectedShape = currentSelectedShape; + option.parent = $scope.dragCurrentParent; + option.containedStencil = containedStencil; + + // If the ctrl key is not pressed, + // snapp the new shape to the center + // if it is near to the center of the other shape + if (!event.ctrlKey) { + // Get the center of the shape + var cShape = currentSelectedShape.bounds.center(); + // Snapp +-20 Pixel horizontal to the center + if (20 > Math.abs(cShape.x - pos.x)) { + pos.x = cShape.x; + } + // Snapp +-20 Pixel vertical to the center + if (20 > Math.abs(cShape.y - pos.y)) { + pos.y = cShape.y; + } + } + + option.position = pos; + + if (containedStencil.idWithoutNs() !== 'SequenceFlow' && containedStencil.idWithoutNs() !== 'Association' && + containedStencil.idWithoutNs() !== 'MessageFlow' && containedStencil.idWithoutNs() !== 'DataAssociation') { + var args = {sourceShape: currentSelectedShape, targetStencil: containedStencil}; + var targetStencil = $scope.editor.getRules().connectMorph(args); + if (!targetStencil) { + return; + }// Check if there can be a target shape + option.connectingType = targetStencil.id(); + } + + var command = new KISBPM.CreateCommand(option, $scope.dropTargetElement, pos, $scope.editor); + + $scope.editor.executeCommands([command]); + } + } else { var canAttach = false; if (containedStencil.idWithoutNs() === 'BoundaryErrorEvent' || containedStencil.idWithoutNs() === 'BoundaryTimerEvent' || containedStencil.idWithoutNs() === 'BoundarySignalEvent' || containedStencil.idWithoutNs() === 'BoundaryMessageEvent' || containedStencil.idWithoutNs() === 'BoundaryCancelEvent' || containedStencil.idWithoutNs() === 'BoundaryCompensationEvent') { // Modify position, otherwise boundary event will get position related to left corner of the canvas instead of the container - pos = $scope.editor.eventCoordinates( event ); + pos = $scope.editor.eventCoordinates(event); canAttach = true; } @@ -861,19 +835,19 @@ angular.module('activitiModeler') option['parent'] = $scope.dragCurrentParent; var commandClass = ORYX.Core.Command.extend({ - construct: function(option, dockedShape, canAttach, position, facade){ + construct: function (option, dockedShape, canAttach, position, facade) { this.option = option; this.docker = null; this.dockedShape = dockedShape; this.dockedShapeParent = dockedShape.parent || facade.getCanvas(); this.position = position; - this.facade = facade; + this.facade = facade; this.selection = this.facade.getSelection(); this.shape = null; this.parent = null; this.canAttach = canAttach; }, - execute: function(){ + execute: function () { if (!this.shape) { this.shape = this.facade.createShape(option); this.parent = this.shape.parent; @@ -892,14 +866,14 @@ angular.module('activitiModeler') if (this.dockedShape !== this.facade.getCanvas()) { this.docker.setDockedShape(this.dockedShape); } - this.facade.setSelection( [this.docker.parent] ); + this.facade.setSelection([this.docker.parent]); } this.facade.getCanvas().update(); this.facade.updateSelection(); }, - rollback: function(){ + rollback: function () { if (this.shape) { this.facade.setSelection(this.selection.without(this.shape)); this.facade.deleteShape(this.shape); @@ -951,18 +925,18 @@ angular.module('activitiModeler') ui.helper.addClass('stencil-item-dragged'); } }; - + $scope.startDragCallbackQuickMenu = function (event, ui) { $scope.dragModeOver = false; $scope.quickMenu = true; }; - + $scope.dragCallback = function (event, ui) { - + if ($scope.dragModeOver != false) { - + var coord = $scope.editor.eventCoordinatesXY(event.pageX, event.pageY); - + var additionalIEZoom = 1; if (!isNaN(screen.logicalXDPI) && !isNaN(screen.systemXDPI)) { var ua = navigator.userAgent; @@ -974,14 +948,14 @@ angular.module('activitiModeler') } } } - + if (additionalIEZoom !== 1) { - coord.x = coord.x / additionalIEZoom; - coord.y = coord.y / additionalIEZoom; + coord.x = coord.x / additionalIEZoom; + coord.y = coord.y / additionalIEZoom; } - + var aShapes = $scope.editor.getCanvas().getAbstractShapesAtPosition(coord); - + if (aShapes.length <= 0) { if (event.helper) { $scope.dragCanContain = false; @@ -993,8 +967,7 @@ angular.module('activitiModeler') $scope.editor.getCanvas().setHightlightStateBasedOnX(coord.x); } - if (aShapes.length == 1 && aShapes[0] instanceof ORYX.Core.Canvas) - { + if (aShapes.length == 1 && aShapes[0] instanceof ORYX.Core.Canvas) { var parentCandidate = aShapes[0]; $scope.dragCanContain = true; @@ -1010,24 +983,22 @@ angular.module('activitiModeler') highlightId: "shapeRepo.added" }); return false; - } - else - { + } else { var item = $scope.getStencilItemById(event.target.id); - + var parentCandidate = aShapes.reverse().find(function (candidate) { return (candidate instanceof ORYX.Core.Canvas || candidate instanceof ORYX.Core.Node || candidate instanceof ORYX.Core.Edge); }); - + if (!parentCandidate) { $scope.dragCanContain = false; return false; } - + if (item.type === "node") { - + // check if the draggable is a boundary event and the parent an Activity var _canContain = false; var parentStencilId = parentCandidate.getStencil().id(); @@ -1041,18 +1012,14 @@ angular.module('activitiModeler') if (item.roles.indexOf("IntermediateEventOnActivityBoundary") > -1) { _canContain = true; } + } else if (parentCandidate.getStencil().idWithoutNs() === 'Pool') { + if (item.id === 'Lane') { + _canContain = true; + } } - else if (parentCandidate.getStencil().idWithoutNs() === 'Pool') - { - if (item.id === 'Lane') - { - _canContain = true; - } - } - - if (_canContain) - { - $scope.editor.handleEvents({ + + if (_canContain) { + $scope.editor.handleEvents({ type: ORYX.CONFIG.EVENT_HIGHLIGHT_SHOW, highlightId: "shapeRepo.attached", elements: [parentCandidate], @@ -1064,9 +1031,7 @@ angular.module('activitiModeler') type: ORYX.CONFIG.EVENT_HIGHLIGHT_HIDE, highlightId: "shapeRepo.added" }); - } - else - { + } else { for (var i = 0; i < $scope.containmentRules.length; i++) { var rule = $scope.containmentRules[i]; if (rule.role === parentItem.id) { @@ -1101,32 +1066,32 @@ angular.module('activitiModeler') $scope.dragCurrentParentId = parentCandidate.id; $scope.dragCurrentParentStencil = parentStencilId; $scope.dragCanContain = _canContain; - - } else { - var canvasCandidate = $scope.editor.getCanvas(); - var canConnect = false; - - var targetStencil = $scope.getStencilItemById(parentCandidate.getStencil().idWithoutNs()); - if (targetStencil) { - var associationConnect = false; - if (stencil.idWithoutNs() === 'Association' && (curCan.getStencil().idWithoutNs() === 'TextAnnotation' || curCan.getStencil().idWithoutNs() === 'BoundaryCompensationEvent')) { - associationConnect = true; - } else if (stencil.idWithoutNs() === 'DataAssociation' && curCan.getStencil().idWithoutNs() === 'DataStore') { + + } else { + var canvasCandidate = $scope.editor.getCanvas(); + var canConnect = false; + + var targetStencil = $scope.getStencilItemById(parentCandidate.getStencil().idWithoutNs()); + if (targetStencil) { + var associationConnect = false; + if (stencil.idWithoutNs() === 'Association' && (curCan.getStencil().idWithoutNs() === 'TextAnnotation' || curCan.getStencil().idWithoutNs() === 'BoundaryCompensationEvent')) { + associationConnect = true; + } else if (stencil.idWithoutNs() === 'DataAssociation' && curCan.getStencil().idWithoutNs() === 'DataStore') { associationConnect = true; } - - if (targetStencil.canConnectTo || associationConnect) { - canConnect = true; - } - } - - //Edge - $scope.dragCurrentParent = canvasCandidate; - $scope.dragCurrentParentId = canvasCandidate.id; + + if (targetStencil.canConnectTo || associationConnect) { + canConnect = true; + } + } + + //Edge + $scope.dragCurrentParent = canvasCandidate; + $scope.dragCurrentParentId = canvasCandidate.id; $scope.dragCurrentParentStencil = canvasCandidate.getStencil().id(); $scope.dragCanContain = canConnect; - - // Show Highlight + + // Show Highlight $scope.editor.handleEvents({ type: ORYX.CONFIG.EVENT_HIGHLIGHT_SHOW, highlightId: 'shapeRepo.added', @@ -1138,16 +1103,16 @@ angular.module('activitiModeler') type: ORYX.CONFIG.EVENT_HIGHLIGHT_HIDE, highlightId: "shapeRepo.attached" }); - } + } } } }; - + $scope.dragCallbackQuickMenu = function (event, ui) { - + if ($scope.dragModeOver != false) { var coord = $scope.editor.eventCoordinatesXY(event.pageX, event.pageY); - + var additionalIEZoom = 1; if (!isNaN(screen.logicalXDPI) && !isNaN(screen.systemXDPI)) { var ua = navigator.userAgent; @@ -1159,14 +1124,14 @@ angular.module('activitiModeler') } } } - + if (additionalIEZoom !== 1) { - coord.x = coord.x / additionalIEZoom; - coord.y = coord.y / additionalIEZoom; + coord.x = coord.x / additionalIEZoom; + coord.y = coord.y / additionalIEZoom; } - + var aShapes = $scope.editor.getCanvas().getAbstractShapesAtPosition(coord); - + if (aShapes.length <= 0) { if (event.helper) { $scope.dragCanContain = false; @@ -1177,45 +1142,41 @@ angular.module('activitiModeler') if (aShapes[0] instanceof ORYX.Core.Canvas) { $scope.editor.getCanvas().setHightlightStateBasedOnX(coord.x); } - - var stencil = undefined; - var stencilSets = $scope.editor.getStencilSets().values(); - for (var i = 0; i < stencilSets.length; i++) - { - var stencilSet = stencilSets[i]; - var nodes = stencilSet.nodes(); - for (var j = 0; j < nodes.length; j++) - { - if (nodes[j].idWithoutNs() === event.target.id) - { - stencil = nodes[j]; - break; - } - } - - if (!stencil) - { - var edges = stencilSet.edges(); - for (var j = 0; j < edges.length; j++) - { - if (edges[j].idWithoutNs() === event.target.id) - { - stencil = edges[j]; - break; - } - } - } - } - + + var stencil = undefined; + var stencilSets = $scope.editor.getStencilSets().values(); + for (var i = 0; i < stencilSets.length; i++) { + var stencilSet = stencilSets[i]; + var nodes = stencilSet.nodes(); + for (var j = 0; j < nodes.length; j++) { + if (nodes[j].idWithoutNs() === event.target.id) { + stencil = nodes[j]; + break; + } + } + + if (!stencil) { + var edges = stencilSet.edges(); + for (var j = 0; j < edges.length; j++) { + if (edges[j].idWithoutNs() === event.target.id) { + stencil = edges[j]; + break; + } + } + } + } + var candidate = aShapes.last(); - + var isValid = false; - if (stencil.type() === "node") - { - //check containment rules - var canContain = $scope.editor.getRules().canContain({containingShape:candidate, containedStencil:stencil}); - - var parentCandidate = aShapes.reverse().find(function (candidate) { + if (stencil.type() === "node") { + //check containment rules + var canContain = $scope.editor.getRules().canContain({ + containingShape: candidate, + containedStencil: stencil + }); + + var parentCandidate = aShapes.reverse().find(function (candidate) { return (candidate instanceof ORYX.Core.Canvas || candidate instanceof ORYX.Core.Node || candidate instanceof ORYX.Core.Edge); @@ -1225,69 +1186,62 @@ angular.module('activitiModeler') $scope.dragCanContain = false; return false; } - - $scope.dragCurrentParent = parentCandidate; + + $scope.dragCurrentParent = parentCandidate; $scope.dragCurrentParentId = parentCandidate.id; $scope.dragCurrentParentStencil = parentCandidate.getStencil().id(); $scope.dragCanContain = canContain; $scope.dropTargetElement = parentCandidate; isValid = canContain; - - } else { //Edge - - var shapes = $scope.editor.getSelection(); - if (shapes && shapes.length == 1) - { - var currentSelectedShape = shapes.first(); - var curCan = candidate; - var canConnect = false; - - var targetStencil = $scope.getStencilItemById(curCan.getStencil().idWithoutNs()); - if (targetStencil) - { - var associationConnect = false; - if (stencil.idWithoutNs() === 'Association' && (curCan.getStencil().idWithoutNs() === 'TextAnnotation' || curCan.getStencil().idWithoutNs() === 'BoundaryCompensationEvent')) - { - associationConnect = true; - } - else if (stencil.idWithoutNs() === 'DataAssociation' && curCan.getStencil().idWithoutNs() === 'DataStore') - { - associationConnect = true; - } - - if (targetStencil.canConnectTo || associationConnect) - { - while (!canConnect && curCan && !(curCan instanceof ORYX.Core.Canvas)) - { - candidate = curCan; - //check connection rules - canConnect = $scope.editor.getRules().canConnect({ - sourceShape: currentSelectedShape, - edgeStencil: stencil, - targetShape: curCan - }); - curCan = curCan.parent; - } - } - } - var parentCandidate = $scope.editor.getCanvas(); - - isValid = canConnect; - $scope.dragCurrentParent = parentCandidate; + + } else { //Edge + + var shapes = $scope.editor.getSelection(); + if (shapes && shapes.length == 1) { + var currentSelectedShape = shapes.first(); + var curCan = candidate; + var canConnect = false; + + var targetStencil = $scope.getStencilItemById(curCan.getStencil().idWithoutNs()); + if (targetStencil) { + var associationConnect = false; + if (stencil.idWithoutNs() === 'Association' && (curCan.getStencil().idWithoutNs() === 'TextAnnotation' || curCan.getStencil().idWithoutNs() === 'BoundaryCompensationEvent')) { + associationConnect = true; + } else if (stencil.idWithoutNs() === 'DataAssociation' && curCan.getStencil().idWithoutNs() === 'DataStore') { + associationConnect = true; + } + + if (targetStencil.canConnectTo || associationConnect) { + while (!canConnect && curCan && !(curCan instanceof ORYX.Core.Canvas)) { + candidate = curCan; + //check connection rules + canConnect = $scope.editor.getRules().canConnect({ + sourceShape: currentSelectedShape, + edgeStencil: stencil, + targetShape: curCan + }); + curCan = curCan.parent; + } + } + } + var parentCandidate = $scope.editor.getCanvas(); + + isValid = canConnect; + $scope.dragCurrentParent = parentCandidate; $scope.dragCurrentParentId = parentCandidate.id; $scope.dragCurrentParentStencil = parentCandidate.getStencil().id(); - $scope.dragCanContain = canConnect; - $scope.dropTargetElement = candidate; - } - - } + $scope.dragCanContain = canConnect; + $scope.dropTargetElement = candidate; + } + + } $scope.editor.handleEvents({ - type: ORYX.CONFIG.EVENT_HIGHLIGHT_SHOW, - highlightId:'shapeMenu', - elements: [candidate], - color: isValid ? ORYX.CONFIG.SELECTION_VALID_COLOR : ORYX.CONFIG.SELECTION_INVALID_COLOR - }); + type: ORYX.CONFIG.EVENT_HIGHLIGHT_SHOW, + highlightId: 'shapeMenu', + elements: [candidate], + color: isValid ? ORYX.CONFIG.SELECTION_VALID_COLOR : ORYX.CONFIG.SELECTION_INVALID_COLOR + }); } }; @@ -1296,18 +1250,18 @@ angular.module('activitiModeler') var KISBPM = KISBPM || {}; //create command for undo/redo KISBPM.CreateCommand = ORYX.Core.Command.extend({ - construct: function(option, currentReference, position, facade){ - this.option = option; - this.currentReference = currentReference; - this.position = position; - this.facade = facade; - this.shape; - this.edge; - this.targetRefPos; - this.sourceRefPos; - /* - * clone options parameters - */ + construct: function (option, currentReference, position, facade) { + this.option = option; + this.currentReference = currentReference; + this.position = position; + this.facade = facade; + this.shape; + this.edge; + this.targetRefPos; + this.sourceRefPos; + /* + * clone options parameters + */ this.connectedShape = option.connectedShape; this.connectingType = option.connectingType; this.namespace = option.namespace; @@ -1316,120 +1270,115 @@ KISBPM.CreateCommand = ORYX.Core.Command.extend({ this.parent = option.parent; this.currentReference = currentReference; this.shapeOptions = option.shapeOptions; - }, - execute: function(){ - - if (this.shape) { - if (this.shape instanceof ORYX.Core.Node) { - this.parent.add(this.shape); - if (this.edge) { - this.facade.getCanvas().add(this.edge); - this.edge.dockers.first().setDockedShape(this.connectedShape); - this.edge.dockers.first().setReferencePoint(this.sourceRefPos); - this.edge.dockers.last().setDockedShape(this.shape); - this.edge.dockers.last().setReferencePoint(this.targetRefPos); - } - - this.facade.setSelection([this.shape]); - - } else if (this.shape instanceof ORYX.Core.Edge) { - this.facade.getCanvas().add(this.shape); - this.shape.dockers.first().setDockedShape(this.connectedShape); - this.shape.dockers.first().setReferencePoint(this.sourceRefPos); - } - } - else { - this.shape = this.facade.createShape(this.option); - this.edge = (!(this.shape instanceof ORYX.Core.Edge)) ? this.shape.getIncomingShapes().first() : undefined; - } - - if (this.currentReference && this.position) { - - if (this.shape instanceof ORYX.Core.Edge) { - - if (!(this.currentReference instanceof ORYX.Core.Canvas)) { - this.shape.dockers.last().setDockedShape(this.currentReference); - - if (this.currentReference.getStencil().idWithoutNs() === 'TextAnnotation') - { - var midpoint = {}; - midpoint.x = 0; - midpoint.y = this.currentReference.bounds.height() / 2; - this.shape.dockers.last().setReferencePoint(midpoint); - } - else - { - this.shape.dockers.last().setReferencePoint(this.currentReference.bounds.midPoint()); - } - } - else { - this.shape.dockers.last().bounds.centerMoveTo(this.position); - } - this.sourceRefPos = this.shape.dockers.first().referencePoint; - this.targetRefPos = this.shape.dockers.last().referencePoint; - - } else if (this.edge){ - this.sourceRefPos = this.edge.dockers.first().referencePoint; - this.targetRefPos = this.edge.dockers.last().referencePoint; - } - } else { - var containedStencil = this.containedStencil; - var connectedShape = this.connectedShape; - var bc = connectedShape.bounds; - var bs = this.shape.bounds; - - var pos = bc.center(); - if(containedStencil.defaultAlign()==="north") { - pos.y -= (bc.height() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET + (bs.height()/2); - } else if(containedStencil.defaultAlign()==="northeast") { - pos.x += (bc.width() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.width()/2); - pos.y -= (bc.height() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.height()/2); - } else if(containedStencil.defaultAlign()==="southeast") { - pos.x += (bc.width() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.width()/2); - pos.y += (bc.height() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.height()/2); - } else if(containedStencil.defaultAlign()==="south") { - pos.y += (bc.height() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET + (bs.height()/2); - } else if(containedStencil.defaultAlign()==="southwest") { - pos.x -= (bc.width() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.width()/2); - pos.y += (bc.height() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.height()/2); - } else if(containedStencil.defaultAlign()==="west") { - pos.x -= (bc.width() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET + (bs.width()/2); - } else if(containedStencil.defaultAlign()==="northwest") { - pos.x -= (bc.width() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.width()/2); - pos.y -= (bc.height() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.height()/2); - } else { - pos.x += (bc.width() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET + (bs.width()/2); - } - - // Move shape to the new position - this.shape.bounds.centerMoveTo(pos); - - // Move all dockers of a node to the position - if (this.shape instanceof ORYX.Core.Node){ - (this.shape.dockers||[]).each(function(docker){ - docker.bounds.centerMoveTo(pos); - }); - } - - //this.shape.update(); - this.position = pos; - - if (this.edge){ - this.sourceRefPos = this.edge.dockers.first().referencePoint; - this.targetRefPos = this.edge.dockers.last().referencePoint; - } - } - - this.facade.getCanvas().update(); - this.facade.updateSelection(); + }, + execute: function () { - }, - rollback: function(){ - this.facade.deleteShape(this.shape); - if(this.edge) { - this.facade.deleteShape(this.edge); - } - //this.currentParent.update(); - this.facade.setSelection(this.facade.getSelection().without(this.shape, this.edge)); - } + if (this.shape) { + if (this.shape instanceof ORYX.Core.Node) { + this.parent.add(this.shape); + if (this.edge) { + this.facade.getCanvas().add(this.edge); + this.edge.dockers.first().setDockedShape(this.connectedShape); + this.edge.dockers.first().setReferencePoint(this.sourceRefPos); + this.edge.dockers.last().setDockedShape(this.shape); + this.edge.dockers.last().setReferencePoint(this.targetRefPos); + } + + this.facade.setSelection([this.shape]); + + } else if (this.shape instanceof ORYX.Core.Edge) { + this.facade.getCanvas().add(this.shape); + this.shape.dockers.first().setDockedShape(this.connectedShape); + this.shape.dockers.first().setReferencePoint(this.sourceRefPos); + } + } else { + this.shape = this.facade.createShape(this.option); + this.edge = (!(this.shape instanceof ORYX.Core.Edge)) ? this.shape.getIncomingShapes().first() : undefined; + } + + if (this.currentReference && this.position) { + + if (this.shape instanceof ORYX.Core.Edge) { + + if (!(this.currentReference instanceof ORYX.Core.Canvas)) { + this.shape.dockers.last().setDockedShape(this.currentReference); + + if (this.currentReference.getStencil().idWithoutNs() === 'TextAnnotation') { + var midpoint = {}; + midpoint.x = 0; + midpoint.y = this.currentReference.bounds.height() / 2; + this.shape.dockers.last().setReferencePoint(midpoint); + } else { + this.shape.dockers.last().setReferencePoint(this.currentReference.bounds.midPoint()); + } + } else { + this.shape.dockers.last().bounds.centerMoveTo(this.position); + } + this.sourceRefPos = this.shape.dockers.first().referencePoint; + this.targetRefPos = this.shape.dockers.last().referencePoint; + + } else if (this.edge) { + this.sourceRefPos = this.edge.dockers.first().referencePoint; + this.targetRefPos = this.edge.dockers.last().referencePoint; + } + } else { + var containedStencil = this.containedStencil; + var connectedShape = this.connectedShape; + var bc = connectedShape.bounds; + var bs = this.shape.bounds; + + var pos = bc.center(); + if (containedStencil.defaultAlign() === "north") { + pos.y -= (bc.height() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET + (bs.height() / 2); + } else if (containedStencil.defaultAlign() === "northeast") { + pos.x += (bc.width() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.width() / 2); + pos.y -= (bc.height() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.height() / 2); + } else if (containedStencil.defaultAlign() === "southeast") { + pos.x += (bc.width() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.width() / 2); + pos.y += (bc.height() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.height() / 2); + } else if (containedStencil.defaultAlign() === "south") { + pos.y += (bc.height() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET + (bs.height() / 2); + } else if (containedStencil.defaultAlign() === "southwest") { + pos.x -= (bc.width() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.width() / 2); + pos.y += (bc.height() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.height() / 2); + } else if (containedStencil.defaultAlign() === "west") { + pos.x -= (bc.width() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET + (bs.width() / 2); + } else if (containedStencil.defaultAlign() === "northwest") { + pos.x -= (bc.width() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.width() / 2); + pos.y -= (bc.height() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET_CORNER + (bs.height() / 2); + } else { + pos.x += (bc.width() / 2) + ORYX.CONFIG.SHAPEMENU_CREATE_OFFSET + (bs.width() / 2); + } + + // Move shape to the new position + this.shape.bounds.centerMoveTo(pos); + + // Move all dockers of a node to the position + if (this.shape instanceof ORYX.Core.Node) { + (this.shape.dockers || []).each(function (docker) { + docker.bounds.centerMoveTo(pos); + }); + } + + //this.shape.update(); + this.position = pos; + + if (this.edge) { + this.sourceRefPos = this.edge.dockers.first().referencePoint; + this.targetRefPos = this.edge.dockers.last().referencePoint; + } + } + + this.facade.getCanvas().update(); + this.facade.updateSelection(); + + }, + rollback: function () { + this.facade.deleteShape(this.shape); + if (this.edge) { + this.facade.deleteShape(this.edge); + } + //this.currentParent.update(); + this.facade.setSelection(this.facade.getSelection().without(this.shape, this.edge)); + } }); diff --git a/module-activiti/src/main/resources/static/stencilset.json b/module-activiti/src/main/resources/static/stencilset.json index c763fe58..e0ab436f 100644 --- a/module-activiti/src/main/resources/static/stencilset.json +++ b/module-activiti/src/main/resources/static/stencilset.json @@ -9,8 +9,8 @@ { "id": "process_id", "type": "String", - "title": "流程名称", - "value": "process", + "title": "流程ID", + "value": "", "description": "流程的特殊唯一的名称标识", "popular": true } @@ -35,7 +35,7 @@ { "id": "name", "type": "String", - "title": "名称", + "title": "元素名称", "value": "", "description": "元素名称", "popular": true, diff --git a/module-activiti/src/main/resources/templates/activiti/list.html b/module-activiti/src/main/resources/templates/activiti/list.html index 8369ff2a..71325a23 100644 --- a/module-activiti/src/main/resources/templates/activiti/list.html +++ b/module-activiti/src/main/resources/templates/activiti/list.html @@ -122,15 +122,12 @@ if(!row.deploymentId) { return '-'; } - return ''; + return ''; } }, - {field: 'option', width: 80, title: '操作', align:'center', fixed: 'right', + {field: 'option2', width: 80, title: '操作', align:'center', fixed: 'right', templet: function(row) { - if(!row.deploymentId) { - return ''; - } - return ''; + return ''; } }, ] @@ -212,10 +209,6 @@ } else if(checkDatas.length > 1) { top.dialog.msg(top.dataMessage.table.selectOneEdit); } else { - if(checkDatas[0].deploymentId) { - top.dialog.msg('已经部署的流程不能编辑'); - return; - } top.dialog.open({ url: top.restAjax.path('route/activiti/update?modelId={modelId}', [checkDatas[0].id]), title: false, @@ -255,21 +248,6 @@ top.dialog.close(loadLayerIndex); }); }); - } else if(layEvent === 'revokePublishEvent') { - top.dialog.confirm('确定 撤销 部署流程?', function(index) { - top.dialog.close(index); - var loadLayerIndex; - top.restAjax.put(top.restAjax.path('api/activiti/revoke-publish/{modelId}', [data.id]), {}, null, function(code, data) { - top.dialog.msg('操作成功'); - reloadTable(); - }, function(code, data) { - top.dialog.msg(data.msg); - }, function() { - loadLayerIndex = top.dialog.msg(top.dataMessage.committing, {icon: 16, time: 0, shade: 0.3}); - }, function() { - top.dialog.close(loadLayerIndex); - }); - }); } else if(layEvent === 'flowChatEvent') { if(!data.deploymentId) { top.dialog.msg('流程未部署,无法查看流程图'); diff --git a/module-activiti/src/main/resources/templates/activiti/procdef/list.html b/module-activiti/src/main/resources/templates/activiti/procdef/list.html new file mode 100644 index 00000000..517ffd38 --- /dev/null +++ b/module-activiti/src/main/resources/templates/activiti/procdef/list.html @@ -0,0 +1,197 @@ + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/module-activiti/src/main/resources/templates/activiti/save.html b/module-activiti/src/main/resources/templates/activiti/save.html index 066cf45f..f3f0e1a7 100644 --- a/module-activiti/src/main/resources/templates/activiti/save.html +++ b/module-activiti/src/main/resources/templates/activiti/save.html @@ -33,13 +33,6 @@ -
- -
- -
-
-