Browse Source

Merge pull request #1 in DEC/decision-webui-dcm from dev to master

* commit 'f4511e1c2d1f3960037f6e45689d4b6cec25739a': (26 commits)
  feat: add dom ready
  feat: 升级到最新的finui
  feat: 添加关闭按钮
  feat: 插件连接池页面可配置
  fix: 修复插件数据连接重名的bug
  feat: 完成redis插件连接的demo
  feat: 更新插件接口
  feat: 提供插件接口已便于拓展开发
  style: 调整代码结构
  fix: 修复复制数据连接时的bug
  fix: 修复删除数据连接的bug
  feat: 优化成功和失败的提示,添加loading
  feat: 完成连接池状态页面
  docs: update readme
  fix: 显示多个驱动器
  feat: 更多数据连接
  feat: 优化代码
  feat: 完成数据连接的修改删除复制等功能
  feat: 完成数据连接明细显示
  feat: 完成数据库连接新增功能
  ...
master
richie 6 years ago
parent
commit
ec61e10d71
  1. 5
      .eslintignore
  2. 288
      .eslintrc.js
  3. 7
      .gitattributes
  4. 3
      .gitignore
  5. 151
      README.md
  6. 32
      package.json
  7. 325
      src/app/app.component.scss
  8. 48
      src/app/app.component.ts
  9. 5
      src/app/app.constant.ts
  10. 32
      src/app/app.model.ts
  11. 26
      src/app/link_set/left/left.component.ts
  12. 18
      src/app/link_set/left/left.service.ts
  13. 79
      src/app/link_set/left/left_item/left.item.component.ts
  14. 86
      src/app/link_set/left/left_item/left.item.icon.component.ts
  15. 51
      src/app/link_set/link-set.component.ts
  16. 195
      src/app/link_set/link-set.model.ts
  17. 26
      src/app/link_set/link-set.service.ts
  18. 61
      src/app/link_set/more/more.link.component.ts
  19. 40
      src/app/link_set/more/more.link.item.component.ts
  20. 54
      src/app/link_set/more/more.link.service.ts
  21. 37
      src/app/link_set/right/nothing.component.ts
  22. 39
      src/app/link_set/right/right.component.ts
  23. 54
      src/app/link_set/right/right_detail/right.detail.component.ts
  24. 278
      src/app/link_set/right/right_edit/right.edit.component.ts
  25. 41
      src/app/link_set/right/right_edit/right.edit.constant.ts
  26. 233
      src/app/link_set/right/right_edit/right.edit.mysql.component.ts
  27. 20
      src/app/link_set/right/right_edit/right.edit.service.ts
  28. 72
      src/app/link_set/right/right_show/right.show.component.ts
  29. 64
      src/app/link_set/right/right_title/right.title.component.ts
  30. 79
      src/app/link_set/select/select.component.ts
  31. 283
      src/app/link_set/select/select.service.ts
  32. 31
      src/app/link_status/left/left.component.ts
  33. 39
      src/app/link_status/left/left.item.component.ts
  34. 17
      src/app/link_status/left/left.model.ts
  35. 18
      src/app/link_status/left/left.service.ts
  36. 56
      src/app/link_status/link_status.component.ts
  37. 9
      src/app/link_status/link_status.model.ts
  38. 93
      src/app/link_status/right/right.card.component.ts
  39. 65
      src/app/link_status/right/right.component.ts
  40. 14
      src/app/link_status/right/right.model.ts
  41. 6
      src/app/link_status/right/right.typings.d.ts
  42. 40
      src/app/title/title.component.ts
  43. 37
      src/app/title/title_item/title_item.component.ts
  44. 11
      src/app/title/title_item/title_item.model.ts
  45. 13
      src/app/title/title_item/title_item.service.ts
  46. 97
      src/demo/plugin.redis.edit.ts
  47. 68
      src/demo/plugin.redis.preview.ts
  48. 53
      src/demo/plugin.tedis.pool.ts
  49. 3
      src/demo/style.scss
  50. BIN
      src/img/ads.jpg
  51. BIN
      src/img/amazon-redshift.jpg
  52. BIN
      src/img/apache-impala.jpg
  53. BIN
      src/img/apache-kylin.jpg
  54. BIN
      src/img/apache-phoenix.jpg
  55. BIN
      src/img/database-selected.png
  56. BIN
      src/img/derby.jpg
  57. BIN
      src/img/error.png
  58. BIN
      src/img/gbase-8a.jpg
  59. BIN
      src/img/gbase-8s.jpg
  60. BIN
      src/img/gbase-8t.jpg
  61. BIN
      src/img/h2.jpg
  62. BIN
      src/img/hadoop-hive.jpg
  63. BIN
      src/img/hbase.jpg
  64. BIN
      src/img/hp-vertica.jpg
  65. BIN
      src/img/hsql.jpg
  66. BIN
      src/img/hw-dws.jpg
  67. BIN
      src/img/hw-elk.jpg
  68. BIN
      src/img/hw-fusioninsight-hd.jpg
  69. BIN
      src/img/hw-libr-a.jpg
  70. BIN
      src/img/ibm-db2.jpg
  71. BIN
      src/img/icon_close9x9_normal.png
  72. BIN
      src/img/informix.jpg
  73. BIN
      src/img/kingbase.jpg
  74. BIN
      src/img/loading.gif
  75. BIN
      src/img/mysql.jpg
  76. BIN
      src/img/oracle.jpg
  77. BIN
      src/img/pivotal-greenplum-database.jpg
  78. BIN
      src/img/postgresql.jpg
  79. BIN
      src/img/presto.jpg
  80. BIN
      src/img/resources.png
  81. BIN
      src/img/sap-hana.jpg
  82. BIN
      src/img/sap-sybase.jpg
  83. BIN
      src/img/spark.jpg
  84. BIN
      src/img/sql-server.jpeg
  85. BIN
      src/img/sql-server.jpg
  86. BIN
      src/img/sqlite.jpg
  87. BIN
      src/img/success.png
  88. BIN
      src/img/teradata.jpg
  89. BIN
      src/img/transwarp-inceptor.jpg
  90. BIN
      src/img/warning.png
  91. 14
      src/index.html
  92. 8
      src/index.ts
  93. 1
      src/lib/fineui.min.css
  94. 41
      src/lib/fineui.min.js
  95. 28
      src/shared/components/both.side.component.ts
  96. 29
      src/shared/components/form.item.component.ts
  97. 16
      src/shared/components/title.component.ts
  98. 130
      src/shared/crud/crud.request.ts
  99. 1
      src/shared/crud/curd.mock.ts
  100. 243
      src/shared/service/dialog.service.ts
  101. Some files were not shown because too many files have changed in this diff Show More

5
.eslintignore

