Browse Source

update

main
wangshaoping 8 months ago
parent
commit
941daaf6d0
  1. 198
      app.platform/src/main/java/app/platform/Application.java
  2. 226
      erm.frontend/package.json
  3. 2
      gradle.properties
  4. 2
      io.sc.engine.mv.frontend/package.json
  5. 2
      io.sc.engine.rule.frontend/package.json
  6. 8
      io.sc.engine.rule.frontend/src/i18n/messages.json
  7. 8
      io.sc.engine.rule.frontend/src/i18n/messages_tw_CN.json
  8. 8
      io.sc.engine.rule.frontend/src/i18n/messages_zh_CN.json
  9. 113
      io.sc.engine.rule.frontend/src/views/resources/AddAttachmentDialog.vue
  10. 65
      io.sc.engine.rule.frontend/src/views/resources/AttachmentDialog.vue
  11. 1
      io.sc.engine.rule.frontend/src/views/resources/ImportSampleDialog.vue
  12. 106
      io.sc.engine.rule.frontend/src/views/resources/Resources.vue
  13. 96
      io.sc.engine.rule.frontend/src/views/resources/StartDeployWorkflowDialog.vue
  14. 35
      io.sc.engine.rule.frontend/src/views/resources/designer/DecisionTreeDialog.vue
  15. 9
      io.sc.engine.rule.frontend/src/views/resources/designer/DesignerDialog.vue
  16. 35
      io.sc.engine.rule.frontend/src/views/resources/designer/ExecutionFlowDialog.vue
  17. 612
      io.sc.engine.rule.frontend/src/views/resources/designer/Parameter.vue
  18. 1618
      io.sc.engine.rule.frontend/src/views/resources/designer/Processor.vue
  19. 63
      io.sc.engine.rule.frontend/src/views/workflow/CompleteTaskDialog.vue
  20. 446
      io.sc.engine.rule.frontend/src/views/workflow/Workflow.vue
  21. 4
      io.sc.engine.rule.server/build.gradle
  22. 72
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/initializer/RuleEngineWorkFlowInitializer.java
  23. 7
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/controller/ParameterProcessorWebController.java
  24. 20
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/controller/ResourceWebController.java
  25. 14
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/entity/ReleasableResourceEntity.java
  26. 14
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/service/ResourceService.java
  27. 44
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/service/impl/ResourceServiceImpl.java
  28. 12
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/vo/ReleasableResourceVo.java
  29. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/workflow/controller/ResourceDeployApprovingController.java
  30. 21
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/workflow/service/impl/RuleEngineWorkflowServiceImpl.java
  31. 10
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/workflow/service/support/RuleEngineApprovingTaskWrapper.java
  32. 3
      io.sc.engine.rule.server/src/main/resources/META-INF/platform/plugins/liquibase.json
  33. 21
      io.sc.engine.rule.server/src/main/resources/META-INF/platform/plugins/messages.json
  34. 22
      io.sc.engine.rule.server/src/main/resources/META-INF/platform/plugins/parameters.json
  35. 1
      io.sc.engine.rule.server/src/main/resources/META-INF/services/io.sc.platform.core.initializer.ApplicationInitializer
  36. 43
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/other.properties
  37. 42
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/other_tw_CN.properties
  38. 42
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/other_zh_CN.properties
  39. 9
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/parameter.properties
  40. 9
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/parameter_zh_CN.properties
  41. 9
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/parameters.properties
  42. 9
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/parameters_tw_CN.properties
  43. 9
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/parameters_zh_CN.properties
  44. 1
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/workflow.properties
  45. 1
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/workflow_tw_CN.properties
  46. 1
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/workflow_zh_CN.properties
  47. 19
      io.sc.engine.rule.server/src/main/resources/liquibase/RE_1.0.0_20220515__Rule Engine Database Data.xml
  48. 6
      io.sc.engine.rule.server/src/main/resources/liquibase/io/sc/engine/rule/sys_dictionary.csv
  49. 130
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor-ext/css/alert.css
  50. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor-ext/images/save.png
  51. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor-ext/images/xml.png
  52. 59
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor-ext/js/alert.js
  53. 2
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor-ext/js/alert.min.js
  54. 3
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/codemirror.css
  55. 151
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/deflate/base64.js
  56. 3
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/deflate/pako.min.js
  57. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/checkmark.gif
  58. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/clear.gif
  59. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/close.png
  60. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/collapsed.gif
  61. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/dropdown.gif
  62. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/dropdown.png
  63. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/edit.gif
  64. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/expanded.gif
  65. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/grid.gif
  66. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/handle-fixed.png
  67. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/handle-main.png
  68. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/handle-rotate.png
  69. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/handle-secondary.png
  70. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/handle-terminal.png
  71. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/help.png
  72. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/locked.png
  73. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/logo.png
  74. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/nocolor.png
  75. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/refresh.png
  76. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/round-drop.png
  77. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/search.png
  78. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/tooltip.png
  79. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/transparent.gif
  80. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/triangle-down.png
  81. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/triangle-left.png
  82. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/triangle-right.png
  83. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/triangle-up.png
  84. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/unlocked.png
  85. 110
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/index.html
  86. 1413
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Actions.js
  87. 2542
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Dialogs.js
  88. 2252
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Editor.js
  89. 4234
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/EditorUi.js
  90. 5496
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Format.js
  91. 8344
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Graph.js
  92. 30
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Init.js
  93. 1315
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Menus.js
  94. 3879
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Shapes.js
  95. 3602
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Sidebar.js
  96. 954
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Toolbar.js
  97. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/jscolor/arrow.gif
  98. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/jscolor/cross.gif
  99. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/jscolor/hs.png
  100. BIN
      io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/jscolor/hv.png

198
app.platform/src/main/java/app/platform/Application.java

@ -2,18 +2,9 @@ package app.platform;
import io.sc.platform.core.ApplicationLauncher;
import io.sc.platform.core.PlatformSpringBootServletInitializer;
import io.sc.platform.core.util.DateUtil;
import io.sc.platform.core.util.FileUtil;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.WebApplicationInitializer;
import java.io.File;
import java.io.FileInputStream;
import java.text.ParseException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 应用程序入口
*/
@ -22,193 +13,4 @@ public class Application extends PlatformSpringBootServletInitializer implements
public static void main(String[] args) throws Exception {
ApplicationLauncher.run(Application.class,args);
}
public static void main2(String[] args) throws Exception {
// ApplicationLauncher.run(Application.class,args);
// if(1==1){
// return;
// }
File dir =new File("/Users/wangshaoping/wspsc/work/yusys/工程项目/宁波银行/rwa/数据资料/安硕/ddl001/table/MODIFYUSER/TABLE");
String[] files =dir.list();
Arrays.sort(files);
StringBuilder result =new StringBuilder();
for(String fileName : files){
if(!fileName.endsWith(".sql")){
continue;
}
StringBuilder sb =new StringBuilder();
String file ="/Users/wangshaoping/wspsc/work/yusys/工程项目/宁波银行/rwa/数据资料/安硕/ddl001/table/MODIFYUSER/TABLE/" + fileName;
String outputFile ="/Users/wangshaoping/wspsc/work/yusys/工程项目/宁波银行/rwa/数据资料/安硕/ddl001/table/MODIFYUSER/output/" + fileName;
List<String> list =FileUtil.readStringAsList(new FileInputStream(file),"UTF-8");
for(String s : list){
String line =s;
line =replace_CONSTRAINT(line);
line =replace_COMPRESS(line);
line =replaceGt4000(line);
line =replace_PARTITION(line);
line =replace_PRIMARY(line);
line =replace_DROP(line);
if(line.trim().equals("")){
if(sb.length()>2) {
sb.setLength(sb.length() - 2);
sb.append(" ");
}
}
sb.append(line).append("\n");
}
sb.setLength(sb.length()-2);
sb.append(";");
//FileUtil.writeString(outputFile,sb.toString(),"UTF-8");
result.append(sb.toString()).append("\n\n");
}
FileUtil.writeString("/Users/wangshaoping/wspsc/work/yusys/工程项目/宁波银行/rwa/数据资料/安硕/ddl001/table/MODIFYUSER/output/result.sql",result.toString(),"UTF-8");
}
public static void main3(String[] args) throws Exception {
File dir =new File("/Users/wangshaoping/wspsc/work/yusys/工程项目/宁波银行/rwa/数据资料/安硕/1716611768596_export_file/MODIFYUSER/TABLE");
String[] files =dir.list();
Arrays.sort(files);
StringBuilder result =new StringBuilder();
for(String fileName : files){
if(!fileName.endsWith(".sql") || "CS_SCRIPT_CONFIG.0.0.sql".equalsIgnoreCase(fileName)
|| "CS_SCRIPT_CONFIG.0.0.sql".equalsIgnoreCase(fileName)){
continue;
}
StringBuilder sb =new StringBuilder();
sb.append("TRUNCATE TABLE ").append(fileName.substring(0,fileName.length()-8)).append(";").append("\n");
String file ="/Users/wangshaoping/wspsc/work/yusys/工程项目/宁波银行/rwa/数据资料/安硕/1716611768596_export_file/MODIFYUSER/TABLE/" + fileName;
String outputFile ="/Users/wangshaoping/wspsc/work/yusys/工程项目/宁波银行/rwa/数据资料/安硕/1716611768596_export_file/MODIFYUSER/output/" + fileName;
List<String> list =FileUtil.readStringAsList(new FileInputStream(file),"UTF-8");
for(String s : list){
String line =s;
line =replace_DATE(line);
line =replace_DATE2(line);
line =replace_COMMIT(line);
sb.append(line).append("\n");
}
result.append(sb.toString()).append("\n\n");
}
FileUtil.writeString("/Users/wangshaoping/wspsc/work/yusys/工程项目/宁波银行/rwa/数据资料/安硕/1716611768596_export_file/MODIFYUSER/output/result.sql",result.toString(),"UTF-8");
}
private static String replace_CONSTRAINT(String str){
Pattern PATTERN =Pattern.compile("(CONSTRAINT\\s(\"(.+?)\") NOT\\sNULL\\sENABLE)");
Matcher matcher =PATTERN.matcher(str);
Map<String,String> founds =new HashMap<String,String>();
while (matcher.find()) {
founds.put(matcher.group(1),matcher.group(2));
}
String result =str;
if(founds!=null && founds.size()>0) {
for(String placeholder : founds.keySet()) {
result =result.replace(placeholder," NOT NULL");
}
}
return result;
}
private static String replace_COMPRESS(String str){
Pattern PATTERN =Pattern.compile("(COMPRESS\\s(.+))");
Matcher matcher =PATTERN.matcher(str);
Map<String,String> founds =new HashMap<String,String>();
while (matcher.find()) {
founds.put(matcher.group(1),"");
}
String result =str;
if(founds!=null && founds.size()>0) {
for(String placeholder : founds.keySet()) {
result =result.replace(placeholder,founds.get(placeholder));
}
}
return result;
}
private static String replace_PRIMARY(String str){
if(str.indexOf("PRIMARY")>-1){
return "";
}
return str;
}
private static String replaceGt4000(String str){
//System.out.println(str);
Pattern PATTERN =Pattern.compile("(VARCHAR2\\((\\d+)\\))");
Matcher matcher =PATTERN.matcher(str);
Map<String,String> founds =new HashMap<String,String>();
while (matcher.find()) {
String number =matcher.group(2);
if(Integer.parseInt(number)>4000){
number ="VARCHAR2(4000)";
}else{
number ="VARCHAR2(" + number + ")";
}
founds.put(matcher.group(1),number);
}
String result =str;
if(founds!=null && founds.size()>0) {
for(String placeholder : founds.keySet()) {
result =result.replace(placeholder,founds.get(placeholder));
}
}
return result;
}
private static String replace_PARTITION(String str){
if(str.indexOf("partition")>-1){
return "";
}
return str;
}
private static String replace_DROP(String str){
if(str.indexOf("DROP")>-1){
//return "";
}
return str;
}
private static String replace_DATE(String str) throws ParseException {
Pattern PATTERN =Pattern.compile("('(\\d{4}\\-\\d{2}\\-\\d{2} \\d{2}:\\d{2}:\\d{2})')");
Matcher matcher =PATTERN.matcher(str);
Map<String,String> founds =new HashMap<String,String>();
while (matcher.find()) {
Date d = DateUtil.parseDate(matcher.group(2));
founds.put(matcher.group(1),"TO_TIMESTAMP('" + matcher.group(2) + ":0','YYYY-MM-DD HH24:MI:SS:FF')");
}
String result =str;
if(founds!=null && founds.size()>0) {
for(String placeholder : founds.keySet()) {
result =result.replace(placeholder,"null");
}
}
return result;
}
private static String replace_DATE2(String str) throws ParseException {
Pattern PATTERN =Pattern.compile("('(\\d{4}\\-\\d{2}\\-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3})')");
Matcher matcher =PATTERN.matcher(str);
Map<String,String> founds =new HashMap<String,String>();
while (matcher.find()) {
Date d = DateUtil.parseDate(matcher.group(2));
founds.put(matcher.group(1),"TO_TIMESTAMP('" + matcher.group(2) + ":0','YYYY-MM-DD HH24:MI:SS:FF')");
}
String result =str;
if(founds!=null && founds.size()>0) {
for(String placeholder : founds.keySet()) {
result =result.replace(placeholder,"null");
}
}
return result;
}
private static String replace_COMMIT(String str){
if(str.indexOf("commit")>-1){
return "";
}
return str;
}
}

226
erm.frontend/package.json

@ -1,116 +1,114 @@
{
"name": "erm.frontend",
"version": "8.1.44",
"description": "",
"private": false,
"keywords": [
],
"author": "",
"license": "ISC",
"scripts": {
"dev": "nodemon",
"serve": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack serve --config webpack.env.serve.cjs",
"build": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack --config webpack.env.build.cjs",
"prod": "node ./util-components-generator.cjs && cross-env NODE_ENV=production webpack --config webpack.env.prod.cjs",
"sync": "platform sync",
"clean": "rm -rf ./node_modules && rm -rf pnpm-lock.yaml"
},
"engines": {
"node": ">=18",
"pnpm": ">=7"
},
"publishConfig": {
"registry": "http://nexus.sc.io:8000/repository/npm-releases/",
"access": "public"
},
"devDependencies": {
"@babel/core": "7.24.4",
"@babel/preset-env": "7.24.4",
"@babel/preset-typescript": "7.24.1",
"@babel/plugin-transform-class-properties": "7.24.1",
"@babel/plugin-transform-object-rest-spread": "7.24.1",
"@quasar/app-webpack": "3.12.5",
"@quasar/cli": "2.4.0",
"@types/mockjs": "1.0.10",
"@types/node": "20.12.7",
"@typescript-eslint/eslint-plugin": "7.7.1",
"@typescript-eslint/parser": "7.7.1",
"@vue/compiler-sfc": "3.4.24",
"@webpack-cli/serve": "2.0.5",
"autoprefixer": "10.4.19",
"babel-loader": "9.1.3",
"clean-webpack-plugin": "4.0.0",
"copy-webpack-plugin": "12.0.2",
"cross-env": "7.0.3",
"css-loader": "7.1.1",
"eslint": "8.56.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-prettier": "5.1.3",
"eslint-plugin-vue": "9.25.0",
"eslint-webpack-plugin": "4.1.0",
"html-webpack-plugin": "5.6.0",
"json5": "2.2.3",
"mini-css-extract-plugin": "2.9.0",
"nodemon": "3.1.0",
"postcss": "8.4.38",
"postcss-import": "16.1.0",
"postcss-loader": "8.1.1",
"postcss-preset-env": "9.5.9",
"prettier": "3.2.5",
"sass": "1.75.0",
"sass-loader": "14.2.1",
"typescript": "5.4.5",
"vue-loader": "17.4.2",
"webpack": "5.91.0",
"webpack-bundle-analyzer": "4.10.2",
"webpack-cli": "5.1.4",
"webpack-dev-server": "5.0.4",
"webpack-merge": "5.10.0",
"@vue/babel-plugin-jsx": "1.2.2"
},
"dependencies": {
"@codemirror/autocomplete": "6.16.0",
"@codemirror/commands": "6.5.0",
"@codemirror/lang-html": "6.4.9",
"@codemirror/lang-java": "6.0.1",
"@codemirror/lang-javascript": "6.2.2",
"@codemirror/lang-json": "6.0.1",
"@codemirror/lang-sql": "6.6.3",
"@codemirror/lang-xml": "6.1.0",
"@codemirror/language": "6.10.1",
"@codemirror/search": "6.5.6",
"@codemirror/state": "6.4.1",
"@codemirror/view": "6.26.3",
"@maxgraph/core": "0.10.0",
"@quasar/extras": "1.16.11",
"@vueuse/core": "10.9.0",
"axios": "1.6.8",
"codemirror": "6.0.1",
"dayjs": "1.11.10",
"echarts": "5.5.0",
"exceljs": "4.4.0",
"file-saver": "2.0.5",
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.231",
"quasar": "2.15.3",
"tailwindcss": "3.4.3",
"vue": "3.4.24",
"vue-dompurify-html": "5.0.1",
"vue-i18n": "9.13.1",
"vue-router": "4.3.2",
"@univerjs/core": "0.1.13",
"@univerjs/design": "0.1.13",
"@univerjs/docs": "0.1.13",
"@univerjs/docs-ui": "0.1.13",
"@univerjs/engine-formula": "0.1.13",
"@univerjs/engine-render": "0.1.13",
"@univerjs/facade": "0.1.13",
"@univerjs/sheets": "0.1.13",
"@univerjs/sheets-formula": "0.1.13",
"@univerjs/sheets-ui": "0.1.13",
"@univerjs/ui": "0.1.13"
}
"name": "erm.frontend",
"version": "8.1.44",
"description": "",
"private": false,
"keywords": [],
"author": "",
"license": "ISC",
"scripts": {
"dev": "nodemon",
"serve": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack serve --config webpack.env.serve.cjs",
"build": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack --config webpack.env.build.cjs",
"prod": "node ./util-components-generator.cjs && cross-env NODE_ENV=production webpack --config webpack.env.prod.cjs",
"sync": "platform sync",
"clean": "rm -rf ./node_modules && rm -rf pnpm-lock.yaml"
},
"engines": {
"node": ">=18",
"pnpm": ">=7"
},
"publishConfig": {
"registry": "http://nexus.sc.io:8000/repository/npm-releases/",
"access": "public"
},
"devDependencies": {
"@babel/core": "7.24.4",
"@babel/preset-env": "7.24.4",
"@babel/preset-typescript": "7.24.1",
"@babel/plugin-transform-class-properties": "7.24.1",
"@babel/plugin-transform-object-rest-spread": "7.24.1",
"@quasar/app-webpack": "3.12.5",
"@quasar/cli": "2.4.0",
"@types/mockjs": "1.0.10",
"@types/node": "20.12.7",
"@typescript-eslint/eslint-plugin": "7.7.1",
"@typescript-eslint/parser": "7.7.1",
"@vue/compiler-sfc": "3.4.24",
"@webpack-cli/serve": "2.0.5",
"autoprefixer": "10.4.19",
"babel-loader": "9.1.3",
"clean-webpack-plugin": "4.0.0",
"copy-webpack-plugin": "12.0.2",
"cross-env": "7.0.3",
"css-loader": "7.1.1",
"eslint": "8.56.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-prettier": "5.1.3",
"eslint-plugin-vue": "9.25.0",
"eslint-webpack-plugin": "4.1.0",
"html-webpack-plugin": "5.6.0",
"json5": "2.2.3",
"mini-css-extract-plugin": "2.9.0",
"nodemon": "3.1.0",
"postcss": "8.4.38",
"postcss-import": "16.1.0",
"postcss-loader": "8.1.1",
"postcss-preset-env": "9.5.9",
"prettier": "3.2.5",
"sass": "1.75.0",
"sass-loader": "14.2.1",
"typescript": "5.4.5",
"vue-loader": "17.4.2",
"webpack": "5.91.0",
"webpack-bundle-analyzer": "4.10.2",
"webpack-cli": "5.1.4",
"webpack-dev-server": "5.0.4",
"webpack-merge": "5.10.0",
"@vue/babel-plugin-jsx": "1.2.2"
},
"dependencies": {
"@codemirror/autocomplete": "6.16.0",
"@codemirror/commands": "6.5.0",
"@codemirror/lang-html": "6.4.9",
"@codemirror/lang-java": "6.0.1",
"@codemirror/lang-javascript": "6.2.2",
"@codemirror/lang-json": "6.0.1",
"@codemirror/lang-sql": "6.6.3",
"@codemirror/lang-xml": "6.1.0",
"@codemirror/language": "6.10.1",
"@codemirror/search": "6.5.6",
"@codemirror/state": "6.4.1",
"@codemirror/view": "6.26.3",
"@maxgraph/core": "0.10.0",
"@quasar/extras": "1.16.11",
"@vueuse/core": "10.9.0",
"axios": "1.6.8",
"codemirror": "6.0.1",
"dayjs": "1.11.10",
"echarts": "5.5.0",
"exceljs": "4.4.0",
"file-saver": "2.0.5",
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.245",
"quasar": "2.15.3",
"tailwindcss": "3.4.3",
"vue": "3.4.24",
"vue-dompurify-html": "5.0.1",
"vue-i18n": "9.13.1",
"vue-router": "4.3.2",
"@univerjs/core": "0.1.13",
"@univerjs/design": "0.1.13",
"@univerjs/docs": "0.1.13",
"@univerjs/docs-ui": "0.1.13",
"@univerjs/engine-formula": "0.1.13",
"@univerjs/engine-render": "0.1.13",
"@univerjs/facade": "0.1.13",
"@univerjs/sheets": "0.1.13",
"@univerjs/sheets-formula": "0.1.13",
"@univerjs/sheets-ui": "0.1.13",
"@univerjs/ui": "0.1.13"
}
}

