Merge branch 'feature/develop1.0'

This commit is contained in:
jinqiming 2021-02-23 15:24:42 +08:00
commit d45bfd5eba
949 changed files with 251943 additions and 443 deletions

View File

@ -1,5 +1,5 @@
## 平台简介
致力于构建钉钉流程OA一体化
## 内置功能
@ -20,11 +20,48 @@
15. 服务监控监视当前系统CPU、内存、磁盘、堆栈等相关信息。
16. 在线构建器拖动表单元素生成相应的HTML代码。
17. 连接池监视监视当前系统数据库连接池状态可进行分析SQL找出系统性能瓶颈。
18. **钉钉管理:钉钉用户,部门体系数据同步,请假单,采购单流程**
19. **流程管理: 流程模型在线设计,流程组管理**
20. **支付管理:一键导入支付宝和微信账单,可系统化管理账单**
## 在线体验
暂未开放数据库,有需要的可以加群,项目可搭建流程平台商业化
- QQ群: 577813338
- admin/admin123
## 启动项目配置
- 1.加群,在群文档获取项目数据库
- 2.配置钉钉秘钥
<img src="https://qimetons.oss-cn-beijing.aliyuncs.com/c2a24a8fd77e462586137f21f3a5380f.png"/>
- 3.配置钉钉回调参数
<img src="https://qimetons.oss-cn-beijing.aliyuncs.com/bbee68c5a1c64092ab4e0fa29d7cdf5d.png"/>
钉钉回调需要公网为了方便提供一个内网穿透工具详情参考http://snowblog.shop.csj361.com/post/26
## 项目截图
<table>
<tr>
<td><img src="https://qimetons.oss-cn-beijing.aliyuncs.com/094981bad3844c25b4e0e9ae5fdfb253.png"/></td>
<td><img src="https://qimetons.oss-cn-beijing.aliyuncs.com/694936c6e1b34af4a9c2525bf25156ba.png"/></td>
</tr>
<tr>
<td><img src="https://qimetons.oss-cn-beijing.aliyuncs.com/102a95b10c5b4094ae9eea060ed3d0c4.png"/></td>
<td><img src="https://qimetons.oss-cn-beijing.aliyuncs.com/de48282f792d4300ba26b7a397464d71.png"/></td>
</tr>
<tr>
<td><img src="https://qimetons.oss-cn-beijing.aliyuncs.com/952eaddf26164feaae13ec9ffdbeab35.png"/></td>
<td><img src="https://qimetons.oss-cn-beijing.aliyuncs.com/416ffa7c1f1f42f8807a24dc2e63a08d.png"/></td>
</tr>
</table>
## 未来规划
TODO 1.0
1.0 部门,用户,角色与钉钉打通
- 1.0 角色与钉钉打通
- 2.0 流程表单设计
- 3.0 钉钉工作流与系统工作流打通(让流程移动化)
## 交流群
QQ群: 577813338 欢迎入群讨论,我们的口号:借助钉钉,致力于流程,让流程更简单
## 感谢诺依系统提供框架
诺依系统地址 http://ruoyi.vip

Binary file not shown.

26
pom.xml
View File

@ -202,6 +202,20 @@
<version>${ruoyi.version}</version>
</dependency>
<!--钉钉模块-->
<dependency>
<groupId>com.snow</groupId>
<artifactId>snow-dingtalk</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!--工作流模块-->
<dependency>
<groupId>com.snow</groupId>
<artifactId>snow-flowable</artifactId>
<version>${ruoyi.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
@ -213,6 +227,7 @@
<module>snow-generator</module>
<module>snow-common</module>
<module>snow-dingtalk</module>
<module>snow-flowable</module>
</modules>
<packaging>pom</packaging>
@ -245,6 +260,17 @@
<enabled>true</enabled>
</releases>
</repository>
<repository>
<id>sonatype-nexus-staging</id>
<name>Sonatype Nexus Staging</name>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>

View File

@ -22,7 +22,12 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
@ -81,6 +86,19 @@
<version>4.3.1</version>
</dependency>
<!--dingtalk-->
<dependency>
<groupId>com.snow</groupId>
<artifactId>snow-dingtalk</artifactId>
<version>4.3.1</version>
</dependency>
<!--工作流-->
<dependency>
<groupId>com.snow</groupId>
<artifactId>snow-flowable</artifactId>
<version>4.3.1</version>
</dependency>
</dependencies>
<build>

View File

@ -1,20 +1,53 @@
package com.snow;
import com.snow.flowable.common.SpringContextUtil;
import org.flowable.ui.common.rest.idm.remote.RemoteAccountResource;
import org.flowable.ui.modeler.properties.FlowableModelerAppProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
/**
* 启动程序
*
* @author snow
*/
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@SpringBootApplication(
exclude= {
DataSourceAutoConfiguration.class,
SecurityAutoConfiguration.class,
SecurityAutoConfiguration.class,
UserDetailsServiceAutoConfiguration.class,
LiquibaseAutoConfiguration.class
}
)
@ComponentScan(basePackages = {"com.snow",
"org.flowable.ui"
},
excludeFilters= @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {RemoteAccountResource.class})
)
public class SnowApplication
{
public static void main(String[] args)
{
// System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(SnowApplication.class, args);
//SpringApplication.run(SnowApplication.class, args);
ApplicationContext context=SpringApplication.run(SnowApplication.class, args);
SpringContextUtil.setApplicationContext(context);
}
@Bean
public FlowableModelerAppProperties flowableModelerAppProperties() {
FlowableModelerAppProperties flowableModelerAppProperties=new FlowableModelerAppProperties();
return flowableModelerAppProperties;
}
}

View File

@ -2,6 +2,13 @@ package com.snow.web.controller.common;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.fasterxml.uuid.impl.UUIDUtil;
import com.snow.common.utils.uuid.IdUtils;
import com.snow.common.utils.uuid.UUID;
import com.snow.framework.storage.StorageService;
import com.snow.system.domain.SysFile;
import org.apache.logging.log4j.core.util.UuidUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -31,6 +38,9 @@ public class CommonController
@Autowired
private ServerConfig serverConfig;
@Autowired
private StorageService storageService;
/**
* 通用下载请求
*
@ -70,18 +80,16 @@ public class CommonController
*/
@PostMapping("/common/upload")
@ResponseBody
public AjaxResult uploadFile(MultipartFile file) throws Exception
public AjaxResult uploadFile(MultipartFile file)
{
try
{
// 上传文件路径
String filePath = Global.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
String originalFilename = file.getOriginalFilename();
SysFile store = storageService.store(file.getInputStream(), file.getSize(), file.getContentType(), originalFilename);
AjaxResult ajax = AjaxResult.success();
ajax.put("fileName", fileName);
ajax.put("url", url);
ajax.put("fileKey",store.getKey());
ajax.put("fileName", store.getName());
ajax.put("url", store.getUrl());
return ajax;
}
catch (Exception e)

View File

@ -0,0 +1,88 @@
package com.snow.web.controller.dingtalk;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.oapi.lib.aes.DingTalkEncryptor;
import com.snow.common.constant.Constants;
import com.snow.common.enums.DingTalkListenerType;
import com.snow.dingtalk.common.EventNameEnum;
import com.snow.dingtalk.sync.ISyncSysInfo;
import com.snow.dingtalk.sync.SyncSysInfoFactory;
import com.snow.system.domain.DingtalkCallBack;
import com.snow.system.service.impl.DingtalkCallBackServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author qimingjin
* @Title:
* @Description:
* @date 2020/11/3 17:11
*/
@RestController
@Slf4j
@RequestMapping("/dingTalk")
public class DingTalkCallBackController {
@Autowired
private DingtalkCallBackServiceImpl dingtalkCallBackService;
private static final String EVENT_TYPE="EventType";
private static final String ENCRYPT="encrypt";
/**
* 钉钉回调
* @param signature
* @param timestamp
* @param nonce
* @param body
* @return
*/
@PostMapping(value = "/dingTalkCallBack")
public Object dingCallback(
@RequestParam(value = "signature") String signature,
@RequestParam(value = "timestamp") Long timestamp,
@RequestParam(value = "nonce") String nonce,
@RequestBody(required = false) JSONObject body
) {
DingtalkCallBack dingtalkCallBack=new DingtalkCallBack();
dingtalkCallBack.setFlag(true);
List<DingtalkCallBack> dingtalkCallBacks = dingtalkCallBackService.selectDingtalkCallBackList(dingtalkCallBack);
if(CollectionUtils.isEmpty(dingtalkCallBacks)){
return Constants.CALL_BACK_FAIL_RETURN;
}
dingtalkCallBack=dingtalkCallBacks.get(0);
try {
log.info("begin callback------》 signature:{},timestamp:{},nonce:{},body:{}" ,signature,timestamp,nonce,body);
DingTalkEncryptor dingTalkEncryptor = new DingTalkEncryptor(dingtalkCallBack.getToken(),dingtalkCallBack.getAesKey(),dingtalkCallBack.getCorpId());
// 从post请求的body中获取回调信息的加密数据进行解密处理
String encrypt = body.getString(ENCRYPT);
String plainText = dingTalkEncryptor.getDecryptMsg(signature, timestamp.toString(), nonce, encrypt);
JSONObject callBackContent = JSON.parseObject(plainText);
// 根据回调事件类型做不同的业务处理
String eventType = callBackContent.getString(EVENT_TYPE);
DingTalkListenerType type = DingTalkListenerType.getType(eventType);
if(StringUtils.isEmpty(type)){
return Constants.CALL_BACK_FAIL_RETURN;
}
//调用工厂模式异步处理数据
SyncSysInfoFactory syncSysInfoFactory = new SyncSysInfoFactory();
ISyncSysInfo iSyncSysInfo = syncSysInfoFactory.getSyncSysInfoService(type);
iSyncSysInfo.SyncSysInfo(type, callBackContent);
// 返回success的加密信息表示回调处理成功
return dingTalkEncryptor.getEncryptedMap(Constants.CALL_BACK_SUCCESS_RETURN, timestamp, nonce);
} catch (Exception e) {
//todo 失败短信或者邮件通知并记录下数据
log.error("process callback fail------》 signature:{},timestamp:{},nonce:{},body:{}" ,signature,timestamp,nonce,body, e);
return Constants.CALL_BACK_FAIL_RETURN;
}
}
}

View File

@ -0,0 +1,54 @@
package com.snow.web.controller.dingtalk;
import com.dingtalk.api.response.OapiDepartmentListResponse;
import com.snow.common.utils.StringUtils;
import com.snow.dingtalk.service.impl.DepartmentServiceImpl;
import com.snow.system.domain.SysDept;
import com.snow.system.service.impl.SysDeptServiceImpl;
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;
/**
* @author qimingjin
* @Title: 同步初始化数据
* @Description:
* @date 2020/11/16 9:51
*/
@RestController
@RequestMapping("/syncInitData")
public class SyncInitDataController {
@Autowired
private DepartmentServiceImpl departmentService;
@Autowired
private SysDeptServiceImpl sysDeptService;
@GetMapping("/initDepartment")
public void initDepartment(){
List<OapiDepartmentListResponse.Department> dingTalkDepartmentList = departmentService.getDingTalkDepartmentList();
dingTalkDepartmentList.stream().forEach(t->{
SysDept sysDept=new SysDept();
SysDept sysDepts = sysDeptService.selectDeptById(t.getId());
if(StringUtils.isNotNull(sysDepts)){
sysDept.setDeptId(t.getId());
sysDept.setDeptName(t.getName());
sysDept.setOrderNum(String.valueOf(t.getId()));
sysDept.setParentId(t.getParentid());
sysDept.setIsSyncDingTalk(false);
sysDeptService.updateDept(sysDept);
}else {
sysDept.setDeptId(t.getId());
sysDept.setDeptName(t.getName());
sysDept.setOrderNum(String.valueOf(t.getId()));
sysDept.setParentId(t.getParentid());
sysDept.setIsSyncDingTalk(false);
sysDeptService.insertDept(sysDept);
}
});
}
}

View File

@ -0,0 +1,188 @@
package com.snow.web.controller.flowable;
import com.google.common.collect.Lists;
import com.snow.common.annotation.Log;
import com.snow.common.core.controller.BaseController;
import com.snow.common.core.domain.AjaxResult;
import com.snow.common.core.page.TableDataInfo;
import com.snow.common.enums.BusinessType;
import com.snow.common.utils.poi.ExcelUtil;
import com.snow.flowable.service.impl.FlowablePublishServiceImpl;
import com.snow.flowable.service.impl.FlowableServiceImpl;
import com.snow.framework.util.ShiroUtils;
import com.snow.system.domain.ActDeModel;
import com.snow.system.service.IActDeModelService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.flowable.engine.repository.Deployment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 设计器modelController
*
* @author qimingjin
* @date 2020-12-01
*/
@Controller
@RequestMapping("/system/model")
public class ActDeModelController extends BaseController
{
private String prefix = "system/model";
@Autowired
private IActDeModelService actDeModelService;
@Autowired
private FlowablePublishServiceImpl flowablePublishServiceImpl;
@Autowired
private FlowableServiceImpl flowableService;
@RequiresPermissions("system:model:view")
@GetMapping()
public String model()
{
return prefix + "/model";
}
/**
* 查询设计器model列表
*/
@RequiresPermissions("system:model:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(ActDeModel actDeModel)
{
startPage();
actDeModel.setModelTypeList(Lists.newArrayList(ActDeModel.MODEL_TYPE_BPMN,ActDeModel.MODEL_TYPE_DECISION_TABLE));
List<ActDeModel> list = actDeModelService.selectActDeModelList(actDeModel);
return getDataTable(list);
}
/**
* 导出设计器model列表
*/
@RequiresPermissions("system:model:export")
@Log(title = "设计器model", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(ActDeModel actDeModel)
{
List<ActDeModel> list = actDeModelService.selectActDeModelList(actDeModel);
ExcelUtil<ActDeModel> util = new ExcelUtil<ActDeModel>(ActDeModel.class);
return util.exportExcel(list, "model");
}
/**
* 新增设计器model
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存设计器model
*/
@RequiresPermissions("system:model:add")
@Log(title = "设计器model", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(ActDeModel actDeModel)
{
Long userId = ShiroUtils.getUserId();
ActDeModel actDeModelName=new ActDeModel();
actDeModelName.setName(actDeModel.getName());
List<ActDeModel> actDeModels = actDeModelService.selectActDeModelList(actDeModelName);
if(!CollectionUtils.isEmpty(actDeModels)){
return AjaxResult.error("该模型名称已存在");
}
ActDeModel actDeModelKey=new ActDeModel();
actDeModelKey.setModelKey(actDeModel.getModelKey());
List<ActDeModel> actDeModelKeyList = actDeModelService.selectActDeModelList(actDeModelKey);
if(!CollectionUtils.isEmpty(actDeModelKeyList)){
return AjaxResult.error("该模型key已存在");
}
actDeModel.setCreatedBy(String.valueOf(userId));
flowableService.saveModel(actDeModel);
return toAjax(1);
}
/**
* 修改设计器model
*/
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") String id, ModelMap mmap)
{
ActDeModel actDeModel = actDeModelService.selectActDeModelById(id);
mmap.put("actDeModel", actDeModel);
return redirect("/modeler/index.html#/editor/"+id);
}
/**
* 修改保存设计器model
*/
@RequiresPermissions("system:model:edit")
@Log(title = "设计器model", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(ActDeModel actDeModel)
{
return toAjax(actDeModelService.updateActDeModel(actDeModel));
}
/**
* 删除设计器model
*/
@RequiresPermissions("system:model:remove")
@Log(title = "设计器model", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
flowableService.deleteModel(ids);
return toAjax(1);
}
@Log(title = "发布流程", businessType = BusinessType.DEPLOYMENT)
@RequiresPermissions("system:model:deployment")
@PostMapping("/deployment")
@ResponseBody
public AjaxResult deployment(String id,Integer type)
{
String deploymentId = flowablePublishServiceImpl.deploymentByModelId(id, type);
if(deploymentId==null){
return AjaxResult.error("modelId不存在");
}
return AjaxResult.success("发布成功");
}
/**
* 导出model的xml文件
*/
@Log(title = "导出流程XML", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:model:exportXml")
@GetMapping(value = "/exportXml/{modelId}")
public void exportXml(@PathVariable("modelId") String modelId, HttpServletResponse response) {
flowableService.exportModelXml(modelId,response);
}
/**
* 展示model的xml文件
*/
@RequiresPermissions("system:model:showXml")
@GetMapping(value = "/showXml/{modelId}")
public void showXml(@PathVariable("modelId") String modelId, HttpServletResponse response) {
flowableService.showModelXml(modelId,response);
}
}

View File

@ -0,0 +1,179 @@
package com.snow.web.controller.flowable;
import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson.JSON;
import com.snow.common.annotation.RepeatSubmit;
import com.snow.common.core.controller.BaseController;
import com.snow.common.core.domain.AjaxResult;
import com.snow.common.core.page.PageModel;
import com.snow.common.core.page.TableDataInfo;
import com.snow.flowable.domain.*;
import com.snow.flowable.service.AppFormService;
import com.snow.flowable.service.FlowableTaskService;
import com.snow.flowable.service.impl.FlowableServiceImpl;
import com.snow.framework.util.ShiroUtils;
import com.snow.system.domain.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
/**
* @program: snow
* @description
* @author: 没用的阿吉
* @create: 2020-11-23 21:17
**/
@Controller
@RequestMapping("/flow")
@Slf4j
public class FlowController extends BaseController {
private String prefix = "flow";
@Autowired
private FlowableServiceImpl flowableService;
@Autowired
private AppFormService appFormService;
@Autowired
private FlowableTaskService flowableTaskService;
/**
* 跳转完成任务界面
* @return
*/
@GetMapping("/toFinishTask")
public String toFinishTask(String taskId,ModelMap mmap)
{
Task task = flowableTaskService.getTask(taskId);
//获取业务参数
AppForm appFrom = appFormService.getAppFrom(task.getProcessInstanceId());
mmap.put("appFrom", appFrom);
mmap.put("taskId", taskId);
mmap.put("processInstanceId", task.getProcessInstanceId());
return task.getFormKey();
}
/**
* 完成任务
* @return
*/
@PostMapping("/finishTask")
@ResponseBody
@RepeatSubmit
public AjaxResult finishTask(CompleteTaskDTO completeTaskDTO)
{
SysUser sysUser = ShiroUtils.getSysUser();
completeTaskDTO.setUserId(String.valueOf(sysUser.getUserId()));
flowableService.completeTask(completeTaskDTO);
return AjaxResult.success();
}
/**
* 获取我的待办
*/
@RequiresPermissions("flow:get:todoList")
@PostMapping("/findTasksByUserId")
@ResponseBody
public TableDataInfo findTasksByUserId(TaskBaseDTO taskBaseDTO)
{
Long userId = ShiroUtils.getUserId();
PageModel<TaskVO> taskList = flowableTaskService.findTasksByUserId(String.valueOf(userId), taskBaseDTO);
return getFlowDataTable(taskList);
}
/**
* 获取所有节点
* @param processInstanceId
* @return
*/
@GetMapping("/getDynamicFlowNodeInfo")
@ResponseBody
public AjaxResult getDynamicFlowNodeInfo(String processInstanceId){
List<TaskVO> dynamicFlowNodeInfo = flowableService.getDynamicFlowNodeInfo(processInstanceId);
return AjaxResult.success(dynamicFlowNodeInfo);
}
/**
* 跳转我发起的流程
* @return
*/
@RequiresPermissions("flow:get:getMyStartProcess")
@GetMapping("/toMyStartProcess")
public String getMyHistoricProcessInstance()
{
return prefix+"/myStartProcess";
}
/**
* 获取我的流程实例
* @param processInstanceDTO
* @return
*/
@RequiresPermissions("flow:process:getMyStartProcess")
@PostMapping("/getMyHistoricProcessInstance")
@ResponseBody
public TableDataInfo getMyHistoricProcessInstance(ProcessInstanceDTO processInstanceDTO){
SysUser sysUser = ShiroUtils.getSysUser();
processInstanceDTO.setStartedUserId(String.valueOf(sysUser.getUserId()));
PageModel<ProcessInstanceVO> historicProcessInstance = flowableService.getHistoricProcessInstance(processInstanceDTO);
log.info(JSON.toJSONString(historicProcessInstance.getPagedRecords()));
return getFlowDataTable(historicProcessInstance);
}
/**
* 跳转我发起的流程详情
*/
@GetMapping("/myStartProcessDetail")
@RequiresPermissions("system:flow:myStartProcessDetail")
public String myStartProcessDetail(String processInstanceId,ModelMap modelMap)
{
//已审批的
HistoricTaskInstanceDTO historicTaskInstanceDTO=new HistoricTaskInstanceDTO();
historicTaskInstanceDTO.setProcessInstanceId(processInstanceId);
//historicTaskInstanceDTO.setProcessStatus(1);
List<HistoricTaskInstanceVO> historicTaskInstanceList= flowableService.getHistoricTaskInstanceNoPage(historicTaskInstanceDTO);
AppForm appFrom = appFormService.getAppFrom(processInstanceId);
modelMap.put("historicTaskInstanceList",historicTaskInstanceList);
modelMap.put("processInstanceId",processInstanceId);
modelMap.put("busVarUrl",appFrom.getBusVarUrl());
modelMap.put("appId",ReflectUtil.getFieldValue(appFrom,"id"));
return prefix +"/myStartProcessDetail";
}
/**
* 我参与的任务
* @return
*/
@RequiresPermissions("flow:process:getMyTakePartInProcess")
@GetMapping("/toMyTakePartInProcess")
public String getMyTakePartInProcess()
{
return prefix+"/myTakePartInProcess";
}
/**
* 获取我办结的任务列表
* @param historicTaskInstanceDTO
* @return
*/
@RequiresPermissions("flow:process:getMyTakePartInProcess")
@PostMapping("/getMyTakePartInProcess")
@ResponseBody
public TableDataInfo getMyTakePartInProcess(HistoricTaskInstanceDTO historicTaskInstanceDTO){
SysUser sysUser = ShiroUtils.getSysUser();
historicTaskInstanceDTO.setUserId(String.valueOf(sysUser.getUserId()));
PageModel<HistoricTaskInstanceVO> historicTaskInstance = flowableService.getHistoricTaskInstance(historicTaskInstanceDTO);
return getFlowDataTable(historicTaskInstance);
}
}

View File

@ -0,0 +1,159 @@
package com.snow.web.controller.flowable;
import java.util.List;
import com.snow.common.constant.UserConstants;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.snow.common.annotation.Log;
import com.snow.common.enums.BusinessType;
import org.springframework.stereotype.Controller;
import com.snow.system.domain.FlowGroupDO;
import com.snow.system.service.IFlowGroupDOService;
import com.snow.common.core.controller.BaseController;
import com.snow.common.core.domain.AjaxResult;
import com.snow.common.utils.poi.ExcelUtil;
import com.snow.common.utils.StringUtils;
import com.snow.common.core.domain.Ztree;
/**
* 流程组信息Controller
*
* @author snow
* @date 2020-12-19
*/
@Controller
@RequestMapping("/flow/role")
public class FlowGroupController extends BaseController
{
private String prefix = "flow/role";
@Autowired
private IFlowGroupDOService flowGroupDOService;
@RequiresPermissions("system:group:view")
@GetMapping()
public String role()
{
return prefix + "/role";
}
/**
* 查询流程组信息树列表
*/
@RequiresPermissions("system:group:list")
@PostMapping("/list")
@ResponseBody
public List<FlowGroupDO> list(FlowGroupDO flowGroupDO)
{
flowGroupDO.setRoleType(UserConstants.FLOW_ROLE_TYPE);
List<FlowGroupDO> list = flowGroupDOService.selectFlowGroupDOList(flowGroupDO);
return list;
}
/**
* 导出流程组信息列表
*/
@RequiresPermissions("system:group:export")
@Log(title = "流程组信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(FlowGroupDO flowGroupDO)
{
flowGroupDO.setRoleType(UserConstants.FLOW_ROLE_TYPE);
List<FlowGroupDO> list = flowGroupDOService.selectFlowGroupDOList(flowGroupDO);
ExcelUtil<FlowGroupDO> util = new ExcelUtil<FlowGroupDO>(FlowGroupDO.class);
return util.exportExcel(list, "role");
}
/**
* 新增流程组信息
*/
@GetMapping(value = { "/add/{roleId}", "/add/" })
public String add(@PathVariable(value = "roleId", required = false) Long roleId, ModelMap mmap)
{
if (StringUtils.isNotNull(roleId))
{
mmap.put("flowGroupDO", flowGroupDOService.selectFlowGroupDOById(roleId));
}
return prefix + "/add";
}
/**
* 新增保存流程组信息
*/
@RequiresPermissions("system:group:add")
@Log(title = "流程组信息", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(FlowGroupDO flowGroupDO)
{
flowGroupDO.setRoleType(UserConstants.FLOW_ROLE_TYPE);
return toAjax(flowGroupDOService.insertFlowGroupDO(flowGroupDO));
}
/**
* 修改流程组信息
*/
@GetMapping("/edit/{roleId}")
public String edit(@PathVariable("roleId") Long roleId, ModelMap mmap)
{
FlowGroupDO flowGroupDO = flowGroupDOService.selectFlowGroupDOById(roleId);
mmap.put("flowGroupDO", flowGroupDO);
return prefix + "/edit";
}
/**
* 修改保存流程组信息
*/
@RequiresPermissions("system:group:edit")
@Log(title = "流程组信息", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(FlowGroupDO flowGroupDO)
{
return toAjax(flowGroupDOService.updateFlowGroupDO(flowGroupDO));
}
/**
* 删除
*/
@RequiresPermissions("system:group:remove")
@Log(title = "流程组信息", businessType = BusinessType.DELETE)
@GetMapping("/remove/{roleId}")
@ResponseBody
public AjaxResult remove(@PathVariable("roleId") Long roleId)
{
return toAjax(flowGroupDOService.deleteFlowGroupDOById(roleId));
}
/**
* 选择流程组信息树
*/
@GetMapping(value = { "/selectRoleTree/{roleId}", "/selectRoleTree/" })
public String selectRoleTree(@PathVariable(value = "roleId", required = false) Long roleId, ModelMap mmap)
{
if (StringUtils.isNotNull(roleId))
{
mmap.put("flowGroupDO", flowGroupDOService.selectFlowGroupDOById(roleId));
}
return prefix + "/tree";
}
/**
* 加载流程组信息树列表
*/
@GetMapping("/treeData")
@ResponseBody
public List<Ztree> treeData()
{
List<Ztree> ztrees = flowGroupDOService.selectFlowGroupDOTree();
return ztrees;
}
}

View File

@ -0,0 +1,153 @@
package com.snow.web.controller.flowable;
import com.snow.common.annotation.Log;
import com.snow.common.annotation.RepeatSubmit;
import com.snow.common.core.controller.BaseController;
import com.snow.common.core.domain.AjaxResult;
import com.snow.common.core.page.PageModel;
import com.snow.common.core.page.TableDataInfo;
import com.snow.common.enums.BusinessType;
import com.snow.flowable.domain.*;
import com.snow.flowable.service.FlowableTaskService;
import com.snow.flowable.service.impl.FlowablePublishServiceImpl;
import com.snow.flowable.service.impl.FlowableServiceImpl;
import com.snow.framework.util.ShiroUtils;
import com.snow.system.domain.FinanceAlipayFlow;
import com.snow.system.service.IFinanceAlipayFlowService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.flowable.engine.repository.Model;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.List;
/**
* Controller
*
* @author snow
* @date 2020-11-09
*/
@Controller
@RequestMapping("/modeler")
public class FlowModelerController extends BaseController
{
private String prefix = "flow";
@Autowired
private FlowableServiceImpl flowableService;
@Autowired
private FlowablePublishServiceImpl flowablePublishService;
/**
* 跳转流程编译器
* @return
*/
@RequiresPermissions("modeler:flow:view")
@GetMapping("/index")
public String index()
{
return redirect("/modeler/index.html");
}
@RequiresPermissions("modeler:model:view")
@GetMapping("/model")
public String modelView()
{
return prefix + "/model";
}
@RequiresPermissions("modeler:deployment:view")
@GetMapping()
public String deploymentView()
{
return prefix + "/deployment";
}
/**
* 查询发布实例列表
*/
@RequiresPermissions("modeler:deployment:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(DeploymentQueryDTO deploymentQuery)
{
PageModel<DeploymentVO> deploymentList = flowableService.getDeploymentList(deploymentQuery);
return getFlowDataTable(deploymentList);
}
/**
* 获取XML
*/
@GetMapping("/getXml")
@RequiresPermissions("modeler:deployment:getXml")
public void getXml(String id,String resourceName,HttpServletResponse response)
{
flowableService.getDeploymentSource(id,resourceName,"xml",response);
}
/**
* 获取流程图
*/
@GetMapping("/getFlowPicture")
@RequiresPermissions("modeler:deployment:getFlowPicture")
public void getFlowPicture(String id,String resourceName,HttpServletResponse response)
{
flowableService.getDeploymentSource(id,resourceName,"png",response);
}
/**
* 获取流程图
*/
@RequiresPermissions("modeler:flow:getProcessDiagram")
@GetMapping("/getProcessDiagram")
public void getProcessDiagram(String processInstanceId,HttpServletResponse response,ModelMap modelMap)
{
flowableService.getFlowableProcessImage(processInstanceId, response);
}
/**
* 删除发布
*/
@RequiresPermissions("modeler:deployment:remove")
@Log(title = "删除发布", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
flowableService.deleteDeployment(ids);
return toAjax(1);
}
@Log(title = "发布流程", businessType = BusinessType.IMPORT)
@RequiresPermissions("modeler:deployment:deployment")
@PostMapping("/importData")
@ResponseBody
@RepeatSubmit
public AjaxResult importData(MultipartFile file, String name,String key,String category) throws Exception
{
InputStream inputStream = file.getInputStream();
String originalFilename = file.getOriginalFilename();
DeploymentDTO deploymentQueryDTO=new DeploymentDTO();
deploymentQueryDTO.setName(name);
deploymentQueryDTO.setKey(key);
deploymentQueryDTO.setCategory(category);
deploymentQueryDTO.setResourceName(originalFilename);
flowablePublishService.createInputStreamDeployment(deploymentQueryDTO,inputStream);
return AjaxResult.success("发布成功");
}
}

View File

@ -0,0 +1,70 @@
package com.snow.web.controller.flowable;
import com.snow.common.core.controller.BaseController;
import com.snow.common.core.page.TableDataInfo;
import com.snow.flowable.domain.FlowRemoteVO;
import com.snow.flowable.service.FlowableUserService;
import org.flowable.ui.common.model.RemoteGroup;
import org.flowable.ui.common.model.RemoteUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author qimingjin
* @Title:
* @Description:
* @date 2020/11/20 10:34
*/
@RestController
@RequestMapping("/app")
public class FlowUserController extends BaseController {
@Autowired
private FlowableUserService flowableUserService;
/**
* 编译器登录
* @return
*/
@RequestMapping(value="/rest/account")
public String getAccount() {
return "{\"id\":\"admin\",\"firstName\":\"Test\",\"lastName\":\"Administrator\",\"email\":\"admin@modeler.org\",\"fullName\":\"Test Administrator\",\"groups\":[],\"privileges\":[\"access-idm\",\"access-task\",\"access-modeler\",\"access-admin\"]}\n" +
"";
}
/**
* 获取用户列表
* @param filter
*/
@GetMapping(value = "/rest/getUserList")
public FlowRemoteVO getFlowUserList(@RequestParam(value = "filter",required = false) String filter) {
startPage();
List<RemoteUser> flowUserList = flowableUserService.getFlowUserList(filter);
TableDataInfo dataTable = getDataTable(flowUserList);
FlowRemoteVO flowRemoteVO = new FlowRemoteVO();
flowRemoteVO.setData(dataTable.getRows());
flowRemoteVO.setSize(dataTable.getPageSize());
flowRemoteVO.setStart(dataTable.getPageIndex());
flowRemoteVO.setTotal(dataTable.getTotal());
return flowRemoteVO;
}
/**
* 获取用户列表
* @param filter
*/
@GetMapping(value = "/rest/getUserGroupList")
public FlowRemoteVO getUserGroupList(@RequestParam(value = "filter",required = false) String filter) {
startPage();
List<RemoteGroup> flowUserGroupList = flowableUserService.getFlowUserGroupList(filter);
TableDataInfo dataTable = getDataTable(flowUserGroupList);
FlowRemoteVO flowRemoteVO = new FlowRemoteVO();
flowRemoteVO.setData(dataTable.getRows());
flowRemoteVO.setSize(dataTable.getPageSize());
flowRemoteVO.setStart(dataTable.getPageIndex());
flowRemoteVO.setTotal(dataTable.getTotal());
return flowRemoteVO;
}
}

View File

@ -0,0 +1,83 @@
package com.snow.web.controller.monitor;
import com.snow.common.core.controller.BaseController;
import com.snow.common.core.domain.AjaxResult;
import com.snow.framework.web.service.CacheService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 缓存监控
*
* @author ruoyi
*/
@Controller
@RequestMapping("/monitor/cache")
public class CacheController extends BaseController
{
private String prefix = "monitor/cache";
@Autowired
private CacheService cacheService;
@GetMapping()
public String cache(ModelMap mmap)
{
mmap.put("cacheNames", cacheService.getCacheNames());
return prefix + "/cache";
}
@PostMapping("/getNames")
public String getCacheNames(String fragment, ModelMap mmap)
{
mmap.put("cacheNames", cacheService.getCacheNames());
return prefix + "/cache::" + fragment;
}
@PostMapping("/getKeys")
public String getCacheKeys(String fragment, String cacheName, ModelMap mmap)
{
mmap.put("cacheName", cacheName);
mmap.put("cacheKyes", cacheService.getCacheKeys(cacheName));
return prefix + "/cache::" + fragment;
}
@PostMapping("/getValue")
public String getCacheValue(String fragment, String cacheName, String cacheKey, ModelMap mmap)
{
mmap.put("cacheName", cacheName);
mmap.put("cacheKey", cacheKey);
mmap.put("cacheValue", cacheService.getCacheValue(cacheName, cacheKey));
return prefix + "/cache::" + fragment;
}
@PostMapping("/clearCacheName")
@ResponseBody
public AjaxResult clearCacheName(String cacheName, ModelMap mmap)
{
cacheService.clearCacheName(cacheName);
return AjaxResult.success();
}
@PostMapping("/clearCacheKey")
@ResponseBody
public AjaxResult clearCacheKey(String cacheName, String cacheKey, ModelMap mmap)
{
cacheService.clearCacheKey(cacheName, cacheKey);
return AjaxResult.success();
}
@GetMapping("/clearAll")
@ResponseBody
public AjaxResult clearAll(ModelMap mmap)
{
cacheService.clearAll();
return AjaxResult.success();
}
}

View File

@ -0,0 +1,134 @@
package com.snow.web.controller.system;
import java.util.List;
import com.dingtalk.api.response.OapiCallBackGetCallBackFailedResultResponse;
import com.snow.dingtalk.service.impl.CallBackServiceImpl;
import com.snow.framework.util.ShiroUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.snow.common.annotation.Log;
import com.snow.common.enums.BusinessType;
import com.snow.system.domain.DingtalkCallBack;
import com.snow.system.service.IDingtalkCallBackService;
import com.snow.common.core.controller.BaseController;
import com.snow.common.core.domain.AjaxResult;
import com.snow.common.utils.poi.ExcelUtil;
import com.snow.common.core.page.TableDataInfo;
/**
* 回调事件Controller
*
* @author qimingjin
* @date 2020-11-02
*/
@Controller
@RequestMapping("/system/back")
public class DingtalkCallBackController extends BaseController
{
private String prefix = "system/back";
@Autowired
private IDingtalkCallBackService dingtalkCallBackService;
@RequiresPermissions("system:back:view")
@GetMapping()
public String back()
{
return prefix + "/back";
}
/**
* 查询回调事件列表
*/
@RequiresPermissions("system:back:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(DingtalkCallBack dingtalkCallBack)
{
startPage();
List<DingtalkCallBack> list = dingtalkCallBackService.selectDingtalkCallBackList(dingtalkCallBack);
return getDataTable(list);
}
/**
* 导出回调事件列表
*/
@RequiresPermissions("system:back:export")
@Log(title = "回调事件", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(DingtalkCallBack dingtalkCallBack)
{
List<DingtalkCallBack> list = dingtalkCallBackService.selectDingtalkCallBackList(dingtalkCallBack);
ExcelUtil<DingtalkCallBack> util = new ExcelUtil<DingtalkCallBack>(DingtalkCallBack.class);
return util.exportExcel(list, "back");
}
/**
* 新增回调事件
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存回调事件
*/
@RequiresPermissions("system:back:add")
@Log(title = "回调事件", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(DingtalkCallBack dingtalkCallBack)
{
dingtalkCallBack.setCreateBy(ShiroUtils.getLoginName());
return toAjax(dingtalkCallBackService.insertDingtalkCallBack(dingtalkCallBack));
}
/**
* 修改回调事件
*/
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
DingtalkCallBack dingtalkCallBack = dingtalkCallBackService.selectDingtalkCallBackById(id);
mmap.put("dingtalkCallBack", dingtalkCallBack);
return prefix + "/edit";
}
/**
* 修改保存回调事件
*/
@RequiresPermissions("system:back:edit")
@Log(title = "回调事件", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(DingtalkCallBack dingtalkCallBack)
{
dingtalkCallBack.setUpdateBy(ShiroUtils.getLoginName());
return toAjax(dingtalkCallBackService.updateDingtalkCallBack(dingtalkCallBack));
}
/**
* 删除回调事件
*/
@RequiresPermissions("system:back:remove")
@Log(title = "回调事件", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(dingtalkCallBackService.deleteDingtalkCallBackByIds(ids));
}
}

View File

@ -0,0 +1,155 @@
package com.snow.web.controller.system;
import java.util.List;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.snow.framework.excel.FinanceAlipayFlowListener;
import com.snow.framework.util.ShiroUtils;
import com.snow.system.domain.FinanceAlipayFlowImport;
import com.snow.system.domain.SysUser;
import com.snow.system.mapper.FinanceAlipayFlowMapper;
import com.snow.system.mapper.SysUserMapper;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.snow.common.annotation.Log;
import com.snow.common.enums.BusinessType;
import com.snow.system.domain.FinanceAlipayFlow;
import com.snow.system.service.IFinanceAlipayFlowService;
import com.snow.common.core.controller.BaseController;
import com.snow.common.core.domain.AjaxResult;
import com.snow.common.utils.poi.ExcelUtil;
import com.snow.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;
/**
* 财务支付宝流水Controller
*
* @author snow
* @date 2020-11-09
*/
@Controller
@RequestMapping("/system/flow")
public class FinanceFlowController extends BaseController
{
private String prefix = "system/flow";
@Autowired
private IFinanceAlipayFlowService financeAlipayFlowService;
@RequiresPermissions("system:flow:view")
@GetMapping()
public String flow()
{
return prefix + "/flow";
}
/**
* 查询财务支付宝流水列表
*/
@RequiresPermissions("system:flow:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(FinanceAlipayFlow financeAlipayFlow)
{
startPage();
List<FinanceAlipayFlow> list = financeAlipayFlowService.selectFinanceAlipayFlowList(financeAlipayFlow);
return getDataTable(list);
}
/**
* 导出财务支付宝流水列表
*/
@RequiresPermissions("system:flow:export")
@Log(title = "财务支付宝流水", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(FinanceAlipayFlow financeAlipayFlow)
{
List<FinanceAlipayFlow> list = financeAlipayFlowService.selectFinanceAlipayFlowList(financeAlipayFlow);
ExcelUtil<FinanceAlipayFlow> util = new ExcelUtil<FinanceAlipayFlow>(FinanceAlipayFlow.class);
return util.exportExcel(list, "flow");
}
/**
* 新增财务支付宝流水
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存财务支付宝流水
*/
@RequiresPermissions("system:flow:add")
@Log(title = "财务支付宝流水", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(FinanceAlipayFlow financeAlipayFlow)
{
return toAjax(financeAlipayFlowService.insertFinanceAlipayFlow(financeAlipayFlow));
}
/**
* 修改财务支付宝流水
*/
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
FinanceAlipayFlow financeAlipayFlow = financeAlipayFlowService.selectFinanceAlipayFlowById(id);
mmap.put("financeAlipayFlow", financeAlipayFlow);
return prefix + "/edit";
}
/**
* 修改保存财务支付宝流水
*/
@RequiresPermissions("system:flow:edit")
@Log(title = "财务支付宝流水", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(FinanceAlipayFlow financeAlipayFlow)
{
return toAjax(financeAlipayFlowService.updateFinanceAlipayFlow(financeAlipayFlow));
}
/**
* 删除财务支付宝流水
*/
@RequiresPermissions("system:flow:remove")
@Log(title = "财务支付宝流水", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(financeAlipayFlowService.deleteFinanceAlipayFlowByIds(ids));
}
@Log(title = "财务支付宝流水", businessType = BusinessType.IMPORT)
@RequiresPermissions("system:flow:import")
@PostMapping("/importData")
@ResponseBody
public AjaxResult importData(MultipartFile file, String tradeRealName,String tradeAccount,String billType) throws Exception
{
SysUser sysUser = ShiroUtils.getSysUser();
FinanceAlipayFlowListener financeAlipayFlowListener = new FinanceAlipayFlowListener(financeAlipayFlowService, sysUser, tradeAccount,tradeRealName,Integer.parseInt(billType));
ExcelReader excelReader = EasyExcel.read(file.getInputStream(), FinanceAlipayFlowImport.class, financeAlipayFlowListener).build();
ReadSheet readSheet = EasyExcel.readSheet(0).build();
excelReader.read(readSheet);
// 这里千万别忘记关闭读的时候会创建临时文件到时磁盘会崩的
excelReader.finish();
return AjaxResult.success("导入成功");
}
}

View File

@ -0,0 +1,269 @@
package com.snow.web.controller.system;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.snow.common.annotation.RepeatSubmit;
import com.snow.common.constant.SequenceContants;
import com.snow.common.utils.poi.EasyExcelUtil;
import com.snow.flowable.domain.CompleteTaskDTO;
import com.snow.flowable.domain.leave.SysOaLeaveForm;
import com.snow.flowable.domain.purchaseOrder.PurchaseOrderForm;
import com.snow.flowable.domain.purchaseOrder.PurchaseOrderMainTask;
import com.snow.flowable.service.FlowableService;
import com.snow.flowable.service.FlowableTaskService;
import com.snow.framework.excel.FinanceAlipayFlowListener;
import com.snow.framework.excel.PurchaseOrderListener;
import com.snow.framework.util.ShiroUtils;
import com.snow.system.domain.*;
import com.snow.system.service.ISysSequenceService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.snow.common.annotation.Log;
import com.snow.common.enums.BusinessType;
import org.springframework.stereotype.Controller;
import com.snow.system.service.IPurchaseOrderMainService;
import com.snow.common.core.controller.BaseController;
import com.snow.common.core.domain.AjaxResult;
import com.snow.common.utils.poi.ExcelUtil;
import com.snow.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
/**
* 采购单主表Controller
*
* @author snow
* @date 2021-01-07
*/
@Controller
@RequestMapping("/system/purchaseOrder")
public class PurchaseOrderController extends BaseController
{
private String prefix = "system/purchaseOrder";
@Autowired
private IPurchaseOrderMainService purchaseOrderMainService;
@Autowired
private FlowableService flowableService;
@Autowired
private FlowableTaskService flowableTaskService;
@Autowired
private ISysSequenceService sequenceService;
@RequiresPermissions("system:purchaseOrder:view")
@GetMapping()
public String purchaseOrder()
{
return prefix + "/purchaseOrder";
}
/**
* 查询采购单主表列表
*/
@RequiresPermissions("system:purchaseOrder:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(PurchaseOrderMain purchaseOrderMain)
{
startPage();
List<PurchaseOrderMain> list = purchaseOrderMainService.selectPurchaseOrderMainList(purchaseOrderMain);
return getDataTable(list);
}
/**
* 导出采购单主表列表detail
*/
@RequiresPermissions("system:purchaseOrder:export")
@Log(title = "采购单主表", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(PurchaseOrderMain purchaseOrderMain)
{
List<PurchaseOrderMain> list = purchaseOrderMainService.selectPurchaseOrderMainList(purchaseOrderMain);
ExcelUtil<PurchaseOrderMain> util = new ExcelUtil<PurchaseOrderMain>(PurchaseOrderMain.class);
return util.exportExcel(list, "purchaseOrder");
}
/**
* 下载标准模板
*/
@GetMapping("/download")
@ResponseBody
public AjaxResult download(HttpServletResponse response)
{
PurchaseOrderImport purchaseOrderImport=new PurchaseOrderImport();
purchaseOrderImport.setGoodsNo("CSJ0001");
purchaseOrderImport.setGoodsName("示例商品1");
purchaseOrderImport.setGoodsPrice(new BigDecimal(2.5));
purchaseOrderImport.setGoodsQuantity(new BigDecimal(2));
purchaseOrderImport.setGoodsSize("示例规格1");
purchaseOrderImport.setRemark("示例备注1");
List<PurchaseOrderImport> list=Lists.newArrayList();
list.add(purchaseOrderImport);
try {
EasyExcelUtil.writeExcel("采购单明细表","明细表",PurchaseOrderImport.class,list,response);
return AjaxResult.success("下载成功");
} catch (Exception e) {
return AjaxResult.error("下载模板异常,请联系管理员");
}
}
/**
* 新增采购单主表
*/
@GetMapping("/add")
public String add(ModelMap mmap)
{
String newSequenceNo = sequenceService.getNewSequenceNo(SequenceContants.OA_PURCHASE_SEQUENCE);
mmap.put("orderNo", newSequenceNo);
return prefix + "/add";
}
/**
* 新增保存采购单主表
*/
@RequiresPermissions("system:purchaseOrder:add")
@Log(title = "采购单主表", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
@RepeatSubmit
public AjaxResult addSave(PurchaseOrderMain purchaseOrderMain)
{
return toAjax(purchaseOrderMainService.insertPurchaseOrderMain(purchaseOrderMain));
}
/**
* 导入采购单子表列表
*/
@RequiresPermissions("system:purchaseOrder:import")
@Log(title = "采购单主表", businessType = BusinessType.IMPORT)
@PostMapping("/import")
@ResponseBody
public AjaxResult importData(MultipartFile file)
{
SysUser sysUser = ShiroUtils.getSysUser();
PurchaseOrderListener purchaseOrderListener = new PurchaseOrderListener(purchaseOrderMainService, sysUser);
ExcelReader excelReader = null;
try {
excelReader = EasyExcel.read(file.getInputStream(), PurchaseOrderImport.class, purchaseOrderListener).build();
ReadSheet readSheet = EasyExcel.readSheet(0).build();
excelReader.read(readSheet);
} catch (IOException e) {
e.printStackTrace();
return AjaxResult.success("导入失败:"+e.getMessage());
}finally {
// 这里千万别忘记关闭读的时候会创建临时文件到时磁盘会崩的
excelReader.finish();
}
List<PurchaseOrderImport> list = purchaseOrderListener.list;
return AjaxResult.success(list);
}
/**
* 修改采购单主表
*/
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Integer id, ModelMap mmap)
{
PurchaseOrderMain purchaseOrderMain = purchaseOrderMainService.selectPurchaseOrderMainById(id);
mmap.put("purchaseOrderMain", purchaseOrderMain);
return prefix + "/edit";
}
/**
* 修改保存采购单并发起申请
*/
@RequiresPermissions("system:purchaseOrder:edit")
@Log(title = "采购单主表", businessType = BusinessType.OTHER)
@PostMapping("/edit")
@ResponseBody
@Transactional
@RepeatSubmit
public AjaxResult editSave(PurchaseOrderMain purchaseOrderMain)
{
SysUser sysUser = ShiroUtils.getSysUser();
purchaseOrderMain.setUpdateBy(String.valueOf(sysUser.getUserId()));
int i = purchaseOrderMainService.updatePurchaseOrderMain(purchaseOrderMain);
PurchaseOrderMain newPurchaseOrderMain = purchaseOrderMainService.selectPurchaseOrderMainById(purchaseOrderMain.getId());
//发起审批
PurchaseOrderForm purchaseOrderForm=new PurchaseOrderForm();
BeanUtils.copyProperties(newPurchaseOrderMain,purchaseOrderForm);
purchaseOrderForm.setBusinessKey(purchaseOrderMain.getOrderNo());
purchaseOrderForm.setStartUserId(String.valueOf(sysUser.getUserId()));
// purchaseOrderForm.setBusVarJson(JSON.toJSONString(purchaseOrderForm));
// purchaseOrderForm.setClassPackName(PurchaseOrderForm.class.getCanonicalName());
purchaseOrderForm.setBusVarUrl("/system/purchaseOrder/detail");
ProcessInstance processInstance = flowableService.startProcessInstanceByAppForm(purchaseOrderForm);
//推进任务节点
flowableTaskService.automaticTask(processInstance.getProcessInstanceId());
return toAjax(i);
}
/**
* 删除采购单主表
*/
@RequiresPermissions("system:purchaseOrder:remove")
@Log(title = "采购单主表", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(purchaseOrderMainService.deletePurchaseOrderMainByIds(ids));
}
/**
* 详情页
*/
@GetMapping("/detail/{id}")
public String detail(@PathVariable("id") Integer id, ModelMap mmap)
{
PurchaseOrderMain purchaseOrderMain = purchaseOrderMainService.selectPurchaseOrderMainById(id);
mmap.put("purchaseOrder", purchaseOrderMain);
return prefix + "/detail";
}
/**
* 重新申请
*/
@PostMapping("/restart")
@ResponseBody
@Transactional
@RepeatSubmit
public AjaxResult restart(PurchaseOrderMainTask purchaseOrderMainTask)
{
SysUser sysUser = ShiroUtils.getSysUser();
purchaseOrderMainTask.setUpdateBy(String.valueOf(sysUser.getUserId()));
PurchaseOrderMain purchaseOrderMain=new PurchaseOrderMain();
BeanUtils.copyProperties(purchaseOrderMainTask,purchaseOrderMain);
int i = purchaseOrderMainService.updatePurchaseOrderMain(purchaseOrderMain);
CompleteTaskDTO completeTaskDTO=new CompleteTaskDTO();
completeTaskDTO.setUserId(String.valueOf(sysUser.getUserId()));
completeTaskDTO.setComment(purchaseOrderMainTask.getComment());
completeTaskDTO.setIsStart(purchaseOrderMainTask.getIsStart());
completeTaskDTO.setFiles(purchaseOrderMainTask.getFiles());
completeTaskDTO.setTaskId(purchaseOrderMainTask.getTaskId());
flowableService.completeTask(completeTaskDTO);
return toAjax(i);
}
}

View File

@ -0,0 +1,126 @@
package com.snow.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.snow.common.annotation.Log;
import com.snow.common.enums.BusinessType;
import org.springframework.stereotype.Controller;
import com.snow.system.domain.SysFile;
import com.snow.system.service.ISysFileService;
import com.snow.common.core.controller.BaseController;
import com.snow.common.core.domain.AjaxResult;
import com.snow.common.utils.poi.ExcelUtil;
import com.snow.common.core.page.TableDataInfo;
/**
* 文件存储Controller
*
* @author snow
* @date 2021-01-11
*/
@Controller
@RequestMapping("/system/file")
public class SysFileController extends BaseController
{
private String prefix = "system/file";
@Autowired
private ISysFileService sysFileService;
@RequiresPermissions("system:file:view")
@GetMapping()
public String file()
{
return prefix + "/file";
}
/**
* 查询文件存储列表
*/
@RequiresPermissions("system:file:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysFile sysFile)
{
startPage();
List<SysFile> list = sysFileService.selectSysFileList(sysFile);
return getDataTable(list);
}
/**
* 导出文件存储列表
*/
@RequiresPermissions("system:file:export")
@Log(title = "文件存储", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysFile sysFile)
{
List<SysFile> list = sysFileService.selectSysFileList(sysFile);
ExcelUtil<SysFile> util = new ExcelUtil<SysFile>(SysFile.class);
return util.exportExcel(list, "file");
}
/**
* 新增文件存储
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存文件存储
*/
@RequiresPermissions("system:file:add")
@Log(title = "文件存储", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SysFile sysFile)
{
return toAjax(sysFileService.insertSysFile(sysFile));
}
/**
* 修改文件存储
*/
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
SysFile sysFile = sysFileService.selectSysFileById(id);
mmap.put("sysFile", sysFile);
return prefix + "/edit";
}
/**
* 修改保存文件存储
*/
@RequiresPermissions("system:file:edit")
@Log(title = "文件存储", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysFile sysFile)
{
return toAjax(sysFileService.updateSysFile(sysFile));
}
/**
* 删除文件存储
*/
@RequiresPermissions("system:file:remove")
@Log(title = "文件存储", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(sysFileService.deleteSysFileByIds(ids));
}
}

View File

@ -1,6 +1,16 @@
package com.snow.web.controller.system;
import java.util.Date;
import java.util.List;
import com.snow.common.constant.ShiroConstants;
import com.snow.common.core.domain.AjaxResult;
import com.snow.common.core.text.Convert;
import com.snow.common.utils.CookieUtils;
import com.snow.common.utils.DateUtils;
import com.snow.common.utils.ServletUtils;
import com.snow.common.utils.StringUtils;
import com.snow.framework.shiro.service.SysPasswordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
@ -12,6 +22,12 @@ import com.snow.system.domain.SysMenu;
import com.snow.system.domain.SysUser;
import com.snow.system.service.ISysConfigService;
import com.snow.system.service.ISysMenuService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
/**
* 首页 业务处理
@ -27,10 +43,16 @@ public class SysIndexController extends BaseController
@Autowired
private ISysConfigService configService;
@Autowired
private SysPasswordService passwordService;
// 系统首页
@GetMapping("/index")
public String index(ModelMap mmap)
{
// 取身份信息
SysUser user = ShiroUtils.getSysUser();
// 根据用户id取出菜单
@ -39,23 +61,104 @@ public class SysIndexController extends BaseController
mmap.put("user", user);
mmap.put("sideTheme", configService.selectConfigByKey("sys.index.sideTheme"));
mmap.put("skinName", configService.selectConfigByKey("sys.index.skinName"));
mmap.put("ignoreFooter", configService.selectConfigByKey("sys.index.ignoreFooter"));
mmap.put("copyrightYear", Global.getCopyrightYear());
mmap.put("demoEnabled", Global.isDemoEnabled());
return "index";
mmap.put("demoEnabled", Global.isDemoEnabled());
mmap.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate()));
mmap.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate()));
// 菜单导航显示风格
String menuStyle = configService.selectConfigByKey("sys.index.menuStyle");
// 移动端默认使左侧导航菜单否则取默认配置
String indexStyle = ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")) ? "index" : menuStyle;
// 优先Cookie配置导航菜单
Cookie[] cookies = ServletUtils.getRequest().getCookies();
for (Cookie cookie : cookies)
{
if (StringUtils.isNotEmpty(cookie.getName()) && "nav-style".equalsIgnoreCase(cookie.getName()))
{
indexStyle = cookie.getValue();
break;
}
}
String webIndex = "topnav".equalsIgnoreCase(indexStyle) ? "index-topnav" : "index";
return webIndex;
}
// 切换主题
@GetMapping("/system/switchSkin")
public String switchSkin(ModelMap mmap)
{
return "skin";
}
// 系统介绍
@GetMapping("/system/main")
public String main(ModelMap mmap)
{
mmap.put("version", Global.getVersion());
return "main";
return "main_v1";
}
// 锁定屏幕
@GetMapping("/lockscreen")
public String lockscreen(ModelMap mmap)
{
mmap.put("user", ShiroUtils.getSysUser());
ServletUtils.getSession().setAttribute(ShiroConstants.LOCK_SCREEN, true);
return "lock";
}
// 解锁屏幕
@PostMapping("/unlockscreen")
@ResponseBody
public AjaxResult unlockscreen(String password)
{
SysUser user = ShiroUtils.getSysUser();
if (StringUtils.isNull(user))
{
return AjaxResult.error("服务器超时,请重新登陆");
}
if (passwordService.matches(user, password))
{
ServletUtils.getSession().removeAttribute(ShiroConstants.LOCK_SCREEN);
return AjaxResult.success();
}
return AjaxResult.error("密码不正确,请重新输入。");
}
// 切换主题
@GetMapping("/system/switchSkin")
public String switchSkin()
{
return "skin";
}
// 切换菜单
@GetMapping("/system/menuStyle/{style}")
public void menuStyle(@PathVariable String style, HttpServletResponse response)
{
CookieUtils.setCookie(response, "nav-style", style);
}
// 检查初始密码是否提醒修改
public boolean initPasswordIsModify(Date pwdUpdateDate)
{
Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify"));
return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null;
}
// 检查密码是否过期
public boolean passwordIsExpiration(Date pwdUpdateDate)
{
Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays"));
if (passwordValidateDays != null && passwordValidateDays > 0)
{
if (StringUtils.isNull(pwdUpdateDate))
{
// 如果从未修改过初始密码直接提醒过期
return true;
}
Date nowDate = DateUtils.getNowDate();
return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays;
}
return false;
}
}

View File

@ -0,0 +1,269 @@
package com.snow.web.controller.system;
import java.util.Date;
import java.util.List;
import java.util.Map;
import cn.hutool.core.date.BetweenFormater;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.snow.common.constant.SequenceContants;
import com.snow.common.enums.WorkRecordStatus;
import com.snow.common.utils.StringUtils;
import com.snow.flowable.common.constants.FlowConstants;
import com.snow.flowable.domain.*;
import com.snow.flowable.domain.leave.LeaveFinishTaskDTO;
import com.snow.flowable.domain.leave.LeaveRestartTaskDTO;
import com.snow.flowable.domain.leave.SysOaLeaveForm;
import com.snow.flowable.service.AppFormService;
import com.snow.flowable.service.FlowableTaskService;
import com.snow.flowable.service.impl.FlowableServiceImpl;
import com.snow.framework.util.ShiroUtils;
import com.snow.system.domain.SysUser;
import com.snow.system.service.ISysSequenceService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.snow.common.annotation.Log;
import com.snow.common.enums.BusinessType;
import com.snow.system.domain.SysOaLeave;
import com.snow.system.service.ISysOaLeaveService;
import com.snow.common.core.controller.BaseController;
import com.snow.common.core.domain.AjaxResult;
import com.snow.common.utils.poi.ExcelUtil;
import com.snow.common.core.page.TableDataInfo;
/**
* 请假单Controller
*
* @author snow
* @date 2020-11-22
*/
@Controller
@RequestMapping("/system/leave")
public class SysOaLeaveController extends BaseController
{
private String prefix = "system/leave";
@Autowired
private ISysOaLeaveService sysOaLeaveService;
@Autowired
private FlowableServiceImpl flowableService;
@Autowired
private ISysSequenceService sequenceService;
@Autowired
private FlowableTaskService flowableTaskService;
@RequiresPermissions("system:leave:view")
@GetMapping()
public String leave()
{
return prefix + "/leave";
}
/**
* 查询请假单列表
*/
@RequiresPermissions("system:leave:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysOaLeave sysOaLeave)
{
startPage();
SysUser sysUser = ShiroUtils.getSysUser();
sysOaLeave.setCreateBy(sysUser.getUserName());
//管理员权限判断
if(!ShiroUtils.getSysUser().isAdmin()){
sysOaLeave.setCreateBy(String.valueOf(sysUser.getUserId()));
}
List<SysOaLeave> list = sysOaLeaveService.selectSysOaLeaveList(sysOaLeave);
return getDataTable(list);
}
/**
* 导出请假单列表
*/
@RequiresPermissions("system:leave:export")
@Log(title = "请假单", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysOaLeave sysOaLeave)
{
List<SysOaLeave> list = sysOaLeaveService.selectSysOaLeaveList(sysOaLeave);
ExcelUtil<SysOaLeave> util = new ExcelUtil<SysOaLeave>(SysOaLeave.class);
return util.exportExcel(list, "leave");
}
/**
* 新增请假单
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 1.填写请假单 可修改
*/
@RequiresPermissions("system:leave:add")
@Log(title = "请假单", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
@Transactional(rollbackFor = Exception.class)
public AjaxResult addSave(SysOaLeave sysOaLeave)
{
SysUser sysUser = ShiroUtils.getSysUser();
Date endTime = sysOaLeave.getEndTime();
Date startTime = sysOaLeave.getStartTime();
int compare = DateUtil.compare(startTime, endTime);
if(compare==1||compare==0){
return AjaxResult.error("请假结束时间必须大于开始时间");
}
//生成请假单
String leaveNo = sequenceService.getNewSequenceNo(SequenceContants.OA_LEAVE_SEQUENCE);
sysOaLeave.setCreateBy(String.valueOf(sysUser.getUserId()));
sysOaLeave.setLeaveNo(leaveNo);
int i = sysOaLeaveService.insertSysOaLeave(sysOaLeave);
return toAjax(i);
}
/**
* 修改请假单
*/
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Integer id, ModelMap mmap)
{
SysOaLeave sysOaLeave = sysOaLeaveService.selectSysOaLeaveById(id);
String spendTime = DateUtil.formatBetween(sysOaLeave.getStartTime(), sysOaLeave.getEndTime(), BetweenFormater.Level.SECOND);
sysOaLeave.setLeaveTime(spendTime);
mmap.put("sysOaLeave", sysOaLeave);
return prefix + "/edit";
}
/**
* 修改保存并发起请假单
*/
@RequiresPermissions("system:leave:edit")
@Log(title = "请假单", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysOaLeave sysOaLeave)
{
SysUser sysUser = ShiroUtils.getSysUser();
sysOaLeave.setApplyPerson(sysUser.getUserName());
int i = sysOaLeaveService.updateSysOaLeave(sysOaLeave);
SysOaLeave newSysOaLeave = sysOaLeaveService.selectSysOaLeaveById(sysOaLeave.getId());
//发起审批
SysOaLeaveForm sysOaLeaveForm=new SysOaLeaveForm();
BeanUtils.copyProperties(sysOaLeave,sysOaLeaveForm);
sysOaLeaveForm.setBusinessKey(newSysOaLeave.getLeaveNo());
sysOaLeaveForm.setStartUserId(String.valueOf(sysUser.getUserId()));
sysOaLeaveForm.setBusVarUrl("/system/leave/detail");
ProcessInstance processInstance = flowableService.startProcessInstanceByAppForm(sysOaLeaveForm);
//提交
CompleteTaskDTO completeTaskDTO=new CompleteTaskDTO();
completeTaskDTO.setUserId(String.valueOf(sysUser.getUserId()));
Task task= flowableService.getTaskProcessInstanceById(processInstance.getProcessInstanceId());
completeTaskDTO.setTaskId(task.getId());
completeTaskDTO.setIsPass(true);
flowableService.completeTask(completeTaskDTO);
return toAjax(i);
}
/**
* 请假单详情
*/
@RequiresPermissions("system:leave:detail")
@GetMapping("/detail/{id}")
public String detail(@PathVariable("id") Integer id, ModelMap mmap)
{
SysOaLeave sysOaLeave = sysOaLeaveService.selectSysOaLeaveById(id);
HistoricTaskInstanceDTO historicTaskInstanceDTO=new HistoricTaskInstanceDTO();
historicTaskInstanceDTO.setBusinessKey(sysOaLeave.getLeaveNo());
historicTaskInstanceDTO.setProcessInstanceId(sysOaLeave.getProcessInstanceId());
historicTaskInstanceDTO.setProcessStatus(WorkRecordStatus.FINISHED);
List<HistoricTaskInstanceVO> historicTaskInstanceList= flowableService.getHistoricTaskInstanceNoPage(historicTaskInstanceDTO);
String spendTime = DateUtil.formatBetween(sysOaLeave.getStartTime(), sysOaLeave.getEndTime(), BetweenFormater.Level.SECOND);
sysOaLeave.setLeaveTime(spendTime);
mmap.put("sysOaLeave", sysOaLeave);
mmap.put("historicTaskInstanceList", historicTaskInstanceList);
return prefix + "/detail";
}
/**
* 删除请假单
*/
@RequiresPermissions("system:leave:remove")
@Log(title = "请假单", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(sysOaLeaveService.deleteSysOaLeaveByIds(ids));
}
@Log(title = "主管完成审批", businessType = BusinessType.OTHER)
@PostMapping("/managerFinishTask")
@ResponseBody
@Transactional(rollbackFor = Exception.class)
public AjaxResult managerFinishTask(LeaveFinishTaskDTO finishTaskDTO)
{
SysUser sysUser = ShiroUtils.getSysUser();
finishTaskDTO.setUserId(String.valueOf(sysUser.getUserId()));
finishTaskDTO.setHr("2");
flowableTaskService.submitTask(finishTaskDTO);
return AjaxResult.success();
}
/**
* hr完成审批
*/
@Log(title = "hr完成审批", businessType = BusinessType.OTHER)
@PostMapping("/hrFinishTask")
@ResponseBody
@Transactional(rollbackFor = Exception.class)
public AjaxResult hrFinishTask(LeaveFinishTaskDTO finishTaskDTO)
{
SysUser sysUser = ShiroUtils.getSysUser();
finishTaskDTO.setUserId(String.valueOf(sysUser.getUserId()));
flowableTaskService.submitTask(finishTaskDTO);
return AjaxResult.success();
}
/**
* 重新发起申请
*/
@Log(title = "重新发起申请", businessType = BusinessType.OTHER)
@PostMapping("/reStartTask")
@ResponseBody
@Transactional
public AjaxResult reStartTask(LeaveRestartTaskDTO finishTaskDTO)
{
SysUser sysUser = ShiroUtils.getSysUser();
SysOaLeave sysOaLeave=new SysOaLeave();
BeanUtils.copyProperties(finishTaskDTO,sysOaLeave);
sysOaLeave.setUpdateBy(sysUser.getUserName());
int i = sysOaLeaveService.updateSysOaLeave(sysOaLeave);
finishTaskDTO.setUserId(String.valueOf(sysUser.getUserId()));
flowableTaskService.submitTask(finishTaskDTO);
return AjaxResult.success();
}
}

View File

@ -1,6 +1,9 @@
package com.snow.web.controller.system;
import java.util.List;
import com.snow.common.core.domain.Ztree;
import com.snow.common.utils.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@ -52,11 +55,12 @@ public class SysRoleController extends BaseController
@RequiresPermissions("system:role:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysRole role)
public List<SysRole> list(SysRole role)
{
startPage();
role.setRoleType(UserConstants.SYSTEM_ROLE_TYPE);
List<SysRole> list = roleService.selectRoleList(role);
return getDataTable(list);
return list;
}
@Log(title = "角色管理", businessType = BusinessType.EXPORT)
@ -98,6 +102,7 @@ public class SysRoleController extends BaseController
}
role.setCreateBy(ShiroUtils.getLoginName());
ShiroUtils.clearCachedAuthorizationInfo();
role.setParentId(0L);
return toAjax(roleService.insertRole(role));
}
@ -301,4 +306,29 @@ public class SysRoleController extends BaseController
{
return toAjax(roleService.insertAuthUsers(roleId, userIds));
}
/**
* 选择角色信息树
*/
@GetMapping(value = { "/selectRoleTree/{roleId}"})
public String selectRoleTree(@PathVariable(value = "roleId", required = false) Long roleId, ModelMap mmap)
{
if (StringUtils.isNotNull(roleId))
{
mmap.put("sysRole", roleService.selectRoleById(roleId));
}
return prefix + "/tree";
}
/**
* 加载角色信息树列表
*/
@GetMapping("/treeData")
@ResponseBody
public List<Ztree> treeData()
{
List<Ztree> ztrees = roleService.selectSysRoleTree();
return ztrees;
}
}

View File

@ -0,0 +1,126 @@
package com.snow.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.snow.common.annotation.Log;
import com.snow.common.enums.BusinessType;
import org.springframework.stereotype.Controller;
import com.snow.system.domain.SysSequence;
import com.snow.system.service.ISysSequenceService;
import com.snow.common.core.controller.BaseController;
import com.snow.common.core.domain.AjaxResult;
import com.snow.common.utils.poi.ExcelUtil;
import com.snow.common.core.page.TableDataInfo;
/**
* 系统序列设置Controller
*
* @author snow
* @date 2020-11-23
*/
@Controller
@RequestMapping("/system/sequence")
public class SysSequenceController extends BaseController
{
private String prefix = "system/sequence";
@Autowired
private ISysSequenceService sysSequenceService;
@RequiresPermissions("system:sequence:view")
@GetMapping()
public String sequence()
{
return prefix + "/sequence";
}
/**
* 查询系统序列设置列表
*/
@RequiresPermissions("system:sequence:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysSequence sysSequence)
{
startPage();
List<SysSequence> list = sysSequenceService.selectSysSequenceList(sysSequence);
return getDataTable(list);
}
/**
* 导出系统序列设置列表
*/
@RequiresPermissions("system:sequence:export")
@Log(title = "系统序列设置", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysSequence sysSequence)
{
List<SysSequence> list = sysSequenceService.selectSysSequenceList(sysSequence);
ExcelUtil<SysSequence> util = new ExcelUtil<SysSequence>(SysSequence.class);
return util.exportExcel(list, "sequence");
}
/**
* 新增系统序列设置
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存系统序列设置
*/
@RequiresPermissions("system:sequence:add")
@Log(title = "系统序列设置", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SysSequence sysSequence)
{
return toAjax(sysSequenceService.insertSysSequence(sysSequence));
}
/**
* 修改系统序列设置
*/
@GetMapping("/edit/{name}")
public String edit(@PathVariable("name") String name, ModelMap mmap)
{
SysSequence sysSequence = sysSequenceService.selectSysSequenceById(name);
mmap.put("sysSequence", sysSequence);
return prefix + "/edit";
}
/**
* 修改保存系统序列设置
*/
@RequiresPermissions("system:sequence:edit")
@Log(title = "系统序列设置", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysSequence sysSequence)
{
return toAjax(sysSequenceService.updateSysSequence(sysSequence));
}
/**
* 删除系统序列设置
*/
@RequiresPermissions("system:sequence:remove")
@Log(title = "系统序列设置", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(sysSequenceService.deleteSysSequenceByIds(ids));
}
}

View File

@ -0,0 +1,134 @@
package com.snow.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.snow.common.annotation.Log;
import com.snow.common.enums.BusinessType;
import com.snow.system.domain.SysDingtalkSyncLog;
import com.snow.system.service.ISysDingtalkSyncLogService;
import com.snow.common.core.controller.BaseController;
import com.snow.common.core.domain.AjaxResult;
import com.snow.common.utils.poi.ExcelUtil;
import com.snow.common.core.page.TableDataInfo;
/**
* 钉钉同步日志记录Controller
*
* @author snow
* @date 2020-11-13
*/
@Controller
@RequestMapping("/system/log")
public class SysSyncLogController extends BaseController
{
private String prefix = "system/log";
@Autowired
private ISysDingtalkSyncLogService sysDingtalkSyncLogService;
@RequiresPermissions("system:log:view")
@GetMapping()
public String log()
{
return prefix + "/log";
}
/**
* 查询钉钉同步日志记录列表
*/
@RequiresPermissions("system:log:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysDingtalkSyncLog sysDingtalkSyncLog)
{
startPage();
List<SysDingtalkSyncLog> list = sysDingtalkSyncLogService.selectSysDingtalkSyncLogList(sysDingtalkSyncLog);
return getDataTable(list);
}
/**
* 导出钉钉同步日志记录列表
*/
@RequiresPermissions("system:log:export")
@Log(title = "钉钉同步日志记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysDingtalkSyncLog sysDingtalkSyncLog)
{
List<SysDingtalkSyncLog> list = sysDingtalkSyncLogService.selectSysDingtalkSyncLogList(sysDingtalkSyncLog);
ExcelUtil<SysDingtalkSyncLog> util = new ExcelUtil<SysDingtalkSyncLog>(SysDingtalkSyncLog.class);
return util.exportExcel(list, "log");
}
/**
* 新增钉钉同步日志记录
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存钉钉同步日志记录
*/
@RequiresPermissions("system:log:add")
@Log(title = "钉钉同步日志记录", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SysDingtalkSyncLog sysDingtalkSyncLog)
{
return toAjax(sysDingtalkSyncLogService.insertSysDingtalkSyncLog(sysDingtalkSyncLog));
}
/**
* 修改钉钉同步日志记录
*/
@GetMapping("/edit/{logId}")
public String edit(@PathVariable("logId") Long logId, ModelMap mmap)
{
SysDingtalkSyncLog sysDingtalkSyncLog = sysDingtalkSyncLogService.selectSysDingtalkSyncLogById(logId);
mmap.put("sysDingtalkSyncLog", sysDingtalkSyncLog);
return prefix + "/edit";
}
/**
* 修改保存钉钉同步日志记录
*/
@RequiresPermissions("system:log:edit")
@Log(title = "钉钉同步日志记录", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysDingtalkSyncLog sysDingtalkSyncLog)
{
return toAjax(sysDingtalkSyncLogService.updateSysDingtalkSyncLog(sysDingtalkSyncLog));
}
/**
* 删除钉钉同步日志记录
*/
@RequiresPermissions("system:log:remove")
@Log(title = "钉钉同步日志记录", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(sysDingtalkSyncLogService.deleteSysDingtalkSyncLogByIds(ids));
}
@RequiresPermissions("system:log:detail")
@GetMapping("/detail/{operId}")
public String detail(@PathVariable("operId") Long operId, ModelMap mmap)
{
mmap.put("operLog", sysDingtalkSyncLogService.selectSysDingtalkSyncLogById(operId));
return prefix + "/detail";
}
}

View File

@ -2,6 +2,8 @@ package com.snow.web.controller.system;
import java.util.List;
import java.util.stream.Collectors;
import com.snow.system.service.impl.SysSequenceServiceImpl;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@ -51,6 +53,9 @@ public class SysUserController extends BaseController
@Autowired
private SysPasswordService passwordService;
@Autowired
private SysSequenceServiceImpl sysSequenceService;
@RequiresPermissions("system:user:view")
@GetMapping()
public String user()
@ -107,7 +112,10 @@ public class SysUserController extends BaseController
@GetMapping("/add")
public String add(ModelMap mmap)
{
mmap.put("roles", roleService.selectRoleAll().stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
String jobNumber = sysSequenceService.getNewSequenceNo("SNOW");
mmap.put("jobNumber",jobNumber);
mmap.put("roles", roleService.selectRoleAll().stream().filter(r -> !r.isAdmin()&&r.getRoleType()==UserConstants.SYSTEM_ROLE_TYPE).collect(Collectors.toList()));
mmap.put("posts", postService.selectPostAll());
return prefix + "/add";
}
@ -288,4 +296,13 @@ public class SysUserController extends BaseController
userService.checkUserAllowed(user);
return toAjax(userService.changeStatus(user));
}
@PostMapping("/getUserInfoById")
@ResponseBody
public AjaxResult getUserInfoById(Long id)
{
SysUser sysUser = userService.selectUserById(id);
return AjaxResult.success(sysUser);
}
}

View File

@ -6,9 +6,9 @@ spring:
druid:
# 主库数据源
master:
url: jdbc:mysql://rm-bp1j1554xv1qs04295o.mysql.rds.aliyuncs.com:3306/ry?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: cloud_root
password: Jin!152377
url: jdbc:mysql://localhost:3306/snow?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: root
# 从库数据源
slave:
# 从数据源开关/默认关闭

View File

@ -1,5 +1,5 @@
# 项目相关配置
ruoyi:
snow:
# 名称
name: snow
# 版本
@ -54,7 +54,7 @@ spring:
basename: static/i18n/messages
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
profiles:
active: druid
# 文件上传
@ -75,10 +75,11 @@ mybatis:
# 搜索指定包别名
typeAliasesPackage: com.snow.**.domain
# 配置mapper的扫描找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/**/*Mapper.xml
mapperLocations: classpath*:META-INF/modeler-mybatis-mappings/*.xml,classpath*:mapper/**/*Mapper.xml
# 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml
# PageHelper分页插件
pagehelper:
helperDialect: mysql
@ -135,3 +136,28 @@ xss:
swagger:
# 是否开启swagger
enabled: true
flowable:
#关闭定时任务JOB
async-executor-activate: false
# 将databaseSchemaUpdate设置为true。当Flowable发现库与数据库表结构不一致时会自动将数据库表结构升级至新版本。
database-schema-update: true
common:
app:
idm-url: http://localhost:80
idm-admin:
user: admin
password: test
#上传文件的方式
sys:
file:
active: aliyun
log4j:
logger:
org:
flowable:
task:
service:
impl:
persistence:
entity: DEBUG

View File

@ -0,0 +1,9 @@
log4j.rootLogger=DEBUG, CA
# ConsoleAppender
log4j.appender.CA=org.apache.log4j.ConsoleAppender
log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n
#custom
log4j.logger.org.flowable.task.service.impl.persistence.entity=DEBUG

View File

@ -75,7 +75,9 @@
<logger name="com.snow" level="info" />
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" />
<logger name="org.flowable.task.service.impl.persistence.entity" level="DEBUG" />
<logger name="org.flowable.db.mapping.entity" level="DEBUG" />
<logger name="org.flowable.engine.impl.persistence.entity" level="DEBUG" />
<root level="info">
<appender-ref ref="console" />
</root>

View File

@ -3,7 +3,12 @@
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties>
<property name="prefix" value="" />
<property name="blobType" value="BLOB" />
</properties>
<settings>
<setting name="cacheEnabled" value="true" /> <!-- 全局映射器启用缓存 -->
<setting name="useGeneratedKeys" value="true" /> <!-- 允许 JDBC 支持自动生成主键 -->
@ -11,5 +16,5 @@ PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
<setting name="logImpl" value="SLF4J" /> <!-- 指定 MyBatis 所用日志的具体实现 -->
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> 驼峰式命名 -->
</settings>
</configuration>

View File

@ -399,14 +399,14 @@
var result = [];
var key;
for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
// Don't enum bug & hidden keys
// Don't enums bug & hidden keys
while (names.length > i) if (has(O, key = names[i++])) {
~indexOf(result, key) || result.push(key);
}
return result;
};
// IE8- don't enum bug keys
// IE8- don't enums bug keys
var enumBugKeys = [
'constructor',
'hasOwnProperty',

View File

@ -399,14 +399,14 @@
var result = [];
var key;
for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
// Don't enum bug & hidden keys
// Don't enums bug & hidden keys
while (names.length > i) if (has(O, key = names[i++])) {
~indexOf(result, key) || result.push(key);
}
return result;
};
// IE8- don't enum bug keys
// IE8- don't enums bug keys
var enumBugKeys = [
'constructor',
'hasOwnProperty',

View File

@ -399,14 +399,14 @@
var result = [];
var key;
for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
// Don't enum bug & hidden keys
// Don't enums bug & hidden keys
while (names.length > i) if (has(O, key = names[i++])) {
~indexOf(result, key) || result.push(key);
}
return result;
};
// IE8- don't enum bug keys
// IE8- don't enums bug keys
var enumBugKeys = [
'constructor',
'hasOwnProperty',

View File

@ -399,14 +399,14 @@
var result = [];
var key;
for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
// Don't enum bug & hidden keys
// Don't enums bug & hidden keys
while (names.length > i) if (has(O, key = names[i++])) {
~indexOf(result, key) || result.push(key);
}
return result;
};
// IE8- don't enum bug keys
// IE8- don't enums bug keys
var enumBugKeys = [
'constructor',
'hasOwnProperty',

View File

@ -399,12 +399,12 @@ function getUniqueId(wizard)
}
/**
* Gets a valid enum value by checking a specific enum key or value.
* Gets a valid enums value by checking a specific enums key or value.
*
* @static
* @private
* @method getValidEnumValue
* @param enumType {Object} Type of enum
* @param enumType {Object} Type of enums
* @param keyOrValue {Object} Key as `String` or value as `Integer` to check for
*/
function getValidEnumValue(enumType, keyOrValue)
@ -418,7 +418,7 @@ function getValidEnumValue(enumType, keyOrValue)
var value = enumType[keyOrValue];
if (value === undefined)
{
throwError("The enum key '{0}' does not exist.", keyOrValue);
throwError("The enums key '{0}' does not exist.", keyOrValue);
}
return value;
@ -434,7 +434,7 @@ function getValidEnumValue(enumType, keyOrValue)
}
}
throwError("Invalid enum value '{0}'.", keyOrValue);
throwError("Invalid enums value '{0}'.", keyOrValue);
}
// Type is not supported
else
@ -1475,7 +1475,7 @@ $.fn.steps.skip = function (count)
};
/**
* An enum represents the different content types of a step and their loading mechanisms.
* An enums represents the different content types of a step and their loading mechanisms.
*
* @class contentMode
* @for steps
@ -1513,7 +1513,7 @@ var contentMode = $.fn.steps.contentMode = {
};
/**
* An enum represents the orientation of the steps navigation.
* An enums represents the orientation of the steps navigation.
*
* @class stepsOrientation
* @for steps
@ -1541,7 +1541,7 @@ var stepsOrientation = $.fn.steps.stepsOrientation = {
};
/**
* An enum that represents the various transition animations.
* An enums that represents the various transition animations.
*
* @class transitionEffect
* @for steps

File diff suppressed because one or more lines are too long

View File

@ -3523,8 +3523,8 @@
/**
* @class Create a virtual table to create what actions to do in change.
* @param {object} startPoint Cell selected to apply change.
* @param {enum} where Where change will be applied Row or Col. Use enum: TableResultAction.where
* @param {enum} action Action to be applied. Use enum: TableResultAction.requestAction
* @param {enums} where Where change will be applied Row or Col. Use enums: TableResultAction.where
* @param {enums} action Action to be applied. Use enums: TableResultAction.requestAction
* @param {object} domTable Dom element of table to make changes.
*/
var TableResultAction = function (startPoint, where, action, domTable) {
@ -3760,17 +3760,17 @@
};
/**
*
* Where action occours enum.
* Where action occours enums.
*/
TableResultAction.where = { 'Row': 0, 'Column': 1 };
/**
*
* Requested action to apply enum.
* Requested action to apply enums.
*/
TableResultAction.requestAction = { 'Add': 0, 'Delete': 1 };
/**
*
* Result action to be executed enum.
* Result action to be executed enums.
*/
TableResultAction.resultAction = { 'Ignore': 0, 'SubtractSpanCount': 1, 'RemoveCell': 2, 'AddCell': 3, 'SumSpanCount': 4 };
/**

View File

@ -1 +1 @@
html{height:100%}body.signin{height:auto;background:url(../img/login-background.jpg) no-repeat center fixed;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;color:rgba(255,255,255,.95)}.signinpanel{width:750px;margin:10% auto 0}.signinpanel .logopanel{float:none;width:auto;padding:0;background:0}.signinpanel .signin-info ul{list-style:none;padding:0;margin:20px 0}.signinpanel .form-control{display:block;margin-top:15px}.signinpanel .uname{background:#fff url(../img/user.png) no-repeat 95% center;color:#333}.signinpanel .pword{background:#fff url(../img/locked.png) no-repeat 95% center;color:#333}.signinpanel .code{background:#fff no-repeat 95% center;color:#333;margin:0 0 15px 0}.signinpanel .btn{margin-top:15px}.signinpanel form{background:rgba(255,255,255,.2);border:1px solid rgba(255,255,255,.3);-moz-box-shadow:0 3px 0 rgba(12,12,12,.03);-webkit-box-shadow:0 3px 0 rgba(12,12,12,.03);box-shadow:0 3px 0 rgba(12,12,12,.03);-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;padding:30px}.signup-footer{border-top:solid 1px rgba(255,255,255,.3);margin:20px 0;padding-top:15px}@media screen and (max-width:768px){.signinpanel,.signuppanel{margin:0 auto;width:420px!important;padding:20px}.signinpanel form{margin-top:20px}.signup-footer,.signuppanel .form-control{margin-bottom:10px}.signup-footer .pull-left,.signup-footer .pull-right{float:none!important;text-align:center}.signinpanel .signin-info ul{display:none}}@media screen and (max-width:320px){.signinpanel,.signuppanel{margin:0 20px;width:auto}}.checkbox-custom{position:relative;padding:0 15px 0 25px;margin-bottom:7px;display:inline-block}.checkbox-custom input[type="checkbox"]{opacity:0;position:absolute;cursor:pointer;z-index:2;margin:-6px 0 0 0;top:50%;left:3px}.checkbox-custom label:before{content:'';position:absolute;top:50%;left:0;margin-top:-9px;width:18px;height:17px;display:inline-block;border-radius:2px;border:1px solid #bbb;background:#fff}.checkbox-custom input[type="checkbox"]:checked+label:after{position:absolute;display:inline-block;font-family:'Glyphicons Halflings';content:"\e013";top:42%;left:3px;margin-top:-5px;font-size:11px;line-height:1;width:16px;height:16px;color:#333}.checkbox-custom label{cursor:pointer;line-height:1.2;font-weight:normal;margin-bottom:0;text-align:left}.form-control,.form-control:focus,.has-error .form-control:focus,.has-success .form-control:focus,.has-warning .form-control:focus,.navbar-collapse,.navbar-form,.navbar-form-custom .form-control:focus,.navbar-form-custom .form-control:hover,.open .btn.dropdown-toggle,.panel,.popover,.progress,.progress-bar{box-shadow:none}.form-control{border-radius:1px!important;padding:6px 12px!important;height:34px!important}.form-control:focus{border-color:#1ab394!important}
html{height:100%}body.signin{height:auto;background:url(../img/login_b.jpg) no-repeat center fixed;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;color:rgba(255,255,255,.95)}.signinpanel{width:850px;margin:10% auto 0}.signinpanel .logopanel{float:none;width:auto;padding:0;background:0}.signinpanel .signin-info ul{list-style:none;padding:0;margin:20px 0}.signinpanel .form-control{display:block;margin-top:15px}.signinpanel .uname{background:#fff url(../img/user.png) no-repeat 95% center;color:#333}.signinpanel .pword{background:#fff url(../img/locked.png) no-repeat 95% center;color:#333}.signinpanel .code{background:#fff no-repeat 95% center;color:#333;margin:0 0 15px 0}.signinpanel .btn{margin-top:15px}.signinpanel form{background:rgba(255,255,255,.2);border:1px solid rgba(255,255,255,.3);-moz-box-shadow:0 3px 0 rgba(12,12,12,.03);-webkit-box-shadow:0 3px 0 rgba(12,12,12,.03);box-shadow:0 3px 0 rgba(12,12,12,.03);-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;padding:30px}.signup-footer{border-top:solid 1px rgba(255,255,255,.3);margin:20px 0;padding-top:15px}@media screen and (max-width:768px){.signinpanel,.signuppanel{margin:0 auto;width:420px!important;padding:20px}.signinpanel form{margin-top:20px}.signup-footer,.signuppanel .form-control{margin-bottom:10px}.signup-footer .pull-left,.signup-footer .pull-right{float:none!important;text-align:center}.signinpanel .signin-info ul{display:none}}@media screen and (max-width:320px){.signinpanel,.signuppanel{margin:0 20px;width:auto}}.checkbox-custom{position:relative;padding:0 15px 0 25px;margin-bottom:7px;display:inline-block}.checkbox-custom input[type="checkbox"]{opacity:0;position:absolute;cursor:pointer;z-index:2;margin:-6px 0 0 0;top:50%;left:3px}.checkbox-custom label:before{content:'';position:absolute;top:50%;left:0;margin-top:-9px;width:18px;height:17px;display:inline-block;border-radius:2px;border:1px solid #bbb;background:#fff}.checkbox-custom input[type="checkbox"]:checked+label:after{position:absolute;display:inline-block;font-family:'Glyphicons Halflings';content:"\e013";top:42%;left:3px;margin-top:-5px;font-size:11px;line-height:1;width:16px;height:16px;color:#333}.checkbox-custom label{cursor:pointer;line-height:1.2;font-weight:normal;margin-bottom:0;text-align:left}.form-control,.form-control:focus,.has-error .form-control:focus,.has-success .form-control:focus,.has-warning .form-control:focus,.navbar-collapse,.navbar-form,.navbar-form-custom .form-control:focus,.navbar-form-custom .form-control:hover,.open .btn.dropdown-toggle,.panel,.popover,.progress,.progress-bar{box-shadow:none}.form-control{border-radius:1px!important;padding:6px 12px!important;height:34px!important}.form-control:focus{border-color:#1ab394!important}

View File

@ -46,18 +46,18 @@ a:focus {
/*white-space: nowrap;*/
}
.nav.navbar-right>li>a {
.nav.navbar-right>li>a, .nav.navbar-left>li>a {
color: #fff;
font-size: 14px;
height: 50px;
padding: 18px 15px;
padding: 15px 15px;
}
.nav>li.active>a {
color: #ffffff;
}
.nav.navbar-right>li>a>.label {
.nav.navbar-right>li>a>.label, .nav.navbar-left>li>a>.label {
position: absolute;
top: 9px;
right: 5px;
@ -66,7 +66,7 @@ a:focus {
padding: 2px 4px;
line-height: .9;
}
.nav.navbar-right>li>a:hover {
.nav.navbar-right>li>a:hover, .nav.navbar-left>li>a:hover {
background-color: #367fa9;
color: #fff;
}
@ -280,6 +280,8 @@ body.body-small .navbar-top-links li:last-child {
.nav-second-level li, .nav-third-level li {
border-bottom: none !important;
padding-left: 2px;
padding-right: 2px;
}
.nav-second-level li a {
@ -288,7 +290,7 @@ body.body-small .navbar-top-links li:last-child {
}
.nav-third-level li a {
padding-left: 62px;
padding-left: 70px;
}
.nav-second-level li:last-child {
@ -307,6 +309,10 @@ body.mini-navbar .navbar-default .nav>li>.nav-second-level li a {
border-radius: 0 2px 2px 0;
}
body.mini-navbar .navbar-default .nav>li>.nav-third-level li a {
padding-left: 31px;
}
.fixed-nav .slimScrollDiv #side-menu {
padding-bottom: 60px;
position: relative;
@ -473,13 +479,12 @@ body.body-small.fixed-sidebar.mini-navbar .navbar-static-side {
border-left-width: 0;
}
/*伸缩菜单*/
/* 伸缩菜单 */
.fixed-sidebar.mini-navbar .nav li:hover>a> span.nav-label {
top: 0px;
padding: 10px 10px 10px 10px;
text-align: center;
background-color: #243747;
border-bottom: dashed 1px #fff;
}
.fixed-sidebar.mini-navbar .nav li:hover>.nav-second-level {
@ -495,6 +500,15 @@ body.body-small.fixed-sidebar.mini-navbar .navbar-static-side {
min-width: 140px;
border-radius: 2px;
}
.fixed-sidebar.mini-navbar .nav li.active:hover>.nav-second-level, .fixed-sidebar.mini-navbar .nav li.active:hover>a> span.nav-label {
left: 67px;
}
.fixed-sidebar.mini-navbar .nav .nav-second-level a> span, .fixed-sidebar.mini-navbar .nav .nav-third-level a> span {
display: inline-block;
}
/*伸缩菜单结束*/
body.fixed-sidebar.mini-navbar .navbar-default .nav>li>.nav-second-level li a {
@ -1161,6 +1175,8 @@ button.dim:active:before {
/* TOOLTIPS */
.tooltip-inner {
background-color: #2F4050;
word-break: break-all;
overflow-wrap: break-word;
}
.tooltip.top .tooltip-arrow {
@ -3254,7 +3270,7 @@ body.body-small .footer.fixed {
position: relative;
height: 39px;
background: #fafafa;
line-height: 38px;
line-height: 39px;
}
.content-tabs .roll-nav, .page-tabs-list {
@ -6873,7 +6889,7 @@ body.rtls .top-navigation .footer.fixed, body.rtls.top-navigation .footer.fixed
}
.navbar-header {
width: 10%;
/* width: 10%; */
height: 50px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -0,0 +1,77 @@
// -----------------------------------------------------------------------
// Eros Fratini - eros@recoding.it
// jqprint 0.3
//
// - 19/06/2009 - some new implementations, added Opera support
// - 11/05/2009 - first sketch
//
// Printing plug-in for jQuery, evolution of jPrintArea: http://plugins.jquery.com/project/jPrintArea
// requires jQuery 1.3.x
//
// Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
//------------------------------------------------------------------------
(function($) {
var opt;
$.fn.jqprint = function (options) {
opt = $.extend({}, $.fn.jqprint.defaults, options);
var $element = (this instanceof jQuery) ? this : $(this);
if (opt.operaSupport && $.browser.opera)
{
var tab = window.open("","jqPrint-preview");
tab.document.open();
var doc = tab.document;
}
else
{
var $iframe = $("<iframe />");
if (!opt.debug) { $iframe.css({ position: "absolute", width: "0px", height: "0px", left: "-600px", top: "-600px" }); }
$iframe.appendTo("body");
var doc = $iframe[0].contentWindow.document;
}
if (opt.importCSS)
{
if ($("link[media=print]").length > 0)
{
$("link[media=print]").each( function() {
doc.write("<link type='text/css' rel='stylesheet' href='" + $(this).attr("href") + "' media='print' />");
});
}
else
{
$("link").each( function() {
doc.write("<link type='text/css' rel='stylesheet' href='" + $(this).attr("href") + "' />");
});
}
}
if (opt.printContainer) { doc.write($element.outer()); }
else { $element.each( function() { doc.write($(this).html()); }); }
doc.close();
(opt.operaSupport && $.browser.opera ? tab : $iframe[0].contentWindow).focus();
setTimeout( function() { (opt.operaSupport && $.browser.opera ? tab : $iframe[0].contentWindow).print(); if (tab) { tab.close(); } }, 1000);
}
$.fn.jqprint.defaults = {
debug: false,
importCSS: true,
printContainer: true,
operaSupport: true
};
// Thanks to 9__, found at http://users.livejournal.com/9__/380664.html
jQuery.fn.outer = function() {
return $($('<div></div>').html(this.clone())).html();
}
})(jQuery);

View File

@ -0,0 +1 @@
(function(c,a,e){var b,d="resizeTabs",f={navSelector:".nav-tabs",itemSelector:">li",dropdownSelector:">.dropdown",dropdownItemSelector:"li",tabParentSelector:"",tabSelector:".tab-pane",activeClassName:"active",noNavClassName:".no-menu",fnCallback:""};b=function(j,i){var h=this.$tabs=e(j),k=this.options=e.extend(true,{},f,i),g=this.$nav=h.find(k.navSelector),l=this.$dropdown=g.find(k.dropdownSelector);this.$items=g.find(k.itemSelector).filter(function(){return !e(this).is(l)});this.$dropdownItems=l.find(k.dropdownItemSelector);if(k.tabParentSelector!==""){this.$tabPanel=e(k.tabParentSelector).find(k.tabSelector)}else{this.$tabPanel=h.find(k.tabSelector)}this.init()};b.prototype={init:function(){var j=this.itemsLenth=this.$items.length,h;if(j===0){throw"There should be some tags here "}if(this.$dropdown.length===0){this.flag=true;this.$nav.append('<li class="dropdown" role="presentation">'+'<a class="dropdown-toggle" data-toggle="dropdown" href="#" aria-expanded="false">'+'<i class="glyphicon glyphicon-align-justify"></i> <b class="caret"></b></a><ul class="dropdown-menu" role="menu"></ul></li>');this.$dropdown=this.$nav.find(this.options.dropdownSelector);this.$dropdown.css("opacity",0);h=this.$dropdown.width();h=h===0?90:h;this.$dropdown.addClass("hidden").css("opacity",1)}else{h=this.$dropdown.width()}this.breakpoints=[];for(var g=0;g<j+1;g++){var k=this.$items.eq(g).width(),l=0;switch(g){case 0:l=k+h;break;case j-1:l=this.breakpoints[g-1]+k-h;break;case j:l=this.breakpoints[g-1]+h;break;default:l=this.breakpoints[g-1]+k}this.breakpoints.push(l)}if(typeof this.options.fnCallback==="function"){this.options.fnCallback(this.$tabs)}this.bind();this.layout()},layout:function(){if(this.breakpoints.length<=0){return}var l=this.$tabs.width()-500,j=0,h=this,g=this.options.activeClassName,m=this.$tabPanel.filter("."+g).index(),k=function(p){var o=p;if(p===h.itemsLenth){o=p-1}for(;o<h.itemsLenth;o++){if(h.flag){h.$dropdown.find("ul").append(h.$items.eq(o).prop("outerHTML"))}else{h.$dropdown.find("ul>li"+h.options.noNavClassName+":first").before(h.$items.eq(o).prop("outerHTML"))}h.$items.eq(o).hide()}},n=function(p){for(var o=0;o<h.itemsLenth+1;o++){if(o<p){h.$items.eq(o).show()}else{k(p);h.$dropdown.find("ul>li").show();break}}h.$dropdownItems=h.$dropdown.find(h.options.dropdownItemSelector)};for(;j<this.breakpoints.length;j++){if(this.breakpoints[j]>l){break}}this.$items.removeClass(g);this.$dropdownItems.removeClass(g);this.$dropdown.removeClass(g);if(j===this.breakpoints.length){if(this.flag){this.$dropdown.addClass("hidden")}else{this.$dropdown.find("ul>li:not(li"+this.options.noNavClassName+")").remove()}this.$items.show();if(m!=-1){this.$items.eq(m-1).addClass(g)}}else{this.$dropdown.removeClass("hidden");if(this.flag){this.$dropdown.find("ul>li").remove()}else{this.$dropdown.find("ul>li:not(li"+this.options.noNavClassName+")").remove()}n(j);if(m<j){if(m!=-1){this.$items.eq(m-1).addClass(g)}}else{this.$dropdown.addClass(g);this.$dropdownItems.eq(m-j).addClass(g)}}},throttle:function(h,g){var k=h,j,i=true;return function(){var m=arguments,l=this;if(i){k.apply(l,m);i=false}if(j){return false}j=setInterval(function(){clearInterval(j);j=null;k.apply(l,m)},g||500)}},bind:function(){var g=this;e(c).resize(function(){g.throttle(function(){g.layout()},1000)()})}};e.fn[d]=function(g){if(typeof g==="string"){var i=g,h=Array.prototype.slice.call(arguments,1);if(/^_/.test(i)){console.error("No such method : "+g)}else{return this.each(function(){var j=e.data(this,d);if(j&&typeof j[i]==="function"){j[i].apply(j,h)}})}}else{return this.each(function(){if(!e.data(this,d)){e.data(this,d,new b(this,g))}else{e.data(this,d).init()}})}}})(window,document,jQuery);$("#navMenu").resizeTabs({tabParentSelector:"#side-menu"});

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,157 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Page Not Found :(</title>
<style>
::-moz-selection {
background: #b3d4fc;
text-shadow: none;
}
::selection {
background: #b3d4fc;
text-shadow: none;
}
html {
padding: 30px 10px;
font-size: 20px;
line-height: 1.4;
color: #737373;
background: #f0f0f0;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
html,
input {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
body {
max-width: 500px;
_width: 500px;
padding: 30px 20px 50px;
border: 1px solid #b3b3b3;
border-radius: 4px;
margin: 0 auto;
box-shadow: 0 1px 10px #a7a7a7, inset 0 1px 0 #fff;
background: #fcfcfc;
}
h1 {
margin: 0 10px;
font-size: 50px;
text-align: center;
}
h1 span {
color: #bbb;
}
h3 {
margin: 1.5em 0 0.5em;
}
p {
margin: 1em 0;
}
ul {
padding: 0 0 0 40px;
margin: 1em 0;
}
.container {
max-width: 380px;
_width: 380px;
margin: 0 auto;
}
/* google search */
#goog-fixurl ul {
list-style: none;
padding: 0;
margin: 0;
}
#goog-fixurl form {
margin: 0;
}
#goog-wm-qt,
#goog-wm-sb {
border: 1px solid #bbb;
font-size: 16px;
line-height: normal;
vertical-align: top;
color: #444;
border-radius: 2px;
}
#goog-wm-qt {
width: 220px;
height: 20px;
padding: 5px;
margin: 5px 10px 0 0;
box-shadow: inset 0 1px 1px #ccc;
}
#goog-wm-sb {
display: inline-block;
height: 32px;
padding: 0 10px;
margin: 5px 0 0;
white-space: nowrap;
cursor: pointer;
background-color: #f5f5f5;
background-image: -webkit-linear-gradient(rgba(255,255,255,0), #f1f1f1);
background-image: -moz-linear-gradient(rgba(255,255,255,0), #f1f1f1);
background-image: -ms-linear-gradient(rgba(255,255,255,0), #f1f1f1);
background-image: -o-linear-gradient(rgba(255,255,255,0), #f1f1f1);
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
*overflow: visible;
*display: inline;
*zoom: 1;
}
#goog-wm-sb:hover,
#goog-wm-sb:focus {
border-color: #aaa;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
background-color: #f8f8f8;
}
#goog-wm-qt:hover,
#goog-wm-qt:focus {
border-color: #105cb6;
outline: 0;
color: #222;
}
input::-moz-focus-inner {
padding: 0;
border: 0;
}
</style>
</head>
<body>
<div class="container">
<h1>Not found <span>:(</span></h1>
<p>Sorry, but the page you were trying to view does not exist.</p>
<p>It looks like this was the result of either:</p>
<ul>
<li>a mistyped address</li>
<li>an out-of-date link</li>
</ul>
<script>
var GOOG_FIXURL_LANG = (navigator.language || '').slice(0,2),GOOG_FIXURL_SITE = location.host;
</script>
<script src="//linkhelp.clients.google.com/tbproxy/lh/wm/fixurl.js"></script>
</div>
</body>
</html>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="images/mstile-150x150.png?v=Om5N75Y123"/>
<TileColor>#da532c</TileColor>
</tile>
</msapplication>
</browserconfig>

View File

@ -0,0 +1,491 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function _cmmnGetColor(element, defaultColor)
{
var strokeColor;
if(element.current) {
strokeColor = CURRENT_COLOR;
} else if(element.completed) {
strokeColor = COMPLETED_COLOR;
} else {
strokeColor = defaultColor;
}
return strokeColor;
}
function _drawPlanModel(planModel)
{
var rect = paper.rect(planModel.x, planModel.y, planModel.width, planModel.height);
rect.attr({"stroke-width": 1,
"stroke": "#000000",
"fill": "white"
});
if (planModel.name)
{
var planModelName = paper.text(planModel.x + 14, planModel.y + (planModel.height / 2), planModel.name).attr({
"text-anchor" : "middle",
"font-family" : "Arial",
"font-size" : "12",
"fill" : "#000000"
});
planModelName.transform("r270");
}
}
function _drawSubProcess(element)
{
var rect = paper.rect(element.x, element.y, element.width, element.height, 4);
var strokeColor = _cmmnGetColor(element, MAIN_STROKE_COLOR);
rect.attr({"stroke-width": 1,
"stroke": strokeColor,
"fill": "white"
});
}
function _drawVariableServiceTaskIcon(element)
{
_drawTask(element);
if (element.taskType === "mail")
{
_drawSendTaskIcon(paper, element.x + 4, element.y + 4);
}
else if (element.taskType === "camel")
{
_drawCamelTaskIcon(paper, element.x + 4, element.y + 4);
}
else if (element.taskType === "mule")
{
_drawMuleTaskIcon(paper, element.x + 4, element.y + 4);
}
else if (element.taskType === "http")
{
_drawHttpTaskIcon(paper, element.x + 4, element.y + 4);
}
else if (element.stencilIconId)
{
paper.image("../service/stencilitem/" + element.stencilIconId + "/icon", element.x + 4, element.y + 4, 16, 16);
}
else
{
_drawServiceTaskIcon(paper, element.x + 4, element.y + 4);
}
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawHttpServiceTask(element)
{
_drawTask(element);
_drawHttpTaskIcon(paper, element.x + 4, element.y + 4);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawHumanTask(element)
{
_drawTask(element);
_drawHumanTaskIcon(paper, element.x + 4, element.y + 4);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawCaseTask(element)
{
_drawTask(element);
_drawCaseTaskIcon(paper, element.x + 1, element.y + 1);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawProcessTask(element)
{
_drawTask(element);
_drawProcessTaskIcon(paper, element.x + 1, element.y + 1);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawScriptTaskIcon(paper, startX, startY)
{
var path1 = paper.path("m 5,2 0,0.094 c 0.23706,0.064 0.53189,0.1645 0.8125,0.375 0.5582,0.4186 1.05109,1.228 1.15625,2.5312 l 8.03125,0 1,0 1,0 c 0,-3 -2,-3 -2,-3 l -10,0 z M 4,3 4,13 2,13 c 0,3 2,3 2,3 l 9,0 c 0,0 2,0 2,-3 L 15,6 6,6 6,5.5 C 6,4.1111 5.5595,3.529 5.1875,3.25 4.8155,2.971 4.5,3 4.5,3 L 4,3 z");
path1.attr({
"opacity": 1,
"stroke": "none",
"fill": "#72a7d0"
});
var scriptTaskIcon = paper.set();
scriptTaskIcon.push(path1);
scriptTaskIcon.transform("T" + startX + "," + startY);
}
function _drawScriptServiceTask(element)
{
_drawTask(element);
_drawScriptTaskIcon(paper, element.x + 4, element.y + 4);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawDecisionTask(element)
{
_drawTask(element);
_drawDecisionTaskIcon(paper, element.x + 1, element.y + 1);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawServiceTask(element)
{
_drawTask(element);
_drawVariableServiceTaskIcon(element);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawTask(element)
{
var rectAttrs = {};
// Stroke
var strokeColor = _cmmnGetColor(element, ACTIVITY_STROKE_COLOR);
rectAttrs['stroke'] = strokeColor;
var strokeWidth;
if (strokeColor === ACTIVITY_STROKE_COLOR) {
strokeWidth = TASK_STROKE;
} else {
strokeWidth = TASK_HIGHLIGHT_STROKE;
}
var width = element.width - (strokeWidth / 2);
var height = element.height - (strokeWidth / 2);
var rect = paper.rect(element.x, element.y, width, height, 4);
rectAttrs['stroke-width'] = strokeWidth;
// Fill
rectAttrs['fill'] = ACTIVITY_FILL_COLOR;
rect.attr(rectAttrs);
rect.id = element.id;
if (element.name) {
this._drawMultilineText(element.name, element.x, element.y, element.width, element.height, "middle", "middle", 11);
}
}
function _drawTimerEventListener(element)
{
_drawEventListener(element);
_drawTimerEventListenerIcon(paper, element);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawUserEventListener(element)
{
_drawEventListener(element);
_drawUserEventListenerIcon(paper, element);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawGenericEventListener(element)
{
_drawEventListener(element);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawEventListener(element)
{
var x = element.x + (element.width / 2);
var y = element.y + (element.height / 2);
var circle = paper.circle(x, y, 15);
circle.attr({"stroke-width": 1,
"stroke": "black",
"fill": "white"
});
circle.id = element.id;
}
function _drawMilestone(element)
{
var rectAttrs = {};
// Stroke
var strokeColor = _cmmnGetColor(element, ACTIVITY_STROKE_COLOR);
rectAttrs['stroke'] = strokeColor;
var strokeWidth;
if (strokeColor === ACTIVITY_STROKE_COLOR) {
strokeWidth = TASK_STROKE;
} else {
strokeWidth = TASK_HIGHLIGHT_STROKE;
}
var width = element.width - (strokeWidth / 2);
var height = element.height - (strokeWidth / 2);
var rect = paper.rect(element.x, element.y, width, height, 24);
rectAttrs['stroke-width'] = strokeWidth;
// Fill
rectAttrs['fill'] = WHITE_FILL_COLOR;
rect.attr(rectAttrs);
rect.id = element.id;
if (element.name) {
this._drawMultilineText(element.name, element.x, element.y, element.width, element.height, "middle", "middle", 11);
}
}
function _drawStage(element)
{
var rectAttrs = {};
// Stroke
var strokeColor = _cmmnGetColor(element, ACTIVITY_STROKE_COLOR);
rectAttrs['stroke'] = strokeColor;
var strokeWidth;
if (strokeColor === ACTIVITY_STROKE_COLOR) {
strokeWidth = TASK_STROKE;
} else {
strokeWidth = TASK_HIGHLIGHT_STROKE;
}
var width = element.width - (strokeWidth / 2);
var height = element.height - (strokeWidth / 2);
var rect = paper.rect(element.x, element.y, width, height, 16);
rectAttrs['stroke-width'] = strokeWidth;
// Fill
rectAttrs['fill'] = WHITE_FILL_COLOR;
rect.attr(rectAttrs);
rect.id = element.id;
if (element.name) {
this._drawMultilineText(element.name, element.x + 10, element.y + 5, element.width, element.height, "start", "top", 11);
}
}
function _drawPlanModel(element)
{
var rectAttrs = {};
// Stroke
var strokeColor = _cmmnGetColor(element, ACTIVITY_STROKE_COLOR);
rectAttrs['stroke'] = strokeColor;
var strokeWidth;
if (strokeColor === ACTIVITY_STROKE_COLOR) {
strokeWidth = TASK_STROKE;
} else {
strokeWidth = TASK_HIGHLIGHT_STROKE;
}
var width = element.width - (strokeWidth / 2);
var height = element.height - (strokeWidth / 2);
var rect = paper.rect(element.x, element.y, width, height, 4);
rectAttrs['stroke-width'] = strokeWidth;
// Fill
rectAttrs['fill'] = WHITE_FILL_COLOR;
rect.attr(rectAttrs);
rect.id = element.id;
var path1 = paper.path("M20 55 L37 34 L275 34 L291 55");
path1.attr({
"opacity": 1,
"stroke": strokeColor,
"fill": "#ffffff"
});
var planModelHeader = paper.set();
planModelHeader.push(path1);
planModelHeader.translate(element.x, element.y - 55);
if (element.name) {
this._drawMultilineText(element.name, element.x + 10, element.y - 16, 275, element.height, "middle", "top", 11);
}
}
function _drawEntryCriterion(element)
{
var strokeColor = _cmmnGetColor(element, MAIN_STROKE_COLOR);
var rhombus = paper.path("M" + element.x + " " + (element.y + (element.height / 2)) +
"L" + (element.x + (element.width / 2)) + " " + (element.y + element.height) +
"L" + (element.x + element.width) + " " + (element.y + (element.height / 2)) +
"L" + (element.x + (element.width / 2)) + " " + element.y + "z"
);
// Fill
var gatewayFillColor = WHITE_FILL_COLOR;
// Opacity
var gatewayOpacity = 1.0;
rhombus.attr("stroke-width", 1);
rhombus.attr("stroke", strokeColor);
rhombus.attr("fill", gatewayFillColor);
rhombus.attr("fill-opacity", gatewayOpacity);
rhombus.id = element.id;
}
function _drawExitCriterion(element)
{
var strokeColor = _cmmnGetColor(element, MAIN_STROKE_COLOR);
var rhombus = paper.path("M" + element.x + " " + (element.y + (element.height / 2)) +
"L" + (element.x + (element.width / 2)) + " " + (element.y + element.height) +
"L" + (element.x + element.width) + " " + (element.y + (element.height / 2)) +
"L" + (element.x + (element.width / 2)) + " " + element.y + "z"
);
// Fill
var gatewayFillColor = '#000000';
// Opacity
var gatewayOpacity = 1.0;
rhombus.attr("stroke-width", 1);
rhombus.attr("stroke", strokeColor);
rhombus.attr("fill", gatewayFillColor);
rhombus.attr("fill-opacity", gatewayOpacity);
rhombus.id = element.id;
}
function _drawMultilineText(text, x, y, boxWidth, boxHeight, horizontalAnchor, verticalAnchor, fontSize)
{
if (!text || text == "")
{
return;
}
var textBoxX, textBoxY;
var width = boxWidth - (2 * TEXT_PADDING);
if (horizontalAnchor === "middle")
{
textBoxX = x + (boxWidth / 2);
}
else if (horizontalAnchor === "start")
{
textBoxX = x;
}
textBoxY = y + (boxHeight / 2);
var t = paper.text(textBoxX + TEXT_PADDING, textBoxY + TEXT_PADDING).attr({
"text-anchor" : horizontalAnchor,
"font-family" : "Arial",
"font-size" : fontSize,
"fill" : "#373e48"
});
var abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
t.attr({
"text" : abc
});
var letterWidth = t.getBBox().width / abc.length;
t.attr({
"text" : text
});
var removedLineBreaks = text.split("\n");
var x = 0, s = [];
for (var r = 0; r < removedLineBreaks.length; r++)
{
var words = removedLineBreaks[r].split(" ");
for ( var i = 0; i < words.length; i++) {
var l = words[i].length;
if (x + (l * letterWidth) > width) {
s.push("\n");
x = 0;
}
x += l * letterWidth;
s.push(words[i] + " ");
}
s.push("\n");
x = 0;
}
t.attr({
"text" : s.join("")
});
if (verticalAnchor && verticalAnchor === "top")
{
t.attr({"y": y + (t.getBBox().height / 2)});
}
}
function _drawAssociation(flow){
var polyline = new Polyline(flow.id, flow.waypoints, ASSOCIATION_STROKE, paper);
polyline.element = paper.path(polyline.path);
polyline.element.attr({"stroke-width": ASSOCIATION_STROKE});
polyline.element.attr({"stroke-dasharray": ". "});
polyline.element.attr({"stroke":"#585858"});
polyline.element.id = flow.id;
var polylineInvisible = new Polyline(flow.id, flow.waypoints, ASSOCIATION_STROKE, paper);
polylineInvisible.element = paper.path(polyline.path);
polylineInvisible.element.attr({
"opacity": 0,
"stroke-width": 8,
"stroke" : "#000000"
});
_showTip(jQuery(polylineInvisible.element.node), flow);
polylineInvisible.element.mouseover(function() {
paper.getById(polyline.element.id).attr({"stroke":"blue"});
});
polylineInvisible.element.mouseout(function() {
paper.getById(polyline.element.id).attr({"stroke":"#585858"});
});
}
function _drawArrowHead(line, connectionType)
{
var doubleArrowWidth = 2 * ARROW_WIDTH;
var arrowHead = paper.path("M0 0L-" + (ARROW_WIDTH / 2 + .5) + " -" + doubleArrowWidth + "L" + (ARROW_WIDTH/2 + .5) + " -" + doubleArrowWidth + "z");
// anti smoothing
if (this.strokeWidth%2 == 1)
line.x2 += .5, line.y2 += .5;
arrowHead.transform("t" + line.x2 + "," + line.y2 + "");
arrowHead.transform("...r" + Raphael.deg(line.angle - Math.PI / 2) + " " + 0 + " " + 0);
arrowHead.attr("fill", "#585858");
arrowHead.attr("stroke-width", SEQUENCEFLOW_STROKE);
arrowHead.attr("stroke", "#585858");
return arrowHead;
}

View File

@ -0,0 +1,180 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function _drawHumanTaskIcon(paper, startX, startY)
{
var path1 = paper.path("m 1,17 16,0 0,-1.7778 -5.333332,-3.5555 0,-1.7778 c 1.244444,0 1.244444,-2.3111 1.244444,-2.3111 l 0,-3.0222 C 12.555557,0.8221 9.0000001,1.0001 9.0000001,1.0001 c 0,0 -3.5555556,-0.178 -3.9111111,3.5555 l 0,3.0222 c 0,0 0,2.3111 1.2444443,2.3111 l 0,1.7778 L 1,15.2222 1,17 17,17");
path1.attr({
"opacity": 1,
"stroke": "none",
"fill": "#d1b575"
});
var userTaskIcon = paper.set();
userTaskIcon.push(path1);
userTaskIcon.transform("T" + startX + "," + startY);
}
function _drawServiceTaskIcon(paper, startX, startY)
{
var path1 = paper.path("M 8,1 7.5,2.875 c 0,0 -0.02438,0.250763 -0.40625,0.4375 C 7.05724,3.330353 7.04387,3.358818 7,3.375 6.6676654,3.4929791 6.3336971,3.6092802 6.03125,3.78125 6.02349,3.78566 6.007733,3.77681 6,3.78125 5.8811373,3.761018 5.8125,3.71875 5.8125,3.71875 l -1.6875,-1 -1.40625,1.4375 0.96875,1.65625 c 0,0 0.065705,0.068637 0.09375,0.1875 0.002,0.00849 -0.00169,0.022138 0,0.03125 C 3.6092802,6.3336971 3.4929791,6.6676654 3.375,7 3.3629836,7.0338489 3.3239228,7.0596246 3.3125,7.09375 3.125763,7.4756184 2.875,7.5 2.875,7.5 L 1,8 l 0,2 1.875,0.5 c 0,0 0.250763,0.02438 0.4375,0.40625 0.017853,0.03651 0.046318,0.04988 0.0625,0.09375 0.1129372,0.318132 0.2124732,0.646641 0.375,0.9375 -0.00302,0.215512 -0.09375,0.34375 -0.09375,0.34375 L 2.6875,13.9375 4.09375,15.34375 5.78125,14.375 c 0,0 0.1229911,-0.09744 0.34375,-0.09375 0.2720511,0.147787 0.5795915,0.23888 0.875,0.34375 0.033849,0.01202 0.059625,0.05108 0.09375,0.0625 C 7.4756199,14.874237 7.5,15.125 7.5,15.125 L 8,17 l 2,0 0.5,-1.875 c 0,0 0.02438,-0.250763 0.40625,-0.4375 0.03651,-0.01785 0.04988,-0.04632 0.09375,-0.0625 0.332335,-0.117979 0.666303,-0.23428 0.96875,-0.40625 0.177303,0.0173 0.28125,0.09375 0.28125,0.09375 l 1.65625,0.96875 1.40625,-1.40625 -0.96875,-1.65625 c 0,0 -0.07645,-0.103947 -0.09375,-0.28125 0.162527,-0.290859 0.262063,-0.619368 0.375,-0.9375 0.01618,-0.04387 0.04465,-0.05724 0.0625,-0.09375 C 14.874237,10.52438 15.125,10.5 15.125,10.5 L 17,10 17,8 15.125,7.5 c 0,0 -0.250763,-0.024382 -0.4375,-0.40625 C 14.669647,7.0572406 14.641181,7.0438697 14.625,7 14.55912,6.8144282 14.520616,6.6141566 14.4375,6.4375 c -0.224363,-0.4866 0,-0.71875 0,-0.71875 L 15.40625,4.0625 14,2.625 l -1.65625,1 c 0,0 -0.253337,0.1695664 -0.71875,-0.03125 l -0.03125,0 C 11.405359,3.5035185 11.198648,3.4455201 11,3.375 10.95613,3.3588185 10.942759,3.3303534 10.90625,3.3125 10.524382,3.125763 10.5,2.875 10.5,2.875 L 10,1 8,1 z m 1,5 c 1.656854,0 3,1.3431458 3,3 0,1.656854 -1.343146,3 -3,3 C 7.3431458,12 6,10.656854 6,9 6,7.3431458 7.3431458,6 9,6 z");
path1.attr({
"opacity": 1,
"stroke": "none",
"fill": "#72a7d0"
});
var serviceTaskIcon = paper.set();
serviceTaskIcon.push(path1);
serviceTaskIcon.transform("T" + startX + "," + startY);
}
function _drawCaseTaskIcon(paper, startX, startY)
{
var path1 = paper.path("M5 8 L9 4 L18 4 L 21 7");
path1.attr({
"opacity": 1,
"stroke": "#000000",
"fill": "#000000"
});
var path2 = paper.path("M1 23 L1 4 L30 4 L30 23z");
path2.attr({
"opacity": 1,
"stroke": "#000000",
"fill": "#F4F6F7"
});
var caseTaskIcon = paper.set();
caseTaskIcon.push(path1);
caseTaskIcon.push(path2);
caseTaskIcon.translate(startX, startY);
caseTaskIcon.scale(0.7, 0.7);
}
function _drawProcessTaskIcon(paper, startX, startY)
{
var path1 = paper.path("M1 23 L7 11 L1 0 L30 0 L 35 11 L 30 23z");
path1.attr({
"opacity": 1,
"stroke": "#000000",
"fill": "#F4F6F7"
});
var processTaskIcon = paper.set();
processTaskIcon.push(path1);
processTaskIcon.translate(startX, startY);
processTaskIcon.scale(0.7, 0.7);
}
function _drawDecisionTaskIcon(paper, startX, startY)
{
var path1 = paper.path("m 1,2 0,14 16,0 0,-14 z m 1.9,2.4000386 3.7,0 0,2.7999224 -3.7,0 z m 4.36364,0 3.7,0 0,2.7999224 -3.7,0 z m 4.36364,0 3.7,0 0,2.7999224 -3.7,0 z m -8.67364,3.9 3.7,0 0,2.7999224 -3.7,0 z m 4.36364,0 3.7,0 0,2.7999224 -3.7,0 z m 4.36364,0 3.7,0 0,2.7999224 -3.7,0 z m -8.67364,3.9 3.7,0 0,2.7999224 -3.7,0 z m 4.36364,0 3.7,0 0,2.7999224 -3.7,0 z m 4.36364,0 3.7,0 0,2.7999224 -3.7,0 z");
path1.attr({
"opacity": 1,
"stroke": "#000000",
"fill": "#F4F6F7"
});
var decisionTaskIcon = paper.set();
decisionTaskIcon.push(path1);
decisionTaskIcon.translate(startX, startY);
decisionTaskIcon.scale(0.7, 0.7);
}
function _drawHttpTaskIcon(paper, startX, startY)
{
var path = paper.path("m 16.704699,5.9229055 q 0.358098,0 0.608767,0.2506681 0.250669,0.250668 0.250669,0.6087677 0,0.3580997 -0.250669,0.6087677 -0.250669,0.2506679 -0.608767,0.2506679 -0.358098,0 -0.608767,-0.2506679 -0.250669,-0.250668 -0.250669,-0.6087677 0,-0.3580997 0.250669,-0.6087677 0.250669,-0.2506681 0.608767,-0.2506681 z m 2.578308,-2.0053502 q -2.229162,0 -3.854034,0.6759125 -1.624871,0.6759067 -3.227361,2.2694472 -0.716197,0.725146 -1.575633,1.7457293 L 7.2329969,8.7876913 Q 7.0897576,8.8055849 7.000233,8.9309334 L 4.9948821,12.368677 q -0.035811,0.06267 -0.035811,0.143242 0,0.107426 0.080572,0.205905 l 0.5729577,0.572957 q 0.125334,0.116384 0.2864786,0.07162 l 2.4708789,-0.760963 2.5156417,2.515645 -0.76096,2.470876 q -0.009,0.02687 -0.009,0.08057 0,0.125338 0.08058,0.205905 l 0.572957,0.572958 q 0.170096,0.152194 0.349146,0.04476 l 3.437744,-2.005351 q 0.125335,-0.08953 0.143239,-0.232763 l 0.17905,-3.392986 q 1.02058,-0.859435 1.745729,-1.575629 1.67411,-1.6830612 2.309735,-3.2049805 0.635625,-1.5219191 0.635625,-3.8585111 0,-0.1253369 -0.08505,-0.2148575 -0.08505,-0.089526 -0.201431,-0.089526 z");
path.attr({
"opacity": 1,
"stroke": "none",
"fill": "#16964d"
});
startX += -2;
startY += -2;
path.transform("T" + startX + "," + startY);
}
function _drawBusinessRuleTaskIcon(paper, startX, startY) {
var path1 = paper.path("m 1,2 0,14 16,0 0,-14 z m 1.45458,5.6000386 2.90906,0 0,2.7999224 -2.90906,0 z m 4.36364,0 8.72718,0 0,2.7999224 -8.72718,0 z m -4.36364,4.1998844 2.90906,0 0,2.800116 -2.90906,0 z m 4.36364,0 8.72718,0 0,2.800116 -8.72718,0 z");
path1.attr({
"stroke": "none",
"fill": "#72a7d0"
});
var businessRuleTaskIcon = paper.set();
businessRuleTaskIcon.push(path1);
businessRuleTaskIcon.transform("T" + startX + "," + startY);
}
function _drawTimerEventListenerIcon(paper, element)
{
var x = element.x + (element.width / 2);
var y = element.y + (element.height / 2);
var circle = paper.circle(x, y, 10);
circle.attr({"stroke-width": 1,
"stroke": "black",
"fill": "none"
});
var path = paper.path("M 10 0 C 4.4771525 0 0 4.4771525 0 10 C 0 15.522847 4.4771525 20 10 20 C 15.522847 20 20 15.522847 20 10 C 20 4.4771525 15.522847 1.1842379e-15 10 0 z M 9.09375 1.03125 C 9.2292164 1.0174926 9.362825 1.0389311 9.5 1.03125 L 9.5 3.5 L 10.5 3.5 L 10.5 1.03125 C 15.063526 1.2867831 18.713217 4.9364738 18.96875 9.5 L 16.5 9.5 L 16.5 10.5 L 18.96875 10.5 C 18.713217 15.063526 15.063526 18.713217 10.5 18.96875 L 10.5 16.5 L 9.5 16.5 L 9.5 18.96875 C 4.9364738 18.713217 1.2867831 15.063526 1.03125 10.5 L 3.5 10.5 L 3.5 9.5 L 1.03125 9.5 C 1.279102 5.0736488 4.7225326 1.4751713 9.09375 1.03125 z M 9.5 5 L 9.5 8.0625 C 8.6373007 8.2844627 8 9.0680195 8 10 C 8 11.104569 8.8954305 12 10 12 C 10.931981 12 11.715537 11.362699 11.9375 10.5 L 14 10.5 L 14 9.5 L 11.9375 9.5 C 11.756642 8.7970599 11.20294 8.2433585 10.5 8.0625 L 10.5 5 L 9.5 5 z");
path.attr({
"stroke": "none",
"fill": "#585858"
});
path.transform("T" + (element.x + 5) + "," + (element.y + 5));
return path;
}
function _drawUserEventListenerIcon(paper, element) {
var userTaskIcon = paper.set();
var path1 = paper.path("M0.585,24.167h24.083v-7.833c0,0-2.333-3.917-7.083-5.167h-9.25 c-4.417,1.333-7.833,5.75-7.833,5.75L0.585,24.167z");
path1.attr({"opacity": 1, "stroke": "none", "fill": "#F4F6F7"});
userTaskIcon.push(path1);
var path2 = paper.path("M6,20L6,24");
path2.attr({"opacity": 1, "stroke": "white", "fill": "none"});
userTaskIcon.push(path2);
var path3 = paper.path("M20,20L20,24");
path3.attr({"opacity": 1, "stroke": "white", "fill": "none"});
userTaskIcon.push(path3);
var circle = paper.circle(13.002, 5.916, 5.417);
circle.attr({"stroke-width": 1, "stroke": "black", "fill": "#000000"});
userTaskIcon.push(circle);
var path4 = paper.path("M8.043,7.083c0,0,2.814-2.426,5.376-1.807s4.624-0.693,4.624-0.693 c0.25,1.688,0.042,3.75-1.458,5.584c0,0,1.083,0.75,1.083,1.5s0.125,1.875-1,3s-5.5,1.25-6.75,0S8.668,12.834,8.668,12 s0.583-1.25,1.25-1.917C8.835,9.5,7.419,7.708,8.043,7.083z");
path4.attr({"opacity": 1, "stroke": "none", "fill": "#F0EFF0"});
userTaskIcon.push(path4);
var x = (element.width / 2) - 2;
var y = (element.height / 2) - 2;
var circle2 = paper.circle(x, y, 17);
circle2.attr({"stroke-width": 1, "stroke": "#F0EFF0", "fill": "none"});
userTaskIcon.push(circle2);
userTaskIcon.transform("S0.7,0.7" + "T" + (element.x + 2) + "," + (element.y + 2));
return userTaskIcon;
}

View File

@ -0,0 +1,24 @@
div[class*='ui-tooltip-flowable-'] {
background-color: #ffffff;
border-color: #c5c5c5;
color: #4a4a4a;
font-family: Verdana;
font-size: 12px;
}
div[class*='ui-tooltip-flowable-'] .qtip-content {
color: #4a4a4a;
background-color: #ffffff;
font-family: Verdana;
font-size: 12px;
}
.ui-tooltip-flowable-cmmn .qtip-titlebar {
color: #FFFFFF;
font-size: 12px;
background: #2B414F;
}
.ui-tooltip-flowable-cmmn .qtip-tip {
background-color: #2B414F;
}

View File

@ -0,0 +1,15 @@
<html>
<head>
<link type="text/css" rel="stylesheet" href="display/jquery.qtip.min.css" />
<link type="text/css" rel="stylesheet" href="display-cmmn/displaymodel.css" />
<script type="text/javascript" src="display/jquery.qtip.min.js"></script>
<script type="text/javascript" src="display/raphael.min.js"></script>
<script type="text/javascript" src="display-cmmn/cmmn-draw.js"></script>
<script type="text/javascript" src="display-cmmn/cmmn-icons.js"></script>
<script type="text/javascript" src="display/Polyline.js"></script>
<script type="text/javascript" src="display-cmmn/displaymodel.js"></script>
</head>
</html>

View File

@ -0,0 +1,272 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var NORMAL_STROKE = 1;
var ASSOCIATION_STROKE = 2;
var TASK_STROKE = 1;
var TASK_HIGHLIGHT_STROKE = 2;
var TEXT_COLOR= "#373e48";
var CURRENT_COLOR= "#017501";
var HOVER_COLOR= "#666666";
var ACTIVITY_STROKE_COLOR = "#bbbbbb";
var ACTIVITY_FILL_COLOR = "#f9f9f9";
var WHITE_FILL_COLOR = "#ffffff";
var MAIN_STROKE_COLOR = "#585858";
var TEXT_PADDING = 3;
var ARROW_WIDTH = 4;
var MARKER_WIDTH = 12;
var TASK_FONT = {font: "11px Arial", opacity: 1, fill: Raphael.rgb(0, 0, 0)};
// icons
var ICON_SIZE = 16;
var ICON_PADDING = 4;
var INITIAL_CANVAS_WIDTH;
var INITIAL_CANVAS_HEIGHT;
var paper;
var viewBox;
var viewBoxWidth;
var viewBoxHeight;
var canvasWidth;
var canvasHeight;
var modelDiv = jQuery('#cmmnModel');
var modelId = modelDiv.attr('data-model-id');
var historyModelId = modelDiv.attr('data-history-id');
var caseDefinitionId = modelDiv.attr('data-case-definition-id');
var modelType = modelDiv.attr('data-model-type');
var elementsAdded = new Array();
var elementsRemoved = new Array();
function _showTip(htmlNode, element)
{
// Default tooltip, no custom tool tip set
if (documentation === undefined) {
var documentation = "";
if (element.name && element.name.length > 0) {
documentation += "<b>Name</b>: <i>" + element.name + "</i><br/><br/>";
}
if (element.properties) {
for (var i = 0; i < element.properties.length; i++) {
var propName = element.properties[i].name;
if (element.properties[i].type && element.properties[i].type === 'list') {
documentation += '<b>' + propName + '</b>:<br/>';
for (var j = 0; j < element.properties[i].value.length; j++) {
documentation += '<i>' + element.properties[i].value[j] + '</i><br/>';
}
}
else {
documentation += '<b>' + propName + '</b>: <i>' + element.properties[i].value + '</i><br/>';
}
}
}
}
var text = element.type + " ";
if (element.name && element.name.length > 0)
{
text += element.name;
}
else
{
text += element.id;
}
htmlNode.qtip({
content: {
text: documentation,
title: {
text: text
}
},
position: {
my: 'top left',
at: 'bottom center',
viewport: jQuery('#cmmnModel')
},
hide: {
fixed: true, delay: 500,
event: 'click mouseleave'
},
style: {
classes: 'ui-tooltip-modeler-cmmn'
}
});
}
function _addHoverLogic(element, type, defaultColor)
{
var strokeColor = _cmmnGetColor(element, defaultColor);
var topBodyRect = null;
if (type === "rect")
{
topBodyRect = paper.rect(element.x, element.y, element.width, element.height);
}
else if (type === "circle")
{
var x = element.x + (element.width / 2);
var y = element.y + (element.height / 2);
topBodyRect = paper.circle(x, y, 15);
}
else if (type === "rhombus")
{
topBodyRect = paper.path("M" + element.x + " " + (element.y + (element.height / 2)) +
"L" + (element.x + (element.width / 2)) + " " + (element.y + element.height) +
"L" + (element.x + element.width) + " " + (element.y + (element.height / 2)) +
"L" + (element.x + (element.width / 2)) + " " + element.y + "z"
);
}
var opacity = 0;
var fillColor = "#ffffff";
if (jQuery.inArray(element.id, elementsAdded) >= 0)
{
opacity = 0.2;
fillColor = "green";
}
if (jQuery.inArray(element.id, elementsRemoved) >= 0)
{
opacity = 0.2;
fillColor = "red";
}
topBodyRect.attr({
"opacity": opacity,
"stroke" : "none",
"fill" : fillColor
});
_showTip(jQuery(topBodyRect.node), element);
topBodyRect.mouseover(function() {
paper.getById(element.id).attr({"stroke":HOVER_COLOR});
});
topBodyRect.mouseout(function() {
paper.getById(element.id).attr({"stroke":strokeColor});
});
}
function _zoom(zoomIn)
{
var tmpCanvasWidth, tmpCanvasHeight;
if (zoomIn)
{
tmpCanvasWidth = canvasWidth * (1.0/0.90);
tmpCanvasHeight = canvasHeight * (1.0/0.90);
}
else
{
tmpCanvasWidth = canvasWidth * (1.0/1.10);
tmpCanvasHeight = canvasHeight * (1.0/1.10);
}
if (tmpCanvasWidth != canvasWidth || tmpCanvasHeight != canvasHeight)
{
canvasWidth = tmpCanvasWidth;
canvasHeight = tmpCanvasHeight;
paper.setSize(canvasWidth, canvasHeight);
}
}
var modelUrl;
if (modelType == 'runtime') {
if (historyModelId) {
modelUrl = FLOWABLE.APP_URL.getCaseInstancesHistoryModelJsonUrl(historyModelId);
} else {
modelUrl = FLOWABLE.APP_URL.getCaseInstancesModelJsonUrl(modelId);
}
} else if (modelType == 'design') {
if (historyModelId) {
modelUrl = FLOWABLE.APP_URL.getModelHistoryModelJsonUrl(modelId, historyModelId);
} else {
modelUrl = FLOWABLE.APP_URL.getModelModelJsonUrl(modelId);
}
} else if (modelType == 'case-definition') {
modelUrl = FLOWABLE.APP_URL.getCaseDefinitionModelJsonUrl(caseDefinitionId);
}
var request = jQuery.ajax({
type: 'get',
url: modelUrl + '?nocaching=' + new Date().getTime()
});
request.success(function(data, textStatus, jqXHR) {
if ((!data.elements || data.elements.length == 0) && (!data.pools || data.pools.length == 0)) return;
INITIAL_CANVAS_WIDTH = data.diagramWidth;
if (modelType == 'design') {
INITIAL_CANVAS_WIDTH += 20;
} else {
INITIAL_CANVAS_WIDTH += 30;
}
INITIAL_CANVAS_HEIGHT = data.diagramHeight + 50;
canvasWidth = INITIAL_CANVAS_WIDTH;
canvasHeight = INITIAL_CANVAS_HEIGHT;
viewBoxWidth = INITIAL_CANVAS_WIDTH;
viewBoxHeight = INITIAL_CANVAS_HEIGHT;
if (modelType == 'design') {
var headerBarHeight = 170;
var offsetY = 0;
if (jQuery(window).height() > (canvasHeight + headerBarHeight))
{
offsetY = (jQuery(window).height() - headerBarHeight - canvasHeight) / 2;
}
if (offsetY > 50) {
offsetY = 50;
}
jQuery('#cmmnModel').css('marginTop', offsetY);
}
jQuery('#cmmnModel').width(INITIAL_CANVAS_WIDTH);
jQuery('#cmmnModel').height(INITIAL_CANVAS_HEIGHT);
paper = Raphael(document.getElementById('cmmnModel'), canvasWidth, canvasHeight);
paper.setViewBox(0, 0, viewBoxWidth, viewBoxHeight, false);
paper.renderfix();
var modelElements = data.elements;
for (var i = 0; i < modelElements.length; i++)
{
var element = modelElements[i];
//try {
var drawFunction = eval("_draw" + element.type);
drawFunction(element);
//} catch(err) {console.log(err);}
}
if (data.flows)
{
for (var i = 0; i < data.flows.length; i++)
{
var flow = data.flows[i];
_drawAssociation(flow);
}
}
});
request.error(function(jqXHR, textStatus, errorThrown) {
alert("error");
});

View File

@ -0,0 +1,153 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
require('time-grunt')(grunt);
grunt.initConfig({
yeoman: {
app: require('./package.json').appPath || 'app',
dist: 'dist'
},
clean: {
dist: {
files: [
{
dot: true,
src: [
'.tmp',
'<%= yeoman.dist %>/*',
'!<%= yeoman.dist %>/.git*'
]
}
]
},
server: '.tmp'
},
useminPrepare: {
html: 'displaymodel.html',
options: {
dest: '<%= yeoman.dist %>/'
}
},
usemin: {
html: ['<%= yeoman.dist %>/{,*/}*.html'],
css: ['<%= yeoman.dist %>/display/styles/{,*/}*.css'],
options: {
dirs: ['<%= yeoman.dist %>']
}
},
// Put files not handled in other tasks here
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '.',
dest: '<%= yeoman.dist %>',
src: [
'fonts/*'
]
}, {
expand: true,
cwd: '.tmp/images',
dest: '<%= yeoman.dist %>/images',
src: [
'generated/*'
]
}]
},
styles: {
expand: true,
cwd: 'styles',
dest: '.tmp/styles/',
src: '{,*/}*.css'
},
index: {
expand: true,
cwd: './',
src: ['*.html', 'views/**/**.html'],
dest: '<%= yeoman.dist %>'
},
copyCss : {
files: [
{expand: true, cwd:'.tmp/concat/display/styles/', src:'*.css', dest:'<%= yeoman.dist %>/display/styles/', filter: 'isFile'}
]
},
copyJs : {
files: [
{expand: true, cwd:'.tmp/concat/display/scripts', src:'*.js', dest:'<%= yeoman.dist %>/display/scripts/', filter: 'isFile'}
]
},
},
ngAnnotate: {
dist: {
files: [
{
expand: true,
cwd: '.tmp/concat/display/scripts',
src: '*.js',
dest: '.tmp/concat/display/scripts'
}
]
}
},
uglify: {
dist: {
options: {
mangle: true
},
files: {
'<%= yeoman.dist %>/display/scripts/displaymodel-logic.js': [
'<%= yeoman.dist %>/display/scripts/displaymodel-logic.js'
]
}
}
},
rev: {
dist: {
files: {
src: [
'<%= yeoman.dist %>/display/{,*/}*.js',
'<%= yeoman.dist %>/display/{,*/}*.css',
'<%= yeoman.dist %>/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
]
}
}
}
});
grunt.registerTask('buildApp', [
'clean:dist',
'useminPrepare',
'copy:styles',
'concat',
'copy:dist',
'ngAnnotate',
'copy:copyCss',
'copy:copyJs',
'copy:index',
'uglify',
'rev',
'usemin'
]);
grunt.registerTask('default', [
'buildApp'
]);
};

View File

@ -0,0 +1,387 @@
/* Copyright 2005-2015 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Class to generate polyline
*
* @author Dmitry Farafonov
*/
var ANCHOR_TYPE= {
main: "main",
middle: "middle",
first: "first",
last: "last"
};
function Anchor(uuid, type, x, y) {
this.uuid = uuid;
this.x = x;
this.y = y;
this.type = (type == ANCHOR_TYPE.middle) ? ANCHOR_TYPE.middle : ANCHOR_TYPE.main;
};
Anchor.prototype = {
uuid: null,
x: 0,
y: 0,
type: ANCHOR_TYPE.main,
isFirst: false,
isLast: false,
ndex: 0,
typeIndex: 0
};
function Polyline(uuid, points, strokeWidth, paper) {
/* Array on coordinates:
* points: [{x: 410, y: 110}, 1
* {x: 570, y: 110}, 1 2
* {x: 620, y: 240}, 2 3
* {x: 750, y: 270}, 3 4
* {x: 650, y: 370}]; 4
*/
this.points = points;
/*
* path for graph
* [["M", x1, y1], ["L", x2, y2], ["C", ax, ay, bx, by, x3, y3], ["L", x3, y3]]
*/
this.path = [];
this.anchors = [];
if (strokeWidth) this.strokeWidth = strokeWidth;
this.paper = paper;
this.closePath = false;
this.init();
};
Polyline.prototype = {
id: null,
points: [],
path: [],
anchors: [],
strokeWidth: 1,
radius: 1,
showDetails: false,
paper: null,
element: null,
isDefaultConditionAvailable: false,
closePath: false,
init: function(points){
var linesCount = this.getLinesCount();
if (linesCount < 1)
return;
this.normalizeCoordinates();
// create anchors
this.pushAnchor(ANCHOR_TYPE.first, this.getLine(0).x1, this.getLine(0).y1);
for (var i = 1; i < linesCount; i++)
{
var line1 = this.getLine(i-1);
this.pushAnchor(ANCHOR_TYPE.main, line1.x2, line1.y2);
}
this.pushAnchor(ANCHOR_TYPE.last, this.getLine(linesCount-1).x2, this.getLine(linesCount-1).y2);
this.rebuildPath();
},
normalizeCoordinates: function(){
for(var i=0; i < this.points.length; i++){
this.points[i].x = parseFloat(this.points[i].x);
this.points[i].y = parseFloat(this.points[i].y);
}
},
getLinesCount: function(){
return this.points.length-1;
},
_getLine: function(i){
if (this.points.length > i && this.points[i]) {
return {x1: this.points[i].x, y1: this.points[i].y, x2: this.points[i+1].x, y2: this.points[i+1].y};
} else {
return undefined;
}
},
getLine: function(i){
var line = this._getLine(i);
if (line != undefined) {
line.angle = this.getLineAngle(i);
}
return line;
},
getLineAngle: function(i){
var line = this._getLine(i);
return Math.atan2(line.y2 - line.y1, line.x2 - line.x1);
},
getLineLengthX: function(i){
var line = this.getLine(i);
return (line.x2 - line.x1);
},
getLineLengthY: function(i){
var line = this.getLine(i);
return (line.y2 - line.y1);
},
getLineLength: function(i){
return Math.sqrt(Math.pow(this.getLineLengthX(i), 2) + Math.pow(this.getLineLengthY(i), 2));
},
getAnchors: function(){
return this.anchors;
},
getAnchorsCount: function(type){
if (!type)
return this.anchors.length;
else {
var count = 0;
for(var i=0; i < this.getAnchorsCount(); i++){
var anchor = this.anchors[i];
if (anchor.getType() == type) {
count++;
}
}
return count;
}
},
pushAnchor: function(type, x, y, index){
if (type == ANCHOR_TYPE.first) {
index = 0;
typeIndex = 0;
} else if (type == ANCHOR_TYPE.last) {
index = this.getAnchorsCount();
typeIndex = 0;
} else if (!index) {
index = this.anchors.length;
} else {
for(var i=0; i < this.getAnchorsCount(); i++){
var anchor = this.anchors[i];
if (anchor.index > index) {
anchor.index++;
anchor.typeIndex++;
}
}
}
var anchor = new Anchor(this.id, ANCHOR_TYPE.main, x, y, index, typeIndex);
this.anchors.push(anchor);
},
getAnchor: function(position){
return this.anchors[position];
},
getAnchorByType: function(type, position){
if (type == ANCHOR_TYPE.first)
return this.anchors[0];
if (type == ANCHOR_TYPE.last)
return this.anchors[this.getAnchorsCount()-1];
for(var i=0; i < this.getAnchorsCount(); i++){
var anchor = this.anchors[i];
if (anchor.type == type) {
if( position == anchor.position)
return anchor;
}
}
return null;
},
addNewPoint: function(position, x, y){
//
for(var i = 0; i < this.getLinesCount(); i++){
var line = this.getLine(i);
if (x > line.x1 && x < line.x2 && y > line.y1 && y < line.y2) {
this.points.splice(i+1,0,{x: x, y: y});
break;
}
}
this.rebuildPath();
},
rebuildPath: function(){
var path = [];
for(var i = 0; i < this.getAnchorsCount(); i++){
var anchor = this.getAnchor(i);
var pathType = "";
if (i == 0)
pathType = "M";
else
pathType = "L";
// TODO: save previous points and calculate new path just if points are updated, and then save currents values as previous
var targetX = anchor.x, targetY = anchor.y;
if (i>0 && i < this.getAnchorsCount()-1) {
// get new x,y
var cx = anchor.x, cy = anchor.y;
// pivot point of prev line
var AO = this.getLineLength(i-1);
if (AO < this.radius) {
AO = this.radius;
}
this.isDefaultConditionAvailable = (this.isDefaultConditionAvailable || (i == 1 && AO > 10));
var ED = this.getLineLengthY(i-1) * this.radius / AO;
var OD = this.getLineLengthX(i-1) * this.radius / AO;
targetX = anchor.x - OD;
targetY = anchor.y - ED;
if (AO < 2*this.radius && i>1) {
targetX = anchor.x - this.getLineLengthX(i-1)/2;
targetY = anchor.y - this.getLineLengthY(i-1)/2;;
}
// pivot point of next line
var AO = this.getLineLength(i);
if (AO < this.radius) {
AO = this.radius;
}
var ED = this.getLineLengthY(i) * this.radius / AO;
var OD = this.getLineLengthX(i) * this.radius / AO;
var nextSrcX = anchor.x + OD;
var nextSrcY = anchor.y + ED;
if (AO < 2*this.radius && i<this.getAnchorsCount()-2) {
nextSrcX = anchor.x + this.getLineLengthX(i)/2;
nextSrcY = anchor.y + this.getLineLengthY(i)/2;;
}
var dx0 = (cx - targetX) / 3,
dy0 = (cy - targetY) / 3,
ax = cx - dx0,
ay = cy - dy0,
dx1 = (cx - nextSrcX) / 3,
dy1 = (cy - nextSrcY) / 3,
bx = cx - dx1,
by = cy - dy1,
zx=nextSrcX, zy=nextSrcY;
} else if (i==1 && this.getAnchorsCount() == 2){
var AO = this.getLineLength(i-1);
if (AO < this.radius) {
AO = this.radius;
}
this.isDefaultConditionAvailable = (this.isDefaultConditionAvailable || (i == 1 && AO > 10));
}
// anti smoothing
if (this.strokeWidth%2 == 1) {
targetX += 0.5;
targetY += 0.5;
}
path.push([pathType, targetX, targetY]);
if (i>0 && i < this.getAnchorsCount()-1) {
path.push(["C", ax, ay, bx, by, zx, zy]);
}
}
if (this.closePath)
{
path.push(["Z"]);
}
this.path = path;
},
transform: function(transformation)
{
this.element.transform(transformation);
},
attr: function(attrs)
{
// TODO: foreach and set each
this.element.attr(attrs);
}
};
function Polygone(points, strokeWidth) {
/* Array on coordinates:
* points: [{x: 410, y: 110}, 1
* {x: 570, y: 110}, 1 2
* {x: 620, y: 240}, 2 3
* {x: 750, y: 270}, 3 4
* {x: 650, y: 370}]; 4
*/
this.points = points;
/*
* path for graph
* [["M", x1, y1], ["L", x2, y2], ["C", ax, ay, bx, by, x3, y3], ["L", x3, y3]]
*/
this.path = [];
this.anchors = [];
if (strokeWidth) this.strokeWidth = strokeWidth;
this.closePath = true;
this.init();
};
/*
* Poligone is inherited from Poliline: draws closedPath of polyline
*/
var Foo = function () { };
Foo.prototype = Polyline.prototype;
Polygone.prototype = new Foo();
Polygone.prototype.rebuildPath = function(){
var path = [];
for(var i = 0; i < this.getAnchorsCount(); i++){
var anchor = this.getAnchor(i);
var pathType = "";
if (i == 0)
pathType = "M";
else
pathType = "L";
var targetX = anchor.x, targetY = anchor.y;
// anti smoothing
if (this.strokeWidth%2 == 1) {
targetX += 0.5;
targetY += 0.5;
}
path.push([pathType, targetX, targetY]);
}
if (this.closePath)
path.push(["Z"]);
this.path = path;
};

View File

@ -0,0 +1,866 @@
/* Copyright 2005-2015 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function _bpmnGetColor(element, defaultColor)
{
var strokeColor;
if(element.current) {
strokeColor = CURRENT_COLOR;
} else if(element.completed) {
strokeColor = COMPLETED_COLOR;
} else {
strokeColor = defaultColor;
}
return strokeColor;
}
function _drawPool(pool)
{
var rect = paper.rect(pool.x, pool.y, pool.width, pool.height);
rect.attr({"stroke-width": 1,
"stroke": "#000000",
"fill": "white"
});
if (pool.name)
{
var poolName = paper.text(pool.x + 14, pool.y + (pool.height / 2), pool.name).attr({
"text-anchor" : "middle",
"font-family" : "Arial",
"font-size" : "12",
"fill" : "#000000"
});
poolName.transform("r270");
}
if (pool.lanes)
{
for (var i = 0; i < pool.lanes.length; i++)
{
var lane = pool.lanes[i];
_drawLane(lane);
}
}
}
function _drawLane(lane)
{
var rect = paper.rect(lane.x, lane.y, lane.width, lane.height);
rect.attr({"stroke-width": 1,
"stroke": "#000000",
"fill": "white"
});
if (lane.name)
{
var laneName = paper.text(lane.x + 10, lane.y + (lane.height / 2), lane.name).attr({
"text-anchor" : "middle",
"font-family" : "Arial",
"font-size" : "12",
"fill" : "#000000"
});
laneName.transform("r270");
}
}
function _drawSubProcess(element)
{
var rect = paper.rect(element.x, element.y, element.width, element.height, 4);
var strokeColor = _bpmnGetColor(element, MAIN_STROKE_COLOR);
rect.attr({"stroke-width": 1,
"stroke": strokeColor,
"fill": "white"
});
}
function _drawTransaction(element)
{
var rect = paper.rect(element.x, element.y, element.width, element.height, 4);
var strokeColor = _bpmnGetColor(element, MAIN_STROKE_COLOR);
rect.attr({"stroke-width": 1,
"stroke": strokeColor,
"fill": "white"
});
var borderRect = paper.rect(element.x + 2, element.y + 2, element.width - 4, element.height -4, 4);
borderRect.attr({"stroke-width": 1,
"stroke": "black",
"fill": "none"
});
}
function _drawEventSubProcess(element)
{
var rect = paper.rect(element.x, element.y, element.width, element.height, 4);
var strokeColor = _bpmnGetColor(element, MAIN_STROKE_COLOR);
rect.attr({"stroke-width": 1,
"stroke": strokeColor,
"stroke-dasharray": ".",
"fill": "white"
});
}
function _drawAdhocSubProcess(element)
{
var rect = paper.rect(element.x, element.y, element.width, element.height, 4);
var strokeColor = _bpmnGetColor(element, MAIN_STROKE_COLOR);
rect.attr({"stroke-width": 1,
"stroke": strokeColor,
"fill": "white"
});
paper.text(element.x + (element.width / 2), element.y + element.height - 8).attr({
"text-anchor" : "middle",
"font-family" : "Arial",
"font-size" : 20,
"text" : "~",
"fill" : "#373e48"
});
}
function _drawStartEvent(element)
{
var startEvent = _drawEvent(element, NORMAL_STROKE, 15);
startEvent.click(function() {
_zoom(true);
});
_addHoverLogic(element, "circle", MAIN_STROKE_COLOR);
}
function _drawEndEvent(element)
{
var endEvent = _drawEvent(element, ENDEVENT_STROKE, 14);
endEvent.click(function() {
_zoom(false);
});
_addHoverLogic(element, "circle", MAIN_STROKE_COLOR);
}
function _drawEvent(element, strokeWidth, radius)
{
var x = element.x + (element.width / 2);
var y = element.y + (element.height / 2);
var circle = paper.circle(x, y, radius);
var strokeColor = _bpmnGetColor(element, MAIN_STROKE_COLOR);
// Fill
var eventFillColor = _determineCustomFillColor(element, "#ffffff");
// Opacity
var eventOpacity = 1.0;
if (customActivityBackgroundOpacity) {
eventOpacity = customActivityBackgroundOpacity;
}
if (element.interrupting === undefined || element.interrupting) {
circle.attr({
"stroke-width": strokeWidth,
"stroke": strokeColor,
"fill": eventFillColor,
"fill-opacity": eventOpacity
});
} else {
circle.attr({
"stroke-width": strokeWidth,
"stroke": strokeColor,
"stroke-dasharray": ".",
"fill": eventFillColor,
"fill-opacity": eventOpacity
});
}
circle.id = element.id;
_drawEventIcon(paper, element);
return circle;
}
function _drawServiceTask(element)
{
_drawTask(element);
if (element.taskType === "mail")
{
_drawSendTaskIcon(paper, element.x + 4, element.y + 4);
}
else if (element.taskType === "camel")
{
_drawCamelTaskIcon(paper, element.x + 4, element.y + 4);
}
else if (element.taskType === "mule")
{
_drawMuleTaskIcon(paper, element.x + 4, element.y + 4);
}
else if (element.taskType === "http")
{
_drawHttpTaskIcon(paper, element.x + 4, element.y + 4);
}
else if (element.taskType === "shell")
{
_drawShellTaskIcon(paper, element.x + 4, element.y + 4);
}
else if (element.taskType === "dmn") {
_drawDecisionTaskIcon(paper, element.x + 4, element.y + 4);
}
else if (element.stencilIconId)
{
paper.image("../service/stencilitem/" + element.stencilIconId + "/icon", element.x + 4, element.y + 4, 16, 16);
}
else
{
_drawServiceTaskIcon(paper, element.x + 4, element.y + 4);
}
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawHttpServiceTask(element)
{
_drawTask(element);
_drawHttpTaskIcon(paper, element.x + 4, element.y + 4);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawCallActivity(element)
{
var width = element.width - (CALL_ACTIVITY_STROKE / 2);
var height = element.height - (CALL_ACTIVITY_STROKE / 2);
var rect = paper.rect(element.x, element.y, width, height, 4);
var strokeColor = _bpmnGetColor(element, ACTIVITY_STROKE_COLOR);
// Fill
var callActivityFillColor = _determineCustomFillColor(element, ACTIVITY_FILL_COLOR);
// Opacity
var callActivityOpacity = 1.0;
if (customActivityBackgroundOpacity) {
callActivityOpacity = customActivityBackgroundOpacity;
}
rect.attr({"stroke-width": CALL_ACTIVITY_STROKE,
"stroke": strokeColor,
"fill": callActivityFillColor,
"fill-opacity": callActivityOpacity
});
rect.id = element.id;
if (element.name) {
this._drawMultilineText(element.name, element.x, element.y, element.width, element.height, "middle", "middle", 11);
}
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawScriptTask(element)
{
_drawTask(element);
_drawScriptTaskIcon(paper, element.x + 4, element.y + 4);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawUserTask(element)
{
_drawTask(element);
_drawUserTaskIcon(paper, element.x + 4, element.y + 4);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawBusinessRuleTask(element)
{
_drawTask(element);
_drawBusinessRuleTaskIcon(paper, element.x + 4, element.y + 4);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawManualTask(element)
{
_drawTask(element);
_drawManualTaskIcon(paper, element.x + 4, element.y + 4);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawSendTask(element)
{
_drawTask(element);
_drawSendTaskIcon(paper, element.x + 4, element.y + 4);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawReceiveTask(element)
{
_drawTask(element);
_drawReceiveTaskIcon(paper, element.x, element.y);
_addHoverLogic(element, "rect", ACTIVITY_STROKE_COLOR);
}
function _drawTask(element)
{
var rectAttrs = {};
// Stroke
var strokeColor = _bpmnGetColor(element, ACTIVITY_STROKE_COLOR);
rectAttrs['stroke'] = strokeColor;
var strokeWidth;
if (strokeColor === ACTIVITY_STROKE_COLOR) {
strokeWidth = TASK_STROKE;
} else {
strokeWidth = TASK_HIGHLIGHT_STROKE;
}
var width = element.width - (strokeWidth / 2);
var height = element.height - (strokeWidth / 2);
var rect = paper.rect(element.x, element.y, width, height, 4);
rectAttrs['stroke-width'] = strokeWidth;
// Fill
var fillColor = _determineCustomFillColor(element, ACTIVITY_FILL_COLOR);
rectAttrs['fill'] = fillColor;
// Opacity
if (customActivityBackgroundOpacity) {
rectAttrs['fill-opacity'] = customActivityBackgroundOpacity;
}
rect.attr(rectAttrs);
rect.id = element.id;
if (element.name) {
this._drawMultilineText(element.name, element.x, element.y, element.width, element.height, "middle", "middle", 11);
}
}
function _drawExclusiveGateway(element)
{
_drawGateway(element);
var quarterWidth = element.width / 4;
var quarterHeight = element.height / 4;
var iks = paper.path(
"M" + (element.x + quarterWidth + 3) + " " + (element.y + quarterHeight + 3) +
"L" + (element.x + 3 * quarterWidth - 3) + " " + (element.y + 3 * quarterHeight - 3) +
"M" + (element.x + quarterWidth + 3) + " " + (element.y + 3 * quarterHeight - 3) +
"L" + (element.x + 3 * quarterWidth - 3) + " " + (element.y + quarterHeight + 3)
);
var strokeColor = _bpmnGetColor(element, MAIN_STROKE_COLOR);
// Fill
var gatewayFillColor = _determineCustomFillColor(element, ACTIVITY_FILL_COLOR);
// Opacity
var gatewayOpacity = 1.0;
if (customActivityBackgroundOpacity) {
gatewayOpacity = customActivityBackgroundOpacity;
}
iks.attr({"stroke-width": 3, "stroke": strokeColor, "fill": gatewayFillColor, "fill-opacity": gatewayOpacity});
_addHoverLogic(element, "rhombus", MAIN_STROKE_COLOR);
}
function _drawParallelGateway(element)
{
_drawGateway(element);
var strokeColor = _bpmnGetColor(element, MAIN_STROKE_COLOR);
var path1 = paper.path("M 6.75,16 L 25.75,16 M 16,6.75 L 16,25.75");
// Fill
var gatewayFillColor = _determineCustomFillColor(element, ACTIVITY_FILL_COLOR);
// Opacity
var gatewayOpacity = 1.0;
if (customActivityBackgroundOpacity) {
gatewayOpacity = customActivityBackgroundOpacity;
}
path1.attr({
"stroke-width": 3,
"stroke": strokeColor,
"fill": gatewayFillColor,
"fill-opacity": gatewayOpacity
});
path1.transform("T" + (element.x + 4) + "," + (element.y + 4));
_addHoverLogic(element, "rhombus", MAIN_STROKE_COLOR);
}
function _drawInclusiveGateway(element)
{
_drawGateway(element);
var strokeColor = _bpmnGetColor(element, MAIN_STROKE_COLOR);
var circle1 = paper.circle(element.x + (element.width / 2), element.y + (element.height / 2), 9.75);
// Fill
var gatewayFillColor = _determineCustomFillColor(element, ACTIVITY_FILL_COLOR);
// Opacity
var gatewayOpacity = 1.0;
if (customActivityBackgroundOpacity) {
gatewayOpacity = customActivityBackgroundOpacity;
}
circle1.attr({
"stroke-width": 2.5,
"stroke": strokeColor,
"fill": gatewayFillColor,
"fill-opacity": gatewayOpacity
});
_addHoverLogic(element, "rhombus", MAIN_STROKE_COLOR);
}
function _drawEventGateway(element)
{
_drawGateway(element);
var strokeColor = _bpmnGetColor(element, MAIN_STROKE_COLOR);
var circle1 = paper.circle(element.x + (element.width / 2), element.y + (element.height / 2), 10.4);
// Fill
var gatewayFillColor = _determineCustomFillColor(element, ACTIVITY_FILL_COLOR);
// Opacity
var gatewayOpacity = 1.0;
if (customActivityBackgroundOpacity) {
gatewayOpacity = customActivityBackgroundOpacity;
}
circle1.attr({
"stroke-width": 0.5,
"stroke": strokeColor,
"fill": gatewayFillColor,
"fill-opacity": gatewayOpacity
});
var circle2 = paper.circle(element.x + (element.width / 2), element.y + (element.height / 2), 11.7);
circle2.attr({
"stroke-width": 0.5,
"stroke": strokeColor,
"fill": gatewayFillColor,
"fill-opacity": gatewayOpacity
});
var path1 = paper.path("M 20.327514,22.344972 L 11.259248,22.344216 L 8.4577203,13.719549 L 15.794545,8.389969 L 23.130481,13.720774 L 20.327514,22.344972 z");
path1.attr({
"stroke-width": 1.39999998,
"stroke": strokeColor,
"fill": gatewayFillColor,
"fill-opacity": gatewayOpacity,
"stroke-linejoin": "bevel"
});
path1.transform("T" + (element.x + 4) + "," + (element.y + 4));
_addHoverLogic(element, "rhombus", MAIN_STROKE_COLOR);
}
function _drawGateway(element)
{
var strokeColor = _bpmnGetColor(element, MAIN_STROKE_COLOR);
var rhombus = paper.path("M" + element.x + " " + (element.y + (element.height / 2)) +
"L" + (element.x + (element.width / 2)) + " " + (element.y + element.height) +
"L" + (element.x + element.width) + " " + (element.y + (element.height / 2)) +
"L" + (element.x + (element.width / 2)) + " " + element.y + "z"
);
// Fill
var gatewayFillColor = _determineCustomFillColor(element, ACTIVITY_FILL_COLOR);
// Opacity
var gatewayOpacity = 1.0;
if (customActivityBackgroundOpacity) {
gatewayOpacity = customActivityBackgroundOpacity;
}
rhombus.attr("stroke-width", 2);
rhombus.attr("stroke", strokeColor);
rhombus.attr("fill", gatewayFillColor);
rhombus.attr("fill-opacity", gatewayOpacity);
rhombus.id = element.id;
return rhombus;
}
function _drawBoundaryEvent(element)
{
var x = element.x + (element.width / 2);
var y = element.y + (element.height / 2);
var circle = paper.circle(x, y, 15);
var strokeColor = _bpmnGetColor(element, MAIN_STROKE_COLOR);
if (element.cancelActivity) {
circle.attr({
"stroke-width": 1,
"stroke": strokeColor,
"fill": "white"
});
} else {
circle.attr({
"stroke-width": 1,
"stroke-dasharray": ".",
"stroke": strokeColor,
"fill": "white"
});
}
var innerCircle = paper.circle(x, y, 12);
if (element.cancelActivity) {
innerCircle.attr({"stroke-width": 1,
"stroke": strokeColor,
"fill": "none"
});
} else {
innerCircle.attr({
"stroke-width": 1,
"stroke-dasharray": ".",
"stroke": strokeColor,
"fill": "none"
});
}
_drawEventIcon(paper, element);
_addHoverLogic(element, "circle", MAIN_STROKE_COLOR);
circle.id = element.id;
innerCircle.id = element.id + "_inner";
}
function _drawIntermediateCatchEvent(element)
{
var x = element.x + (element.width / 2);
var y = element.y + (element.height / 2);
var circle = paper.circle(x, y, 15);
var strokeColor = _bpmnGetColor(element, MAIN_STROKE_COLOR);
circle.attr({"stroke-width": 1,
"stroke": strokeColor,
"fill": "white"
});
var innerCircle = paper.circle(x, y, 12);
innerCircle.attr({"stroke-width": 1,
"stroke": strokeColor,
"fill": "none"
});
_drawEventIcon(paper, element);
_addHoverLogic(element, "circle", MAIN_STROKE_COLOR);
circle.id = element.id;
innerCircle.id = element.id + "_inner";
}
function _drawThrowEvent(element)
{
var x = element.x + (element.width / 2);
var y = element.y + (element.height / 2);
var circle = paper.circle(x, y, 15);
var strokeColor = _bpmnGetColor(element, MAIN_STROKE_COLOR);
circle.attr({"stroke-width": 1,
"stroke": strokeColor,
"fill": "white"
});
var innerCircle = paper.circle(x, y, 12);
innerCircle.attr({"stroke-width": 1,
"stroke": strokeColor,
"fill": "none"
});
_drawEventIcon(paper, element);
_addHoverLogic(element, "circle", MAIN_STROKE_COLOR);
circle.id = element.id;
innerCircle.id = element.id + "_inner";
}
function _drawMultilineText(text, x, y, boxWidth, boxHeight, horizontalAnchor, verticalAnchor, fontSize)
{
if (!text || text == "")
{
return;
}
var textBoxX, textBoxY;
var width = boxWidth - (2 * TEXT_PADDING);
if (horizontalAnchor === "middle")
{
textBoxX = x + (boxWidth / 2);
}
else if (horizontalAnchor === "start")
{
textBoxX = x;
}
textBoxY = y + (boxHeight / 2);
var t = paper.text(textBoxX + TEXT_PADDING, textBoxY + TEXT_PADDING).attr({
"text-anchor" : horizontalAnchor,
"font-family" : "Arial",
"font-size" : fontSize,
"fill" : "#373e48"
});
var abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
t.attr({
"text" : abc
});
var letterWidth = t.getBBox().width / abc.length;
t.attr({
"text" : text
});
var removedLineBreaks = text.split("\n");
var x = 0, s = [];
for (var r = 0; r < removedLineBreaks.length; r++)
{
var words = removedLineBreaks[r].split(" ");
for ( var i = 0; i < words.length; i++) {
var l = words[i].length;
if (x + (l * letterWidth) > width) {
s.push("\n");
x = 0;
}
x += l * letterWidth;
s.push(words[i] + " ");
}
s.push("\n");
x = 0;
}
t.attr({
"text" : s.join("")
});
if (verticalAnchor && verticalAnchor === "top")
{
t.attr({"y": y + (t.getBBox().height / 2)});
}
}
function _drawTextAnnotation(element)
{
var path1 = paper.path("M20,1 L1,1 L1,50 L20,50");
path1.attr({
"stroke": "#585858",
"fill": "none"
});
var annotation = paper.set();
annotation.push(path1);
annotation.transform("T" + element.x + "," + element.y);
if (element.text) {
this._drawMultilineText(element.text, element.x + 2, element.y, element.width, element.height, "start", "middle", 11);
}
}
function _drawFlow(flow){
var polyline = new Polyline(flow.id, flow.waypoints, SEQUENCEFLOW_STROKE, paper);
var strokeColor = _bpmnGetColor(flow, MAIN_STROKE_COLOR);
polyline.element = paper.path(polyline.path);
polyline.element.attr({"stroke-width":SEQUENCEFLOW_STROKE});
polyline.element.attr({"stroke":strokeColor});
polyline.element.id = flow.id;
var lastLineIndex = polyline.getLinesCount() - 1;
var line = polyline.getLine(lastLineIndex);
if (line == undefined) return;
if (flow.type == "connection" && flow.conditions)
{
var middleX = (line.x1 + line.x2) / 2;
var middleY = (line.y1 + line.y2) / 2;
var image = paper.image("../editor/images/condition-flow.png", middleX - 8, middleY - 8, 16, 16);
}
var polylineInvisible = new Polyline(flow.id, flow.waypoints, SEQUENCEFLOW_STROKE, paper);
polylineInvisible.element = paper.path(polyline.path);
polylineInvisible.element.attr({
"opacity": 0,
"stroke-width": 8,
"stroke" : "#000000"
});
if (flow.name) {
var firstLine = polyline.getLine(0);
var angle;
if (firstLine.x1 !== firstLine.x2) {
angle = Math.atan((firstLine.y2 - firstLine.y1) / (firstLine.x2 - firstLine.x1));
} else if (firstLine.y1 < firstLine.y2) {
angle = Math.PI / 2;
} else {
angle = -Math.PI / 2;
}
var flowName = paper.text(firstLine.x1, firstLine.y1, flow.name).attr({
"text-anchor": "middle",
"font-family" : "Arial",
"font-size" : "12",
"fill" : "#000000"
});
var offsetX = (flowName.getBBox().width / 2 + 5);
var offsetY = -(flowName.getBBox().height / 2 + 5);
if (firstLine.x1 > firstLine.x2) {
offsetX = -offsetX;
}
var rotatedOffsetX = offsetX * Math.cos(angle) - offsetY * Math.sin(angle);
var rotatedOffsetY = offsetX * Math.sin(angle) + offsetY * Math.cos(angle);
flowName.attr({
x: firstLine.x1 + rotatedOffsetX,
y: firstLine.y1 + rotatedOffsetY
});
flowName.transform("r" + ((angle) * 180) / Math.PI);
}
_showTip(jQuery(polylineInvisible.element.node), flow);
polylineInvisible.element.mouseover(function() {
paper.getById(polyline.element.id).attr({"stroke":"blue"});
});
polylineInvisible.element.mouseout(function() {
paper.getById(polyline.element.id).attr({"stroke":"#585858"});
});
_drawArrowHead(line);
}
function _drawAssociation(flow){
var polyline = new Polyline(flow.id, flow.waypoints, ASSOCIATION_STROKE, paper);
polyline.element = paper.path(polyline.path);
polyline.element.attr({"stroke-width": ASSOCIATION_STROKE});
polyline.element.attr({"stroke-dasharray": ". "});
polyline.element.attr({"stroke":"#585858"});
polyline.element.id = flow.id;
var polylineInvisible = new Polyline(flow.id, flow.waypoints, ASSOCIATION_STROKE, paper);
polylineInvisible.element = paper.path(polyline.path);
polylineInvisible.element.attr({
"opacity": 0,
"stroke-width": 8,
"stroke" : "#000000"
});
_showTip(jQuery(polylineInvisible.element.node), flow);
polylineInvisible.element.mouseover(function() {
paper.getById(polyline.element.id).attr({"stroke":"blue"});
});
polylineInvisible.element.mouseout(function() {
paper.getById(polyline.element.id).attr({"stroke":"#585858"});
});
}
function _drawArrowHead(line, connectionType)
{
var doubleArrowWidth = 2 * ARROW_WIDTH;
var arrowHead = paper.path("M0 0L-" + (ARROW_WIDTH / 2 + .5) + " -" + doubleArrowWidth + "L" + (ARROW_WIDTH/2 + .5) + " -" + doubleArrowWidth + "z");
// anti smoothing
if (this.strokeWidth%2 == 1)
line.x2 += .5, line.y2 += .5;
arrowHead.transform("t" + line.x2 + "," + line.y2 + "");
arrowHead.transform("...r" + Raphael.deg(line.angle - Math.PI / 2) + " " + 0 + " " + 0);
arrowHead.attr("fill", "#585858");
arrowHead.attr("stroke-width", SEQUENCEFLOW_STROKE);
arrowHead.attr("stroke", "#585858");
return arrowHead;
}
function _determineCustomFillColor(element, defaultColor) {
var color;
// By name
if (customActivityColors && customActivityColors[element.name]) {
color = customActivityColors[element.name];
}
if (color !== null && color !== undefined) {
return color;
}
// By id
if (customActivityColors && customActivityColors[element.id]) {
color = customActivityColors[element.id];
}
if (color !== null && color !== undefined) {
return color;
}
return defaultColor;
}

View File

@ -0,0 +1,342 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function _drawUserTaskIcon(paper, startX, startY)
{
var path1 = paper.path("m 1,17 16,0 0,-1.7778 -5.333332,-3.5555 0,-1.7778 c 1.244444,0 1.244444,-2.3111 1.244444,-2.3111 l 0,-3.0222 C 12.555557,0.8221 9.0000001,1.0001 9.0000001,1.0001 c 0,0 -3.5555556,-0.178 -3.9111111,3.5555 l 0,3.0222 c 0,0 0,2.3111 1.2444443,2.3111 l 0,1.7778 L 1,15.2222 1,17 17,17");
path1.attr({
"opacity": 1,
"stroke": "none",
"fill": "#d1b575"
});
var userTaskIcon = paper.set();
userTaskIcon.push(path1);
userTaskIcon.transform("T" + startX + "," + startY);
}
function _drawServiceTaskIcon(paper, startX, startY)
{
var path1 = paper.path("M 8,1 7.5,2.875 c 0,0 -0.02438,0.250763 -0.40625,0.4375 C 7.05724,3.330353 7.04387,3.358818 7,3.375 6.6676654,3.4929791 6.3336971,3.6092802 6.03125,3.78125 6.02349,3.78566 6.007733,3.77681 6,3.78125 5.8811373,3.761018 5.8125,3.71875 5.8125,3.71875 l -1.6875,-1 -1.40625,1.4375 0.96875,1.65625 c 0,0 0.065705,0.068637 0.09375,0.1875 0.002,0.00849 -0.00169,0.022138 0,0.03125 C 3.6092802,6.3336971 3.4929791,6.6676654 3.375,7 3.3629836,7.0338489 3.3239228,7.0596246 3.3125,7.09375 3.125763,7.4756184 2.875,7.5 2.875,7.5 L 1,8 l 0,2 1.875,0.5 c 0,0 0.250763,0.02438 0.4375,0.40625 0.017853,0.03651 0.046318,0.04988 0.0625,0.09375 0.1129372,0.318132 0.2124732,0.646641 0.375,0.9375 -0.00302,0.215512 -0.09375,0.34375 -0.09375,0.34375 L 2.6875,13.9375 4.09375,15.34375 5.78125,14.375 c 0,0 0.1229911,-0.09744 0.34375,-0.09375 0.2720511,0.147787 0.5795915,0.23888 0.875,0.34375 0.033849,0.01202 0.059625,0.05108 0.09375,0.0625 C 7.4756199,14.874237 7.5,15.125 7.5,15.125 L 8,17 l 2,0 0.5,-1.875 c 0,0 0.02438,-0.250763 0.40625,-0.4375 0.03651,-0.01785 0.04988,-0.04632 0.09375,-0.0625 0.332335,-0.117979 0.666303,-0.23428 0.96875,-0.40625 0.177303,0.0173 0.28125,0.09375 0.28125,0.09375 l 1.65625,0.96875 1.40625,-1.40625 -0.96875,-1.65625 c 0,0 -0.07645,-0.103947 -0.09375,-0.28125 0.162527,-0.290859 0.262063,-0.619368 0.375,-0.9375 0.01618,-0.04387 0.04465,-0.05724 0.0625,-0.09375 C 14.874237,10.52438 15.125,10.5 15.125,10.5 L 17,10 17,8 15.125,7.5 c 0,0 -0.250763,-0.024382 -0.4375,-0.40625 C 14.669647,7.0572406 14.641181,7.0438697 14.625,7 14.55912,6.8144282 14.520616,6.6141566 14.4375,6.4375 c -0.224363,-0.4866 0,-0.71875 0,-0.71875 L 15.40625,4.0625 14,2.625 l -1.65625,1 c 0,0 -0.253337,0.1695664 -0.71875,-0.03125 l -0.03125,0 C 11.405359,3.5035185 11.198648,3.4455201 11,3.375 10.95613,3.3588185 10.942759,3.3303534 10.90625,3.3125 10.524382,3.125763 10.5,2.875 10.5,2.875 L 10,1 8,1 z m 1,5 c 1.656854,0 3,1.3431458 3,3 0,1.656854 -1.343146,3 -3,3 C 7.3431458,12 6,10.656854 6,9 6,7.3431458 7.3431458,6 9,6 z");
path1.attr({
"opacity": 1,
"stroke": "none",
"fill": "#72a7d0"
});
var serviceTaskIcon = paper.set();
serviceTaskIcon.push(path1);
serviceTaskIcon.transform("T" + startX + "," + startY);
}
function _drawScriptTaskIcon(paper, startX, startY)
{
var path1 = paper.path("m 5,2 0,0.094 c 0.23706,0.064 0.53189,0.1645 0.8125,0.375 0.5582,0.4186 1.05109,1.228 1.15625,2.5312 l 8.03125,0 1,0 1,0 c 0,-3 -2,-3 -2,-3 l -10,0 z M 4,3 4,13 2,13 c 0,3 2,3 2,3 l 9,0 c 0,0 2,0 2,-3 L 15,6 6,6 6,5.5 C 6,4.1111 5.5595,3.529 5.1875,3.25 4.8155,2.971 4.5,3 4.5,3 L 4,3 z");
path1.attr({
"opacity": 1,
"stroke": "none",
"fill": "#72a7d0"
});
var scriptTaskIcon = paper.set();
scriptTaskIcon.push(path1);
scriptTaskIcon.transform("T" + startX + "," + startY);
}
function _drawBusinessRuleTaskIcon(paper, startX, startY)
{
var path1 = paper.path("m 1,2 0,14 16,0 0,-14 z m 1.45458,5.6000386 2.90906,0 0,2.7999224 -2.90906,0 z m 4.36364,0 8.72718,0 0,2.7999224 -8.72718,0 z m -4.36364,4.1998844 2.90906,0 0,2.800116 -2.90906,0 z m 4.36364,0 8.72718,0 0,2.800116 -8.72718,0 z");
path1.attr({
"stroke": "none",
"fill": "#72a7d0"
});
var businessRuleTaskIcon = paper.set();
businessRuleTaskIcon.push(path1);
businessRuleTaskIcon.transform("T" + startX + "," + startY);
}
function _drawSendTaskIcon(paper, startX, startY)
{
var path1 = paper.path("M 1 3 L 9 11 L 17 3 L 1 3 z M 1 5 L 1 13 L 5 9 L 1 5 z M 17 5 L 13 9 L 17 13 L 17 5 z M 6 10 L 1 15 L 17 15 L 12 10 L 9 13 L 6 10 z");
path1.attr({
"stroke": "none",
"fill": "#16964d"
});
var sendTaskIcon = paper.set();
sendTaskIcon.push(path1);
sendTaskIcon.transform("T" + startX + "," + startY);
}
function _drawManualTaskIcon(paper, startX, startY)
{
var path1 = paper.path("m 17,9.3290326 c -0.0069,0.5512461 -0.455166,1.0455894 -0.940778,1.0376604 l -5.792746,0 c 0.0053,0.119381 0.0026,0.237107 0.0061,0.355965 l 5.154918,0 c 0.482032,-0.0096 0.925529,0.49051 0.919525,1.037574 -0.0078,0.537128 -0.446283,1.017531 -0.919521,1.007683 l -5.245273,0 c -0.01507,0.104484 -0.03389,0.204081 -0.05316,0.301591 l 2.630175,0 c 0.454137,-0.0096 0.872112,0.461754 0.866386,0.977186 C 13.619526,14.554106 13.206293,15.009498 12.75924,15 L 3.7753054,15 C 3.6045812,15 3.433552,14.94423 3.2916363,14.837136 c -0.00174,0 -0.00436,0 -0.00609,0 C 1.7212035,14.367801 0.99998255,11.458641 1,11.458641 L 1,7.4588393 c 0,0 0.6623144,-1.316333 1.8390583,-2.0872584 1.1767614,-0.7711868 6.8053358,-2.40497 7.2587847,-2.8052901 0.453484,-0.40032 1.660213,1.4859942 0.04775,2.4010487 C 8.5332315,5.882394 8.507351,5.7996113 8.4370292,5.7936859 l 6.3569748,-0.00871 c 0.497046,-0.00958 0.952273,0.5097676 0.94612,1.0738232 -0.0053,0.556126 -0.456176,1.0566566 -0.94612,1.0496854 l -4.72435,0 c 0.01307,0.1149374 0.0244,0.2281319 0.03721,0.3498661 l 5.952195,0 c 0.494517,-0.00871 0.947906,0.5066305 0.940795,1.0679848 z");
path1.attr({
"opacity": 1,
"stroke": "none",
"fill": "#d1b575"
});
var manualTaskIcon = paper.set();
manualTaskIcon.push(path1);
manualTaskIcon.transform("T" + startX + "," + startY);
}
function _drawReceiveTaskIcon(paper, startX, startY)
{
var path = paper.path("m 0.5,2.5 0,13 17,0 0,-13 z M 2,4 6.5,8.5 2,13 z M 4,4 14,4 9,9 z m 12,0 0,9 -4.5,-4.5 z M 7.5,9.5 9,11 10.5,9.5 15,14 3,14 z");
path.attr({
"opacity": 1,
"stroke": "none",
"fill": "#16964d"
});
startX += 4;
startY += 2;
path.transform("T" + startX + "," + startY);
}
function _drawCamelTaskIcon(paper, startX, startY)
{
var path = paper.path("m 8.1878027,15.383782 c -0.824818,-0.3427 0.375093,-1.1925 0.404055,-1.7743 0.230509,-0.8159 -0.217173,-1.5329 -0.550642,-2.2283 -0.106244,-0.5273 -0.03299,-1.8886005 -0.747194,-1.7818005 -0.712355,0.3776 -0.9225,1.2309005 -1.253911,1.9055005 -0.175574,1.0874 -0.630353,2.114 -0.775834,3.2123 -0.244009,0.4224 -1.741203,0.3888 -1.554386,-0.1397 0.651324,-0.3302 1.13227,-0.9222 1.180246,-1.6705 0.0082,-0.7042 -0.133578,-1.3681 0.302178,-2.0083 0.08617,-0.3202 0.356348,-1.0224005 -0.218996,-0.8051 -0.694517,0.2372 -1.651062,0.6128 -2.057645,-0.2959005 -0.696769,0.3057005 -1.102947,-0.611 -1.393127,-1.0565 -0.231079,-0.6218 -0.437041,-1.3041 -0.202103,-1.9476 -0.185217,-0.7514 -0.39751099,-1.5209 -0.35214999,-2.301 -0.243425,-0.7796 0.86000899,-1.2456 0.08581,-1.8855 -0.76078999,0.1964 -1.41630099,-0.7569 -0.79351899,-1.2877 0.58743,-0.52829998 1.49031699,-0.242 2.09856399,-0.77049998 0.816875,-0.3212 1.256619,0.65019998 1.923119,0.71939998 0.01194,0.7333 -0.0031,1.5042 -0.18417,2.2232 -0.194069,0.564 -0.811196,1.6968 0.06669,1.9398 0.738382,-0.173 1.095723,-0.9364 1.659041,-1.3729 0.727298,-0.3962 1.093982,-1.117 1.344137,-1.8675 0.400558,-0.8287 1.697676,-0.6854 1.955367,0.1758 0.103564,0.5511 0.9073983,1.7538 1.2472763,0.6846 0.121868,-0.6687 0.785541,-1.4454 1.518183,-1.0431 0.813587,0.4875 0.658233,1.6033 1.285504,2.2454 0.768715,0.8117 1.745394,1.4801 2.196633,2.5469 0.313781,0.8074 0.568552,1.707 0.496624,2.5733 -0.35485,0.8576005 -1.224508,-0.216 -0.64725,-0.7284 0.01868,-0.3794 -0.01834,-1.3264 -0.370249,-1.3272 -0.123187,0.7586 -0.152778,1.547 -0.10869,2.3154 0.270285,0.6662005 1.310741,0.7653005 1.060553,1.6763005 -0.03493,0.9801 0.294343,1.9505 0.148048,2.9272 -0.320479,0.2406 -0.79575,0.097 -1.185062,0.1512 -0.165725,0.3657 -0.40138,0.921 -1.020848,0.6744 -0.564671,0.1141 -1.246404,-0.266 -0.578559,-0.7715 0.679736,-0.5602 0.898618,-1.5362 0.687058,-2.3673 -0.529674,-1.108 -1.275984,-2.0954005 -1.839206,-3.1831005 -0.634619,-0.1004 -1.251945,0.6779 -1.956789,0.7408 -0.6065893,-0.038 -1.0354363,-0.06 -0.8495673,0.6969005 0.01681,0.711 0.152396,1.3997 0.157345,2.1104 0.07947,0.7464 0.171287,1.4944 0.238271,2.2351 0.237411,1.0076 -0.687542,1.1488 -1.414811,0.8598 z m 6.8675483,-1.8379 c 0.114364,-0.3658 0.206751,-1.2704 -0.114466,-1.3553 -0.152626,0.5835 -0.225018,1.1888 -0.227537,1.7919 0.147087,-0.1166 0.265559,-0.2643 0.342003,-0.4366 z");
path.attr({
"opacity": 1,
"stroke": "none",
"fill": "#bd4848"
});
startX += 4;
startY += 2;
path.transform("T" + startX + "," + startY);
}
function _drawMuleTaskIcon(paper, startX, startY)
{
var path = paper.path("M 8,0 C 3.581722,0 0,3.5817 0,8 c 0,4.4183 3.581722,8 8,8 4.418278,0 8,-3.5817 8,-8 L 16,7.6562 C 15.813571,3.3775 12.282847,0 8,0 z M 5.1875,2.7812 8,7.3437 10.8125,2.7812 c 1.323522,0.4299 2.329453,1.5645 2.8125,2.8438 1.136151,2.8609 -0.380702,6.4569 -3.25,7.5937 -0.217837,-0.6102 -0.438416,-1.2022 -0.65625,-1.8125 0.701032,-0.2274 1.313373,-0.6949 1.71875,-1.3125 0.73624,-1.2317 0.939877,-2.6305 -0.03125,-4.3125 l -2.75,4.0625 -0.65625,0 -0.65625,0 -2.75,-4 C 3.5268433,7.6916 3.82626,8.862 4.5625,10.0937 4.967877,10.7113 5.580218,11.1788 6.28125,11.4062 6.063416,12.0165 5.842837,12.6085 5.625,13.2187 2.755702,12.0819 1.238849,8.4858 2.375,5.625 2.858047,4.3457 3.863978,3.2112 5.1875,2.7812 z");
path.attr({
"opacity": 1,
"stroke": "none",
"fill": "#bd4848"
});
startX += 4;
startY += 2;
path.transform("T" + startX + "," + startY);
}
function _drawAlfrescoPublishTaskIcon(paper, startX, startY)
{
startX += 2;
startY += 2;
var path = paper.path("M4.11870968,2.12890323 L6.12954839,0.117935484 L3.10993548,0.118064516 L3.10270968,0.118064516 C1.42941935,0.118064516 0.0729032258,1.47458065 0.0729032258,3.14774194 C0.0729032258,4.82116129 1.42929032,6.17754839 3.10258065,6.17754839 C3.22967742,6.17754839 3.35470968,6.16877419 3.47767742,6.15354839 C2.8163871,4.85083871 3.02954839,3.21793548 4.11870968,2.12890323M6.57032258,3.144 L6.57032258,0.300258065 L4.43522581,2.4356129 L4.43006452,2.44064516 C3.24683871,3.62387097 3.24683871,5.54219355 4.43006452,6.72541935 C5.61329032,7.90864516 7.5316129,7.90864516 8.71483871,6.72541935 C8.80464516,6.6356129 8.88529032,6.54025806 8.96154839,6.44270968 C7.57341935,5.98864516 6.57045161,4.68387097 6.57032258,3.144");
path.attr({"fill": "#87C040"});
var startX1 = startX + 1.419355;
var startY1 = startY + 8.387097;
path.transform("T" + startX1 + "," + startY1);
path = paper.path("M10.4411613,10.5153548 L8.43032258,8.50451613 L8.43032258,11.5313548 C8.43032258,13.2047742 9.78683871,14.5611613 11.460129,14.5611613 C13.1334194,14.5611613 14.4899355,13.2047742 14.4899355,11.5314839 C14.4899355,11.4043871 14.4811613,11.2793548 14.4659355,11.1563871 C13.1632258,11.8178065 11.5303226,11.6045161 10.4411613,10.5153548M15.0376774,5.91935484 C14.947871,5.82954839 14.8526452,5.74890323 14.7550968,5.67264516 C14.3010323,7.06064516 12.996129,8.06374194 11.4563871,8.06374194 L8.61277419,8.06374194 L10.7529032,10.204 C11.936129,11.3872258 13.8545806,11.3872258 15.0376774,10.204 C16.2209032,9.02077419 16.2209032,7.10245161 15.0376774,5.91935484");
path.attr({"fill": "#87C040"});
path.transform("T" + startX + "," + startY);
path = paper.path("M5.9083871,1.5636129 C5.78129032,1.5636129 5.65625806,1.57225806 5.53329032,1.58748387 C6.19458065,2.89032258 5.98141935,4.52309677 4.89225806,5.61225806 L2.88154839,7.62309677 L5.9083871,7.62309677 C7.58154839,7.62309677 8.93806452,6.26658065 8.93806452,4.59329032 C8.93819355,2.92 7.58167742,1.5636129 5.9083871,1.5636129");
path.attr({"fill": "#ED9A2D"});
var startX2 = startX + 5.548387;
path.transform("T" + startX2 + "," + startY);
path = paper.path("M4.58090323,1.0156129 C3.39767742,-0.167483871 1.47935484,-0.167483871 0.296129032,1.01574194 C0.206451613,1.10554839 0.125806452,1.20077419 0.0495483871,1.29845161 C1.43754839,1.75251613 2.44064516,3.05729032 2.44064516,4.59703226 L2.44064516,7.44077419 L4.57574194,5.30554839 L4.58090323,5.30051613 C5.76412903,4.11729032 5.76412903,2.19896774 4.58090323,1.0156129");
path.attr({"fill": "#5698C6"});
path.transform("T" + startX2 + "," + startY);
path = paper.path("M5.54051613,5.61432258 L5.62670968,5.70425806 L7.54632258,7.62387097 L7.5483871,7.62387097 L7.5483871,4.604 L7.5483871,4.59677419 C7.5483871,2.92348387 6.19187097,1.56696774 4.51858065,1.56696774 C2.84529032,1.56696774 1.48877419,2.92335484 1.48890323,4.59664516 C1.48890323,4.72348387 1.49754839,4.84812903 1.51264516,4.97083871 C2.81625806,4.30993548 4.45122581,4.52503226 5.54051613,5.61432258M1.23251613,10.4292903 C1.25625806,10.3588387 1.28180645,10.2894194 1.30980645,10.2210323 C1.31329032,10.2123871 1.3163871,10.2036129 1.32,10.1952258 C1.35070968,10.1216774 1.38451613,10.0500645 1.42,9.97935484 C1.42774194,9.96374194 1.43574194,9.9483871 1.44387097,9.93277419 C1.4803871,9.86258065 1.51883871,9.79354839 1.55987097,9.72632258 C1.56425806,9.71909677 1.56903226,9.71225806 1.57341935,9.70529032 C1.6123871,9.64245161 1.65354839,9.58141935 1.6963871,9.52141935 C1.70516129,9.50903226 1.71380645,9.49651613 1.72283871,9.48425806 C1.76890323,9.42154839 1.81690323,9.36064516 1.86683871,9.30129032 C1.87703226,9.28916129 1.88735484,9.27741935 1.89780645,9.26567742 C1.94658065,9.20916129 1.99690323,9.15406452 2.04916129,9.10090323 C2.05380645,9.09625806 2.05806452,9.09135484 2.06270968,9.08670968 C2.11832258,9.03083871 2.17625806,8.97741935 2.23548387,8.92554839 C2.2483871,8.91419355 2.26129032,8.90296774 2.27432258,8.89187097 C2.33393548,8.84103226 2.39496774,8.79212903 2.45780645,8.74529032 C2.46606452,8.73922581 2.47470968,8.73354839 2.48296774,8.7276129 C2.54167742,8.68490323 2.60180645,8.64412903 2.66322581,8.60503226 C2.67535484,8.59729032 2.68735484,8.58929032 2.6996129,8.58167742 C2.76593548,8.54064516 2.83380645,8.50206452 2.90296774,8.46541935 C2.91754839,8.45780645 2.93225806,8.45045161 2.94696774,8.44296774 C3.016,8.40774194 3.08593548,8.37406452 3.15741935,8.34348387 C3.16090323,8.34206452 3.16425806,8.3403871 3.16774194,8.33883871 C3.24167742,8.30748387 3.31729032,8.27948387 3.39380645,8.25316129 C3.41032258,8.24748387 3.42670968,8.24180645 3.44335484,8.2363871 C3.51909677,8.21174194 3.59587097,8.18903226 3.67380645,8.16929032 C3.68567742,8.16645161 3.69793548,8.16387097 3.70980645,8.16116129 C3.78206452,8.14374194 3.85509677,8.12877419 3.92890323,8.116 C3.94270968,8.11367742 3.9563871,8.11083871 3.97019355,8.10877419 C4.05032258,8.09587097 4.13148387,8.08619355 4.21329032,8.07896774 C4.23096774,8.07741935 4.24877419,8.07625806 4.26645161,8.07483871 C4.35109677,8.06877419 4.43612903,8.06451613 4.52232258,8.06451613 L7.36606452,8.0643871 L5.22580645,5.92412903 C4.04258065,4.74103226 2.12412903,4.74090323 0.941032258,5.92412903 C-0.242193548,7.10735484 -0.242193548,9.02567742 0.941032258,10.2089032 C1.03070968,10.2985806 1.12464516,10.3814194 1.22206452,10.4575484 C1.22529032,10.448 1.22929032,10.4388387 1.23251613,10.4292903");
path.attr({"fill": "#5698C6"});
path.transform("T" + startX + "," + startY);
path = paper.path("M5.23290323,5.92412903 L6.92748387,7.61870968 L4.64980645,7.61870968 L4.52064516,7.62141935 C3.13354839,7.62141935 1.96425806,6.68929032 1.60477419,5.41729032 C2.75870968,4.77019355 4.24619355,4.93754839 5.22787097,5.91909677 L5.23290323,5.92412903M7.54722581,4.59612903 L7.54722581,6.99264516 L5.93664516,5.38206452 L5.84348387,5.29264516 C4.86258065,4.31187097 4.69483871,2.82580645 5.34012903,1.67225806 C6.61367742,2.03070968 7.54722581,3.20090323 7.54722581,4.58890323 L7.54722581,4.59612903M10.1385806,5.29819355 L8.444,6.99290323 L8.444,4.71522581 L8.44129032,4.58606452 C8.44129032,3.19896774 9.37341935,2.02954839 10.6454194,1.67019355 C11.2925161,2.82412903 11.1251613,4.3116129 10.1436129,5.29316129 L10.1385806,5.29819355");
path.attr({"fill": "#446BA5"});
path.transform("T" + startX + "," + startY);
path = paper.path("M11.4548387,7.61677419 L9.05832258,7.61677419 L10.6689032,6.00619355 L10.7583226,5.91303226 C11.7390968,4.93212903 13.2251613,4.7643871 14.3787097,5.40967742 C14.0202581,6.68322581 12.8500645,7.61677419 11.4620645,7.61677419 L11.4548387,7.61677419");
path.attr({"fill": "#FFF101"});
path.transform("T" + startX + "," + startY);
path = paper.path("M10.7470968,10.192 L9.05251613,8.49741935 L11.3301935,8.49741935 L11.4593548,8.49470968 C12.8464516,8.49483871 14.0157419,9.42696774 14.3752258,10.6989677 C13.2211613,11.3459355 11.7338065,11.1787097 10.752129,10.1970323 L10.7470968,10.192M8.43729032,11.5174194 L8.43729032,9.12090323 L10.047871,10.7314839 L10.1411613,10.8209032 C11.1219355,11.8018065 11.2896774,13.2876129 10.6443871,14.4412903 C9.37083871,14.0828387 8.43729032,12.9127742 8.43729032,11.5245161 L8.43729032,11.5174194M5.86193548,10.8296774 L7.55651613,9.13496774 L7.55651613,11.4126452 L7.55922581,11.5418065 C7.55922581,12.9289032 6.62709677,14.0983226 5.35509677,14.4578065 C4.708,13.3036129 4.87535484,11.8162581 5.85690323,10.8347097 L5.86193548,10.8296774M4.53251613,8.50993548 L6.92903226,8.50993548 L5.31845161,10.1205161 L5.22903226,10.2136774 C4.24812903,11.1945806 2.76219355,11.3623226 1.60851613,10.7170323 C1.96709677,9.44335484 3.13716129,8.50993548 4.52529032,8.50993548 L4.53251613,8.50993548");
path.attr({"fill": "#45AB47"});
path.transform("T" + startX + "," + startY);
}
function _drawHttpTaskIcon(paper, startX, startY)
{
var path = paper.path("m 16.704699,5.9229055 q 0.358098,0 0.608767,0.2506681 0.250669,0.250668 0.250669,0.6087677 0,0.3580997 -0.250669,0.6087677 -0.250669,0.2506679 -0.608767,0.2506679 -0.358098,0 -0.608767,-0.2506679 -0.250669,-0.250668 -0.250669,-0.6087677 0,-0.3580997 0.250669,-0.6087677 0.250669,-0.2506681 0.608767,-0.2506681 z m 2.578308,-2.0053502 q -2.229162,0 -3.854034,0.6759125 -1.624871,0.6759067 -3.227361,2.2694472 -0.716197,0.725146 -1.575633,1.7457293 L 7.2329969,8.7876913 Q 7.0897576,8.8055849 7.000233,8.9309334 L 4.9948821,12.368677 q -0.035811,0.06267 -0.035811,0.143242 0,0.107426 0.080572,0.205905 l 0.5729577,0.572957 q 0.125334,0.116384 0.2864786,0.07162 l 2.4708789,-0.760963 2.5156417,2.515645 -0.76096,2.470876 q -0.009,0.02687 -0.009,0.08057 0,0.125338 0.08058,0.205905 l 0.572957,0.572958 q 0.170096,0.152194 0.349146,0.04476 l 3.437744,-2.005351 q 0.125335,-0.08953 0.143239,-0.232763 l 0.17905,-3.392986 q 1.02058,-0.859435 1.745729,-1.575629 1.67411,-1.6830612 2.309735,-3.2049805 0.635625,-1.5219191 0.635625,-3.8585111 0,-0.1253369 -0.08505,-0.2148575 -0.08505,-0.089526 -0.201431,-0.089526 z");
path.attr({
"opacity": 1,
"stroke": "none",
"fill": "#16964d"
});
startX += -2;
startY += -2;
path.transform("T" + startX + "," + startY);
}
function _drawShellTaskIcon(paper, startX, startY) {
var path = paper.path("m 1,2 0,14 16,0 0,-14 z m 1.4,3 12.7,0 0,10 -12.7,0 z");
path.attr({
"opacity": 1,
"stroke": "none",
"fill": "#16964d"
});
var text = paper.text(3, 9, ">_").attr({
"font-size": "5px",
"fill": "#16964d"
});
startY += -2;
text.transform("T" + startX + "," + startY);
startX += -2;
path.transform("T" + startX + "," + startY);
}
function _drawDecisionTaskIcon(paper, startX, startY) {
var path1 = paper.path("m 1,2 0,14 16,0 0,-14 z m 1.9,2.4000386 3.7,0 0,2.7999224 -3.7,0 z m 4.36364,0 3.7,0 0,2.7999224 -3.7,0 z m 4.36364,0 3.7,0 0,2.7999224 -3.7,0 z m -8.67364,3.9 3.7,0 0,2.7999224 -3.7,0 z m 4.36364,0 3.7,0 0,2.7999224 -3.7,0 z m 4.36364,0 3.7,0 0,2.7999224 -3.7,0 z m -8.67364,3.9 3.7,0 0,2.7999224 -3.7,0 z m 4.36364,0 3.7,0 0,2.7999224 -3.7,0 z m 4.36364,0 3.7,0 0,2.7999224 -3.7,0 z");
path1.attr({
"opacity": 1,
"stroke": "#000000",
"fill": "#F4F6F7"
});
var decisionTaskIcon = paper.set();
decisionTaskIcon.push(path1);
decisionTaskIcon.translate(startX, startY);
decisionTaskIcon.scale(0.7, 0.7);
}
function _drawEventIcon(paper, element)
{
if (element.eventDefinition && element.eventDefinition.type)
{
if ("timer" === element.eventDefinition.type)
{
_drawTimerIcon(paper, element);
}
else if ("error" === element.eventDefinition.type)
{
_drawErrorIcon(paper, element);
}
else if ("signal" === element.eventDefinition.type)
{
_drawSignalIcon(paper, element);
}
else if ("message" === element.eventDefinition.type)
{
_drawMessageIcon(paper, element);
}
}
}
function _drawTimerIcon(paper, element)
{
var x = element.x + (element.width / 2);
var y = element.y + (element.height / 2);
var circle = paper.circle(x, y, 10);
circle.attr({"stroke-width": 1,
"stroke": "black",
"fill": "none"
});
var path = paper.path("M 10 0 C 4.4771525 0 0 4.4771525 0 10 C 0 15.522847 4.4771525 20 10 20 C 15.522847 20 20 15.522847 20 10 C 20 4.4771525 15.522847 1.1842379e-15 10 0 z M 9.09375 1.03125 C 9.2292164 1.0174926 9.362825 1.0389311 9.5 1.03125 L 9.5 3.5 L 10.5 3.5 L 10.5 1.03125 C 15.063526 1.2867831 18.713217 4.9364738 18.96875 9.5 L 16.5 9.5 L 16.5 10.5 L 18.96875 10.5 C 18.713217 15.063526 15.063526 18.713217 10.5 18.96875 L 10.5 16.5 L 9.5 16.5 L 9.5 18.96875 C 4.9364738 18.713217 1.2867831 15.063526 1.03125 10.5 L 3.5 10.5 L 3.5 9.5 L 1.03125 9.5 C 1.279102 5.0736488 4.7225326 1.4751713 9.09375 1.03125 z M 9.5 5 L 9.5 8.0625 C 8.6373007 8.2844627 8 9.0680195 8 10 C 8 11.104569 8.8954305 12 10 12 C 10.931981 12 11.715537 11.362699 11.9375 10.5 L 14 10.5 L 14 9.5 L 11.9375 9.5 C 11.756642 8.7970599 11.20294 8.2433585 10.5 8.0625 L 10.5 5 L 9.5 5 z");
path.attr({
"stroke": "none",
"fill": "#585858"
});
path.transform("T" + (element.x + 5) + "," + (element.y + 5));
return path;
}
function _drawErrorIcon(paper, element)
{
var path = paper.path("M 22.820839,11.171502 L 19.36734,24.58992 L 13.54138,14.281819 L 9.3386512,20.071607 L 13.048949,6.8323057 L 18.996148,16.132659 L 22.820839,11.171502 z");
var fill = "none";
var x = element.x - 1;
var y = element.y - 1;
if (element.type === "EndEvent")
{
fill = "black";
x -= 1;
y -= 1;
}
path.attr({
"stroke": "black",
"stroke-width": 1,
"fill": fill
});
path.transform("T" + x + "," + y);
return path;
}
function _drawSignalIcon(paper, element)
{
var fill = "none";
if (element.type === "ThrowEvent")
{
fill = "black";
}
var path = paper.path("M 8.7124971,21.247342 L 23.333334,21.247342 L 16.022915,8.5759512 L 8.7124971,21.247342 z");
path.attr({
"stroke": "black",
"stroke-width": 1,
"fill": fill
});
path.transform("T" + (element.x - 1) + "," + (element.y - 1));
return path;
}
function _drawMessageIcon(paper, element)
{
var fill = "none";
if (element.type === "ThrowEvent")
{
fill = "black";
}
var path = paper.path("M 1 3 L 9 11 L 17 3 L 1 3 z M 1 5 L 1 13 L 5 9 L 1 5 z M 17 5 L 13 9 L 17 13 L 17 5 z M 6 10 L 1 15 L 17 15 L 12 10 L 9 13 L 6 10 z");
path.attr({
"stroke": "black",
"stroke-width": 1,
"fill": fill
});
path.transform("T" + (element.x + 6) + "," + (element.y + 6));
return path;
}

View File

@ -0,0 +1,24 @@
div[class*='ui-tooltip-kisbpm-'] {
background-color: #ffffff;
border-color: #c5c5c5;
color: #4a4a4a;
font-family: Verdana;
font-size: 12px;
}
div[class*='ui-tooltip-kisbpm-'] .qtip-content {
color: #4a4a4a;
background-color: #ffffff;
font-family: Verdana;
font-size: 12px;
}
.ui-tooltip-kisbpm-bpmn .qtip-titlebar {
color: #FFFFFF;
font-size: 12px;
background: #2B414F;
}
.ui-tooltip-kisbpm-bpmn .qtip-tip {
background-color: #2B414F;
}

View File

@ -0,0 +1,19 @@
<html>
<head>
<!-- build:css display/styles/displaymodel-style.css -->
<link type="text/css" rel="stylesheet" href="display/jquery.qtip.min.css" />
<link type="text/css" rel="stylesheet" href="display/displaymodel.css" />
<!-- endbuild -->
<!-- build:js display/scripts/displaymodel-logic.js -->
<script type="text/javascript" src="display/jquery.qtip.min.js"></script>
<script type="text/javascript" src="display/raphael.min.js"></script>
<script type="text/javascript" src="display/bpmn-draw.js"></script>
<script type="text/javascript" src="display/bpmn-icons.js"></script>
<script type="text/javascript" src="display/Polyline.js"></script>
<script type="text/javascript" src="display/displaymodel.js"></script>
<!-- endbuild -->
</head>
</html>

View File

@ -0,0 +1,317 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var NORMAL_STROKE = 1;
var SEQUENCEFLOW_STROKE = 1.5;
var ASSOCIATION_STROKE = 2;
var TASK_STROKE = 1;
var TASK_HIGHLIGHT_STROKE = 2;
var CALL_ACTIVITY_STROKE = 2;
var ENDEVENT_STROKE = 3;
var COMPLETED_COLOR= "#2632aa";
var TEXT_COLOR= "#373e48";
var CURRENT_COLOR= "#017501";
var HOVER_COLOR= "#666666";
var ACTIVITY_STROKE_COLOR = "#bbbbbb";
var ACTIVITY_FILL_COLOR = "#f9f9f9";
var MAIN_STROKE_COLOR = "#585858";
var TEXT_PADDING = 3;
var ARROW_WIDTH = 4;
var MARKER_WIDTH = 12;
var TASK_FONT = {font: "11px Arial", opacity: 1, fill: Raphael.rgb(0, 0, 0)};
// icons
var ICON_SIZE = 16;
var ICON_PADDING = 4;
var INITIAL_CANVAS_WIDTH;
var INITIAL_CANVAS_HEIGHT;
var paper;
var viewBox;
var viewBoxWidth;
var viewBoxHeight;
var canvasWidth;
var canvasHeight;
var modelDiv = jQuery('#bpmnModel');
var modelId = modelDiv.attr('data-model-id');
var historyModelId = modelDiv.attr('data-history-id');
var processDefinitionId = modelDiv.attr('data-process-definition-id');
var modelType = modelDiv.attr('data-model-type');
// Support for custom background colors for activities
var customActivityColors = modelDiv.attr('data-activity-color-mapping');
if (customActivityColors !== null && customActivityColors !== undefined && customActivityColors.length > 0) {
// Stored on the attribute as a string
customActivityColors = JSON.parse(customActivityColors);
}
var customActivityToolTips = modelDiv.attr('data-activity-tooltips');
if (customActivityToolTips !== null && customActivityToolTips !== undefined && customActivityToolTips.length > 0) {
// Stored on the attribute as a string
customActivityToolTips = JSON.parse(customActivityToolTips);
}
// Support for custom opacity for activity backgrounds
var customActivityBackgroundOpacity = modelDiv.attr('data-activity-opacity');
var elementsAdded = new Array();
var elementsRemoved = new Array();
function _showTip(htmlNode, element)
{
// Custom tooltip
var documentation = undefined;
if (customActivityToolTips) {
if (customActivityToolTips[element.name]) {
documentation = customActivityToolTips[element.name];
} else if (customActivityToolTips[element.id]) {
documentation = customActivityToolTips[element.id];
} else {
documentation = ''; // Show nothing if custom tool tips are enabled
}
}
// Default tooltip, no custom tool tip set
if (documentation === undefined) {
var documentation = "";
if (element.name && element.name.length > 0) {
documentation += "<b>Name</b>: <i>" + element.name + "</i><br/><br/>";
}
if (element.properties) {
for (var i = 0; i < element.properties.length; i++) {
var propName = element.properties[i].name;
if (element.properties[i].type && element.properties[i].type === 'list') {
documentation += '<b>' + propName + '</b>:<br/>';
for (var j = 0; j < element.properties[i].value.length; j++) {
documentation += '<i>' + element.properties[i].value[j] + '</i><br/>';
}
}
else {
documentation += '<b>' + propName + '</b>: <i>' + element.properties[i].value + '</i><br/>';
}
}
}
}
var text = element.type + " ";
if (element.name && element.name.length > 0)
{
text += element.name;
}
else
{
text += element.id;
}
htmlNode.qtip({
content: {
text: documentation,
title: {
text: text
}
},
position: {
my: 'top left',
at: 'bottom center',
viewport: jQuery('#bpmnModel')
},
hide: {
fixed: true, delay: 500,
event: 'click mouseleave'
},
style: {
classes: 'ui-tooltip-kisbpm-bpmn'
}
});
}
function _addHoverLogic(element, type, defaultColor)
{
var strokeColor = _bpmnGetColor(element, defaultColor);
var topBodyRect = null;
if (type === "rect")
{
topBodyRect = paper.rect(element.x, element.y, element.width, element.height);
}
else if (type === "circle")
{
var x = element.x + (element.width / 2);
var y = element.y + (element.height / 2);
topBodyRect = paper.circle(x, y, 15);
}
else if (type === "rhombus")
{
topBodyRect = paper.path("M" + element.x + " " + (element.y + (element.height / 2)) +
"L" + (element.x + (element.width / 2)) + " " + (element.y + element.height) +
"L" + (element.x + element.width) + " " + (element.y + (element.height / 2)) +
"L" + (element.x + (element.width / 2)) + " " + element.y + "z"
);
}
var opacity = 0;
var fillColor = "#ffffff";
if (jQuery.inArray(element.id, elementsAdded) >= 0)
{
opacity = 0.2;
fillColor = "green";
}
if (jQuery.inArray(element.id, elementsRemoved) >= 0)
{
opacity = 0.2;
fillColor = "red";
}
topBodyRect.attr({
"opacity": opacity,
"stroke" : "none",
"fill" : fillColor
});
_showTip(jQuery(topBodyRect.node), element);
topBodyRect.mouseover(function() {
paper.getById(element.id).attr({"stroke":HOVER_COLOR});
});
topBodyRect.mouseout(function() {
paper.getById(element.id).attr({"stroke":strokeColor});
});
}
function _zoom(zoomIn)
{
var tmpCanvasWidth, tmpCanvasHeight;
if (zoomIn)
{
tmpCanvasWidth = canvasWidth * (1.0/0.90);
tmpCanvasHeight = canvasHeight * (1.0/0.90);
}
else
{
tmpCanvasWidth = canvasWidth * (1.0/1.10);
tmpCanvasHeight = canvasHeight * (1.0/1.10);
}
if (tmpCanvasWidth != canvasWidth || tmpCanvasHeight != canvasHeight)
{
canvasWidth = tmpCanvasWidth;
canvasHeight = tmpCanvasHeight;
paper.setSize(canvasWidth, canvasHeight);
}
}
var modelUrl;
if (modelType == 'runtime') {
if (historyModelId) {
modelUrl = FLOWABLE.APP_URL.getProcessInstanceModelJsonHistoryUrl(historyModelId);
} else {
modelUrl = FLOWABLE.APP_URL.getProcessInstanceModelJsonUrl(modelId);
}
} else if (modelType == 'design') {
if (historyModelId) {
modelUrl = FLOWABLE.APP_URL.getModelHistoryModelJsonUrl(modelId, historyModelId);
} else {
modelUrl = FLOWABLE.APP_URL.getModelModelJsonUrl(modelId);
}
} else if (modelType == 'process-definition') {
modelUrl = FLOWABLE.APP_URL.getProcessDefinitionModelJsonUrl(processDefinitionId);
}
var request = jQuery.ajax({
type: 'get',
url: modelUrl + '?nocaching=' + new Date().getTime()
});
request.success(function(data, textStatus, jqXHR) {
if ((!data.elements || data.elements.length == 0) && (!data.pools || data.pools.length == 0)) return;
INITIAL_CANVAS_WIDTH = data.diagramWidth;
if (modelType == 'design') {
INITIAL_CANVAS_WIDTH += 20;
} else {
INITIAL_CANVAS_WIDTH += 30;
}
INITIAL_CANVAS_HEIGHT = data.diagramHeight + 50;
canvasWidth = INITIAL_CANVAS_WIDTH;
canvasHeight = INITIAL_CANVAS_HEIGHT;
viewBoxWidth = INITIAL_CANVAS_WIDTH;
viewBoxHeight = INITIAL_CANVAS_HEIGHT;
if (modelType == 'design') {
var headerBarHeight = 170;
var offsetY = 0;
if (jQuery(window).height() > (canvasHeight + headerBarHeight))
{
offsetY = (jQuery(window).height() - headerBarHeight - canvasHeight) / 2;
}
if (offsetY > 50) {
offsetY = 50;
}
jQuery('#bpmnModel').css('marginTop', offsetY);
}
jQuery('#bpmnModel').width(INITIAL_CANVAS_WIDTH);
jQuery('#bpmnModel').height(INITIAL_CANVAS_HEIGHT);
paper = Raphael(document.getElementById('bpmnModel'), canvasWidth, canvasHeight);
paper.setViewBox(0, 0, viewBoxWidth, viewBoxHeight, false);
paper.renderfix();
if (data.pools)
{
for (var i = 0; i < data.pools.length; i++)
{
var pool = data.pools[i];
_drawPool(pool);
}
}
var modelElements = data.elements;
for (var i = 0; i < modelElements.length; i++)
{
var element = modelElements[i];
//try {
var drawFunction = eval("_draw" + element.type);
drawFunction(element);
//} catch(err) {console.log(err);}
}
if (data.flows)
{
for (var i = 0; i < data.flows.length; i++)
{
var flow = data.flows[i];
if (flow.type === 'sequenceFlow') {
_drawFlow(flow);
} else if (flow.type === 'association') {
_drawAssociation(flow);
}
}
}
});
request.error(function(jqXHR, textStatus, errorThrown) {
alert("error");
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,37 @@
{
"name": "displaymodel",
"version": "1.0.0",
"dependencies": {},
"devDependencies": {
"grunt": "0.4.2",
"grunt-autoprefixer": "0.4.0",
"grunt-bower-install": "0.7.0",
"grunt-concurrent": "0.4.1",
"grunt-contrib-clean": "0.5.0",
"grunt-contrib-coffee": "0.7.0",
"grunt-contrib-compass": "0.6.0",
"grunt-contrib-concat": "0.3.0",
"grunt-contrib-connect": "0.5.0",
"grunt-contrib-copy": "0.4.1",
"grunt-contrib-cssmin": "0.7.0",
"grunt-contrib-htmlmin": "0.1.3",
"grunt-contrib-imagemin": "0.3.0",
"grunt-contrib-jshint": "0.7.1",
"grunt-contrib-uglify": "0.2.0",
"grunt-contrib-watch": "0.5.2",
"grunt-google-cdn": "0.2.0",
"grunt-newer": "0.5.4",
"grunt-ng-annotate": "0.5.0",
"grunt-rev": "0.1.0",
"grunt-svgmin": "0.2.0",
"grunt-usemin": "2.0.0",
"jshint-stylish": "0.1.3",
"load-grunt-tasks": "0.2.0",
"time-grunt": "0.2.1",
"grunt-text-replace": "0.3.11",
"grunt-contrib-rename": "0.0.3"
},
"engines": {
"node": ">=0.8.0"
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,19 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
FLOWABLE.HEADER_CONFIG.showAppTitle = false;
FLOWABLE.HEADER_CONFIG.showHeaderMenu = false;
FLOWABLE.HEADER_CONFIG.showMainNavigation = false;
FLOWABLE.HEADER_CONFIG.showPageHeader = false;

View File

@ -0,0 +1,46 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Create custom functions for the FLOWABLE-editor
FLOWABLE.TOOLBAR.ACTIONS.closeEditor = function(services) {
if (services.editorManager && services.editorManager.getStencilData()) {
var stencilNameSpace = services.editorManager.getStencilData().namespace;
if (stencilNameSpace !== undefined && stencilNameSpace !== null && stencilNameSpace.indexOf('cmmn1.1') !== -1) {
services.$location.path("/casemodels");
return;
}
}
services.$location.path("/processes");
};
FLOWABLE.TOOLBAR.ACTIONS.navigateToProcess = function(processId) {
var navigateEvent = {
type: FLOWABLE.eventBus.EVENT_TYPE_NAVIGATE_TO_PROCESS,
processId: processId
};
FLOWABLE.eventBus.dispatch(FLOWABLE.eventBus.EVENT_TYPE_NAVIGATE_TO_PROCESS, navigateEvent);
},
// Add custom buttons
FLOWABLE.TOOLBAR_CONFIG.secondaryItems.push(
{
"type" : "button",
"title" : "Close",
"cssClass" : "glyphicon glyphicon-remove",
"action" : "FLOWABLE.TOOLBAR.ACTIONS.closeEditor"
}
);

View File

@ -0,0 +1,507 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Assignment
*/
'use strict';
angular.module('flowableModeler').controller('FlowableAssignmentCtrl', [ '$scope', '$modal', function($scope, $modal) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/assignment-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowableAssignmentPopupCtrl',
[ '$rootScope', '$scope', '$translate', '$http', 'UserService', 'GroupService', function($rootScope, $scope, $translate, $http, UserService, GroupService) {
// Put json representing assignment on scope
if ($scope.property.value !== undefined && $scope.property.value !== null
&& $scope.property.value.assignment !== undefined
&& $scope.property.value.assignment !== null) {
$scope.assignment = $scope.property.value.assignment;
if (typeof $scope.assignment.type === 'undefined') {
$scope.assignment.type = 'static';
}
} else {
$scope.assignment = {type:'idm'};
}
$scope.popup = {
assignmentObject: {
type:$scope.assignment.type,
idm: {
type:undefined,
assignee: undefined,
candidateUsers: [],
candidateGroups: []
},
static: {
assignee: undefined,
candidateUsers: [],
candidateGroups: []
}
}
};
$scope.assignmentOptions = [
{id: "initiator", title: $translate.instant('PROPERTY.ASSIGNMENT.IDM.DROPDOWN.INITIATOR')},
{id: "user", title: $translate.instant('PROPERTY.ASSIGNMENT.IDM.DROPDOWN.USER')},
{id: "users", title: $translate.instant('PROPERTY.ASSIGNMENT.IDM.DROPDOWN.USERS')},
{id: "groups", title: $translate.instant('PROPERTY.ASSIGNMENT.IDM.DROPDOWN.GROUPS')}
];
if ($scope.assignment.idm && $scope.assignment.idm.type) {
for (var i = 0; i < $scope.assignmentOptions.length; i++) {
if ($scope.assignmentOptions[i].id == $scope.assignment.idm.type) {
$scope.assignmentOption = $scope.assignmentOptions[i];
break;
}
}
}
// fill the IDM area
if (!$scope.assignmentOption) {
// Default, first time opening the popup
$scope.assignmentOption = $scope.assignmentOptions[0];
} else {
// Values already filled
if ($scope.assignment.idm) { //fill the IDM tab
if ($scope.assignment.idm.assignee) {
if ($scope.assignment.idm.assignee.id) {
$scope.popup.assignmentObject.idm.assignee = $scope.assignment.idm.assignee;
} else {
$scope.popup.assignmentObject.idm.assignee = {email: $scope.assignment.idm.assignee.email};
}
}
if ($scope.assignment.idm.candidateUsers && $scope.assignment.idm.candidateUsers.length > 0) {
for (var i = 0; i < $scope.assignment.idm.candidateUsers.length; i++) {
$scope.popup.assignmentObject.idm.candidateUsers.push($scope.assignment.idm.candidateUsers[i]);
}
}
if ($scope.assignment.idm.candidateGroups && $scope.assignment.idm.candidateGroups.length > 0) {
for (var i = 0; i < $scope.assignment.idm.candidateGroups.length; i++) {
$scope.popup.assignmentObject.idm.candidateGroups.push($scope.assignment.idm.candidateGroups[i]);
}
}
}
}
//fill the static area
if ($scope.assignment.assignee) {
$scope.popup.assignmentObject.static.assignee = $scope.assignment.assignee;
}
if ($scope.assignment.candidateUsers && $scope.assignment.candidateUsers.length > 0) {
for (var i = 0; i < $scope.assignment.candidateUsers.length; i++) {
$scope.popup.assignmentObject.static.candidateUsers.push($scope.assignment.candidateUsers[i]);
}
}
if ($scope.assignment.candidateGroups && $scope.assignment.candidateGroups.length > 0) {
for (var i = 0; i < $scope.assignment.candidateGroups.length; i++) {
$scope.popup.assignmentObject.static.candidateGroups.push($scope.assignment.candidateGroups[i]);
}
}
initStaticContextForEditing($scope);
$scope.$watch('popup.groupFilter', function () {
$scope.updateGroupFilter();
});
$scope.$watch('popup.filter', function() {
$scope.updateFilter();
});
$scope.updateFilter = function() {
if ($scope.popup.oldFilter == undefined || $scope.popup.oldFilter != $scope.popup.filter) {
if (!$scope.popup.filter) {
$scope.popup.oldFilter = '';
} else {
$scope.popup.oldFilter = $scope.popup.filter;
}
if ($scope.popup.filter !== null && $scope.popup.filter !== undefined) {
UserService.getFilteredUsers($scope.popup.filter).then(function (result) {
var filteredUsers = [];
for (var i=0; i<result.data.length; i++) {
var filteredUser = result.data[i];
var foundCandidateUser = false;
if ($scope.popup.assignmentObject.idm.candidateUsers !== null && $scope.popup.assignmentObject.idm.candidateUsers !== undefined) {
for (var j=0; j<$scope.popup.assignmentObject.idm.candidateUsers.length; j++) {
var candidateUser = $scope.popup.assignmentObject.idm.candidateUsers[j];
if (candidateUser.id === filteredUser.id) {
foundCandidateUser = true;
break;
}
}
}
if (!foundCandidateUser) {
filteredUsers.push(filteredUser);
}
}
$scope.popup.userResults = filteredUsers;
$scope.resetSelection();
});
}
}
};
$scope.updateGroupFilter = function() {
if ($scope.popup.oldGroupFilter == undefined || $scope.popup.oldGroupFilter != $scope.popup.groupFilter) {
if (!$scope.popup.groupFilter) {
$scope.popup.oldGroupFilter = '';
} else {
$scope.popup.oldGroupFilter = $scope.popup.groupFilter;
}
GroupService.getFilteredGroups($scope.popup.groupFilter).then(function(result) {
$scope.popup.groupResults = result.data;
$scope.resetGroupSelection();
});
}
};
$scope.confirmUser = function(user) {
if (!user) {
// Selection is done with keyboard, use selection index
var users = $scope.popup.userResults;
if ($scope.popup.selectedIndex >= 0 && $scope.popup.selectedIndex < users.length) {
user = users[$scope.popup.selectedIndex];
}
}
if (user) {
if ("user" == $scope.assignmentOption.id) {
$scope.popup.assignmentObject.idm.assignee = user;
} else if ("users" == $scope.assignmentOption.id) {
// Only add if not yet part of candidate users
var found = false;
if ($scope.popup.assignmentObject.idm.candidateUsers) {
for (var i = 0; i < $scope.popup.assignmentObject.idm.candidateUsers.length; i++) {
if ($scope.popup.assignmentObject.idm.candidateUsers[i].id === user.id) {
found = true;
break;
}
}
}
if (!found) {
$scope.addCandidateUser(user);
}
}
}
};
$scope.confirmEmail = function() {
if ("user" == $scope.assignmentOption.id) {
$scope.popup.assignmentObject.idm.assignee = {email: $scope.popup.email};
} else if ("users" == $scope.assignmentOption.id) {
// Only add if not yet part of candidate users
var found = false;
if ($scope.popup.assignmentObject.idm.candidateUsers) {
for (var i = 0; i < $scope.popup.assignmentObject.idm.candidateUsers.length; i++) {
if ($scope.popup.assignmentObject.idm.candidateUsers[i].id) {
if ($scope.popup.assignmentObject.idm.candidateUsers[i].id === user.id) {
found = true;
break;
}
} else if ($scope.popup.assignmentObject.idm.candidateUsers[i].email) {
if ($scope.popup.assignmentObject.idm.candidateUsers[i].email === $scope.popup.email) {
found = true;
break;
}
}
}
}
if (!found) {
$scope.addCandidateUser({email: $scope.popup.email});
}
}
};
$scope.confirmGroup = function(group) {
if (!group) {
// Selection is done with keyboard, use selection index
var groups = $scope.popup.groupResults;
if ($scope.popup.selectedGroupIndex >= 0 && $scope.popup.selectedGroupIndex < groups.length) {
group = groups[$scope.popup.selectedGroupIndex];
}
}
if (group) {
// Only add if not yet part of candidate groups
var found = false;
if ($scope.popup.assignmentObject.idm.candidateGroups) {
for (var i = 0; i < $scope.popup.assignmentObject.idm.candidateGroups.length; i++) {
if ($scope.popup.assignmentObject.idm.candidateGroups[i].id === group.id) {
found = true;
break;
}
}
}
if (!found) {
$scope.addCandidateGroup(group);
}
}
};
$scope.addCandidateUser = function(user) {
$scope.popup.assignmentObject.idm.candidateUsers.push(user);
};
$scope.removeCandidateUser = function(user) {
var users = $scope.popup.assignmentObject.idm.candidateUsers;
var indexToRemove = -1;
for (var i = 0; i < users.length; i++) {
if (user.id) {
if (user.id === users[i].id) {
indexToRemove = i;
break;
}
} else {
if (user.email === users[i].email) {
indexToRemove = i;
break;
}
}
}
if (indexToRemove >= 0) {
users.splice(indexToRemove, 1);
}
};
$scope.addCandidateGroup = function(group) {
$scope.popup.assignmentObject.idm.candidateGroups.push(group);
};
$scope.removeCandidateGroup = function(group) {
var groups = $scope.popup.assignmentObject.idm.candidateGroups;
var indexToRemove = -1;
for (var i = 0; i < groups.length; i++) {
if (group.id == groups[i].id) {
indexToRemove = i;
break;
}
}
if (indexToRemove >= 0) {
groups.splice(indexToRemove, 1);
}
};
$scope.resetSelection = function() {
if ($scope.popup.userResults && $scope.popup.userResults.length > 0) {
$scope.popup.selectedIndex = 0;
} else {
$scope.popup.selectedIndex = -1;
}
};
$scope.nextUser = function() {
var users = $scope.popup.userResults;
if (users && users.length > 0 && $scope.popup.selectedIndex < users.length -1) {
$scope.popup.selectedIndex += 1;
}
};
$scope.previousUser = function() {
var users = $scope.popup.userResults;
if (users && users.length > 0 && $scope.popup.selectedIndex > 0) {
$scope.popup.selectedIndex -= 1;
}
};
$scope.resetGroupSelection = function() {
if ($scope.popup.groupResults && $scope.popup.groupResults.length > 0) {
$scope.popup.selectedGroupIndex = 0;
} else {
$scope.popup.selectedGroupIndex = -1;
}
};
$scope.nextGroup = function() {
var groups = $scope.popup.groupResults;
if (groups && groups.length > 0 && $scope.popup.selectedGroupIndex < groups.length -1) {
$scope.popup.selectedGroupIndex += 1;
}
};
$scope.previousGroup = function() {
var groups = $scope.popup.groupResults;
if (groups && groups.length > 0 && $scope.popup.selectedGroupIndex > 0) {
$scope.popup.selectedGroupIndex -= 1;
}
};
$scope.removeAssignee = function() {
$scope.popup.assignmentObject.idm.assignee = undefined;
};
// Click handler for + button after enums value
$scope.addCandidateUserValue = function(index) {
$scope.popup.assignmentObject.static.candidateUsers.splice(index + 1, 0, {value: ''});
};
// Click handler for - button after enums value
$scope.removeCandidateUserValue = function(index) {
$scope.popup.assignmentObject.static.candidateUsers.splice(index, 1);
};
// Click handler for + button after enums value
$scope.addCandidateGroupValue = function(index) {
$scope.popup.assignmentObject.static.candidateGroups.splice(index + 1, 0, {value: ''});
};
// Click handler for - button after enums value
$scope.removeCandidateGroupValue = function(index) {
$scope.popup.assignmentObject.static.candidateGroups.splice(index, 1);
};
$scope.setSearchType = function() {
$scope.popup.assignmentObject.assignmentSourceType = 'search';
};
$scope.allSteps = EDITOR.UTIL.collectSortedElementsFromPrecedingElements($scope.selectedShape);
$scope.save = function () {
handleAssignmentInput($scope.popup.assignmentObject.static);
$scope.assignment.type = $scope.popup.assignmentObject.type;
if ('idm' === $scope.popup.assignmentObject.type) { // IDM
$scope.popup.assignmentObject.static = undefined;
//Construct an IDM object to be saved to the process model.
var idm = {type: $scope.assignmentOption.id};
if ('user' == idm.type) {
if ($scope.popup.assignmentObject.idm.assignee) {
idm.assignee = $scope.popup.assignmentObject.idm.assignee;
}
} else if ('users' == idm.type) {
if ($scope.popup.assignmentObject.idm.candidateUsers && $scope.popup.assignmentObject.idm.candidateUsers.length > 0) {
idm.candidateUsers = $scope.popup.assignmentObject.idm.candidateUsers;
}
} else if ('groups' == idm.type) {
if ($scope.popup.assignmentObject.idm.candidateGroups && $scope.popup.assignmentObject.idm.candidateGroups.length > 0) {
idm.candidateGroups = $scope.popup.assignmentObject.idm.candidateGroups;
}
}
$scope.assignment.idm = idm;
$scope.assignment.assignee = undefined;
$scope.assignment.candidateUsers = undefined;
$scope.assignment.candidateGroups = undefined;
}
if ('static' === $scope.popup.assignmentObject.type) { // IDM
$scope.popup.assignmentObject.idm = undefined;
$scope.assignment.idm = undefined;
$scope.assignment.assignee = $scope.popup.assignmentObject.static.assignee;
$scope.assignment.candidateUsers = $scope.popup.assignmentObject.static.candidateUsers;
$scope.assignment.candidateGroups = $scope.popup.assignmentObject.static.candidateGroups;
}
$scope.property.value = {};
$scope.property.value.assignment = $scope.assignment;
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
// Close button handler
$scope.close = function() {
$scope.property.mode = 'read';
$scope.$hide();
};
var handleAssignmentInput = function ($assignment) {
function isEmptyString(value) {
return (value === undefined || value === null || value.trim().length === 0);
}
if (isEmptyString($assignment.assignee)){
$assignment.assignee = undefined;
}
var toRemoveIndexes;
var removedItems=0;
var i = 0;
if ($assignment.candidateUsers) {
toRemoveIndexes = [];
for (i = 0; i < $assignment.candidateUsers.length; i++) {
if (isEmptyString($assignment.candidateUsers[i].value)) {
toRemoveIndexes[toRemoveIndexes.length] = i;
}
}
if (toRemoveIndexes.length == $assignment.candidateUsers.length) {
$assignment.candidateUsers = undefined;
} else {
removedItems=0;
for (i = 0; i < toRemoveIndexes.length; i++) {
$assignment.candidateUsers.splice(toRemoveIndexes[i]-removedItems, 1);
removedItems++;
}
}
}
if ($assignment.candidateGroups) {
toRemoveIndexes = [];
for (i = 0; i < $assignment.candidateGroups.length; i++) {
if (isEmptyString($assignment.candidateGroups[i].value)) {
toRemoveIndexes[toRemoveIndexes.length] = i;
}
}
if (toRemoveIndexes.length == $assignment.candidateGroups.length) {
$assignment.candidateGroups = undefined;
} else {
removedItems=0;
for (i = 0; i < toRemoveIndexes.length; i++) {
$assignment.candidateGroups.splice(toRemoveIndexes[i]-removedItems, 1);
removedItems++;
}
}
}
};
function initStaticContextForEditing($scope) {
if (!$scope.popup.assignmentObject.static.candidateUsers || $scope.popup.assignmentObject.static.candidateUsers.length==0) {
$scope.popup.assignmentObject.static.candidateUsers = [{value: ''}];
}
if (!$scope.popup.assignmentObject.static.candidateGroups || $scope.popup.assignmentObject.static.candidateGroups.length==0) {
$scope.popup.assignmentObject.static.candidateGroups = [{value: ''}];
}
}
}]);

View File

@ -0,0 +1,28 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Call activity calledElement type property
*/
angular.module('flowableModeler').controller('FlowableCalledElementTypeCtrl', [ '$scope', function($scope) {
if ($scope.property.value == undefined && $scope.property.value == null)
{
$scope.property.value = 'key';
}
$scope.calledElementTypeChanged = function() {
$scope.updatePropertyInModel($scope.property);
};
}]);

View File

@ -0,0 +1,80 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
angular.module('flowableModeler').controller('FlowableCaseReferenceCtrl',
[ '$scope', '$modal', '$http', function($scope, $modal, $http) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/case-reference-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowableCaseReferencePopupCtrl', [ '$scope', '$http', 'editorManager', function($scope, $http, editorManager) {
$scope.state = {'loadingCases' : true, 'error' : false};
// Close button handler
$scope.close = function() {
$scope.property.mode = 'read';
$scope.$hide();
};
// Selecting/deselecting a case
$scope.selectCase = function(caseModel, $event) {
$event.stopPropagation();
if ($scope.selectedCase && $scope.selectedCase.id && caseModel.id == $scope.selectedCase.id) {
// un-select the current selection
$scope.selectedCase = null;
} else {
$scope.selectedCase = caseModel;
}
};
// Saving the selected value
$scope.save = function() {
if ($scope.selectedCase) {
$scope.property.value = {'id' : $scope.selectedCase.id, 'name' : $scope.selectedCase.name};
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
$scope.loadCases = function() {
var modelMetaData = editorManager.getBaseModelData();
$http.get(FLOWABLE.APP_URL.getCaseModelsUrl('?excludeId=' + modelMetaData.modelId))
.success(
function(response) {
$scope.state.loadingCases = false;
$scope.state.caseError = false;
$scope.caseModels = response.data;
})
.error(
function(data, status, headers, config) {
$scope.state.loadingCases = false;
$scope.state.caseError = true;
});
};
if ($scope.property && $scope.property.value && $scope.property.value.id) {
$scope.selectedCase = $scope.property.value;
}
$scope.loadCases();
}]);

View File

@ -0,0 +1,59 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Condition expression
*/
angular.module('flowableModeler').controller('FlowableConditionExpressionCtrl', [ '$scope', '$modal', function($scope, $modal) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/condition-expression-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowableConditionExpressionPopupCtrl',
[ '$rootScope', '$scope', '$translate', 'FormBuilderService', function($rootScope, $scope, $translate, FormBuilderService) {
// Put json representing assignment on scope
if ($scope.property.value !== undefined && $scope.property.value !== null
&& $scope.property.value.expression !== undefined
&& $scope.property.value.expression !== null) {
$scope.expression = $scope.property.value.expression;
} else if ($scope.property.value !== undefined && $scope.property.value !== null) {
$scope.expression = {type: 'static', staticValue: $scope.property.value};
} else {
$scope.expression = {};
}
$scope.save = function() {
$scope.property.value = {expression: $scope.expression};
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
// Close button handler
$scope.close = function() {
$scope.property.mode = 'read';
$scope.$hide();
};
}]);

View File

@ -0,0 +1,12 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

View File

@ -0,0 +1,330 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Data Properties
*/
angular.module('flowableModeler').controller('FlowableDataPropertiesCtrl',
['$scope', '$modal', '$timeout', '$translate', function ($scope, $modal, $timeout, $translate) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/data-properties-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowableDataPropertiesPopupCtrl',
['$scope', '$q', '$translate', '$timeout', function ($scope, $q, $translate, $timeout) {
// Put json representing data properties on scope
if ($scope.property.value !== undefined && $scope.property.value !== null
&& $scope.property.value.items !== undefined
&& $scope.property.value.items !== null) {
// Note that we clone the json object rather then setting it directly,
// this to cope with the fact that the user can click the cancel button and no changes should have happened
$scope.dataProperties = angular.copy($scope.property.value.items);
for (var i = 0; i < $scope.dataProperties.length; i++) {
var dataProperty = $scope.dataProperties[i];
if (dataProperty.enumValues && dataProperty.enumValues.length > 0) {
for (var j = 0; j < dataProperty.enumValues.length; j++) {
var enumValue = dataProperty.enumValues[j];
if (!enumValue.id && !enumValue.name && enumValue.value) {
enumValue.id = enumValue.value;
enumValue.name = enumValue.value;
}
}
}
}
} else {
$scope.dataProperties = [];
}
$scope.enumValues = [];
$scope.translationsRetrieved = false;
$scope.labels = {};
var idPromise = $translate('PROPERTY.DATAPROPERTIES.ID');
var namePromise = $translate('PROPERTY.DATAPROPERTIES.NAME');
var typePromise = $translate('PROPERTY.DATAPROPERTIES.TYPE');
var valuePromise = $translate('PROPERTY.DATAPROPERTIES.VALUE');
$q.all([idPromise, namePromise, typePromise, valuePromise]).then(function (results) {
$scope.labels.idLabel = results[0];
$scope.labels.nameLabel = results[1];
$scope.labels.typeLabel = results[2];
$scope.labels.valueLabel = results[3];
$scope.translationsRetrieved = true;
// Config for grid
$scope.gridOptions = {
data: $scope.dataProperties,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
enableHorizontalScrollbar: 0,
enableColumnMenus: false,
enableSorting: false,
columnDefs: [{field: 'dataproperty_id', displayName: $scope.labels.idLabel},
{field: 'dataproperty_name', displayName: $scope.labels.nameLabel},
{field: 'dataproperty_type', displayName: $scope.labels.typeLabel},
{field: 'dataproperty_value', displayName: $scope.labels.valueLabel}]
};
$scope.enumGridOptions = {
data: $scope.enumValues,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
enableHorizontalScrollbar: 0,
enableColumnMenus: false,
enableSorting: false,
columnDefs: [{ field: 'id', displayName: $scope.labels.idLabel },
{ field: 'name', displayName: $scope.labels.nameLabel}]
}
$scope.gridOptions.onRegisterApi = function (gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedProperty = row.entity;
$scope.selectedEnumValue = undefined;
if ($scope.selectedProperty && $scope.selectedProperty.enumValues) {
$scope.enumValues.length = 0;
for (var i = 0; i < $scope.selectedProperty.enumValues.length; i++) {
$scope.enumValues.push($scope.selectedProperty.enumValues[i]);
}
}
});
};
$scope.enumGridOptions.onRegisterApi = function (gridApi) {
//set gridApi on scope
$scope.enumGridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedEnumValue = row.entity;
});
};
});
// Handler for when the value of the type dropdown changes
$scope.propertyTypeChanged = function () {
// Check date. If date, show date pattern
if ($scope.selectedProperty.type === 'date') {
$scope.selectedProperty.datePattern = 'MM-dd-yyyy hh:mm';
} else {
delete $scope.selectedProperty.datePattern;
}
// Check enums. If enums, show list of options
if ($scope.selectedProperty.type === 'enums') {
$scope.selectedProperty.enumValues = [ {id: 'value1', name: 'Value 1'}, {id: 'value2', name: 'Value 2'}];
$scope.enumValues.length = 0;
for (var i = 0; i < $scope.selectedProperty.enumValues.length; i++) {
$scope.enumValues.push($scope.selectedProperty.enumValues[i]);
}
} else {
delete $scope.selectedProperty.enumValues;
$scope.enumValues.length = 0;
}
};
// Click handler for add button
var propertyIndex = 1;
$scope.addNewProperty = function () {
var newProperty = {
dataproperty_id: 'new_data_object_' + propertyIndex++,
dataproperty_name: '',
dataproperty_type: 'string',
readable: true,
writable: true
};
$scope.dataProperties.push(newProperty);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(newProperty);
});
};
// Click handler for remove button
$scope.removeProperty = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.dataProperties.indexOf(selectedItems[0]);
$scope.gridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.dataProperties.splice(index, 1);
if ($scope.dataProperties.length == 0) {
$scope.selectedProperty = undefined;
}
$timeout(function() {
if ($scope.dataProperties.length > 0) {
$scope.gridApi.selection.toggleRowSelection($scope.dataProperties[0]);
}
});
}
};
// Click handler for up button
$scope.movePropertyUp = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.dataProperties.indexOf(selectedItems[0]);
if (index != 0) { // If it's the first, no moving up of course
var temp = $scope.dataProperties[index];
$scope.dataProperties.splice(index, 1);
$timeout(function(){
$scope.dataProperties.splice(index + -1, 0, temp);
$timeout(function() {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for down button
$scope.movePropertyDown = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.dataProperties.indexOf(selectedItems[0]);
if (index != $scope.dataProperties.length - 1) { // If it's the last element, no moving down of course
var temp = $scope.dataProperties[index];
$scope.dataProperties.splice(index, 1);
$timeout(function(){
$scope.dataProperties.splice(index + 1, 0, temp);
$timeout(function() {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
$scope.addNewEnumValue = function() {
if ($scope.selectedProperty) {
var newEnumValue = { id : '', name : ''};
$scope.selectedProperty.enumValues.push(newEnumValue);
$scope.enumValues.push(newEnumValue);
$timeout(function () {
$scope.enumGridApi.selection.toggleRowSelection(newEnumValue);
});
}
};
// Click handler for remove button
$scope.removeEnumValue = function() {
var selectedItems = $scope.enumGridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.enumValues.indexOf(selectedItems[0]);
$scope.enumGridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.enumValues.splice(index, 1);
$scope.selectedProperty.enumValues.splice(index, 1);
if ($scope.enumValues.length == 0) {
$scope.selectedEnumValue = undefined;
}
$timeout(function () {
if ($scope.enumValues.length > 0) {
$scope.enumGridApi.selection.toggleRowSelection($scope.enumValues[0]);
}
});
}
};
// Click handler for up button
$scope.moveEnumValueUp = function() {
var selectedItems = $scope.enumGridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.enumValues.indexOf(selectedItems[0]);
if (index != 0) { // If it's the first, no moving up of course
var temp = $scope.enumValues[index];
$scope.enumValues.splice(index, 1);
$scope.selectedProperty.enumValues.splice(index, 1);
$timeout(function () {
$scope.enumValues.splice(index + -1, 0, temp);
$scope.selectedProperty.enumValues.splice(index + -1, 0, temp);
$timeout(function () {
$scope.enumGridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for down button
$scope.moveEnumValueDown = function() {
var selectedItems = $scope.enumGridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.enumValues.indexOf(selectedItems[0]);
if (index != $scope.enumValues.length - 1) { // If it's the last element, no moving down of course
var temp = $scope.enumValues[index];
$scope.enumValues.splice(index, 1);
$scope.selectedProperty.enumValues.splice(index, 1);
$timeout(function () {
$scope.enumValues.splice(index + 1, 0, temp);
$scope.selectedProperty.enumValues.splice(index + 1, 0, temp);
$timeout(function () {
$scope.enumGridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for save button
$scope.save = function () {
if ($scope.dataProperties.length > 0) {
$scope.property.value = {};
$scope.property.value.items = $scope.dataProperties;
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
$scope.cancel = function () {
$scope.$hide();
$scope.property.mode = 'read';
};
// Close button handler
$scope.close = function () {
$scope.$hide();
$scope.property.mode = 'read';
};
}])
;

View File

@ -0,0 +1,288 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
angular.module('flowableModeler').controller('FlowableDecisionTableReferenceCtrl',
[ '$scope', '$modal', '$http', function($scope, $modal, $http) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/decisiontable-reference-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowableDecisionTableReferencePopupCtrl', ['$rootScope', '$scope', '$http', '$location', 'editorManager',
function($rootScope, $scope, $http, $location, editorManager) {
$scope.state = {
'loadingDecisionTables': true,
'decisionTableError': false
};
$scope.popup = {
'state': 'decisionTableReference'
};
$scope.foldersBreadCrumbs = [];
// Make click outside dialog also call close.
$scope.$parent.$on('modal.hide.before', function() {
$scope.close();
$scope.$parent.$apply();
});
// Close button handler
$scope.close = function() {
$scope.property.newVariablesMapping = undefined;
$scope.property.mode = 'read';
$scope.$hide();
};
// Selecting/deselecting a decision table
$scope.selectDecisionTable = function(decisionTable, $event) {
$event.stopPropagation();
if ($scope.selectedDecisionTable && $scope.selectedDecisionTable.id && decisionTable.id == $scope.selectedDecisionTable.id) {
// un-select the current selection
$scope.selectedDecisionTable = null;
} else {
$scope.selectedDecisionTable = decisionTable;
}
};
$scope.isSelected = function () {
if ($scope.selectedDecisionTable && $scope.selectedDecisionTable.id) {
return true;
}
return false;
};
// Saving the selected value
$scope.save = function() {
if ($scope.selectedDecisionTable) {
$scope.property.value = {
'id': $scope.selectedDecisionTable.id,
'name': $scope.selectedDecisionTable.name,
'key': $scope.selectedDecisionTable.key
};
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
// Open the selected value
$scope.open = function() {
if ($scope.selectedDecisionTable) {
$scope.property.value = {
'id': $scope.selectedDecisionTable.id,
'name': $scope.selectedDecisionTable.name,
'key': $scope.selectedDecisionTable.key
};
$scope.updatePropertyInModel($scope.property);
var modelMetaData = editorManager.getBaseModelData();
var json = editorManager.getModel();
json = JSON.stringify(json);
var params = {
modeltype: modelMetaData.model.modelType,
json_xml: json,
name: modelMetaData.name,
key: modelMetaData.key,
description: modelMetaData.description,
newversion: false,
lastUpdated: modelMetaData.lastUpdated
};
// Update
$http({
method: 'POST',
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: FLOWABLE.URL.putModel(modelMetaData.modelId)
})
.success(function(data, status, headers, config) {
editorManager.handleEvents({
type: ORYX.CONFIG.EVENT_SAVED
});
$rootScope.addHistoryItem($scope.selectedShape.resourceId);
$location.path('decision-table-editor/' + $scope.selectedDecisionTable.id);
})
.error(function(data, status, headers, config) {
});
$scope.close();
}
};
$scope.newDecisionTable = function() {
$scope.property.value.variablesmapping = [];
$scope.popup.state = 'newDecisionTable';
var modelMetaData = editorManager.getBaseModelData();
$scope.model = {
loading: false,
decisionTable: {
name: '',
key: '',
description: '',
modelType: 4
},
defaultStencilSet: undefined,
decisionTableStencilSets: []
};
};
$scope.createDecisionTable = function() {
if (!$scope.model.decisionTable.name || $scope.model.decisionTable.name.length == 0 ||
!$scope.model.decisionTable.key || $scope.model.decisionTable.key.length == 0) {
return;
}
var stencilSetId = $scope.model.decisionTable.stencilSet;
$scope.model.loading = true;
$http({
method: 'POST',
url: FLOWABLE.APP_URL.getModelsUrl(),
data: $scope.model.decisionTable
}).
success(function(data, status, headers, config) {
var newDecisionTableId = data.id;
$scope.property.value = {
'id': newDecisionTableId,
'name': data.name,
'key': data.key
};
$scope.updatePropertyInModel($scope.property);
var modelMetaData = editorManager.getBaseModelData();
var json = editorManager.getModel();
json = JSON.stringify(json);
var params = {
modeltype: modelMetaData.model.modelType,
json_xml: json,
name: modelMetaData.name,
key: modelMetaData.key,
description: modelMetaData.description,
newversion: false,
lastUpdated: modelMetaData.lastUpdated,
stencilSet: stencilSetId
};
// Update
$http({
method: 'POST',
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: FLOWABLE.URL.putModel(modelMetaData.modelId)
})
.success(function(data, status, headers, config) {
editorManager.handleEvents({
type: ORYX.CONFIG.EVENT_SAVED
});
$scope.model.loading = false;
$scope.$hide();
$rootScope.addHistoryItem($scope.selectedShape.resourceId);
$location.path('decision-table-editor/' + newDecisionTableId);
})
.error(function(data, status, headers, config) {
$scope.model.loading = false;
$scope.$hide();
});
}).
error(function(data, status, headers, config) {
$scope.model.loading = false;
$scope.model.errorMessage = data.message;
});
};
$scope.cancel = function() {
$scope.close();
};
$scope.resetCurrent = function () {
for (var i = 0, found = false; i < $scope.decisionTables.length && found === false; i++) {
var table = $scope.decisionTables[i];
if (table.id === $scope.property.value.id) {
$scope.selectedDecisionTable = table;
found = true;
}
}
};
$scope.loadDecisionTables = function() {
var modelMetaData = editorManager.getBaseModelData();
$http.get(FLOWABLE.APP_URL.getDecisionTableModelsUrl())
.success(
function(response) {
$scope.state.loadingDecisionTables = false;
$scope.state.decisionTableError = false;
$scope.decisionTables = response.data;
$scope.resetCurrent();
})
.error(
function(data, status, headers, config) {
$scope.state.loadingDecisionTables = false;
$scope.state.decisionTableError = true;
});
};
if ($scope.property && $scope.property.value && $scope.property.value.id) {
$scope.selectedDecisionTable = $scope.property.value;
$scope.storedId = $scope.property.value.id;
}
$scope.loadDecisionTables();
}
]);

View File

@ -0,0 +1,118 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* String controller
*/
angular.module('flowableModeler').controller('FlowableStringPropertyCtrl', [ '$scope', function ($scope) {
$scope.shapeId = $scope.selectedShape.id;
$scope.valueFlushed = false;
/** Handler called when input field is blurred */
$scope.inputBlurred = function() {
$scope.valueFlushed = true;
if ($scope.property.value) {
$scope.property.value = $scope.property.value.replace(/(<([^>]+)>)/ig,"");
}
$scope.updatePropertyInModel($scope.property);
};
$scope.enterPressed = function(keyEvent) {
// if enter is pressed
if (keyEvent && keyEvent.which === 13) {
keyEvent.preventDefault();
$scope.inputBlurred(); // we want to do the same as if the user would blur the input field
}
// else; do nothing
};
$scope.$on('$destroy', function controllerDestroyed() {
if(!$scope.valueFlushed) {
if ($scope.property.value) {
$scope.property.value = $scope.property.value.replace(/(<([^>]+)>)/ig,"");
}
$scope.updatePropertyInModel($scope.property, $scope.shapeId);
}
});
}]);
/*
* Boolean controller
*/
angular.module('flowableModeler').controller('FlowableBooleanPropertyCtrl', ['$scope', function ($scope) {
$scope.changeValue = function() {
if ($scope.property.key === 'oryx-defaultflow' && $scope.property.value) {
var selectedShape = $scope.selectedShape;
if (selectedShape) {
var incomingNodes = selectedShape.getIncomingShapes();
if (incomingNodes && incomingNodes.length > 0) {
// get first node, since there can be only one for a sequence flow
var rootNode = incomingNodes[0];
var flows = rootNode.getOutgoingShapes();
if (flows && flows.length > 1) {
// in case there are more flows, check if another flow is already defined as default
for (var i = 0; i < flows.length; i++) {
if (flows[i].resourceId != selectedShape.resourceId) {
var defaultFlowProp = flows[i].properties.get('oryx-defaultflow');
if (defaultFlowProp) {
flows[i].setProperty('oryx-defaultflow', false, true);
}
}
}
}
}
}
}
$scope.updatePropertyInModel($scope.property);
};
}]);
/*
* Text controller
*/
angular.module('flowableModeler').controller('FlowableTextPropertyCtrl', [ '$scope', '$modal', '$timeout', function($scope, $modal, $timeout) {
var opts = {
template: 'editor-app/configuration/properties/text-popup.html?version=' + Date.now(),
scope: $scope,
prefixEvent: 'textModalEvent'
};
$scope.$on('textModalEvent.hide.before', function() {
$timeout(function() {
$scope.property.mode = 'read';
}, 0);
});
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowableTextPropertyPopupCtrl', ['$scope', function($scope) {
$scope.save = function() {
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
$scope.close = function() {
$scope.property.mode = 'read';
$scope.$hide();
};
}]);

View File

@ -0,0 +1,126 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Due date
*/
'use strict';
angular.module('flowableModeler').controller('BpmnEditorDueDateCtrl', [ '$scope', '$modal', function($scope, $modal) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/duedate-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('BpmnEditorDueDatePopupCtrl',
[ '$rootScope', '$scope', '$translate', function($rootScope, $scope, $translate) {
// Put json representing assignment on scope
if ($scope.property.value !== undefined && $scope.property.value !== null) {
if ($scope.property.value.duedate !== undefined && $scope.property.value.duedate !== null) {
$scope.popup = {'duedate': $scope.property.value.duedate};
} else if ($scope.property.value.duedateExpression !== undefined && $scope.property.value.duedateExpression !== null) {
$scope.popup = {'duedateExpression': $scope.property.value.duedateExpression};
} else {
$scope.popup = {'duedateExpression': $scope.property.value};
}
} else {
$scope.popup = {};
}
$scope.taskDueDateOptions = [
{id: "none", title: $translate.instant('PROPERTY.DUEDATE.TASK-DUE-DATE-OPTIONS.NO-DUEDATE')},
{id: "expression", title: $translate.instant('PROPERTY.DUEDATE.TASK-DUE-DATE-OPTIONS.EXPRESSION')},
{id: "static", title: $translate.instant('PROPERTY.DUEDATE.TASK-DUE-DATE-OPTIONS.STATIC')},
{id: "field", title: $translate.instant('PROPERTY.DUEDATE.TASK-DUE-DATE-OPTIONS.FIELD')}
];
if (!$scope.popup.duedate && !$scope.popup.duedateExpression) {
// Default, first time opening the popup
$scope.popup.selectedDueDateOption = $scope.taskDueDateOptions[0].id;
} else if (!$scope.popup.duedate) {
$scope.popup.selectedDueDateOption = $scope.taskDueDateOptions[1].id;
} else {
if ($scope.popup.duedate.fixed) {
$scope.popup.selectedDueDateOption = $scope.taskDueDateOptions[2].id;
} else if ($scope.popup.duedate.field) {
$scope.popup.selectedDueDateOption = $scope.taskDueDateOptions[3].id;
} else {
$scope.popup.selectedDueDateOption = $scope.taskDueDateOptions[0].id;
}
}
$scope.dueDateOptionChanged = function() {
if ($scope.popup.selectedDueDateOption === 'expression') {
$scope.popup.duedate = undefined;
} else if ($scope.popup.selectedDueDateOption === 'none') {
$scope.popup.duedate = undefined;
$scope.popup.duedateExpression = undefined;
} else if ($scope.popup.selectedDueDateOption === 'static') {
$scope.popup.duedate = {'fixed': {}};
$scope.popup.duedateExpression = undefined;
} else if ($scope.popup.selectedDueDateOption === 'field') {
$scope.popup.duedate = {'field': {}};
$scope.popup.duedateExpression = undefined;
}
};
$scope.setAddCalculationType = function() {
$scope.popup.duedate.field.taskDueDateCalculationType = 'add';
};
$scope.setSubtractCalculationType = function() {
$scope.popup.duedate.field.taskDueDateCalculationType = 'subtract';
};
$scope.allSteps = EDITOR.UTIL.collectSortedElementsFromPrecedingElements($scope.selectedShape);
$scope.save = function () {
$scope.property.value = {};
if ($scope.popup.duedate) {
$scope.property.value.duedate = $scope.popup.duedate;
} else if ($scope.popup.duedateExpression) {
$scope.property.value.duedateExpression = $scope.popup.duedateExpression;
} else {
$scope.property.value = '';
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
// Close button handler
$scope.close = function() {
$scope.property.mode = 'read';
$scope.$hide();
};
}]);

View File

@ -0,0 +1,263 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Execution listeners
*/
angular.module('flowableModeler').controller('FlowableEventListenersCtrl',
['$scope', '$modal', '$timeout', '$translate', function ($scope, $modal, $timeout, $translate) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/event-listeners-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
//Need a separate controller for the modal window due to https://github.com/angular-ui/bootstrap/issues/259
// Will be fixed in a newer version of Angular UI
angular.module('flowableModeler').controller('FlowableEventListenersPopupCtrl',
['$scope', '$q', '$translate', '$timeout', function ($scope, $q, $translate, $timeout) {
// Put json representing form properties on scope
if ($scope.property.value !== undefined && $scope.property.value !== null
&& $scope.property.value.eventListeners !== undefined
&& $scope.property.value.eventListeners !== null) {
if ($scope.property.value.eventListeners.constructor == String) {
$scope.eventListeners = JSON.parse($scope.property.value.eventListeners);
}
else {
// Note that we clone the json object rather then setting it directly,
// this to cope with the fact that the user can click the cancel button and no changes should have happened
$scope.eventListeners = angular.copy($scope.property.value.eventListeners);
}
} else {
$scope.eventListeners = [];
}
$scope.translationsRetrieved = false;
$scope.labels = {};
var eventPromise = $translate('PROPERTY.EXECUTIONLISTENERS.EVENT');
var implementationPromise = $translate('PROPERTY.EXECUTIONLISTENERS.FIELDS.IMPLEMENTATION');
var namePromise = $translate('PROPERTY.EXECUTIONLISTENERS.FIELDS.NAME');
$q.all([eventPromise, implementationPromise, namePromise]).then(function (results) {
$scope.labels.eventLabel = results[0];
$scope.labels.implementationLabel = results[1];
$scope.labels.nameLabel = results[2];
$scope.translationsRetrieved = true;
// Config for grid
$scope.gridOptions = {
data: $scope.eventListeners,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
enableHorizontalScrollbar: 0,
enableColumnMenus: false,
enableSorting: false,
columnDefs: [{field: 'event', displayName: $scope.labels.eventLabel},
{field: 'implementation', displayName: $scope.labels.implementationLabel}]
};
$scope.gridOptions.onRegisterApi = function (gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedListener = row.entity;
if ($scope.selectedListener) {
var fields = $scope.selectedListener.fields;
if (fields !== undefined && fields !== null) {
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
if (field.stringValue !== undefined && field.stringValue !== '') {
field.implementation = field.stringValue;
} else if (field.expression !== undefined && field.expression !== '') {
field.implementation = field.expression;
} else if (field.string !== undefined && field.string !== '') {
field.implementation = field.string;
}
}
} else {
$scope.selectedListener.fields = [];
}
if (!$scope.selectedListener.events) {
$scope.selectedListener.events = [{event: ''}];
}
}
});
};
});
// Click handler for + button after enums value
$scope.addEventValue = function (index) {
$scope.selectedListener.events.splice(index + 1, 0, {event: ''});
};
// Click handler for - button after enums value
$scope.removeEventValue = function (index) {
$scope.selectedListener.events.splice(index, 1);
$scope.listenerDetailsChanged();
};
$scope.listenerDetailsChanged = function () {
var listener = $scope.selectedListener;
if (listener.events) {
var eventText = '';
for (var i = 0; i < listener.events.length; i++) {
if (i > 0) {
eventText += ", ";
}
eventText += listener.events[i].event;
}
$scope.selectedListener.event = eventText;
}
if (listener.rethrowEvent) {
var implementationText = '';
if (listener.rethrowType && listener.rethrowType.length > 0) {
if (listener.rethrowType === 'error' && listener.errorcode !== '') {
implementationText = "Rethrow as error " + listener.errorcode;
}
else if (listener.rethrowType === 'message' && listener.messagename !== '') {
implementationText = "Rethrow as message " + listener.messagename;
}
else if ((listener.rethrowType === 'signal' || listener.rethrowType === 'globalSignal') && listener.signalname !== '') {
implementationText = "Rethrow as signal " + listener.signalname;
}
}
$scope.selectedListener.implementation = implementationText;
}
else {
if ($scope.selectedListener.className !== '') {
$scope.selectedListener.implementation = $scope.selectedListener.className;
}
else if ($scope.selectedListener.delegateExpression !== '') {
$scope.selectedListener.implementation = $scope.selectedListener.delegateExpression;
}
else {
$scope.selectedListener.implementation = '';
}
}
};
// Click handler for add button
$scope.addNewListener = function () {
var newListener = {
event: '',
implementation: '',
className: '',
delegateExpression: '',
retrowEvent: false
};
$scope.eventListeners.push(newListener);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(newListener);
});
};
// Click handler for remove button
$scope.removeListener = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.eventListeners.indexOf(selectedItems[0]);
$scope.gridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.eventListeners.splice(index, 1);
if ($scope.eventListeners.length == 0) {
$scope.selectedListener = undefined;
}
$timeout(function () {
if ($scope.eventListeners.length > 0) {
$scope.gridApi.selection.toggleRowSelection($scope.eventListeners[0]);
}
});
}
};
// Click handler for up button
$scope.moveListenerUp = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.eventListeners.indexOf(selectedItems[0]);
if (index != 0) { // If it's the first, no moving up of course
var temp = $scope.eventListeners[index];
$scope.eventListeners.splice(index, 1);
$timeout(function () {
$scope.eventListeners.splice(index + -1, 0, temp);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for down button
$scope.moveListenerDown = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.eventListeners.indexOf(selectedItems[0]);
if (index != $scope.eventListeners.length - 1) { // If it's the last element, no moving down of course
var temp = $scope.eventListeners[index];
$scope.eventListeners.splice(index, 1);
$timeout(function () {
$scope.eventListeners.splice(index + 1, 0, temp);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for save button
$scope.save = function () {
if ($scope.eventListeners.length > 0) {
$scope.property.value = {};
$scope.property.value.eventListeners = $scope.eventListeners;
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
$scope.cancel = function () {
$scope.property.mode = 'read';
$scope.$hide();
};
// Close button handler
$scope.close = function () {
$scope.property.mode = 'read';
$scope.$hide();
};
}]);

View File

@ -0,0 +1,358 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Execution listeners
*/
angular.module('flowableModeler').controller('FlowableExecutionListenersCtrl',
['$scope', '$modal', '$timeout', '$translate', function ($scope, $modal, $timeout, $translate) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/execution-listeners-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowableExecutionListenersPopupCtrl',
['$scope', '$q', '$translate', '$timeout', function ($scope, $q, $translate, $timeout) {
// Put json representing form properties on scope
if ($scope.property.value !== undefined && $scope.property.value !== null
&& $scope.property.value.executionListeners !== undefined
&& $scope.property.value.executionListeners !== null) {
if ($scope.property.value.executionListeners.constructor == String) {
$scope.executionListeners = JSON.parse($scope.property.value.executionListeners);
}
else {
// Note that we clone the json object rather then setting it directly,
// this to cope with the fact that the user can click the cancel button and no changes should have happened
$scope.executionListeners = angular.copy($scope.property.value.executionListeners);
}
for (var i = 0; i < $scope.executionListeners.length; i++) {
var executionListener = $scope.executionListeners[i];
if (executionListener.className !== undefined && executionListener.className !== '') {
executionListener.implementation = executionListener.className;
}
else if (executionListener.expression !== undefined && executionListener.expression !== '') {
executionListener.implementation = executionListener.expression;
}
else if (executionListener.delegateExpression !== undefined && executionListener.delegateExpression !== '') {
executionListener.implementation = executionListener.delegateExpression;
}
}
} else {
$scope.executionListeners = [];
}
$scope.selectedListener = undefined;
$scope.selectedField = undefined;
$scope.fields = [];
$scope.translationsRetrieved = false;
$scope.labels = {};
var eventPromise = $translate('PROPERTY.EXECUTIONLISTENERS.EVENT');
var implementationPromise = $translate('PROPERTY.EXECUTIONLISTENERS.FIELDS.IMPLEMENTATION');
var namePromise = $translate('PROPERTY.EXECUTIONLISTENERS.FIELDS.NAME');
$q.all([eventPromise, implementationPromise, namePromise]).then(function (results) {
$scope.labels.eventLabel = results[0];
$scope.labels.implementationLabel = results[1];
$scope.labels.nameLabel = results[2];
$scope.translationsRetrieved = true;
// Config for grid
$scope.gridOptions = {
data: $scope.executionListeners,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
enableHorizontalScrollbar: 0,
enableColumnMenus: false,
enableSorting: false,
columnDefs: [{field: 'event', displayName: $scope.labels.eventLabel},
{field: 'implementation', displayName: $scope.labels.implementationLabel}]
};
$scope.gridOptions.onRegisterApi = function (gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedListener = row.entity;
$scope.selectedField = undefined;
if ($scope.selectedListener) {
var fields = $scope.selectedListener.fields;
if (fields !== undefined && fields !== null) {
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
if (field.stringValue !== undefined && field.stringValue !== '') {
field.implementation = field.stringValue;
} else if (field.expression !== undefined && field.expression !== '') {
field.implementation = field.expression;
} else if (field.string !== undefined && field.string !== '') {
field.implementation = field.string;
}
}
} else {
$scope.selectedListener.fields = [];
}
$scope.fields.length = 0;
for (var i = 0; i < $scope.selectedListener.fields.length; i++) {
$scope.fields.push($scope.selectedListener.fields[i]);
}
}
});
};
// Config for field grid
$scope.gridFieldOptions = {
data: $scope.fields,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
enableHorizontalScrollbar: 0,
enableColumnMenus: false,
enableSorting: false,
columnDefs: [{field: 'name', displayName: $scope.labels.name},
{field: 'implementation', displayName: $scope.labels.implementationLabel}]
};
$scope.gridFieldOptions.onRegisterApi = function (gridApi) {
// set gridApi on scope
$scope.fieldGridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedField = row.entity;
});
};
});
$scope.listenerDetailsChanged = function () {
if ($scope.selectedListener.className !== '') {
$scope.selectedListener.implementation = $scope.selectedListener.className;
} else if ($scope.selectedListener.expression !== '') {
$scope.selectedListener.implementation = $scope.selectedListener.expression;
} else if ($scope.selectedListener.delegateExpression !== '') {
$scope.selectedListener.implementation = $scope.selectedListener.delegateExpression;
} else {
$scope.selectedListener.implementation = '';
}
};
// Click handler for add button
$scope.addNewListener = function () {
var newListener = {
event: 'start',
implementation: '',
className: '',
expression: '',
delegateExpression: ''
};
$scope.executionListeners.push(newListener);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(newListener);
});
};
// Click handler for remove button
$scope.removeListener = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.executionListeners.indexOf(selectedItems[0]);
$scope.gridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.executionListeners.splice(index, 1);
if ($scope.executionListeners.length == 0) {
$scope.selectedListener = undefined;
}
$timeout(function () {
if ($scope.executionListeners.length > 0) {
$scope.gridApi.selection.toggleRowSelection($scope.executionListeners[0]);
}
});
}
};
// Click handler for up button
$scope.moveListenerUp = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.executionListeners.indexOf(selectedItems[0]);
if (index != 0) { // If it's the first, no moving up of course
var temp = $scope.executionListeners[index];
$scope.executionListeners.splice(index, 1);
$timeout(function () {
$scope.executionListeners.splice(index + -1, 0, temp);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for down button
$scope.moveListenerDown = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.executionListeners.indexOf(selectedItems[0]);
if (index != $scope.executionListeners.length - 1) { // If it's the last element, no moving down of course
var temp = $scope.executionListeners[index];
$scope.executionListeners.splice(index, 1);
$timeout(function () {
$scope.executionListeners.splice(index + 1, 0, temp);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
$scope.fieldDetailsChanged = function () {
if ($scope.selectedField.stringValue != '') {
$scope.selectedField.implementation = $scope.selectedField.stringValue;
} else if ($scope.selectedField.expression != '') {
$scope.selectedField.implementation = $scope.selectedField.expression;
} else if ($scope.selectedField.string != '') {
$scope.selectedField.implementation = $scope.selectedField.string;
} else {
$scope.selectedField.implementation = '';
}
};
// Click handler for add button
$scope.addNewField = function () {
if ($scope.selectedListener) {
if ($scope.selectedListener.fields == undefined) {
$scope.selectedListener.fields = [];
}
var newField = {
name: 'fieldName',
implementation: '',
stringValue: '',
expression: '',
string: ''
};
$scope.fields.push(newField);
$scope.selectedListener.fields.push(newField);
$timeout(function () {
$scope.fieldGridApi.selection.toggleRowSelection(newField);
});
}
};
// Click handler for remove button
$scope.removeField = function () {
var selectedItems = $scope.fieldGridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.fields.indexOf(selectedItems[0]);
$scope.fieldGridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.fields.splice(index, 1);
$scope.selectedListener.fields.splice(index, 1);
if ($scope.fields.length == 0) {
$scope.selectedField = undefined;
}
$timeout(function () {
if ($scope.fields.length > 0) {
$scope.fieldGridApi.selection.toggleRowSelection($scope.fields[0]);
}
});
}
};
// Click handler for up button
$scope.moveFieldUp = function () {
var selectedItems = $scope.fieldGridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.fields.indexOf(selectedItems[0]);
if (index != 0) { // If it's the first, no moving up of course
var temp = $scope.fields[index];
$scope.fields.splice(index, 1);
$scope.selectedListener.fields.splice(index, 1);
$timeout(function () {
$scope.fields.splice(index + -1, 0, temp);
$scope.selectedListener.fields.splice(index + -1, 0, temp);
$timeout(function () {
$scope.fieldGridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for down button
$scope.moveFieldDown = function () {
var selectedItems = $scope.fieldGridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.fields.indexOf(selectedItems[0]);
if (index != $scope.fields.length - 1) { // If it's the last element, no moving down of course
var temp = $scope.fields[index];
$scope.fields.splice(index, 1);
$scope.selectedListener.fields.splice(index, 1);
$timeout(function () {
$scope.fields.splice(index + 1, 0, temp);
$scope.selectedListener.fields.splice(index + 1, 0, temp);
$timeout(function () {
$scope.fieldGridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for save button
$scope.save = function () {
if ($scope.executionListeners.length > 0) {
$scope.property.value = {};
$scope.property.value.executionListeners = $scope.executionListeners;
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
$scope.cancel = function () {
$scope.$hide();
$scope.property.mode = 'read';
};
// Close button handler
$scope.close = function () {
$scope.$hide();
$scope.property.mode = 'read';
};
}]);

View File

@ -0,0 +1,206 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Task listeners
*/
angular.module('flowableModeler').controller('FlowableFieldsCtrl',
['$scope', '$modal', '$timeout', '$translate', function ($scope, $modal, $timeout, $translate) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/fields-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowableFieldsPopupCtrl',
['$scope', '$q', '$translate', '$timeout', function ($scope, $q, $translate, $timeout) {
// Put json representing form properties on scope
if ($scope.property.value !== undefined && $scope.property.value !== null
&& $scope.property.value.fields !== undefined
&& $scope.property.value.fields !== null) {
// Note that we clone the json object rather then setting it directly,
// this to cope with the fact that the user can click the cancel button and no changes should have happened
$scope.fields = angular.copy($scope.property.value.fields);
for (var i = 0; i < $scope.fields.length; i++) {
var field = $scope.fields[i];
if (field.stringValue !== undefined && field.stringValue !== '') {
field.implementation = field.stringValue;
}
else if (field.expression !== undefined && field.expression !== '') {
field.implementation = field.expression;
}
else if (field.string !== undefined && field.string !== '') {
field.implementation = field.string;
}
}
} else {
$scope.fields = [];
}
$scope.translationsRetrieved = false;
$scope.labels = {};
var namePromise = $translate('PROPERTY.FIELDS.NAME');
var implementationPromise = $translate('PROPERTY.FIELDS.IMPLEMENTATION');
$q.all([namePromise, implementationPromise]).then(function (results) {
$scope.labels.nameLabel = results[0];
$scope.labels.implementationLabel = results[1];
$scope.translationsRetrieved = true;
// Config for grid
$scope.gridOptions = {
data: $scope.fields,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
enableHorizontalScrollbar: 0,
enableColumnMenus: false,
enableSorting: false,
columnDefs: [{field: 'name', displayName: $scope.labels.nameLabel},
{field: 'implementation', displayName: $scope.labels.implementationLabel}]
};
$scope.gridOptions.onRegisterApi = function (gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedField = row.entity;
});
};
});
$scope.fieldDetailsChanged = function () {
if ($scope.selectedField.stringValue != '') {
$scope.selectedField.implementation = $scope.selectedField.stringValue;
}
else if ($scope.selectedField.expression != '') {
$scope.selectedField.implementation = $scope.selectedField.expression;
}
else if ($scope.selectedField.string != '') {
$scope.selectedField.implementation = $scope.selectedField.string;
}
else {
$scope.selectedField.implementation = '';
}
};
// Click handler for add button
$scope.addNewField = function () {
var newField = {
name: 'fieldName',
implementation: '',
stringValue: '',
expression: '',
string: ''
};
$scope.fields.push(newField);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(newField);
});
};
// Click handler for remove button
$scope.removeField = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.fields.indexOf(selectedItems[0]);
$scope.gridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.fields.splice(index, 1);
if ($scope.fields.length == 0) {
$scope.selectedField = undefined;
}
$timeout(function () {
if ($scope.fields.length > 0) {
$scope.gridApi.selection.toggleRowSelection($scope.fields[0]);
}
});
}
};
// Click handler for up button
$scope.moveFieldUp = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.fields.indexOf(selectedItems[0]);
if (index != 0) { // If it's the first, no moving up of course
var temp = $scope.fields[index];
$scope.fields.splice(index, 1);
$timeout(function () {
$scope.fields.splice(index + -1, 0, temp);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for down button
$scope.moveFieldDown = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.fields.indexOf(selectedItems[0]);
if (index != $scope.fields.length - 1) { // If it's the last element, no moving down of course
var temp = $scope.fields[index];
$scope.fields.splice(index, 1);
$timeout(function () {
$scope.fields.splice(index + 1, 0, temp);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for save button
$scope.save = function () {
if ($scope.fields.length > 0) {
$scope.property.value = {};
$scope.property.value.fields = $scope.fields;
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
$scope.cancel = function () {
$scope.$hide();
};
// Close button handler
$scope.close = function () {
$scope.property.mode = 'read';
$scope.$hide();
};
}]);

View File

@ -0,0 +1,327 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Form Properties
*/
angular.module('flowableModeler').controller('FlowableFormPropertiesCtrl',
['$scope', '$modal', '$timeout', '$translate', function ($scope, $modal, $timeout, $translate) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/form-properties-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowableFormPropertiesPopupCtrl',
['$scope', '$q', '$translate', '$timeout', function ($scope, $q, $translate, $timeout) {
// Put json representing form properties on scope
if ($scope.property.value !== undefined && $scope.property.value !== null
&& $scope.property.value.formProperties !== undefined
&& $scope.property.value.formProperties !== null) {
// Note that we clone the json object rather then setting it directly,
// this to cope with the fact that the user can click the cancel button and no changes should have happended
$scope.formProperties = angular.copy($scope.property.value.formProperties);
for (var i = 0; i < $scope.formProperties.length; i++) {
var formProperty = $scope.formProperties[i];
if (formProperty.enumValues && formProperty.enumValues.length > 0) {
for (var j = 0; j < formProperty.enumValues.length; j++) {
var enumValue = formProperty.enumValues[j];
if (!enumValue.id && !enumValue.name && enumValue.value) {
enumValue.id = enumValue.value;
enumValue.name = enumValue.value;
}
}
}
}
} else {
$scope.formProperties = [];
}
$scope.enumValues = [];
$scope.translationsRetrieved = false;
$scope.labels = {};
var idPromise = $translate('PROPERTY.FORMPROPERTIES.ID');
var namePromise = $translate('PROPERTY.FORMPROPERTIES.NAME');
var typePromise = $translate('PROPERTY.FORMPROPERTIES.TYPE');
$q.all([idPromise, namePromise, typePromise]).then(function (results) {
$scope.labels.idLabel = results[0];
$scope.labels.nameLabel = results[1];
$scope.labels.typeLabel = results[2];
$scope.translationsRetrieved = true;
// Config for grid
$scope.gridOptions = {
data: $scope.formProperties,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
enableHorizontalScrollbar: 0,
enableColumnMenus: false,
enableSorting: false,
columnDefs: [{field: 'id', displayName: $scope.labels.idLabel},
{field: 'name', displayName: $scope.labels.nameLabel},
{field: 'type', displayName: $scope.labels.typeLabel}]
};
$scope.enumGridOptions = {
data: $scope.enumValues,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
enableHorizontalScrollbar: 0,
enableColumnMenus: false,
enableSorting: false,
columnDefs: [{ field: 'id', displayName: $scope.labels.idLabel },
{ field: 'name', displayName: $scope.labels.nameLabel}]
}
$scope.gridOptions.onRegisterApi = function (gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedProperty = row.entity;
$scope.selectedEnumValue = undefined;
if ($scope.selectedProperty && $scope.selectedProperty.enumValues) {
$scope.enumValues.length = 0;
for (var i = 0; i < $scope.selectedProperty.enumValues.length; i++) {
$scope.enumValues.push($scope.selectedProperty.enumValues[i]);
}
}
});
};
$scope.enumGridOptions.onRegisterApi = function (gridApi) {
//set gridApi on scope
$scope.enumGridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedEnumValue = row.entity;
});
};
});
// Handler for when the value of the type dropdown changes
$scope.propertyTypeChanged = function () {
// Check date. If date, show date pattern
if ($scope.selectedProperty.type === 'date') {
$scope.selectedProperty.datePattern = 'MM-dd-yyyy hh:mm';
} else {
delete $scope.selectedProperty.datePattern;
}
// Check enums. If enums, show list of options
if ($scope.selectedProperty.type === 'enums') {
$scope.selectedProperty.enumValues = [ {id: 'value1', name: 'Value 1'}, {id: 'value2', name: 'Value 2'}];
$scope.enumValues.length = 0;
for (var i = 0; i < $scope.selectedProperty.enumValues.length; i++) {
$scope.enumValues.push($scope.selectedProperty.enumValues[i]);
}
} else {
delete $scope.selectedProperty.enumValues;
$scope.enumValues.length = 0;
}
};
// Click handler for add button
var propertyIndex = 1;
$scope.addNewProperty = function () {
var newProperty = {
id: 'new_property_' + propertyIndex++,
name: '',
type: 'string',
readable: true,
writable: true
};
$scope.formProperties.push(newProperty);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(newProperty);
});
};
// Click handler for remove button
$scope.removeProperty = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.formProperties.indexOf(selectedItems[0]);
$scope.gridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.formProperties.splice(index, 1);
if ($scope.formProperties.length == 0) {
$scope.selectedProperty = undefined;
}
$timeout(function() {
if ($scope.formProperties.length > 0) {
$scope.gridApi.selection.toggleRowSelection($scope.formProperties[0]);
}
});
}
};
// Click handler for up button
$scope.movePropertyUp = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.formProperties.indexOf(selectedItems[0]);
if (index != 0) { // If it's the first, no moving up of course
var temp = $scope.formProperties[index];
$scope.formProperties.splice(index, 1);
$timeout(function(){
$scope.formProperties.splice(index + -1, 0, temp);
$timeout(function() {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for down button
$scope.movePropertyDown = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.formProperties.indexOf(selectedItems[0]);
if (index != $scope.formProperties.length - 1) { // If it's the last element, no moving down of course
var temp = $scope.formProperties[index];
$scope.formProperties.splice(index, 1);
$timeout(function(){
$scope.formProperties.splice(index + 1, 0, temp);
$timeout(function() {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
$scope.addNewEnumValue = function() {
if ($scope.selectedProperty) {
var newEnumValue = { id : '', name : ''};
$scope.selectedProperty.enumValues.push(newEnumValue);
$scope.enumValues.push(newEnumValue);
$timeout(function () {
$scope.enumGridApi.selection.toggleRowSelection(newEnumValue);
});
}
};
// Click handler for remove button
$scope.removeEnumValue = function() {
var selectedItems = $scope.enumGridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.enumValues.indexOf(selectedItems[0]);
$scope.enumGridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.enumValues.splice(index, 1);
$scope.selectedProperty.enumValues.splice(index, 1);
if ($scope.enumValues.length == 0) {
$scope.selectedEnumValue = undefined;
}
$timeout(function () {
if ($scope.enumValues.length > 0) {
$scope.enumGridApi.selection.toggleRowSelection($scope.enumValues[0]);
}
});
}
};
// Click handler for up button
$scope.moveEnumValueUp = function() {
var selectedItems = $scope.enumGridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.enumValues.indexOf(selectedItems[0]);
if (index != 0) { // If it's the first, no moving up of course
var temp = $scope.enumValues[index];
$scope.enumValues.splice(index, 1);
$scope.selectedProperty.enumValues.splice(index, 1);
$timeout(function () {
$scope.enumValues.splice(index + -1, 0, temp);
$scope.selectedProperty.enumValues.splice(index + -1, 0, temp);
$timeout(function () {
$scope.enumGridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for down button
$scope.moveEnumValueDown = function() {
var selectedItems = $scope.enumGridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.enumValues.indexOf(selectedItems[0]);
if (index != $scope.enumValues.length - 1) { // If it's the last element, no moving down of course
var temp = $scope.enumValues[index];
$scope.enumValues.splice(index, 1);
$scope.selectedProperty.enumValues.splice(index, 1);
$timeout(function () {
$scope.enumValues.splice(index + 1, 0, temp);
$scope.selectedProperty.enumValues.splice(index + 1, 0, temp);
$timeout(function () {
$scope.enumGridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for save button
$scope.save = function () {
if ($scope.formProperties.length > 0) {
$scope.property.value = {};
$scope.property.value.formProperties = $scope.formProperties;
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
$scope.cancel = function () {
$scope.$hide();
$scope.property.mode = 'read';
};
// Close button handler
$scope.close = function () {
$scope.$hide();
$scope.property.mode = 'read';
};
}])
;

View File

@ -0,0 +1,261 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
angular.module('flowableModeler').controller('FlowableFormReferenceDisplayCtrl',
[ '$scope', '$modal', '$http', function($scope, $modal, $http) {
if ($scope.property && $scope.property.value && $scope.property.value.id) {
$http.get(FLOWABLE.APP_URL.getModelUrl($scope.property.value.id))
.success(
function(response) {
$scope.form = {
id: response.id,
name: response.name
};
});
}
}]);
angular.module('flowableModeler').controller('FlowableFormReferenceCtrl',
[ '$scope', '$modal', '$http', function($scope, $modal, $http) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/form-reference-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowableFormReferencePopupCtrl',
[ '$rootScope', '$scope', '$http', '$location', 'editorManager', function($rootScope, $scope, $http, $location, editorManager) {
$scope.state = {'loadingForms' : true, 'formError' : false};
$scope.popup = {'state' : 'formReference'};
$scope.foldersBreadCrumbs = [];
// Close button handler
$scope.close = function() {
$scope.property.mode = 'read';
$scope.$hide();
};
// Selecting/deselecting a subprocess
$scope.selectForm = function(form, $event) {
$event.stopPropagation();
if ($scope.selectedForm && $scope.selectedForm.id && form.id == $scope.selectedForm.id) {
// un-select the current selection
$scope.selectedForm = null;
} else {
$scope.selectedForm = form;
}
};
// Saving the selected value
$scope.save = function() {
if ($scope.selectedForm) {
$scope.property.value = {
'id' : $scope.selectedForm.id,
'name' : $scope.selectedForm.name,
'key' : $scope.selectedForm.key
};
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
// Open the selected value
$scope.open = function() {
if ($scope.selectedForm) {
$scope.property.value = {
'id' : $scope.selectedForm.id,
'name' : $scope.selectedForm.name,
'key' : $scope.selectedForm.key
};
$scope.updatePropertyInModel($scope.property);
var modelMetaData = editorManager.getBaseModelData();
var json = editorManager.getModel();
json = JSON.stringify(json);
var params = {
modeltype: modelMetaData.model.modelType,
json_xml: json,
name: modelMetaData.name,
key: modelMetaData.key,
description: modelMetaData.description,
newversion: false,
lastUpdated: modelMetaData.lastUpdated
};
// Update
$http({ method: 'POST',
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: FLOWABLE.URL.putModel(modelMetaData.modelId)})
.success(function (data, status, headers, config) {
editorManager.handleEvents({
type: ORYX.CONFIG.EVENT_SAVED
});
var allSteps = EDITOR.UTIL.collectSortedElementsFromPrecedingElements($scope.selectedShape);
$rootScope.addHistoryItem($scope.selectedShape.resourceId);
$location.path('form-editor/' + $scope.selectedForm.id);
})
.error(function (data, status, headers, config) {
});
$scope.close();
}
};
$scope.newForm = function() {
$scope.popup.state = 'newForm';
var modelMetaData = editorManager.getBaseModelData();
$scope.model = {
loading: false,
form: {
name: '',
key: '',
description: '',
modelType: 2
}
};
};
$scope.createForm = function() {
if (!$scope.model.form.name || $scope.model.form.name.length == 0 ||
!$scope.model.form.key || $scope.model.form.key.length == 0) {
return;
}
$scope.model.loading = true;
$http({method: 'POST', url: FLOWABLE.APP_URL.getModelsUrl(), data: $scope.model.form}).
success(function(data, status, headers, config) {
var newFormId = data.id;
$scope.property.value = {
'id' : newFormId,
'name' : data.name,
'key' : data.key
};
$scope.updatePropertyInModel($scope.property);
var modelMetaData = editorManager.getBaseModelData();
var json = editorManager.getModel();
json = JSON.stringify(json);
var params = {
modeltype: modelMetaData.model.modelType,
json_xml: json,
name: modelMetaData.name,
key: modelMetaData.key,
description: modelMetaData.description,
newversion: false,
lastUpdated: modelMetaData.lastUpdated
};
// Update
$http({ method: 'POST',
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: FLOWABLE.URL.putModel(modelMetaData.modelId)})
.success(function (data, status, headers, config) {
editorManager.handleEvents({
type: ORYX.CONFIG.EVENT_SAVED
});
$scope.model.loading = false;
$scope.$hide();
var allSteps = EDITOR.UTIL.collectSortedElementsFromPrecedingElements($scope.selectedShape);
$rootScope.addHistoryItem($scope.selectedShape.resourceId);
$location.path('form-editor/' + newFormId);
})
.error(function (data, status, headers, config) {
$scope.model.loading = false;
$scope.$hide();
});
}).
error(function(data, status, headers, config) {
$scope.model.loading = false;
$scope.model.errorMessage = data.message;
});
};
$scope.cancel = function() {
$scope.close();
};
$scope.loadForms = function() {
var modelMetaData = editorManager.getBaseModelData();
$http.get(FLOWABLE.APP_URL.getFormModelsUrl())
.success(
function(response) {
$scope.state.loadingForms = false;
$scope.state.formError = false;
$scope.forms = response.data;
})
.error(
function(data, status, headers, config) {
$scope.state.loadingForms = false;
$scope.state.formError = true;
});
};
if ($scope.property && $scope.property.value && $scope.property.value.id) {
$scope.selectedForm = $scope.property.value;
}
$scope.loadForms();
}]);

View File

@ -0,0 +1,24 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
angular.module('flowableModeler').controller('FlowableHttpRequestMethodCtrl', [ '$scope', function($scope) {
if ($scope.property.value == undefined && $scope.property.value == null)
{
$scope.property.value = 'GET';
}
$scope.httpRequestMethodChanged = function() {
$scope.updatePropertyInModel($scope.property);
};
}]);

View File

@ -0,0 +1,179 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Input parameters for call activity
*/
angular.module('flowableModeler').controller('FlowableInParametersCtrl',
['$scope', '$modal', '$timeout', '$translate', function ($scope, $modal, $timeout, $translate) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/in-parameters-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowableInParametersPopupCtrl',
['$scope', '$q', '$translate', '$timeout', function ($scope, $q, $translate, $timeout) {
// Put json representing form properties on scope
if ($scope.property.value !== undefined && $scope.property.value !== null
&& $scope.property.value.inParameters !== undefined
&& $scope.property.value.inParameters !== null) {
// Note that we clone the json object rather then setting it directly,
// this to cope with the fact that the user can click the cancel button and no changes should have happened
$scope.parameters = angular.copy($scope.property.value.inParameters);
} else {
$scope.parameters = [];
}
$scope.translationsRetrieved = false;
$scope.labels = {};
var sourcePromise = $translate('PROPERTY.PARAMETER.SOURCE');
var sourceExpressionPromise = $translate('PROPERTY.PARAMETER.SOURCEEXPRESSION');
var targetPromise = $translate('PROPERTY.PARAMETER.TARGET');
$q.all([sourcePromise, sourceExpressionPromise, targetPromise]).then(function (results) {
$scope.labels.sourceLabel = results[0];
$scope.labels.sourceExpressionLabel = results[1];
$scope.labels.targetLabel = results[2];
$scope.translationsRetrieved = true;
// Config for grid
$scope.gridOptions = {
data: $scope.parameters,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
enableHorizontalScrollbar: 0,
enableColumnMenus: false,
enableSorting: false,
columnDefs: [{field: 'source', displayName: $scope.labels.sourceLabel},
{field: 'sourceExpression', displayName: $scope.labels.sourceExpressionLabel},
{field: 'target', displayName: $scope.labels.targetLabel}]
};
$scope.gridOptions.onRegisterApi = function (gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedParameter = row.entity;
});
};
});
// Click handler for add button
$scope.addNewParameter = function () {
var newParameter = {
source: '',
sourceExpression: '',
target: ''
};
$scope.parameters.push(newParameter);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(newParameter);
});
};
// Click handler for remove button
$scope.removeParameter = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.parameters.indexOf(selectedItems[0]);
$scope.gridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.parameters.splice(index, 1);
if ($scope.parameters.length == 0) {
$scope.selectedParameter = undefined;
}
$timeout(function () {
if ($scope.parameters.length > 0) {
$scope.gridApi.selection.toggleRowSelection($scope.parameters[0]);
}
});
}
};
// Click handler for up button
$scope.moveParameterUp = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.parameters.indexOf(selectedItems[0]);
if (index != 0) { // If it's the first, no moving up of course
var temp = $scope.parameters[index];
$scope.parameters.splice(index, 1);
$timeout(function () {
$scope.parameters.splice(index + -1, 0, temp);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for down button
$scope.moveParameterDown = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.parameters.indexOf(selectedItems[0]);
if (index != $scope.parameters.length - 1) { // If it's the last element, no moving down of course
var temp = $scope.parameters[index];
$scope.parameters.splice(index, 1);
$timeout(function () {
$scope.parameters.splice(index + 1, 0, temp);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for save button
$scope.save = function () {
if ($scope.parameters.length > 0) {
$scope.property.value = {};
$scope.property.value.inParameters = $scope.parameters;
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
$scope.cancel = function () {
$scope.close();
};
// Close button handler
$scope.close = function () {
$scope.property.mode = 'read';
$scope.$hide();
};
}]);

View File

@ -0,0 +1,145 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Execution listeners
*/
angular.module('flowableModeler').controller('FlowableMessageDefinitionsCtrl', ['$scope', '$modal', function ($scope, $modal) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/message-definitions-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
//Need a separate controller for the modal window due to https://github.com/angular-ui/bootstrap/issues/259
// Will be fixed in a newer version of Angular UI
angular.module('flowableModeler').controller('FlowableMessageDefinitionsPopupCtrl',
['$scope', '$q', '$translate', '$timeout', function ($scope, $q, $translate, $timeout) {
// Put json representing mesage definitions on scope
if ($scope.property.value !== undefined && $scope.property.value !== null && $scope.property.value.length > 0) {
if ($scope.property.value.constructor == String) {
$scope.messageDefinitions = JSON.parse($scope.property.value);
}
else {
// Note that we clone the json object rather then setting it directly,
// this to cope with the fact that the user can click the cancel button and no changes should have happened
$scope.messageDefinitions = angular.copy($scope.property.value);
}
} else {
$scope.messageDefinitions = [];
}
// Array to contain selected mesage definitions (yes - we only can select one, but ng-grid isn't smart enough)
$scope.selectedMessageDefinition = undefined;
$scope.translationsRetrieved = false;
$scope.labels = {};
var idPromise = $translate('PROPERTY.MESSAGEDEFINITIONS.ID');
var namePromise = $translate('PROPERTY.MESSAGEDEFINITIONS.NAME');
$q.all([idPromise, namePromise]).then(function (results) {
$scope.labels.idLabel = results[0];
$scope.labels.nameLabel = results[1];
$scope.translationsRetrieved = true;
// Config for grid
$scope.gridOptions = {
data: $scope.messageDefinitions,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
enableHorizontalScrollbar: 0,
enableColumnMenus: false,
enableSorting: false,
columnDefs: [
{field: 'id', displayName: $scope.labels.idLabel},
{field: 'name', displayName: $scope.labels.nameLabel}]
};
$scope.gridOptions.onRegisterApi = function (gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedMessageDefinition = row.entity;
});
};
});
// Click handler for add button
$scope.addNewMessageDefinition = function () {
var newMessageDefinition = {id: '', name: ''};
$scope.messageDefinitions.push(newMessageDefinition);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(newMessageDefinition);
});
};
// Click handler for remove button
$scope.removeMessageDefinition = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.messageDefinitions.indexOf(selectedItems[0]);
$scope.gridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.messageDefinitions.splice(index, 1);
if ($scope.messageDefinitions.length == 0) {
$scope.selectedMesageDefinition = undefined;
}
$timeout(function () {
if ($scope.messageDefinitions.length > 0) {
$scope.gridApi.selection.toggleRowSelection($scope.messageDefinitions[0]);
}
});
}
};
// Click handler for save button
$scope.save = function () {
if ($scope.messageDefinitions.length > 0) {
$scope.property.value = $scope.messageDefinitions;
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
$scope.cancel = function () {
$scope.property.mode = 'read';
$scope.$hide();
};
// Close button handler
$scope.close = function () {
$scope.property.mode = 'read';
$scope.$hide();
};
}]);

View File

@ -0,0 +1,41 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
angular.module('flowableModeler').controller('FlowableMessageRefCtrl', [ '$scope', function($scope) {
// Find the parent shape on which the message definitions are defined
var messageDefinitionsProperty = undefined;
var parent = $scope.selectedShape;
while (parent !== null && parent !== undefined && messageDefinitionsProperty === undefined) {
if (parent.properties && parent.properties.get('oryx-messagedefinitions')) {
messageDefinitionsProperty = parent.properties.get('oryx-messagedefinitions');
} else {
parent = parent.parent;
}
}
try {
messageDefinitionsProperty = JSON.parse(messageDefinitionsProperty);
if (typeof messageDefinitionsProperty == 'string') {
messageDefinitionsProperty = JSON.parse(messageDefinitionsProperty);
}
} catch (err) {
// Do nothing here, just to be sure we try-catch it
}
$scope.messageDefinitions = messageDefinitionsProperty;
$scope.messageChanged = function() {
$scope.updatePropertyInModel($scope.property);
};
}]);

View File

@ -0,0 +1,24 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
angular.module('flowableModeler').controller('FlowableMultiInstanceCtrl', [ '$scope', function($scope) {
if ($scope.property.value == undefined && $scope.property.value == null)
{
$scope.property.value = 'None';
}
$scope.multiInstanceChanged = function() {
$scope.updatePropertyInModel($scope.property);
};
}]);

View File

@ -0,0 +1,28 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Adhoc sub process ordering property
*/
angular.module('flowableModeler').controller('FlowableOrderingCtrl', [ '$scope', function($scope) {
if ($scope.property.value == undefined && $scope.property.value == null)
{
$scope.property.value = 'Parallel';
}
$scope.orderingChanged = function() {
$scope.updatePropertyInModel($scope.property);
};
}]);

View File

@ -0,0 +1,176 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Input parameters for call activity
*/
angular.module('flowableModeler').controller('FlowableOutParametersCtrl',
['$scope', '$modal', '$timeout', '$translate', function ($scope, $modal, $timeout, $translate) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/out-parameters-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowableOutParametersPopupCtrl',
['$scope', '$q', '$translate', '$timeout', function ($scope, $q, $translate, $timeout) {
// Put json representing form properties on scope
if ($scope.property.value !== undefined && $scope.property.value !== null
&& $scope.property.value.outParameters !== undefined
&& $scope.property.value.outParameters !== null) {
// Note that we clone the json object rather then setting it directly,
// this to cope with the fact that the user can click the cancel button and no changes should have happened
$scope.parameters = angular.copy($scope.property.value.outParameters);
} else {
$scope.parameters = [];
}
$scope.translationsRetrieved = false;
$scope.labels = {};
var sourcePromise = $translate('PROPERTY.PARAMETER.SOURCE');
var sourceExpressionPromise = $translate('PROPERTY.PARAMETER.SOURCEEXPRESSION');
var targetPromise = $translate('PROPERTY.PARAMETER.TARGET');
$q.all([sourcePromise, sourceExpressionPromise, targetPromise]).then(function (results) {
$scope.labels.sourceLabel = results[0];
$scope.labels.sourceExpressionLabel = results[1];
$scope.labels.targetLabel = results[2];
$scope.translationsRetrieved = true;
// Config for grid
$scope.gridOptions = {
data: $scope.parameters,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
enableHorizontalScrollbar: 0,
enableColumnMenus: false,
enableSorting: false,
columnDefs: [{field: 'source', displayName: $scope.labels.sourceLabel},
{field: 'sourceExpression', displayName: $scope.labels.sourceExpressionLabel},
{field: 'target', displayName: $scope.labels.targetLabel}]
};
$scope.gridOptions.onRegisterApi = function (gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedParameter = row.entity;
});
};
});
// Click handler for add button
$scope.addNewParameter = function () {
var newParameter = {
source: '',
sourceExpression: '',
target: ''};
$scope.parameters.push(newParameter);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(newParameter);
});
};
// Click handler for remove button
$scope.removeParameter = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.parameters.indexOf(selectedItems[0]);
$scope.gridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.parameters.splice(index, 1);
if ($scope.parameters.length == 0) {
$scope.selectedParameter = undefined;
}
$timeout(function () {
if ($scope.parameters.length > 0) {
$scope.gridApi.selection.toggleRowSelection($scope.parameters[0]);
}
});
}
};
// Click handler for up button
$scope.moveParameterUp = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.parameters.indexOf(selectedItems[0]);
if (index != 0) { // If it's the first, no moving up of course
var temp = $scope.parameters[index];
$scope.parameters.splice(index, 1);
$timeout(function () {
$scope.parameters.splice(index + -1, 0, temp);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for down button
$scope.moveParameterDown = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.parameters.indexOf(selectedItems[0]);
if (index != $scope.parameters.length - 1) { // If it's the last element, no moving down of course
var temp = $scope.parameters[index];
$scope.parameters.splice(index, 1);
$timeout(function () {
$scope.parameters.splice(index + 1, 0, temp);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for save button
$scope.save = function () {
if ($scope.parameters.length > 0) {
$scope.property.value = {};
$scope.property.value.outParameters = $scope.parameters;
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
$scope.cancel = function () {
$scope.close();
};
// Close button handler
$scope.close = function () {
$scope.property.mode = 'read';
$scope.$hide();
};
}]);

View File

@ -0,0 +1,357 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
angular.module('flowableModeler').controller('FlowablePlanItemLifecycleListenersCtrl',
['$scope', '$modal', '$timeout', '$translate', function ($scope, $modal, $timeout, $translate) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/plan-item-lifecycle-listeners-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowablePlanItemLifecycleListenersPopupCtrl',
['$scope', '$q', '$translate', '$timeout', function ($scope, $q, $translate, $timeout) {
// Put json representing form properties on scope
if ($scope.property.value !== undefined && $scope.property.value !== null
&& $scope.property.value.planItemLifecycleListeners !== undefined
&& $scope.property.value.planItemLifecycleListeners !== null) {
if ($scope.property.value.planItemLifecycleListeners.constructor == String) {
$scope.planItemLifecycleListeners = JSON.parse($scope.property.value.planItemLifecycleListeners);
}
else {
// Note that we clone the json object rather then setting it directly,
// this to cope with the fact that the user can click the cancel button and no changes should have happened
$scope.planItemLifecycleListeners = angular.copy($scope.property.value.planItemLifecycleListeners);
}
for (var i = 0; i < $scope.planItemLifecycleListeners.length; i++) {
var planItemLifeCycleListener = $scope.planItemLifecycleListeners[i];
if (planItemLifeCycleListener.className !== undefined && planItemLifeCycleListener.className !== '') {
planItemLifeCycleListener.implementation = planItemLifeCycleListener.className;
}
else if (planItemLifeCycleListener.expression !== undefined && planItemLifeCycleListener.expression !== '') {
planItemLifeCycleListener.implementation = planItemLifeCycleListener.expression;
}
else if (planItemLifeCycleListener.delegateExpression !== undefined && planItemLifeCycleListener.delegateExpression !== '') {
planItemLifeCycleListener.implementation = planItemLifeCycleListener.delegateExpression;
}
}
} else {
$scope.planItemLifecycleListeners = [];
}
$scope.selectedListener = undefined;
$scope.selectedField = undefined;
$scope.fields = [];
$scope.translationsRetrieved = false;
$scope.labels = {};
var sourceStatePromise = $translate('PROPERTY.PLANITEMLIFECYCLELISTENERS.SOURCE_STATE');
var targetStatePromise = $translate('PROPERTY.PLANITEMLIFECYCLELISTENERS.TARGET_STATE');
var implementationPromise = $translate('PROPERTY.PLANITEMLIFECYCLELISTENERS.FIELDS.IMPLEMENTATION');
var namePromise = $translate('PROPERTY.PLANITEMLIFECYCLELISTENERS.FIELDS.NAME');
$q.all([sourceStatePromise, targetStatePromise, implementationPromise, namePromise]).then(function (results) {
$scope.labels.sourceStateLabel = results[1];
$scope.labels.targetStateLabel = results[2];
$scope.labels.implementationLabel = results[3];
$scope.labels.nameLabel = results[4];
$scope.translationsRetrieved = true;
// Config for grid
$scope.gridOptions = {
data: $scope.planItemLifecycleListeners,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
enableHorizontalScrollbar: 0,
enableColumnMenus: false,
enableSorting: false,
columnDefs: [
{field: 'sourceState', displayName: $scope.labels.sourceStateLabel},
{field: 'targetState', displayName: $scope.labels.targetStateLabel},
{field: 'implementation', displayName: $scope.labels.implementationLabel}
]
};
$scope.gridOptions.onRegisterApi = function (gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedListener = row.entity;
$scope.selectedField = undefined;
if ($scope.selectedListener) {
var fields = $scope.selectedListener.fields;
if (fields !== undefined && fields !== null) {
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
if (field.stringValue !== undefined && field.stringValue !== '') {
field.implementation = field.stringValue;
} else if (field.expression !== undefined && field.expression !== '') {
field.implementation = field.expression;
} else if (field.string !== undefined && field.string !== '') {
field.implementation = field.string;
}
}
} else {
$scope.selectedListener.fields = [];
}
$scope.fields.length = 0;
for (var i = 0; i < $scope.selectedListener.fields.length; i++) {
$scope.fields.push($scope.selectedListener.fields[i]);
}
}
});
};
// Config for field grid
$scope.gridFieldOptions = {
data: $scope.fields,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
columnDefs: [{field: 'name', displayName: $scope.labels.name},
{field: 'implementation', displayName: $scope.labels.implementationLabel}]
};
$scope.gridFieldOptions.onRegisterApi = function (gridApi) {
// set gridApi on scope
$scope.fieldGridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedField = row.entity;
});
};
});
$scope.listenerDetailsChanged = function () {
if ($scope.selectedListener.className !== '') {
$scope.selectedListener.implementation = $scope.selectedListener.className;
} else if ($scope.selectedListener.expression !== '') {
$scope.selectedListener.implementation = $scope.selectedListener.expression;
} else if ($scope.selectedListener.delegateExpression !== '') {
$scope.selectedListener.implementation = $scope.selectedListener.delegateExpression;
} else {
$scope.selectedListener.implementation = '';
}
};
// Click handler for add button
$scope.addNewListener = function () {
var newListener = {
sourceState: 'available',
targetState: 'active',
implementation: '',
className: '',
expression: '',
delegateExpression: ''
};
$scope.planItemLifecycleListeners.push(newListener);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(newListener);
});
};
// Click handler for remove button
$scope.removeListener = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.planItemLifecycleListeners.indexOf(selectedItems[0]);
$scope.gridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.planItemLifecycleListeners.splice(index, 1);
if ($scope.planItemLifecycleListeners.length == 0) {
$scope.selectedListener = undefined;
}
$timeout(function () {
if ($scope.planItemLifecycleListeners.length > 0) {
$scope.gridApi.selection.toggleRowSelection($scope.planItemLifecycleListeners[0]);
}
});
}
};
// Click handler for up button
$scope.moveListenerUp = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.planItemLifecycleListeners.indexOf(selectedItems[0]);
if (index != 0) { // If it's the first, no moving up of course
var temp = $scope.planItemLifecycleListeners[index];
$scope.planItemLifecycleListeners.splice(index, 1);
$timeout(function () {
$scope.planItemLifecycleListeners.splice(index + -1, 0, temp);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for down button
$scope.moveListenerDown = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.planItemLifecycleListeners.indexOf(selectedItems[0]);
if (index != $scope.planItemLifecycleListeners.length - 1) { // If it's the last element, no moving down of course
var temp = $scope.planItemLifecycleListeners[index];
$scope.planItemLifecycleListeners.splice(index, 1);
$timeout(function () {
$scope.planItemLifecycleListeners.splice(index + 1, 0, temp);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
$scope.fieldDetailsChanged = function () {
if ($scope.selectedField.stringValue != '') {
$scope.selectedField.implementation = $scope.selectedField.stringValue;
} else if ($scope.selectedField.expression != '') {
$scope.selectedField.implementation = $scope.selectedField.expression;
} else if ($scope.selectedField.string != '') {
$scope.selectedField.implementation = $scope.selectedField.string;
} else {
$scope.selectedField.implementation = '';
}
};
// Click handler for add button
$scope.addNewField = function () {
if ($scope.selectedListener) {
if ($scope.selectedListener.fields == undefined) {
$scope.selectedListener.fields = [];
}
var newField = {
name: 'fieldName',
implementation: '',
stringValue: '',
expression: '',
string: ''
};
$scope.fields.push(newField);
$scope.selectedListener.fields.push(newField);
$timeout(function () {
$scope.fieldGridApi.selection.toggleRowSelection(newField);
});
}
};
// Click handler for remove button
$scope.removeField = function () {
var selectedItems = $scope.fieldGridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.fields.indexOf(selectedItems[0]);
$scope.fieldGridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.fields.splice(index, 1);
$scope.selectedListener.fields.splice(index, 1);
if ($scope.fields.length == 0) {
$scope.selectedField = undefined;
}
$timeout(function () {
if ($scope.fields.length > 0) {
$scope.fieldGridApi.selection.toggleRowSelection($scope.fields[0]);
}
});
}
};
// Click handler for up button
$scope.moveFieldUp = function () {
var selectedItems = $scope.fieldGridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.fields.indexOf(selectedItems[0]);
if (index != 0) { // If it's the first, no moving up of course
var temp = $scope.fields[index];
$scope.fields.splice(index, 1);
$scope.selectedListener.fields.splice(index, 1);
$timeout(function () {
$scope.fields.splice(index + -1, 0, temp);
$scope.selectedListener.fields.splice(index + -1, 0, temp);
$timeout(function () {
$scope.fieldGridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for down button
$scope.moveFieldDown = function () {
var selectedItems = $scope.fieldGridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.fields.indexOf(selectedItems[0]);
if (index != $scope.fields.length - 1) { // If it's the last element, no moving down of course
var temp = $scope.fields[index];
$scope.fields.splice(index, 1);
$scope.selectedListeners.fields.splice(index, 1);
$timeout(function () {
$scope.fields.splice(index + 1, 0, temp);
$scope.selectedListener.fields.splice(index + 1, 0, temp);
$timeout(function () {
$scope.fieldGridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for save button
$scope.save = function () {
if ($scope.planItemLifecycleListeners.length > 0) {
$scope.property.value = {};
$scope.property.value.planItemLifecycleListeners = $scope.planItemLifecycleListeners;
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
$scope.cancel = function () {
$scope.close();
};
// Close button handler
$scope.close = function () {
$scope.property.mode = 'read';
$scope.$hide();
};
}]);

View File

@ -0,0 +1,82 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
angular.module('flowableModeler').controller('FlowablePlanItemDropdownCtrl', [ '$scope', function($scope) {
// Find all planitems
var selectedShape = $scope.selectedShape;
if (selectedShape) {
// Go up in parent chain until plan model is found
var planModel;
var parent = selectedShape.parent;
if (parent) {
while (planModel === undefined && parent !== null && parent !== undefined) {
if (parent.resourceId !== null && parent.resourceId !== undefined && 'casePlanModel' === parent.resourceId) {
planModel = parent;
} else {
parent = parent.parent;
}
}
}
var planItems = [];
if (planModel !== null && planModel !== undefined) {
var toVisit = [];
for (var i=0; i<planModel.children.length; i++) {
toVisit.push(planModel.children[i]);
}
while (toVisit.length > 0) {
var child = toVisit.pop();
if (typeof child.getStencil === 'function'
&& (child.getStencil()._jsonStencil.groups.indexOf('Activities') >= 0 || (child.getStencil()._jsonStencil.title === 'Stage') )) {
planItems.push(child);
}
if (child.children !== null && child.children !== undefined) {
for (var i=0; i<child.children.length; i++) {
toVisit.push(child.children[i]);
}
}
}
}
var simplifiedPlanItems = [];
for (var i=0; i<planItems.length; i++) {
simplifiedPlanItems.push({ id: planItems[i].resourceId, name: planItems[i].properties.get('oryx-name') });
}
if (simplifiedPlanItems.length > 0) {
simplifiedPlanItems.sort(function(a,b) {
if(a.name < b.name) {
return -1;
} else if (a.name > b.name) {
return 1;
} else {
return 0;
}
});
}
$scope.planItems = simplifiedPlanItems;
}
if ($scope.property.value == undefined && $scope.property.value == null) {
$scope.property.value = '';
}
$scope.planItemChanged = function() {
$scope.updatePropertyInModel($scope.property);
};
}]);

View File

@ -0,0 +1,24 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
angular.module('flowableModeler').controller('FlowableProcessHistoryLevelCtrl', [ '$scope', function($scope) {
if ($scope.property.value == undefined && $scope.property.value == null)
{
$scope.property.value = 'None';
}
$scope.historyLevelChanged = function() {
$scope.updatePropertyInModel($scope.property);
};
}]);

View File

@ -0,0 +1,80 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
angular.module('flowableModeler').controller('FlowableProcessReferenceCtrl',
[ '$scope', '$modal', '$http', function($scope, $modal, $http) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/process-reference-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowableProcessReferencePopupCtrl', [ '$scope', '$http', function($scope, $http) {
$scope.state = {'loadingProcesses' : true, 'error' : false};
// Close button handler
$scope.close = function() {
$scope.property.mode = 'read';
$scope.$hide();
};
// Selecting/deselecting a process
$scope.selectProcess = function(processModel, $event) {
$event.stopPropagation();
if ($scope.selectedProcess && $scope.selectedProcess.id && processModel.id == $scope.selectedProcess.id) {
// un-select the current selection
$scope.selectedProcess = null;
} else {
$scope.selectedProcess = processModel;
}
};
// Saving the selected value
$scope.save = function() {
if ($scope.selectedProcess) {
$scope.property.value = {'id' : $scope.selectedProcess.id, 'name' : $scope.selectedProcess.name};
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
$scope.loadProcesses = function() {
$http.get(FLOWABLE.APP_URL.getModelsUrl("?modelType=0"))
.success(
function(response) {
$scope.state.loadingProcesses = false;
$scope.state.processError = false;
$scope.processModels = response.data;
})
.error(
function(data, status, headers, config) {
$scope.state.loadingProcesses = false;
$scope.state.processError = true;
});
};
if ($scope.property && $scope.property.value && $scope.property.value.id) {
$scope.selectedProcess = $scope.property.value;
}
$scope.loadProcesses();
}]);

View File

@ -0,0 +1,126 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Sequence flow order controller
*/
angular.module('flowableModeler').controller('FlowableSequenceFlowOrderCtrl',
[ '$scope', '$modal', '$timeout', '$translate', function($scope, $modal, $timeout, $translate) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/sequenceflow-order-popup.html?version=' + Date.now(),
scope: $scope
};
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowableSequenceFlowOrderPopupCtrl',
['$scope', '$translate', function($scope, $translate) {
// Find the outgoing sequence flow of the current selected shape
var outgoingSequenceFlow = [];
var selectedShape = $scope.selectedShape;
if (selectedShape) {
var outgoingNodes = selectedShape.getOutgoingShapes();
for (var i=0; i<outgoingNodes.length; i++) {
if (outgoingNodes[i].getStencil().idWithoutNs() === 'SequenceFlow') {
var targetActivity = outgoingNodes[i].getTarget();
// We need the resourceId of a sequence flow, not the id because that will change with every editor load
outgoingSequenceFlow.push({
id : outgoingNodes[i].resourceId,
targetTitle : targetActivity.properties.get('oryx-name'),
targetType : $translate.instant(targetActivity.getStencil().title())
});
}
}
} else {
console.log('Programmatic error: no selected shape found');
}
// Now we can apply the order which was (possibly) previously saved
var orderedOutgoingSequenceFlow = [];
if ($scope.property.value && $scope.property.value.sequenceFlowOrder) {
var sequenceFlowOrderList = $scope.property.value.sequenceFlowOrder;
// Loop the list of sequence flow that was saved in the json model and match them with the outgoing sequence flow found above
for (var flowIndex=0; flowIndex < sequenceFlowOrderList.length; flowIndex++) {
// find the sequence flow in the outgoing sequence flows.
for (var outgoingFlowIndex=0; outgoingFlowIndex < outgoingSequenceFlow.length; outgoingFlowIndex++) {
if (outgoingSequenceFlow[outgoingFlowIndex].id === sequenceFlowOrderList[flowIndex]) {
orderedOutgoingSequenceFlow.push(outgoingSequenceFlow[outgoingFlowIndex]);
outgoingSequenceFlow.splice(outgoingFlowIndex, 1);
break;
}
}
}
// Now all the matching sequence flow we're removed from the outgoing sequence flow list
// We can simply apply the remaining ones (these are new vs. the time when the values were saved to the model)
orderedOutgoingSequenceFlow = orderedOutgoingSequenceFlow.concat(outgoingSequenceFlow);
} else {
orderedOutgoingSequenceFlow = outgoingSequenceFlow;
}
// Now we can put it on the scope
$scope.outgoingSequenceFlow = orderedOutgoingSequenceFlow;
// Move up click handler
$scope.moveUp = function(index) {
var temp = $scope.outgoingSequenceFlow[index];
$scope.outgoingSequenceFlow[index] = $scope.outgoingSequenceFlow[index - 1];
$scope.outgoingSequenceFlow[index - 1] = temp;
};
// Move down click handler
$scope.moveDown = function(index) {
var temp = $scope.outgoingSequenceFlow[index];
$scope.outgoingSequenceFlow[index] = $scope.outgoingSequenceFlow[index + 1];
$scope.outgoingSequenceFlow[index + 1] = temp;
};
// Save click handler
$scope.save = function() {
if ($scope.outgoingSequenceFlow.length > 0) {
$scope.property.value = {};
$scope.property.value.sequenceFlowOrder = [];
for (var flowIndex=0; flowIndex < $scope.outgoingSequenceFlow.length; flowIndex++) {
$scope.property.value.sequenceFlowOrder.push($scope.outgoingSequenceFlow[flowIndex].id);
}
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
// Cancel click handler
$scope.cancel = function() {
$scope.close();
};
// Close button handler
$scope.close = function() {
$scope.property.mode = 'read';
$scope.$hide();
};
}]);

View File

@ -0,0 +1,151 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Execution listeners
*/
angular.module('flowableModeler').controller('FlowableSignalDefinitionsCtrl', ['$scope', '$modal', function ($scope, $modal) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/signal-definitions-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
//Need a separate controller for the modal window due to https://github.com/angular-ui/bootstrap/issues/259
// Will be fixed in a newer version of Angular UI
angular.module('flowableModeler').controller('FlowableSignalDefinitionsPopupCtrl',
['$scope', '$q', '$translate', '$timeout', function ($scope, $q, $translate, $timeout) {
// Put json representing signal definitions on scope
if ($scope.property.value !== undefined && $scope.property.value !== null && $scope.property.value.length > 0) {
if ($scope.property.value.constructor == String) {
$scope.signalDefinitions = JSON.parse($scope.property.value);
}
else {
// Note that we clone the json object rather then setting it directly,
// this to cope with the fact that the user can click the cancel button and no changes should have happened
$scope.signalDefinitions = angular.copy($scope.property.value);
}
} else {
$scope.signalDefinitions = [];
}
// Array to contain selected signal definitions (yes - we only can select one, but ng-grid isn't smart enough)
$scope.selectedSignalDefinition = undefined;
$scope.translationsRetrieved = false;
$scope.labels = {};
var idPromise = $translate('PROPERTY.SIGNALDEFINITIONS.ID');
var namePromise = $translate('PROPERTY.SIGNALDEFINITIONS.NAME');
var scopePromise = $translate('PROPERTY.SIGNALDEFINITIONS.SCOPE');
$q.all([idPromise, namePromise, scopePromise]).then(function (results) {
$scope.labels.idLabel = results[0];
$scope.labels.nameLabel = results[1];
$scope.labels.scopeLabel = results[2];
$scope.translationsRetrieved = true;
// Config for grid
$scope.gridOptions = {
data: $scope.signalDefinitions,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
enableHorizontalScrollbar: 0,
enableColumnMenus: false,
enableSorting: false,
columnDefs: [
{field: 'id', displayName: $scope.labels.idLabel},
{field: 'name', displayName: $scope.labels.nameLabel},
{field: 'scope', displayName: $scope.labels.scopeLabel}]
};
$scope.gridOptions.onRegisterApi = function (gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedSignalDefinition = row.entity;
});
};
});
// Click handler for add button
$scope.addNewSignalDefinition = function () {
var newSignalDefinition = {id: '', name: '', scope: 'global'};
$scope.signalDefinitions.push(newSignalDefinition);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(newSignalDefinition);
});
};
// Click handler for remove button
$scope.removeSignalDefinition = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.signalDefinitions.indexOf(selectedItems[0]);
$scope.gridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.signalDefinitions.splice(index, 1);
if ($scope.signalDefinitions.length == 0) {
$scope.selectedSignalDefinition = undefined;
}
$timeout(function () {
if ($scope.signalDefinitions.length > 0) {
$scope.gridApi.selection.toggleRowSelection($scope.signalDefinitions[0]);
}
});
}
};
$scope.scopeOptions = [{'value': 'global', 'translationId': 'PROPERTY.SIGNALDEFINITIONS.SCOPE-GLOBAL'},
{'value': 'processInstance', 'translationId': 'PROPERTY.SIGNALDEFINITIONS.SCOPE-PROCESSINSTANCE'}];
// Click handler for save button
$scope.save = function () {
if ($scope.signalDefinitions.length > 0) {
$scope.property.value = $scope.signalDefinitions;
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
$scope.cancel = function () {
$scope.property.mode = 'read';
$scope.$hide();
};
// Close button handler
$scope.close = function () {
$scope.property.mode = 'read';
$scope.$hide();
};
}]);

View File

@ -0,0 +1,42 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
angular.module('flowableModeler').controller('FlowableSignalRefCtrl', [ '$scope', function($scope) {
// Find the parent shape on which the signal definitions are defined
var signalDefinitionsProperty = undefined;
var parent = $scope.selectedShape;
while (parent !== null && parent !== undefined && signalDefinitionsProperty === undefined) {
if (parent.properties && parent.properties.get('oryx-signaldefinitions')) {
signalDefinitionsProperty = parent.properties.get('oryx-signaldefinitions');
} else {
parent = parent.parent;
}
}
try {
signalDefinitionsProperty = JSON.parse(signalDefinitionsProperty);
if (typeof signalDefinitionsProperty == 'string') {
signalDefinitionsProperty = JSON.parse(signalDefinitionsProperty);
}
} catch (err) {
// Do nothing here, just to be sure we try-catch it
}
$scope.signalDefinitions = signalDefinitionsProperty;
$scope.signalChanged = function() {
$scope.updatePropertyInModel($scope.property);
};
}]);

View File

@ -0,0 +1,356 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Task listeners
*/
angular.module('flowableModeler').controller('FlowableTaskListenersCtrl',
['$scope', '$modal', '$timeout', '$translate', function ($scope, $modal, $timeout, $translate) {
// Config for the modal window
var opts = {
template: 'editor-app/configuration/properties/task-listeners-popup.html?version=' + Date.now(),
scope: $scope
};
// Open the dialog
_internalCreateModal(opts, $modal, $scope);
}]);
angular.module('flowableModeler').controller('FlowableTaskListenersPopupCtrl',
['$scope', '$q', '$translate', '$timeout', function ($scope, $q, $translate, $timeout) {
// Put json representing form properties on scope
if ($scope.property.value !== undefined && $scope.property.value !== null
&& $scope.property.value.taskListeners !== undefined
&& $scope.property.value.taskListeners !== null) {
if ($scope.property.value.taskListeners.constructor == String) {
$scope.taskListeners = JSON.parse($scope.property.value.taskListeners);
}
else {
// Note that we clone the json object rather then setting it directly,
// this to cope with the fact that the user can click the cancel button and no changes should have happened
$scope.taskListeners = angular.copy($scope.property.value.taskListeners);
}
for (var i = 0; i < $scope.taskListeners.length; i++) {
var taskListener = $scope.taskListeners[i];
if (taskListener.className !== undefined && taskListener.className !== '') {
taskListener.implementation = taskListener.className;
}
else if (taskListener.expression !== undefined && taskListener.expression !== '') {
taskListener.implementation = taskListener.expression;
}
else if (taskListener.delegateExpression !== undefined && taskListener.delegateExpression !== '') {
taskListener.implementation = taskListener.delegateExpression;
}
}
} else {
$scope.taskListeners = [];
}
$scope.selectedListener = undefined;
$scope.selectedField = undefined;
$scope.fields = [];
$scope.translationsRetrieved = false;
$scope.labels = {};
var eventPromise = $translate('PROPERTY.TASKLISTENERS.EVENT');
var implementationPromise = $translate('PROPERTY.TASKLISTENERS.FIELDS.IMPLEMENTATION');
var namePromise = $translate('PROPERTY.TASKLISTENERS.FIELDS.NAME');
$q.all([eventPromise, implementationPromise, namePromise]).then(function (results) {
$scope.labels.eventLabel = results[0];
$scope.labels.implementationLabel = results[1];
$scope.labels.nameLabel = results[2];
$scope.translationsRetrieved = true;
// Config for grid
$scope.gridOptions = {
data: $scope.taskListeners,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
enableHorizontalScrollbar: 0,
enableColumnMenus: false,
enableSorting: false,
columnDefs: [{field: 'event', displayName: $scope.labels.eventLabel},
{field: 'implementation', displayName: $scope.labels.implementationLabel}]
};
$scope.gridOptions.onRegisterApi = function (gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedListener = row.entity;
$scope.selectedField = undefined;
if ($scope.selectedListener) {
var fields = $scope.selectedListener.fields;
if (fields !== undefined && fields !== null) {
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
if (field.stringValue !== undefined && field.stringValue !== '') {
field.implementation = field.stringValue;
} else if (field.expression !== undefined && field.expression !== '') {
field.implementation = field.expression;
} else if (field.string !== undefined && field.string !== '') {
field.implementation = field.string;
}
}
} else {
$scope.selectedListener.fields = [];
}
$scope.fields.length = 0;
for (var i = 0; i < $scope.selectedListener.fields.length; i++) {
$scope.fields.push($scope.selectedListener.fields[i]);
}
}
});
};
// Config for field grid
$scope.gridFieldOptions = {
data: $scope.fields,
headerRowHeight: 28,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
columnDefs: [{field: 'name', displayName: $scope.labels.name},
{field: 'implementation', displayName: $scope.labels.implementationLabel}]
};
$scope.gridFieldOptions.onRegisterApi = function (gridApi) {
// set gridApi on scope
$scope.fieldGridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.selectedField = row.entity;
});
};
});
$scope.listenerDetailsChanged = function () {
if ($scope.selectedListener.className !== '') {
$scope.selectedListener.implementation = $scope.selectedListener.className;
} else if ($scope.selectedListener.expression !== '') {
$scope.selectedListener.implementation = $scope.selectedListener.expression;
} else if ($scope.selectedListener.delegateExpression !== '') {
$scope.selectedListener.implementation = $scope.selectedListener.delegateExpression;
} else {
$scope.selectedListener.implementation = '';
}
};
// Click handler for add button
$scope.addNewListener = function () {
var newListener = {
event: 'create',
implementation: '',
className: '',
expression: '',
delegateExpression: ''
};
$scope.taskListeners.push(newListener);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(newListener);
});
};
// Click handler for remove button
$scope.removeListener = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.taskListeners.indexOf(selectedItems[0]);
$scope.gridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.taskListeners.splice(index, 1);
if ($scope.taskListeners.length == 0) {
$scope.selectedListener = undefined;
}
$timeout(function () {
if ($scope.taskListeners.length > 0) {
$scope.gridApi.selection.toggleRowSelection($scope.taskListeners[0]);
}
});
}
};
// Click handler for up button
$scope.moveListenerUp = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.taskListeners.indexOf(selectedItems[0]);
if (index != 0) { // If it's the first, no moving up of course
var temp = $scope.taskListeners[index];
$scope.taskListeners.splice(index, 1);
$timeout(function () {
$scope.taskListeners.splice(index + -1, 0, temp);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for down button
$scope.moveListenerDown = function () {
var selectedItems = $scope.gridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.taskListeners.indexOf(selectedItems[0]);
if (index != $scope.taskListeners.length - 1) { // If it's the last element, no moving down of course
var temp = $scope.taskListeners[index];
$scope.taskListeners.splice(index, 1);
$timeout(function () {
$scope.taskListeners.splice(index + 1, 0, temp);
$timeout(function () {
$scope.gridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
$scope.fieldDetailsChanged = function () {
if ($scope.selectedField.stringValue != '') {
$scope.selectedField.implementation = $scope.selectedField.stringValue;
} else if ($scope.selectedField.expression != '') {
$scope.selectedField.implementation = $scope.selectedField.expression;
} else if ($scope.selectedField.string != '') {
$scope.selectedField.implementation = $scope.selectedField.string;
} else {
$scope.selectedField.implementation = '';
}
};
// Click handler for add button
$scope.addNewField = function () {
if ($scope.selectedListener) {
if ($scope.selectedListener.fields == undefined) {
$scope.selectedListener.fields = [];
}
var newField = {
name: 'fieldName',
implementation: '',
stringValue: '',
expression: '',
string: ''
};
$scope.fields.push(newField);
$scope.selectedListener.fields.push(newField);
$timeout(function () {
$scope.fieldGridApi.selection.toggleRowSelection(newField);
});
}
};
// Click handler for remove button
$scope.removeField = function () {
var selectedItems = $scope.fieldGridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.fields.indexOf(selectedItems[0]);
$scope.fieldGridApi.selection.toggleRowSelection(selectedItems[0]);
$scope.fields.splice(index, 1);
$scope.selectedListener.fields.splice(index, 1);
if ($scope.fields.length == 0) {
$scope.selectedField = undefined;
}
$timeout(function () {
if ($scope.fields.length > 0) {
$scope.fieldGridApi.selection.toggleRowSelection($scope.fields[0]);
}
});
}
};
// Click handler for up button
$scope.moveFieldUp = function () {
var selectedItems = $scope.fieldGridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.fields.indexOf(selectedItems[0]);
if (index != 0) { // If it's the first, no moving up of course
var temp = $scope.fields[index];
$scope.fields.splice(index, 1);
$scope.selectedListener.fields.splice(index, 1);
$timeout(function () {
$scope.fields.splice(index + -1, 0, temp);
$scope.selectedListener.fields.splice(index + -1, 0, temp);
$timeout(function () {
$scope.fieldGridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for down button
$scope.moveFieldDown = function () {
var selectedItems = $scope.fieldGridApi.selection.getSelectedRows();
if (selectedItems && selectedItems.length > 0) {
var index = $scope.fields.indexOf(selectedItems[0]);
if (index != $scope.fields.length - 1) { // If it's the last element, no moving down of course
var temp = $scope.fields[index];
$scope.fields.splice(index, 1);
$scope.selectedListeners.fields.splice(index, 1);
$timeout(function () {
$scope.fields.splice(index + 1, 0, temp);
$scope.selectedListener.fields.splice(index + 1, 0, temp);
$timeout(function () {
$scope.fieldGridApi.selection.toggleRowSelection(temp);
});
});
}
}
};
// Click handler for save button
$scope.save = function () {
if ($scope.taskListeners.length > 0) {
$scope.property.value = {};
$scope.property.value.taskListeners = $scope.taskListeners;
} else {
$scope.property.value = null;
}
$scope.updatePropertyInModel($scope.property);
$scope.close();
};
$scope.cancel = function () {
$scope.close();
};
// Close button handler
$scope.close = function () {
$scope.property.mode = 'read';
$scope.$hide();
};
}]);

View File

@ -0,0 +1,27 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Execution listeners
*/
angular.module('flowableModeler').controller('FlowableTransitionEventCtrl', [ '$scope', function($scope) {
if ($scope.property.value == undefined && $scope.property.value == null) {
$scope.property.value = 'complete';
}
$scope.transitionEventChanged = function() {
$scope.updatePropertyInModel($scope.property);
};
}]);

View File

@ -0,0 +1,23 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
angular.module('flowableModeler').controller('FlowableTriggerModeCtrl', [ '$scope', function($scope) {
if ($scope.property.value === undefined || $scope.property.value == null) {
$scope.property.value = 'default';
}
$scope.triggerModeChanged = function() {
$scope.updatePropertyInModel($scope.property);
};
}]);

View File

@ -0,0 +1,157 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
var FLOWABLE = FLOWABLE || {};
FLOWABLE.PROPERTY_CONFIG =
{
"string": {
"readModeTemplateUrl": "editor-app/configuration/properties/default-value-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/string-property-write-mode-template.html"
},
"boolean": {
"templateUrl": "editor-app/configuration/properties/boolean-property-template.html"
},
"text" : {
"readModeTemplateUrl": "editor-app/configuration/properties/default-value-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/text-property-write-template.html"
},
"flowable-calledelementtype" : {
"readModeTemplateUrl": "editor-app/configuration/properties/default-value-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/calledelementtype-property-write-template.html"
},
"flowable-multiinstance" : {
"readModeTemplateUrl": "editor-app/configuration/properties/default-value-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/multiinstance-property-write-template.html"
},
"flowable-processhistorylevel" : {
"readModeTemplateUrl": "editor-app/configuration/properties/default-value-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/process-historylevel-property-write-template.html"
},
"flowable-ordering" : {
"readModeTemplateUrl": "editor-app/configuration/properties/default-value-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/ordering-property-write-template.html"
},
"oryx-dataproperties-complex": {
"readModeTemplateUrl": "editor-app/configuration/properties/data-properties-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/data-properties-write-template.html"
},
"oryx-formproperties-complex": {
"readModeTemplateUrl": "editor-app/configuration/properties/form-properties-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/form-properties-write-template.html"
},
"oryx-executionlisteners-multiplecomplex": {
"readModeTemplateUrl": "editor-app/configuration/properties/execution-listeners-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/execution-listeners-write-template.html"
},
"oryx-tasklisteners-multiplecomplex": {
"readModeTemplateUrl": "editor-app/configuration/properties/task-listeners-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/task-listeners-write-template.html"
},
"oryx-eventlisteners-multiplecomplex": {
"readModeTemplateUrl": "editor-app/configuration/properties/event-listeners-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/event-listeners-write-template.html"
},
"oryx-usertaskassignment-complex": {
"readModeTemplateUrl": "editor-app/configuration/properties/assignment-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/assignment-write-template.html"
},
"oryx-servicetaskfields-complex": {
"readModeTemplateUrl": "editor-app/configuration/properties/fields-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/fields-write-template.html"
},
"oryx-callactivityinparameters-complex": {
"readModeTemplateUrl": "editor-app/configuration/properties/in-parameters-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/in-parameters-write-template.html"
},
"oryx-callactivityoutparameters-complex": {
"readModeTemplateUrl": "editor-app/configuration/properties/out-parameters-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/out-parameters-write-template.html"
},
"oryx-subprocessreference-subprocess-link": {
"readModeTemplateUrl": "editor-app/configuration/properties/subprocess-reference-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/subprocess-reference-write-template.html"
},
"oryx-formreference-complex": {
"readModeTemplateUrl": "editor-app/configuration/properties/form-reference-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/form-reference-write-template.html"
},
"oryx-sequencefloworder-complex" : {
"readModeTemplateUrl": "editor-app/configuration/properties/sequenceflow-order-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/sequenceflow-order-write-template.html"
},
"oryx-conditionsequenceflow-complex" : {
"readModeTemplateUrl": "editor-app/configuration/properties/condition-expression-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/condition-expression-write-template.html"
},
"oryx-signaldefinitions-multiplecomplex" : {
"readModeTemplateUrl": "editor-app/configuration/properties/signal-definitions-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/signal-definitions-write-template.html"
},
"oryx-signalref-string" : {
"readModeTemplateUrl": "editor-app/configuration/properties/default-value-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/signal-property-write-template.html"
},
"oryx-messagedefinitions-multiplecomplex" : {
"readModeTemplateUrl": "editor-app/configuration/properties/message-definitions-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/message-definitions-write-template.html"
},
"oryx-messageref-string" : {
"readModeTemplateUrl": "editor-app/configuration/properties/default-value-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/message-property-write-template.html"
},
"oryx-duedatedefinition-complex": {
"readModeTemplateUrl": "editor-app/configuration/properties/duedate-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/duedate-write-template.html"
},
"oryx-decisiontaskdecisiontablereference-complex": {
"readModeTemplateUrl": "editor-app/configuration/properties/decisiontable-reference-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/decisiontable-reference-write-template.html"
},
"oryx-casetaskcasereference-complex": {
"readModeTemplateUrl": "editor-app/configuration/properties/case-reference-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/case-reference-write-template.html"
},
"oryx-processtaskprocessreference-complex": {
"readModeTemplateUrl": "editor-app/configuration/properties/process-reference-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/process-reference-write-template.html"
},
"oryx-processtaskinparameters-complex": {
"readModeTemplateUrl": "editor-app/configuration/properties/in-parameters-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/in-parameters-write-template.html"
},
"oryx-processtaskoutparameters-complex": {
"readModeTemplateUrl": "editor-app/configuration/properties/out-parameters-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/out-parameters-write-template.html"
},
"oryx-planitemlifecyclelisteners-multiplecomplex": {
"readModeTemplateUrl": "editor-app/configuration/properties/plan-item-lifecycle-listeners-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/plan-item-lifecycle-listeners-write-template.html"
},
"flowable-transitionevent" : {
"readModeTemplateUrl": "editor-app/configuration/properties/default-value-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/transition-event-write-template.html"
},
"flowable-planitem-dropdown" : {
"readModeTemplateUrl": "editor-app/configuration/properties/planitem-dropdown-read-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/planitem-dropdown-write-template.html"
},
"flowable-http-request-method" : {
"readModeTemplateUrl": "editor-app/configuration/properties/http-request-method-display-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/http-request-method-property-write-template.html"
},
"flowable-triggermode" : {
"readModeTemplateUrl": "editor-app/configuration/properties/trigger-mode-read-template.html",
"writeModeTemplateUrl": "editor-app/configuration/properties/trigger-mode-write-template.html"
},
};

View File

@ -0,0 +1,15 @@
<span ng-if="property.value.assignment.type != 'idm' && property.value.assignment.assignee">{{'PROPERTY.ASSIGNMENT.ASSIGNEE_DISPLAY' | translate:property.value.assignment }} </span>
<span ng-if="property.value.assignment.type != 'idm' && property.value.assignment.candidateUsers.length > 0">{{'PROPERTY.ASSIGNMENT.CANDIDATE_USERS_DISPLAY' | translate:property.value.assignment.candidateUsers}} </span>
<span ng-if="property.value.assignment.type != 'idm' && property.value.assignment.candidateGroups.length > 0">{{'PROPERTY.ASSIGNMENT.CANDIDATE_GROUPS_DISPLAY' | translate:property.value.assignment.candidateGroups}} </span>
<span ng-if="property.value.assignment.type == 'idm' && property.value.assignment.idm.assignee && property.value.assignment.idm.assignee.id">{{'PROPERTY.ASSIGNMENT.USER_IDM_DISPLAY' | translate:property.value.assignment.idm.assignee }} </span>
<span ng-if="property.value.assignment.type == 'idm' && property.value.assignment.idm.assignee && !property.value.assignment.idm.assignee.id">{{'PROPERTY.ASSIGNMENT.USER_IDM_EMAIL_DISPLAY' | translate:property.value.assignment.idm.assignee }} </span>
<span ng-if="property.value.assignment.type == 'idm' && property.value.assignment.idm.assigneeField && property.value.assignment.idm.assigneeField.id">{{'PROPERTY.ASSIGNMENT.USER_IDM_FIELD_DISPLAY' | translate:property.value.assignment.idm.assigneeField }} </span>
<span ng-if="property.value.assignment.type == 'idm' && property.value.assignment.idm.candidateUsers && property.value.assignment.idm.candidateUsers.length > 0 && (!property.value.assignment.idm.candidateUserFields || property.value.assignment.idm.candidateUserFields.length === 0)">{{'PROPERTY.ASSIGNMENT.CANDIDATE_USERS_DISPLAY' | translate:property.value.assignment.idm.candidateUsers}} </span>
<span ng-if="property.value.assignment.type == 'idm' && property.value.assignment.idm.candidateGroups && property.value.assignment.idm.candidateGroups.length > 0 && (!property.value.assignment.idm.candidateGroupFields || property.value.assignment.idm.candidateGroupFields.length === 0)">{{'PROPERTY.ASSIGNMENT.CANDIDATE_GROUPS_DISPLAY' | translate:property.value.assignment.idm.candidateGroups}} </span>
<span ng-if="property.value.assignment.type == 'idm' && property.value.assignment.idm.candidateUserFields && property.value.assignment.idm.candidateUserFields.length > 0 && (!property.value.assignment.idm.candidateUsers || property.value.assignment.idm.candidateUsers.length === 0)">{{'PROPERTY.ASSIGNMENT.CANDIDATE_USERS_DISPLAY' | translate:property.value.assignment.idm.candidateUserFields}} </span>
<span ng-if="property.value.assignment.type == 'idm' && property.value.assignment.idm.candidateGroupFields && property.value.assignment.idm.candidateGroupFields.length > 0 && (!property.value.assignment.idm.candidateGroups || property.value.assignment.idm.candidateGroups.length === 0)">{{'PROPERTY.ASSIGNMENT.CANDIDATE_GROUPS_DISPLAY' | translate:property.value.assignment.idm.candidateGroupFields}} </span>
<span ng-if="property.value.assignment.type == 'idm' && property.value.assignment.idm.candidateUserFields && property.value.assignment.idm.candidateUserFields.length > 0 && property.value.assignment.idm.candidateUsers && property.value.assignment.idm.candidateUsers.length > 0">{{'PROPERTY.ASSIGNMENT.CANDIDATE_USERS_DISPLAY' | translate:property.value.assignment.idm.candidateUserFields.concat(property.value.assignment.idm.candidateUsers)}} </span>
<span ng-if="property.value.assignment.type == 'idm' && property.value.assignment.idm.candidateGroupFields && property.value.assignment.idm.candidateGroupFields.length > 0 && property.value.assignment.idm.candidateGroups && property.value.assignment.idm.candidateGroups.length > 0">{{'PROPERTY.ASSIGNMENT.CANDIDATE_GROUPS_DISPLAY' | translate:property.value.assignment.idm.candidateGroupFields.concat(property.value.assignment.idm.candidateGroups)}} </span>
<span ng-if="property.value.assignment.type != 'idm' && !property.value.assignment.assignee && (!property.value.assignment.candidateUsers || property.value.assignment.candidateUsers.length == 0) && (!property.value.assignment.candidateGroups || property.value.assignment.candidateGroups.length == 0)" translate>PROPERTY.ASSIGNMENT.EMPTY</span>
<span ng-if="property.value.assignment.type == 'idm' && !property.value.assignment.idm.assignee && !property.value.assignment.idm.assigneeField && (!property.value.assignment.idm.candidateUsers || property.value.assignment.idm.candidateUsers.length == 0) && (!property.value.assignment.idm.candidateUserFields || property.value.assignment.idm.candidateUserFields.length == 0) && (!property.value.assignment.idm.candidateGroups || property.value.assignment.idm.candidateGroups.length == 0) && (!property.value.assignment.idm.candidateGroupFields || property.value.assignment.idm.candidateGroupFields.length == 0)" translate>PROPERTY.ASSIGNMENT.IDM_EMPTY</span>

View File

@ -0,0 +1,268 @@
<div class="modal" ng-controller="FlowableAssignmentPopupCtrl">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" ng-click="close()">&times;</button>
<h2 translate>PROPERTY.ASSIGNMENT.TITLE</h2>
</div>
<div class="modal-body">
<div class="detail-group clearfix">
<div class="form-group clearfix">
<div class="col-xs-12">
<label class="col-xs-4">{{'PROPERTY.ASSIGNMENT.TYPE' | translate}}</label>
<div class="col-xs-8">
<div class="btn-group btn-group-justified">
<div class="btn-group">
<button type="button" class="btn btn-default" ng-click="popup.assignmentObject.type = 'idm'"
ng-model="popup.assignmentObject.type" ng-class="{'active' : popup.assignmentObject.type == 'idm'}">
{{'PROPERTY.ASSIGNMENT.TYPE.IDENTITYSTORE' | translate}}
</button>
</div>
<div class="btn-group">
<button type="button" class="btn btn-default" ng-click="popup.assignmentObject.type = 'static'"
ng-model="popup.assignmentObject.type" ng-class="{'active' : popup.assignmentObject.type != 'idm'}">
{{'PROPERTY.ASSIGNMENT.TYPE.STATIC' | translate}}
</button>
</div>
</div>
</div>
</div>
</div>
<div class="form-group clearfix" ng-show="popup.assignmentObject.type != 'idm'">
<div class="col-xs-12">
<label>{{'PROPERTY.ASSIGNMENT.ASSIGNEE' | translate}}</label>
</div>
<div class="col-xs-12">
<input type="text" id="assigneeField" class="form-control" ng-model="popup.assignmentObject.static.assignee"
placeholder="{{'PROPERTY.ASSIGNMENT.ASSIGNEE_PLACEHOLDER' | translate}}"/>
</div>
</div>
<div class="form-group clearfix" ng-show="popup.assignmentObject.type != 'idm'">
<div class="col-xs-12">
<label>{{'PROPERTY.ASSIGNMENT.CANDIDATE_USERS' | translate}}</label>
</div>
<div class="col-xs-12" ng-repeat="candidateUser in popup.assignmentObject.static.candidateUsers">
<input id="userField" class="form-control" type="text" ng-model="candidateUser.value"/>
<i ng-if="popup.assignmentObject.static.candidateUsers.length >1" class="glyphicon glyphicon-minus clickable-property"
ng-click="removeCandidateUserValue($index)"></i>
<i ng-if="$index == (popup.assignmentObject.static.candidateUsers.length - 1)" class="glyphicon glyphicon-plus clickable-property"
ng-click="addCandidateUserValue($index)"></i>
</div>
</div>
<div class="form-group clearfix" ng-show="popup.assignmentObject.type != 'idm'">
<div class="col-xs-12">
<label>{{'PROPERTY.ASSIGNMENT.CANDIDATE_GROUPS' | translate}}</label>
</div>
<div class="col-xs-12" ng-repeat="candidateGroup in popup.assignmentObject.static.candidateGroups">
<input id="groupField" class="form-control" type="text" ng-model="candidateGroup.value"/>
<i ng-if="popup.assignmentObject.static.candidateGroups.length >1" class="glyphicon glyphicon-minus clickable-property"
ng-click="removeCandidateGroupValue($index)"></i>
<i ng-if="$index == (popup.assignmentObject.static.candidateGroups.length - 1)" class="glyphicon glyphicon-plus clickable-property"
ng-click="addCandidateGroupValue($index)"></i>
</div>
</div>
<div class="form-group clearfix" ng-show="popup.assignmentObject.type == 'idm'">
<div class="col-xs-12">
<div class="col-xs-4">
<label>{{'PROPERTY.ASSIGNMENT.IDM.TYPE' | translate}}</label>
</div>
<div class="col-xs-8">
<div class="btn-group span">
<button class="selection" ng-options="option as (option.title | translate) for option in assignmentOptions"
bs-select ng-model="assignmentOption" activiti-fix-dropdown-bug>
</button>
</div>
</div>
</div>
</div>
<div class="form-group clearfix" ng-show="popup.assignmentObject.type == 'idm' && assignmentOption.id == 'users'">
<div class="col-xs-12">
<div class="col-xs-4">
<label>{{'PROPERTY.ASSIGNMENT.CANDIDATE_USERS' | translate}}</label>
</div>
<div class="col-xs-8 clearfix">
<ul class="simple-list"
ng-show="popup.assignmentObject.idm.candidateUsers.length || popup.assignmentObject.idm.candidateUserFields.length">
<li ng-repeat="user in popup.assignmentObject.idm.candidateUsers">
<i class="icon icon-user"></i>
<span user-name="user"></span>
<div class="actions">
<a ng-click="removeCandidateUser(user)"><i class="icon icon-remove"></i></a>
</div>
</li>
<li ng-repeat="userField in popup.assignmentObject.idm.candidateUserFields">
<i class="icon icon-user"></i>
<span>{{userField.name}}</span>
<span class="field-type"> - {{userFieldField.id}}</span>
<div class="actions">
<a ng-click="removeCandidateUserField(userField)"><i class="icon icon-remove"></i></a>
</div>
</li>
</ul>
<div class="no-results"
ng-if="(!popup.assignmentObject.idm.candidateUsers || !popup.assignmentObject.idm.candidateUsers.length) && (!popup.assignmentObject.idm.candidateUserFields || !popup.assignmentObject.idm.candidateUserFields.length)">
{{'PROPERTY.ASSIGNMENT.IDM.NO_CANDIDATE_USERS' | translate}}
</div>
</div>
</div>
</div>
<div class="form-group clearfix" ng-show="popup.assignmentObject.type == 'idm' && assignmentOption.id == 'groups'">
<div class="col-xs-12">
<div class="col-xs-4">
<label>{{'PROPERTY.ASSIGNMENT.CANDIDATE_GROUPS' | translate}}</label>
</div>
<div class="col-xs-8 clearfix">
<ul class="simple-list"
ng-show="popup.assignmentObject.idm.candidateGroups.length || popup.assignmentObject.idm.candidateGroupFields.length">
<li ng-repeat="group in popup.assignmentObject.idm.candidateGroups">
{{group.name}}
<div class="actions">
<a ng-click="removeCandidateGroup(group)"><i class="icon icon-remove"></i></a>
</div>
</li>
<li ng-repeat="groupField in popup.assignmentObject.idm.candidateGroupFields">
{{groupField.name}}
<div class="actions">
<a ng-click="removeCandidateGroupField(groupField)"><i class="icon icon-remove"></i></a>
</div>
</li>
</ul>
<div class="no-results"
ng-if="(!popup.assignmentObject.idm.candidateGroups || !popup.assignmentObject.idm.candidateGroups.length) && (!popup.assignmentObject.idm.candidateGroupFields || !popup.assignmentObject.idm.candidateGroupFields.length)">
{{'PROPERTY.ASSIGNMENT.IDM.NO_CANDIDATE_GROUPS' | translate}}
</div>
</div>
</div>
</div>
<div class="form-group clearfix" ng-show="popup.assignmentObject.type == 'idm' && assignmentOption.id == 'user'">
<div class="col-xs-12">
<div class="col-xs-4">
<label>{{'PROPERTY.ASSIGNMENT.ASSIGNEE' | translate}}</label>
</div>
<div class="col-xs-8">
<label ng-if="!popup.assignmentObject.idm.assignee && !popup.assignmentObject.idm.assigneeField">{{'PROPERTY.ASSIGNMENT.NONE' | translate}}</label>
<ul class="simple-list" ng-if="popup.assignmentObject.idm.assignee || popup.assignmentObject.idm.assigneeField">
<li>
<i class="icon icon-user"></i>
<span ng-if="popup.assignmentObject.idm.assignee" user-name="popup.assignmentObject.idm.assignee"></span>
<span ng-if="popup.assignmentObject.idm.assigneeField">{{popup.assignmentObject.idm.assigneeField.name}}</span>
<span ng-if="popup.assignmentObject.idm.assigneeField"
class="field-type"> - {{popup.assignmentObject.idm.assigneeField.id}}</span>
<div class="actions" ng-if="popup.assignmentObject.idm.assignee || popup.assignmentObject.idm.assigneeField">
<a ng-click="removeAssignee()"><i class="icon icon-remove"></i></a>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="form-group clearfix"
ng-if="popup.assignmentObject.type == 'idm' && (!popup.assignmentObject.assignmentSourceType || popup.assignmentObject.assignmentSourceType == 'search') && (assignmentOption.id == 'user' || assignmentOption.id == 'users')">
<div class="col-xs-12">
<div class="col-xs-4">
<label>{{'PROPERTY.ASSIGNMENT.SEARCH' | translate}}</label>
</div>
<div class="col-xs-8">
<input class="form-control" type="text" id="people-select-input" placeholder="{{'PROPERTY.ASSIGNMENT.PLACEHOLDER-SEARCHUSER' | translate}}" auto-focus custom-keys
up-pressed="previousUser()" down-pressed="nextUser()" enter-pressed="confirmUser()" delayed-model="popup.filter" delay="200"/>
</div>
</div>
<div class="col-xs-12">
<div class="col-xs-4">
<label></label>
</div>
<div class="col-xs-8">
<div class="subtle" style="margin: 2px 0 2px 0">
<span translate="PROPERTY.ASSIGNMENT.MATCHING"></span>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="col-xs-4">
<label></label>
</div>
<div class="col-xs-8">
<div class="inline-people-select">
<ul class="simple-list">
<li ng-click="confirmUser(user)" ng-repeat="user in popup.userResults" ng-class="{'active': $index == popup.selectedIndex}">
<div user-picture="user" user-index="$index" user-name="user"></div>
</li>
</ul>
<div class="nothing-to-see" translate="GENERAL.MESSAGE.PEOPLE-NO-MATCHING-RESULTS" ng-show="popup.userResults.length == 0"></div>
</div>
</div>
</div>
</div>
<div class="form-group clearfix"
ng-if="popup.assignmentObject.type == 'idm' && (!popup.assignmentObject.assignmentSourceType || popup.assignmentObject.assignmentSourceType == 'search') && assignmentOption.id == 'groups'">
<div class="col-xs-12">
<div class="col-xs-4">
<label>{{'PROPERTY.ASSIGNMENT.SEARCH' | translate}}</label>
</div>
<div class="col-xs-8">
<input class="form-control" type="text" id="people-select-input" placeholder="{{'PROPERTY.ASSIGNMENT.PLACEHOLDER-SEARCHGROUP' | translate}}" auto-focus custom-keys
up-pressed="previousGroup()" down-pressed="nextGroup()" enter-pressed="confirmGroup()" delayed-model="popup.groupFilter"
delay="200"/>
</div>
</div>
<div class="col-xs-12">
<div class="col-xs-4">
<label></label>
</div>
<div class="col-xs-8">
<div class="subtle">
<span translate="PROPERTY.ASSIGNMENT.MATCHING"></span>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="col-xs-4">
<label></label>
</div>
<div class="col-xs-8">
<div class="inline-people-select">
<ul class="simple-list">
<li ng-click="confirmGroup(group);" ng-repeat="group in popup.groupResults"
ng-class="{'active': $index == popup.selectedGroupIndex}">
{{group.name}}
</li>
</ul>
<div class="nothing-to-see" translate="GENERAL.MESSAGE.GROUP-NO-MATCHING-RESULTS" ng-show="popup.groupResults.length == 0"></div>
</div>
</div>
</div>
</div>
<div class="form-group clearfix">
<div class="col-xs-12">
<div class="col-xs-12">
<label>
<input type="checkbox" ng-model="assignment.initiatorCanCompleteTask">
&nbsp;{{'PROPERTY.ASSIGNMENT.INITIATOR-CAN-COMPLETE' | translate}}
</label>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button ng-click="close()" class="btn btn-primary" translate>ACTION.CANCEL</button>
<button ng-click="save()" class="btn btn-primary" translate>ACTION.SAVE</button>
</div>
</div>
</div>

View File

@ -0,0 +1,4 @@
<!-- Just need to instantiate the controller, and it will take care of showing the modal dialog -->
<span ng-controller="FlowableAssignmentCtrl">
</span>

View File

@ -0,0 +1,4 @@
<div ng-controller="FlowableBooleanPropertyCtrl">
<input type="checkbox" ng-model="property.value" ng-change="changeValue()"/>
</div>

View File

@ -0,0 +1,7 @@
<div ng-controller="FlowableCalledElementTypeCtrl">
<select ng-model="property.value" ng-change="calledElementTypeChanged ()">
<option>key</option>
<option>id</option>
</select>
</div>

Some files were not shown because too many files have changed in this diff Show More