@ -0,0 +1,5 @@
dist/*.js
src/assets/*
src/lib/*
webpack.config.js
curd.mock.ts

288
.eslintrc.js

@ -0,0 +1,288 @@
module.exports = {
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: ['plugin:@typescript-eslint/recommended'],
rules:{
"indent": "off",
"quotes": [1, "single"],
"space-infix-ops": 2,//操作符前后有空格
// 必须使用 === 和 !== ,和 null 对比时除外
'eqeqeq': [2, 'always', { 'null': 'ignore' }],
// 函数的形参不能多于5个
'max-params': [2, 5],
// 禁止 switch 中出现相同的 case
'no-duplicate-case': 2,
// 禁止使用 var,必须用 let 或 const
'no-var': 0,
// 禁止出现空代码块
'no-empty': [2, { 'allowEmptyCatch': true }],
// 禁止空的 function
// 包含注释的情况下允许
'no-empty-function': 0,
// if 后必须包含 { ,单行 if 除外
'curly': [2, 'multi-line', 'consistent'],
// for 循环不得因方向错误造成死循环
'for-direction': 2,
// 关键字前后必须有空格
'keyword-spacing': 2,
// 最大块嵌套深度为 5 层
'max-depth': [2, 5],
// 最大回调深度为 3 层
'max-nested-callbacks': [2, 3],
// 禁止普通字符串中出现模板字符串语法
'no-template-curly-in-string': 0,
// 禁止连等赋值
'no-multi-assign': 2,
// 禁止使用连续的空格
'no-multi-spaces': 2,
// 禁止使用 \ 来定义多行字符串,统一使用模板字符串来做
'no-multi-str': 2,
// 禁止使用 new Object
'no-new-object': 2,
// 禁止使用 new require
'no-new-require': 2,
// 禁止使用 new Symbol
'no-new-symbol': 2,
// 禁止 new Boolean、Number 或 String
'no-new-wrappers': 2,
// 禁止 new 一个类而不存储该实例
'no-new': 2,
// 禁止把原生对象 Math、JSON、Reflect 当函数使用
'no-obj-calls': 2,
// 禁止使用八进制转义符
'no-octal-escape': 2,
// 禁止使用0开头的数字表示八进制
'no-octal': 2,
// 禁止使用 __dirname + 'file' 的形式拼接路径,应该使用 path.join 或 path.resolve 来代替
'no-path-concat': 2,
// 禁止对函数的参数重新赋值
'no-param-reassign': 2,
// 禁止使用保留字作为变量名
'no-shadow-restricted-names': 2,
// 禁止数组中出现连续逗号
'no-sparse-arrays': 2,
// 禁止在finally块中出现 return、throw、break、continue
'no-unsafe-finally': 2,
// 禁止出现不安全的否定,如 for (!key in obj} {},应该写为 for (!(key in obj)} {}
'no-unsafe-negation': 2,
// ...后面不允许有空格
'rest-spread-spacing': [2, 'never'],
// 注释的斜线和星号后要加空格
'spaced-comment': [2, 'always', {
'block': {
exceptions: ['*'],
balanced: true
}
}],
// typeof 判断条件只能是 "undefined", "object", "boolean", "number", "string", "function" 或 "symbol"
'valid-typeof': 2,
"@typescript-eslint/indent": ["error", 2],
"@typescript-eslint/explicit-function-return-type": ["warn", {
allowExpressions: true
}],
"@typescript-eslint/no-explicit-any": ["off"],
// 声明
"prefer-const": "error", //如果一个变量不会被重新赋值,最好使用const进行声明
"no-const-assign": "error", //不允许改变用const声明的变量
"no-var": "error", //用let/const代替var
// 对象
"no-dupe-keys": "error", // 禁止在对象字面量中出现重复的键
"no-prototype-builtins": "error", // 禁止直接使用 Object.prototypes 的内置属性
"no-extend-native": "error", // 禁止扩展原生对象
"no-new-object": "error", // 禁止使用 Object 构造函数
"object-shorthand": [
"error",
"always"
], //要求对象字面量简写语法
"quote-props": [
"error",
"as-needed"
], // 对象属性只在需要的时候加引号
// 数组
"no-sparse-arrays": "error", // 禁用稀疏数组
"no-array-constructor": "error", //禁止使用 Array 构造函数
"array-callback-return": "error", // 数组回调函数内必须返回一个状态
// 字符串
"quotes": [
"error",
"single",
{
"allowTemplateLiterals": true
}
], // 字符串开头和结束使用单引号
"prefer-template": "error", // 使用模板而非字符串连接
"template-curly-spacing": [
"error",
"never"
], // 强制模板字符串中花括号内不能出现空格
"no-path-concat": "error", // 当使用 _dirname 和 _filename 时不允许字符串拼接
"no-useless-concat": "error", // 禁止没有必要的字符拼接
"no-useless-escape": "error", // 禁用不必要的转义
// 函数
"no-dupe-args": "error", // 禁止在 function 定义中出现重复的参数
"no-new-func": "error", // 禁用Function构造函数
"no-return-assign": "error", // 禁止在返回语句中赋值
"func-style": [
"error",
"declaration",
{
"allowArrowFunctions": true
}
], // 统一函数风格为函数表达式或函数声明,并且允许使用箭头函数
"newline-before-return": "error", // 要求 return 语句之前有一空行
"wrap-iife": [
"error",
"outside"
], // 立即执行函数外部必须包裹括号
"no-loop-func": "error", // 禁止在非function内声明function
// "space-before-function-paren": "error", // 函数括号前必须要有空格
"no-param-reassign": "error", // 禁止修改函数参数
"prefer-spread": "error", // 使用解构形式代替.apply()
// 箭头函数
"prefer-arrow-callback": "error", // 回调使用箭头函数
"arrow-spacing": "error", // 箭头前后要有空格
"arrow-parens": [
"error",
"as-needed"
], // 参数使用括号包裹
"arrow-body-style": [
"error",
"as-needed",
{
"requireReturnForObjectLiteral": true
}
], // 函数体在必要的时候使用大括号
// 类 & 构造器
"no-useless-constructor": "error", // 禁止没必要的构造器
"no-dupe-class-members": "error", // 禁止重复创建类成员
// 模块
"no-duplicate-imports": "error", // 禁止从一个模块多次import
// 迭代器 & 生成器
"no-iterator": "error", // 禁止使用Iterator属性
"no-restricted-syntax": "error", // 使用对应的数组/对象方法去迭代操作成员
"generator-star-spacing": "error", // *前后不要都有空格
// 属性
"dot-notation": "error", //强制在任何允许的时候使用点号访问属性
// 变量
// "one-var": ["error", "never"], // 变量统一声明
// 比较运算符 & 相等运算符
"eqeqeq": "error", // 使用 === 和 !== 代替 == 和 !=
"no-nested-ternary": "error", // 禁止混合的三目运算符
"no-unneeded-ternary": "error", //禁止可以在有更简单的可替代的表达式时使用三元操作符
// 条件
"no-cond-assign": "error", // 禁止在条件语句中出现赋值操作符
"no-constant-condition": "error", //禁止在条件中使用常量表达式
"no-duplicate-case": "error", // 禁止在 switch 语句中的 case 子句中出现重复的测试表达式
"default-case": "error", // 要求 Switch 语句中有 Default 分支
"no-else-return": "error", // 如果 if 块中包含了一个 return 语句,else 块就成了多余的了。可以将其内容移至块外
"no-fallthrough": "error", // 禁止 case 语句落空
// 代码块
"brace-style": "error", // 代码块左括号紧跟上一行结束
"curly": [
"error",
"multi-line"
], // if、else if、else、for、while强制使用大括号,但允许在单行中省略大括号
"no-empty": [
"error",
{
"allowEmptyCatch": true
}
], // 禁止空块语句,但允许出现空的 catch 子句
// 注释
"spaced-comment": "error", // 注释前有空格
"no-mixed-spaces-and-tabs": "error", // 禁止使用 空格 和 tab 混合缩进
"space-before-blocks": [
"error",
"always"
], // 语句块之前的需要有空格
"keyword-spacing": "error", // 关键字后面必须要有空格
"space-infix-ops": [
"error",
{
"int32Hint": false
}
], // 要求中缀操作符周围有空格,设置 int32Hint 选项为 true (默认 false) 允许 a|0 不带空格
"eol-last": "error", // 要求文件末尾保留一行空行
"newline-per-chained-call": "error", // 要求方法链中每个调用都有一个换行符
"padded-blocks": [
"error",
"never"
], // 代码块开始和结束位置不可以有多余的空行
"space-in-parens": [
"error",
"never"
], // 禁止圆括号内的空格
"array-bracket-spacing": [
"error",
"never"
], // 数组紧贴括号部分不允许包含空格
"object-curly-spacing": [
"error",
"never"
], // 对象紧贴花括号部分不允许包含空格
"no-regex-spaces": "error", // 禁止正则表达式字面量中出现多个空格
"no-multi-spaces": "error", // 禁止出现多个空格而且不是用来作缩进的
"block-spacing": [
"error",
"never"
], // 单行代码块中紧贴括号部分不允许包含空格
"computed-property-spacing": [
"error",
"never"
], // 禁止括号和其内部值之间的空格
"no-trailing-spaces": [
"error",
{
"skipBlankLines": true
}
], // 禁用行尾空格
"no-spaced-func": "error", // 禁止函数调用时,与圆括号之间有空格
"space-unary-ops": "error", // 要求或禁止在一元操作符之前或之后存在空格,new、delete、typeof、void、yield要求有空格,-、+、--、++、!、!!要求无空格
"yield-star-spacing": [
"error",
{
"before": true,
"after": false
}
], // 强制 yield* 表达式中 * 号前有空格,后无空格
// 逗号
"comma-style": "error", // 逗号必须放在行末
"comma-dangle": [
"error",
"always-multiline"
], // 多行对象字面量中要求拖尾逗号
"comma-spacing": [
"error",
{
"before": false,
"after": true
}
], //在变量声明、数组字面量、对象字面量、函数参数 和 序列中禁止在逗号前使用空格,要求在逗号后使用一个或多个空格
// 分号
"semi": "error", //不得省略语句结束的分号
"semi-spacing": [
"error",
{
"before": false,
"after": true
}
], //禁止分号周围的空格
"no-extra-semi": "error", // 禁用不必要的分号
// 类型转换
"radix": "error", // 在parseInt()中始终使用基数以消除意想不到的后果
"no-extra-boolean-cast": "error", // 禁止不必要的布尔类型转换
// 其他最佳实践或规范
"strict": "error", // 使用强制模式开关use strict;
// "@typescript-eslint/no-extra-parens": ["error"],
"no-eval": "error", // 禁用 eval()
"no-with": "error", // 禁用 with 语句
"no-unexpected-multiline": "error", // 禁止使用令人困惑的多行表达式
"no-unreachable": "error", // 禁止在 return、throw、continue 和 break 语句后出现不可达代码
"no-unsafe-finally": "error", // 禁止在 finally 语句块中出现控制流语句
"valid-typeof": "error", // 强制 typeof 表达式与有效的字符串进行比较
"no-new-wrappers": "error", // 禁止通过 new 操作符使用 String、Number 和 Boolean
"handle-callback-err": "error" // 强制回调错误处理
}
}

7
.gitattributes vendored

@ -0,0 +1,7 @@
* text=auto !eol
designer_scripts/designer_scripts.iml -text
designer_scripts/src/readme.md -text
designer_scripts/src/scripts/store/web/index.html -text
designer_scripts/src/scripts/store/web/js/bridge.js -text
designer_scripts/src/scripts/store/web/js/lib/jquery-2.2.2.min.js -text
designer_scripts/src/scripts/store/web/js/store.js -text

3
.gitignore vendored

@ -0,0 +1,3 @@
node_modules
yarn.lock
dist

151
README.md

@ -0,0 +1,151 @@
# database-connection 数据连接设置页面
![start](https://img.shields.io/badge/start-2019%2F04%2F26-blue.svg) ![finui](https://img.shields.io/badge/lib-FinUi-blue.svg)
[KERNEL-493](http://www.finedevelop.com:2016/browse/KERNEL-493)
## 开始
下载代码
```
git clone ssh://git@cloud.finedevelop.com:7999/~alan/database-connection.git
```
安装依赖
```
yarn
```
开始开发
```
yarn start
```
## 接口文档
### 增加数据连接类型
使用`BI.config`,ConstantName名称为`dec.constant.database.conf.connect.list`,值为连接的名称
例如增加`Redis`的连接:
```js
BI.config(ConstantName, (datas: string[]) => [...datas, 'Redis']);
```
### 数据连接填写页面
ConstantName名称为`dec.constant.database.conf.connect.form.${name.toLowerCase()}.edit`,值为组件shortcut的名称
例如配置`Redis`的连接填写页面:
```js
const className = 'fr.plugin.redis.preview';
const RedisPreview = BI.inherit(BI.Widget, {
render() {
return {
type: 'bi.left',
cls: 'title',
items: [{
type: 'bi.editor',
watermark:'这里是编辑页',
}],
};
},
});
BI.shortcut(className, RedisPreview);
BI.constant('dec.constant.database.conf.connect.form.redis.edit', className);
```
### 数据连接预览页面
ConstantName名称为`dec.constant.database.conf.connect.form.${name.toLowerCase()}.show`,值为组件shortcut的名称
例如配置`Redis`的连接预览页面:
```js
const className = 'fr.plugin.redis.edit';
const RedisPreview = BI.inherit(BI.Widget, {
render() {
return {
type: 'bi.left',
cls: 'title',
items: [{
type: 'bi.label',
text:'这里是预览页',
}],
};
},
});
BI.shortcut(className, RedisPreview);
BI.constant('dec.constant.database.conf.connect.form.redis.edit', className);
```
### 插件配置表单值传递
ConstantName名称为`dec.constant.database.conf.connect.form.${name.toLowerCase()}.value`,值为插件数据结构
例如:
```js
const ConstantName = 'dec.constant.database.conf.connect.form.redis.value';
const form = {
url:'192.168.1.22',
port: 6379,
password: '123456'
};
BI.config(ConstantName, (data: object) => form);
```
### 数据连接池页面
ConstantName名称为`dec.constant.database.conf.connect.form.${name.toLowerCase()}.pool`,值为组件shortcut的名称
例如配置`Redis`的连接预览页面:
```js
const classNamePool = 'fr.plugin.redis.pool';
const WidgetPool = BI.inherit(BI.Widget, {
render() {
const {maxActive, maxIdle, numActive, numIdle} = this.options;
return {
type: 'bi.left',
items: [
{
type: 'bi.left',
cls: 'right-status-item',
items: [
{
type: 'bi.vertical',
cls:'right-status-board',
items: [
{
type: 'bi.vertical',
cls:'right-status-board-item',
items: [
{
type: 'bi.label',
cls: 'right-status-text',
extraCls: 'card-font1',
text: numActive,
},
{
type: 'bi.label',
cls: 'right-status-text',
text: '/',
},
{
type: 'bi.label',
cls: 'right-status-text',
text: maxActive,
},
],
},
{
type: 'bi.label',
text: 'Redis连接数',
},
],
},
],
},
],
};
},
});
BI.shortcut(classNamePool, WidgetPool);
BI.constant('dec.constant.database.conf.connect.form.redis.pool', classNamePool);
```

32
package.json

@ -0,0 +1,32 @@
{
"name": "database-connection",
"version": "1.0.0",
"description": "数据连接设置页面",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server --mode development --open",
"build": "webpack --mode production"
},
"author": "alan <alan@fanrun.com>",
"license": "ISC",
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^1.6.0",
"@typescript-eslint/parser": "^1.6.0",
"copy-webpack-plugin": "^5.0.2",
"css-loader": "^2.1.1",
"eslint": "^5.16.0",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.6.0",
"node-sass": "^4.11.0",
"path": "^0.12.7",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"ts-loader": "^5.3.3",
"typescript": "^3.4.1",
"webpack": "^4.29.6",
"webpack-cli": "^3.3.0",
"webpack-dev-server": "^3.2.1",
"webpack-stream": "^5.2.1"
}
}

325
src/app/app.component.scss

@ -0,0 +1,325 @@
.database-connection-layout{
width: 100%;
height: 100%;
background-color: #f7f8fa;
.title{
background-color: #fff;
border-bottom: 1px solid #e8eaed;
.title-item{
height: 39px;
line-height: 39px;
padding-left: 15px;
padding-right: 15px;
text-align: center;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
position: relative;
flex-shrink: 0;
font-weight: 700;
cursor: pointer;
}
.close-button {
position: absolute !important;
right: 5px;
top: 5px;
width: 30px;
height: 30px;
cursor: pointer;
background-image: url("../img/icon_close9x9_normal.png");
background-repeat: no-repeat;
background-position: center;
}
}
.linkset{
margin: 10px;
bottom: 0px;
background-color: #ffffff;
}
.linkStatus{
margin: 10px;
top: 40px;
background-color: #ffffff;
}
}
.database-left{
border-right: 1px solid #e8eaed;
.select-group{
border-bottom: 1px solid #e8eaed;
.select{
margin: 10px;
.database-link-items{
padding-left:10px;
.link-item{
border-top: 1px solid #e8eaed;
}
}
}
.status-title{
font-weight: 700;
margin-left: 12px;
margin-top: 12px;
}
}
.left-list{
margin: 10px;
.left-item{
height: 24px;
line-height: 24px;
cursor: pointer;
&:hover{
background-color: rgba(54,133,242,.05);
.icons{
.action-icon{
visibility: visible !important;
}
}
}
.icons{
float: right !important;
.action-icon{
visibility: hidden;
}
.b-font{
font-size: 16px;
}
}
}
.left-item-selected{
background-color: rgba(54,133,242,.05);
.link-title{
color: #3685f2;
}
}
}
}
.database-right{
min-width: 400px;
overflow: auto;
.bi-flex-center-adapt-layout{
height: 100%;
.data-connection-background{
background: url(../img/resources.png) center center no-repeat;
background-size: contain;
}
}
.right-status-title{
border-bottom: 1px solid #e8eaed;
color: #3d4d66;
line-height: 40px;
padding-left: 10px;
font-weight: 700;
}
.right-status-body{
margin: 10px 30px 0px 30px;
height: 50%;
.right-status-item{
height: 150px;
width: 50%;
top: 0; left: 0;
position: absolute !important;
.right-status-board { margin-left: 25px; position: relative !important; left: -25px;}
}
.right-status-right{
height: 150px;
width: 50%;
top: 0; right:0;
position: absolute !important;
.right-status-board { margin-right: 25px; position: relative !important; left: 25px; }
}
.right-status-board{
background-color: #f7f8fa;
color: #3d4d66;
width: 100%;
height: 100%;
.right-status-board-item{
text-align: center;
margin-top: 38px;
.right-status-text{
display: inline-block;
}
.card-font1{
color: #13CD66;
font-size: 32px;
}
.card-font2{
color: #3685F2;
font-size: 32px;
}
}
}
}
.right-content{
height: 100%;
.right-title{
border-bottom: 1px solid #e8eaed;
color: #3d4d66;
line-height: 40px;
padding-left: 10px;
.right-title-text{
font-weight: 700;
}
.right-title-button{
float: right !important;
margin-right: 10px;
margin-top: 8px;
}
}
.right-show{
margin: 10px;
.right-form{
width: 100%;
}
}
}
}
.both-side{
line-height: 24px;
margin-bottom: 10px;
.left{
white-space: nowrap;
text-overflow: ellipsis;
position: relative;
flex-shrink: 0;
font-weight: 700;
}
.hint{
padding-left: 5px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
position: relative;
flex-shrink: 0;
margin-left: 5px;
color: #9ea6b2;
}
}
.shared-component-title{
height: 24px;
line-height: 24px;
margin-bottom: 10px;
color: #9ea6b2;
border-bottom: 1px solid #e8eaed;
}
.comfirm-content{
margin-top: 40px;
margin-left: 20px;
.comfirm-icon{
background-image: url("../img/warning.png");
background-size: contain;
margin-right: 12px;
}
.bi-text{
height: 50px;
line-height: 50px;
margin-left: 12px;
}
}
.more-link{
.more-link-item{
width: 538px;
overflow: hidden auto;
left: -10px !important;
right: 0px;
top: 10px;
bottom: 0px;
position: absolute;
height: 380px;
.link-item{
margin-left: 10px;
margin-bottom: 10px;
cursor: pointer;
border: solid 1px #fff;
&:hover{
border: solid 1px #3480f2;
}
.selected{
position: absolute !important;
right: -1px;
top: -1px;
height: 30px;
width: 30px;
background: url(../img/database-selected.png) center center no-repeat;
background-size: contain;
}
.text{
height: 27px;
line-height: 27px;
padding-left: 2px;
padding-right: 2px;
text-align: center;
white-space: nowrap;
background: #F0F3F7;
}
}
}
}
.popover-notitle{
.bi-header-background{
display: none;
}
.bi-absolute-layout{
top:0px !important;
}
}
.bi-custom-show{
.show-content{
text-align: center;
.loading-icon{
display: block;
background: url(../img/loading.gif) center center no-repeat;
background-size: contain;
margin: 0 auto;
margin-bottom: 18px;
}
.success-icon{
display: block;
background: url(../img/success.png) center center no-repeat;
background-size: contain;
margin: 0 auto;
margin-bottom: 18px;
}
.error-icon{
display: block;
background: url(../img/error.png) center center no-repeat;
background-size: contain;
margin: 0 auto;
margin-bottom: 18px;
}
.buttons{
margin-top: 18px;
div{
margin: 0 4px;
}
}
}
.show-more{
text-align: left !important;
height: 73px;
background: #F2F4F7;
margin-bottom: 10px;
padding: 5px;
margin-top: 10px;
}
}
.link-font .b-font:before {
content: "\e759";
color: inherit;
}
.link-text-font .b-font:before {
content: "\e763";
color: inherit;
}
.info-font .b-font:before {
content: "\e63c";
color: inherit;
}
.delete-font .b-font:before {
content: "\e6c4";
color: inherit;
}

48
src/app/app.component.ts

@ -0,0 +1,48 @@
import {Vtape} from '../ui/index';
import {LinkType} from '@ui/type';
import appModel from './app.model';
import title from './title/title.component';
import linkSet from './link_set/link-set.component';
import linkStatus from './link_status/link_status.component';
import '../demo/plugin.redis.edit';
import '../demo/plugin.redis.preview';
import '../demo/plugin.tedis.pool';
import {fetchLinkList} from '../shared/crud/crud.request';
import './app.component.scss';
const className = 'fr.main';
const Widget = BI.inherit(BI.Widget, {
_store() {
return BI.Models.getModel(appModel);
},
render() {
return {
type: Vtape,
cls: 'database-connection-layout',
items: [{
el: {
type: title,
},
height: 40,
},
{
type:linkSet,
},
{
type: linkStatus,
},
],
};
},
mounted() {
/**
*
*/
fetchLinkList((linkList: LinkType[]) => {
this.store.setLinkList(linkList);
});
},
});
BI.shortcut(className, Widget);
export default className;

