* 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
@ -0,0 +1,5 @@
|
||||
dist/*.js |
||||
src/assets/* |
||||
src/lib/* |
||||
webpack.config.js |
||||
curd.mock.ts |
@ -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" // 强制回调错误处理
|
||||
} |
||||
} |
@ -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 |
@ -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); |
||||
``` |
@ -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" |
||||
} |
||||
} |
@ -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; |
||||
} |
@ -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; |
@ -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; |
@ -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; |
@ -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; |
@ -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; |
||||
}; |
@ -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; |
@ -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; |
@ -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; |
@ -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; |
@ -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); |
||||
} |
||||
})); |
||||
} |
@ -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; |
@ -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; |
@ -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); |
||||
}; |
@ -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; |
@ -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; |
@ -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; |
@ -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; |
@ -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; |
@ -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; |
@ -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; |
||||
} |
@ -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; |
@ -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; |
@ -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; |
@ -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 : ''}`; |
||||
}; |
@ -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; |
@ -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; |
@ -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; |
@ -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; |
||||
}; |
@ -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; |
@ -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; |
@ -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; |
@ -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; |
@ -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; |
@ -0,0 +1,6 @@
|
||||
export interface InfoType{ |
||||
maxActive: number; |
||||
maxIdle: number; |
||||
numActive: number; |
||||
numIdle: number; |
||||
} |
@ -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; |
@ -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; |
@ -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; |
@ -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', |
||||
}; |
||||
} |
@ -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); |
@ -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); |
@ -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); |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 260 B |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 9.6 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 5.9 KiB |
@ -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> |
@ -0,0 +1,8 @@
|
||||
BI.DOM.ready(() => { |
||||
const app = require('./app/app.component').default; |
||||
BI.createWidget({ |
||||
type:app, |
||||
element: 'body', |
||||
}); |
||||
}); |
||||
|
@ -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; |
@ -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; |
@ -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; |
@ -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}); |
||||
} |
||||
} |
@ -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'}]} |
@ -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(); |