2
gradle.properties

@ -38,7 +38,7 @@ application_version=1.0.0
platform_group=io.sc
platform_version=8.1.44
platform_plugin_version=8.1.44
platform_core_frontend_version=8.1.231
platform_core_frontend_version=8.1.245
###########################################################
# dependencies version

2
io.sc.engine.mv.frontend/package.json

@ -92,7 +92,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.231",
"platform-core": "8.1.245",
"quasar": "2.15.3",
"tailwindcss": "3.4.3",
"vue": "3.4.24",

2
io.sc.engine.rule.frontend/package.json

@ -92,7 +92,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.244",
"platform-core": "8.1.245",
"quasar": "2.15.3",
"tailwindcss": "3.4.3",
"vue": "3.4.24",

8
io.sc.engine.rule.frontend/src/i18n/messages.json

@ -20,6 +20,7 @@
"re.resources.grid.toolbar.deploy.online":"Online",
"re.resources.grid.toolbar.deploy.online.tip":"Are you sure to on line the resource?",
"re.resources.grid.toolbar.deploy.offline":"Offline",
"re.resources.grid.toolbar.deploy.offline.tip":"Are you sure to off line the resource?",
"re.resources.grid.toolbar.importExample": "Import Example",
"re.resources.grid.entity.effectiveDate": "Effective Date",
@ -98,6 +99,9 @@
"re.resources.designer.processor.grid.entity.rule": "Rule",
"re.resources.designer.processor.grid.entity.singleRule": "Single Rule",
"re.resources.designer.processor.dialog.decisionTree.title": "Decision Tree Designer",
"re.resources.designer.processor.dialog.executionFlow.title": "Execution Flow Designer",
"re.resources.designer.testCase.grid.title": "Test Case List",
"re.resources.designer.testCase.grid.entity.testResult": "Result",
"re.resources.designer.testCase.grid.entity.lastTestDate": "Test Date",
@ -191,6 +195,10 @@
"re.migration.remove.action":"Remove",
"re.migration.remove.action.tip":"Are you sure to remove the all data?",
"re.workflow.dialog.title":"Workflow Approving",
"re.workflow.dialog.tip":"Tip: workflow approving needed, the resource will be active after approved!",
"re.workflow.dialog.entity.treatment":"Treatment",
"re.workflow.task.grid.title":"Task List",
"re.workflow.task.grid.toolbar.viewResource":"View Resource",
"re.workflow.task.grid.toolbar.viewAttachment":"View Attachment",

8
io.sc.engine.rule.frontend/src/i18n/messages_tw_CN.json

@ -20,6 +20,7 @@
"re.resources.grid.toolbar.deploy.online":"上線",
"re.resources.grid.toolbar.deploy.online.tip":"您確定要上線資源嗎?",
"re.resources.grid.toolbar.deploy.offline":"下線",
"re.resources.grid.toolbar.deploy.offline.tip":"您確定要下線資源嗎?",
"re.resources.grid.toolbar.importExample": "導入示例",
"re.resources.grid.entity.effectiveDate": "生效日期",
@ -98,6 +99,9 @@
"re.resources.designer.processor.grid.entity.rule": "規則",
"re.resources.designer.processor.grid.entity.singleRule": "單規則",
"re.resources.designer.processor.dialog.decisionTree.title": "決策樹設計器",
"re.resources.designer.processor.dialog.executionFlow.title": "執行流設計器",
"re.resources.designer.testCase.grid.title": "測試用例列表",
"re.resources.designer.testCase.grid.entity.testResult": "測試結果",
"re.resources.designer.testCase.grid.entity.lastTestDate": "測試日期",
@ -191,6 +195,10 @@
"re.migration.remove.action":"刪除數據",
"re.migration.remove.action.tip":"您確定要刪除所有數據嗎?",
"re.workflow.dialog.title":"審批流程",
"re.workflow.dialog.tip":"提示: 該資源發佈需要流程審批, 待審批通過後方能生效!",
"re.workflow.dialog.entity.treatment":"說明",
"re.workflow.task.grid.title":"任務列表",
"re.workflow.task.grid.toolbar.viewResource":"查看資源",
"re.workflow.task.grid.toolbar.viewAttachment":"查看附件",

8
io.sc.engine.rule.frontend/src/i18n/messages_zh_CN.json

@ -20,6 +20,7 @@
"re.resources.grid.toolbar.deploy.online":"上线",
"re.resources.grid.toolbar.deploy.online.tip":"您确定要上线资源吗?",
"re.resources.grid.toolbar.deploy.offline":"下线",
"re.resources.grid.toolbar.deploy.offline.tip":"您确定要下线资源吗?",
"re.resources.grid.toolbar.importExample": "导入示例",
"re.resources.grid.entity.effectiveDate": "生效日期",
@ -98,6 +99,9 @@
"re.resources.designer.processor.grid.entity.rule": "规则",
"re.resources.designer.processor.grid.entity.singleRule": "单规则",
"re.resources.designer.processor.dialog.decisionTree.title": "决策树设计器",
"re.resources.designer.processor.dialog.executionFlow.title": "执行流设计器",
"re.resources.designer.testCase.grid.title": "测试用例列表",
"re.resources.designer.testCase.grid.entity.testResult": "测试结果",
"re.resources.designer.testCase.grid.entity.lastTestDate": "测试日期",
@ -190,6 +194,10 @@
"re.migration.remove.subTitle":"请注意: 此操作将删除引擎中配置的所有数据, 且不可逆!",
"re.migration.remove.action":"删除数据",
"re.migration.remove.action.tip":"您确定要删除所有数据吗?",
"re.workflow.dialog.title":"审批流程",
"re.workflow.dialog.tip":"提示: 该资源发布需要流程审批, 待审批通过后方能生效!",
"re.workflow.dialog.entity.treatment":"说明",
"re.workflow.task.grid.title":"任务列表",
"re.workflow.task.grid.toolbar.viewResource":"查看资源",

113
io.sc.engine.rule.frontend/src/views/resources/AddAttachmentDialog.vue

@ -0,0 +1,113 @@
<template>
<w-dialog
ref="dialogRef"
:title="$t('addNew')"
width="600px"
:can-maximize="false"
:buttons="[
{
label: $t('submit'),
click: upload,
},
]"
>
<q-form ref="formRef" :autofocus="false" :greedy="true" class="p-2">
<q-file
ref="fileRef"
v-model="modelValue.file"
:label="$t('file.single.tip')"
dense
outlined
clearable
counter
:rules="[(val) => !!val || '必填项未填写']"
@update:model-value="
(value) => {
modelValue.name = value.name;
}
"
>
<template #prepend>
<q-icon name="cloud_upload" />
</template>
</q-file>
<q-input v-model="modelValue.name" :label="$t('name')" outlined dense required :rules="[(val) => !!val || '必填项未填写']"></q-input>
<q-input v-model="modelValue.description" :label="$t('description')" outlined dense></q-input>
</q-form>
</w-dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue';
import { axios, Environment } from 'platform-core';
const props = defineProps({
opener: { type: Object, default: undefined },
foreignKey: { type: String, default: '' },
foreignValue: { type: String, default: '' },
});
const emit = defineEmits<{
(e: 'afterAdd', evt: Event): void;
}>();
const dialogRef = ref();
const formRef = ref();
const fileRef = ref();
const modelValue = reactive({
name: undefined,
description: undefined,
file: undefined,
});
const upload = async () => {
const validated = await validateForm();
if (validated) {
axios
.post(
Environment.apiContextPath('/api/system/attachment/upload/' + props.foreignValue),
{
name: modelValue.name,
description: modelValue.description,
file: fileRef.value.nativeEl.files[0],
},
{
loading: true,
headers: {
'Content-Type': 'multipart/form-data',
},
},
)
.then(() => {
close();
emit('afterAdd');
});
}
};
const validateForm = async () => {
let validate = false;
await formRef.value.validate().then((success) => {
if (success) {
validate = true;
}
});
return validate;
};
const open = () => {
dialogRef.value.show();
modelValue.name = undefined;
modelValue.description = undefined;
modelValue.file = undefined;
};
const close = () => {
dialogRef.value.hide();
};
defineExpose({
open,
close,
});
</script>

65
io.sc.engine.rule.frontend/src/views/resources/AttachmentDialog.vue

@ -3,18 +3,33 @@
<div class="px-2">
<w-grid
ref="gridRef"
:height="300"
:height="400"
:title="$t('re.resources.dialog.attachment.grid.title')"
selection="multiple"
:config-button="false"
:full-screen-button="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'refresh',
'add',
'separator',
{
extend: 'add',
click: () => {
addAttachmentDialogRef.open();
},
},
'remove',
'separator',
{
name: 'download',
label: $t('download'),
icon: 'bi-download',
enableIf: (arg) => {
return arg.selected;
},
click: (arg) => {
download(arg.selected.id);
},
},
]"
:query-form-fields="[]"
@ -23,34 +38,32 @@
:data-url="dataUrl"
:columns="[
{ width: 120, name: 'id', label: $t('id'), hidden: true },
{ width: 200, name: 'name', label: $t('name') },
{ width: '100%', name: 'description', label: $t('description') },
{
width: '100%',
name: 'name',
label: $t('name'),
format: (value, row) => {
return value;
},
},
{ width: 200, name: 'description', label: $t('description') },
{ width: 100, name: 'lastModifier', label: $t('lastModifier') },
{ width: 120, name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() },
]"
:editor="{
dialog: {
width: '600px',
height: '300px',
},
form: {
colsNum: 1,
fields: [
{ name: 'bussinessKey', label: $t('bussinessKey'), type: 'text', defaultValue: foreignValue, hidden: true },
{ name: 'name', label: $t('re.resources.grid.entity.name'), type: 'text', required: true },
{ name: 'description', label: $t('re.resources.grid.entity.description'), type: 'text' },
{ name: 'file', label: $t('re.resources.dialog.attachment.grid.entity.file'), type: 'file' },
],
},
}"
></w-grid>
<AddAttachmentDialog
ref="addAttachmentDialogRef"
:foreign-key="foreignKey"
:foreign-value="foreignValue"
@after-add="gridRef.refresh()"
></AddAttachmentDialog>
</div>
</w-dialog>
</template>
<script setup lang="ts">
import { ref, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { Environment, Tools, EnumTools, Options, Formater } from 'platform-core';
import { Environment, Formater, Downloader } from 'platform-core';
import AddAttachmentDialog from './AddAttachmentDialog.vue';
const props = defineProps({
opener: { type: Object, default: undefined },
@ -62,12 +75,14 @@ const props = defineProps({
const dialogRef = ref();
const gridRef = ref();
const foreignKeyRef = ref();
const addAttachmentDialogRef = ref();
const open = (foreignKey: string) => {
foreignKeyRef.value = foreignKey;
dialogRef.value.show();
const download = (id) => {
Downloader.get(Environment.apiContextPath('/api/system/attachment/download/') + id);
};
const open = () => {
dialogRef.value.show();
nextTick(() => {
gridRef.value.refresh();
});

1
io.sc.engine.rule.frontend/src/views/resources/ImportSampleDialog.vue

@ -7,6 +7,7 @@
:title="$t('re.resources.importSample.grid.title')"
selection="multiple"
:full-screen-button="false"
:config-button="false"
:tree="true"
dense-body
:toolbar-configure="{ noIcon: false }"

106
io.sc.engine.rule.frontend/src/views/resources/Resources.vue

@ -165,13 +165,22 @@
label: $t('re.resources.grid.toolbar.deploy.online'),
icon: 'bi-arrow-up-right-circle',
enableIf: (arg) => {
return arg.selected && arg.selected.type !== 'FOLDER';
return arg.selected && arg.selected.type !== 'FOLDER' && arg.selected.status !== 'ON_LINE';
},
click: (arg) => {
DialogManager.confirm($t('re.resources.grid.toolbar.deploy.online.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/resource/deploy/' + arg.selected.id)).then(() => {
treeGridRef.refresh();
});
currentSelectedResourceIdRef = arg.selected.id;
axios.get(Environment.apiContextPath('/api/parameter/list/parameter.re.server.deploy.approve.workflow.enable')).then((response) => {
if (response.data === 'true') {
startDeployWorkflowDialogRef.open(arg.selected.id, arg.selected.code, arg.selected.version, 'ON_LINE');
} else {
DialogManager.confirm($t('re.resources.grid.toolbar.deploy.online.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/resource/online/' + arg.selected.id)).then(() => {
axios.get(Environment.apiContextPath('/api/re/resource/' + currentSelectedResourceIdRef)).then((response) => {
treeGridRef.replaceRow(response.data);
});
});
});
}
});
},
},
@ -180,9 +189,24 @@
label: $t('re.resources.grid.toolbar.deploy.offline'),
icon: 'bi-arrow-down-right-circle',
enableIf: (arg) => {
return arg.selected && arg.selected.type !== 'FOLDER';
return arg.selected && arg.selected.type !== 'FOLDER' && arg.selected.status === 'ON_LINE';
},
click: (arg) => {
currentSelectedResourceIdRef = arg.selected.id;
axios.get(Environment.apiContextPath('/api/parameter/list/parameter.re.server.deploy.approve.workflow.enable')).then((response) => {
if (response.data === 'true') {
startDeployWorkflowDialogRef.open(arg.selected.id, arg.selected.code, arg.selected.version);
} else {
DialogManager.confirm($t('re.resources.grid.toolbar.deploy.offline.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/resource/offline/' + arg.selected.id)).then(() => {
axios.get(Environment.apiContextPath('/api/re/resource/' + currentSelectedResourceIdRef)).then((response) => {
treeGridRef.replaceRow(response.data);
});
});
});
}
});
},
click: () => {},
},
],
[
@ -228,19 +252,61 @@
}
},
},
{ width: 100, name: 'code', label: $t('code') },
{ width: 150, name: 'code', label: $t('code') },
{ width: 60, name: 'version', label: $t('version') },
{ width: 60, name: 'status', label: $t('status'), format: Formater.enum(Enums.DeployStatus) },
{
width: 80,
name: 'status',
label: $t('status'),
align: 'center',
format: (value, row) => {
const result = {
componentType: 'q-chip',
attrs: {
color: '',
textColor: 'white',
size: '10px',
label: $t('io.sc.engine.rule.core.enums.DeployStatus.HISTORY'),
},
};
if (value === 'HISTORY') {
result.attrs.label = $t('io.sc.engine.rule.core.enums.DeployStatus.HISTORY');
result.attrs.color = '';
return result;
} else if (value === 'ON_LINE') {
result.attrs.label = $t('io.sc.engine.rule.core.enums.DeployStatus.ON_LINE');
result.attrs.color = 'green';
return result;
} else if (value === 'OFF_LINE') {
result.attrs.label = $t('io.sc.engine.rule.core.enums.DeployStatus.OFF_LINE');
result.attrs.color = 'red';
return result;
} else if (value === 'SKETCH') {
result.attrs.label = $t('io.sc.engine.rule.core.enums.DeployStatus.SKETCH');
result.attrs.color = 'blue';
return result;
} else if (value === 'APPROVING') {
result.attrs.label = $t('io.sc.engine.rule.core.enums.DeployStatus.APPROVING');
result.attrs.color = 'orange';
return result;
}
return '';
},
},
{ width: 120, name: 'taskName', label: $t('re.resources.grid.entity.taskName') },
{ width: 80, name: 'taskAssignee', label: $t('re.resources.grid.entity.taskAssignee') },
{ width: 100, name: 'taskAssignee', label: $t('re.resources.grid.entity.taskAssignee') },
{ width: 80, name: 'lastModifier', label: $t('lastModifier'), sortable: false },
{ width: 90, name: 'lastModifyDate', label: $t('lastModifyDate'), sortable: false, format: Formater.dateOnly() },
{
width: 200,
name: 'attachmentHtml',
width: 60,
name: 'attachmentCount',
label: $t('attachment'),
format: (value) => {
return value;
if (value > 0) {
return value;
} else {
return '';
}
},
},
]"
@ -322,6 +388,16 @@
<DesignerDialog ref="designerDialogRef"></DesignerDialog>
<ImportDialog ref="importDialogRef" @after-imported="afterImported"></ImportDialog>
<ImportSampleDialog ref="importSampleDialogRef" @after-imported="afterImported"></ImportSampleDialog>
<StartDeployWorkflowDialog
ref="startDeployWorkflowDialogRef"
@after-started="
() => {
axios.get(Environment.apiContextPath('/api/re/resource/' + currentSelectedResourceIdRef)).then((response) => {
treeGridRef.replaceRow(response.data);
});
}
"
></StartDeployWorkflowDialog>
</div>
</template>
<script setup lang="ts">
@ -331,6 +407,7 @@ import AttachmentDialog from './AttachmentDialog.vue';
import DesignerDialog from './designer/DesignerDialog.vue';
import ImportSampleDialog from './ImportSampleDialog.vue';
import ImportDialog from './ImportDialog.vue';
import StartDeployWorkflowDialog from './StartDeployWorkflowDialog.vue';
const treeGridRef = ref();
const attachmentDialogRef = ref();
@ -338,6 +415,9 @@ const foreignValueRef = ref('');
const designerDialogRef = ref();
const importDialogRef = ref();
const importSampleDialogRef = ref();
const startDeployWorkflowDialogRef = ref();
const currentSelectedResourceIdRef = ref();
const afterImported = () => {
treeGridRef.value.refresh();
};

96
io.sc.engine.rule.frontend/src/views/resources/StartDeployWorkflowDialog.vue

@ -0,0 +1,96 @@
<template>
<w-dialog
ref="dialogRef"
:title="$t('re.workflow.dialog.title')"
width="600px"
:can-maximize="false"
:buttons="[
{
label: $t('submit'),
noCaps: true,
click: () => {
submit();
},
},
]"
>
<div class="p-3 text-red-500">{{ $t('re.workflow.dialog.tip') }}</div>
<w-form
ref="formRef"
:cols-num="1"
:fields="[{ name: 'treatment', label: $t('re.workflow.dialog.entity.treatment'), type: 'textarea', rows: 5, required: true }]"
class="p-2"
></w-form>
<w-select-assignee-dialog ref="selectAssigneeDialogRef" @assignee-selected="assigneeSelected"></w-select-assignee-dialog>
</w-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { axios, Environment, NotifyManager } from 'platform-core';
const props = defineProps({
opener: { type: Object, default: undefined },
foreignKey: { type: String, default: '' },
foreignValue: { type: String, default: '' },
});
const emit = defineEmits<{
(e: 'afterStarted', evt: Event): void;
}>();
const dialogRef = ref();
const formRef = ref();
const selectAssigneeDialogRef = ref();
const resourceIdRef = ref();
const resourceCodeRef = ref('');
const resourceVersionRef = ref('');
const resourceTargetStatusRef = ref('');
const submit = (assignee) => {
const data = formRef.value.getData();
const variables = { targetStatus: resourceTargetStatusRef.value };
const transientVariables = { task_treatment: data.treatment };
if (assignee) {
transientVariables.assignee = assignee;
}
axios
.post(Environment.apiContextPath('/api/re/resource/workflow/startProcessInstance/' + resourceIdRef.value), {
bussinessKey: resourceCodeRef.value + ':' + resourceVersionRef.value,
variables: variables,
transientVariables: transientVariables,
autoCompleteFirstTask: true,
})
.then((response) => {
if (response.data.code === 0) {
//
NotifyManager.success();
close();
emit('afterStarted');
} else if (response.data.code === 1) {
//
selectAssigneeDialogRef.value.open(response.data);
}
});
};
const assigneeSelected = (assignee) => {
submit(assignee);
};
const open = (id, code, version, status) => {
resourceIdRef.value = id;
resourceCodeRef.value = code;
resourceVersionRef.value = version;
resourceTargetStatusRef.value = status;
dialogRef.value.show();
};
const close = () => {
dialogRef.value.hide();
};
defineExpose({
open,
close,
});
</script>

35
io.sc.engine.rule.frontend/src/views/resources/designer/DecisionTreeDialog.vue

@ -0,0 +1,35 @@
<template>
<w-dialog
ref="dialogRef"
:title="$t('re.resources.designer.processor.dialog.decisionTree.title')"
:can-maximize="false"
:maximized="true"
body-padding="2px 2px 2px 2px"
>
<iframe
:src="Environment.getWebContextPath() + 'api/re/model/parameter/processor/editDecisionTreeById/' + processorIdRef"
style="width: 100%; height: 100%"
></iframe>
</w-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { Environment } from 'platform-core';
const dialogRef = ref();
const processorIdRef = ref();
const open = (processorId) => {
processorIdRef.value = processorId;
dialogRef.value.show();
};
const close = () => {
dialogRef.value.hide();
};
defineExpose({
open,
close,
});
</script>

9
io.sc.engine.rule.frontend/src/views/resources/designer/DesignerDialog.vue