5
src/app/app.constant.ts

@ -0,0 +1,5 @@
export const ConstantName = 'dec.constant.database.conf.connect.list';
export const links = ['APACHE KYLIN', 'DERBY', 'HP Vertica', 'IBM DB2', 'INFORMIX', 'Microsoft SQL Server', 'MySQL', 'Oracle', 'Privotal Greenplum Database', 'Postgresql', 'GaussDB 200'];
BI.constant(ConstantName, [
]);
export default ConstantName;

32
src/app/app.model.ts

@ -0,0 +1,32 @@
const className = 'fr.model.main';
import {ModelType} from '@ui';
import {LinkType} from '@ui/type';
const linkList: LinkType[] = [];
const Model: ModelType = {
childContext: ['tab', 'linkList', 'linkSelected', 'linkUpdate', 'moreLinkSelected', 'statusSelected', 'connectionNameErr'],
state () {
return {
tab: '数据连接管理',
linkList,
linkSelected: {},
linkUpdate: {},
moreLinkSelected:'',
statusSelected:'',
connectionNameErr:'',
};
},
computed: {
},
actions: {
setLinkList(value: LinkType[]) {
this.model.linkList = value;
},
},
};
BI.model(className, BI.inherit(Fix.Model, Model));
export default className;

26
src/app/link_set/left/left.component.ts

@ -0,0 +1,26 @@
import {WidgetType, Vertical} from '@ui';
import Model from '../link-set.model';
import {LinkType} from '@ui/type';
import {getLinks} from './left.service';
const className = 'fr.component.linkset.left';
let leftContent: any = null;
const Widget: WidgetType = {
_store() {
return BI.Models.getModel(Model);
},
watch:{
linkList(linkList: LinkType[]) {
leftContent.populate(BI.createItems(getLinks(linkList)));
},
},
render() {
return {
type: Vertical,
ref(_ref: any) {
leftContent = _ref;
},
};
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

18
src/app/link_set/left/left.service.ts

@ -0,0 +1,18 @@
import {LinkType} from '@ui/type';
import LeftItem from './left_item/left.item.component';
export const getLinks = (linkList: LinkType[]): any => {
const links: any[] = [];
linkList.forEach((item: LinkType) => {
links.push({
type: LeftItem,
extraCls: item.isSelected ? 'left-item-selected' : '',
title: item.connectionName,
id: item.connectionId,
creator: item.creator,
text: item.text ? item.text : '默认',
});
});
return links;
};

79
src/app/link_set/left/left_item/left.item.component.ts

@ -0,0 +1,79 @@
import {WidgetType, Left, Label, Icon} from '@ui';
import ItemIcon from './left.item.icon.component';
import Model from '../../link-set.model';
const className = 'fr.component.linkSet.left.item';
const Widget: WidgetType = {
props: {
title:'',
id:'',
creator: '',
},
_store() {
return BI.Models.getModel(Model);
},
render() {
const {title, extraCls, creator, text, id} = this.options;
return {
type: Left,
cls: 'left-item',
extraCls,
items: [
{
type: Icon,
cls: 'link-font',
height: 24,
width: 26,
text: '连接',
title,
},
{
type: Label,
cls:'link-title',
textAlign: 'left',
text: title,
title,
},
{
type: Left,
cls: 'icons',
items: [
{
type: ItemIcon,
cls: 'link-text-font',
title: '测试连接',
id,
},
{
type: ItemIcon,
cls: 'copy-font',
title: '复制',
id,
},
{
type: ItemIcon,
cls: 'info-font',
title: `类型:${text === 'DESIGNER' ? '其他' : text} \r\n创建者:${creator}`,
id,
},
{
type: ItemIcon,
cls: 'delete-font',
title: '删除',
id,
},
],
},
],
};
},
mounted() {
const {title} = this.options;
this.element.on('click', () => {
this.store.setLinkSelected(title);
});
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

86
src/app/link_set/left/left_item/left.item.icon.component.ts

@ -0,0 +1,86 @@
import {WidgetType, Icon, BubbleCombo, TextBubblePopupBarView} from '@ui/index';
import Model from '../../link-set.model';
const className = 'fr.component.linkSet.left.item.icon';
const Widget: WidgetType = {
_store() {
return BI.Models.getModel(Model);
},
render() {
const {cls, title, id} = this.options;
const that = this;
let iconContent: any = null;
let combo: any = null;
if (title === '删除') {
return {
type: BubbleCombo,
direction: 'bottom',
ref () {
combo = this;
},
el: {
type: Icon,
cls,
extraCls: 'action-icon',
height: 24,
width: 26,
title,
ref (ref: any) {
iconContent = ref;
},
},
popup: {
type: TextBubblePopupBarView,
text: '确定删除该数据连接?',
listeners: [{
eventName: BI.BubblePopupBarView.EVENT_CLICK_TOOLBAR_BUTTON,
action (type: boolean) {
combo.hideView();
if (type) {
that.store.onIconClick(title, id);
}
},
}],
},
listeners: [{
eventName: BI.BubbleCombo.EVENT_EXPAND,
action () {
iconContent.element.css({
visibility:'visible',
});
},
}, {
eventName: BI.BubbleCombo.EVENT_AFTER_HIDEVIEW,
action () {
iconContent.element.css({
visibility:'hidden',
});
},
}],
};
}
return {
type: Icon,
cls,
extraCls: 'action-icon',
height: 24,
width: 26,
title,
};
},
mounted() {
const {title, id} = this.options;
if (title !== '删除') {
this.element.on('click', (event: any) => {
event.stopPropagation();
this.store.onIconClick(title, id);
});
} else {
this.element.on('click', (event: any) => {
event.stopPropagation();
});
}
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

51
src/app/link_set/link-set.component.ts

@ -0,0 +1,51 @@
import {Htape, WidgetType, Vtape, Left} from '@ui';
import LeftList from './left/left.component';
import linkSetModel from './link-set.model';
import Select from './select/select.component';
import Right from './right/right.component';
const className = 'fr.linkset';
const Widget: WidgetType = {
_store() {
return BI.Models.getModel(linkSetModel);
},
watch:{
tab(tab: string) {
this.setVisible(tab === '数据连接管理');
},
},
render() {
return {
type: Htape,
cls: 'linkset',
items: [{
el: {
type: Vtape,
cls: 'database-left',
items: [
{
el: {
type: Left,
cls:'select-group',
items:[
{
type: Select,
},
],
},
height: 40,
}, {
type: LeftList,
cls: 'left-list',
},
],
},
width: 280,
}, {
type: Right,
}],
};
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

195
src/app/link_set/link-set.model.ts

@ -0,0 +1,195 @@
import {ModelType} from '@ui/index';
import {LinkType} from '@ui/type';
import {deleteConnection, testConnection} from '@shared/crud/crud.request';
import {databaseTyle, getCnnectionName} from './select/select.service';
import dialog from '@shared/service/dialog.service';
import {saveConnection} from './link-set.service';
const className = 'fr.model.linkset';
const Model: ModelType = {
context: ['tab', 'linkList', 'linkSelected', 'linkUpdate', 'connectionNameErr'],
actions: {
/**
*
* @param name
*/
setLinkSelected(name: string) {
this.noSaveConfirm(() => {
this._setLinkSelected(name);
});
},
_setLinkSelected(name: string) {
this.model.linkList.forEach((item: LinkType) => {
item.isSelected = item.connectionName === name;
if (item.connectionName === name) {
this.model.linkSelected = {
...item,
isSelected: false,
};
}
});
this.model.linkList = [...this.model.linkList];
this.model.linkUpdate = this.model.linkSelected;
},
onIconClick(title: string, id: string) {
switch (title) {
case '删除':
deleteConnection(id, () => {
this.model.linkList = [...this.model.linkList.filter((item: LinkType) => item.connectionId !== id)];
this.model.linkSelected = {};
this.model.linkUpdate = {};
});
break;
case '测试连接':
this._textLink(id);
break;
case '复制':
this.noSaveConfirm(() => {
this.copyLink(id);
});
break;
default:
break;
}
},
_textLink(id: string) {
const loadingId = dialog.loading('正在测试连接,请稍候...');
const link = this.model.linkList.find((item: LinkType) => item.connectionId === id);
testConnection(link, (res: any) => {
dialog.close(loadingId);
if (res && res.errorCode) {
dialog.linkFail(`${link.connectionName}测试连接失败`, res.errorMsg, () => {
this._textLink(id);
});
} else {
dialog.success('连接成功');
}
});
},
copyLink(id: string) {
const connectionName = BI.find(this.model.linkList, (index: number, item: LinkType) => item.connectionId === id).connectionName;
const name = getCnnectionName(this.model.linkList, connectionName);
let data = {};
this.model.linkList.forEach((item: LinkType) => {
if (item.connectionId === id) {
data = item;
}
});
const newCopy = {
...data,
isSelected: true,
connectionName:name,
connectionId: '',
};
this.model.linkList = [
newCopy,
...this.model.linkList,
];
this.model.linkSelected = {
...newCopy,
};
this.model.linkUpdate = {
...newCopy,
};
},
setLinkUpdate(value: any) {
this.model.linkUpdate = value;
},
setEdit(type: boolean) {
this.model.linkSelected = {
...this.model.linkSelected,
isSelected: type,
};
this.model.linkUpdate = this.model.linkSelected;
},
setCancel() {
const linkSelected: LinkType = this.model.linkSelected;
const linkList: LinkType[] = this.model.linkList;
if (linkSelected.connectionId) {
this.setEdit(false);
} else {
this.model.linkList = [
...linkList.filter(item => !!item.connectionId),
];
if (this.model.linkList.length > 0) {
this.model.linkList[0].isSelected = true;
this.model.linkSelected = {
...this.model.linkList[0],
isSelected: false,
};
} else {
this.model.linkSelected = {};
}
this.model.linkUpdate = this.model.linkSelected;
}
},
setNewLink(value: string) {
if (!databaseTyle.some(item => item.text === value) && !BI.Constants.getConstant(`dec.constant.database.conf.connect.form.${value.toLowerCase()}.edit`)) {
dialog.error('找不到该连接的配置信息');
return;
}
this.noSaveConfirm(() => {
this._setNewLink(value);
});
},
_setNewLink(value: string) {
const name = getCnnectionName(this.model.linkList, value);
let data = {};
databaseTyle.forEach(item => {
if (item.text === value) {
data = item;
}
});
this.model.linkList = [
{
connectionName:name,
isSelected: true,
...data,
text: value,
},
...this.model.linkList,
];
this.model.linkSelected = {
...data,
connectionName:name,
isSelected: true,
text: value,
};
this.model.linkUpdate = {
...data,
connectionName:name,
text: value,
};
},
setConnectionNameErr(err: string) {
this.model.connectionNameErr = err;
},
noSaveConfirm(cb: Function) {
if (this.model.linkSelected && this.model.linkSelected.isSelected) {
dialog.confirm('当前设置尚未保存,是否保存?', (isConfirm: boolean) => {
if (isConfirm) {
this.saveLink();
} else {
this.setCancel();
}
cb();
});
} else {
cb();
}
},
saveLink() {
const pluginData = this.model.linkUpdate.text ? BI.Constants.getConstant(`dec.constant.database.conf.connect.form.${this.model.linkUpdate.text.toLowerCase()}.value`) : {};
const update = {
...this.model.linkUpdate,
...pluginData,
};
saveConnection(update).then(() => {
this.setEdit(false);
});
},
},
};
BI.model(className, BI.inherit(Fix.Model, Model));
export default className;

26
src/app/link_set/link-set.service.ts

@ -0,0 +1,26 @@
import {LinkType} from '@ui/type';
import {addConnection, updateConnection} from '@shared/crud/crud.request';
export function saveConnection(linkUpdate: LinkType): Promise<string> {
if (linkUpdate.connectionId) {
return new Promise(((resolve, reject) => {
try {
addConnection(linkUpdate, (res: string) => {
resolve(res);
});
} catch (error) {
reject(error);
}
}));
}
return new Promise(((resolve, reject) => {
try {
updateConnection(linkUpdate, (res: string) => {
resolve(res);
});
} catch (error) {
reject(error);
}
}));
}

61
src/app/link_set/more/more.link.component.ts

@ -0,0 +1,61 @@
import {WidgetType, Vertical, SearchEditor, Left, Vtape} from '@ui/index';
import {databaseTyle} from '../select/select.service';
import MoreLinkItem from './more.link.item.component';
const className = 'fr.component.linkSet.morelink';
let morkLinkItem: any = null;
const Widget: WidgetType = {
render() {
return {
type: Vtape,
cls: 'more-link',
items: [
{
el:{
type: Vertical,
items:[{
type: SearchEditor,
width: 300,
watermark: '搜索',
}],
},
height: 30,
},
{
type: Left,
cls:'more-link-item',
ref(ref: any) {
morkLinkItem = ref;
},
},
],
};
},
mounted() {
this._renderItems();
},
_renderItems(text = '') {
const databaseLink = databaseTyle.slice(12, 12 + 33);
const items: any[] = [];
const that = this;
databaseLink.forEach(item => {
items.push({
type: MoreLinkItem,
text: item.text,
name: item.databaseType,
selected: text === item.text,
listeners: [
{
eventName: 'EVENT_SELECT',
action (text: string) {
that._renderItems(text);
that.fireEvent('EVENT_SELECT', text);
},
},
],
});
});
morkLinkItem.populate(BI.createItems(items));
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

40
src/app/link_set/more/more.link.item.component.ts

@ -0,0 +1,40 @@
import {WidgetType, Vertical, Img, Label, Layout} from '@ui/index';
const className = 'fr.component.linkSet.morelink.item';
const Widget: WidgetType = {
render() {
const {text, name, selected} = this.options;
return {
type: Vertical,
cls:'link-item',
width: 120,
height: 117,
items:[
{
type: Img,
width: 120,
height: 90,
src:`./img/${name}.jpg`,
}, {
type: Layout,
cls: 'selected',
invisible: !selected,
width:30,
height: 30,
}, {
type: Label,
cls:'text',
text,
},
],
};
},
mounted() {
const {text} = this.options;
this.element.on('click', () => {
this.fireEvent('EVENT_SELECT', text);
});
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

54
src/app/link_set/more/more.link.service.ts

@ -0,0 +1,54 @@
import MoreLink from './more.link.component';
let SubbitButton: any = null;
let selectKey = '';
export const moreLink = (onConfirm?: Function): void => {
const id = BI.UUID();
let Popovers: any = null;
BI.Popovers.create(id, {
type: 'bi.bar_popover',
size: 'normal',
header: '更多数据连接',
width: 550,
height: 500,
body: {
type: MoreLink,
listeners: [
{
eventName: 'EVENT_SELECT',
action (text: string) {
selectKey = text;
SubbitButton.setEnable(true);
},
},
],
},
footer:{
type: 'bi.right_vertical_adapt',
lgap: 10,
items: [{
type: 'bi.button',
text: '取消',
value: 1,
level: 'ignore',
handler (v: any) {
Popovers.close(v);
},
}, {
type: 'bi.button',
text: '确定',
disabled: true,
value: 0,
ref(ref: any) {
SubbitButton = ref;
},
handler (v: any) {
Popovers.close(v);
onConfirm ? onConfirm(selectKey) : null;
},
}],
},
ref(ref: any) {
Popovers = ref;
},
}).open(id);
};

37
src/app/link_set/right/nothing.component.ts

@ -0,0 +1,37 @@
import {WidgetType, CenterAdapt, Vertical, Layout, Label} from '@ui/index';
const className = 'fr.component.right.nothing';
const Widget: WidgetType = {
render() {
return {
type: CenterAdapt,
items: [{
type: Vertical,
width: 260,
height: 180,
items:[
{
type: Layout,
cls: 'data-connection-background',
width: 260,
height: 130,
},
{
type:Label,
cls: 'bi-tips',
height: 20,
text:'请选择左侧数据连接或点击新建数据连接',
},
{
type:Label,
cls: 'bi-tips',
height: 20,
text:'平台仅支持使用JDBC的数据连接的管理',
},
],
}],
};
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

39
src/app/link_set/right/right.component.ts

@ -0,0 +1,39 @@
import {WidgetType, Vertical} from '@ui';
import {LinkType} from '@ui/type';
import Nothing from './nothing.component';
import RightDetail from './right_detail/right.detail.component';
import Model from '../link-set.model';
let rightContent: any = null;
const className = 'fr.component.right';
const Widget: WidgetType = {
_store() {
return BI.Models.getModel(Model);
},
watch:{
linkSelected(linkSelected: LinkType) {
rightContent.populate(BI.createItems([
{
type: (linkSelected && linkSelected.connectionName) ? RightDetail : Nothing,
},
]));
},
},
render() {
return {
type:Vertical,
cls:'database-right',
ref(_ref: any) {
rightContent = _ref;
},
};
},
mounted() {
rightContent.populate(BI.createItems([
{
type: Nothing,
},
]));
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

54
src/app/link_set/right/right_detail/right.detail.component.ts

@ -0,0 +1,54 @@
import {WidgetType, Vertical} from '@ui/index';
import Model from '../../link-set.model';
import Title from '../right_title/right.title.component';
import RightShow from '../right_show/right.show.component';
import RightEdit from '../right_edit/right.edit.component';
import RightEditMysql from '../right_edit/right.edit.mysql.component';
import {LinkType} from '@ui/type';
import pluginListConstant from '../../../app.constant';
const className = 'fr.component.right.detail';
let rightDetail: any = null;
const renderEdit = (linkSelected: LinkType): void => {
const plugins: string[] = BI.Constants.getConstant(pluginListConstant);
const isPlugin = BI.some(plugins, (index: number, item: string) => item === linkSelected.text);
let typeEdit = linkSelected.databaseType === 'mysql' ? RightEditMysql : RightEdit;
if (isPlugin) {
typeEdit = BI.Constants.getConstant(`dec.constant.database.conf.connect.form.${linkSelected.text.toLowerCase()}.edit`);
}
const showPage = !isPlugin ? RightShow : BI.Constants.getConstant(`dec.constant.database.conf.connect.form.${linkSelected.text.toLowerCase()}.preview`);
rightDetail.populate(BI.createItems([
{
type: Title,
isEdit: linkSelected.isSelected,
linkSelected,
}, {
type: linkSelected.isSelected ? typeEdit : showPage,
linkSelected,
},
]));
};
const Widget: WidgetType = {
_store() {
return BI.Models.getModel(Model);
},
watch:{
linkSelected(linkSelected: LinkType) {
renderEdit(linkSelected);
},
},
render() {
return {
type: Vertical,
cls:'right-content',
ref(_ref: any) {
rightDetail = _ref;
},
};
},
mounted() {
const linkSelected: LinkType = this.model.linkSelected;
renderEdit(linkSelected);
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

278
src/app/link_set/right/right_edit/right.edit.component.ts

@ -0,0 +1,278 @@
import {WidgetType, Vertical, MultiSelectItem, TextAreaEditor, Editor, Button, TextValueCombo} from '@ui/index';
import {LinkType} from '@ui/type';
import charset from './right.edit.constant';
import Model from '../../link-set.model';
import FormItem from '@shared/components/form.item.component';
import Title from '@shared/components/title.component';
import {getDrivers} from './right.edit.service';
let ConnectionName: any = null;
const className = 'fr.component.right.edit';
const Widget: WidgetType = {
_store() {
return BI.Models.getModel(Model);
},
watch:{
connectionNameErr(msg: string) {
if (msg) {
BI.Bubbles.show('singleBubble', msg, ConnectionName, {
level: 'error',
});
} else {
BI.Bubbles.hide('singleBubble');
}
},
},
render() {
const linkSelected: LinkType = this.model.linkSelected;
const that = this;
return {
type: Vertical,
cls: 'right-show',
items: [
{
type: FormItem,
text: '数据连接名',
hint: '*修改数据连接名会影响相关数据表和仪表板',
form:{
type: Editor,
cls: 'bi-border',
width: 300,
value: linkSelected.connectionName,
ref(ref: any) {
ConnectionName = ref;
},
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
connectionName: this.getValue(),
});
},
}, {
eventName: BI.Editor.EVENT_FOCUS,
action() {
that.store.setConnectionNameErr('');
},
}],
},
},
{
type: FormItem,
text: '第一步',
height: 400,
form:{
type: Vertical,
cls: 'right-form',
items:[
{
type: FormItem,
text: '驱动器',
form:{
type: TextValueCombo,
cls: 'bi-border',
width: 300,
text: linkSelected.driver,
items: getDrivers(linkSelected),
listeners: [{
eventName: BI.TextValueCombo.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
driver: this.getValue()[0],
});
},
}],
},
},
{
type: FormItem,
text: 'URL',
form:{
type: Editor,
cls: 'bi-border',
watermark:'请输入',
width: 300,
value: linkSelected.url,
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
url: this.getValue(),
});
},
}],
},
},
{
type: FormItem,
text: '编码',
form:{
type: TextValueCombo,
cls: 'bi-border',
width: 300,
text: linkSelected.originalCharsetName === '' ? '自动' : linkSelected.originalCharsetName,
items: BI.Constants.getConstant(charset),
listeners: [{
eventName: BI.TextValueCombo.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
originalCharsetName: this.getValue()[0],
});
},
}],
},
},
{
type: FormItem,
text: '用户名',
form:{
type: Editor,
cls: 'bi-border',
allowBlank:true,
watermark:'请输入',
width: 300,
value: linkSelected.user,
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
user: this.getValue(),
});
},
}],
},
},
{
type: FormItem,
text: '密码',
form:{
type: Editor,
cls: 'bi-border',
inputType:'password',
allowBlank:true,
watermark:'请输入',
width: 300,
value: linkSelected.password,
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
password: this.getValue(),
});
},
}],
},
},
{
type: Title,
text: '连接池属性',
},
{
type: FormItem,
text: 'SQL验证查询',
height: 100,
form:{
type: TextAreaEditor,
cls: 'bi-border',
allowBlank:true,
watermark:'请输入',
width: 300,
height:100,
value: linkSelected.validationQuery,
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
validationQuery: this.getValue(),
});
},
}],
},
},
{
type: FormItem,
text: '获取连接前校验',
form:{
type: MultiSelectItem,
text: '是',
selected: linkSelected.testOnBorrow,
width: 60,
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
testOnBorrow: this.isSelected(),
});
},
}],
},
},
{
type: FormItem,
text: '最大活动连接数',
form:{
type: Editor,
cls: 'bi-border',
allowBlank:true,
watermark:'请输入',
width: 60,
value: linkSelected.maxActive,
errorText: '请输入有效的正整数',
validationChecker (v: string) {
if (/^\+?[1-9][0-9]*$/.test(v)) {
return true;
}
return false;
},
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
maxActive: this.getValue(),
});
},
}],
},
},
],
},
},
{
type: FormItem,
text: '第二步',
form: {
type: Button,
text: '测试连接',
level: 'ignore',
},
},
{
type: FormItem,
text: '第三步',
form: {
type: FormItem,
text: '模式',
form: {
type: Editor,
cls: 'bi-border',
width: 300,
disabled: true,
},
},
},
],
};
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