@ -62,7 +62,6 @@
no-caps
inline-label
align="left"
class="px-2"
@update:model-value="
(value) => {
if (value === 'testcase') {
@ -77,7 +76,7 @@
<q-tab v-if="statusReactive.isShowTestCase" name="testcase" icon="bi-receipt" :label="$t('re.resources.designer.testcase.tab.title')" />
</q-tabs>
<q-tab-panels v-model="statusReactive.parameterAndTestcaseTab" animated style="height: calc(100% - 48px)">
<q-tab-panel v-if="statusReactive.isShowParameter" name="parameter" class="px-0 pb-0" style="height: 100%">
<q-tab-panel v-if="statusReactive.isShowParameter" name="parameter" style="padding: 0px; height: 100%">
<Parameter
ref="parameterGridRef"
:model="currentSelectedModelRef"
@ -120,7 +119,7 @@
"
></Parameter>
</q-tab-panel>
<q-tab-panel v-if="statusReactive.isShowTestCase" name="testcase" class="px-0 pb-0" style="height: 100%">
<q-tab-panel v-if="statusReactive.isShowTestCase" name="testcase" class="px-0 pb-0" style="padding: 0px; height: 100%">
<TestCase
ref="testCaseGridRef"
:model="currentSelectedModelRef"
@ -186,6 +185,7 @@ const dialogRef = ref();
const horizontalSplitterRef = ref(400);
const verticalSplitterRef = ref(400);
const readOnlyRef = ref();
const currentSelectedResourceRef = ref();
const currentSelectedModelRef = ref({});
const currentSelectedParameterRef = ref({});
@ -207,7 +207,8 @@ const statusReactive = reactive({
isShowTestCaseParameter: false,
});
const open = (resource) => {
const open = (resource, readOnly) => {
readOnlyRef.value = Tools.isUndefinedOrNull(readOnly) ? false : readOnly;
currentSelectedResourceRef.value = resource;
dialogRef.value.show();
};

35
io.sc.engine.rule.frontend/src/views/resources/designer/ExecutionFlowDialog.vue

@ -0,0 +1,35 @@
<template>
<w-dialog
ref="dialogRef"
:title="$t('re.resources.designer.processor.dialog.executionFlow.title')"
:can-maximize="false"
:maximized="true"
body-padding="2px 2px 2px 2px"
>
<iframe
:src="Environment.getWebContextPath() + 'api/re/model/parameter/processor/editExecutionFlowById/' + processorIdRef"
style="width: 100%; height: 100%"
></iframe>
</w-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { Environment } from 'platform-core';
const dialogRef = ref();
const processorIdRef = ref();
const open = (processorId) => {
processorIdRef.value = processorId;
dialogRef.value.show();
};
const close = () => {
dialogRef.value.hide();
};
defineExpose({
open,
close,
});
</script>

612
io.sc.engine.rule.frontend/src/views/resources/designer/Parameter.vue

@ -1,343 +1,345 @@
<template>
<w-grid
ref="gridRef"
:title="$t('re.resources.designer.parameter.grid.title')"
dense-body
class="px-1"
hide-bottom
:config-button="false"
selection="multiple"
:checkbox-selection="false"
:tree="false"
:fetch-data-url="Environment.apiContextPath('/api/re/model/parameter/findByModelId?modelId=' + model.id)"
:data-url="Environment.apiContextPath('/api/re/model/parameter')"
:pageable="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'refresh',
'separator',
{
name: 'move',
label: $t('re.resources.designer.parameter.grid.toolbar.move'),
icon: 'bi-share-fill',
},
[
<div style="height: 100%">
<w-grid
ref="gridRef"
:title="$t('re.resources.designer.parameter.grid.title')"
dense-body
class="px-1"
hide-bottom
:config-button="false"
selection="multiple"
:checkbox-selection="false"
:tree="false"
:fetch-data-url="Environment.apiContextPath('/api/re/model/parameter/findByModelId?modelId=' + model.id)"
:data-url="Environment.apiContextPath('/api/re/model/parameter')"
:pageable="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'refresh',
'separator',
{
extend: 'add',
click: undefined,
name: 'move',
label: $t('re.resources.designer.parameter.grid.toolbar.move'),
icon: 'bi-share-fill',
},
{
extend: 'add',
name: 'constant',
label: $t('re.resources.designer.parameter.grid.toolbar.add.constant'),
icon: 'bi-tag',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'CONSTANT');
[
{
extend: 'add',
click: undefined,
},
},
'separator',
{
extend: 'add',
name: 'in',
label: $t('re.resources.designer.parameter.grid.toolbar.add.in'),
icon: 'bi-terminal',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'IN');
{
extend: 'add',
name: 'constant',
label: $t('re.resources.designer.parameter.grid.toolbar.add.constant'),
icon: 'bi-tag',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'CONSTANT');
},
},
},
{
extend: 'add',
name: 'inOption',
label: $t('re.resources.designer.parameter.grid.toolbar.add.inOption'),
icon: 'bi-list-check',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'IN_OPTION');
'separator',
{
extend: 'add',
name: 'in',
label: $t('re.resources.designer.parameter.grid.toolbar.add.in'),
icon: 'bi-terminal',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'IN');
},
},
},
{
extend: 'add',
name: 'indicator',
label: $t('re.resources.designer.parameter.grid.toolbar.add.indicator'),
icon: 'bi-link',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'INDICATOR');
{
extend: 'add',
name: 'inOption',
label: $t('re.resources.designer.parameter.grid.toolbar.add.inOption'),
icon: 'bi-list-check',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'IN_OPTION');
},
},
},
'separator',
{
extend: 'add',
name: 'intermediate',
label: $t('re.resources.designer.parameter.grid.toolbar.add.intermediate'),
icon: 'bi-superscript',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'INTERMEDIATE');
{
extend: 'add',
name: 'indicator',
label: $t('re.resources.designer.parameter.grid.toolbar.add.indicator'),
icon: 'bi-link',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'INDICATOR');
},
},
},
{
extend: 'add',
name: 'out',
label: $t('re.resources.designer.parameter.grid.toolbar.add.out'),
icon: 'bi-shuffle',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'OUT');
'separator',
{
extend: 'add',
name: 'intermediate',
label: $t('re.resources.designer.parameter.grid.toolbar.add.intermediate'),
icon: 'bi-superscript',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'INTERMEDIATE');
},
},
},
{
extend: 'add',
name: 'out',
label: $t('re.resources.designer.parameter.grid.toolbar.add.out'),
icon: 'bi-shuffle',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'OUT');
},
},
'separator',
{
extend: 'add',
name: 'ruleResult',
label: $t('re.resources.designer.parameter.grid.toolbar.add.ruleResult'),
icon: 'bi-sliders',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'RULE_RESULT');
},
},
{
extend: 'add',
name: 'singleRuleResult',
label: $t('re.resources.designer.parameter.grid.toolbar.add.singleRuleResult'),
icon: 'bi-lightning',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'SINGLE_RULE_RESULT');
},
},
'separator',
{
name: 'importPmml',
label: $t('re.resources.designer.parameter.grid.toolbar.add.importPmml'),
icon: 'bi-file-earmark-text',
},
],
'separator',
{
extend: 'add',
name: 'ruleResult',
label: $t('re.resources.designer.parameter.grid.toolbar.add.ruleResult'),
icon: 'bi-sliders',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'RULE_RESULT');
extend: 'clone',
enableIf: (arg) => {
return arg.selected && arg.selected.parent;
},
},
{
extend: 'add',
name: 'singleRuleResult',
label: $t('re.resources.designer.parameter.grid.toolbar.add.singleRuleResult'),
icon: 'bi-lightning',
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'SINGLE_RULE_RESULT');
extend: 'clone',
name: 'deepClone',
label: $t('deepClone'),
icon: 'bi-copy',
enableIf: (arg) => {
return arg.selected && arg.selected.parent;
},
click: (arg) => {},
},
'edit',
'remove',
'separator',
'view',
'separator',
'export',
]"
:columns="[
{ width: 60, name: 'order', label: $t('order'), sortable: false, align: 'right' },
{ width: '100%', name: 'name', label: $t('name'), sortable: false },
{ width: 150, name: 'code', label: $t('code'), sortable: false },
{ width: 100, name: 'type', label: $t('type'), sortable: false, format: Formater.enum(Enums.ParameterType) },
{
name: 'importPmml',
label: $t('re.resources.designer.parameter.grid.toolbar.add.importPmml'),
icon: 'bi-file-earmark-text',
},
],
'separator',
{
extend: 'clone',
enableIf: (arg) => {
return arg.selected && arg.selected.parent;
width: 150,
name: 'valueType',
label: $t('re.resources.designer.parameter.grid.entity.valueType'),
sortable: false,
format: (value) => {
return ValueTypeMap[value];
},
},
},
{
extend: 'clone',
name: 'deepClone',
label: $t('deepClone'),
icon: 'bi-copy',
enableIf: (arg) => {
return arg.selected && arg.selected.parent;
{
width: 80,
name: 'valueTypeIsList',
label: $t('re.resources.designer.parameter.grid.entity.valueTypeIsList'),
sortable: false,
format: Formater.yesNo(),
},
click: (arg) => {},
},
'edit',
'remove',
'separator',
'view',
'separator',
'export',
]"
:columns="[
{ width: 60, name: 'order', label: $t('order'), sortable: false, align: 'right' },
{ width: '100%', name: 'name', label: $t('name'), sortable: false },
{ width: 150, name: 'code', label: $t('code'), sortable: false },
{ width: 100, name: 'type', label: $t('type'), sortable: false, format: Formater.enum(Enums.ParameterType) },
{
width: 150,
name: 'valueType',
label: $t('re.resources.designer.parameter.grid.entity.valueType'),
sortable: false,
format: (value) => {
return ValueTypeMap[value];
{ width: 200, name: 'defaultValue', label: $t('defaultValue'), sortable: false },
]"
:editor="{
dialog: {
width: '600px',
height: '550px',
},
},
{
width: 80,
name: 'valueTypeIsList',
label: $t('re.resources.designer.parameter.grid.entity.valueTypeIsList'),
sortable: false,
format: Formater.yesNo(),
},
{ width: 200, name: 'defaultValue', label: $t('defaultValue'), sortable: false },
]"
:editor="{
dialog: {
width: '600px',
height: '550px',
},
form: {
colsNum: 1,
fields: [
{ name: 'model', label: $t('modelId'), type: 'text', defaultValue: model.id, hidden: true },
{ name: 'code', label: $t('code'), type: 'text' },
{ name: 'name', label: $t('name'), type: 'text', required: true },
{ name: 'description', label: $t('description'), type: 'text' },
{ name: 'type', label: $t('type'), type: 'select', options: Options.enum(Enums.ParameterType) },
{
name: 'libCode',
label: $t('re.resources.designer.parameter.grid.entity.libCode'),
type: 'select',
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
return type === 'INDICATOR';
form: {
colsNum: 1,
fields: [
{ name: 'model', label: $t('modelId'), type: 'text', defaultValue: model.id, hidden: true },
{ name: 'code', label: $t('code'), type: 'text' },
{ name: 'name', label: $t('name'), type: 'text', required: true },
{ name: 'description', label: $t('description'), type: 'text' },
{ name: 'type', label: $t('type'), type: 'select', options: Options.enum(Enums.ParameterType) },
{
name: 'libCode',
label: $t('re.resources.designer.parameter.grid.entity.libCode'),
type: 'select',
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
return type === 'INDICATOR';
},
},
},
{
name: 'libVersion',
label: $t('re.resources.designer.parameter.grid.entity.libVersion'),
type: 'select',
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
return type === 'INDICATOR';
{
name: 'libVersion',
label: $t('re.resources.designer.parameter.grid.entity.libVersion'),
type: 'select',
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
return type === 'INDICATOR';
},
},
},
{
name: 'indicatorCode',
label: $t('re.resources.designer.parameter.grid.entity.indicatorCode'),
type: 'select',
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
return type === 'INDICATOR';
{
name: 'indicatorCode',
label: $t('re.resources.designer.parameter.grid.entity.indicatorCode'),
type: 'select',
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
return type === 'INDICATOR';
},
},
},
{
name: 'valueType',
label: $t('re.resources.designer.parameter.grid.entity.valueType'),
type: 'select',
options: ValueTypeList,
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
if (type == 'INDICATOR' || type == 'IN_OPTION' || type == 'RULE_RESULT' || type == 'SINGLE_RULE_RESULT') {
return false;
}
return true;
},
},
{
name: 'valueTypeVersion',
label: $t('re.resources.designer.parameter.grid.entity.valueTypeVersion'),
type: 'select',
options: ValueTypeList,
showIf: (arg) => {
const valueType = arg.form.getFieldValue('valueType');
if (valueType) {
if (
valueType == 'java.lang.Boolean' ||
valueType == 'java.lang.Long' ||
valueType == 'java.lang.Float' ||
valueType == 'Float' ||
valueType == 'java.math.BigDecimal' ||
valueType == 'java.lang.String' ||
valueType == 'java.util.Date' ||
valueType == 'org.wsp.engine.rule.core.classes.ResourceAbstract' ||
valueType == 'org.wsp.engine.rule.core.classes.RuleResult' ||
valueType == 'org.wsp.engine.rule.core.classes.SingleRuleResult' ||
valueType.startsWith('List') ||
valueType.startsWith('Map')
) {
{
name: 'valueType',
label: $t('re.resources.designer.parameter.grid.entity.valueType'),
type: 'select',
options: ValueTypeList,
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
if (type == 'INDICATOR' || type == 'IN_OPTION' || type == 'RULE_RESULT' || type == 'SINGLE_RULE_RESULT') {
return false;
} else if (Tools.isUndefinedOrNull(ValueTypeMap[valueType])) {
return false;
} else {
return true;
}
}
return false;
},
},
{
name: 'valueScale',
label: $t('re.resources.designer.parameter.grid.entity.valueScale'),
type: 'number',
showIf: (arg) => {
const valueType = arg.form.getFieldValue('valueType');
const type = arg.form.getFieldValue('type');
if (valueType == 'java.math.BigDecimal' && type != 'INDICATOR' && type != 'RULE_RESULT' && type != 'SINGLE_RULE_RESULT') {
return true;
}
return false;
},
},
},
{
name: 'valueRoundingMode',
label: $t('re.resources.designer.parameter.grid.entity.valueRoundingMode'),
type: 'select',
options: Options.enum(Enums.RoundingMode),
showIf: (arg) => {
const valueType = arg.form.getFieldValue('valueType');
const type = arg.form.getFieldValue('type');
if (valueType == 'java.math.BigDecimal' && type != 'INDICATOR' && type != 'RULE_RESULT' && type != 'SINGLE_RULE_RESULT') {
return true;
}
return false;
{
name: 'valueTypeVersion',
label: $t('re.resources.designer.parameter.grid.entity.valueTypeVersion'),
type: 'select',
options: ValueTypeList,
showIf: (arg) => {
const valueType = arg.form.getFieldValue('valueType');
if (valueType) {
if (
valueType == 'java.lang.Boolean' ||
valueType == 'java.lang.Long' ||
valueType == 'java.lang.Float' ||
valueType == 'Float' ||
valueType == 'java.math.BigDecimal' ||
valueType == 'java.lang.String' ||
valueType == 'java.util.Date' ||
valueType == 'org.wsp.engine.rule.core.classes.ResourceAbstract' ||
valueType == 'org.wsp.engine.rule.core.classes.RuleResult' ||
valueType == 'org.wsp.engine.rule.core.classes.SingleRuleResult' ||
valueType.startsWith('List') ||
valueType.startsWith('Map')
) {
return false;
} else if (Tools.isUndefinedOrNull(ValueTypeMap[valueType])) {
return false;
} else {
return true;
}
}
return false;
},
},
},
{
name: 'valueTypeIsList',
label: $t('re.resources.designer.parameter.grid.entity.valueTypeIsList'),
type: 'checkbox',
defaultValue: false,
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
if (type == 'IN_OPTION' || type == 'INDICATOR' || type == 'RULE_RESULT' || type == 'SINGLE_RULE_RESULT') {
{
name: 'valueScale',
label: $t('re.resources.designer.parameter.grid.entity.valueScale'),
type: 'number',
showIf: (arg) => {
const valueType = arg.form.getFieldValue('valueType');
const type = arg.form.getFieldValue('type');
if (valueType == 'java.math.BigDecimal' && type != 'INDICATOR' && type != 'RULE_RESULT' && type != 'SINGLE_RULE_RESULT') {
return true;
}
return false;
}
return true;
},
},
},
{
name: 'defaultValue',
label: $t('defaultValue'),
type: 'text',
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
const valueTypeIsList = arg.form.getFieldValue('valueTypeIsList');
if (type == 'INDICATOR' || type == 'RULE_RESULT' || type == 'SINGLE_RULE_RESULT' || valueTypeIsList) {
{
name: 'valueRoundingMode',
label: $t('re.resources.designer.parameter.grid.entity.valueRoundingMode'),
type: 'select',
options: Options.enum(Enums.RoundingMode),
showIf: (arg) => {
const valueType = arg.form.getFieldValue('valueType');
const type = arg.form.getFieldValue('type');
if (valueType == 'java.math.BigDecimal' && type != 'INDICATOR' && type != 'RULE_RESULT' && type != 'SINGLE_RULE_RESULT') {
return true;
}
return false;
}
return true;
},
},
{
name: 'valueTypeIsList',
label: $t('re.resources.designer.parameter.grid.entity.valueTypeIsList'),
type: 'checkbox',
defaultValue: false,
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
if (type == 'IN_OPTION' || type == 'INDICATOR' || type == 'RULE_RESULT' || type == 'SINGLE_RULE_RESULT') {
return false;
}
return true;
},
},
{
name: 'defaultValue',
label: $t('defaultValue'),
type: 'text',
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
const valueTypeIsList = arg.form.getFieldValue('valueTypeIsList');
if (type == 'INDICATOR' || type == 'RULE_RESULT' || type == 'SINGLE_RULE_RESULT' || valueTypeIsList) {
return false;
}
return true;
},
},
},
{ name: 'order', label: $t('order'), type: 'number' },
],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'order', label: $t('order') },
{ name: 'id', label: $t('id') },
{ name: 'code', label: $t('code') },
{ name: 'name', label: $t('name') },
{ name: 'description', label: $t('description') },
{ name: 'type', label: $t('type') },
{ name: 'valueType', label: $t('re.resources.designer.parameter.grid.entity.valueType') },
{ name: 'valueTypeVersion', label: $t('re.resources.designer.parameter.grid.entity.valueTypeVersion') },
{ name: 'valueScale', label: $t('re.resources.designer.parameter.grid.entity.valueScale') },
{ name: 'valueRoundingMode', label: $t('re.resources.designer.parameter.grid.entity.valueRoundingMode') },
{ name: 'valueTypeIsList', label: $t('re.resources.designer.parameter.grid.entity.valueTypeIsList') },
{ name: 'defaultValue', label: $t('defaultValue') },
{ name: 'libCode', label: $t('re.resources.designer.parameter.grid.entity.libCode') },
{ name: 'libVersion', label: $t('re.resources.designer.parameter.grid.entity.libVersion') },
{ name: 'indicatorCode', label: $t('re.resources.designer.parameter.grid.entity.indicatorCode') },
{ name: 'order', label: $t('order'), type: 'number' },
],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'order', label: $t('order') },
{ name: 'id', label: $t('id') },
{ name: 'code', label: $t('code') },
{ name: 'name', label: $t('name') },
{ name: 'description', label: $t('description') },
{ name: 'type', label: $t('type') },
{ name: 'valueType', label: $t('re.resources.designer.parameter.grid.entity.valueType') },
{ name: 'valueTypeVersion', label: $t('re.resources.designer.parameter.grid.entity.valueTypeVersion') },
{ name: 'valueScale', label: $t('re.resources.designer.parameter.grid.entity.valueScale') },
{ name: 'valueRoundingMode', label: $t('re.resources.designer.parameter.grid.entity.valueRoundingMode') },
{ name: 'valueTypeIsList', label: $t('re.resources.designer.parameter.grid.entity.valueTypeIsList') },
{ name: 'defaultValue', label: $t('defaultValue') },
{ name: 'libCode', label: $t('re.resources.designer.parameter.grid.entity.libCode') },
{ name: 'libVersion', label: $t('re.resources.designer.parameter.grid.entity.libVersion') },
{ name: 'indicatorCode', label: $t('re.resources.designer.parameter.grid.entity.indicatorCode') },
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
@row-click="
(evt, row, index) => {
emit('rowClick', evt, row, index);
}
"
@before-request-data="
() => {
emit('beforeRequestData');
}
"
></w-grid>
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
@row-click="
(evt, row, index) => {
emit('rowClick', evt, row, index);
}
"
@before-request-data="
() => {
emit('beforeRequestData');
}
"
></w-grid>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';

1618
io.sc.engine.rule.frontend/src/views/resources/designer/Processor.vue

File diff suppressed because it is too large

63
io.sc.engine.rule.frontend/src/views/workflow/CompleteTaskDialog.vue

@ -0,0 +1,63 @@
<template>
<w-dialog ref="dialogRef" :title="$t('lcdp.bpm.completeTask.dialog.title')" width="800px" :can-maximize="false">
<template #buttons>
<w-workflow-action
ref="workflowActionRef"
:task-id="taskIdRef"
:data="formModelValue"
:action-url="Environment.apiContextPath('/api/flowable/process/operation/complete')"
@before-submit="beforeSubmit"
@after-submit="afterSubmit"
>
</w-workflow-action>
</template>
<w-form
v-model="formModelValue"
:cols-num="1"
:fields="[{ name: 'treatment', label: $t('re.workflow.dialog.entity.treatment'), type: 'textarea', rows: 5, required: true }]"
>
</w-form>
</w-dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue';
import { Environment } from 'platform-core';
/**
* 定义组件支持的自定义事件
*/
const emit = defineEmits([
'afterTaskCompleted', //
]);
const dialogRef = ref();
const taskIdRef = ref<string>('');
const workflowActionRef = ref();
const formModelValue = reactive({
treatment: undefined,
});
const open = (taskId: string) => {
taskIdRef.value = taskId;
formModelValue.treatment = undefined;
dialogRef.value.show();
};
const close = () => {
dialogRef.value.hide();
};
const beforeSubmit = async (action, callback) => {
callback(true);
};
const afterSubmit = () => {
close();
emit('afterTaskCompleted');
};
defineExpose({
open,
close,
});
</script>