41
src/app/link_set/right/right_edit/right.edit.constant.ts

@ -0,0 +1,41 @@
export const ConstantName = 'bi.constant.database.conf.charset.list';
export const Constant = BI.constant(ConstantName, [
{
text: '自动',
value: '',
},
{
text: 'GBK',
value: 'GBK',
},
{
text: 'BIG5',
value: 'BIG5',
},
{
text: 'ISO-8859-1',
value: 'ISO-8859-1',
},
{
text: 'UTF-8',
value: 'UTF-8',
},
{
text: 'UTF-16',
value: 'UTF-16',
},
{
text: 'EUC_JP',
value: 'EUC_JP',
},
{
text: 'EUC_KR',
value: 'EUC_KR',
},
{
text: 'CP850',
value: 'CP850',
},
]);
export default ConstantName;

233
src/app/link_set/right/right_edit/right.edit.mysql.component.ts

@ -0,0 +1,233 @@
import {WidgetType, Vertical, MultiSelectItem, TextAreaEditor, Editor, Button, TextValueCombo} from '@ui/index';
import {LinkType} from '@ui/type';
import charset from './right.edit.constant';
import Model from '../../link-set.model';
import FormItem from '@shared/components/form.item.component';
import Title from '@shared/components/title.component';
import {getDrivers} from './right.edit.service';
const className = 'fr.component.right.edit.mysql';
const Widget: WidgetType = {
_store() {
return BI.Models.getModel(Model);
},
render() {
const linkSelected: LinkType = this.model.linkSelected;
const that = this;
return {
type: Vertical,
cls: 'right-show',
items: [
{
type: FormItem,
text: '数据连接名',
hint: '*修改数据连接名会影响相关数据表和仪表板',
form:{
type: Editor,
cls: 'bi-border',
width: 300,
value: linkSelected.connectionName,
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
connectionName: this.getValue(),
});
},
}],
},
},
{
type: FormItem,
text: '驱动器',
form:{
type: TextValueCombo,
cls: 'bi-border',
width: 300,
text: linkSelected.driver,
items: getDrivers(linkSelected),
listeners: [{
eventName: BI.TextValueCombo.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
driver: this.getValue()[0],
});
},
}],
},
},
{
type: FormItem,
text: 'URL',
form:{
type: Editor,
cls: 'bi-border',
watermark:'请输入',
width: 300,
value: linkSelected.url,
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
url: this.getValue(),
});
},
}],
},
},
{
type: FormItem,
text: '编码',
form:{
type: TextValueCombo,
cls: 'bi-border',
width: 300,
text: linkSelected.originalCharsetName === '' ? '自动' : linkSelected.originalCharsetName,
items: BI.Constants.getConstant(charset),
listeners: [{
eventName: BI.TextValueCombo.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
originalCharsetName: this.getValue()[0],
});
},
}],
},
},
{
type: FormItem,
text: '用户名',
form:{
type: Editor,
cls: 'bi-border',
allowBlank:true,
watermark:'请输入',
width: 300,
value: linkSelected.user,
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
user: this.getValue(),
});
},
}],
},
},
{
type: FormItem,
text: '密码',
form:{
type: Editor,
cls: 'bi-border',
inputType:'password',
allowBlank:true,
watermark:'请输入',
width: 300,
value: linkSelected.password,
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
password: this.getValue(),
});
},
}],
},
},
{
type: Title,
text: '连接池属性',
},
{
type: FormItem,
text: 'SQL验证查询',
height: 100,
form:{
type: TextAreaEditor,
cls: 'bi-border',
allowBlank:true,
watermark:'请输入',
width: 300,
height:100,
value: linkSelected.validationQuery,
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
validationQuery: this.getValue(),
});
},
}],
},
},
{
type: FormItem,
text: '获取连接前校验',
form:{
type: MultiSelectItem,
text: '是',
selected: linkSelected.testOnBorrow,
width: 60,
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
testOnBorrow: this.isSelected(),
});
},
}],
},
},
{
type: FormItem,
text: '最大活动连接数',
form:{
type: Editor,
cls: 'bi-border',
allowBlank:true,
watermark:'请输入',
width: 60,
value: linkSelected.maxActive,
errorText: '请输入有效的正整数',
validationChecker (v: string) {
if (/^\+?[1-9][0-9]*$/.test(v)) {
return true;
}
return false;
},
listeners: [{
eventName: BI.Editor.EVENT_CHANGE,
action() {
that.store.setLinkUpdate({
...that.model.linkUpdate,
maxActive: this.getValue(),
});
},
}],
},
},
{
type: FormItem,
text: '测试连接',
form: {
type: Button,
text: '测试连接',
level: 'ignore',
},
},
],
};
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

20
src/app/link_set/right/right_edit/right.edit.service.ts

@ -0,0 +1,20 @@
import {LinkType} from '@ui/type';
export function getDrivers(linkSelected: LinkType): {text: string; value: string}[] {
const drivers: {text: string; value: string}[] = [];
if (linkSelected.drivers && linkSelected.drivers.length > 0) {
linkSelected.drivers.forEach(item => {
drivers.push({
text: item,
value: item,
});
});
} else {
drivers.push({
text: linkSelected.driver,
value: linkSelected.driver,
});
}
return drivers;
}

72
src/app/link_set/right/right_show/right.show.component.ts

@ -0,0 +1,72 @@
import {WidgetType, Vertical} from '@ui/index';
import RightShowModel from '../../link-set.model';
import BothSide from '@shared/components/both.side.component';
import Title from '@shared/components/title.component';
import {LinkType} from '@ui/type';
const className = 'fr.component.right.show';
const Widget: WidgetType = {
_store() {
return BI.Models.getModel(RightShowModel);
},
render() {
const linkSelected: LinkType = this.model.linkSelected;
return {
type: Vertical,
cls: 'right-show',
items: [
{
type: BothSide,
leftText: '数据连接名',
rightText: linkSelected.connectionName,
},
{
type: BothSide,
leftText: '驱动器',
rightText: linkSelected.driver,
},
{
type: BothSide,
leftText: 'URL',
rightText: linkSelected.url,
},
{
type: BothSide,
leftText: '编码',
rightText: linkSelected.originalCharsetName === '' ? '自动' : linkSelected.originalCharsetName,
},
{
type: BothSide,
leftText: '用户名',
rightText: linkSelected.user,
},
{
type: BothSide,
leftText: '密码',
rightText: linkSelected.password,
},
{
type: Title,
text: '连接池属性',
},
{
type: BothSide,
leftText: 'SQL验证查询',
rightText: linkSelected.validationQuery,
},
{
type: BothSide,
leftText: '获取连接前校验',
rightText: linkSelected.testOnBorrow ? '是' : '否',
},
{
type: BothSide,
leftText: '最大连接数量',
rightText: linkSelected.maxActive,
},
],
};
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

64
src/app/link_set/right/right_title/right.title.component.ts

@ -0,0 +1,64 @@
import {WidgetType, Left, Label, Button} from '@ui/index';
import RightTitleModel from '../../link-set.model';
import {LinkType} from '@ui/type';
import {saveConnection} from '../../link-set.service';
const className = 'fr.component.right.title';
const Widget: WidgetType = {
_store() {
return BI.Models.getModel(RightTitleModel);
},
render() {
const linkSelected: LinkType = this.model.linkSelected;
const linkList: LinkType[] = this.model.linkList;
const that = this;
const {isEdit} = this.options;
return {
type: Left,
height: 40,
cls: 'right-title',
items: [
{
type: Label,
cls: 'right-title-text',
text: `数据连接(${linkSelected.text ? linkSelected.text : '默认'})`,
},
{
type: Button,
cls:'right-title-button',
invisible: isEdit,
text: '编辑',
handler() {
that.store.setEdit(true);
},
},
{
type: Button,
cls:'right-title-button',
invisible: !isEdit,
text: '保存',
handler() {
const result = BI.find(linkList, (idx: number, value: LinkType) => that.model.linkUpdate.connectionName === value.connectionName && value.connectionId !== that.model.linkUpdate.connectionId);
if (result) {
that.store.setConnectionNameErr('数据连接名已存在');
} else {
that.store.saveLink();
}
},
},
{
type: Button,
cls:'right-title-button',
invisible: !isEdit,
level: 'ignore',
text: '取消',
handler() {
that.store.setCancel();
},
},
],
};
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

79
src/app/link_set/select/select.component.ts

@ -0,0 +1,79 @@
import {WidgetType, Combo, ButtonGroup, TextItem, Vertical} from '@ui';
import selectModel from '../link-set.model';
import {moreLink} from '../more/more.link.service';
import connectList, {links} from '../../app.constant';
const className = 'fr.linkset.select';
const Widget: WidgetType = {
_store() {
return BI.Models.getModel(selectModel);
},
render() {
let combo: any = null;
return {
type: Combo,
cls:'select',
trigger: 'click',
adjustYOffset: 4,
el: {
type: 'bi.button',
text: '新建数据连接',
height: 24,
},
popup: {
el: {
type: ButtonGroup,
cls:'database-link-items',
items: [...BI.map([...links, ...BI.Constants.getConstant(connectList)], (index: number, item: string) => {
return {
type: TextItem,
height: 24,
width: 152,
text: item,
title: item,
value: item,
};
}), {
type: TextItem,
cls: 'link-item',
height: 24,
width: 152,
text: '更多数据连接...',
title:'更多数据连接...',
value: 'more',
}, {
type: TextItem,
cls: 'link-item',
height: 24,
width: 152,
text: '其他',
title:'其他',
value: '其他',
}],
layouts: [{
type: Vertical,
}],
},
maxHeight: 400,
},
listeners:[{
eventName: 'EVENT_CHANGE',
action: (v: string) => {
if (v === 'more') {
moreLink((text: string) => {
this.store.setNewLink(text);
});
} else {
this.store.setNewLink(v);
}
combo.hideView();
},
}],
ref () {
combo = this;
},
};
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

283
src/app/link_set/select/select.service.ts

@ -0,0 +1,283 @@
import {LinkType} from '@ui/type';
import pluginListConstant from '../../app.constant';
export const databaseTyle = [
{
text:'APACHE KYLIN',
databaseType: 'apache-kylin',
driver: 'org.apache.kylin.jdbc.Driver',
url: 'jdbc:kylin://<hostname>:<port>/<kylin_project_name>',
},
{
text:'DERBY',
databaseType: 'derby',
driver: 'org.apache.derby.jdbc.ClientDriver',
url: 'jdbc:derby://localhost:1527/',
},
{
text:'HP Vertica',
databaseType: 'hp-vertica',
driver: 'com.vertica.jdbc.Driver',
url: 'jdbc:vertica://ip:port/databaseName',
},
{
text:'IBM DB2',
databaseType: 'ibm-db2',
driver: 'com.ibm.db2.jcc.DB2Driver',
url: 'jdbc:db2://hostname:port/dbname',
},
{
text:'INFORMIX',
databaseType: 'informix',
driver: 'com.informix.jdbc.IfxDriver',
url: 'jdbc:informix-sqli://{host}:{port}/{database}:INFORMIXSERVER={server}',
},
{
text:'Microsoft SQL Server',
databaseType: 'sql-server',
driver: 'com.microsoft.sqlserver.jdbc.SQLServerDriver',
url: 'jdbc:sqlserver://localhost:1433;databaseName=',
},
{
text:'Oracle',
databaseType: 'oracle',
driver: 'oracle.jdbc.driver.OracleDriver',
url: 'jdbc:oracle:thin:@localhost:1521:databaseName',
},
{
text:'Privotal Greenplum Database',
databaseType: 'pivotal-greenplum-database',
driver: 'org.postgresql.Driver',
url: 'jdbc:postgresql://hostname:port/dbname',
},
{
text:'Postgresql',
databaseType: 'postgresql',
driver: 'org.postgresql.Driver',
url: 'jdbc:postgresql://hostname:port/dbname',
},
{
text:'GaussDB 200',
databaseType: 'hw-libr-a',
driver: 'org.postgresql.Driver',
url: 'jdbc:postgresql://hostname:port/dbname',
},
{
text:'MySQL',
databaseType: 'mysql',
driver: 'com.mysql.jdbc.Driver',
drivers:['com.mysql.jdbc.Driver', 'org.gjt.mm.mysql.Driver'],
url: 'jdbc:mysql://localhost/dbname',
},
{
text:'其他',
databaseType: 'other',
driver: 'org.h2.Driver',
drivers:['org.h2.Driver', 'com.fr.third.org.hsqldb.jdbcDriver', 'org.sqlite.JDBC'],
url: 'jdbc:h2://${ENV_HOME}/../databaseName',
},
{
text:'ADS',
databaseType:'ads',
driver:'com.mysql.jdbc.Driver',
url:'jdbc:mysql://hostname:port/my_ads_db',
},
{
text:'Amazon Redshift',
databaseType:'amazon-redshift',
driver: 'com.amazon.redshift.jdbc4.Driver',
drivers:['com.amazon.redshift.jdbc4.Driver', 'com.amazon.redshift.jdbc41.Driver'],
url:'jdbc:redshift://endpoint:port/database',
},
{
text:'APACHE IMPALA',
databaseType:'apache-impala',
driver:'com.cloudera.impala.jdbc41.Driver',
url:'jdbc:impala://hostname:port/_impala_builtins',
},
{
text:'APACHE KYLIN',
databaseType:'apache-kylin',
driver:'org.apache.kylin.jdbc.Driver',
url:'jdbc:kylin://<hostname>:<port>/<kylin_project_name>',
},
{
text:'APACHE Phoenix',
databaseType: 'apache-phoenix',
driver: 'org.apache.phoenix.jdbc.PhoenixDriver',
url: 'jdbc:phoenix:hostname:port/dbname',
},
{
text:'DERBY',
databaseType: 'derby',
driver: 'org.apache.derby.jdbc.ClientDriver',
url: 'jdbc:derby://localhost:1527/',
},
{
text:'Gbase 8A',
databaseType: 'gbase-8a',
driver: 'com.gbase.jdbc.Driver',
url: 'jdbc:gbase://hostname:port/dbname',
},
{
text:'Gbase 8S',
databaseType: 'gbase-8s',
driver: 'com.gbasedbt.jdbc.IfxDriver',
url: 'jdbc:gbasedbt-sqli://{host}:{port}/{database}',
},
{
text:'Gbase 8T',
databaseType: 'gbase-8t',
driver: 'com.informix.jdbc.IfxDriver',
url: 'jdbc:informix-sqli://{host}:{port}/{database}:INFORMIXSERVER={server}',
},
{
text:'H2',
databaseType: 'h2',
driver: 'org.h2.Driver',
url: 'jdbc:h2://${ENV_HOME}/../databaseName',
},
{
text:'华为云DWS',
databaseType: 'hw-dws',
driver: 'org.postgresql.Driver',
url: 'jdbc:postgresql://hostname:port/dbname',
},
{
text:'FusionInsight elk',
databaseType: 'hw-elk',
driver: 'org.postgresql.Driver',
url: 'jdbc:postgresql://hostname:port/dbname',
},
{
text:'FusionInsight HD',
databaseType: 'hw-fusioninsight-hd',
driver: 'org.apache.hive.jdbc.HiveDriver',
url: 'jdbc:hive2://10.135.0.110:24002,10.135.0.67:24002,10.135.0.66:24002/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2;sasl.qop=auth-conf;auth=KERBEROS;zk.principal=zookeeper/hadoop;principal=hive/hadoop.hadoop.com@HADOOP.COM;',
},
{
text:'GaussDB 200',
databaseType: 'hw-libr-a',
driver: 'org.postgresql.Driver',
url: 'jdbc:postgresql://hostname:port/dbname',
}, {
text:'Hadoop Hive',
databaseType: 'hadoop-hive',
driver: 'org.apache.hive.jdbc.HiveDriver',
url: 'jdbc:hive2://hostname:port/databasename',
}, {
text:'Hbase',
databaseType: 'hbase',
driver: 'org.apache.phoenix.jdbc.PhoenixDriver',
url: 'jdbc:phoenix:hostname:port/dbname',
}, {
text:'HP Vertica',
databaseType: 'hp-vertica',
driver: 'com.vertica.jdbc.Driver',
url: 'jdbc:vertica://ip:port/databaseName',
}, {
text:'Hsql',
databaseType: 'hsql',
driver: 'com.fr.third.org.hsqldb.jdbcDriver',
url: 'jdbc:hsqldb:file:[PATH_TO_DB_FILES]',
}, {
text:'IBM DB2',
databaseType: 'ibm-db2',
driver: 'com.ibm.db2.jcc.DB2Driver',
url: 'jdbc:db2://hostname:port/dbname',
}, {
text:'INFORMIX',
databaseType: 'informix',
driver: 'com.informix.jdbc.IfxDriver',
url: 'jdbc:informix-sqli://{host}:{port}/{database}:INFORMIXSERVER={server}',
}, {
text:'KINGBASE',
databaseType: 'kingbase',
driver: 'com.kingbase.Driver',
url: 'jdbc:kingbase://hostname:port',
}, {
text:'Microsoft SQL Server',
databaseType: 'sql-server',
driver: 'com.microsoft.sqlserver.jdbc.SQLServerDriver',
url: 'jdbc:sqlserver://localhost:1433;databaseName=',
}, {
text:'MySQL',
databaseType: 'mysql',
driver: 'com.mysql.jdbc.Driver',
drivers:['com.mysql.jdbc.Driver', 'org.gjt.mm.mysql.Driver'],
url: 'jdbc:mysql://localhost/dbname',
},
{
text:'Oracle',
databaseType: 'oracle',
driver: 'oracle.jdbc.driver.OracleDriver',
url: 'jdbc:oracle:thin:@localhost:1521:databaseName',
},
{
text:'Pivotal Greenplum Database',
databaseType: 'pivotal-greenplum-database',
driver: 'org.postgresql.Driver',
url: 'jdbc:postgresql://hostname:port/dbname',
}, {
text:'Postgresql',
databaseType: 'postgresql',
driver: 'org.postgresql.Driver',
url: 'jdbc:postgresql://hostname:port/dbname',
}, {
text:'Presto',
databaseType: 'presto',
driver: 'com.facebook.presto.jdbc.PrestoDriver',
url: 'jdbc:presto://host:port/catalog',
}, {
text:'SAP HANA',
databaseType: 'sap-hana',
driver: 'com.sap.db.jdbc.Driver',
url: 'jdbc:sap://hostname:port?reconnect=true',
}, {
text:'SAP Sybase',
databaseType: 'sap-sybase',
driver: 'com.sybase.jdbc4.jdbc.SybDriver',
url: 'jdbc:sybase:Tds:hostname:2638/databasename',
}, {
text:'SPARK',
databaseType: 'spark',
driver: 'org.apache.hive.jdbc.HiveDriver',
url: 'jdbc:hive2://hostname:port/databasename',
}, {
text:'Sqlite',
databaseType: 'sqlite',
driver: 'org.sqlite.JDBC',
url: 'jdbc:sqlite:[PATH_TO_DB_FILES]',
}, {
text:'TeraData',
databaseType: 'teradata',
driver: 'com.ncr.teradata.TeraDriver',
url: 'jdbc:teradata://localhost/CLIENT_CHARSET=EUC_CN,TMODE=TERA,CHARSET=ASCII,LOB_SUPPORT',
}, {
text:'TRANSWARP INCEPTOR',
databaseType: 'transwarp-inceptor',
driver: 'org.apache.hive.jdbc.HiveDriver',
url: 'jdbc:hive2://hostname:port/databasename',
},
];
export const getCnnectionName = (links: LinkType[], name: string): string => {
const plugins: string[] = BI.Constants.getConstant(pluginListConstant);
let nameIndex = 0;
const title = name.replace(/[0-9]/g, '');
const isPlugin = BI.some(plugins, (index: number, item: string) => item === title);
const startWith = isPlugin ? title : '数据连接';
links.forEach(link => {
link.isSelected = false;
if (link.connectionName.startsWith(startWith)) {
const name = link.connectionName.replace(startWith, '0');
const index = parseInt(name, 10) + 1;
if (index > nameIndex) {
nameIndex = index;
}
}
});
return `${startWith}${nameIndex > 0 ? nameIndex : ''}`;
};

31
src/app/link_status/left/left.component.ts

@ -0,0 +1,31 @@
import {WidgetType, Vertical} from '@ui';
import Model from './left.model';
import {LinkType} from '@ui/type';
import {getLinks} from './left.service';
const className = 'fr.component.linkStatus.left';
let leftContent: any = null;
const Widget: WidgetType = {
_store() {
return BI.Models.getModel(Model);
},
watch:{
linkList(linkList: LinkType[]) {
const title = linkList.length > 0 ? linkList[0].connectionName : '';
this.store.setStatusSelected(title);
},
statusSelected(title: string) {
const linkList = this.model.linkList;
leftContent.populate(BI.createItems(getLinks(linkList, title)));
},
},
render() {
return {
type: Vertical,
ref(_ref: any) {
leftContent = _ref;
},
};
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

39
src/app/link_status/left/left.item.component.ts

@ -0,0 +1,39 @@
import {WidgetType, Left, Label} from '@ui';
import Model from './left.model';
const className = 'fr.component.linkStatus.left.item';
const Widget: WidgetType = {
props: {
title:'',
id:'',
creator: '',
},
_store() {
return BI.Models.getModel(Model);
},
render() {
const {title, extraCls, creator, text, id} = this.options;
return {
type: Left,
cls: 'left-item',
extraCls,
items: [
{
type: Label,
cls:'link-title',
textAlign: 'left',
text: title,
title,
},
],
};
},
mounted() {
const {title} = this.options;
this.element.on('click', () => {
this.store.setStatusSelected(title);
});
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

17
src/app/link_status/left/left.model.ts

@ -0,0 +1,17 @@
import {ModelType} from '@ui';
const className = 'fr.model.linkstatus.left';
const Model: ModelType = {
context: ['tab', 'linkList', 'statusSelected'],
state () {
return {
selected:'',
};
},
actions: {
setStatusSelected(title: string) {
this.model.statusSelected = title;
},
},
};
BI.model(className, BI.inherit(Fix.Model, Model));
export default className;

18
src/app/link_status/left/left.service.ts

@ -0,0 +1,18 @@
import {LinkType} from '@ui/type';
import LeftItem from './left.item.component';
export const getLinks = (linkList: LinkType[], selectTitle = ''): any => {
const links: any[] = [];
linkList.forEach((item: LinkType) => {
links.push({
type: LeftItem,
extraCls: item.connectionName === selectTitle ? 'left-item-selected' : '',
title: item.connectionName,
id: item.connectionId,
creator: item.creator,
text: item.text ? item.text : '默认',
});
});
return links;
};

56
src/app/link_status/link_status.component.ts

@ -0,0 +1,56 @@
import {WidgetType, Htape, Vtape, Left, Label} from '@ui';
import linkStatusModel from './link_status.model';
import LeftList from './left/left.component';
import Right from './right/right.component';
const className = 'fr.linkstatus';
const Widget: WidgetType = {
_store() {
return BI.Models.getModel(linkStatusModel);
},
watch:{
tab(tab: string) {
this.setVisible(tab === '连接池状态');
},
},
render() {
return {
type: Htape,
cls: 'linkStatus',
items: [{
el: {
type: Vtape,
cls: 'database-left',
items: [
{
el: {
type: Left,
cls:'select-group',
items:[
{
type: Label,
cls:'status-title',
text: '数据连接',
},
],
},
height: 40,
}, {
type: LeftList,
cls: 'left-list',
},
],
},
width: 280,
}, {
type: Right,
}],
};
},
mounted() {
this.setVisible(false);
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

9
src/app/link_status/link_status.model.ts

@ -0,0 +1,9 @@
import {ModelType} from '@ui';
const className = 'fr.model.linkstatus';
const Model: ModelType = {
context: ['tab', 'linkList'],
actions: {
},
};
BI.model(className, BI.inherit(Fix.Model, Model));
export default className;

93
src/app/link_status/right/right.card.component.ts

@ -0,0 +1,93 @@
import {WidgetType, Left, Label, Vertical} from '@ui/index';
const className = 'fr.component.linkStatus.right.card';
const Widget: WidgetType = {
render() {
const {maxActive, maxIdle, numActive, numIdle} = this.options;
return {
type: Left,
items: [
{
type: Left,
cls: 'right-status-item',
items: [
{
type: Vertical,
cls:'right-status-board',
items: [
{
type: Vertical,
cls:'right-status-board-item',
items: [
{
type: Label,
cls: 'right-status-text',
extraCls: 'card-font1',
text: numActive,
},
{
type: Label,
cls: 'right-status-text',
text: '/',
},
{
type: Label,
cls: 'right-status-text',
text: maxActive,
},
],
},
{
type: Label,
height: 20,
text: '活动连接数',
},
],
},
],
},
{
type: Left,
cls: 'right-status-right',
items: [
{
type: Vertical,
cls:'right-status-board',
items: [
{
type: Vertical,
cls:'right-status-board-item',
items: [
{
type: Label,
cls: 'right-status-text',
extraCls: 'card-font2',
text: numIdle,
},
{
type: Label,
cls: 'right-status-text',
text: '/',
},
{
type: Label,
cls: 'right-status-text',
text: maxIdle,
},
],
},
{
type: Label,
height: 20,
text: '空闲连接数',
},
],
},
],
},
],
};
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

65
src/app/link_status/right/right.component.ts

@ -0,0 +1,65 @@
import {WidgetType, Vertical, Left, Label} from '@ui/index';
import Model from './right.model';
import {info} from '@shared/crud/crud.request';
import RightCard from './right.card.component';
import {InfoType} from './right.typings';
import {LinkType} from '@ui/type';
import pluginListConstant from '../../app.constant';
const className = 'fr.component.linkStatus.right';
let Title: any = null;
let Group: any = null;
const Widget: WidgetType = {
_store() {
return BI.Models.getModel(Model);
},
watch:{
statusSelected(title: string) {
const link = BI.find(this.model.linkList, (index: number, item: LinkType) => item.connectionName === title);
const plugins: string[] = BI.Constants.getConstant(pluginListConstant);
const isPlugin = link.text && BI.some(plugins, (index: number, item: string) => item === link.text);
const Pool = isPlugin ? BI.Constants.getConstant(`dec.constant.database.conf.connect.form.${link.text.toLowerCase()}.pool`) : RightCard;
info(name, (res: InfoType) => {
Group.populate(BI.createItems([{
type: Pool,
...res,
}]));
});
Title.setText(`数据连接(${title})`);
},
},
render() {
return {
type:Vertical,
cls:'database-right',
items:[
{
type: Left,
height: 40,
cls: 'right-status-title',
items:[
{
type: Label,
text:'数据连接',
},
],
ref(ref: any) {
Title = ref;
},
}, {
type: Vertical,
cls: 'right-status-body',
ref(ref: any) {
Group = ref;
},
},
],
};
},
mounted() {
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

14
src/app/link_status/right/right.model.ts

@ -0,0 +1,14 @@
import {ModelType} from '@ui';
const className = 'fr.model.linkstatus.right';
const Model: ModelType = {
context: ['linkList', 'statusSelected'],
state () {
return {
selected:'',
};
},
actions: {
},
};
BI.model(className, BI.inherit(Fix.Model, Model));
export default className;

6
src/app/link_status/right/right.typings.d.ts vendored

@ -0,0 +1,6 @@
export interface InfoType{
maxActive: number;
maxIdle: number;
numActive: number;
numIdle: number;
}

40
src/app/title/title.component.ts

@ -0,0 +1,40 @@
import {Left, WidgetType, IconButton} from '@ui/index';
import TitleItem from './title_item/title_item.component';
import {isDesigner, closeWindow} from '@shared/crud/crud.request';
const tabs = ['数据连接管理', '连接池状态'];
const className = 'fr.title';
const Widget: WidgetType = {
render() {
return {
type: Left,
cls: 'title',
items: [
...BI.map(tabs, (index: number, text: string) => {
return {
type: TitleItem,
text,
};
}),
{
type:IconButton,
cls:'close-button',
handler() {
closeWindow();
},
invisible: true,
ref: _ref => {
this.CloseButton = _ref;
},
},
],
};
},
mounted() {
if (isDesigner()) {
this.CloseButton.setVisible(true);
}
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

37
src/app/title/title_item/title_item.component.ts

@ -0,0 +1,37 @@
import {Label} from '@ui';
import tableItemModel from './title_item.model';
import {getSelectStyle} from './title_item.service';
const className = 'fr.title.item';
const Widget = BI.inherit(BI.Widget, {
props: {
text:'',
},
_store() {
return BI.Models.getModel(tableItemModel);
},
watch:{
tab(tab: string) {
const {text} = this.options;
this.element.css(getSelectStyle(text, tab));
},
},
render() {
const {text} = this.options;
return {
type: Label,
cls: 'title-item',
text,
};
},
mounted() {
const {text} = this.options;
this.element.css(getSelectStyle('数据连接管理', text));
this.element.on('click', () => {
this.store.setTab(text);
});
},
});
BI.shortcut(className, Widget);
export default className;

11
src/app/title/title_item/title_item.model.ts

@ -0,0 +1,11 @@
const className = 'fr.model.title.item';
const Model = BI.inherit(Fix.Model, {
context: ['tab'],
actions: {
setTab(value: string) {
this.model.tab = value;
},
},
});
BI.model(className, Model);
export default className;

13
src/app/title/title_item/title_item.service.ts

@ -0,0 +1,13 @@
export function getSelectStyle(status: string, nowStatus: string): any {
if (status === nowStatus) {
return {
color: '#3685f2',
'border-bottom': 'solid 2px #3685f2',
};
}
return {
color: '#3d4d66',
'border-bottom': 'none',
};
}

97
src/demo/plugin.redis.edit.ts

@ -0,0 +1,97 @@
import './style.scss';
const RedisConstantName = 'dec.constant.database.conf.connect.form.redis.value';
const form = {
url:'192.168.1.22',
port: 6379,
password: '123456',
};
const classNameEdit = 'fr.plugin.redis.edit';
const Widget = BI.inherit(BI.Widget, {
render() {
return {
type: 'bi.vertical',
cls:'bi-plugin-redis',
bgap:10,
items: [
{
type: 'bi.left',
height: 30,
items: [
{
type: 'bi.label',
text: '数据库地址:',
height: 24,
width: 115,
textAlign: 'left',
},
{
type: 'bi.editor',
cls: 'bi-border',
watermark: '数据库地址',
value:form.url,
allowBlank: true,
width: 300,
height: 24,
}],
},
{
type: 'bi.left',
height: 30,
items: [
{
type: 'bi.label',
text: '端口:',
height: 24,
width: 115,
textAlign: 'left',
},
{
type: 'bi.editor',
cls: 'bi-border',
watermark: '端口',
allowBlank: true,
width: 300,
height: 24,
value: form.port,
errorText: '请输入有效的正整数',
validationChecker (v: string) {
if (/^\+?[1-9][0-9]*$/.test(v)) {
return true;
}
return false;
},
}],
},
{
type: 'bi.left',
height: 30,
items: [
{
type: 'bi.label',
text: '密码:',
height: 24,
width: 115,
textAlign: 'left',
},
{
type: 'bi.editor',
cls: 'bi-border',
inputType:'password',
value: form.password,
allowBlank: true,
width: 300,
height: 24,
}],
},
],
};
},
});
BI.shortcut(classNameEdit, Widget);
export default classNameEdit;
export const ConstantName = 'dec.constant.database.conf.connect.list';
BI.config(ConstantName, (datas: string[]) => [...datas, 'Redis']);
BI.constant(RedisConstantName, form);
BI.constant('dec.constant.database.conf.connect.form.redis.edit', classNameEdit);

68
src/demo/plugin.redis.preview.ts

@ -0,0 +1,68 @@
const classNamePreview = 'fr.plugin.redis.preview';
const RedisConstantName = 'dec.constant.database.conf.connect.form.redis.value';
const form = BI.Constants.getConstant(RedisConstantName);
const Widget = BI.inherit(BI.Widget, {
render() {
return {
type: 'bi.vertical',
cls:'bi-plugin-redis',
bgap:10,
items: [
{
type: 'bi.left',
height: 30,
items: [
{
type: 'bi.label',
text: '数据库地址:',
height: 24,
width: 115,
textAlign: 'left',
},
{
type: 'bi.label',
text:form.url,
height: 24,
}],
},
{
type: 'bi.left',
height: 30,
items: [
{
type: 'bi.label',
text: '端口:',
height: 24,
width: 115,
textAlign: 'left',
},
{
type: 'bi.label',
text:form.port,
height: 24,
}],
},
{
type: 'bi.left',
height: 30,
items: [
{
type: 'bi.label',
text: '密码:',
height: 24,
width: 115,
textAlign: 'left',
},
{
type: 'bi.label',
text:'********',
height: 24,
}],
},
],
};
},
});
BI.shortcut(classNamePreview, Widget);
BI.constant('dec.constant.database.conf.connect.form.redis.preview', classNamePreview);

53
src/demo/plugin.tedis.pool.ts

@ -0,0 +1,53 @@
const classNamePool = 'fr.plugin.redis.pool';
const WidgetPool = BI.inherit(BI.Widget, {
render() {
const {maxActive, maxIdle, numActive, numIdle} = this.options;
return {
type: 'bi.left',
items: [
{
type: 'bi.left',
cls: 'right-status-item',
items: [
{
type: 'bi.vertical',
cls:'right-status-board',
items: [
{
type: 'bi.vertical',
cls:'right-status-board-item',
items: [
{
type: 'bi.label',
cls: 'right-status-text',
extraCls: 'card-font1',
text: numActive,
},
{
type: 'bi.label',
cls: 'right-status-text',
text: '/',
},
{
type: 'bi.label',
cls: 'right-status-text',
text: maxActive,
},
],
},
{
type: 'bi.label',
text: 'Redis连接数',
},
],
},
],
},
],
};
},
});
BI.shortcut(classNamePool, WidgetPool);
BI.constant('dec.constant.database.conf.connect.form.redis.pool', classNamePool);

3
src/demo/style.scss

@ -0,0 +1,3 @@
.bi-plugin-redis{
padding: 20px;
}

BIN
src/img/ads.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
src/img/amazon-redshift.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
src/img/apache-impala.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/img/apache-kylin.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
src/img/apache-phoenix.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/img/database-selected.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/img/derby.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/img/error.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

BIN
src/img/gbase-8a.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
src/img/gbase-8s.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
src/img/gbase-8t.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
src/img/h2.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/img/hadoop-hive.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
src/img/hbase.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
src/img/hp-vertica.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/img/hsql.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/img/hw-dws.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/img/hw-elk.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
src/img/hw-fusioninsight-hd.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/img/hw-libr-a.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
src/img/ibm-db2.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
src/img/icon_close9x9_normal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

BIN
src/img/informix.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
src/img/kingbase.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
src/img/loading.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
src/img/mysql.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
src/img/oracle.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
src/img/pivotal-greenplum-database.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/img/postgresql.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
src/img/presto.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
src/img/resources.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
src/img/sap-hana.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
src/img/sap-sybase.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/img/spark.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/img/sql-server.jpeg

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/img/sql-server.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/img/sqlite.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/img/success.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

BIN
src/img/teradata.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
src/img/transwarp-inceptor.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/img/warning.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

14
src/index.html

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>数据库连接设置</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="./lib/fineui.min.css" />
<script type="text/javascript" charset="UTF-8" src="./lib/fineui.min.js"></script>
</head>
<body>
<noscript> You need to enable JavaScript to run this app. </noscript>
</body>
</html>

8
src/index.ts

@ -0,0 +1,8 @@
BI.DOM.ready(() => {
const app = require('./app/app.component').default;
BI.createWidget({
type:app,
element: 'body',
});
});

1
src/lib/fineui.min.css vendored

File diff suppressed because one or more lines are too long

41
src/lib/fineui.min.js vendored

File diff suppressed because one or more lines are too long

28
src/shared/components/both.side.component.ts

@ -0,0 +1,28 @@
import {WidgetType, Htape, Label} from '@ui/index';
const BothSide = 'fr.shared.component.both.side';
const Widget: WidgetType = {
render() {
const {leftText, rightText} = this.options;
return {
type: Htape,
cls: 'both-side',
height:24,
items: [{
el: {
type: Label,
cls: 'left',
textAlign: 'left',
text: leftText,
},
width: 115,
}, {
type: Label,
textAlign: 'left',
text: rightText,
}],
};
},
};
BI.shortcut(BothSide, BI.inherit(BI.Widget, Widget));
export default BothSide;

29
src/shared/components/form.item.component.ts

@ -0,0 +1,29 @@
import {WidgetType, Htape, Label} from '@ui/index';
const className = 'fr.shared.component.form.item';
const Widget: WidgetType = {
render() {
const {text, form, hint, height} = this.options;
return {
type: Htape,
cls: 'both-side',
height:height ? height : 24,
items: [{
el: {
type: Label,
cls: 'left',
textAlign: 'left',
text,
},
width: 115,
}, form, {
type: Label,
cls: 'hint',
textAlign: 'left',
text: hint,
}],
};
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

16
src/shared/components/title.component.ts

@ -0,0 +1,16 @@
import {WidgetType, Label} from '@ui/index';
const className = 'fr.shared.component.title';
const Widget: WidgetType = {
render() {
const {text} = this.options;
return {
type: Label,
cls: 'shared-component-title',
textAlign: 'left',
text,
};
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));
export default className;

130
src/shared/crud/crud.request.ts

@ -0,0 +1,130 @@
import {linkList} from './curd.mock';
import {LinkType} from '@ui/type';
const Dec: any = (window as any).parent.Dec;
const PluginHelper: any = (window as any).PluginHelper;
/**
*
*/
export function isDesigner(): boolean {
if (PluginHelper) {
return PluginHelper.isDesigner();
}
return false;
}
/**
*
*/
export function closeWindow(): void{
if (PluginHelper) {
return PluginHelper.closeWindow();
}
console.log('关闭窗口');
}
/**
*
* @param callback
*/
export function fetchLinkList(callback: Function): void {
if (Dec) {
Dec.reqGet('/v10/config/connection/list', 'getInstalledPlugins', (res: any) => {
callback(res.data);
});
} else {
callback(linkList.data);
}
}
/**
*
* @param data
* @param cb
*/
export function addConnection(data: LinkType, cb: Function): void{
console.log('%cdata: ', 'color: MidnightBlue; background: Aquamarine;', data);
if (Dec) {
Dec.reqPost(`/v10/config/connection`, data, (res: any) => {
cb(res.data);
});
} else {
cb('success');
}
}
/**
*
* @param data
* @param cb
*/
export function updateConnection(data: LinkType, cb: Function): void{
console.log('%cdata: ', 'color: MidnightBlue; background: Aquamarine;', data);
if (Dec) {
Dec.reqPut(`/v10/config/connection`, data, (res: any) => {
cb(res.data);
});
} else {
cb('success');
}
}
/**
*
* @param data
* @param cb
*/
export function testConnection(data: LinkType, cb: Function): void{
console.log('%cdata: ', 'color: MidnightBlue; background: Aquamarine;', data);
if (Dec) {
Dec.reqPost(`/v10/config/connection/test`, data, (res: any) => {
cb(res);
});
} else {
setTimeout(() => {
cb({errorCode:'500', errorMsg:'createConnectionThread not start!'});
}, 2000);
}
}
/**
*
* @param id id
* @param cb
*/
export function deleteConnection(id: string, cb: Function): void{
console.log('%cid: ', 'color: MidnightBlue; background: Aquamarine;', id);
if (Dec) {
Dec.reqDeleta(`/v10/config/connection/${id}`, (res: any) => {
cb(res.data);
});
} else {
cb('success');
}
}
/**
*
* @param id id
* @param cb
*/
export function getConnectionStatus(id: string, cb: Function): void{
console.log('%cid: ', 'color: MidnightBlue; background: Aquamarine;', id);
if (Dec) {
Dec.reqDeleta(`/v10/config/connection/${id}/status`, (res: any) => {
cb(res.data);
});
} else {
cb('success');
}
}
export function info(name: string, cb: Function): void{
console.log('%cname: ', 'color: MidnightBlue; background: Aquamarine;', name);
if (Dec) {
Dec.reqDeleta(`/v10/config/connection/pool/info?connectionName=${name}`, (res: any) => {
cb(res.data);
});
} else {
cb({maxActive:50, maxIdle:10, numActive:0, numIdle:0});
}
}

1
src/shared/crud/curd.mock.ts

@ -0,0 +1 @@
export const linkList = {"data":[{"connectionId":"8c1c52f1-3d0a-429e-b35f-ee1e085a8b72","database":"","connectionName":"FRDemo","driver":"org.sqlite.JDBC","url":"jdbc:sqlite://${ENV_HOME}/../help/FRDemo.db","user":"","password":"","queryType":"","newCharsetName":'null',"originalCharsetName":'',"validationQuery":"","schema":"","testOnBorrow":true,"maxActive":50,"options":'null',"port":0,"authType":"","creator":"designer","principal":"","keyPath":"","databaseType":"designer","privilegeDetailBeanList":'null'}]}

243
src/shared/service/dialog.service.ts

@ -0,0 +1,243 @@
import {Label, Vertical, Left, Button, Layout} from '@ui/index';
class Dialog {
/**
*
* @param message
* @param onConfirm
*/
public confirm(message: string, onConfirm: Function): string {
const id = BI.UUID();
BI.Popovers.create(id, {
type: 'bi.bar_popover',
size: 'normal',
header: '提示',
width: 450,
height: 220,
body: {
type: 'bi.left',
cls: 'comfirm-content',
items: [
{
type: 'bi.layout',
cls: 'comfirm-icon',
width: 50,
height: 50,
},
{
type: 'bi.label',
text: message,
},
],
},
listeners: [
{
eventName: 'EVENT_CONFIRM',
action () {
onConfirm ? onConfirm(true) : null;
},
},
{
eventName: 'EVENT_CANCEL',
action () {
onConfirm ? onConfirm(false) : null;
},
},
],
}).open(id);
return id;
}
public loading(message: string): string {
const body = {
type: 'bi.center_adapt',
cls: 'show-content',
items: [
{
type: Vertical,
items:[
{
type: 'bi.layout',
cls: 'loading-icon',
width: 100,
height: 100,
},
{
type: Label,
text: message,
},
],
},
],
};
return this.show(body);
}
public success(message: string): string {
const body = {
type: 'bi.center_adapt',
cls: 'show-content',
items: [
{
type: Vertical,
items:[
{
type: 'bi.layout',
cls: 'success-icon',
width: 100,
height: 100,
},
{
type: Label,
text: message,
},
],
},
],
};
return this.show(body, 1000);
}
public error(message: string): string {
const body = {
type: 'bi.center_adapt',
cls: 'show-content',
items: [
{
type: Vertical,
items:[
{
type: 'bi.layout',
cls: 'error-icon',
width: 100,
height: 100,
},
{
type: Label,
text: message,
},
],
},
],
};
return this.show(body, 2000);
}
public linkFail(text: string, more: string, cb?: Function): string {
let Popover: any = null;
let More: any = null;
const id = BI.UUID();
const that = this;
const body = {
type: Vertical,
items: [
{
type: 'bi.center_adapt',
cls: 'show-content',
tgap:10,
items: [
{
type: Vertical,
items:[
{
type: Layout,
cls: 'error-icon',
width: 100,
height: 100,
},
{
type: Label,
text,
},
{
type: Left,
cls:'buttons',
items:[
{
type: Button,
text:'详细信息',
level: 'ignore',
handler() {
const isHide = this.getText() === '详细信息';
Popover.element.css({
height: isHide ? '290' : '220',
});
More.setVisible(isHide);
this.setText(isHide ? '收起信息' : '详细信息');
},
},
{
type: Button,
text:'返回',
level: 'ignore',
handler() {
that.close(id);
},
},
{
type: Button,
text:'重新连接',
handler() {
that.close(id);
cb ? cb() : null;
},
},
],
},
],
},
],
}, {
type: Label,
cls:'show-more',
text:more,
invisible: true,
ref(ref: any) {
More = ref;
},
},
],
};
BI.Popovers.create(id, {
type: 'bi.popover',
cls:'popover-notitle',
extraCls:'bi-custom-show',
size: 'normal',
width: 450,
height: 220,
body,
ref(ref: any) {
Popover = ref;
},
}).open(id);
return id;
}
public close(id: string): void{
BI.Popovers.close(id);
}
public show(body: any, autoClose = 0): string {
const id = BI.UUID();
BI.Popovers.create(id, {
type: 'bi.popover',
cls:'popover-notitle',
extraCls:'bi-custom-show',
size: 'normal',
width: 450,
height: 220,
body,
}).open(id);
if (autoClose > 0) {
setTimeout(() => {
this.close(id);
}, autoClose);
}
return id;
}
}
export default new Dialog();

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

Loading…
Cancel
Save