446
io.sc.engine.rule.frontend/src/views/workflow/Workflow.vue

@ -1,223 +1,277 @@
<template>
<q-splitter :model-value="splitterRef" unit="px" separator-style="width: 3px;" class="w-full" style="height: 100%">
<template #before>
<div class="pr-1" style="height: 100%">
<w-grid
ref="processTaskGridRef"
:title="$t('re.workflow.task.grid.title')"
:config-button="false"
selection="multiple"
:checkbox-selection="false"
:tree="false"
:fetch-data-url="Environment.apiContextPath('/api/re/resource/workflow/task/query')"
:pageable="true"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'refresh',
'separator',
{
name: 'viewResource',
label: $t('re.workflow.task.grid.toolbar.viewResource'),
icon: 'bi-boxes',
},
{
name: 'attachment',
label: $t('re.workflow.task.grid.toolbar.viewAttachment'),
icon: 'bi-briefcase-fill',
enableIf: (arg) => {
return arg.selected && arg.selected.attachments;
},
click: (arg) => {
if (arg.selected) {
foreignValueRef = arg.selected.id;
attachmentDialogRef.open();
}
},
},
'separator',
[
<div style="height: 100%">
<q-splitter horizontal :model-value="splitterRef" unit="px" separator-style="width: 3px;" class="w-full" style="height: 100%">
<template #before>
<div class="pr-1" style="height: 100%">
<w-grid
ref="taskGridRef"
:title="$t('re.workflow.task.grid.title')"
:config-button="false"
selection="multiple"
:checkbox-selection="false"
:tree="false"
:fetch-data-url="Environment.apiContextPath('/api/re/resource/workflow/task/query')"
:pageable="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'refresh',
'separator',
{
label: $t('operation'),
icon: 'bi-cursor',
name: 'viewResource',
label: $t('re.workflow.task.grid.toolbar.viewResource'),
icon: 'bi-boxes',
click: (arg) => {
const resource = {
type: arg.selected.resourceType,
id: arg.selected.resourceId,
code: arg.selected.resourceCode,
name: arg.selected.resourceName,
version: arg.selected.resourceVersion,
status: arg.selected.resourceStatus,
};
designerDialogRef.open(resource);
},
},
{
name: 'claim',
label: $t('re.workflow.task.grid.toolbar.claim'),
icon: 'bi-clipboard-check',
enableIf: function (selecteds) {
return selecteds && selecteds.length > 0 && !selecteds[0].assignee;
name: 'attachment',
label: $t('re.workflow.task.grid.toolbar.viewAttachment'),
icon: 'bi-briefcase-fill',
enableIf: (arg) => {
return arg.selected && arg.selected.attachmentCount > 0;
},
click: (arg) => {
if (arg.selected) {
DialogManager.confirm($t('re.workflow.task.grid.toolbar.claim.tip'), () => {
axios.post(Environment.apiContextPath('/api/flowable/process/operation/claim/') + arg.selected.id).then(() => {
taskGridRef.refresh();
NotifyManager.success();
});
});
attachmentIdRef = arg.selected.resourceId;
attachmentDialogRef.open();
}
},
},
{
name: 'unclaim',
label: $t('re.workflow.task.grid.toolbar.unclaim'),
icon: 'bi-clipboard-x',
enableIf: function (arg) {
return arg.selected && arg.selected.assignee;
'separator',
[
{
label: $t('operation'),
icon: 'bi-cursor',
},
click: (arg) => {
if (arg.selected) {
DialogManager.confirm($t('re.workflow.task.grid.toolbar.unclaim.tip'), () => {
axios.post(Environment.apiContextPath('/api/flowable/process/operation/unClaim/') + arg.selected.id).then(() => {
taskGridRef.refresh();
NotifyManager.success();
{
name: 'claim',
label: $t('re.workflow.task.grid.toolbar.claim'),
icon: 'bi-clipboard-check',
enableIf: function (arg) {
return arg.selected && !arg.selected.taskAssignee;
},
click: (arg) => {
if (arg.selected) {
DialogManager.confirm($t('re.workflow.task.grid.toolbar.claim.tip'), () => {
axios.post(Environment.apiContextPath('/api/flowable/process/operation/claim/') + arg.selected.taskId).then(() => {
taskGridRef.refresh();
NotifyManager.success();
});
});
});
}
}
},
},
},
{
name: 'complete',
label: $t('re.workflow.task.grid.toolbar.complete'),
icon: 'bi-caret-right',
enableIf: function (arg) {
return arg.selected;
{
name: 'unclaim',
label: $t('re.workflow.task.grid.toolbar.unclaim'),
icon: 'bi-clipboard-x',
enableIf: function (arg) {
return arg.selected && arg.selected.taskAssignee;
},
click: (arg) => {
if (arg.selected) {
DialogManager.confirm($t('re.workflow.task.grid.toolbar.unclaim.tip'), () => {
axios.post(Environment.apiContextPath('/api/flowable/process/operation/unClaim/') + arg.selected.taskId).then(() => {
taskGridRef.refresh();
NotifyManager.success();
});
});
}
},
},
click: (arg) => {
if (arg.selected) {
completeTaskDialogRef.open(arg.selected.id);
{
name: 'complete',
label: $t('re.workflow.task.grid.toolbar.complete'),
icon: 'bi-caret-right',
enableIf: function (arg) {
return arg.selected;
},
click: (arg) => {
if (arg.selected) {
completeTaskDialogRef.open(arg.selected.taskId);
}
},
},
{
name: 'terminate',
label: $t('re.workflow.task.grid.toolbar.terminate'),
icon: 'bi-stop',
enableIf: function (arg) {
return arg.selected;
},
click: (arg) => {
if (arg.selected) {
DialogManager.confirm($t('re.workflow.task.grid.toolbar.terminate.tip'), () => {
axios.post(Environment.apiContextPath('/api/flowable/process/operation/terminateProcessInstance/') + arg.selected.id).then(() => {
taskGridRef.refresh();
NotifyManager.success();
});
});
}
},
},
],
'separator',
'view',
'separator',
'export',
]"
:columns="[
{ width: 150, name: 'resourceCode', label: $t('code'), hidden: true },
{ width: '100%', name: 'resourceName', label: $t('name') },
{ width: 100, name: 'resourceType', label: $t('type'), format: Formater.enum(Enums.ResourceType) },
{ width: 100, name: 'resourceVersion', label: $t('version') },
{
width: 100,
name: 'attachmentCount',
label: $t('attachment'),
format: (value) => {
if (value > 0) {
return value;
}
return '';
},
},
{ width: 150, name: 'taskName', label: $t('re.workflow.task.grid.entity.taskName') },
{ width: 120, name: 'taskAssignee', label: $t('re.workflow.task.grid.entity.taskAssignee') },
{ width: 150, name: 'taskCreateTime', label: $t('re.workflow.task.grid.entity.taskCreateTime') },
]"
:editor="{
dialog: {
width: '600px',
height: '250px',
},
form: {
colsNum: 1,
fields: [
{ name: 'order', label: $t('order'), type: 'text', hidden: true },
{ name: 'id', label: $t('id'), type: 'text', hidden: true },
{ name: 'name', label: $t('name'), type: 'text', required: true },
{ name: 'description', label: $t('description'), type: 'text' },
],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'order', label: $t('order') },
{ name: 'id', label: $t('id') },
{ name: 'name', label: $t('name') },
{ name: 'description', label: $t('description') },
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
@row-click="
(evt, row, index) => {
currentSelectedTaskRef = row;
historyProcessTaskGridRef?.refresh();
}
"
@before-request-data="
() => {
currentSelectedTaskRef = {};
historyProcessTaskGridRef?.refresh();
}
"
></w-grid>
</div>
</template>
<template #after>
<div class="pl-1" style="height: 100%">
<w-grid
ref="historyProcessTaskGridRef"
:title="$t('re.workflow.historyTask.grid.title')"
hide-bottom
:config-button="false"
selection="multiple"
:checkbox-selection="false"
:tree="false"
:fetch-data-url="
Environment.apiContextPath('/api/re/resource/workflow/task/queryHistory?processInstanceId=' + currentSelectedTaskRef.processInstanceId)
"
:pageable="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['refresh', 'separator', 'view', 'separator', 'export']"
:columns="[
{ width: 150, name: 'taskName', label: $t('re.workflow.task.grid.entity.taskName') },
{ width: 100, name: 'taskAssignee', label: $t('re.workflow.task.grid.entity.taskAssignee') },
{ width: 150, name: 'taskEndTime', label: $t('re.workflow.task.grid.entity.taskEndTime') },
{
name: 'terminate',
label: $t('re.workflow.task.grid.toolbar.terminate'),
icon: 'bi-stop',
enableIf: function (arg) {
return arg.selected;
},
click: (arg) => {
if (arg.selected) {
DialogManager.confirm($t('re.workflow.task.grid.toolbar.terminate.tip'), () => {
axios.post(Environment.apiContextPath('/api/flowable/process/operation/terminateProcessInstance/') + arg.selected.id).then(() => {
taskGridRef.refresh();
NotifyManager.success();
});
});
width: '100%',
name: 'taskTreatment',
label: $t('re.workflow.task.grid.entity.taskTreatment'),
format: (value) => {
if (value) {
return value.replace(/(\r\n)|(\n)/g, '<br>');
}
return '';
},
},
],
'separator',
'view',
'separator',
'export',
]"
:columns="[
{ width: 50, name: 'resourceType', label: $t('type') },
{ width: 50, name: 'resourceCode', label: $t('code') },
{ width: 50, name: 'resourceName', label: $t('name') },
{ width: 50, name: 'resourceVersion', label: $t('version') },
{ width: 50, name: 'attachments', label: $t('attachment') },
{ width: 50, name: 'taskName', label: $t('re.workflow.task.grid.entity.taskName') },
{ width: 50, name: 'taskAssignee', label: $t('re.workflow.task.grid.entity.taskAssignee') },
{ width: 50, name: 'taskCreateTime', label: $t('re.workflow.task.grid.entity.taskCreateTime') },
]"
:editor="{
dialog: {
width: '600px',
height: '250px',
},
form: {
colsNum: 1,
fields: [
{ name: 'order', label: $t('order'), type: 'text', hidden: true },
{ name: 'id', label: $t('id'), type: 'text', hidden: true },
{ name: 'name', label: $t('name'), type: 'text', required: true },
{ name: 'description', label: $t('description'), type: 'text' },
],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'order', label: $t('order') },
{ name: 'id', label: $t('id') },
{ name: 'name', label: $t('name') },
{ name: 'description', label: $t('description') },
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
@row-click="
(evt, row, index) => {
currentSelectedTaskRef = row;
historyProcessTaskGridRef?.refresh();
}
"
@before-request-data="
() => {
currentSelectedTaskRef = {};
historyProcessTaskGridRef?.refresh();
}
"
></w-grid>
</div>
</template>
<template #after>
<div class="pl-1" style="height: 100%">
<w-grid
ref="historyProcessTaskGridRef"
:title="$t('re.workflow.historyTask.grid.title')"
dense-body
hide-bottom
:config-button="false"
selection="multiple"
:checkbox-selection="false"
:tree="false"
:fetch-data-url="Environment.apiContextPath('/api/re/testCaseParameter/findByTestCase?testCaseId=' + currentSelectedTaskRef.id)"
:pageable="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['refresh', 'separator', 'view', 'separator', 'export']"
:columns="[
{ width: 100, name: 'taskName', label: $t('re.workflow.task.grid.entity.taskName') },
{ width: 100, name: 'taskAssignee', label: $t('re.workflow.task.grid.entity.taskAssignee') },
{ width: 120, name: 'taskEndTime', label: $t('re.workflow.task.grid.entity.taskEndTime') },
{ width: 300, name: 'taskTreatment', label: $t('re.workflow.task.grid.entity.taskTreatment') },
]"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
></w-grid>
</div>
</template>
</q-splitter>
]"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
></w-grid>
</div>
</template>
</q-splitter>
<DesignerDialog ref="designerDialogRef"></DesignerDialog>
<AttachmentDialog
ref="attachmentDialogRef"
:fetch-data-url="Environment.apiContextPath('/api/system/attachment/findByBussinessKey')"
:data-url="Environment.apiContextPath('/api/system/attachment')"
foreign-key="bussinessKey"
:foreign-value="attachmentIdRef"
></AttachmentDialog>
<CompleteTaskDialog ref="completeTaskDialogRef" @after-task-completed="afterTaskCompleted"></CompleteTaskDialog>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref, useAttrs } from 'vue';
import { axios, Environment, EnumTools, Formater, Options, Tools } from 'platform-core';
import PassOrNotFormater from '@/utils/PassOrNotFormater';
import { ref } from 'vue';
import { axios, Environment, EnumTools, Formater, DialogManager, NotifyManager } from 'platform-core';
import DesignerDialog from '@/views/resources/designer/DesignerDialog.vue';
import AttachmentDialog from '@/views/resources/AttachmentDialog.vue';
import CompleteTaskDialog from './CompleteTaskDialog.vue';
const splitterRef = ref(800); //
const processTaskGridRef = ref();
const splitterRef = ref(400); //
const taskGridRef = ref();
const historyProcessTaskGridRef = ref();
const designerDialogRef = ref();
const attachmentDialogRef = ref();
const attachmentIdRef = ref();
const completeTaskDialogRef = ref();
const currentSelectedTaskRef = ref({});
const afterTaskCompleted = () => {
NotifyManager.success();
taskGridRef.value.refresh();
};
const Enums = await EnumTools.fetch(['io.sc.engine.rule.core.enums.ResourceType', 'io.sc.engine.rule.core.enums.DeployStatus']);
</script>

4
io.sc.engine.rule.server/build.gradle

@ -11,6 +11,10 @@ dependencies {
project(":io.sc.engine.rule.client"),
project(":io.sc.engine.rule.client.spring"),
project(":io.sc.engine.rule.frontend"),
project(":org.webjars.codemirror-5.37.0"),
project(":org.webjars.mxgraph-3.9.12"),
project(":org.webjars.jquery-1.12.4"),
)
}

72
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/initializer/RuleEngineWorkFlowInitializer.java

@ -0,0 +1,72 @@
package io.sc.engine.rule.server.common.initializer;
import io.sc.engine.rule.server.service.RuleEngineServerConfigurationService;
import io.sc.platform.core.Environment;
import io.sc.platform.core.initializer.ApplicationInitializer;
import io.sc.platform.core.initializer.ApplicationInitializerExecuteException;
import io.sc.platform.core.util.FileUtil;
import io.sc.platform.flowable.enums.ProcessStatus;
import io.sc.platform.flowable.jpa.entity.ProcessEntity;
import io.sc.platform.flowable.service.ProcessEntityService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public class RuleEngineWorkFlowInitializer implements ApplicationInitializer{
private static final Logger log =LoggerFactory.getLogger(RuleEngineWorkFlowInitializer.class);
private Boolean isInitialized =null;
private ApplicationContext applicationContext;
private ProcessEntityService processEntityService;
@Override
public void init(ApplicationContext applicationContext) {
this.processEntityService =applicationContext.getBean(ProcessEntityService.class);
this.applicationContext =applicationContext;
}
@Override
public int getOrder() {
return 1100;
}
@Override
public synchronized boolean isInitialized() {
if(isInitialized!=null) {
return isInitialized;
}
List<ProcessEntity> entities =processEntityService.getRepository().findByKey(RuleEngineServerConfigurationService.RESOURCE_DEPLOY_WORKFLOW_KEY);
if(entities==null || entities.isEmpty()){
isInitialized =false;
}else {
isInitialized = true;
}
return isInitialized;
}
@Override
public void execute() throws ApplicationInitializerExecuteException {
try {
ProcessEntity entity = new ProcessEntity();
entity.setCategory(RuleEngineServerConfigurationService.RESOURCE_DEPLOY_WORKFLOW_KEY);
entity.setKey(RuleEngineServerConfigurationService.RESOURCE_DEPLOY_WORKFLOW_KEY);
entity.setName(applicationContext.getMessage(RuleEngineServerConfigurationService.RESOURCE_DEPLOY_WORKFLOW_CATEGORY + "." + RuleEngineServerConfigurationService.RESOURCE_DEPLOY_WORKFLOW_KEY, null, Locale.getDefault()));
entity.setStatus(ProcessStatus.RELEASE);
entity.setVersion(1);
entity.setCanClaimTask(true);
entity.setXml(getRuleEngineWorkflowXmlContent());
entity = processEntityService.add(entity);
processEntityService.deploy(entity.getId());
}catch (Exception e){
log.error("",e);
throw new ApplicationInitializerExecuteException(e);
}
}
private String getRuleEngineWorkflowXmlContent() throws IOException {
return FileUtil.readString("classpath:/workflow/io/sc/engine/rule/Sample.bpmn", Environment.DEFAULT_CHARSET_NAME);
}
}

7
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/controller/ParameterProcessorWebController.java

@ -12,6 +12,7 @@ import io.sc.engine.rule.server.model.vo.ParameterProcessorVo;
import io.sc.engine.rule.server.model.vo.ParameterValidatorVo;
import io.sc.engine.rule.server.util.CodeAndNameMapping;
import io.sc.engine.rule.server.util.VariableCodeAndNameReplacer;
import io.sc.platform.core.annotation.IgnoreResponseBodyAdvice;
import io.sc.platform.mvc.controller.support.RestCrudController;
import io.sc.platform.orm.util.EntityVoUtil;
import org.springframework.beans.factory.annotation.Autowired;
@ -50,7 +51,7 @@ public class ParameterProcessorWebController extends RestCrudController<Paramete
//决策树==========================================================================================================
@RequestMapping(value="editDecisionTreeById/{processorId}",method=RequestMethod.GET)
public ModelAndView editDecisionTreeById(@PathVariable(name="processorId")String processorId) throws Exception{
ModelAndView mv =new ModelAndView("org/wsp/engine/rule/server/view/model/decisionTree/decisionTree.html");
ModelAndView mv =new ModelAndView("io/sc/engine/rule/server/view/decisionTree.html");
mv.addObject("processorId", processorId);
mv.addObject("paremterHints",parameterService.listParemterHintsByProcessorId(processorId));
return mv;
@ -58,6 +59,7 @@ public class ParameterProcessorWebController extends RestCrudController<Paramete
@RequestMapping(value="getDecisionTreeById/{processorId}",method=RequestMethod.GET)
@ResponseBody
@IgnoreResponseBodyAdvice
public String getDecisionTreeById(@PathVariable(name="processorId",required=false)String processorId) throws Exception{
ParameterProcessorEntity entity =service.findById(processorId);
if(entity!=null && entity instanceof DecisionTreeParameterProcessorEntity) {
@ -84,7 +86,7 @@ public class ParameterProcessorWebController extends RestCrudController<Paramete
//执行流==========================================================================================================
@RequestMapping(value="editExecutionFlowById/{processorId}",method=RequestMethod.GET)
public ModelAndView editExecutionFlowById(@PathVariable(name="processorId")String processorId) throws Exception{
ModelAndView mv =new ModelAndView("org/wsp/engine/rule/server/view/model/executionFlow/executionFlow.html");
ModelAndView mv =new ModelAndView("io/sc/engine/rule/server/view/executionFlow.html");
mv.addObject("processorId", processorId);
mv.addObject("paremterHints",parameterService.listParemterHintsByProcessorId(processorId));
return mv;
@ -92,6 +94,7 @@ public class ParameterProcessorWebController extends RestCrudController<Paramete
@RequestMapping(value="getExecutionFlowById/{processorId}",method=RequestMethod.GET)
@ResponseBody
@IgnoreResponseBodyAdvice
public String getExecutionFlowById(@PathVariable(name="processorId",required=false)String processorId) throws Exception{
ParameterProcessorEntity entity =service.findById(processorId);
if(entity!=null && entity instanceof ExecutionFlowParameterProcessorEntity) {

20
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/controller/ResourceWebController.java

@ -174,15 +174,27 @@ public class ResourceWebController extends RestCrudController<ResourceVo, Resour
}
/**
* 发布资源实体
* 上线资源实体
* @param id 被发布的资源实体ID
* @return 发布后的资源实体
* @throws Exception 违例
*/
@RequestMapping(value="deploy/{id}",method=RequestMethod.POST)
@RequestMapping(value="online/{id}",method=RequestMethod.POST)
@ResponseBody
public ResourceVo deploy(@PathVariable(name="id",required=true)String id) throws Exception{
return service.deploy(id);
public ResourceVo online(@PathVariable(name="id",required=true)String id) throws Exception{
return service.online(id);
}
/**
* 下线资源实体
* @param id 被发布的资源实体ID
* @return 发布后的资源实体
* @throws Exception 违例
*/
@RequestMapping(value="offline/{id}",method=RequestMethod.POST)
@ResponseBody
public ResourceVo offline(@PathVariable(name="id",required=true)String id) throws Exception{
return service.offline(id);
}
@RequestMapping(value="getAllReleasableResourceAbstract",method=RequestMethod.GET)

14
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/entity/ReleasableResourceEntity.java

@ -31,9 +31,9 @@ public abstract class ReleasableResourceEntity extends ResourceEntity implements
@Column(name="IMPORTS_")
protected String imports;
//附件链接HTML文本
//附件个数
@Transient
protected String attachmentHtml;
protected int attachmentCount;
//审批任务节点名称
@Transient
@ -50,7 +50,7 @@ public abstract class ReleasableResourceEntity extends ResourceEntity implements
vo.setVersion(this.getVersion());
vo.setEffectiveDate(this.getEffectiveDate());
vo.setImports(this.getImports());
vo.setAttachmentHtml(this.getAttachmentHtml());
vo.setAttachmentCount(this.getAttachmentCount());
vo.setTaskName(this.getTaskName());
vo.setTaskAssignee(this.getTaskAssignee());
}
@ -88,12 +88,12 @@ public abstract class ReleasableResourceEntity extends ResourceEntity implements
this.imports = imports;
}
public String getAttachmentHtml() {
return attachmentHtml;
public int getAttachmentCount() {
return attachmentCount;
}
public void setAttachmentHtml(String attachmentHtml) {
this.attachmentHtml = attachmentHtml;
public void setAttachmentCount(int attachmentCount) {
this.attachmentCount = attachmentCount;
}
public String getTaskName() {

14
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/service/ResourceService.java

@ -78,12 +78,20 @@ public interface ResourceService extends DaoService<ResourceEntity, String, Reso
public ResourceEntity deepCloneNew(String id) throws Exception;
/**
* 资源发布
* 资源上线
* @param id 资源ID
* @return 发布后资源
* @return 上线后资源
* @throws Exception 违例
*/
public ResourceVo deploy(String id) throws Exception;
public ResourceVo online(String id) throws Exception;
/**
* 资源下线
* @param id 资源ID
* @return 下线后资源
* @throws Exception 违例
*/
public ResourceVo offline(String id) throws Exception;
/**
* 获取所有可发布的资源摘要信息

44
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/service/impl/ResourceServiceImpl.java

@ -299,7 +299,7 @@ public class ResourceServiceImpl extends DaoServiceImpl<ResourceEntity, String,
@Override
@Transactional
public ResourceVo deploy(String id) throws Exception {
public ResourceVo online(String id) throws Exception {
if(StringUtils.hasText(id)) {
ReleasableResourceEntity entity =repository.findReleasableResourceById(id);
if(entity!=null) {
@ -317,6 +317,20 @@ public class ResourceServiceImpl extends DaoServiceImpl<ResourceEntity, String,
}
return null;
}
@Override
@Transactional
public ResourceVo offline(String id) throws Exception {
if(StringUtils.hasText(id)) {
ReleasableResourceEntity entity =repository.findReleasableResourceById(id);
if(entity!=null) {
entity.setStatus(DeployStatus.OFF_LINE);
repository.save(entity);
return entity.toVo();
}
}
return null;
}
@Override
public ResourceWrapper getDefineById(String resourceId) throws Exception {
@ -716,7 +730,9 @@ public class ResourceServiceImpl extends DaoServiceImpl<ResourceEntity, String,
if(entity instanceof ReleasableResourceEntity) {
ReleasableResourceEntity releasableEntity =(ReleasableResourceEntity)entity;
List<AttachmentVo> attachments =attachmentCache.get(getAttachmentBussinessKey(releasableEntity));
generateReleaseableResourceAttachmentHtml(releasableEntity,attachments);
if(attachments!=null && !attachments.isEmpty()){
releasableEntity.setAttachmentCount(attachments.size());
}
}
break;
default:
@ -767,7 +783,10 @@ public class ResourceServiceImpl extends DaoServiceImpl<ResourceEntity, String,
if(entity instanceof ReleasableResourceEntity) {
ReleasableResourceEntity releasableEntity =(ReleasableResourceEntity)entity;
HistoricTaskInstance task =historicTaskInstanceCache.get(getAttachmentBussinessKey(releasableEntity));
generateResourceTaskInfo(releasableEntity,task);
if(task!=null){
releasableEntity.setTaskName(task.getName());
releasableEntity.setTaskAssignee(task.getAssignee());
}
}
break;
default:
@ -778,24 +797,7 @@ public class ResourceServiceImpl extends DaoServiceImpl<ResourceEntity, String,
}
private String getAttachmentBussinessKey(ReleasableResourceEntity entity) {
return entity.getId();
}
private void generateReleaseableResourceAttachmentHtml(ReleasableResourceEntity entity, List<AttachmentVo> attachments) {
if(entity!=null && attachments!=null && attachments.size()>0) {
StringBuilder sb =new StringBuilder();
for(AttachmentVo attachment : attachments) {
sb.append("<a href='").append("../../system/attachment/download/").append(attachment.getId()).append("' title='").append(attachment.getName()).append("'>").append(attachment.getName()).append("</a>").append("<br/>");
}
entity.setAttachmentHtml(sb.toString());
}
}
private void generateResourceTaskInfo(ReleasableResourceEntity entity, HistoricTaskInstance task) {
if(entity!=null && task!=null) {
entity.setTaskName(task.getName());
entity.setTaskAssignee(task.getAssignee());
}
return entity.getCode() + ":" + entity.getVersion();
}
private void updateResourceAndRoleRelationship(String roleId,String resourceId) {

12
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/vo/ReleasableResourceVo.java

@ -21,9 +21,9 @@ public abstract class ReleasableResourceVo extends ResourceVo {
//引入外部包
protected String imports;
//附件链接HTML文本
//附件个数
@Transient
protected String attachmentHtml;
protected int attachmentCount;
//审批任务节点名称
@Transient
@ -65,12 +65,12 @@ public abstract class ReleasableResourceVo extends ResourceVo {
this.imports = imports;
}
public String getAttachmentHtml() {
return attachmentHtml;
public int getAttachmentCount() {
return attachmentCount;
}
public void setAttachmentHtml(String attachmentHtml) {
this.attachmentHtml = attachmentHtml;
public void setAttachmentCount(int attachmentCount) {
this.attachmentCount = attachmentCount;
}
public String getTaskName() {

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/workflow/controller/ResourceDeployApprovingController.java

@ -15,8 +15,6 @@ import java.util.List;
/**
* 资源管理器 Controller
* @author wangshaoping
*
*/
@Controller
@RequestMapping("/api/re/resource/workflow")

21
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/workflow/service/impl/RuleEngineWorkflowServiceImpl.java

@ -130,7 +130,7 @@ public class RuleEngineWorkflowServiceImpl implements RuleEngineWorkflowService{
wrapper.setResourceName(entity.getName());
wrapper.setResourceVersion(entity.getVersion());
wrapper.setResourceStatus(entity.getStatus());
wrapper.setAttachments(generateAttachmentsHtml(entity));
wrapper.setAttachmentCount(getAttachmentCount(entity));
wrappers.add(wrapper);
}
}
@ -152,7 +152,6 @@ public class RuleEngineWorkflowServiceImpl implements RuleEngineWorkflowService{
List<RuleEngineApprovingHistoryTaskWrapper> wrappers =new ArrayList<RuleEngineApprovingHistoryTaskWrapper>();
for(HistoricTaskInstance task : historyTasks){
if(task.getEndTime()!=null) {
RuleEngineApprovingHistoryTaskWrapper wrapper =new RuleEngineApprovingHistoryTaskWrapper();
wrapper.setProcessDefinitionId(task.getProcessDefinitionId());
wrapper.setProcessInstanceId(task.getProcessInstanceId());
@ -164,7 +163,6 @@ public class RuleEngineWorkflowServiceImpl implements RuleEngineWorkflowService{
wrapper.setTaskClaimTime(task.getClaimTime());
wrapper.setTaskEndTime(task.getEndTime());
wrapper.setTaskTreatment(getTaskTreatment(task.getId(),"<br/>"));
wrappers.add(wrapper);
}
}
@ -186,20 +184,14 @@ public class RuleEngineWorkflowServiceImpl implements RuleEngineWorkflowService{
}
}
private String generateAttachmentsHtml(ReleasableResourceEntity entity) {
private int getAttachmentCount(ReleasableResourceEntity entity) {
if(entity!=null) {
String code =entity.getCode();
Integer version =entity.getVersion();
List<AttachmentVo> attachments =attachmentService.findByBussinessKey(code + ":" + version);
List<AttachmentVo> attachments =attachmentService.findByBussinessKey(entity.getId());
if(attachments!=null && attachments.size()>0) {
StringBuilder sb =new StringBuilder();
for(AttachmentVo attachment : attachments) {
sb.append("<a href='").append("../../../system/attachment/download/").append(attachment.getId()).append("' title='").append(attachment.getName()).append("'>").append(attachment.getName()).append("</a>").append("<br/>");
}
return sb.toString();
return attachments.size();
}
}
return null;
return 0;
}
private String getTaskTreatment(String taskId,String replaceString) {
@ -210,8 +202,7 @@ public class RuleEngineWorkflowServiceImpl implements RuleEngineWorkflowService{
for(Comment comment : comments) {
sb.append(comment.getFullMessage()).append("\n");
}
String result =sb.toString();
return result.replace("\r", "").replace("\n", replaceString);
return sb.toString();
}
}
return null;

10
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/workflow/service/support/RuleEngineApprovingTaskWrapper.java

@ -21,7 +21,7 @@ public class RuleEngineApprovingTaskWrapper {
private String resourceName; //资源名称
private Integer resourceVersion; //资源版本
private DeployStatus resourceStatus; //资源状态
private String attachments; //附件链接
private int attachmentCount; //附件个数
public String getProcessDefinitionId() {
return processDefinitionId;
@ -107,10 +107,6 @@ public class RuleEngineApprovingTaskWrapper {
public void setResourceStatus(DeployStatus resourceStatus) {
this.resourceStatus = resourceStatus;
}
public String getAttachments() {
return attachments;
}
public void setAttachments(String attachments) {
this.attachments = attachments;
}
public int getAttachmentCount() { return attachmentCount; }
public void setAttachmentCount(int attachmentCount) { this.attachmentCount = attachmentCount; }
}

3
io.sc.engine.rule.server/src/main/resources/META-INF/platform/plugins/liquibase.json

@ -4,7 +4,8 @@
"order" : 11000,
"description":"决策引擎表结构",
"locations":[
"classpath:/liquibase/RE_1.0.0_20220515__Rule Engine Database Schema DDL.xml"
"classpath:/liquibase/RE_1.0.0_20220515__Rule Engine Database Schema DDL.xml",
"classpath:/liquibase/RE_1.0.0_20220515__Rule Engine Database Data.xml"
]
}
]

21
io.sc.engine.rule.server/src/main/resources/META-INF/platform/plugins/messages.json

@ -10,24 +10,11 @@
{
"includes":[
"io/sc/engine/rule/server/i18n/other",
"io/sc/engine/rule/server/i18n/parameters",
"io/sc/engine/rule/server/i18n/workflow",
"io/sc/engine/rule/server/sample/i18n/messages",
"org/wsp/engine/rule/server/i18n/enums",
"org/wsp/engine/rule/server/i18n/example",
"org/wsp/engine/rule/server/i18n/exception",
"org/wsp/engine/rule/server/i18n/menu",
"org/wsp/engine/rule/server/i18n/parameter",
"org/wsp/engine/rule/server/i18n/messages",
"io/sc/engine/rule/server/i18n/dictionary/messages",
"org/wsp/engine/rule/server/i18n/graph/graph_editor",
"org/wsp/engine/rule/server/i18n/lib/messages",
"org/wsp/engine/rule/server/i18n/model/messages",
"org/wsp/engine/rule/server/i18n/resource/messages",
"org/wsp/engine/rule/server/i18n/scorecard/messages",
"org/wsp/engine/rule/server/i18n/testcase/messages",
"org/wsp/engine/rule/server/i18n/migration/messages",
"org/wsp/engine/rule/server/i18n/workflow/messages"
"io/sc/engine/rule/server/i18n/dictionary/messages"
],
"excludes":[]
}

22
io.sc.engine.rule.server/src/main/resources/META-INF/platform/plugins/parameter.json → io.sc.engine.rule.server/src/main/resources/META-INF/platform/plugins/parameters.json

@ -12,30 +12,18 @@
[
//
{"id":"parameter.re.server","order":1000},
///
///
{
"id" :"parameter.re.server.deploy.approve.workflow.enable",
"parentId" :"parameter.re.server",
"code" :"parameter.re.server.deploy.approve.workflow.enable",
"defaultValue" :"false",
"options" :{
"false" : "#{no}",
"true" : "#{yes}"
"true" : "parameter.re.server.deploy.approve.workflow.enable.true",
"false" : "parameter.re.server.deploy.approve.workflow.enable.false"
},
"order" : 0
},
///
{
"id" :"parameter.re.server.attachment.enable",
"parentId" :"parameter.re.server",
"code" :"parameter.re.server.attachment.enable",
"defaultValue" :"true",
"options" :{
"false" : "#{no}",
"true" : "#{yes}"
},
"order" : 50
},
///,
{
"id" :"parameter.re.server.modelDefine.nullVersion.strategy",
@ -43,8 +31,8 @@
"code" :"parameter.re.server.modelDefine.nullVersion.strategy",
"defaultValue" :"last",
"options" :{
"last_deploy" : "#{parameter.re.server.modelDefine.nullVersion.strategy.last_deploy}",
"last" : "#{parameter.re.server.modelDefine.nullVersion.strategy.last}"
"last_deploy" : "parameter.re.server.modelDefine.nullVersion.strategy.last_deploy",
"last" : "parameter.re.server.modelDefine.nullVersion.strategy.last"
},
"order" : 100
}

1
io.sc.engine.rule.server/src/main/resources/META-INF/services/io.sc.platform.core.initializer.ApplicationInitializer

@ -0,0 +1 @@
io.sc.engine.rule.server.common.initializer.RuleEngineWorkFlowInitializer

43
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/other.properties

@ -0,0 +1,43 @@
# \u7EC4\u4EF6\u9762\u677F\u6807\u9898
mxgraph.re.editor.Palette.title=Available
# \u5F00\u59CB\u7EC4\u4EF6
mxgraph.re.editor.component.start.title=Start
# \u6761\u4EF6\u5224\u65AD\u7EC4\u4EF6
mxgraph.re.editor.component.condition.title=Condition
mxgraph.re.editor.component.condition.entity.condition=Condition
# \u5E76\u53D1\u7EC4\u4EF6
mxgraph.re.editor.component.parallel.title=Paralleler
# \u6761\u4EF6\u5206\u503C\u8FDE\u7EBF\u7EC4\u4EF6
mxgraph.re.editor.component.condition.edge.conditionValue=Condition Value
mxgraph.re.editor.component.condition.edge.type=Value Type
mxgraph.re.editor.component.condition.edge.type.string=String
mxgraph.re.editor.component.condition.edge.type.number=Number
mxgraph.re.editor.component.condition.edge.type.boolean=Boolean
# \u8868\u8FBE\u5F0F\u7EC4\u4EF6
mxgraph.re.editor.component.expression.title=Expression
mxgraph.re.editor.component.expression.entity.expression=Expression
mxgraph.re.editor.component.expression.entity.commands=Commands
# \u6307\u4EE4\u96C6\u7EC4\u4EF6
mxgraph.re.editor.component.commandSet.title=Command Set
mxgraph.re.editor.component.commandSet.entity.commands=Command Set
# \u8D44\u6E90\u6458\u8981\u4FE1\u606F\u7EC4\u4EF6
mxgraph.re.editor.component.resourceAbstract.title=Resource
mxgraph.re.editor.component.resourceAbstract.entity.resource=Resource
# \u53EF\u914D\u7F6E\u8F93\u5165\u8F93\u51FA\u6307\u4EE4\u7684\u8D44\u6E90\u6458\u8981\u4FE1\u606F\u7EC4\u4EF6
mxgraph.re.editor.component.configurableResourceAbstract.title=Configurable Resource
mxgraph.re.editor.component.configurableResourceAbstract.entity.resource=Resource
mxgraph.re.editor.component.configurableResourceAbstract.entity.inputCommands=Input Command Set
mxgraph.re.editor.component.configurableResourceAbstract.entity.outputCommands=Output Command Set
# \u6A21\u578B\u7EC4\u4EF6
mxgraph.re.editor.component.submodel.title=Model
mxgraph.re.editor.component.submodel.entity.model=Model

42
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/other_tw_CN.properties

@ -0,0 +1,42 @@
# \u7EC4\u4EF6\u9762\u677F\u6807\u9898
mxgraph.re.editor.Palette.title=\u53EF\u7528\u7EC4\u4EF6
# \u5F00\u59CB\u7EC4\u4EF6
mxgraph.re.editor.component.start.title=\u5F00\u59CB
# \u6761\u4EF6\u5224\u65AD\u7EC4\u4EF6
mxgraph.re.editor.component.condition.title=\u6761\u4EF6\u5224\u65AD
mxgraph.re.editor.component.condition.entity.condition=\u6761\u4EF6
# \u5E76\u53D1\u7EC4\u4EF6
mxgraph.re.editor.component.parallel.title=\u5E76\u53D1\u5668
# \u6761\u4EF6\u5206\u503C\u8FDE\u7EBF\u7EC4\u4EF6
mxgraph.re.editor.component.condition.edge.conditionValue=\u6761\u4EF6\u503C
mxgraph.re.editor.component.condition.edge.type=\u503C\u7C7B\u578B
mxgraph.re.editor.component.condition.edge.type.string=\u5B57\u7B26\u4E32
mxgraph.re.editor.component.condition.edge.type.number=\u6570\u5B57
mxgraph.re.editor.component.condition.edge.type.boolean=\u5E03\u5C14
# \u8868\u8FBE\u5F0F\u7EC4\u4EF6
mxgraph.re.editor.component.expression.title=\u8868\u8FBE\u5F0F
mxgraph.re.editor.component.expression.entity.expression=\u8868\u8FBE\u5F0F
mxgraph.re.editor.component.expression.entity.commands=\u9644\u52A0\u6307\u4EE4\u96C6
# \u6307\u4EE4\u96C6\u7EC4\u4EF6
mxgraph.re.editor.component.commandSet.title=\u6307\u4EE4\u96C6
mxgraph.re.editor.component.commandSet.entity.commands=\u6307\u4EE4\u96C6
# \u8D44\u6E90\u6458\u8981\u4FE1\u606F\u7EC4\u4EF6
mxgraph.re.editor.component.resourceAbstract.title=\u8D44\u6E90
mxgraph.re.editor.component.resourceAbstract.entity.resource=\u8D44\u6E90
# \u53EF\u914D\u7F6E\u8F93\u5165\u8F93\u51FA\u6307\u4EE4\u7684\u8D44\u6E90\u6458\u8981\u4FE1\u606F\u7EC4\u4EF6
mxgraph.re.editor.component.configurableResourceAbstract.title=\u8F93\u5165\u8F93\u51FA\u6307\u4EE4\u8D44\u6E90
mxgraph.re.editor.component.configurableResourceAbstract.entity.resource=\u8D44\u6E90
mxgraph.re.editor.component.configurableResourceAbstract.entity.inputCommands=\u8F93\u5165\u6307\u4EE4\u96C6
mxgraph.re.editor.component.configurableResourceAbstract.entity.outputCommands=\u8F93\u51FA\u6307\u4EE4\u96C6
# \u6A21\u578B\u7EC4\u4EF6
mxgraph.re.editor.component.submodel.title=\u5B50\u6A21\u578B
mxgraph.re.editor.component.submodel.entity.model=\u5B50\u6A21\u578B

42
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/other_zh_CN.properties

@ -0,0 +1,42 @@
# \u7EC4\u4EF6\u9762\u677F\u6807\u9898
mxgraph.re.editor.Palette.title=\u53EF\u7528\u7EC4\u4EF6
# \u5F00\u59CB\u7EC4\u4EF6
mxgraph.re.editor.component.start.title=\u5F00\u59CB
# \u6761\u4EF6\u5224\u65AD\u7EC4\u4EF6
mxgraph.re.editor.component.condition.title=\u6761\u4EF6\u5224\u65AD
mxgraph.re.editor.component.condition.entity.condition=\u6761\u4EF6
# \u5E76\u53D1\u7EC4\u4EF6
mxgraph.re.editor.component.parallel.title=\u5E76\u53D1\u5668
# \u6761\u4EF6\u5206\u503C\u8FDE\u7EBF\u7EC4\u4EF6
mxgraph.re.editor.component.condition.edge.conditionValue=\u6761\u4EF6\u503C
mxgraph.re.editor.component.condition.edge.type=\u503C\u7C7B\u578B
mxgraph.re.editor.component.condition.edge.type.string=\u5B57\u7B26\u4E32
mxgraph.re.editor.component.condition.edge.type.number=\u6570\u5B57
mxgraph.re.editor.component.condition.edge.type.boolean=\u5E03\u5C14
# \u8868\u8FBE\u5F0F\u7EC4\u4EF6
mxgraph.re.editor.component.expression.title=\u8868\u8FBE\u5F0F
mxgraph.re.editor.component.expression.entity.expression=\u8868\u8FBE\u5F0F
mxgraph.re.editor.component.expression.entity.commands=\u9644\u52A0\u6307\u4EE4\u96C6
# \u6307\u4EE4\u96C6\u7EC4\u4EF6
mxgraph.re.editor.component.commandSet.title=\u6307\u4EE4\u96C6
mxgraph.re.editor.component.commandSet.entity.commands=\u6307\u4EE4\u96C6
# \u8D44\u6E90\u6458\u8981\u4FE1\u606F\u7EC4\u4EF6
mxgraph.re.editor.component.resourceAbstract.title=\u8D44\u6E90
mxgraph.re.editor.component.resourceAbstract.entity.resource=\u8D44\u6E90
# \u53EF\u914D\u7F6E\u8F93\u5165\u8F93\u51FA\u6307\u4EE4\u7684\u8D44\u6E90\u6458\u8981\u4FE1\u606F\u7EC4\u4EF6
mxgraph.re.editor.component.configurableResourceAbstract.title=\u8F93\u5165\u8F93\u51FA\u6307\u4EE4\u8D44\u6E90
mxgraph.re.editor.component.configurableResourceAbstract.entity.resource=\u8D44\u6E90
mxgraph.re.editor.component.configurableResourceAbstract.entity.inputCommands=\u8F93\u5165\u6307\u4EE4\u96C6
mxgraph.re.editor.component.configurableResourceAbstract.entity.outputCommands=\u8F93\u51FA\u6307\u4EE4\u96C6
# \u6A21\u578B\u7EC4\u4EF6
mxgraph.re.editor.component.submodel.title=\u5B50\u6A21\u578B
mxgraph.re.editor.component.submodel.entity.model=\u5B50\u6A21\u578B

9
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/parameter.properties

@ -1,9 +0,0 @@
#================================================
# \u6700\u65b0\u6a21\u578b\u5b9a\u4e49\u52a0\u8f7d\u7b56\u7565\u7cfb\u7edf\u914d\u7f6e\u53c2\u6570\u9009\u9879
#================================================
parameter.re.server=\u51b3\u7b56\u5f15\u64ce(\u670d\u52a1\u5668)
parameter.re.server.deploy.approve.workflow.enable=Enable Model Deploy Work Flow
parameter.re.server.attachment.enable=Enable Upload Attachment
parameter.re.server.modelDefine.nullVersion.strategy=Load Model Define Strategy When Version is Empty
parameter.re.server.modelDefine.nullVersion.strategy.last_deploy=Last (Deployed)
parameter.re.server.modelDefine.nullVersion.strategy.last=Last

9
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/parameter_zh_CN.properties

@ -1,9 +0,0 @@
#================================================
# \u6700\u65b0\u6a21\u578b\u5b9a\u4e49\u52a0\u8f7d\u7b56\u7565\u7cfb\u7edf\u914d\u7f6e\u53c2\u6570\u9009\u9879
#================================================
parameter.re.server=\u51b3\u7b56\u5f15\u64ce(\u670d\u52a1\u5668)
parameter.re.server.deploy.approve.workflow.enable=\u662f\u5426\u5f00\u542f\u6a21\u578b\u53d1\u5e03\u5ba1\u6279\u6d41\u7a0b
parameter.re.server.attachment.enable=\u662f\u5426\u5141\u8bb8\u4e0a\u4f20\u9644\u4ef6
parameter.re.server.modelDefine.nullVersion.strategy=\u5f53\u6a21\u578b\u7248\u672c\u4e3a\u7a7a\u65f6,\u52a0\u8f7d\u6a21\u578b\u5b9a\u4e49\u7684\u7b56\u7565
parameter.re.server.modelDefine.nullVersion.strategy.last_deploy=\u6700\u65b0(\u5df2\u53d1\u5e03)
parameter.re.server.modelDefine.nullVersion.strategy.last=\u6700\u65b0

9
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/parameters.properties

@ -0,0 +1,9 @@
parameter.re.server=Rule Engine
parameter.re.server.deploy.approve.workflow.enable=Workflow needed before rule online
parameter.re.server.deploy.approve.workflow.enable.true=Yes
parameter.re.server.deploy.approve.workflow.enable.false=No
parameter.re.server.modelDefine.nullVersion.strategy=Load Model Define Strategy When Version is Empty
parameter.re.server.modelDefine.nullVersion.strategy.last_deploy=Last (Deployed)
parameter.re.server.modelDefine.nullVersion.strategy.last=Last

9
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/parameters_tw_CN.properties

@ -0,0 +1,9 @@
parameter.re.server=\u6C7A\u7B56\u5F15\u64CE(\u670D\u52D9\u5668)
parameter.re.server.deploy.approve.workflow.enable=\u6A21\u578B\u767C\u4F48\u524D\u662F\u5426\u9700\u8981\u6D41\u7A0B\u5BE9\u6279
parameter.re.server.deploy.approve.workflow.enable.true=\u662F
parameter.re.server.deploy.approve.workflow.enable.false=\u5426
parameter.re.server.modelDefine.nullVersion.strategy=\u7576\u6A21\u578B\u7248\u672C\u70BA\u7A7A\u6642,\u52A0\u8F09\u6A21\u578B\u5B9A\u7FA9\u7684\u7B56\u7565
parameter.re.server.modelDefine.nullVersion.strategy.last_deploy=\u6700\u65B0(\u5DF2\u767C\u4F48)
parameter.re.server.modelDefine.nullVersion.strategy.last=\u6700\u65B0

9
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/parameters_zh_CN.properties

@ -0,0 +1,9 @@
parameter.re.server=\u51B3\u7B56\u5F15\u64CE(\u670D\u52A1\u5668)
parameter.re.server.deploy.approve.workflow.enable=\u6A21\u578B\u53D1\u5E03\u524D\u662F\u5426\u9700\u8981\u6D41\u7A0B\u5BA1\u6279
parameter.re.server.deploy.approve.workflow.enable.true=\u662F
parameter.re.server.deploy.approve.workflow.enable.false=\u5426
parameter.re.server.modelDefine.nullVersion.strategy=\u5F53\u6A21\u578B\u7248\u672C\u4E3A\u7A7A\u65F6,\u52A0\u8F7D\u6A21\u578B\u5B9A\u4E49\u7684\u7B56\u7565
parameter.re.server.modelDefine.nullVersion.strategy.last_deploy=\u6700\u65B0(\u5DF2\u53D1\u5E03)
parameter.re.server.modelDefine.nullVersion.strategy.last=\u6700\u65B0

1
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/workflow.properties

@ -0,0 +1 @@
WORK_FLOW.RULE_ENGINE_APPROVING=Rule Engine Workflow

1
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/workflow_tw_CN.properties

@ -0,0 +1 @@
WORK_FLOW.RULE_ENGINE_APPROVING=\u6C7A\u7B56\u5F15\u64CE\u5BE9\u6279\u6D41\u7A0B

1
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/i18n/workflow_zh_CN.properties

@ -0,0 +1 @@
WORK_FLOW.RULE_ENGINE_APPROVING=\u51B3\u7B56\u5F15\u64CE\u5BA1\u6279\u6D41\u7A0B

19
io.sc.engine.rule.server/src/main/resources/liquibase/RE_1.0.0_20220515__Rule Engine Database Data.xml

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="
http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd
"
>
<changeSet id="RE_1.0.0_20220515__Rule Engine Database Data" author="platform">
<!-- 数据字典数据 -->
<customChange class="io.sc.platform.jdbc.liquibase.task.CsvImportTaskChange">
<param name="dataFile" value="classpath:/liquibase/io/sc/engine/rule/sys_dictionary.csv"/>
</customChange>
</changeSet>
</databaseChangeLog>

6
io.sc.engine.rule.server/src/main/resources/liquibase/io/sc/engine/rule/sys_dictionary.csv

@ -0,0 +1,6 @@
"SYS_DICTIONARY",,,,,,,,,,
"ID_","CODE_","VALUE_","ORDER_","JPA_VERSION_","DATA_COME_FROM_","CREATOR_","CREATE_DATE_","LAST_MODIFIER_","LAST_MODIFYDATE_","CORP_CODE_"
"ID","","","排序","JPA乐观锁版本","","创建人","创建日期","最后修改人","最后修改日期",""
"VARCHAR","VARCHAR","VARCHAR","INTEGER","INTEGER","VARCHAR","VARCHAR","TIMESTAMP","VARCHAR","TIMESTAMP","VARCHAR"
"java.lang.String","java.lang.String","java.lang.String","java.lang.Integer","java.lang.Integer","java.lang.String","java.lang.String","java.sql.Timestamp","java.lang.String","java.sql.Timestamp","java.lang.String"
"debe6a2c-da11-46f9-a66d-28481e1da319","WORK_FLOW","RULE_ENGINE_APPROVING","2",,"INPUT","system","2024-03-11 12:50:35.0","system","2024-03-11 12:50:35.0","_PRIMARY_"
1 SYS_DICTIONARY
2 ID_ CODE_ VALUE_ ORDER_ JPA_VERSION_ DATA_COME_FROM_ CREATOR_ CREATE_DATE_ LAST_MODIFIER_ LAST_MODIFYDATE_ CORP_CODE_
3 ID 排序 JPA乐观锁版本 创建人 创建日期 最后修改人 最后修改日期
4 VARCHAR VARCHAR VARCHAR INTEGER INTEGER VARCHAR VARCHAR TIMESTAMP VARCHAR TIMESTAMP VARCHAR
5 java.lang.String java.lang.String java.lang.String java.lang.Integer java.lang.Integer java.lang.String java.lang.String java.sql.Timestamp java.lang.String java.sql.Timestamp java.lang.String
6 debe6a2c-da11-46f9-a66d-28481e1da319 WORK_FLOW RULE_ENGINE_APPROVING 2 INPUT system 2024-03-11 12:50:35.0 system 2024-03-11 12:50:35.0 _PRIMARY_

130
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor-ext/css/alert.css

@ -0,0 +1,130 @@
/*为手机端定制的一款皮肤(引用此皮肤时无需引用alert.css) 最后更新2016-07-27*/
/*
alert_overlay 背景遮罩
alert_msg 消息框主体
alert_content 内容容器
alert_buttons 底部按钮容器
alert_btn 两个按钮公用class
alert_btn_ok 确定按钮
alert_btn_cancel 取消按钮
*/
.alert_overlay {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 1000;
background: rgba(0, 0, 0, .1)
}
.alert_msg {
position: fixed;
width: 280px;
left: 50%;
margin-left: -140px;
top: 20%;
z-index: 1000;
border: 1px solid #ccc;
border-radius: 4px;
box-shadow: 0 0 15px rgba(0, 0, 0, .3);
background: #fff;
animation: alertshow .2s ease
}
.alert_content {
padding: 20px;
font-size: 14px;
text-align: left
}
.alert_buttons {
text-align: center;
border-top: 1px solid #ccc;
-webkit-user-select: none
}
.alert_buttons .alert_btn {
display: inline-block;
width: 50%;
border: none;
height: 45px;
line-height: 45px;
font-size: 14px;
outline: 0;
-webkit-appearance: none;
background: #fff;
-webkit-tap-highlight-color: transparent;
border-radius: 0 0 4px 4px;
}
.alert_buttons .alert_btn:only-child {
width: 100%
}
.alert_buttons .alert_btn:first-child + .alert_btn {
border-left: 1px solid #ccc;
border-radius: 0 0 4px 0;
}
.alert_tips {
position: fixed;
z-index: 10176523;
width: 100%;
top: 55%;
pointer-events: none;
text-align: center;
}
.alert_tips div {
box-siziong: border-box;
display: inline-block;
padding: 15px;
border-radius: 10px;
background: rgba(0, 0, 0, .7);
min-width: 50px;
max-width: 230px;
text-align: center;
color: #fff;
animation: tipsshow 3s .01s ease;
opacity: 0;
}
@keyframes alertshow {
0% {
opacity: 0;
transform: scale(.5)
}
70% {
opacity: .7;
transform: scale(1.05)
}
100% {
opacity: 1;
transform: scale(1)
}
}
@keyframes tipsshow {
0% {
opacity: 0;
transform: scale(1.4) rotateX(-360deg)
}
20% {
opacity: 1;
transform: scale(1) rotateX(0deg)
}
80% {
opacity: 1;
transform: scale(1) rotateX(0deg)
}
100% {
opacity: 0;
transform: scale(1.4) rotateX(360deg)
}
}

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor-ext/images/save.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor-ext/images/xml.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

59
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor-ext/js/alert.js

@ -0,0 +1,59 @@
/**
* jQuery/Zepto 弹窗插件
* 调用方法中括号的为可选参数
* $.alert(string[,function])
* $.confirm(string[,function])
* $.tips(string[,number])
* version:2016-11-30
*/
!function($){
//所有的css,可以自定义,css和Dom结构请参考 https://github.com/ydq/alert
var css='.alert_overlay{position:fixed;width:100%;height:100%;top:0;left:0;z-index:1000;background:rgba(0,0,0,.05);-webkit-backdrop-filter:blur(3px)}.pc .alert_msg{width:320px}.mob .alert_msg{width:260px;border-radius:4px}.alert_msg{box-sizing:border-box;position:absolute;left:50%;top:30%;border:1px solid #ccc;box-shadow:0 2px 15px rgba(0,0,0,.3);background:#fff;transition:all .2s cubic-bezier(.8,.5,.2,1.4);-webkit-transform:translate(-50%,-50%) scale(.5);opacity:0;transform:translate(-50%,-50%) scale(.5)}.alert_show .alert_msg{opacity:1;transform:translate(-50%,-50%) scale(1);-webkit-transform:translate(-50%,-50%) scale(1)}.alert_content{padding:20px 15px;font-size:14px;text-align:left}.alert_tips{position:fixed;z-index:10176523}.pc .alert_buttons{padding:6px;border-top:1px solid #ccc;text-align:right;box-shadow:0 1px 0 #fff inset;background:#eee;-webkit-user-select:none}.pc .alert_buttons .alert_btn{padding:4px 8px;margin:0 2px;border:1px solid #ccc;background:#eee;cursor:pointer;border-radius:2px;font-size:14px;outline:0;-webkit-appearance:none}.pc .alert_buttons .alert_btn:hover{border-color:#ccc;box-shadow:0 1px 2px #ccc;background:#eaeaea}.pc .alert_buttons .alert_btn:active{box-shadow:0 1px 2px #ccc inset;background:#e6e6e6}.pc.alert_tips{top:50px;right:50px}.pc.alert_tips div{background:rgba(0,0,0,.7);position:relative;color:#fff;font-size:16px;padding:10px 15px;border-radius:2px;margin-bottom:20px;box-shadow:0 0 3px #000;display:none;float:right;clear:both}.mob .alert_buttons{text-align:center;border-top:1px solid #ccc;-webkit-user-select:none}.mob .alert_buttons .alert_btn{display:inline-block;width:50%;border:0;height:40px;font-size:14px;outline:0;-webkit-appearance:none;background:#fff;-webkit-tap-highlight-color:transparent;border-radius:0 0 4px 4px}.mob .alert_buttons .alert_btn:only-child{width:100%}.mob .alert_buttons .alert_btn:first-child+.alert_btn{border-left:1px solid #ccc;border-radius:0 0 4px 0}.mob.alert_tips{width:100%;top:55%;pointer-events:none;text-align:center}.mob.alert_tips div{box-sizing:border-box;display:inline-block;padding:15px;border-radius:10px;background:rgba(0,0,0,.7);min-width:50px;max-width:230px;text-align:center;color:#fff;animation:tipsshow 3s .01s ease;-webkit-animation:tipsshow 3s .01s ease;opacity:0}@keyframes tipsshow{0%{opacity:0;transform:scale(1.4) rotateX(-360deg)}20%,80%{opacity:1;transform:scale(1) rotateX(0deg)}to{transform:scale(1.4) rotateX(360deg)}}@-webkit-keyframes tipsshow{0%,to{opacity:0}0%{-webkit-transform:scale(1.4) rotateX(-360deg)}20%,80%{opacity:1;-webkit-transform:scale(1) rotateX(0deg)}to{opacity:0;-webkit-transform:scale(1.4) rotateX(360deg)}}';
$('head').append('<style type="text/css">'+css+'</style>');
$._ismob=/i(Phone|Pod)|Android|phone/i.test(navigator.userAgent)
$._isalert=$._isload=0
$.alert=function(){
if(arguments.length){
$._isalert=1;
return $.confirm.apply($,arguments);
}
}
$.confirm=function(){
var args=arguments,d;
if(args.length){
var fn=args[1],_click = function(e){typeof fn=='function'?(fn.call(d,e.data.r)!=!1&&d.close()):d.close()};
d = $('<div class="alert_overlay '+($._ismob?'mob':'pc')+'"><div class="alert_msg"><div class="alert_content">'+args[0]+'</div><div class="alert_buttons"><button class="alert_btn alert_btn_cancel">Cancel</button><button class="alert_btn alert_btn_ok">Okey</button></div></div></div>')
.on('contextmenu',!1)
.on('click','.alert_btn_ok',{r:!0},_click)
.on('click','.alert_btn_cancel',{r:!1},_click)
$._isload?d.find('.alert_content').css('text-align','center').parent().css({width:'auto',borderRadius:'4px'}).find('.alert_buttons').remove():($._isalert&&d.find('.alert_btn_cancel').remove())
d.appendTo('body').find('.alert_btn_ok').focus();//让对话框打开后支持直接键盘回车触发确定按钮点击
d.ok = function(t){d.find('.alert_btn_ok').text(t||'Okey');return d}
d.cancel = function(t){d.find('.alert_btn_cancel').text(t||'Cancel');return d}
d.content = function(t){t&&d.find('.alert_content').html(t);return d}
d.close = function(){d.one('webkitTransitionEnd transitionEnd',function(){d.remove();}).removeClass('alert_show')}
d.addClass('alert_show')
}
$._isalert=$._isload=0;
return d;
},
$.tips=function(m,t){
if(m){
if($._ismob){
$('.alert_tips').remove();
$('<div class="alert_tips mob"><div>'+m+'</div></div>').appendTo('body').one('webkitAnimationEnd animationEnd',function(){$(this).remove()})
}else{
var tipsContainer = $('.alert_tips');
tipsContainer.length||(tipsContainer=$('<div class="alert_tips pc"></div>').appendTo('body'));
$('<div>'+m+'</div>').appendTo(tipsContainer).fadeIn('fast').delay(t||2e3).slideUp('fast',function(){$(this).remove();});
}
}
}
$.load=function(){
$('.alert_overlay').remove();
$._isload =1;
var d = $.confirm.call($,arguments[0]||"Loading...");
$.loaded = d.close;
return d;
}
}($)

2
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor-ext/js/alert.min.js

@ -0,0 +1,2 @@
/*jQuery/Zepto弹窗插件 | version:2016-11-30*/
!function(t){var e=".alert_overlay{position:fixed;width:100%;height:100%;top:0;left:0;z-index:1000;background:rgba(0,0,0,.05);-webkit-backdrop-filter:blur(3px)}.pc .alert_msg{width:320px}.mob .alert_msg{width:260px;border-radius:4px}.alert_msg{box-sizing:border-box;position:absolute;left:50%;top:30%;border:1px solid #ccc;box-shadow:0 2px 15px rgba(0,0,0,.3);background:#fff;transition:all .2s cubic-bezier(.8,.5,.2,1.4);-webkit-transform:translate(-50%,-50%) scale(.5);opacity:0;transform:translate(-50%,-50%) scale(.5)}.alert_show .alert_msg{opacity:1;transform:translate(-50%,-50%) scale(1);-webkit-transform:translate(-50%,-50%) scale(1)}.alert_content{padding:20px 15px;font-size:14px;text-align:left}.alert_tips{position:fixed;z-index:10176523}.pc .alert_buttons{padding:6px;border-top:1px solid #ccc;text-align:right;box-shadow:0 1px 0 #fff inset;background:#eee;-webkit-user-select:none}.pc .alert_buttons .alert_btn{padding:4px 8px;margin:0 2px;border:1px solid #ccc;background:#eee;cursor:pointer;border-radius:2px;font-size:14px;outline:0;-webkit-appearance:none}.pc .alert_buttons .alert_btn:hover{border-color:#ccc;box-shadow:0 1px 2px #ccc;background:#eaeaea}.pc .alert_buttons .alert_btn:active{box-shadow:0 1px 2px #ccc inset;background:#e6e6e6}.pc.alert_tips{top:50px;right:50px}.pc.alert_tips div{background:rgba(0,0,0,.7);position:relative;color:#fff;font-size:16px;padding:10px 15px;border-radius:2px;margin-bottom:20px;box-shadow:0 0 3px #000;display:none;float:right;clear:both}.mob .alert_buttons{text-align:center;border-top:1px solid #ccc;-webkit-user-select:none}.mob .alert_buttons .alert_btn{display:inline-block;width:50%;border:0;height:40px;font-size:14px;outline:0;-webkit-appearance:none;background:#fff;-webkit-tap-highlight-color:transparent;border-radius:0 0 4px 4px}.mob .alert_buttons .alert_btn:only-child{width:100%}.mob .alert_buttons .alert_btn:first-child+.alert_btn{border-left:1px solid #ccc;border-radius:0 0 4px 0}.mob.alert_tips{width:100%;top:55%;pointer-events:none;text-align:center}.mob.alert_tips div{box-sizing:border-box;display:inline-block;padding:15px;border-radius:10px;background:rgba(0,0,0,.7);min-width:50px;max-width:230px;text-align:center;color:#fff;animation:tipsshow 3s .01s ease;-webkit-animation:tipsshow 3s .01s ease;opacity:0}@keyframes tipsshow{0%{opacity:0;transform:scale(1.4) rotateX(-360deg)}20%,80%{opacity:1;transform:scale(1) rotateX(0deg)}to{transform:scale(1.4) rotateX(360deg)}}@-webkit-keyframes tipsshow{0%,to{opacity:0}0%{-webkit-transform:scale(1.4) rotateX(-360deg)}20%,80%{opacity:1;-webkit-transform:scale(1) rotateX(0deg)}to{opacity:0;-webkit-transform:scale(1.4) rotateX(360deg)}}";t("head").append('<style type="text/css">'+e+"</style>"),t._ismob=/i(Phone|Pod)|Android|phone/i.test(navigator.userAgent),t._isalert=t._isload=0,t.alert=function(){if(arguments.length)return t._isalert=1,t.confirm.apply(t,arguments)},t.confirm=function(){var e,o=arguments;if(o.length){var a=o[1],n=function(t){"function"==typeof a?0!=a.call(e,t.data.r)&&e.close():e.close()};e=t('<div class="alert_overlay '+(t._ismob?"mob":"pc")+'"><div class="alert_msg"><div class="alert_content">'+o[0]+'</div><div class="alert_buttons"><button class="alert_btn alert_btn_cancel">Cancel</button><button class="alert_btn alert_btn_ok">Okey</button></div></div></div>').on("contextmenu",!1).on("click",".alert_btn_ok",{r:!0},n).on("click",".alert_btn_cancel",{r:!1},n),t._isload?e.find(".alert_content").css("text-align","center").parent().css({width:"auto",borderRadius:"4px"}).find(".alert_buttons").remove():t._isalert&&e.find(".alert_btn_cancel").remove(),e.appendTo("body").find(".alert_btn_ok").focus(),e.ok=function(t){return e.find(".alert_btn_ok").text(t||"Okey"),e},e.cancel=function(t){return e.find(".alert_btn_cancel").text(t||"Cancel"),e},e.content=function(t){return t&&e.find(".alert_content").html(t),e},e.close=function(){e.one("webkitTransitionEnd transitionEnd",function(){e.remove()}).removeClass("alert_show")},e.addClass("alert_show")}return t._isalert=t._isload=0,e},t.tips=function(e,o){if(e)if(t._ismob)t(".alert_tips").remove(),t('<div class="alert_tips mob"><div>'+e+"</div></div>").appendTo("body").one("webkitAnimationEnd animationEnd",function(){t(this).remove()});else{var a=t(".alert_tips");a.length||(a=t('<div class="alert_tips pc"></div>').appendTo("body")),t("<div>"+e+"</div>").appendTo(a).fadeIn("fast").delay(o||2e3).slideUp("fast",function(){t(this).remove()})}},t.load=function(){t(".alert_overlay").remove(),t._isload=1;var e=t.confirm.call(t,arguments[0]||"Loading...");return t.loaded=e.close,e}}($);

3
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/codemirror.css

@ -0,0 +1,3 @@
.CodeMirror-hints{
z-index:1000000;
}

151
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/deflate/base64.js

@ -0,0 +1,151 @@
/**
*
* Base64 encode / decode
* http://www.webtoolkit.info/
*
**/
var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// public method for encoding
encode : function (input, binary) {
binary = (binary != null) ? binary : false;
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
if (!binary)
{
input = Base64._utf8_encode(input);
}
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function (input, binary) {
binary = (binary != null) ? binary : false;
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
if (!binary)
{
output = Base64._utf8_decode(output);
}
return output;
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}

3
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/deflate/pako.min.js

File diff suppressed because one or more lines are too long

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/checkmark.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/clear.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/close.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/collapsed.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/dropdown.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/dropdown.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/edit.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 B

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/expanded.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/grid.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 B

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/handle-fixed.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/handle-main.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/handle-rotate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/handle-secondary.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/handle-terminal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/help.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/locked.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1020 B

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/nocolor.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 948 B

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/refresh.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/round-drop.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/search.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/tooltip.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1006 B

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/transparent.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/triangle-down.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/triangle-left.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/triangle-right.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/triangle-up.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/images/unlocked.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

110
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/index.html

@ -0,0 +1,110 @@
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=5,IE=9" ><![endif]-->
<!DOCTYPE html>
<html>
<head>
<title>Grapheditor</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" type="text/css" href="styles/grapheditor.css">
<script type="text/javascript">
// Parses URL parameters. Supported parameters are:
// - lang=xy: Specifies the language of the user interface.
// - touch=1: Enables a touch-style user interface.
// - storage=local: Enables HTML5 local storage.
// - chrome=0: Chromeless mode.
var urlParams = (function(url)
{
var result = new Object();
var idx = url.lastIndexOf('?');
if (idx > 0)
{
var params = url.substring(idx + 1).split('&');
for (var i = 0; i < params.length; i++)
{
idx = params[i].indexOf('=');
if (idx > 0)
{
result[params[i].substring(0, idx)] = params[i].substring(idx + 1);
}
}
}
return result;
})(window.location.href);
// Default resources are included in grapheditor resources
mxLoadResources = false;
</script>
<script type="text/javascript" src="js/Init.js"></script>
<script type="text/javascript" src="deflate/pako.min.js"></script>
<script type="text/javascript" src="deflate/base64.js"></script>
<script type="text/javascript" src="jscolor/jscolor.js"></script>
<script type="text/javascript" src="sanitizer/sanitizer.min.js"></script>
<script type="text/javascript" src="../../../src/js/mxClient.js"></script>
<script type="text/javascript" src="js/EditorUi.js"></script>
<script type="text/javascript" src="js/Editor.js"></script>
<script type="text/javascript" src="js/Sidebar.js"></script>
<script type="text/javascript" src="js/Graph.js"></script>
<script type="text/javascript" src="js/Format.js"></script>
<script type="text/javascript" src="js/Shapes.js"></script>
<script type="text/javascript" src="js/Actions.js"></script>
<script type="text/javascript" src="js/Menus.js"></script>
<script type="text/javascript" src="js/Toolbar.js"></script>
<script type="text/javascript" src="js/Dialogs.js"></script>
</head>
<body class="geEditor">
<script type="text/javascript">
// Extends EditorUi to update I/O action states based on availability of backend
(function()
{
var editorUiInit = EditorUi.prototype.init;
EditorUi.prototype.init = function()
{
editorUiInit.apply(this, arguments);
this.actions.get('export').setEnabled(false);
// Updates action states which require a backend
if (!Editor.useLocalStorage)
{
mxUtils.post(OPEN_URL, '', mxUtils.bind(this, function(req)
{
var enabled = req.getStatus() != 404;
this.actions.get('open').setEnabled(enabled || Graph.fileSupport);
this.actions.get('import').setEnabled(enabled || Graph.fileSupport);
this.actions.get('save').setEnabled(enabled);
this.actions.get('saveAs').setEnabled(enabled);
this.actions.get('export').setEnabled(enabled);
}));
}
};
// Adds required resources (disables loading of fallback properties, this can only
// be used if we know that all keys are defined in the language specific file)
mxResources.loadDefaultBundle = false;
var bundle = mxResources.getDefaultBundle(RESOURCE_BASE, mxLanguage) ||
mxResources.getSpecialBundle(RESOURCE_BASE, mxLanguage);
// Fixes possible asynchronous requests
mxUtils.getAll([bundle, STYLE_PATH + '/default.xml'], function(xhr)
{
// Adds bundle text to resources
mxResources.parse(xhr[0].getText());
// Configures the default graph theme
var themes = new Object();
themes[Graph.prototype.defaultThemeName] = xhr[1].getDocumentElement();
// Main
new EditorUi(new Editor(urlParams['chrome'] == '0', themes));
}, function()
{
document.body.innerHTML = '<center style="margin-top:10%;">Error loading resource files. Please check browser console.</center>';
});
})();
</script>
</body>
</html>

1413
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Actions.js

File diff suppressed because it is too large

2542
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Dialogs.js

File diff suppressed because it is too large

2252
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Editor.js

File diff suppressed because it is too large

4234
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/EditorUi.js

File diff suppressed because it is too large

5496
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Format.js

File diff suppressed because it is too large

8344
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Graph.js

File diff suppressed because one or more lines are too long

30
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Init.js

@ -0,0 +1,30 @@
// urlParams is null when used for embedding
window.urlParams = window.urlParams || {};
// Public global variables
window.MAX_REQUEST_SIZE = window.MAX_REQUEST_SIZE || 10485760;
window.MAX_AREA = window.MAX_AREA || 15000 * 15000;
// URLs for save and export
window.EXPORT_URL = window.EXPORT_URL || '/export';
window.SAVE_URL = window.SAVE_URL || '/save';
window.OPEN_URL = window.OPEN_URL || '/open';
window.RESOURCES_PATH = window.RESOURCES_PATH || 'resources';
window.RESOURCE_BASE = window.RESOURCE_BASE || window.RESOURCES_PATH + '/grapheditor';
window.STENCIL_PATH = window.STENCIL_PATH || 'stencils';
window.IMAGE_PATH = window.IMAGE_PATH || 'images';
window.STYLE_PATH = window.STYLE_PATH || 'styles';
window.CSS_PATH = window.CSS_PATH || 'styles';
window.OPEN_FORM = window.OPEN_FORM || 'open.html';
// Sets the base path, the UI language via URL param and configures the
// supported languages to avoid 404s. The loading of all core language
// resources is disabled as all required resources are in grapheditor.
// properties. Note that in this example the loading of two resource
// files (the special bundle and the default bundle) is disabled to
// save a GET request. This requires that all resources be present in
// each properties file since only one file is loaded.
window.mxBasePath = window.mxBasePath || '../../../src';
window.mxLanguage = window.mxLanguage || urlParams['lang'];
window.mxLanguages = window.mxLanguages || ['de','zh'];

1315
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Menus.js

File diff suppressed because it is too large

3879
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Shapes.js

File diff suppressed because it is too large

3602
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Sidebar.js

File diff suppressed because it is too large

954
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/js/Toolbar.js

@ -0,0 +1,954 @@
/**
* Copyright (c) 2006-2012, JGraph Ltd
*/
/**
* Construcs a new toolbar for the given editor.
*/
function Toolbar(editorUi, container)
{
this.editorUi = editorUi;
this.container = container;
this.staticElements = [];
this.init();
// Global handler to hide the current menu
this.gestureHandler = mxUtils.bind(this, function(evt)
{
if (this.editorUi.currentMenu != null && mxEvent.getSource(evt) != this.editorUi.currentMenu.div)
{
this.hideMenu();
}
});
mxEvent.addGestureListeners(document, this.gestureHandler);
};
/**
* Image for the dropdown arrow.
*/
Toolbar.prototype.dropdownImage = (!mxClient.IS_SVG) ? IMAGE_PATH + '/dropdown.gif' : 'data:image/gif;base64,R0lGODlhDQANAIABAHt7e////yH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCREM1NkJFMjE0NEMxMUU1ODk1Q0M5MjQ0MTA4QjNDMSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCREM1NkJFMzE0NEMxMUU1ODk1Q0M5MjQ0MTA4QjNDMSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkQzOUMzMjZCMTQ0QjExRTU4OTVDQzkyNDQxMDhCM0MxIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkQzOUMzMjZDMTQ0QjExRTU4OTVDQzkyNDQxMDhCM0MxIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAAIfkEAQAAAQAsAAAAAA0ADQAAAhGMj6nL3QAjVHIu6azbvPtWAAA7';
/**
* Image element for the dropdown arrow.
*/
Toolbar.prototype.dropdownImageHtml = '<img border="0" style="position:absolute;right:4px;top:' +
((!EditorUi.compactUi) ? 8 : 6) + 'px;" src="' + Toolbar.prototype.dropdownImage + '" valign="middle"/>';
/**
* Defines the background for selected buttons.
*/
Toolbar.prototype.selectedBackground = '#d0d0d0';
/**
* Defines the background for selected buttons.
*/
Toolbar.prototype.unselectedBackground = 'none';
/**
* Array that contains the DOM nodes that should never be removed.
*/
Toolbar.prototype.staticElements = null;
/**
* Adds the toolbar elements.
*/
Toolbar.prototype.init = function()
{
var sw = screen.width;
// Takes into account initial compact mode
sw -= (screen.height > 740) ? 56 : 0;
if (sw >= 700)
{
var formatMenu = this.addMenu('', mxResources.get('view') + ' (' + mxResources.get('panTooltip') + ')', true, 'viewPanels', null, true);
this.addDropDownArrow(formatMenu, 'geSprite-formatpanel', 38, 50, -4, -3, 36, -8);
this.addSeparator();
}
var viewMenu = this.addMenu('', mxResources.get('zoom') + ' (Alt+Mousewheel)', true, 'viewZoom', null, true);
viewMenu.showDisabled = true;
viewMenu.style.whiteSpace = 'nowrap';
viewMenu.style.position = 'relative';
viewMenu.style.overflow = 'hidden';
if (EditorUi.compactUi)
{
viewMenu.style.width = (mxClient.IS_QUIRKS) ? '58px' : '50px';
}
else
{
viewMenu.style.width = (mxClient.IS_QUIRKS) ? '62px' : '36px';
}
if (sw >= 420)
{
this.addSeparator();
var elts = this.addItems(['zoomIn', 'zoomOut']);
elts[0].setAttribute('title', mxResources.get('zoomIn') + ' (' + this.editorUi.actions.get('zoomIn').shortcut + ')');
elts[1].setAttribute('title', mxResources.get('zoomOut') + ' (' + this.editorUi.actions.get('zoomOut').shortcut + ')');
}
// Updates the label if the scale changes
this.updateZoom = mxUtils.bind(this, function()
{
viewMenu.innerHTML = Math.round(this.editorUi.editor.graph.view.scale * 100) + '%' +
this.dropdownImageHtml;
if (EditorUi.compactUi)
{
viewMenu.getElementsByTagName('img')[0].style.right = '1px';
viewMenu.getElementsByTagName('img')[0].style.top = '5px';
}
});
this.editorUi.editor.graph.view.addListener(mxEvent.EVENT_SCALE, this.updateZoom);
this.editorUi.editor.addListener('resetGraphView', this.updateZoom);
var elts = this.addItems(['-', 'undo', 'redo']);
elts[1].setAttribute('title', mxResources.get('undo') + ' (' + this.editorUi.actions.get('undo').shortcut + ')');
elts[2].setAttribute('title', mxResources.get('redo') + ' (' + this.editorUi.actions.get('redo').shortcut + ')');
if (sw >= 320)
{
var elts = this.addItems(['-', 'delete']);
elts[1].setAttribute('title', mxResources.get('delete') + ' (' + this.editorUi.actions.get('delete').shortcut + ')');
}
if (sw >= 550)
{
this.addItems(['-', 'toFront', 'toBack']);
}
if (sw >= 740)
{
this.addItems(['-', 'fillColor']);
if (sw >= 780)
{
this.addItems(['strokeColor']);
if (sw >= 820)
{
this.addItems(['shadow']);
}
}
}
if (sw >= 400)
{
this.addSeparator();
if (sw >= 440)
{
this.edgeShapeMenu = this.addMenuFunction('', mxResources.get('connection'), false, mxUtils.bind(this, function(menu)
{
this.editorUi.menus.edgeStyleChange(menu, '', [mxConstants.STYLE_SHAPE, 'width'], [null, null], 'geIcon geSprite geSprite-connection', null, true).setAttribute('title', mxResources.get('line'));
this.editorUi.menus.edgeStyleChange(menu, '', [mxConstants.STYLE_SHAPE, 'width'], ['link', null], 'geIcon geSprite geSprite-linkedge', null, true).setAttribute('title', mxResources.get('link'));
this.editorUi.menus.edgeStyleChange(menu, '', [mxConstants.STYLE_SHAPE, 'width'], ['flexArrow', null], 'geIcon geSprite geSprite-arrow', null, true).setAttribute('title', mxResources.get('arrow'));
this.editorUi.menus.edgeStyleChange(menu, '', [mxConstants.STYLE_SHAPE, 'width'], ['arrow', null], 'geIcon geSprite geSprite-simplearrow', null, true).setAttribute('title', mxResources.get('simpleArrow'));
}));
this.addDropDownArrow(this.edgeShapeMenu, 'geSprite-connection', 44, 50, 0, 0, 22, -4);
}
this.edgeStyleMenu = this.addMenuFunction('geSprite-orthogonal', mxResources.get('waypoints'), false, mxUtils.bind(this, function(menu)
{
this.editorUi.menus.edgeStyleChange(menu, '', [mxConstants.STYLE_EDGE, mxConstants.STYLE_CURVED, mxConstants.STYLE_NOEDGESTYLE], [null, null, null], 'geIcon geSprite geSprite-straight', null, true).setAttribute('title', mxResources.get('straight'));
this.editorUi.menus.edgeStyleChange(menu, '', [mxConstants.STYLE_EDGE, mxConstants.STYLE_CURVED, mxConstants.STYLE_NOEDGESTYLE], ['orthogonalEdgeStyle', null, null], 'geIcon geSprite geSprite-orthogonal', null, true).setAttribute('title', mxResources.get('orthogonal'));
this.editorUi.menus.edgeStyleChange(menu, '', [mxConstants.STYLE_EDGE, mxConstants.STYLE_ELBOW, mxConstants.STYLE_CURVED, mxConstants.STYLE_NOEDGESTYLE], ['elbowEdgeStyle', null, null, null], 'geIcon geSprite geSprite-horizontalelbow', null, true).setAttribute('title', mxResources.get('simple'));
this.editorUi.menus.edgeStyleChange(menu, '', [mxConstants.STYLE_EDGE, mxConstants.STYLE_ELBOW, mxConstants.STYLE_CURVED, mxConstants.STYLE_NOEDGESTYLE], ['elbowEdgeStyle', 'vertical', null, null], 'geIcon geSprite geSprite-verticalelbow', null, true).setAttribute('title', mxResources.get('simple'));
this.editorUi.menus.edgeStyleChange(menu, '', [mxConstants.STYLE_EDGE, mxConstants.STYLE_ELBOW, mxConstants.STYLE_CURVED, mxConstants.STYLE_NOEDGESTYLE], ['isometricEdgeStyle', null, null, null], 'geIcon geSprite geSprite-horizontalisometric', null, true).setAttribute('title', mxResources.get('isometric'));
this.editorUi.menus.edgeStyleChange(menu, '', [mxConstants.STYLE_EDGE, mxConstants.STYLE_ELBOW, mxConstants.STYLE_CURVED, mxConstants.STYLE_NOEDGESTYLE], ['isometricEdgeStyle', 'vertical', null, null], 'geIcon geSprite geSprite-verticalisometric', null, true).setAttribute('title', mxResources.get('isometric'));
this.editorUi.menus.edgeStyleChange(menu, '', [mxConstants.STYLE_EDGE, mxConstants.STYLE_CURVED, mxConstants.STYLE_NOEDGESTYLE], ['orthogonalEdgeStyle', '1', null], 'geIcon geSprite geSprite-curved', null, true).setAttribute('title', mxResources.get('curved'));
this.editorUi.menus.edgeStyleChange(menu, '', [mxConstants.STYLE_EDGE, mxConstants.STYLE_CURVED, mxConstants.STYLE_NOEDGESTYLE], ['entityRelationEdgeStyle', null, null], 'geIcon geSprite geSprite-entity', null, true).setAttribute('title', mxResources.get('entityRelation'));
}));
this.addDropDownArrow(this.edgeStyleMenu, 'geSprite-orthogonal', 44, 50, 0, 0, 22, -4);
}
this.addSeparator();
var insertMenu = this.addMenu('', mxResources.get('insert') + ' (' + mxResources.get('doubleClickTooltip') + ')', true, 'insert', null, true);
this.addDropDownArrow(insertMenu, 'geSprite-plus', 38, 48, -4, -3, 36, -8);
};
/**
* Adds the toolbar elements.
*/
Toolbar.prototype.addDropDownArrow = function(menu, sprite, width, atlasWidth, left, top, atlasDelta, atlasLeft)
{
atlasDelta = (atlasDelta != null) ? atlasDelta : 32;
left = (EditorUi.compactUi) ? left : atlasLeft;
menu.style.whiteSpace = 'nowrap';
menu.style.overflow = 'hidden';
menu.style.position = 'relative';
menu.innerHTML = '<div class="geSprite ' + sprite + '" style="margin-left:' + left + 'px;margin-top:' + top + 'px;"></div>' +
this.dropdownImageHtml;
menu.style.width = (mxClient.IS_QUIRKS) ? atlasWidth + 'px' : (atlasWidth - atlasDelta) + 'px';
if (mxClient.IS_QUIRKS)
{
menu.style.height = (EditorUi.compactUi) ? '24px' : '26px';
}
// Fix for item size in kennedy theme
if (EditorUi.compactUi)
{
menu.getElementsByTagName('img')[0].style.left = '24px';
menu.getElementsByTagName('img')[0].style.top = '5px';
menu.style.width = (mxClient.IS_QUIRKS) ? width + 'px' : (width - 10) + 'px';
}
};
/**
* Sets the current font name.
*/
Toolbar.prototype.setFontName = function(value)
{
if (this.fontMenu != null)
{
this.fontMenu.innerHTML = '<div style="width:60px;overflow:hidden;display:inline-block;">' +
mxUtils.htmlEntities(value) + '</div>' + this.dropdownImageHtml;
}
};
/**
* Sets the current font name.
*/
Toolbar.prototype.setFontSize = function(value)
{
if (this.sizeMenu != null)
{
this.sizeMenu.innerHTML = '<div style="width:24px;overflow:hidden;display:inline-block;">' +
value + '</div>' + this.dropdownImageHtml;
}
};
/**
* Hides the current menu.
*/
Toolbar.prototype.createTextToolbar = function()
{
var graph = this.editorUi.editor.graph;
var styleElt = this.addMenu('', mxResources.get('style'), true, 'formatBlock');
styleElt.style.position = 'relative';
styleElt.style.whiteSpace = 'nowrap';
styleElt.style.overflow = 'hidden';
styleElt.innerHTML = mxResources.get('style') + this.dropdownImageHtml;
if (EditorUi.compactUi)
{
styleElt.style.paddingRight = '18px';
styleElt.getElementsByTagName('img')[0].style.right = '1px';
styleElt.getElementsByTagName('img')[0].style.top = '5px';
}
this.addSeparator();
this.fontMenu = this.addMenu('', mxResources.get('fontFamily'), true, 'fontFamily');
this.fontMenu.style.position = 'relative';
this.fontMenu.style.whiteSpace = 'nowrap';
this.fontMenu.style.overflow = 'hidden';
this.fontMenu.style.width = (mxClient.IS_QUIRKS) ? '80px' : '60px';
this.setFontName(Menus.prototype.defaultFont);
if (EditorUi.compactUi)
{
this.fontMenu.style.paddingRight = '18px';
this.fontMenu.getElementsByTagName('img')[0].style.right = '1px';
this.fontMenu.getElementsByTagName('img')[0].style.top = '5px';
}
this.addSeparator();
this.sizeMenu = this.addMenu(Menus.prototype.defaultFontSize, mxResources.get('fontSize'), true, 'fontSize');
this.sizeMenu.style.position = 'relative';
this.sizeMenu.style.whiteSpace = 'nowrap';
this.sizeMenu.style.overflow = 'hidden';
this.sizeMenu.style.width = (mxClient.IS_QUIRKS) ? '44px' : '24px';
this.setFontSize(Menus.prototype.defaultFontSize);
if (EditorUi.compactUi)
{
this.sizeMenu.style.paddingRight = '18px';
this.sizeMenu.getElementsByTagName('img')[0].style.right = '1px';
this.sizeMenu.getElementsByTagName('img')[0].style.top = '5px';
}
var elts = this.addItems(['-', 'undo', 'redo','-', 'bold', 'italic', 'underline']);
elts[1].setAttribute('title', mxResources.get('undo') + ' (' + this.editorUi.actions.get('undo').shortcut + ')');
elts[2].setAttribute('title', mxResources.get('redo') + ' (' + this.editorUi.actions.get('redo').shortcut + ')');
elts[4].setAttribute('title', mxResources.get('bold') + ' (' + this.editorUi.actions.get('bold').shortcut + ')');
elts[5].setAttribute('title', mxResources.get('italic') + ' (' + this.editorUi.actions.get('italic').shortcut + ')');
elts[6].setAttribute('title', mxResources.get('underline') + ' (' + this.editorUi.actions.get('underline').shortcut + ')');
// KNOWN: Lost focus after click on submenu with text (not icon) in quirks and IE8. This is because the TD seems
// to catch the focus on click in these browsers. NOTE: Workaround in mxPopupMenu for icon items (without text).
var alignMenu = this.addMenuFunction('', mxResources.get('align'), false, mxUtils.bind(this, function(menu)
{
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
document.execCommand('justifyleft', false, null);
}), null, 'geIcon geSprite geSprite-left');
elt.setAttribute('title', mxResources.get('left'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
document.execCommand('justifycenter', false, null);
}), null, 'geIcon geSprite geSprite-center');
elt.setAttribute('title', mxResources.get('center'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
document.execCommand('justifyright', false, null);
}), null, 'geIcon geSprite geSprite-right');
elt.setAttribute('title', mxResources.get('right'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
document.execCommand('justifyfull', false, null);
}), null, 'geIcon geSprite geSprite-justifyfull');
elt.setAttribute('title', mxResources.get('justifyfull'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
document.execCommand('insertorderedlist', false, null);
}), null, 'geIcon geSprite geSprite-orderedlist');
elt.setAttribute('title', mxResources.get('numberedList'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
document.execCommand('insertunorderedlist', false, null);
}), null, 'geIcon geSprite geSprite-unorderedlist');
elt.setAttribute('title', mxResources.get('bulletedList'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
document.execCommand('outdent', false, null);
}), null, 'geIcon geSprite geSprite-outdent');
elt.setAttribute('title', mxResources.get('decreaseIndent'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
document.execCommand('indent', false, null);
}), null, 'geIcon geSprite geSprite-indent');
elt.setAttribute('title', mxResources.get('increaseIndent'));
}));
alignMenu.style.position = 'relative';
alignMenu.style.whiteSpace = 'nowrap';
alignMenu.style.overflow = 'hidden';
alignMenu.innerHTML = '<div class="geSprite geSprite-left" style="margin-left:-2px;"></div>' + this.dropdownImageHtml;
alignMenu.style.width = (mxClient.IS_QUIRKS) ? '50px' : '30px';
if (EditorUi.compactUi)
{
alignMenu.getElementsByTagName('img')[0].style.left = '22px';
alignMenu.getElementsByTagName('img')[0].style.top = '5px';
}
var formatMenu = this.addMenuFunction('', mxResources.get('format'), false, mxUtils.bind(this, function(menu)
{
elt = menu.addItem('', null, this.editorUi.actions.get('subscript').funct,
null, 'geIcon geSprite geSprite-subscript');
elt.setAttribute('title', mxResources.get('subscript') + ' (' + Editor.ctrlKey + '+,)');
elt = menu.addItem('', null, this.editorUi.actions.get('superscript').funct,
null, 'geIcon geSprite geSprite-superscript');
elt.setAttribute('title', mxResources.get('superscript') + ' (' + Editor.ctrlKey + '+.)');
// KNOWN: IE+FF don't return keyboard focus after color dialog (calling focus doesn't help)
elt = menu.addItem('', null, this.editorUi.actions.get('fontColor').funct,
null, 'geIcon geSprite geSprite-fontcolor');
elt.setAttribute('title', mxResources.get('fontColor'));
elt = menu.addItem('', null, this.editorUi.actions.get('backgroundColor').funct,
null, 'geIcon geSprite geSprite-fontbackground');
elt.setAttribute('title', mxResources.get('backgroundColor'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
document.execCommand('removeformat', false, null);
}), null, 'geIcon geSprite geSprite-removeformat');
elt.setAttribute('title', mxResources.get('removeFormat'));
}));
formatMenu.style.position = 'relative';
formatMenu.style.whiteSpace = 'nowrap';
formatMenu.style.overflow = 'hidden';
formatMenu.innerHTML = '<div class="geSprite geSprite-dots" style="margin-left:-2px;"></div>' +
this.dropdownImageHtml;
formatMenu.style.width = (mxClient.IS_QUIRKS) ? '50px' : '30px';
if (EditorUi.compactUi)
{
formatMenu.getElementsByTagName('img')[0].style.left = '22px';
formatMenu.getElementsByTagName('img')[0].style.top = '5px';
}
this.addSeparator();
this.addButton('geIcon geSprite geSprite-code', mxResources.get('html'), function()
{
graph.cellEditor.toggleViewMode();
if (graph.cellEditor.textarea.innerHTML.length > 0 && (graph.cellEditor.textarea.innerHTML != '&nbsp;' || !graph.cellEditor.clearOnChange))
{
window.setTimeout(function()
{
document.execCommand('selectAll', false, null);
});
}
});
this.addSeparator();
// FIXME: Uses geButton here and geLabel in main menu
var insertMenu = this.addMenuFunction('', mxResources.get('insert'), true, mxUtils.bind(this, function(menu)
{
menu.addItem(mxResources.get('insertLink'), null, mxUtils.bind(this, function()
{
this.editorUi.actions.get('link').funct();
}));
menu.addItem(mxResources.get('insertImage'), null, mxUtils.bind(this, function()
{
this.editorUi.actions.get('image').funct();
}));
menu.addItem(mxResources.get('insertHorizontalRule'), null, mxUtils.bind(this, function()
{
document.execCommand('inserthorizontalrule', false, null);
}));
}));
insertMenu.style.whiteSpace = 'nowrap';
insertMenu.style.overflow = 'hidden';
insertMenu.style.position = 'relative';
insertMenu.innerHTML = '<div class="geSprite geSprite-plus" style="margin-left:-4px;margin-top:-3px;"></div>' +
this.dropdownImageHtml;
insertMenu.style.width = (mxClient.IS_QUIRKS) ? '36px' : '16px';
// Fix for item size in kennedy theme
if (EditorUi.compactUi)
{
insertMenu.getElementsByTagName('img')[0].style.left = '24px';
insertMenu.getElementsByTagName('img')[0].style.top = '5px';
insertMenu.style.width = (mxClient.IS_QUIRKS) ? '50px' : '30px';
}
this.addSeparator();
// KNOWN: All table stuff does not work with undo/redo
// KNOWN: Lost focus after click on submenu with text (not icon) in quirks and IE8. This is because the TD seems
// to catch the focus on click in these browsers. NOTE: Workaround in mxPopupMenu for icon items (without text).
var elt = this.addMenuFunction('geIcon geSprite geSprite-table', mxResources.get('table'), false, mxUtils.bind(this, function(menu)
{
var elt = graph.getSelectedElement();
var cell = graph.getParentByName(elt, 'TD', graph.cellEditor.text2);
var row = graph.getParentByName(elt, 'TR', graph.cellEditor.text2);
if (row == null)
{
this.editorUi.menus.addInsertTableItem(menu);
}
else
{
var table = graph.getParentByName(row, 'TABLE', graph.cellEditor.text2);
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
try
{
graph.selectNode(graph.insertColumn(table, (cell != null) ? cell.cellIndex : 0));
}
catch (e)
{
mxUtils.alert(mxResources.get('error') + ': ' + e.message);
}
}), null, 'geIcon geSprite geSprite-insertcolumnbefore');
elt.setAttribute('title', mxResources.get('insertColumnBefore'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
try
{
graph.selectNode(graph.insertColumn(table, (cell != null) ? cell.cellIndex + 1 : -1));
}
catch (e)
{
mxUtils.alert(mxResources.get('error') + ': ' + e.message);
}
}), null, 'geIcon geSprite geSprite-insertcolumnafter');
elt.setAttribute('title', mxResources.get('insertColumnAfter'));
elt = menu.addItem('Delete column', null, mxUtils.bind(this, function()
{
if (cell != null)
{
try
{
graph.deleteColumn(table, cell.cellIndex);
}
catch (e)
{
mxUtils.alert(mxResources.get('error') + ': ' + e.message);
}
}
}), null, 'geIcon geSprite geSprite-deletecolumn');
elt.setAttribute('title', mxResources.get('deleteColumn'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
try
{
graph.selectNode(graph.insertRow(table, row.sectionRowIndex));
}
catch (e)
{
mxUtils.alert(mxResources.get('error') + ': ' + e.message);
}
}), null, 'geIcon geSprite geSprite-insertrowbefore');
elt.setAttribute('title', mxResources.get('insertRowBefore'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
try
{
graph.selectNode(graph.insertRow(table, row.sectionRowIndex + 1));
}
catch (e)
{
mxUtils.alert(mxResources.get('error') + ': ' + e.message);
}
}), null, 'geIcon geSprite geSprite-insertrowafter');
elt.setAttribute('title', mxResources.get('insertRowAfter'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
try
{
graph.deleteRow(table, row.sectionRowIndex);
}
catch (e)
{
mxUtils.alert(mxResources.get('error') + ': ' + e.message);
}
}), null, 'geIcon geSprite geSprite-deleterow');
elt.setAttribute('title', mxResources.get('deleteRow'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
// Converts rgb(r,g,b) values
var color = table.style.borderColor.replace(
/\brgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/g,
function($0, $1, $2, $3) {
return "#" + ("0"+Number($1).toString(16)).substr(-2) + ("0"+Number($2).toString(16)).substr(-2) + ("0"+Number($3).toString(16)).substr(-2);
});
this.editorUi.pickColor(color, function(newColor)
{
if (newColor == null || newColor == mxConstants.NONE)
{
table.removeAttribute('border');
table.style.border = '';
table.style.borderCollapse = '';
}
else
{
table.setAttribute('border', '1');
table.style.border = '1px solid ' + newColor;
table.style.borderCollapse = 'collapse';
}
});
}), null, 'geIcon geSprite geSprite-strokecolor');
elt.setAttribute('title', mxResources.get('borderColor'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
// Converts rgb(r,g,b) values
var color = table.style.backgroundColor.replace(
/\brgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/g,
function($0, $1, $2, $3) {
return "#" + ("0"+Number($1).toString(16)).substr(-2) + ("0"+Number($2).toString(16)).substr(-2) + ("0"+Number($3).toString(16)).substr(-2);
});
this.editorUi.pickColor(color, function(newColor)
{
if (newColor == null || newColor == mxConstants.NONE)
{
table.style.backgroundColor = '';
}
else
{
table.style.backgroundColor = newColor;
}
});
}), null, 'geIcon geSprite geSprite-fillcolor');
elt.setAttribute('title', mxResources.get('backgroundColor'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
var value = table.getAttribute('cellPadding') || 0;
var dlg = new FilenameDialog(this.editorUi, value, mxResources.get('apply'), mxUtils.bind(this, function(newValue)
{
if (newValue != null && newValue.length > 0)
{
table.setAttribute('cellPadding', newValue);
}
else
{
table.removeAttribute('cellPadding');
}
}), mxResources.get('spacing'));
this.editorUi.showDialog(dlg.container, 300, 80, true, true);
dlg.init();
}), null, 'geIcon geSprite geSprite-fit');
elt.setAttribute('title', mxResources.get('spacing'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
table.setAttribute('align', 'left');
}), null, 'geIcon geSprite geSprite-left');
elt.setAttribute('title', mxResources.get('left'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
table.setAttribute('align', 'center');
}), null, 'geIcon geSprite geSprite-center');
elt.setAttribute('title', mxResources.get('center'));
elt = menu.addItem('', null, mxUtils.bind(this, function()
{
table.setAttribute('align', 'right');
}), null, 'geIcon geSprite geSprite-right');
elt.setAttribute('title', mxResources.get('right'));
}
}));
elt.style.position = 'relative';
elt.style.whiteSpace = 'nowrap';
elt.style.overflow = 'hidden';
elt.innerHTML = '<div class="geSprite geSprite-table" style="margin-left:-2px;"></div>' + this.dropdownImageHtml;
elt.style.width = (mxClient.IS_QUIRKS) ? '50px' : '30px';
// Fix for item size in kennedy theme
if (EditorUi.compactUi)
{
elt.getElementsByTagName('img')[0].style.left = '22px';
elt.getElementsByTagName('img')[0].style.top = '5px';
}
};
/**
* Hides the current menu.
*/
Toolbar.prototype.hideMenu = function()
{
this.editorUi.hideCurrentMenu();
};
/**
* Adds a label to the toolbar.
*/
Toolbar.prototype.addMenu = function(label, tooltip, showLabels, name, c, showAll)
{
var menu = this.editorUi.menus.get(name);
var elt = this.addMenuFunction(label, tooltip, showLabels, function()
{
menu.funct.apply(menu, arguments);
}, c, showAll);
menu.addListener('stateChanged', function()
{
elt.setEnabled(menu.enabled);
});
return elt;
};
/**
* Adds a label to the toolbar.
*/
Toolbar.prototype.addMenuFunction = function(label, tooltip, showLabels, funct, c, showAll)
{
return this.addMenuFunctionInContainer((c != null) ? c : this.container, label, tooltip, showLabels, funct, showAll);
};
/**
* Adds a label to the toolbar.
*/
Toolbar.prototype.addMenuFunctionInContainer = function(container, label, tooltip, showLabels, funct, showAll)
{
var elt = (showLabels) ? this.createLabel(label) : this.createButton(label);
this.initElement(elt, tooltip);
this.addMenuHandler(elt, showLabels, funct, showAll);
container.appendChild(elt);
return elt;
};
/**
* Adds a separator to the separator.
*/
Toolbar.prototype.addSeparator = function(c)
{
c = (c != null) ? c : this.container;
var elt = document.createElement('div');
elt.className = 'geSeparator';
c.appendChild(elt);
return elt;
};
/**
* Adds given action item
*/
Toolbar.prototype.addItems = function(keys, c, ignoreDisabled)
{
var items = [];
for (var i = 0; i < keys.length; i++)
{
var key = keys[i];
if (key == '-')
{
items.push(this.addSeparator(c));
}
else
{
items.push(this.addItem('geSprite-' + key.toLowerCase(), key, c, ignoreDisabled));
}
}
return items;
};
/**
* Adds given action item
*/
Toolbar.prototype.addItem = function(sprite, key, c, ignoreDisabled)
{
var action = this.editorUi.actions.get(key);
var elt = null;
if (action != null)
{
var tooltip = action.label;
if (action.shortcut != null)
{
tooltip += ' (' + action.shortcut + ')';
}
elt = this.addButton(sprite, tooltip, action.funct, c);
if (!ignoreDisabled)
{
elt.setEnabled(action.enabled);
action.addListener('stateChanged', function()
{
elt.setEnabled(action.enabled);
});
}
}
return elt;
};
/**
* Adds a button to the toolbar.
*/
Toolbar.prototype.addButton = function(classname, tooltip, funct, c)
{
var elt = this.createButton(classname);
c = (c != null) ? c : this.container;
this.initElement(elt, tooltip);
this.addClickHandler(elt, funct);
c.appendChild(elt);
return elt;
};
/**
* Initializes the given toolbar element.
*/
Toolbar.prototype.initElement = function(elt, tooltip)
{
// Adds tooltip
if (tooltip != null)
{
elt.setAttribute('title', tooltip);
}
this.addEnabledState(elt);
};
/**
* Adds enabled state with setter to DOM node (avoids JS wrapper).
*/
Toolbar.prototype.addEnabledState = function(elt)
{
var classname = elt.className;
elt.setEnabled = function(value)
{
elt.enabled = value;
if (value)
{
elt.className = classname;
}
else
{
elt.className = classname + ' mxDisabled';
}
};
elt.setEnabled(true);
};
/**
* Adds enabled state with setter to DOM node (avoids JS wrapper).
*/
Toolbar.prototype.addClickHandler = function(elt, funct)
{
if (funct != null)
{
mxEvent.addListener(elt, 'click', function(evt)
{
if (elt.enabled)
{
funct(evt);
}
mxEvent.consume(evt);
});
if (document.documentMode != null && document.documentMode >= 9)
{
// Prevents focus
mxEvent.addListener(elt, 'mousedown', function(evt)
{
evt.preventDefault();
});
}
}
};
/**
* Creates and returns a new button.
*/
Toolbar.prototype.createButton = function(classname)
{
var elt = document.createElement('a');
elt.setAttribute('href', 'javascript:void(0);');
elt.className = 'geButton';
var inner = document.createElement('div');
if (classname != null)
{
inner.className = 'geSprite ' + classname;
}
elt.appendChild(inner);
return elt;
};
/**
* Creates and returns a new button.
*/
Toolbar.prototype.createLabel = function(label, tooltip)
{
var elt = document.createElement('a');
elt.setAttribute('href', 'javascript:void(0);');
elt.className = 'geLabel';
mxUtils.write(elt, label);
return elt;
};
/**
* Adds a handler for showing a menu in the given element.
*/
Toolbar.prototype.addMenuHandler = function(elt, showLabels, funct, showAll)
{
if (funct != null)
{
var graph = this.editorUi.editor.graph;
var menu = null;
var show = true;
mxEvent.addListener(elt, 'click', mxUtils.bind(this, function(evt)
{
if (show && (elt.enabled == null || elt.enabled))
{
graph.popupMenuHandler.hideMenu();
menu = new mxPopupMenu(funct);
menu.div.className += ' geToolbarMenu';
menu.showDisabled = showAll;
menu.labels = showLabels;
menu.autoExpand = true;
var offset = mxUtils.getOffset(elt);
menu.popup(offset.x, offset.y + elt.offsetHeight, null, evt);
this.editorUi.setCurrentMenu(menu, elt);
// Workaround for scrollbar hiding menu items
if (!showLabels && menu.div.scrollHeight > menu.div.clientHeight)
{
menu.div.style.width = '40px';
}
menu.hideMenu = mxUtils.bind(this, function()
{
mxPopupMenu.prototype.hideMenu.apply(menu, arguments);
this.editorUi.resetCurrentMenu();
menu.destroy();
});
// Extends destroy to reset global state
menu.addListener(mxEvent.EVENT_HIDE, mxUtils.bind(this, function()
{
this.currentElt = null;
}));
}
show = true;
mxEvent.consume(evt);
}));
// Hides menu if already showing
mxEvent.addListener(elt, 'mousedown', mxUtils.bind(this, function(evt)
{
show = this.currentElt != elt;
// Prevents focus
if (document.documentMode != null && document.documentMode >= 9)
{
evt.preventDefault();
}
}));
}
};
/**
* Adds a handler for showing a menu in the given element.
*/
Toolbar.prototype.destroy = function()
{
if (this.gestureHandler != null)
{
mxEvent.removeGestureListeners(document, this.gestureHandler);
this.gestureHandler = null;
}
};

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/jscolor/arrow.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 B

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/jscolor/cross.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 B

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/jscolor/hs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
io.sc.engine.rule.server/src/main/resources/static/tools/graph-editor/jscolor/hv.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

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

Loading…
Cancel
Save